- Name of place
- Name of the jca file
- Type of the adapter
- Is it an activation (consume) or interaction (type)
- What is the location (eis JNDI )
- Destination
- Payload
- Message selector (when consumption)
Using ANT to scan jca Files
<!-- Initialisatie --> <target name="clean" description="Clean the temp folder"> <delete dir="${jcaTempDir}"/> <mkdir dir="${jcaTempDir}"/> </target> <!-- Perform all --> <target name="all" description="Scan All SOA applications" depends="clean"> <echo>FMW_HOME=${fmw.home}.</echo> <echo file="${outputFile}" append="false" message="project name,jcaFile,adapter-config-name,adapter-type,connection factory location,endpoint type,class,DestinationName,QueueName,DeliveryMode,TimeToLive,UseMessageListener,MessageSelector,PayloadType,ObjectFieldName,PayloadHeaderRequired,RecipientList,Consumer${line.separator}"></echo> <foreach param="project.file" target="handleProject" delimiter=';' inheritall="true"> <path> <fileset id="dist.contents" dir="${svnRoot}" includes="**/*.jpr"/> </path> </foreach> </target>
So, I do a foreach over a fileset, using the svnRoot property in the build.properties, that includes ever .jpr file anywhere in the structure. For each file the handleProject target is called with the file in the project.file property. Foreach is an antcontrib addition to ANT. So you need to add that as a task definition (one thing I do as a first thing).
<taskdef resource="net/sf/antcontrib/antlib.xml"> <classpath> <pathelement location="${ant-contrib.jar}"/> </classpath> </taskdef>
With the name of the .jpr file I have the name of the project and the location:
<target name="handleProject"> <echo message="projectFile: ${project.file}"></echo> <dirname property="project.dir" file="${project.file}"/> <echo message="project dir: ${project.dir}"></echo> <basename property="project.name" file="${project.file}" suffix=".jpr"/> <foreach param="jca.file" target="handleJca" delimiter=";" inheritall="true"> <path> <fileset id="dist.contents" dir="${project.dir}" includes="**/*.jca"/> </path> </foreach> </target>
In this snippet the dirname ANT task trims the filename from the project.file property, to provide me the project folder into the project.dir property. The project.name can be determined from the project.file using the basename task. Nice touch is that it allows you to trim the suffix (.jpr) from it. Within the project location I can find all the .jca file, and in the same way as the .jpr files I can use a foreach on the project.dir and call the handleJca target for each .jca file.
Using XSL to pre-process the jca files
Fortunately, jca files are simply XML files and ANT turns out to be able to read XML as a property file, using the xmlproperty task, which came in handy. Those properties can be appended to an output file using echo, very easily.However, there are two main problems with the structure of the jca files:
- The jca files for the interaction type (the write kind) are different from the activation type (the read kind), So I would need to distinguish those.
- The properties like DestinationName, payload and message selector are name value pair properties in the .jca file. The interprets the names of the properties as separate property values with the name. I can't select specifically the Destination Name for instance.
Just follow the wizard, but emtpy the target namespace. As said I did this for both kinds of jca files (the interaction and activation kinds) and merge them into jcaAdapter.xsd with a xsd:choice:
Out of that I created jcaAdapterProps.xsd where the xsd:choice elements are merged into spec element. I changed the targetnamespace and created specific property elements:
That allowed me to create the XSL Map jcaAdapter.xsl easily:
For the xmlproperty task it is important that the resulting xml is in a default namespace and that the elements depend on the default namespaces, they should not reference a specific namespace (not even the default one).
With that I can finish off with the handleJca target of my script:
<target name="handleJca"> <basename property="jca.file.name" file="${jca.file}"/> <property name="jca.file.props" value="${jcaTempDir}/${jca.file.name}.props"/> <echo message="Jca File: ${jca.file.name}"></echo> <xslt style="${jcaPropsXsl}" in="${jca.file}" out="${jca.file.props}"/> <xmlproperty file="${jca.file.props}" collapseattributes="true"/> <!-- see https://ant.apache.org/manual/Tasks/xmlproperty.html --> <property name="cf.location" value="${adapter-config.connection-factory.location}"/> <property name="ep.class" value="${adapter-config.endpoint.spec.className}"/> <property name="ep.type" value="${adapter-config.endpoint.spec.type}"/> <property name="ep.DestinationName" value="${adapter-config.endpoint.spec.DestinationName}"/> <property name="ep.DeliveryMode" value="${adapter-config.endpoint.spec.DeliveryMode}"/> <property name="ep.TimeToLive" value="${adapter-config.endpoint.spec.TimeToLive}"/> <property name="ep.UseMessageListener" value="${adapter-config.endpoint.spec.UseMessageListener}"/> <property name="ep.MessageSelector" value="${adapter-config.endpoint.spec.MessageSelector}"/> <property name="ep.PayloadType" value="${adapter-config.endpoint.spec.PayloadType}"/> <property name="ep.QueueName" value="${adapter-config.endpoint.spec.QueueName}"/> <property name="ep.ObjectFieldName" value="${adapter-config.endpoint.spec.ObjectFieldName}"/> <property name="ep.PayloadHeaderRequired" value="${adapter-config.endpoint.spec.PayloadHeaderRequired}"/> <property name="ep.RecipientList" value="${adapter-config.endpoint.spec.RecipientList}"/> <property name="ep.Consumer" value="${adapter-config.endpoint.spec.Consumer}"/> <echo file="${outputFile}" append="true" message="${project.name},${jca.file.name},${adapter-config.name},${adapter-config.adapter},${cf.location},${ep.type},${ep.class},${ep.DestinationName},${ep.QueueName},${ep.DeliveryMode},${ep.TimeToLive},${ep.UseMessageListener},${ep.MessageSelector},${ep.PayloadType},${ep.ObjectFieldName},${ep.PayloadHeaderRequired},${ep.RecipientList},${ep.Consumer}${line.separator}"></echo> </target>With the xslt task the jca file is transformed to the jcaTempDir folder. And using the xmlproperty task the transformed .jca is read as an xml property file. Because the property references are quite long, I copy them in a shorter named property and then echo them as a comma separated line into the outputFile using the append attribute to true.
Note that I used collapseattributes attribute set to true.
Conclusion
And that is actually about it. ANT is very handy to find and process files in a controlled way. Also the combination with XSL makes it powerfull. In this project I concentrated on JMS and AQ adapters, as far as the properties are concerned. But you can extend this for DB Adapters and File Adapters, etc. quite easily. Maybe even create an output file per type.I can't share the output with you, due to company policy contraints. Just try it out.