HelloWorld Tutorial

HelloWorld program tries to simulate the population growth of particular country provided that the initial population and the number of years for the simulation entered from command line. This simple example explains the detailes about HLA/RTI software so that we can build more sophisticated simulations by using this communication bus.

Demo explains how we can define a particular federate and interact with the RTI software. This demos allows us to define a HelloWorld federation and then we can see the simulation results of the other joined countries to this federation. We discover them on the fly (if they exist) and send our updates (if it is required) without knowing other participants.

There are five objects in this demo. Country object represents the Country data, EntityManager keeps the track of discovered Country objects and their states, SimCountry object represents the country that this instance is simulating, HwFederateAmbassador object is the callback object to receive RTI calls and HelloWorld object controls the whole simulation. HelloWorld object completes the required declaration procedures, runs the main simulation loop and clears all the definitions related to this simulation instance.

To communicate with RTI we need to get the handle of RTIAmbassador object. Therefore we first obtain the RTIKernel object and ask it a RTIAmbassador object. Current design defines RTIAmbassador object for each federate in the server side (not necessarily on the same machine). The next version of this software will allow definition of this object on the client side and hide the necessary CORBA mechanism from the user.

   /**
   */
   public static void 
   main(String args[])
   {
     try
     {
      
        // Create and initialize the ORB
        ORB orb = ORB.init(args, null); 
      
        /*  ----- This Part is required if we are using Naming Service ---
        // Get the root naming context
        org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
        NamingContext ncRef = NamingContextHelper.narrow(objRef);
      
        // Resolve the object reference in naming
        NameComponent nc = new NameComponent("RTIKernel", " ");
        NameComponent path[] = {nc};
        RTIKernelInterface rtiKernel = RTIKernelInterfaceHelper.narrow(ncRef.resolve(path));
        */

        try 
        {
           BufferedReader input = new BufferedReader(new FileReader("../IOR"));
           String strIOR = input.readLine();  // get IOR address of RTIKernelInterface
           if( strIOR != null )
           {
      
              RTIKernelInterface rtiKernel = RTIKernelInterfaceHelper.narrow(orb.string_to_object(strIOR)); 

              // Get the Version of the Kernel
              String version = rtiKernel.getVersion();
              System.out.println(" Version is : "+version);      

              if(args.length>2)
              {
                 RTIambassador rtiAmb = rtiKernel.createRTIAmbassador();
                 HelloWorld hello = new HelloWorld(rtiAmb,args[0],Double.valueOf(args[1]).doubleValue(),Integer.parseInt(args[2]),orb);
                 hello.start();

              }// end of if

           } else System.out.println(" IOR file is empty| \n "+
                        "I can not find the address of RTIKernelInterface ");

        } catch(java.io.FileNotFoundException fnf) {}
          catch(java.io.IOException ioe) {}
          catch(NumberFormatException ioe) {}
          
     } catch(Exception e) 
       {
         System.out.println("ERROR : " + e);
         e.printStackTrace(System.out);
       }  

  }// end of main()

All the process is being handled in the run() method of HelloWorld object. Therefore, we will go through the each line of this method and try to explain what the purpose of a particular code is.

   /**
   */
   public void 
   run()
   {
      int count = 0;

      /*******************************************************************/
      /** Define FederateAmbassador for HelloWorld. This objects serves  */
      /** as a callback mechanism so that RTI can bring us the necessary */ 
      /** events.                                                        */
      /*******************************************************************/
      HwFederateAmbassador fedAmb = new HwFederateAmbassador(EntityMng,this);
      orb.connect(fedAmb);
Define a callback object so that HelloWorld control object can receive the RTI calls via this object.
      /************************************************************/
      /** Create FederationExecution, get RTI id of the objects,  */
      /** attributes, interactions, and parameters.               */
      /** Define interest for Subscription/Publishing.            */
      /** Define my simulated object.                             */
      /************************************************************/
      if( joinFederationExecution(fedAmb) && getRtiIds() && 
          publishSubscribe() && registerMyCountry() )
      {
We need to join the federation execution.
   boolean joinFederationExecution(RTIcap.FederateAmbassador fedAmb)
   {

      boolean ret = false;

      if( rtiAmb != null )
      {

         try {
           rtiAmb.createFederationExecution("HelloWorld","HelloWorld.fed");
        } catch( RTIcap.FederationExecutionAlreadyExists icnd) {}
           catch( RTIcap.RTIinternalError ie) {}

         try {
           federateId = rtiAmb.joinFederationExecution(myCountryName,"HelloWorld",fedAmb);
             ret = true;
         } catch( RTIcap.FederateAlreadyExecutionMember fnem) {}
           catch( RTIcap.FederationExecutionDoesNotExist icnd) {}
           catch( RTIcap.CouldNotOpenFED fnem) {}
           catch( RTIcap.ErrorReadingFED fnem) {}
           catch( RTIcap.SaveInProgress sip) {}
           catch( RTIcap.RestoreInProgress rip) {}
           catch( RTIcap.RTIinternalError ie) {}

      }// end of if

      return ret;

   }// end of joinFederationExecution() 
Ask RTI to create a FederationExecution named as HelloWorld. RTI finds the HelloWorld.fed file and creates this federation execution according to those parameters (OMT definition) if this federation does not exist.

If it is, RTI send the proper exception (FederationExecutionAlreadyExists).

After we make sure that federation execution is defined somehow, then we need to register this instance with the FederateAmbassador object. If we can join this FederationExecution, then RTI gives a uniqe federate id as a return value.

Now we need to find out the exact object class ids, object attribute ids, interaction ids and parameter ids assigned by the RTI.

boolean getRtiIds()
   {
      boolean ret = false;

      if( rtiAmb != null )
      {
           try
           {
           countryTypeId = rtiAmb.getObjectClassHandle(countryTypeStr);
           } catch( RTIcap.FederateNotExecutionMember icnd ) {}
             catch( RTIcap.NameNotFound icnd ) {}
             catch( RTIcap.RTIinternalError icnd ) {}


           try
           {
           countryNameTypeId = 
                rtiAmb.getAttributeHandle(countryNameTypeStr,countryTypeId );
           } catch( RTIcap.ObjectClassNotDefined icnd ) {}
             catch( RTIcap.NameNotFound icnd ) {}
             catch( RTIcap.FederateNotExecutionMember icnd ) {}
             catch( RTIcap.RTIinternalError icnd ) {}

           try
           { 
           countryPopuTypeId = 
                  rtiAmb.getAttributeHandle(countryPopuTypeStr, countryTypeId );
           } catch( RTIcap.ObjectClassNotDefined icnd ) {}
             catch( RTIcap.NameNotFound icnd ) {}
             catch( RTIcap.FederateNotExecutionMember icnd ) {}
             catch( RTIcap.RTIinternalError icnd ) {}

        
           try
           { 
           countryCommTypeId = 
                  rtiAmb.getInteractionClassHandle(countryCommTypeStr);
           } catch( RTIcap.NameNotFound icnd ) {}
             catch( RTIcap.FederateNotExecutionMember icnd ) {}
             catch( RTIcap.RTIinternalError icnd ) {}

           try
           { 
           countryCommMsgTypeId = 
                 rtiAmb.getParameterHandle(countryCommMsgTypeStr,countryCommTypeId);
             ret = true;
           } catch( RTIcap.InteractionClassNotDefined icnd ) {}
             catch( RTIcap.NameNotFound icnd ) {}
             catch( RTIcap.FederateNotExecutionMember icnd ) {}
             catch( RTIcap.RTIinternalError icnd ) {}

           /** Place them into a hashtable */

      }// end of if
  
      return ret;

   }// end of getRtiIds()
Object classes, attributes, interaction classes and parameters are accessed with their names. These names are defined in the FED file (HelloWorld.fed).

First we ask the id of Country object class(getObjectClassHandle). Then we can get the id of attributes Name and Population(getAttributeHandle).

We do the same for interaction class Communication and its parameter Message with getInteractionClassHandle and getParameterHandle calls.

Since we know the each object and interaction class related information, we can define our interest about sending/receiving these object updates and interactions when they occur in the federatation execution.

boolean publishSubscribe()
   {

      boolean ret = false;

      if( rtiAmb != null )
      {
           short[] myAttributes = new short[2];  
           myAttributes[0] = (short) countryNameTypeId;
           myAttributes[1] = (short) countryPopuTypeId;

           try 
           {
             rtiAmb.subscribeObjectClassAttributes( countryTypeId, myAttributes , RTIcap._Boolean.RTI_TRUE);
           } catch( RTIcap.ObjectClassNotDefined  flsc) {}
             catch( RTIcap.AttributeNotDefined  fnem) {}
             catch( RTIcap.FederateNotExecutionMember  fnem) {}
             catch( RTIcap.RTIinternalError  ie) {}
             catch( RTIcap.RestoreInProgress  rip) {}
             catch( RTIcap.SaveInProgress  sip) {}

           try 
           {
             rtiAmb.publishObjectClass( countryTypeId, myAttributes );
           } catch( RTIcap.ObjectClassNotDefined  flsc) {}
             catch( RTIcap.AttributeNotDefined  fnem) {}
             catch( RTIcap.FederateNotExecutionMember  fnem) {}
             catch( RTIcap.RTIinternalError  ie) {}
             catch( RTIcap.RestoreInProgress  rip) {}
             catch( RTIcap.SaveInProgress  sip) {}

           try
           {
             rtiAmb.subscribeInteractionClass( countryCommTypeId, RTIcap._Boolean.RTI_TRUE);
           } catch( RTIcap.FederateLoggingServiceCalls  flsc) {}
             catch( RTIcap.FederateNotExecutionMember  fnem) {}
             catch( RTIcap.RTIinternalError  ie) {}
             catch( RTIcap.RestoreInProgress  rip) {}
             catch( RTIcap.InteractionClassNotDefined  icnd) {}
             catch( RTIcap.SaveInProgress  sip) {}

           try
           {
             rtiAmb.publishInteractionClass( countryCommTypeId );
             ret = true;
           } catch( RTIcap.FederateNotExecutionMember fnem) {}
             catch( RTIcap.RestoreInProgress rip) {}
             catch( RTIcap.InteractionClassNotDefined icnd) {}
             catch( RTIcap.SaveInProgress sip) {}
             catch( RTIcap.RTIinternalError ie) {}

      }// end of if

      return ret;

   }// end of publishSubscribe()

First we subscribe the object class (Country). This subscription will inform us all the instances of Country object in the federation execution and the value of their Name and Population attributes. It is possible to subscribe only a group of attributes instead of all of them. Then we inform RTI that we are going to publish an instance of Country object and we are going to provide the given attributes for this instance.

We subscribed for the interaction class (Communication) and all its parameters(subscribeInteractionClass). We informed the RTI that we are going to publish these interactions also(publishInteractionClass).

Now we told RTI what kind of messages we might produce and process. We need to define our simulation object and register it through RTI so that it can be perceived by other interested federates in the execution.

 boolean registerMyCountry()
   {
      boolean ret = false;
      int     objInstanceId;

      if( rtiAmb != null )
      {

         try 
         {
             objInstanceId = rtiAmb.registerObjectInstance(countryTypeId);
             myCountry = new SimCountry(rtiAmb,this,myCountryName,myPopulation,objInstanceId); 
             ret = true;

         } catch( RTIcap.ObjectClassNotDefined sip) {}
           catch( RTIcap.ObjectClassNotPublished sip) {}
           catch( RTIcap.SaveInProgress sip) {}
           catch( RTIcap.RestoreInProgress rip) {}
           catch( RTIcap.FederateNotExecutionMember icnd) {}
           catch( RTIcap.RTIinternalError ie) {}

      }// end of if

      return ret;

   }// end of registerMyCountry() 

We asked an object instance id from RTI so that RTI can define this object in its internal tables for us and sends the appropriate messages to other parties. For each update of the country object we are simulating, we inform RTI with this given object instance id so that RTI can accept this updates provided that we are allowed to this update for this object's attribute(Ownership Management).

We defined our intentions related to objects and interactions but we did not tell anything about the Time Management strategy we want to use. We have to decide whether we want to contribute the calculation of current time in the federation(enableTimeRegulation/disableTimeRegulation). Similarly, we have to decide whether we want to receive events in Time Stamp Ordered (TSO) or not(enableTimeConstrained/disableTimeConstrained);

        /*********************************************************************/
        /** TimeConstrained : we want to receive timestamped events in order */
        /*********************************************************************/
        resetTimeAdvanceGranted();

        try
        { 
          rtiAmb.enableTimeConstrained( );
        } catch( RTIcap.TimeAdvanceAlreadyInProgress aa ) {}
          catch( RTIcap.EnableTimeConstrainedPending aa ) {}
          catch( RTIcap.TimeConstrainedAlreadyEnabled aa ) {}
          catch( RTIcap.FederateNotExecutionMember aa ) {}
          catch( RTIcap.SaveInProgress aa ) {}
          catch( RTIcap.RestoreInProgress aa ) {}
          catch( RTIcap.RTIinternalError aa ) {}

        /***************************************************/
        /** Tick RTI to get timeConstrainedEnabled message */
        /***************************************************/
        tickRTI(2);

We want to receive events in TSO therefore we send enableTimeConstrained message. We tick the RTI to receive the result of this call.

        /**********************************************************/
        /** TimeRegulating : We want to vote for time advancement */
        /**********************************************************/
        resetTimeAdvanceGranted();

        try
        { 
          rtiAmb.enableTimeRegulation( currentTime, 5.0 );
        } catch( RTIcap.TimeAdvanceAlreadyInProgress aa ) {}
          catch( RTIcap.EnableTimeRegulationPending aa ) {}
          catch( RTIcap.ConcurrentAccessAttempted aa ) {}
          catch( RTIcap.TimeRegulationAlreadyEnabled aa ) {}
          catch( RTIcap.InvalidLookahead aa ) {}
          catch( RTIcap.InvalidFederationTime aa ) {}
          catch( RTIcap.FederateNotExecutionMember aa ) {}
          catch( RTIcap.SaveInProgress aa ) {}
          catch( RTIcap.RestoreInProgress aa ) {}
          catch( RTIcap.RTIinternalError aa ) {}

        /**************************************************/
        /** Tick RTI to get timeRegulationEnabled message */
        /**************************************************/
        tickRTI(2);
We want to contribute the time evaluation of the federation therefore we send enableTimeRegulation message. We tick the RTI to receive the result of this call. This also informs us about the current time in the federation.
        try
        { 
           rtiAmb.enableAsynchronousDelivery( );
        } 
          catch( RTIcap.FederateNotExecutionMember aa ) {}
          catch( RTIcap.AsynchronousDeliveryAlreadyEnabled aa ) {}
          catch( RTIcap.ConcurrentAccessAttempted aa ) {}
          catch( RTIcap.SaveInProgress aa ) {}
          catch( RTIcap.RestoreInProgress aa ) {}
          catch( RTIcap.RTIinternalError aa ) {}
We want to receive the messages if they do not have any time stamp.
        /**************************************************/
        /** Add my simulation object to the EntityManager */
        /**************************************************/
        EntityMng.add( myCountry.getObjectID(), myCountry );
Register our simulation object to the EntityManager. Note that EntityManager keeps the other simulated objects as well as the object simulated by this HelloWorld instance.

The following loop will be executed the number of times we provided from the command line. In this simulation loop we do the followings:

  1. Update the current time of the country so that it calculates the proper population.
  2. Prints the current known simulation objects in the federation.
  3. Calculates the new time value and asks RTI to advance the time and waits until it receives a proper response.
        /***************/
        /** Event Loop */
        /***************/
        while( count++ < MaximumNumberOfIterations )
        {
           /***************************************************/
           /** Simulate the current population for my country */
           /***************************************************/
           myCountry.UpdateTime(currentTime);

           /***************************************************************/
           /** Print state of all the simulated objects in the Simulation */
           /***************************************************************/
           printSimObjects();
       
           /*****************/
           /** Advance time */
           /*****************/
           resetTimeAdvanceGranted();
           requestTime = currentTime + timeStep;

           /************************************/
           /** Try to advance the current time */
           /************************************/
           do
           {

              try
              { 
                rtiAmb.timeAdvanceRequest( requestTime );
              } catch( RTIcap.TimeAdvanceAlreadyInProgress aa ) {}
                catch( RTIcap.EnableTimeConstrainedPending aa ) {}
                catch( RTIcap.EnableTimeRegulationPending aa ) {}
                catch( RTIcap.InvalidFederationTime aa ) {}
                catch( RTIcap.FederationTimeAlreadyPassed aa ) {}
                catch( RTIcap.FederateNotExecutionMember aa ) {}
                catch( RTIcap.SaveInProgress aa ) {}
                catch( RTIcap.RestoreInProgress aa ) {}
                catch( RTIcap.RTIinternalError aa ) {}

             mySleep(2);

           } while( !isTimeAdvanceGranted() );
           
        }// end of while()

Since the simulation loop is over we need to leave the federation and inform the RTI about our intention so that it can update its internal state.

        /************************************/
        /** Leave the Federation Execution  */
        /************************************/
        leaveFederationExecution();

      }// end of if 

   }// end of run()

Before we leave the federation we need to delete the simulation object we defined (deleteObjectInstance). Then we resign from the federation execution(resignFederationExecution) and try to destroy the federation execution(destroyFederationExecution). If we are the last federate, then federation execution will be destroyed.

void leaveFederationExecution()
   {

      if( rtiAmb != null )
      {

         try 
         {
           rtiAmb.deleteObjectInstance(myCountry.getObjectID(),"destroy");
         } catch( RTIcap.DeletePrivilegeNotHeld ie) {}
           catch( RTIcap.ObjectNotKnown ie) {}
           catch( RTIcap.FederateNotExecutionMember ie) {}
           catch( RTIcap.SaveInProgress ie) {}
           catch( RTIcap.RestoreInProgress ie) {}
           catch( RTIcap.RTIinternalError ie) {}

         try 
         {

           rtiAmb.resignFederationExecution(RTIcap.ResignAction.DELETE_OBJECTS_AND_RELEASE_ATTRIBUTES);
         } catch( RTIcap.InvalidResignAction ie) {}
           catch( RTIcap.FederateOwnsAttributes ie) {}
           catch( RTIcap.FederateNotExecutionMember ie) {}
           catch( RTIcap.RTIinternalError ie) {}

         try 
         {
           rtiAmb.destroyFederationExecution("HelloWorld");
         } catch( RTIcap.FederationExecutionDoesNotExist icnd) {}
           catch( RTIcap.FederatesCurrentlyJoined ie) {}
           catch( RTIcap.RTIinternalError ie) {}

      }// end of if

   }// end of leaveFederationExecution() 

Receiving/Sending Events From/To RTI

In the previous section we explained how you can start interact with RTI software but we did not explain how you can update the attributes of a simulated object or receive messages from RTI.

Sending Population Attribute Update

UpdateTime() method of SimCountry object is being called in each simulation loop.

public final void
UpdateTime( double time )
{
      double diff = time - currentTime;

      if( diff > 0 )
      {
         setCurrentTime(time);
       
         /*******************************/
         /** Set the population changed */
         /*******************************/
         setPopuChanged();
         UpdatePopulation(myPopulation+diff*grRate);

         UpdateName( getName() );

      }// end of if

}// end of Update()

This method updates the population and executes UpdatePopulation() and UpdateName() methods.

public final void
UpdatePopulation( double newPop )
{
      myPopulation = newPop ;

      /********************************************************************/
      /** If we are allowed to send this update and population is changed,*/ 
      /** then we will send this update message to the RTI.               */
      /********************************************************************/
      if( rtiAmb != null && sendPopuUpdateFlag && isPopuChanged() )
      {
           
          RTIcap.AttributeHandleValuePair[] eles = new RTIcap.AttributeHandleValuePair[1];
              
          eles[0] = new RTIcap.AttributeHandleValuePair(
                        boss.getPopuAttributeId(),
                        Double.toString(myPopulation).getBytes()); 
          try
          {   
            rtiAmb.updateAttributeValues(ObjectID,eles,"population");

            resetPopuChanged();

          } catch (RTIcap.ObjectNotKnown onk) {}
            catch (RTIcap.AttributeNotDefined onk) {}
            catch (RTIcap.AttributeNotOwned onk) {}
            catch (RTIcap.FederateNotExecutionMember onk) {}
            catch (RTIcap.SaveInProgress onk) {}
            catch (RTIcap.RestoreInProgress onk) {}
            catch (RTIcap.RTIinternalError onk) {}

      }// end of if

   }// end of Update()

If we need to send this update(sendPopuUpdateFlag) and the population is changed, then we send updateAttributeValues message to RTI. This message contains the object instance id, id of attribute and value of attribute (coded into a byte array).

RTI informs us whether it requires attribute update or not. Assume that we are the only participant of an execution or there is nobody who wants to receive our updates in an execution, then there is no point for us to send this update message and use the network. When RTI informs that update is required UpdateControls() method of SimCountry will be called.

Recieving Messages from RTI

FederateAmbassador object is defined for callback purposes so that RTI sends messages back to the federates via this object. It is the responsibility of the developer to handle each message properly.

We defined HwFederateAmbassador object which implements RTIcap.FederateAmbassador interface. We will try to explain each method we handled in this code.

Discovering New Object Instance

public void 
discoverObjectInstance(int theObject, short theObjectClass)
        throws RTIcap.CouldNotDiscover, RTIcap.ObjectClassNotKnown, 
               RTIcap.InvalidFederationTime, RTIcap.FederateInternalError
{ 
        Country c = entManager.getEntity(theObject);
        if(c==null) entManager.add(theObject,new Country(theObject));

}// end of discoverObjectInstance()

RTI send discoverObjectInstance message to federate whenever a new instance of a particular object class is defined. The first parameter gives the object id and the second gives the object class id.

Here we look at the EntityManager object whether this object is already discovered by us. If not, we defined a Country object for this new object and add it to EntityManager.

Removing Object Instance

Whenever an object instance removed from execution, RTI informs all the federates which received discover message before about this event by sending removeObjectInstance or removeObjectInstanceWithTime message.

public void 
removeObjectInstance(int theObject, String theTag)
        throws RTIcap.ObjectNotKnown, RTIcap.FederateInternalError
{ 
        Country c = entManager.getEntity(theObject);
        if(c!=null) entManager.remove(theObject);

}// end of removeObjectInstanceWith()

When we receive this message, we remove the representation of this object from the EntityManager.

Turn Updates On/Off For Object Instance

RTI sends turnUpdatesOffForObjectInstance message when the update of a particular attribute is no longer required.

public void 
turnUpdatesOffForObjectInstance(int theObject, short[] theAttributes)
        throws RTIcap.ObjectNotKnown, RTIcap.AttributeNotOwned, 
               RTIcap.FederateInternalError
{ 
        Country c = entManager.getEntity(theObject);
        if( c != null && c instanceof SimCountry ) 
            ((SimCountry)c).UpdateControls(false,theAttributes); 
}// end of turnUpdatesOffForObjectInstance()

Code asks EntityManager about the object and executes the UpdateControls() method of the SimCountry object. This will disable the attribute updates for the given object.

Provide Attribute Updates For Object Instance

When the update of an attribute is required by somebody in the federation, RTI sends this message to the owner of that attribute. It is the responsibility of the owner to provide the update.

public void 
provideAttributeValueUpdate(int theObject, short[] theAttributes)
        throws RTIcap.ObjectNotKnown, RTIcap.AttributeNotKnown, 
               RTIcap.AttributeNotOwned, RTIcap.FederateInternalError
{ 
        Country c = entManager.getEntity(theObject);

        if(c!=null && c instanceof SimCountry )
        {
           for(int i=0;i < theAttributes.length;i++)
            if( theAttributes[i] == boss.getNameAttributeId() )
                ((SimCountry)c).setNameChanged();
            else if( theAttributes[i] == boss.getPopuAttributeId() )
                ((SimCountry)c).setPopuChanged();

        }// end of if

}// end of provideAttributeValueUpdate()

Code informs the SimCountry object to send the update of the particular attribute.

Receiving Attribute Updates

Whenever RTI receives an update of an object attribute, it sends the reflectAttributeValues message to interested participants(suscribers).

public void 
reflectAttributeValues(int theObject, 
               RTIcap.AttributeHandleValuePair[] theAttributes, String theTag)
        throws RTIcap.ObjectNotKnown, RTIcap.AttributeNotKnown, 
               RTIcap.FederateOwnsAttributes, RTIcap.FederateInternalError
{ 
        Country c = entManager.getEntity(theObject);

        if( c != null ) 
        {
           for(int i=0;i < theAttributes.length;i++)
           {
              if( theAttributes[i].handle == boss.getNameAttributeId() )
                  c.setName(new String(theAttributes[i].value));
              else if( theAttributes[i].handle == boss.getPopuAttributeId()
)
                      c.setPopulation(Double.valueOf(new String(theAttributes[i].value)).doubleValue());

           }// end of for

        } else System.out.println(theObject+" is not known ");

}// end of reflectAttributeValues()

First we find the proper Country object in the EntityManager. According to the handle of attribute, we update Name or Population attributes.

List Of Source Files


Prepared by : H. Timucin Ozdemir
Date : July 01, 1998