Building J2C beans using Ant scripts

You can use Ant scripts to invoke J2C components, and these Ant scripts can be called from the workbench or from the command line.

Before you begin

In some situations, you might want to recreate the J2C beans or data binding beans (for example, if your COBOL copybook adds a new field). You can recreate your J2C beans using an Ant definition file that mimics the interaction between the user and the underlying J2C components.

About this task

You can use the J2C wizards to create an Ant configuration file by capturing your selections and entered values. Since an Ant configuration file is essentially an XML file, it can be modified or built entirely by hand.

An Ant configuration file consists of a target tree where various tasks are run. Tasks within a target are processed in a pipeline fashion. Each task is run by an object that implements a particular task interface. When the Ant configuration file is invoked, properties corresponding to each task are loaded into the implementing task objects. After the information is loaded the task object is invoked.

Data discovery task

In general, a discovery cycle has two steps, each of which is done by a distinct component:
  • Discovery agents perform the actual import of data (see performImport task in the example script) to produce proprietary metadata that is called the import result.
  • Resource writers consume the import result (seethe writeToWorkspace task in the example script) to produce appropriate application artifacts.
During the import and generation steps, the discovery agent and the resource writer requires a set of user input to be provided. For example, in the Query phase, each discovery agent has a different set of parameters that are used to define a query on the corresponding metadata repository. The discovery agent and the resource writer can be paired in various ways to import and generate the artifact you want. They are identified by their name (QName). For example, the Cobol discovery agent can by identified by the following name: {com/ibm/adapter}CobolDiscoveryAgent
The following example script shows how to generate the J2C Java™ interface, J2C Java implementation and the data binding classes based on the taderc99.cbl COBOL file and importing the ECIResourceAdapter version 6.0.2.
<adapter:discover>
	<adapter:performImport agent="{com/ibm/adapter}CobolDiscoveryAgent">
		<adapter:importResource>
			<adapter:propertyGroup name="CobolFileGroup">
				<adapter:propertyElement name="CobolFile" value="/${project}/taderc99.ccp"/>
			</adapter:propertyGroup>
		</adapter:importResource>
		<adapter:queryProperties>
			<adapter:propertyGroup name="ImportProperties">
				<adapter:propertyElement name="Platform" value="Win32"/>
			</adapter:propertyGroup>
		</adapter:queryProperties>
		<adapter:queryResult>
			<adapter:selectElement name="DFHCOMMAREA"/>
		</adapter:queryResult>
	</adapter:performImport>
	<adapter:writeToWorkspace writer="{com/ibm/adapter/cobol/writer}JAVA_WRITER">
		<adapter:propertyGroup name="COBOLToJavaResourceWriter">
			<adapter:propertyElement name="GenerationStyle" value="0"/>
			<adapter:propertyGroup name="Java Type Name">
				<adapter:propertyElement name="Overwrite existing class" value="true"/>
				<adapter:propertyElement name="Project Name" value="${project}"/>
				<adapter:propertyElement name="Package Name" value="com.ibm.test"/>
				<adapter:propertyElement name="Class Name" value="Taderc99"/>
			</adapter:propertyGroup>
		</adapter:propertyGroup>
	</adapter:writeToWorkspace>
</adapter:discover>

Procedure

  1. Example of the Import section of the Ant script:
    <discoveryAgent type="DiscoveryAgentName">
    		<importResource name="PropertyName" value="PropertyValue"/>
    		<importProperties>
    			<propertyElement name="PropetyName" value="PropertyValue"/>
    		</importProperties>
    		<searchParameters>
    			<propertyElement name="ParameterName"/>
    		</searchParameters>
    </discoveryAgent>
    Where:
    • discoveryAgent is the name of the discovery agent to be used for import
    • importResource is the resource to be imported
    • queryProperties is a list of parameters that represent the information required to form a query against the metadata repository
    • searchParameters is the select nodes on the result tree that you want to import as application artifacts
    • propertyElement is a list (pairs of property name and property value)
  2. In order to generate the application artifact, a resource writer that knows to consume the imported result is invoked. For instance, after a COBOL import only a writer that knows to consume the COBOL type import result can be used. The write section of the Ant script looks like this:
    <adapter:writeToWorkspace writer="{com/ibm/adapter/cobol/writer}JAVA_WRITER">
    <adapter:propertyGroup name="COBOLToJavaResourceWriter">
    <adapter:propertyGroup name="Java Type Name">
    <adapter:propertyElement name="Project Name" value="${project1}"/>
    <adapter:propertyElement name="Package Name" value="sample.cics"/>
    <adapter:propertyElement name="Class Name" value="DFHCOMMAREA"/>
    </adapter:propertyGroup>
    </adapter:propertyGroup>
    </adapter:writeToWorkspace>
    Where:
    • workspaceResourceWriter is the name of the writer used to generated the application artifacts.
    • propertyElement is a list of property name and property value pairs that the writer uses for generation.
  3. In the special case of the language import (COBOL, C and PL/I) there is an additional step, which is binding generation. The binding section of the Ant script looks like this:
    <createBinding package="PackageName" class="ClassName">
        <methodElement>
            <name value="MethodName"/>
            <input value="Input"/>
            <output value="Output"/>
            <interactioSpec>
                <propertyElement name="PropertyName" value="PropetyValue"/>
            </interactioSpec>
        </methodElement>
        <connectionSpec>
            <propertyElement name="PropertyName" value="PropertyValue"/>
        </connectionSpec>
        <resourceAdapter project="ResourceAdapterProjectName"/>
    </createBinding>
  4. The resourceAdapter can also be defined in the following way:
    <resourceAdapter>
         <propertyElement name="displayName" value="PropertyValue"/>
         <propertyElement name="version" value="PropertyValue"/>
         <propertyElement name="vendorName" value="PropertyValue"/>
    </resourceAdapter>
    Where:
    • createBinding defines the package and interface binding class name
    • methodElement is the Java method to access the enterprise information system
      • name is the name of the method
      • input is the input type
      • output is the output type
      • interactioSpec is a list of interaction properties
    • connectionSpec is a list of connection properties
    • resourceAdapter is the resource adapter used either by specifying the project name or a list of properties
  5. After the properties are set, you can run a command that invokes the underlying API to drive either the import or the artifact generation.

Example

Note: Keep in mind these guidelines while using your Ant scripts:
  • If you are calling a resource adapter in your Ant script, the resource adapter must be imported into the workspace before invoking the Ant script.
  • Any resource that is used must have either a file path that points to the workspace and project, or a full file system path.
  • Discovery agents and workspace writer are referred by name (QName), which is uniquely identified. To find all registered discovery agents, workspace resource writers, and import configurations, use the displayAll.xml script found in the script directory.
  • Some of the elements have a pair of name, value attributes. The name is actually a property defined internally by the discovery agent or resource writer and it is used to pass the value along. It is important to get the name right. If the name is not recognized by the component the value is not set. These attributes are always part of a propertyElement tag which has a one-to-many multiplicity. The same multiplicity also applies to the methodElement tag.
The following script example generates a data binding based on the specified (taderc99.ccp) COBOL file. The script can be found in the com.ibm.adapter.command plugin script directory.
<?xml version="1.0" encoding="UTF-8" ?> 
  <project xmlns:adapter="http://com.ibm.adapter" default="DataBinding1" name="/Taderc99/CustomerInfo.xml">
    <property name="debug" value="true" /> 
    <property name="project1" value="Taderc99" /> 
    <target name="DataBinding1">
  <adapter:createProject projectName="${project1}" projectType="Java" /> 
    <adapter:discover>
    <adapter:performImport agent="{com/ibm/adapter}CobolDiscoveryAgent">
    <adapter:importResource>
    <adapter:propertyGroup name="CobolFileGroup">
  <adapter:propertyElement name="CobolFile" value="C:\Samples\CICS\taderc99\taderc99.cbl" /> 
  </adapter:propertyGroup>
  </adapter:importResource>
    <adapter:queryProperties>
    <adapter:propertyGroup name="ImportProperties">
  <adapter:propertyElement name="Platform" value="Win32" /> 
  <adapter:propertyElement name="Codepage" value="ISO-8859-1" /> 
  <adapter:propertyElement name="Numproc" value="PFD" /> 
  <adapter:propertyElement name="FloatingPointFormat" value="IEEE 754" /> 
    <adapter:propertyGroup name="ExternalDecimalSignGroup">
  <adapter:propertyElement name="ExternalDecimalSign" value="ASCII" /> 
  </adapter:propertyGroup>
    <adapter:propertyGroup name="EndianGroup">
  <adapter:propertyElement name="Endian" value="Little" /> 
  <adapter:propertyElement name="RemoteEndian" value="Little" /> 
  </adapter:propertyGroup>
    <adapter:propertyGroup name="CompileOptions">
  <adapter:propertyElement name="Quote" value="DOUBLE" /> 
  <adapter:propertyElement name="Trunc" value="STD" /> 
  <adapter:propertyElement name="Nsymbol" value="DBCS" /> 
  </adapter:propertyGroup>
  </adapter:propertyGroup>
  </adapter:queryProperties>
    <adapter:queryResult>
  <adapter:selectElement name="DFHCOMMAREA" /> 
  </adapter:queryResult>
  </adapter:performImport>
    <adapter:writeToWorkspace writer="{com/ibm/adapter/cobol/writer}JAVA_WRITER">
    <adapter:propertyGroup name="COBOLToJavaResourceWriter">
  <adapter:propertyElement name="GenerationStyle" value="Default" /> 
    <adapter:propertyGroup name="Java Type Name">
  <adapter:propertyElement name="Project Name" value="${project1}" /> 
  <adapter:propertyElement name="Package Name" value="sample.cics" /> 
  <adapter:propertyElement name="Class Name" value="CustomerInfo" /> 
  <adapter:propertyElement name="Overwrite existing class" value="true" /> 
  </adapter:propertyGroup>
  </adapter:propertyGroup>
  </adapter:writeToWorkspace>
  </adapter:discover>
  <eclipse.refreshLocal depth="infinite" resource="${project1}" /> 
  <eclipse.incrementalBuild project="${project1}" /> 
  </target>
  </project> 
Where:
  • importResource defines the resource to be imported
  • queryProperties are the parameters that represent the information required to form a query against the metadata repository
  • managedConnectionFactory defines the connection factory properties
  • queryResult are the selected nodes on the result tree that you want to import as application artifacts
  • propertyGroup is the structure containing the properties and their values.

Service Generation Task

In the special case of the language import (COBOL, C and PL/I), there is an additional step that involves generating the interface binding. The following example describes the data discovery section of the Ant script used to generate a J2C bean:

  <j2c:generateService>
            <j2c:buildService class="Customer" package="sample.cics">
                <j2c:method>
                    <j2c:methodName value="getCustomer"/>
                    <j2c:methodInput value="/Test/src/sample/cics/data/CustomerInfo.java"/>
                    <j2c:methodOutput value="/Test/src/sample/cics/data/CustomerInfo.java"/>
                    <j2c:interactionSpec class="com.ibm.connector2.cics.ECIInteractionSpec">
                        <adapter:propertyGroup name="INTERACTION_SPEC_PROPERTY_PG">
                            <adapter:propertyElement name="functionName" value="taderc99"/>
                            <adapter:propertyElement name="commareaLength" value="-1"/>
                            <adapter:propertyElement name="replyLength" value="-1"/>
                            <adapter:propertyElement name="executeTimeout" value="0"/>
                            <adapter:propertyElement name="interactionVerb" value="1"/>
                        </adapter:propertyGroup>
                    </j2c:interactionSpec>
                </j2c:method>
                <j2c:managedConnectionFactory class="com.ibm.connector2.cics.ECIManagedConnectionFactory" target="MyDefaultJNDIName">
                    <adapter:propertyGroup name="MANAGED_CONNECTION_FACTORY_CLASS_PROPERTIES">
                        <adapter:propertyGroup name="Server">
                            <adapter:propertyElement name="ConnectionURL" value="j2c"/>
                            <adapter:propertyElement name="ServerName" value="cics"/>
                        </adapter:propertyGroup>
                        <adapter:propertyGroup name="UserVerification">
                            <adapter:propertyElement name="UserName" value="sysad"/>
                            <adapter:propertyElement name="Password" value="susad"/>
                        </adapter:propertyGroup>
                        <adapter:propertyGroup name="Security"/>
                    </adapter:propertyGroup>
                </j2c:managedConnectionFactory>
                <j2c:connectionSpec class="com.ibm.connector2.cics.ECIConnectionSpec"/>
                <j2c:resourceAdapter project="${ra.project}"/>
            </j2c:buildService>
            <adapter:writeToWorkspace writer="{com/ibm/adapter/j2c/codegen/writer}J2CAnnotationWorkspaceResourceWriter">
                <adapter:propertyGroup name="J2C Java Bean Writer Properties">
                    <adapter:propertyElement name="Project" value="Test"/>
                    <adapter:propertyElement name="PackageName" value="sample.cics"/>
                    <adapter:propertyElement name="InterfaceName" value="Customer"/>
                </adapter:propertyGroup>
            </adapter:writeToWorkspace>
        </j2c:generateService>
Where:
  • buildService defines the package and interface binding class name
  • method is the Java™ method to access the EIS
    • methodName is the name of the method
    • methodInput is the input type
    • methodOutput is the output type
    • interactionSpec is a list of interaction properties
  • managedConnectionFactory defines the connection factory properties
  • connectionSpec is the connection class used
  • resourceAdapter is the resource adapter used by either specifying the project name or a list of properties

Additional Tasks

Other utility tasks are useful but not required to generate the artifact.

The createProject task creates a workspace project.
<adapter:createProject 
		projectName="taderc99Project" 
		projectType="Web" 
		runtimeName="J2EE Runtime Library"
		addToEAR="yes"
		EARProjectName="TestEAR"/>
Where:
  • projectName is the name of the project
  • projectType is the type can be Java, Web and EJB, not case-sensitive
  • runtimeName (optional) is the runtime name as defined in Window > Preferences > Server > Installed Runtimes
  • addToEAR (optional) valid values are
    • yes
    • no
    • true
    • false
  • EARProjectName (optional) is the EAR project name
The importResourceAdapter task creates a connector project.
<j2c:importResourceAdapter 
		connectorModule="cicseci602"
		connectorFile="D:\IBM\SDP70\ResourceAdapters\cics15\cicseci602.rar" 
		targetRuntime="J2EE Runtime Library"
		addToEAR="yes"
		EARProjectName="TestEAR"/>
Where:

Defining properties

Discovery agents and workspace writer are referred to by their unique names (QName). To find all registered discovery agents, workspace resource writers, and import configurations, use the displayAll.xml script found in the sample directory.

As observed in the example scripts, the values that are passed to the discovery agents or resource writers are defined by propertyGroup and propertyElement tags. A property group defines a logical grouping of properties through a nested structure. The structure layout and the group and property names, is described in the discovery agent or resource writer documentation.

Properties are defined by a pair of name-value attributes. The name is a property defined internally by the discovery agent or resource writer and it is used to pass the value along. It is important to get the name right. If the name is not recognized by the component the value is not set.


Feedback