"Callbacks in CORBA," Volume: 4 Issue: 3, p. 24

Listing 1: traffic.idl
module traffic
{
 interface TrafficLight
 {
  attribute short LightNumber;
void SetColor (in string color);
};

interface TrafficCoordinator
{
typedef sequence <TrafficLight> LightsList;
attribute LightsList lights;
void Register(in TrafficLight light);
void SetColor (in short LightNumber, in string color);
};
}

Listing 2: TrafficLightImpl.java
//***************************
// File : TrafficLightImpl.java
// This file contains implementation of following classes
// 1. TrafficLightImpl
// copyright 1998: ABCOM Information Systems Pvt. Ltd.,
All rights reserved.
//***************************

//***************************
// Class implemented : TrafficLightImpl
// Derived from : _TrafficLightImplBase
// Implements : None
// Description :
// TrafficLightImpl class provides the implementation for CORBA
// TrafficLight interface
//***************************

package traffic;
import TrafficLightServer;

public class TrafficLightImpl extends traffic._TrafficLightImplBase
{
//a variable which holds light number
private short Number;
// The LightServer variable declared below holds a
// reference to the server object which creates
// this object
private TrafficLightServer LightServer;

// class constructor - receives reference to TrafficLightServer
// object and the the light number to be assigned
// to the constructed object.
public TrafficLightImpl(TrafficLightServer LightServer,
short LightNumber)
{
super("Traffic Light" + String.valueOf (LightNumber));
this.LightServer = LightServer;

// print the message on the system console to inform
// the user that the Traffic Light is created.
System.out.println ("Traffic Light #"
+ String.valueOf (LightNumber)
+ " created");
Number = LightNumber;
}

// no-argument constructor
public TrafficLightImpl() {
super();
}

// The SetColor method calls the SetColor method
// on the server object to set the states of three
// lights
public void SetColor(java.lang.String color)
{
LightServer.SetColor (color);
}

// modifier method for LightNumber attribute
public void LightNumber(short LightNumber)
{
this.Number = LightNumber;
}

// accessor method for LightNumber attribute
public short LightNumber() {
return Number;
}
}

Listing 3: TrafficLightServer.java
//****************************
// File : TrafficLightServer.java
// This file contains implementation of following classes
// 1. TrafficLightServer
// 2. TLightPanel
// copyright 1998: ABCOM Information Systems Pvt. Ltd., All rights reserved.
//****************************

// Import the classes we are going to use
import traffic.TrafficLightImpl;
import traffic.TrafficCoordinator;
import org.omg.CosNaming.*;
import org.omg.CORBA.*;
import java.awt.*;
import java.awt.event.*;

//*****************************
// Class implemented : TrafficLightServer
// Derived from : Frame
// Implements : None
// Description :
// The TrafficLightServer class defines a Java Command line
// program. The server creates object of TrafficLightImpl class,
// obtains a reference to the TrafficCoordinator object and registers
// the newly created traffic light object with the coordinator by
// calling Register method of the coordinator object.
//*****************************
public class TrafficLightServer extends Frame
{
// declare three TLightPanel variables for three colors.
TLightPanel RedLight, AmberLight, GreenLight;

// class constructor
public TrafficLightServer (String[] args)
{
super ("# " + args[0]);
init (args);
}

// the program execution begins here
// the first command line argument specifies the light number.
static public void main (String[] args)
{
if (args[0] == null)
{
System.out.println ("Usage: Java TrafficLightServer LightNumber");
System.exit(0);
}

// create an instance of the server class
TrafficLightServer obj = new TrafficLightServer (args);

try
{
// obtain a reference to ORB
ORB orb = ORB.init (args, null);
// create a traffic light implementation object
TrafficLightImpl TL =
new TrafficLightImpl(
obj,
(short)Integer.parseInt(args[0]));
// Export the newly created object
// orb.connect(TL);

// Get a reference to the Naming service
org.omg.CORBA.Object nameServiceObj =
orb.resolve_initial_references("NameService");
if (nameServiceObj == null)
{
System.out.println("nameServiceObj = null");
return;
}

// do type casting
NamingContext nameService =
NamingContextHelper.narrow (nameServiceObj);
if (nameService == null)
{
System.out.println("nameService = null");
return;
}

// Locate and register with coordinator
NameComponent[] Coordinator = {new NameComponent("Coordinator", "")};

traffic.TrafficCoordinator MyCoordinator =
traffic.TrafficCoordinatorHelper.narrow(nameService.resolve(Coordinator));

if (MyCoordinator == null)
System.out.println ("could not locate Coordinator");
MyCoordinator.Register (TL);

// wait forever for current thread to die
Thread.currentThread().join();
}
catch (org.omg.CORBA.SystemException e)
{
System.err.println (e);
}
catch(Exception e)
{
System.err.println(e);
}
}

public void init(String[] args)
{
// set the location for traffic lights frame
int x=0, y=0;

// only four lights are assumed here
switch (Integer.parseInt (args[0]))
{
case 1:
x=0; y=0;
break;
case 2:
x=125; y=0;
break;
case 3:
x=250; y=0;
break;
case 4:
x=375; y=0;
break;
}
// set the size and location of the application frame
setBounds (x, y, 5, 300);
// set the layout manager
setLayout (new GridLayout (3, 1, 10, 10));

// create three light panel objects
// and add them to the container
RedLight = new TLightPanel (Color.red);
AmberLight = new TLightPanel (Color.orange);
GreenLight = new TLightPanel (Color.green);
add (RedLight);
add (AmberLight);
add (GreenLight);

// set up the window listener
addWindowListener (new WindowAdapter ()
{
public void windowClosing (WindowEvent evt)
{
System.exit(0);
}
});

// show the frame
show();
// set lights to red
SetRedLight();
}

// SetColor method receives the string describing the
// color for the light. It calls the apprpriate Set...
// method depending on the value of string received.
public void SetColor (String color)
{
if (color.equals ("Red"))
SetRedLight();
else if (color.equals ("Amber"))
SetAmberLight();
else if (color.equals ("Green"))
SetGreenLight();
repaint();
}

// The SetRedLight() method calls SetColor() method
// on individual light objects and enables red light
// disabling the other two lights
private void SetRedLight()
{
RedLight.SetColor (Color.red);
AmberLight.SetColor (Color.darkGray);
GreenLight.SetColor (Color.darkGray);
}

// The SetAmberLight() method calls SetColor() method
// on individual light objects and enables Amber light
// disabling the other two lights
private void SetAmberLight()
{
RedLight.SetColor (Color.darkGray);
AmberLight.SetColor (Color.orange);
GreenLight.SetColor (Color.darkGray);
}

// The SetGreenLight() method calls SetColor() method
// on individual light objects and enables Green light
// disabling the other two lights
private void SetGreenLight()
{
RedLight.SetColor (Color.darkGray);
AmberLight.SetColor (Color.darkGray);
GreenLight.SetColor (Color.green);
}
}

// class TLightPanel is extending from Panel class and is
// used for displaying individual lights.
class TLightPanel extends Panel
{
final int MARGIN=10;
Color color;

//class constructor
public TLightPanel(Color color)
{
super();
this.color = color;
}

// create an oval shaped light and fill it with
// desired color.
public void paint (Graphics g)
{
Rectangle r = getBounds();
setBackground (Color.lightGray);
g.draw3DRect (2, 2, r.width-4, r.height-4, false);
g.setColor (color);
g.fillOval (MARGIN,MARGIN,r.width-2*MARGIN,r.height-2*MARGIN);
}

// Set the color of this light object
public void SetColor (Color color)
{
this.color = color;
repaint();
}
}

Listing 4:TrafficCoordinatorImpl.java
//**************************************
// File : TrafficCoordinatorImpl.java
// This file contains implementation of following classes
// 1. TrafficCoordinatorImpl
// copyright 1998: ABCOM Information Systems Pvt. Ltd., All rights reserved.
//*******************************

package traffic;

// Import the classes we are going to use
import java.util.*;

//*******************************
// Class implemented : TrafficCoordinatorImpl
// Derived from : _TrafficCoordinatorImplBase
// Implements : None
// Description :
// The TrafficCoordinatorImpl provides the
// implementation for TrafficCoordinator interface
// defined in our CORBA IDL. The class is derived
// from _TrafficCoordinatorImplBase class which is
// generated by idl2java compiler. The instance
// of this class acts as a coordinator for
// traffic light objects. Each traffic light
// object registers itself with the coordinator.
// The traffic cop makes use of coordinator to
// control the various traffic lights.
//*******************************

public class TrafficCoordinatorImpl extends traffic._TrafficCoordinatorImplBase
{
// declare a vector for storing references to traffic light objects
private Vector LightsList = new Vector();

// class constructor
public TrafficCoordinatorImpl(java.lang.String name) {
super(name);
// print the message on the system console to inform
// the user that the object is created.
System.out.println ("Traffic Coordinator object created");
}

// no-argument constructor
public TrafficCoordinatorImpl() {
super();
}

// This method will be called by a traffic light (TrafficLight)
// object. The method receives a reference to the traffic light
// object which is to be registered with the coordinator. The
// method stores the reference to the object in the local vector.
public void Register(traffic.TrafficLight light)
{
// add to the local vector
LightsList.addElement (light);
// print out the message for the user
System.out.println ("Registered Traffic Light # " +
String.valueOf (light.LightNumber()));
}

// The SetColor method is called by the traffic cop. The method
// receives the light number and the color to be set. The method
// searches through the registered list of traffic lights for the
// given light number. If the number is found, it calls the
// SetColor method on the traffic light object to set the desired
// color.
public void SetColor(short LightNumber,java.lang.String color)
{
// Iterate through the list of registered lights
for (int i=0; i<LightsList.size(); i++)
{
TrafficLight light = (TrafficLight)LightsList.elementAt(i);
// if a matching light is found, call its SetColor method.
if (light.LightNumber() == LightNumber)
{
light.SetColor (color);
break;
}
}
}

// modifier method for the lights attribute. As the current
// application does not require to modify this attribute, this
// method is not implemented.
public void lights(traffic.TrafficLight[] lights) {
// implement attribute writer...
}


// accessor method for lights attribute. The method
// returns an array of TrafficLight objects to the caller.
public traffic.TrafficLight[] lights() {
// create an array for holding traffic light objects
traffic.TrafficLight[] lightsList =
new traffic.TrafficLight[LightsList.size()];

// initialize each element of the array
for (int i=0; i<LightsList.size(); i++)
lightsList[i] = (traffic.TrafficLight)LightsList.elementAt(i);

// return the array to the caller.
return (lightsList);
}
}

Listing 5: TrafficCoordinatorServer.java
//*******************************
// File : TrafficCoordinatorServer.java
// This file contains implementation of following classes
// 1. TrafficCoordinatorServer
// copyright 1998: ABCOM Information Systems Pvt. Ltd., All rights reserved.
//*******************************

// Import the classes we are going to use
import traffic.TrafficCoordinatorImpl;
import org.omg.CosNaming.*;
import org.omg.CORBA.*;

//*******************************
// Class implemented : TrafficCoordinatorServer
// Derived from : None
// Implements : None
// Description :
// The TrafficCoordinatorServer class defines a Java Command line
// program. The server creates object of TrafficCoordinatorImpl class
// and registers the object with CORBA naming service by using the name
// "Coordinator" for the object. After registering the object, the
// program simply waits for invocations to occur.
//*******************************

public class TrafficCoordinatorServer
{
// program execution begins here
static public void main (String[] args)
{
try
{
// obtain reference to ORB.
ORB orb = ORB.init (args, null);
// create object of our coordinator implementation class
TrafficCoordinatorImpl TC =
new TrafficCoordinatorImpl("TrafficCoordinator");
// Export the newly created object
orb.connect(TC);

// Get a reference to the Naming service
org.omg.CORBA.Object nameServiceObj =
orb.resolve_initial_references ("NameService");
if (nameServiceObj == null)
{
System.out.println("nameServiceObj = null");
return;
}

// Do type casting
NamingContext nameService =
NamingContextHelper.narrow (nameServiceObj);
if (nameService == null)
{
System.out.println("nameService = null");
return;
}

// bind the Count object to the Naming service
NameComponent[] Name = {new NameComponent("Coordinator", "")};
nameService.rebind(Name, TC);

// wait forever for current thread to die
Thread.currentThread().join();
}
catch (org.omg.CORBA.SystemException e)
{
System.err.println (e);
}
catch(Exception e)
{
System.err.println(e);
}
}
}

Listing 6: TrafficCop.java
//*******************************
// File : TrafficCop.java
// This file contains implementation of following classes
// 1. TrafficCop
// 2. TrafficBasePanel
// copyright 1998: ABCOM Information Systems Pvt. Ltd., All rights reserved.
//*******************************

// Import the classes we are going to use

import traffic.TrafficLightImpl;
import traffic.TrafficCoordinator;
import org.omg.CosNaming.*;
import org.omg.CORBA.*;
import java.awt.*;
import java.awt.event.*;

//*******************************
// Class implemented : TrafficCop
// Derived from : Frame
// Implements : ActionListener
// Description :
// This class controls the various lights at a junction
// with the help of traffic coordinator. The user interface
// displays the available lights at the junction. The user
// sets the lights to desired colors and presses set button
// to request the controller to do the desired settings for
// individual lights.
//*******************************

class TrafficCop extends Frame
implements ActionListener
{
// variable for holding reference to
// traffic coordinator
private static traffic.TrafficCoordinator MyCoordinator;
// set button variable
private Button SetButton;
// array to hold references to traffic light objects
public static traffic.TrafficLight[] Lights;
// base panel variable
private TrafficBasePanel basePanel;

// class constructor
public TrafficCop ()
{
super ("Traffic Cop");
init ();
// set size and location
setBounds (0,0, 200, 300);
}

// program execution begins here
static public void main (String[] args)
{
try
{
// initialize ORB
ORB orb = ORB.init (args, null);

// Get a reference to the Naming service
org.omg.CORBA.Object nameServiceObj =
orb.resolve_initial_references ("NameService");
if (nameServiceObj == null)
{
System.out.println("nameServiceObj = null");
return;
}

// type cast the reference
NamingContext nameService =
NamingContextHelper.narrow (nameServiceObj);
if (nameService == null)
{
System.out.println("nameService = null");
return;
}

// Locate the Coordinator object
NameComponent[] Coordinator = {new NameComponent("Coordinator", "")};

traffic.TrafficCoordinator t =
traffic.TrafficCoordinatorHelper.narrow (nameService.resolve(Coordinator));
if (t == null)
System.out.println ("could not locate Coordinator");

// retrieve the list of registered objects
Lights = t.lights();
}
catch (org.omg.CORBA.SystemException e)
{
System.err.println (e);
}
catch(Exception e)
{
System.err.println(e);
}

// Create an instance of our application class
new TrafficCop ();
}

// init() provides the initialization of our application
public void init()
{
// create the set button and set action listener
SetButton = new Button ("Set");
SetButton.addActionListener (this);
// create base panel object
basePanel = new TrafficBasePanel(this);
// add components to the container
add ("Center", basePanel);
add ("South", SetButton);

// set up window listener
addWindowListener (new WindowAdapter ()
{
public void windowClosing (WindowEvent evt)
{
System.exit(0);
}
});

// pack and show the frame
pack();
show();
}

// process action events generated by set button
public void actionPerformed (ActionEvent evt)
{
if (evt.getSource() == SetButton)
{
// update the base panel to show
// changes to lights
basePanel.update();
}
}
}

//*******************************
// Class implemented : TrafficBasePanel
// Derived from : Panel
// Implements : None
// Description :
// Class TrafficBasePanel provides a panel for showing the
// individual light panels for all the registered traffic
// lights.
//*******************************

class TrafficBasePanel extends Panel
{
private int MAXPANELS;
private TrafficCop Cop;
private TrafficLightsPanel[] LightsPanel;

// The update method iterates through all the displayed
// light panels and calls SetColor method on each.
public void update()
{
for (int i=0; i<MAXPANELS; i++)
{
Cop.Lights[i].SetColor (LightsPanel[i].clr);
}
}

// class constructor
public TrafficBasePanel(TrafficCop Cop)
{
super();
this.Cop = Cop;
// set the variable to the number of lights
// received by the cop.
MAXPANELS = Cop.Lights.length;
// create light panels equal to the number
// of lights
LightsPanel = new TrafficLightsPanel[MAXPANELS];
// initialize.
init();
}

// init() method sets the user interface of the application.
private void init()
{
// set the layout manager. A maximum of 4 lights
// is assumed.
setLayout (new GridLayout (1, 4, 10, 10));
// create the light panels and add to container.
for (int i=0; i<MAXPANELS; i++)
{
LightsPanel[i] = new TrafficLightsPanel();
add (LightsPanel[i]);
}
}
}

//*******************************
// Class implemented : TrafficLightsPanel
// Derived from : Panel
// Implements : MouseListener
// Description :
// The TrafficLightsPanel class creates three LightPanel objects
// and displays them to the user. When user clicks on any of the
// lights, the class process the event and set the color
// string variable. It then calls the appropriate Set.. method
// to set the colors of three light objects.
//*******************************

class TrafficLightsPanel extends Panel implements MouseListener
{
// variable to hold three LightPanel objects
LightPanel RedLight, AmberLight, GreenLight;
// the color selected on this panel
String clr = "Red";

// class constructor
public TrafficLightsPanel()
{
init();
}


private void init()
{
setBackground (Color.lightGray);
// set layout manager
setLayout (new GridLayout (3, 1, 10, 10));
// create three LightPanel objects and add
RedLight = new LightPanel (this, Color.red);
AmberLight = new LightPanel (this, Color.orange);
GreenLight = new LightPanel (this, Color.green);
add (RedLight);
add (AmberLight);
add (GreenLight);
// set default to red light
SetRedLight();
}

// sets red light and others to gray.
private void SetRedLight()
{

RedLight.SetColor (Color.red);
AmberLight.SetColor (Color.darkGray);
GreenLight.SetColor (Color.darkGray);
}

// sets amber light and others to gray.
private void SetAmberLight()
{
RedLight.SetColor (Color.darkGray);
AmberLight.SetColor (Color.orange);
GreenLight.SetColor (Color.darkGray);
}

// sets green light and others to gray.
private void SetGreenLight()
{
RedLight.SetColor (Color.darkGray);
AmberLight.SetColor (Color.darkGray);
GreenLight.SetColor (Color.green);
}

// process mouse pressed events
public void mousePressed(MouseEvent evt)
{
// depeding on the source of mouse click
// event, set the appropriate light
if (evt.getSource() == RedLight)
{
clr = "Red";
SetRedLight();
}
if (evt.getSource() == AmberLight)
{
clr = "Amber";
SetAmberLight();
}
if (evt.getSource() == GreenLight)
{
clr = "Green";
SetGreenLight();
}
}

public void mouseExited (MouseEvent evt) {}
public void mouseClicked (MouseEvent evt) {}
public void mouseReleased (MouseEvent evt) {}
public void mouseEntered (MouseEvent evt) {}
}

// class LightPanel displays one traffic light
class LightPanel extends Panel
{
private final int MARGIN=10;
private Color color;
private String str = "";

// class constructor
public LightPanel(TrafficLightsPanel LightsPanel, Color color)
{
super();

// depending on the input color parameter
// set the color string
this.color = color;
if (color == Color.red)
str = "Red";
else if (color == Color.orange)
str = "Amber";
else if (color == Color.green)
str = "Green";
// set up mouse listener
addMouseListener (LightsPanel);
}

// draw the user interface for the light
public void paint (Graphics g)
{
Rectangle r = getBounds();
setBackground (Color.lightGray);
g.draw3DRect (2, 2, r.width-4, r.height-4, false);
g.setColor (color);
g.fillOval (MARGIN,MARGIN,r.width-2*MARGIN,r.height-2*MARGIN);
FontMetrics tm = this.getFontMetrics (this.getFont ());
if (color == Color.darkGray)
g.setColor (Color.white);
else
g.setColor (Color.black);
g.drawString (str,
(int)(r.width/2.0 - tm.stringWidth ("Red")/2.0),
(int)(r.height/2.0));
}

// Set the color to the value of input color variable
public void SetColor (Color color)
{
this.color = color;
repaint();
}
}

Listing 7. make.bat
javac -d . TrafficLightImpl.java
javac TrafficLightServer.
javajavac -d . TrafficCoordinatorImpl.java
javac TrafficCoordinatorServer.java
javac TrafficCop.java