Writing Java code to capture details of code generation

You can now write Java™ code to produce a report or otherwise respond to events at generation time.
The product provides the following code in the plugin named com.ibm.etools.egl plugin, in the package named com.ibm.etools.egl.genresults:
The product classes call the following methods in your listener:
Here is an order of calls that might occur during a generation:
generationStarted
   phaseStarted
      warning
      generatingPart
         createdArtifact
         warning
         createdArtifact
         createdArtifact
      generatingPart
         warning
      generatingPart
         createdArtifact
         information
   phaseFinished
   phaseStarted
      generatingPart
         createdArtifact
      generatingPart
      generatingPart
         createdArtifact
   phaseFinished
generationFinished
In general, do as follows:
  1. Write a class to implement the GenerationResultsListener interface, which is described in the following section: Interface details.
  2. Instantiate the class to create the listener, then register the listener to the EGL generator. Here is an example:
    MyListenerClass myListenerObject = new MyListenerClass();
    com.ibm.etools.egl.genresults.GenerationResultsServer.
       getInstance().addListener(myListenerObject);

    The second statement has these effects:

    1. Obtains a GenerationResultsServer object by invoking the static getInstance method of that class.
    2. Passes the listener named myListenerObject to the addListener method of the GenerationResultsServer object.

    You can deregister the listener by passing it to the removeListener method of the GenerationResultsServer object.

For details on the task, see the section that meets your need:

Interacting with the workbench

If you are interacting with the workbench, you need to create a plugin that registers a generation results listener. In addition, you need to override a default behavior of the Eclipse runtime code, which typically loads a plugin only when the plugin is needed by a previously loaded plugin.

Do as follows:
  1. Put your code into a plugin, updating the MANIFEST.MF file so that your plugin depends on the following plugins:
    • com.ibm.etools.egl, which is in the product installation directory.
    • org.eclipse.ui.
  2. Create a class that implements org.eclipse.ui.IStartup, which is a Java interface that has only one method, earlyStartup. Your implementation of earlyStartup registers your listener object, as in the following example:
    package com.ibm.test.egl.genresults.listener;
    
    import org.eclipse.ui.IStartup;
    import com.ibm.etools.egl.genresults.GenerationResultsServer;
    
    public class StartupClass implements IStartup
    {
       public void earlyStartup()
       {
          GenerationResultsServer.getInstance().addListener(new TestListener(true));
       }
    }
  3. Include the following entry in the plugin.xml file:
    <extension point="org.eclipse.ui.startup">
       <startup class="com.ibm.test.egl.genresults.listener.StartupClass"/>
    </extension>
  4. Export the plugin to a jar file as follows:
    1. Click File > Export. The Export page opens.
    2. Under Select an export destination, expand Plug-in Development and click Deployable plug-ins and fragments. The Deployable plug-ins and fragments page opens.
    3. In the middle of the page, on the Destinations tab, specify the Eclipse dropins folder; for example, C:\Program Files\IBM\SDP80\dropins.
    4. Click the Options tab and ensure that Package plug-ins as individual JAR archives is selected.
    5. Click Finish. The jar file is in the dropins folder, in a plugins folder.
    6. Open Windows Explorer and go to the plugins folder.
    7. Move the new jar file so that it is directly in the dropins folder.
    8. Delete the empty plugins folder.

Using the workbench batch interface (EGLCMD)

If you are using the workbench batch interface (EGLCMD), do as follows:
  1. Create a plugin.
  2. Update the MANIFEST.MF file so that your plugin depends on the com.ibm.etools.egl plugin, which is in the product installation directory.
  3. Ensure that your plugin references the extension point named org.eclipse.core.runtime.applications, as in the following example code in a plugin.xml file:
    <extension id="TestCMD" point="org.eclipse.core.runtime.applications">
       <application>
          <run class="com.ibm.test.egl.genresults.listener.TestCMD"></run>
       </application>
    </extension>

    The value of the id attribute can be any that you assign.

    The value of the class attribute identifies a class that implements the Eclipse IApplication interface, registers a GenerationResultsListener object, and passes the command-line arguments to the com.ibm.etools.edt.core.ide.batch.EGLCMD.process method. Here is an example of such a class:
    package com.ibm.test.egl.genresults.listener;
    
    import org.eclipse.equinox.app.IApplication;
    import org.eclipse.equinox.app.IApplicationContext;
    import com.ibm.etools.edt.core.ide.batch.EGLCMD;
    import com.ibm.etools.egl.genresults.GenerationResultsServer;
    
    public class TestCMD implements IApplication
    {
       @Override
       public Object start( IApplicationContext appContext ) throws Exception
       {
          // Register a GenerationResultsListener.
          GenerationResultsServer.getInstance().addListener(new TestListener(true));
    
    	      // Get the command-line arguments.
          String[] args = (String[])appContext.getArguments().
                                    get( IApplicationContext.APPLICATION_ARGS );
    
          // Pass the command-line arguments to EGLCMD.
          EGLCMD.process( args );
          return null;
       }
    
       @Override
       public void stop()
       {}
    }
  4. Export the plugin to a jar file as follows:
    1. Click File > Export. The Export page opens.
    2. Under Select an export destination, expand Plug-in Development and click Deployable plug-ins and fragments. The Deployable plug-ins and fragments page opens.
    3. In the middle of the page, on the Destinations tab, specify the Eclipse dropins folder; for example, C:\Program Files\IBM\SDP80\dropins.
    4. Click the Options tab and ensure that Package plug-ins as individual JAR archives is selected.
    5. Click Finish. The jar file is in the dropins folder, in a plugins folder.
    6. Open Windows Explorer and go to the plugins folder.
    7. Move the new jar file so that it is directly in the dropins folder.
    8. Delete the empty plugins folder.
  5. Make sure that your Java classpath provides access to the following jar files:
    • org.eclipse.equinox.launcher_version.jar, which is in the following directory:
      installationDir\sdp70\plugins
      installationDir
      The product installation directory, such as C:\Program Files\IBM.

      Please note that the directory is not the shared one.

    • com.ibm.etools.edt.core.ide.version, which is in the following directory:
      installationDir\sdp70shared\plugins
      installationDir
      The product installation directory, such as C:\Program Files\IBM.
  6. Invoke the application as follows:
    java org.eclipse.core.launcher.Main -application 
       test.genresults.listener.TestCMD argument_list

    In place of argument_list, substitute the arguments that are documented in the “EGLCMD” reference topic.

    In this example, test.genresults.listener is the name of the plugin, and TestCMD is the value of the id attribute of the <extension> element in plugin.xml.

Using the EGL Software Development Kit (EGLSDK)

If you are using the EGL Software Development Kit (EGLSDK), you need to write your own Java class and run it in place of the EGLSDK command:
  1. Set classpaths so that the eglbatchgen.jar file is available:
    • When you are developing your code, the eglbatchgen.jar file must be in the classpath of the Java compiler.
    • When you are running the code, the eglbatchgen.jar file must be in your CLASSPATH system variable.

    For details on the location of the eglbatchgen.jar file and other prerequisites, see “Generation using the EGL Software Development Kit.”

  2. Register an object of type GenerationResultsListener and create an EGLSDK object, as in the following example:
    package example;
    
    import com.ibm.etools.egl.genresults.GenerationResultsServer;
    import com.ibm.etools.egl.util.EGLSDK;
    
    public class EGLSDKWithListener
    {
       public static void main( String[] args )
       {
          MyListenerClass myListenerObject = new MyListenerClass();
          GenerationResultsServer.getInstance().addListener(myListenerObject);
          EGLSDK sdk = new EGLSDK();
          sdk.process( args );
       }
    }
  3. Run your class in place of the EGLSDK command, using the same arguments as if you were invoking the EGLSDK command.
    Here are details on the EGLSDK class that you instantiate:
    public class EGLSDK
    {
       /* Creates an EGLSDK object that does not print messages to System.out. */
       public EGLSDK();
    
       /* Creates an EGLSDK object that might print messages to System.out.
        *
        * @param printMessages   true if messages should be printed to System.out.
       */
       public EGLSDK(boolean printMessages);
       
       /*
        * Generates EGL.
        *
        * @param args are the EGLSDK command-line arguments.
       */
       public void process(String[] args);
       
       /*
        * Returns the messages from the most recent call of process(String[]).
        *
        * @return the messages.  The array may be empty but will not be null.
       */
       public Message[] getMessages();
    
       /*
        * Indicates if there were any errors during generation.
        *
        * @return true if any errors occurred
        *              in the most recent call of process(String[]).
        */
        public boolean generationFailed();
    }
    Here is the Message class referenced in the EGLSDK class:
    package com.ibm.etools.egl.util;
    
    public class Message
    {
       public static final int ERROR_MESSAGE = 1;
       public static final int WARNING_MESSAGE = 2;
       public static final int INFORMATIONAL_MESSAGE = 3;
    
       public String getText();
       public int getSeverity();
       public boolean isError();
    }

Interface details

Here is the GenerationResultsListener interface:
public interface GenerationResultsListener
{
   // Called when generation starts
   void generationStarted( GenerationStartedEvent gse );

   // Called when generation ends
   void generationFinished();

   // Called when a generation phase starts
   void phaseStarted( GenerationPhase gp );

   // Called when a generation phase ends
   void phaseFinished();

   // Called when generation of a part begins
   void generatingPart( PartGenerationEvent event );

   // Called after one generated output is created for the part
   // during the most recent event of type PartGenerationEvent
   void createdArtifact( ArtifactCreatedEvent event );    

   // Called when an error message is issued
   void error( MessageEvent event );
    
   // Called when a warning message is issued.
   void warning( MessageEvent event );
    
   // Called when an informational message is issued.
   void information( MessageEvent event );
}
Here are the additional Java interfaces:
public interface GenerationStartedEvent
{
   /**
    * Returns true if generation is running in the workbench or EGLCMD,
    * false if generation is running in EGLSDK.
    */
   boolean generatingInEclipse();
   
   /**
    * Returns the path to the Eclipse workspace if generation is running
    * in the workbench or EGLCMD.  Returns the eglpath value if generation 
    * is running in EGLSDK.
    */
   String getWorkPath();
}

public interface GenerationPhase
{
   /**
    * Returns a Part object (explained later) 
    * that gives details on the build descriptor.
   */
   Part getPart();
}

public interface PartGenerationEvent
{
   /**
    * Returns a Part object that gives details on the part being generated.
    */
   Part getPart();
}

public interface ArtifactCreatedEvent
{
   /**
    * Returns the path to a file generated from the part.  
    * The path is relative to the Eclipse workspace if generation 
    * is running in the workbench or EGLCMD and if the artifact was generated
    * into a project named by the genProject option in the build descriptor.  
    *
    * In other cases, the path is an absolute path in the file system.
    */
   String getFileName();

   /**
    * Returns the absolute path to a file generated from the part.
    * (The method returns the same value as getFileName if generation 
    * is running in EGLSDK or if the artifact was not generated into a project.)
    */
   String getAbsolutePath();
}
public interface Part
{
   static final int BUILD_DESCRIPTOR = 1;
   static final int DEPLOYMENT_DESCRIPTOR = 2;
   static final int PROGRAM = 3;
   static final int LIBRARY = 4;
   static final int HANDLER = 5;
   static final int RECORD = 6;
   static final int DATA_TABLE = 7;
   static final int FORM_GROUP = 8;
   static final int SERVICE = 9;
   static final int DELEGATE = 10;
    
   /**
    * 
    * Returns the constant identifying the kind of part 
    * that has been generated.
    */
   int getKind();

   /**
    * Returns the name of the part.
    */
   String getName();
   
   /**
    * Returns the package name of the part. 
    * If the part is in the default package, an empty string is returned.  
    * If the part represents a build descriptor or deployment descriptor, 
    * the method returns null.
    */
   String getPackageName();

   /**
    * Returns the path to the EGL file for the part. The path is relative to the 
    * Eclipse workspace if generation is running in the workbench or EGLCMD. The path
    * is an absolute path in the file system if generation is running in EGLSDK.
    */
   String getFileName();

   /**
    * Returns the absolute path to the EGL file for the part.  
    * (This method returns the same value as getFileName 
    * if generation is running in EGLSDK.)
    */
   String getAbsolutePath();
}

public interface MessageEvent
{
   static final int ERROR = 1;
   static final int WARNING = 2;
   static final int INFORMATION = 3;
    
   /**
    * Returns INFORMATION, WARNING, or ERROR.
    */
   int getKind();

   /**
    * Returns the text of the message.
    */
   String getText();
   
   /**
    * Returns the ID of the message.
    */    
   String getID();
}

Feedback