Wednesday, August 27, 2008

openArchitectureWare XSD Tutorial (tweak)

Recently, I have needed to interogate a set of XML artifacts. I've found that my tooling (Stylus Studio, etc.) has let me down when it comes to transforming and understanding the various XML documents and schemas. For me it's not about having the tool do it all, it's about developing skill in handling the code/language/text etc.

I started with the openArchitectureWare XSD tutorial. In order to do this, I had to "modify" my oAW installation; in fact, I redid it since I found that the XSD Adapter is new and not included in the standard distribution and, in order to use it, newer modules were needed. This entry is good therapy for me in that, by writing it down, I am finalizing what I've learned and perhaps helping others in the process.

Here is what I installed to get things working. That last one was very important in that neither the workflow nor the XSDMetaModel reader worked until it was installed (hence it's last in the list :).

00-eclipse-oaw-43-ganymede-win32.win32.x86.zip (317,467,119)
01-dtp-sdk_1.6.0.zip (26,059,296)
02-eclipse-test-framework-3.4.zip (715,044)
03-wtp-R-3.0.1-20080818032401.zip (61,813,465)
04-wtp-wst-R-3.0.1-20080818032401.zip (37,307,900)
05-mdt-uml2tools-SDK-incubation-0.8.0.zip (12,166,067)
06-xsd-runtime-2.4.1.zip (1,185,283)
07-xsd-sourcedoc-2.4.1.zip (5,807,873)
08-mdt-ocl-SDK-1.2.1.zip (11,984,668)
09-oaw-xsd-adapter-rev20080702-1635.zip (1,335,497)
10-gmf-sdk-2.1.1.zip (35,010,940)
11-orbit-R20080611105805.zip (75,846,607)
12-emf-sdo-xsd-SDK-2.4.1.zip (28,890,765)


Since I was interested in delving into a fairly complicated schema-set that defined the payload for some fairly sensitive information, another thing that I needed was the mother of all schemas. You can get that at http://www.w3.org/2001/XMLSchema. I saved it as "xmlschema.xsd" and used it as my metamodel and each of the component elements of the schema-set as my input model. Check out the workflow below to see what I mean. I am hoping in the end to be able to generate a decent UML2 model or, if that didn't seem feasable, an EMF model.

Here are the steps that I took:

1. Installed the above software.
At the time, the files above represented the latest releases of all of the software. Perhaps you will find that you can just download and install the latest releases also. But for the record, the files above together comprised a configuration that worked.

2. Created a new openArchitectureWare project and adjust a few settings

- File -> New -> openArchitectureWare Project
- Project -> Properties ... openArchitectureWare ...
[X] Enable project specific settings ...
[ ] EMF Metamodels,
[X] XSD Metamodels
- Open <project>/META-INF/MANIFEST.MF ...
- Overview tab ... Execution Environments ... Add ...
JavaSE-1.6 ... OK
- Configure JRE associations ... Execution Environments ...
JavaSE-1.6 ... [X] jre 1.6.0_03 [perfect match]
- Update the classpath settings (warnings should
clear if they are/were present)
- Dependencies tab ... Add ...
org.openarchitectureware.xsd (4.3.0) ...
OK ... Ctrl-S

now, after several hours, you're ready to do the XSD tutorial if you want to: http://softeys.de/oaw-xsd-adapter/doc/contents/xsd_tutorial.html


3. Prepare the files

- Import the xmlschema.xsd file into src
(R-Click src -> Import ... File System ...
Next ... Browse ... <containing directory> ...
[X] xmlschema.xsd ... Finish).
- Import the target XML schema files or, as was my
case, the directory containing the schemas
(R-Click src -> Import ... File System ...
Next ... Browse ... <containing directory> ...
[X] <containing folder> ... Finish).


4. Created a Worflow file (e.g. schema-walker.oaw).

<workflow>
<property name="metamodel" value="xmlschema.xsd"/>
<property name="model" value="niem/fbi/2.0/fbi.xsd"/>
<property name="output" value="src-gen/xml" />
<property name="template" value="schema2xml" />

<component class="org.openarchitectureware.xsd.XMLReader">
<modelSlot value="model" />
<uri value="${model}" />
<metaModel id="mm"
class="org.openarchitectureware.xsd.XSDMetaModel">
<schemaFile value="${metamodel}" />
</metaModel>
</component>

<component class="org.openarchitectureware.xpand2.Generator">
<metaModel idRef="mm" />
<expand value="${template}::Root FOR model" />
<outlet path="${output}" />
</component>
</workflow>


6. Created an Xpand template (e.g. schema2xml.xpt). One thing to keep in mind is that the "xmlschema" metamodel needs to be on the classpath somewhere. So the fact that I have "xmlschema.xsd" in the "src" folder which is on the classpath (R-Click <project> ... Properties ... Java Build Path ... Source tab ... <project>/src) and that I've likewise "activated" the "XSD Metamodels" (R-Click <project> ... Properties ... openArchitectureWare), then that file will be found and interpreted into a .ecore metamodel and is therefore referencable by name in various oAW code types including Xpand files.

«IMPORT xmlschema»

«EXTENSION support»

«DEFINE writeFile FOR xmlschema::ComplexType»
«FILE name + ".xml" -»
<complex name="«name»"«complexContent.extension.extends()»>
«FOREACH annotation.documentation AS doc-»
«IF doc.mixed != null && doc.mixed.size > 0-»
<description>«doc.docString()»</description>
«ENDIF-»
«ENDFOREACH-»
«FOREACH complexContent.extension.sequence.element AS elem -»
<element name="«elem.getElementName().toFirstLower()»" type="«elem.getElementName()»"/>
«ENDFOREACH-»
«FOREACH sequence.element AS elem -»
<element name="«elem.getElementName().toFirstLower()»" type="«elem.getElementName()»"«elem.nullableAttribute()»«elem.ceilingAttribute()»/>
«ENDFOREACH-»
</complex>
«ENDFILE-»
«ENDDEFINE»

«DEFINE writeFile FOR xmlschema::SimpleType»
«FILE "codes/" + name + ".xml" -»
<enumeration name="«name»">
«FOREACH annotation.documentation AS doc-»
«IF doc.mixed != null && doc.mixed.size > 0-»
<description>«doc.docString()»</description>
«ENDIF-»
«ENDFOREACH-»
«FOREACH restriction.maxExclusive AS me-»
<max-exclusive>«me.value»</max-exclusive>
«ENDFOREACH-»
«FOREACH restriction.maxInclusive AS mi-»
<max-inclusive>«mi.value»</max-inclusive>
«ENDFOREACH-»
«FOREACH restriction.minExclusive AS me-»
<min-exclusive>«me.value»</min-exclusive>
«ENDFOREACH-»
«FOREACH restriction.minInclusive AS mi-»
<min-inclusive>«mi.value»</min-inclusive>
«ENDFOREACH-»
«IF restriction.enumeration.size > 0-»
«FOREACH restriction.enumeration AS enum-»
<code key="«enum.value»" value="«enum.annotation.annotationDocString()»"/>
«ENDFOREACH-»
«ENDIF-»
</enumeration>
«ENDFILE-»
«ENDDEFINE»

«DEFINE writeFile FOR xmlschema::AnyType»
«ENDDEFINE»

«DEFINE Root FOR xmlschema::SchemaType»
«FOREACH complexType.typeSelect(xmlschema::ComplexType) AS ct»
«EXPAND writeFile FOR ct»
«ENDFOREACH»
«FOREACH simpleType.typeSelect(xmlschema::SimpleType) AS st»
«EXPAND writeFile FOR st»
«ENDFOREACH»
«ENDDEFINE»


The supporting calculations (support.ext) look like this:


import xmlschema;

extends(ExtensionType e) :
(e.base.localPart.length > 0 ? " extends=\"" + e.base.localPart + "\"" : "");

annotationDocString(AnnotationType at) :
(at != null && at.documentation != null && at.documentation.size > 0 ? at.documentation.get(0).docString() : "");

docString(DocumentationType dt) :
(dt != null && dt.mixed != null && dt.mixed.size > 0 ? dt.mixed.get(0).value.toString().escape() : "");

getElementName(LocalElement elem) :
(elem != null ? elem.ref.localPart : "unknown");

nullableAttribute(LocalElement elem) :
(elem != null && elem.minOccurs != null ? " nullable=\"" + (elem.minOccurs != 0 ? "false" : "true" ) + "\"" : "");

ceilingAttribute(LocalElement elem) :
(elem != null && elem.maxOccurs != null ? " ceiling=\"" + elem.maxOccurs + "\"" : "" );

escapeLT (String s) :
(s.contains("<") ? s.replaceAll("<", "<") : s);

escapeAmp (String s) :
(s.contains("&") ? s.replaceAll("&", "&") : s);

escapeQuote (String s) :
(s.contains("\"") ? s.replaceAll("\"", """) : s);

escape (String s) :
s.escapeAmp().escapeLT().escapeQuote();


7. Ran the output to be sure that everything is working (R-Click the workflow -> Run As -> oAW Workflow). Here is my output.

0 INFO WorkflowRunner - --------------------------------------------------------------------------------------
16 INFO WorkflowRunner - openArchitectureWare 4.3.0, Build 20080508-1430PRD
16 INFO WorkflowRunner - (c) 2005-2008 openarchitectureware.org and contributors
16 INFO WorkflowRunner - --------------------------------------------------------------------------------------
16 INFO WorkflowRunner - running workflow: schema-walker.oaw
16 INFO WorkflowRunner -
1344 INFO XSDMetaModel - Loading XSDSchema from 'xmlschema.xsd'
3828 INFO XSDResolver - Importing 'http://www.w3.org/2001/xml.xsd' (http://www.w3.org/XML/1998/namespace) from XSDSchema 'file:/.../bin/xmlschema.xsd' (http://www.w3.org/2001/XMLSchema)
4672 INFO OawXSDEcoreBuilder - Creating EPackage 'xml' from XSDSchema 'http://www.w3.org/2001/xml.xsd' (http://www.w3.org/XML/1998/namespace)
4688 INFO OawXSDEcoreBuilder - Creating EPackage 'xmlschema' from XSDSchema 'file:/.../bin/xmlschema.xsd' (http://www.w3.org/2001/XMLSchema)
4938 WARN OawXSDEcoreBuilder - Name Conflict: Created EReference 'anyAttribute1', EAttribute 'anyAttribute' is in the way. Container1:/EPackage'xmlschema'/EClass'OpenAttrs', Container2:/EPackage'xmlschema'/EClass'AttributeGroup'
4938 WARN OawXSDEcoreBuilder - Name Conflict: Created EAttribute 'group1', EReference 'group' is in the way. Container:/EPackage'xmlschema'/EClass'RestrictionType'
4969 WARN OawXSDEcoreBuilder - Name Conflict: Created EReference 'anyAttribute1', EAttribute 'anyAttribute' is in the way. Container1:/EPackage'xmlschema'/EClass'OpenAttrs', Container2:/EPackage'xmlschema'/EClass'RestrictionType'
4969 WARN OawXSDEcoreBuilder - Name Conflict: Created EAttribute 'group1', EReference 'group' is in the way. Container:/EPackage'xmlschema'/EClass'ComplexType'
4969 WARN OawXSDEcoreBuilder - Name Conflict: Created EReference 'anyAttribute1', EAttribute 'anyAttribute' is in the way. Container1:/EPackage'xmlschema'/EClass'OpenAttrs', Container2:/EPackage'xmlschema'/EClass'ComplexType'
4969 WARN OawXSDEcoreBuilder - Name Conflict: Created EAttribute 'group1', EReference 'group' is in the way. Container:/EPackage'xmlschema'/EClass'ExtensionType'
4985 WARN OawXSDEcoreBuilder - Name Conflict: Created EReference 'anyAttribute1', EAttribute 'anyAttribute' is in the way. Container1:/EPackage'xmlschema'/EClass'OpenAttrs', Container2:/EPackage'xmlschema'/EClass'ExtensionType'
4985 WARN OawXSDEcoreBuilder - Name Conflict: Created EReference 'all1', EReference 'all' is in the way. Container1:/EPackage'xmlschema'/EClass'Group', Container2:/EPackage'xmlschema'/EClass'RealGroup'
4985 WARN OawXSDEcoreBuilder - Name Conflict: Created EReference 'choice1', EReference 'choice' is in the way. Container1:/EPackage'xmlschema'/EClass'Group', Container2:/EPackage'xmlschema'/EClass'RealGroup'
4985 WARN OawXSDEcoreBuilder - Name Conflict: Created EReference 'sequence1', EReference 'sequence' is in the way. Container1:/EPackage'xmlschema'/EClass'Group', Container2:/EPackage'xmlschema'/EClass'RealGroup'
5000 WARN OawXSDEcoreBuilder - Name Conflict: Created EReference 'group1', EAttribute 'group' is in the way. Container:/EPackage'xmlschema'/EClass'RedefineType'
5000 WARN OawXSDEcoreBuilder - Name Conflict: Created EClass 'RestrictionType1', EClass 'RestrictionType' is in the way. Container:/EPackage'xmlschema'
5016 WARN OawXSDEcoreBuilder - Name Conflict: Created EAttribute 'group1', EAttribute 'group' is in the way. Container:/EPackage'xmlschema'/EClass'SchemaType'
5016 WARN OawXSDEcoreBuilder - Name Conflict: Created EReference 'group2', EAttribute 'group' is in the way. Container:/EPackage'xmlschema'/EClass'SchemaType'
5047 WARN OawXSDEcoreBuilder - Name Conflict: Created EReference 'annotation1', EReference 'annotation' is in the way. Container:/EPackage'xmlschema'/EClass'SchemaType'
5063 WARN OawXSDEcoreBuilder - Name Conflict: Created EDataType 'XpathType1', EDataType 'XpathType' is in the way. Container:/EPackage'xmlschema'
5063 INFO XSDMetaModel - Registering EPackage 'xmlschema' (http://www.w3.org/2001/XMLSchema) globally.
5266 INFO CompositeComponent - XMLReader: Loading XML file niem/fbi/2.0/fbi.xsd
7188 INFO CompositeComponent - Generator: generating 'schema2xml::Root FOR model' => directory 'null'
35938 INFO Generator - Written 53 files to outlet [default](src-gen/niem/fbi)
35938 INFO WorkflowRunner - workflow completed in 30672ms!


Now I'm off to get to know the schema through altering my template file and reviewing the output. Once I think that I have a good understanding of what's there, then I'll move on to UML2 model creation. "There is joy in the journey" :)

Here is a link to the source.

8. Create an Xtend file (.ext).
This may take some time so I'll fill it in later. Email me if you're getting impatient.

No comments: