Developing plug-ins in Java for Gen Toolset

Overview

CA Gen allows applications to access the currently opened model through a mechanism that is known as a plug-in. The application should register itself in the Windows registry, and from there the CA Gen toolset knows how to call it. Toolset adds a menu item to the CA Gen “Plug-in” menu. The developer starts plugin from the toolset after Toolset opens model for processing.

You will find more information about CA Gen Toolset Automation here.

However, there is a problem when you are willing to develop something in Java language. The problem is because the plug-in application should instantiate a pointer to the currently opened toolset using the toolset OLE automation interface. Such interface allows the application to access the functionality provided by the interface. Unfortunately,  Java program cannot do it without using some software bridging those two different technologies.

Fortunately, Eclipse is using the SWT GUI framework. SWT does allow to integrated Microsoft application via OLE (Object Linking and Embedding). You can locate jar file org.eclipse.swt.win32.win32.x86_3.3.0.v3346.jar in the subdirectory of your Eclipse installation. Subdirectory name is  plugin.

It has the SWT Win32 OLE implementation classes. Classes provide the public API to the Microsoft Win32 Object Linking and Embedding mechanism that the win32 variant of SWT is capable of using. Referencing any of the classes in this package directly guarantees that the code is platform specific.

You can consult tutorial “Microsoft and Java Integration with Eclipse” written by Lars Vogel here. It helps understand the SWT Win32 OLE implementation classes and shows examples of the use.

Idea developing plugs using Java resulted in the need for some easier ways to access the Gen model and hide the complexity of the SWT Win32 OLE implementation classes. The Toolset Automation Wrapper is a package of Java classes doing just that. The Toolset Automation Wrapper does not cover all functionality offered by the Toolset Automation.

You can download Java documentation and jar file with the wrapper classes here.

You can find Eclipse project on GitHub here.

Sample Application

Sample application connects to the currently opened model in the CA Gen Toolset and lists all business systems defined in the model. The application is a simple Java class with the method main().  You need to run the application from the command line. Yon need be sure that you have two jar files on the classpath. They are jmmi and ToolsetAutomationWrapper.

Here is the source of the application:

package eu.jgen.notes.automation.example;

import com.ca.gen.jmmi.schema.ObjTypeCode;
import com.ca.gen.jmmi.schema.ObjTypeHelper;
import com.ca.gen.jmmi.schema.PrpTypeCode;
import com.ca.gen.jmmi.schema.PrpTypeHelper;

import eu.jgen.notes.automation.wrapper.JGenEncyclopedia;
import eu.jgen.notes.automation.wrapper.JGenFactory;
import eu.jgen.notes.automation.wrapper.JGenModel;
import eu.jgen.notes.automation.wrapper.JGenObject;

public class ListAllBusinessSystems {

	public static void main(String[] args) {
		// create instance of the factory class
		JGenFactory factory = JGenFactory.eINSTANCE;

		// create instance of the encyclopedia
		JGenEncyclopedia ency = factory.createEncyclopedia();

		// connect to the encyclopedia (model needs to be opened in the toolset
		// already)
		ency.connect();

		// select model for processing
		JGenModel genModel = ency.findModels()[0];
		System.out.println(genModel.getName());

		// find all business system in the model
		JGenObject[] bussyss = genModel.findTypeObjects(ObjTypeHelper.getCode(ObjTypeCode.BUSSYS));
		for (JGenObject bussys : bussyss) {
			System.out.println(bussys.findTextProperty(PrpTypeHelper.getCode(PrpTypeCode.NAME)));
		}
	}

}


The application will print the following messages on the console for the sample.ief model which is coming with the standard CA Gen installation on the workstation.

GEN SAMPLE MODEL 8 6
CORPORATE_MANAGEMENT
GUI_CORPORATE_MANAGEMENT
COOP_CORPORATE_MANAGEMENT

Summary

Solution and sample application have been developed using the following software:

  • Windows 10
  • CA Gen 8.6 (Free)
  • Java Version 8 (Update 20)
  • Eclipse Neon.3 Release (4.6.3)

Researching  contents of  local model using JGen Notes Walkency

CA Gen Documentation provides Encyclopedia API Reference which is place providing a lot of information about internal of the CA Gen model and metamodel which describes a structure of the model. Metamodel shows the properties and object associations that are inherited and from which objects they are inherited. The metamodel is the CA Gen Information Model. Additionally, you will find in your CA Gen installation directory file with published Object Decomposition Report presented in a hierarchical format. Name of the file is odrpta. This is the Microsoft’s standard help format (chm).

odr

 You will find here a link to the web page describing utility allowing explore the internal structure of the local model on the workstation easily and comprehensively.  Its name Walkency refers to traditional tools used to display contents of the model stored in the Host Encyclopedia (HE) and Client Server Encyclopedia (CSE). JGen Notes Walkency is the reincarnation of such tool dedicated for the developers using the CA Gen Toolset. JGen Notes Walkency is written entirely in Java and developed as Eclipse Rich Client.

Technically, from the CA Gen Toolset perspective, JGen Notes Walkency is a plug-in registered with the CA Gen Toolset and available for use when selected from the menu system of the CA Gen Toolset.

Zrzut ekranu 2017-06-19 o 20.15.17

Developing utility generating applications from the CA Gen model

Overview

This blog entry focuses on explaining some hidden possibilities to activate the generation process using the CA Gen JMMI API. Selecting generation dialog from the Gen Toolset or Gen Studio is commonly known as the only way to trigger generation process, but CA Gen JMMI API allows controlling generation process outside the Toolset by developing your own utilities that can run online or in batch mode depending on your needs.

It makes sense to mention that historically the CA Gen Toolset was designed allowing the full cycle of the development, starting from the designing model, generating code in a number of the programming languages, allows building applications for some hardware and software platforms. This also includes dispatching packaged applications to the various operating systems and build them using native tools available on the target platform.

An integral part of the development cycle includes generating source code that can later be delivered and built in many different various target environments. Also, the CA Gen Toolset running on the Windows platform is not the only place where source code can be generated from the Gen Model. Please consult the CA Gen documentation to discover many possibilities that this software offers.

Standard generation process starts by selecting toolset dialog offering selection of the generation choices. This offers a selection of the operating system, programming language, transaction processing environment and database to mention few options. The whole process is under control of the toolset and strictly regulated and it has to be triggered manually from the workstation.

The generation process is implemented internally by a number of utilities that are triggered by the CA Gen Toolset transparently to the developer. Usually, the Gen Build Tools is activated later to start building application or performs packaging of the deliverables so packages of the generated source code can be transferred to one of many target platforms to complete building process. Those utilities are considered by the CA as internal and they are not documented so should not be used by the inexperienced developer.

The CA Gen JMMI API is quite elaborate and complex solution. We are going to focus only on the specific fragment of the API that deals with the generation process.

We are going to walk thru the sample utility built using JMMI API. Our simple utility will open selected local model and will generate code in Java and use JDBC as an access method to the database for the selected action block. Utility stores generated code at the location provided by the user.

The utility will be developed in Java and run from the command line taking a number of parameters. We are using Eclipse project for the development and project you can download from the Github here.

JMMI API

The CA Gen JMMI API is a hidden treasure. You will not find any part of the official documentation manual explaining how JMMI API works and how it can be used. There is a dedicated manual called Encyclopedia API Reference, but the JMMI API is not mentioned there. It is strange because the whole CA Gen Studio which is an Eclipse-based Java application is using JMMI API as the main way to access local model kept on the workstation.  Fortunately, you will find basic Java type of documentation in one of the CA Gen Toolset installation directories. There are not too many rich explanatory comments, but nicely crafted name for classes and methods allows to be familiar with the API very quickly.

Here is where you find your JMMI API.

Zrzut ekranu 2017-06-16 o 19.21.00

The CA Gen JMMI API is a really clever number of classes and methods are mostly native and implemented in C++ that can be executed only on the workstation running Window operating system, so you cannot port an application using JMMI API to any other platform. The CA Gen JMMI API can only access local models, but it looks like is designed to provide remote access to CA Gen encyclopaedias (Client Server Encyclopedia and Host Encyclopedia)in the future as well.

The JMMI provides a lot of classes, but we focus on only few of them. They are as follows:

  • com.ca.gen.jmmi.Generation
  • com.ca.gen.jmmi.GenerationData
  • com.ca.gen.jmmi.GenerationData

Soample utility explained

Our utility is very simple. This is a Java class run from the command line and accepting a number arguments. In its simplest form you can start application as follows:

java ABGenerate -j "C:\jgen.notes.models\sample.ief" "c:\temp" "FILE_FUNCTIONS_READ"

You specify location of your local model, location for generated source code and name of the action block to be generated.

The below snapshot of the code shows processing of the input arguments and what part of the application is responsible for the executing requests.

	public static void main(String[] args) {
		ABGenerate utility = new ABGenerate();
		try {
			System.out.println("Action Block Generaion Utility, Version 1.0");
			if(args.length == 0) {
				displayHelp();
			}
			if(args.length == 1 && args[0].equals("-h")) {
				displayHelp();
				return;
			}
			if(args.length == 4 && args[0].equals("-j")) {
				utility.start(args[1], args[2], args[3]);
				System.out.println("Completed.");
				return;
			}
		if(args.length == 2 && args[0].equals("-o")) {
			utility.options(args[1]);
			System.out.println("Completed.");
			return;
		}			
			displayHelp();
		} catch (EncyException e) {
			e.printStackTrace();
		} catch (ModelNotFoundException e) {
			e.printStackTrace();
		}
	}

	private static void displayHelp() {
		System.out.println("Usage: java ABGenerate [  ]");
		System.out.println("\toptions:");
		System.out.println("\t\t-h help");
		System.out.println("\t\t-j to generate for Java and   ");
		System.out.println("\t\t-o to display generation choices for ");
	}

The main function of the application starts here and will be explain step-by-step.

	private void start(String modelpath, String sourcepath, String abname)
			throws EncyException, ModelNotFoundException {
		openModel(modelpath);
		System.out.println("Generating action block " + abname + " into " + sourcepath + "\\" + JAVA_SUBDIRECTORY);
		generate(findActionBlock(abname), sourcepath, abname);
		closeModel();
	}	
	private void openModel(String modelpath) throws EncyException, ModelNotFoundException {
		ency = EncyManager.connectLocal(modelpath);
		model = ModelManager.open(ency, ency.getModelIds().get(0));
		System.out.println("Openning " + model.getName());
	}

	private void generate(long id, String sourcepath, String abname) {
		generation = GenerationManager.getInstance(model);
		generateActionBlock(id, sourcepath);
	}

	private void generateActionBlock(long id, String sourcepath) {
		generation.generateActionBlock(generation.getModelContext(), id, sourcepath, JAVA_SUBDIRECTORY, "ABC", "JVM",
				"JDBC", "INTERNET", "JAVA", "NO", "JAVAC", "YES");
	}

	private long findActionBlock(String abname) {
		ObjId objId = model.getObjIdByName(ObjTypeCode.ACBLKBSD, PrpTypeCode.NAME, abname);
		return objId.getValue();
	}

	private void closeModel() {
		model.close();
		ency.disconnect();
	}

  1. The first task is to open model. Class EncyManager has a static method connectLocal()allowing to connect to the encyclopedia. It is a little bit misleading because we are really connecting to the single local model which is not kept in the encyclopedia.
  2. Class ModelManager has the static method open()allowing to open selected model. An instance of the class Model is now available and represent a real model. Again, there is only one model at the chosen connection so we are going to pick the first one.
  3. We can start generation process once the model is selected and opened. We need to obtain an instance of the generator first.
  4. Class Generation has dedicated methods to perform a specific type of generation. We are going to use generateActionBlock().

These methods performing generation takes a number of parameters representing generation choices. You can display possible choices for the type of generation using this utility by starting it as follows:

java ABGenerate -j "C:\jgen.notes.models\sample.ief"
Here is the code printing possible generation choices.
	private void displayGenerationOptions() {
		generation =  GenerationManager.getInstance(model);
		operatingSystemsChoices();
		languagesChoices();
		databaseChoices();
		tpmonChoices();
		compilerChoices();
		communicationChoices();
	}

	private void operatingSystemsChoices() {
		System.out.println("Operating System  Choices:");
		for (GenerationData generationData : generation.getOperatingSystemsChoices()) {
			System.out.println("\t" +generationData.getGenerationDataKey() + "= " + generationData.getGenerationDataValue());
		}
	}
	
	private void databaseChoices() {
		System.out.println("Database Choices:");
		for (GenerationData generationData : generation.getDatabaseChoices()) {
			System.out.println("\t" +generationData.getGenerationDataKey() + "= " + generationData.getGenerationDataValue());
		}
	}
	
	private void tpmonChoices() {
		System.out.println("Tpmon Choices:");
		for (GenerationData generationData : generation.getTpmonChoices()) {
			System.out.println("\t" +generationData.getGenerationDataKey() + "= " + generationData.getGenerationDataValue());
		}
	}

	private void compilerChoices() {
		System.out.println("Compiler Choices:");
		for (GenerationData generationData : generation.getCompilerChoices()) {
			System.out.println("\t" +generationData.getGenerationDataKey() + "= " + generationData.getGenerationDataValue());
		}
	}
	
	private void communicationChoices() {
		System.out.println("Communication Choices:");
		for (GenerationData generationData : generation.getCommunicationChoices()) {
			System.out.println("\t" +generationData.getGenerationDataKey() + "= " + generationData.getGenerationDataValue());
		}
	}
	
	private void languagesChoices() {
		System.out.println("Language Choices:");
		for (GenerationData generationData : generation.getLanguageChoices()) {
			System.out.println("\t" +generationData.getGenerationDataKey() + "= " + generationData.getGenerationDataValue());
		}
	}

Our simple utility produces a couple messages at the completion of the job.

Action Block Generaion Utility, Version 1.0
Openning GEN SAMPLE MODEL 8 6
Generating action block FILE_FUNCTIONS_READ into c:\temp\sources
Completed.

You will find also a text file cgdebug.err created and summarizing what has been generated.

abg.exe, c:\temp\sources\java, JVM, JDBC, INTERNET, JAVA, JAVAC, OFF, *, *, ABC, *, *, *, *, YES.
ABG generating Encyid: 22020096
os       JVM
lang     JAVA
dbms     JDBC
compiler JAVAC
tpmon    INTERNET
MBCS set code page ID: 1252.
Starting Action Block Generator
Generated 1136 lines of Java.
Writing output file: c:\temp\sources\java\com/ca FILEFUNC.java
Wrote 548 lines.
Writing output file: c:\temp\sources\java\com/ca FILEFUNC_IA.java
Wrote 211 lines.
Writing output file: c:\temp\sources\java\com/ca FILEFUNC_OA.java
Wrote 177 lines.
Writing output file: c:\temp\sources\java\com/ca FILEFUNC_LA.java
Wrote 114 lines.

Summary

The sample application has been developed using the following software:

  • Windows 10
  • CA Gen 8.6 (Free)
  • Java Version 8 (Update 20)
  • Eclipse Neon.3 Release (4.6.3)

You can find project files here.