Java tutorial
/** * PlasmaSDO License * * This is a community release of PlasmaSDO, a dual-license * Service Data Object (SDO) 2.1 implementation. * This particular copy of the software is released under the * version 2 of the GNU General Public License. PlasmaSDO was developed by * TerraMeta Software, Inc. * * Copyright (c) 2013, TerraMeta Software, Inc. All rights reserved. * * General License information can be found below. * * This distribution may include materials developed by third * parties. For license and attribution notices for these * materials, please refer to the documentation that accompanies * this distribution (see the "Licenses for Third-Party Components" * appendix) or view the online documentation at * <http://plasma-sdo.org/licenses/>. * */ package org.plasma.xml.uml; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import javax.xml.bind.JAXBException; import javax.xml.bind.ValidationEvent; import javax.xml.bind.ValidationEventLocator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jdom2.Attribute; import org.jdom2.CDATA; import org.jdom2.Content; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.Namespace; import org.jdom2.Text; import org.jdom2.output.Format; import org.jdom2.output.XMLOutputter; import org.plasma.common.bind.BindingValidationEventHandler; import org.plasma.config.ConfigUtils; import org.plasma.provisioning.Alias; import org.plasma.provisioning.Behavior; import org.plasma.provisioning.Class; import org.plasma.provisioning.ClassRef; import org.plasma.provisioning.DataTypeRef; import org.plasma.provisioning.Documentation; import org.plasma.provisioning.Enumeration; import org.plasma.provisioning.EnumerationConstraint; import org.plasma.provisioning.EnumerationLiteral; import org.plasma.provisioning.EnumerationRef; import org.plasma.provisioning.Model; import org.plasma.provisioning.Package; import org.plasma.provisioning.Property; import org.plasma.provisioning.ProvisioningModelAssembler; import org.plasma.provisioning.ProvisioningModelDataBinding; import org.plasma.provisioning.SchemaProvisioningModelAssembler; import org.plasma.provisioning.ValueConstraint; import org.plasma.query.Query; import org.plasma.sdo.profile.KeyType; import org.plasma.sdo.profile.SDOAlias; import org.plasma.sdo.profile.SDOEnumerationConstraint; import org.plasma.sdo.profile.SDOKey; import org.plasma.sdo.profile.SDONamespace; import org.plasma.sdo.profile.SDOSort; import org.plasma.sdo.profile.SDOUniqueConstraint; import org.plasma.sdo.profile.SDOValueConstraint; import org.plasma.sdo.profile.SDOXmlProperty; import org.plasma.xml.schema.Schema; import org.xml.sax.SAXException; public abstract class DefaultUMLModelAssembler implements UMLModelAssembler { private static Log log = LogFactory.getLog(DefaultUMLModelAssembler.class); protected String xmiVersion; protected Namespace umlNs; protected Namespace xmiNs; protected Namespace plasmaNs; protected String dataTypeHRefPrefix; protected Namespace platformNs; protected Namespace xsiNs; protected String xsiSchemaLocation; private Model provisioningModel; private String destNamespaceURI; private String destNamespacePrefix; private boolean derivePackageNamesFromURIs = true; private Document document; private Map<String, Package> packageMap = new HashMap<String, Package>(); private Map<String, Class> classMap = new HashMap<String, Class>(); private Map<Class, Package> classPackageMap = new HashMap<Class, Package>(); private Map<String, Enumeration> enumMap = new HashMap<String, Enumeration>(); private Map<Enumeration, Package> enumPackageMap = new HashMap<Enumeration, Package>(); private Element xmiElem; private Element modelElem; private Map<String, Element> elementMap = new HashMap<String, Element>(); private Map<String, Element> associationElementMap = new HashMap<String, Element>(); private Map<String, Element> enumElementMap = new HashMap<String, Element>(); @SuppressWarnings("unused") private DefaultUMLModelAssembler() { } @Deprecated protected DefaultUMLModelAssembler(Query query, String destNamespaceURI, String destNamespacePrefix) { super(); this.destNamespaceURI = destNamespaceURI; this.destNamespacePrefix = destNamespacePrefix; if (destNamespaceURI == null || destNamespaceURI.trim().length() == 0) throw new IllegalArgumentException("expected 'destNamespaceURI' argument"); if (destNamespacePrefix == null || destNamespacePrefix.trim().length() == 0) throw new IllegalArgumentException("expected 'destNamespacePrefix' argument"); this.document = buildDocumentModel(query, this.destNamespaceURI, this.destNamespacePrefix); } @Deprecated protected DefaultUMLModelAssembler(Schema schema, String destNamespaceURI, String destNamespacePrefix) { super(); this.destNamespaceURI = destNamespaceURI; this.destNamespacePrefix = destNamespacePrefix; if (destNamespaceURI == null || destNamespaceURI.trim().length() == 0) throw new IllegalArgumentException("expected 'destNamespaceURI' argument"); if (destNamespacePrefix == null || destNamespacePrefix.trim().length() == 0) throw new IllegalArgumentException("expected 'destNamespacePrefix' argument"); this.document = buildDocumentModel(schema, this.destNamespaceURI, this.destNamespacePrefix); } protected DefaultUMLModelAssembler(Model model, String destNamespaceURI, String destNamespacePrefix) { super(); this.destNamespaceURI = destNamespaceURI; this.destNamespacePrefix = destNamespacePrefix; if (destNamespaceURI == null || destNamespaceURI.trim().length() == 0) throw new IllegalArgumentException("expected 'destNamespaceURI' argument"); if (destNamespacePrefix == null || destNamespacePrefix.trim().length() == 0) throw new IllegalArgumentException("expected 'destNamespacePrefix' argument"); this.provisioningModel = model; } /* (non-Javadoc) * @see org.plasma.xml.uml.UMLModelAssembler#getDestNamespaceURI() */ @Override public String getDestNamespaceURI() { return destNamespaceURI; } /* (non-Javadoc) * @see org.plasma.xml.uml.UMLModelAssembler#setDestNamespaceURI(java.lang.String) */ @Override public void setDestNamespaceURI(String destNamespaceURI) { this.destNamespaceURI = destNamespaceURI; } /* (non-Javadoc) * @see org.plasma.xml.uml.UMLModelAssembler#getDestNamespacePrefix() */ @Override public String getDestNamespacePrefix() { return destNamespacePrefix; } /* (non-Javadoc) * @see org.plasma.xml.uml.UMLModelAssembler#setDestNamespacePrefix(java.lang.String) */ @Override public void setDestNamespacePrefix(String destNamespacePrefix) { this.destNamespacePrefix = destNamespacePrefix; } /* (non-Javadoc) * @see org.plasma.xml.uml.UMLModelAssembler#isDerivePackageNamesFromURIs() */ @Override public boolean isDerivePackageNamesFromURIs() { return derivePackageNamesFromURIs; } /* (non-Javadoc) * @see org.plasma.xml.uml.UMLModelAssembler#setDerivePackageNamesFromURIs(boolean) */ @Override public void setDerivePackageNamesFromURIs(boolean derivePackageNamesFromURIs) { this.derivePackageNamesFromURIs = derivePackageNamesFromURIs; } /* (non-Javadoc) * @see org.plasma.xml.uml.UMLModelAssembler#getDocument() */ @Override public Document getDocument() { if (this.document == null) this.document = buildDocumentModel(this.provisioningModel, this.destNamespaceURI, this.destNamespacePrefix); return this.document; } /* (non-Javadoc) * @see org.plasma.xml.uml.UMLModelAssembler#getContent() */ @Override @SuppressWarnings("deprecation") public String getContent() { return getContent(new XMLOutputter()); } /* (non-Javadoc) * @see org.plasma.xml.uml.UMLModelAssembler#getContent(java.lang.String, boolean) */ @Override @SuppressWarnings("deprecation") public String getContent(java.lang.String indent, boolean newlines) { XMLOutputter outputter = new XMLOutputter(); outputter.getFormat().setIndent(indent); return getContent(outputter); } /* (non-Javadoc) * @see org.plasma.xml.uml.UMLModelAssembler#getContent(org.jdom2.output.Format) */ @Override public String getContent(Format format) { return getContent(new XMLOutputter(format)); } /* (non-Javadoc) * @see org.plasma.xml.uml.UMLModelAssembler#getContent(java.io.OutputStream) */ @Override @SuppressWarnings("deprecation") public void getContent(OutputStream stream) { XMLOutputter outputter = new XMLOutputter(); getContent(stream, outputter); } /* (non-Javadoc) * @see org.plasma.xml.uml.UMLModelAssembler#getContent(java.io.OutputStream, java.lang.String, boolean) */ @Override @SuppressWarnings("deprecation") public void getContent(OutputStream stream, java.lang.String indent, boolean newlines) { XMLOutputter outputter = new XMLOutputter(); outputter.getFormat().setIndent(indent); getContent(stream, outputter); } /* (non-Javadoc) * @see org.plasma.xml.uml.UMLModelAssembler#getContent(java.io.OutputStream, org.jdom2.output.Format) */ @Override public void getContent(OutputStream stream, Format format) { getContent(stream, new XMLOutputter(format)); } private String getContent(XMLOutputter outputter) { String result = null; ByteArrayOutputStream os = new ByteArrayOutputStream(); try { if (this.document == null) this.document = buildDocumentModel(this.provisioningModel, this.destNamespaceURI, this.destNamespacePrefix); outputter.output(this.document, os); os.flush(); result = new String(os.toByteArray()); } catch (java.io.IOException e) { } finally { try { os.close(); } catch (IOException e) { } } return result; } private void getContent(OutputStream stream, XMLOutputter outputter) { String result = null; try { if (this.document == null) this.document = buildDocumentModel(this.provisioningModel, this.destNamespaceURI, this.destNamespacePrefix); outputter.output(this.document, stream); stream.flush(); } catch (java.io.IOException e) { } finally { try { stream.close(); } catch (IOException e) { } } } private Document buildDocumentModel(Query query, String destNamespaceURI, String destNamespacePrefix) { ProvisioningModelAssembler stagingAssembler = new ProvisioningModelAssembler(query, destNamespaceURI, destNamespacePrefix); Model model = stagingAssembler.getModel(); if (log.isDebugEnabled()) { try { BindingValidationEventHandler debugHandler = new BindingValidationEventHandler() { public int getErrorCount() { return 0; } public boolean handleEvent(ValidationEvent ve) { ValidationEventLocator vel = ve.getLocator(); String message = "Line:Col:Offset[" + vel.getLineNumber() + ":" + vel.getColumnNumber() + ":" + String.valueOf(vel.getOffset()) + "] - " + ve.getMessage(); String sev = ""; switch (ve.getSeverity()) { case ValidationEvent.WARNING: sev = "WARNING"; break; case ValidationEvent.ERROR: sev = "ERROR"; break; case ValidationEvent.FATAL_ERROR: sev = "FATAL_ERROR"; break; default: } log.debug(sev + " - " + message); return true; } }; ProvisioningModelDataBinding binding = new ProvisioningModelDataBinding(debugHandler); String xml = binding.marshal(model); binding.validate(xml); log.debug(xml); } catch (JAXBException e) { log.debug(e.getMessage(), e); } catch (SAXException e) { log.debug(e.getMessage(), e); } } return buildDocumentModel(model, destNamespaceURI, destNamespacePrefix); } private Document buildDocumentModel(Schema schema, String destNamespaceURI, String destNamespacePrefix) { SchemaProvisioningModelAssembler stagingAssembler = new SchemaProvisioningModelAssembler(schema, destNamespaceURI, destNamespacePrefix); Model model = stagingAssembler.getModel(); return buildDocumentModel(model, destNamespaceURI, destNamespacePrefix); } private Document buildDocumentModel(Model model, String destNamespaceURI, String destNamespacePrefix) { this.xmiElem = new Element("XMI"); this.xmiElem.setNamespace(xmiNs); Document document = new Document(this.xmiElem); this.xmiElem.setAttribute(new Attribute("version", this.xmiVersion, this.xmiNs)); // FIXME - use FUML config for this, i.e which version? this.xmiElem.addNamespaceDeclaration(umlNs); this.xmiElem.addNamespaceDeclaration(xmiNs); this.xmiElem.addNamespaceDeclaration(plasmaNs); if (this.platformNs != null) this.xmiElem.addNamespaceDeclaration(platformNs); if (this.xsiNs != null) { this.xmiElem.addNamespaceDeclaration(xsiNs); this.xmiElem.setAttribute(new Attribute("schemaLocation", this.xsiSchemaLocation, this.xsiNs)); } if (this.derivePackageNamesFromURIs) this.modelElem = this.buildModelFromURITokens(model); else this.modelElem = this.buildModelFromPackageNames(model); Element profileApplicationElem = buildProfileApplication(); if (profileApplicationElem != null) this.modelElem.addContent(profileApplicationElem); collectPackages(model); collectClasses(model); collectEnumerations(model); for (Class clss : this.classMap.values()) { Package pkg = this.classPackageMap.get(clss); Element clssElem = buildClass(clss); elementMap.put(clss.getId(), clssElem); // build properties w/o any associations for (Property property : clss.getProperties()) { Element ownedAttribute = buildProperty(pkg, clss, property, clssElem); elementMap.put(property.getId(), ownedAttribute); } } // create associations for (Class clss : this.classMap.values()) { for (Property prop : clss.getProperties()) { if (prop.getType() instanceof DataTypeRef) continue; if (associationElementMap.get(prop.getId()) != null) continue; // we created it String associationUUID = UUID.randomUUID().toString(); // link assoc to both properties Element leftOwnedAttribute = elementMap.get(prop.getId()); leftOwnedAttribute.setAttribute(new Attribute("association", associationUUID)); Property targetProp = getOppositeProperty(clss, prop); if (targetProp != null) { Element rightOwnedAttribute = elementMap.get(targetProp.getId()); rightOwnedAttribute.setAttribute(new Attribute("association", associationUUID)); Element association = buildAssociation(prop, targetProp, this.modelElem, associationUUID); // map it to both props so we can know not to create it again associationElementMap.put(prop.getId(), association); associationElementMap.put(targetProp.getId(), association); } else { Class targetClass = getOppositeClass(clss, prop); Element association = buildAssociation(prop, targetClass, this.modelElem, associationUUID); // map it to both props so we can know not to create it again associationElementMap.put(prop.getId(), association); } } } return document; } private void collectPackages(Model model) { if (model.getUri() != null) { packageMap.put(model.getUri() + "#" + model.getName(), model); } for (Package pkg : model.getPackages()) { if (pkg.getUri() != null) { packageMap.put(pkg.getUri() + "#" + pkg.getName(), pkg); } } } //FIXME: only a model can have packages? A package cannot? private void collectClasses(Model model) { collectClasses((Package) model); for (Package pkg : model.getPackages()) collectClasses(pkg); } private void collectClasses(Package pkg) { for (Class clss : pkg.getClazzs()) { classMap.put(clss.getUri() + "#" + clss.getName(), clss); classPackageMap.put(clss, pkg); } } private void collectEnumerations(Model model) { collectEnumerations((Package) model); for (Package pkg : model.getPackages()) collectEnumerations(pkg); } private void collectEnumerations(Package pkg) { for (Enumeration enm : pkg.getEnumerations()) { enumMap.put(enm.getUri() + "#" + enm.getName(), enm); enumPackageMap.put(enm, pkg); } } private Element buildModelFromPackageNames(Model model) { Element modelElem = new Element("Model"); modelElem.setNamespace(umlNs); this.xmiElem.addContent(modelElem); modelElem.setAttribute(new Attribute("id", model.getId(), xmiNs)); modelElem.setAttribute(new Attribute("name", model.getName())); modelElem.setAttribute(new Attribute("visibility", "public")); elementMap.put(model.getId(), modelElem); if (model.getDocumentations() != null) for (Documentation doc : model.getDocumentations()) { addOwnedComment(modelElem, model.getId(), doc.getBody().getValue()); } // Only a root (model) package // tag the model w/a SDO namespace streotype, else tag the // last package descendant below if (model.getPackages().size() == 0) { Element modelStereotype = new Element(SDONamespace.class.getSimpleName(), plasmaNs); this.xmiElem.addContent(modelStereotype); modelStereotype.setAttribute(new Attribute("id", UUID.randomUUID().toString(), xmiNs)); modelStereotype.setAttribute(new Attribute(SDONamespace.BASE__PACKAGE, model.getId())); modelStereotype.setAttribute(new Attribute(SDONamespace.URI, model.getUri())); if (model.getAlias() != null) addAlias(model.getAlias(), model.getId()); } for (Package pkg : model.getPackages()) { Element pkgElem = new Element("packagedElement"); modelElem.addContent(pkgElem); // add package child pkgElem.setAttribute(new Attribute("type", "uml:Package", xmiNs)); pkgElem.setAttribute(new Attribute("id", pkg.getId(), xmiNs)); pkgElem.setAttribute(new Attribute("name", pkg.getName())); pkgElem.setAttribute(new Attribute("visibility", "public")); elementMap.put(pkg.getId(), pkgElem); if (pkg.getAlias() != null) addAlias(pkg.getAlias(), pkg.getId()); Element pkgStereotypeElem = new Element(SDONamespace.class.getSimpleName(), plasmaNs); this.xmiElem.addContent(pkgStereotypeElem); pkgStereotypeElem.setAttribute(new Attribute("id", UUID.randomUUID().toString(), xmiNs)); pkgStereotypeElem.setAttribute(new Attribute(SDONamespace.BASE__PACKAGE, pkg.getId())); pkgStereotypeElem.setAttribute(new Attribute(SDONamespace.URI, pkg.getUri())); if (pkg.getDocumentations() != null) for (Documentation doc : model.getDocumentations()) { addOwnedComment(pkgElem, pkg.getId(), doc.getBody().getValue()); } } return modelElem; } private Element buildModelFromURITokens(Model model) { Element rootPackageElem = null; String[] packageNames = ConfigUtils.toPackageTokens(model.getUri()); Element modelElem = new Element("Model"); modelElem.setNamespace(umlNs); this.xmiElem.addContent(modelElem); modelElem.setAttribute(new Attribute("id", model.getId(), xmiNs)); modelElem.setAttribute(new Attribute("name", packageNames[0])); modelElem.setAttribute(new Attribute("visibility", "public")); elementMap.put(model.getId(), modelElem); // FIXME: duplicating model level docs at package // descendant level if (model.getDocumentations() != null) for (Documentation doc : model.getDocumentations()) { addOwnedComment(modelElem, model.getId(), doc.getBody().getValue()); } // tag the model w/a SDO namespace streotype, else tag the // last package descendant below if (packageNames.length == 1) { Element modelStereotype = new Element(SDONamespace.class.getSimpleName(), plasmaNs); this.xmiElem.addContent(modelStereotype); modelStereotype.setAttribute(new Attribute("id", UUID.randomUUID().toString(), xmiNs)); modelStereotype.setAttribute(new Attribute(SDONamespace.BASE__PACKAGE, model.getId())); modelStereotype.setAttribute(new Attribute(SDONamespace.URI, this.destNamespaceURI)); } rootPackageElem = modelElem; for (int i = 1; i < packageNames.length; i++) { Element pkgElem = new Element("packagedElement"); rootPackageElem.addContent(pkgElem); String id = UUID.randomUUID().toString(); pkgElem.setAttribute(new Attribute("type", "uml:Package", xmiNs)); pkgElem.setAttribute(new Attribute("id", id, xmiNs)); pkgElem.setAttribute(new Attribute("name", packageNames[i])); pkgElem.setAttribute(new Attribute("visibility", "public")); elementMap.put(id, pkgElem); if (i == packageNames.length - 1) { Element pkgStereotypeElem = new Element(SDONamespace.class.getSimpleName(), plasmaNs); this.xmiElem.addContent(pkgStereotypeElem); pkgStereotypeElem.setAttribute(new Attribute("id", UUID.randomUUID().toString(), xmiNs)); pkgStereotypeElem.setAttribute(new Attribute(SDONamespace.BASE__PACKAGE, id)); pkgStereotypeElem.setAttribute(new Attribute(SDONamespace.URI, this.destNamespaceURI)); // FIXME: no packages or package-level docs in provisioning model // use model-level docs here if (model.getDocumentations() != null) for (Documentation doc : model.getDocumentations()) { addOwnedComment(pkgElem, id, doc.getBody().getValue()); } } rootPackageElem = pkgElem; } return rootPackageElem; } /** * Creates and element which is a profile application for the model * @return the profile application or null if not applicable for concerned subclass */ protected abstract Element buildProfileApplication(); private Element buildClass(Class clss) { if (log.isDebugEnabled()) log.debug("creating class " + clss.getName()); // find parent element Package pkgParent = this.classPackageMap.get(clss); Element parent = this.elementMap.get(pkgParent.getId()); Element clssElem = new Element("packagedElement"); parent.addContent(clssElem); elementMap.put(clss.getId(), clssElem); clssElem.setAttribute(new Attribute("type", "uml:Class", xmiNs)); clssElem.setAttribute(new Attribute("id", clss.getId(), xmiNs)); clssElem.setAttribute(new Attribute("name", clss.getName())); clssElem.setAttribute(new Attribute("visibility", "public")); if (clss.getDocumentations() != null) for (Documentation doc : clss.getDocumentations()) { addOwnedComment(clssElem, clss.getId(), doc.getBody().getValue()); } if (clss.getAlias() != null) { addAlias(clss.getAlias(), clss.getId()); } for (ClassRef baseRef : clss.getSuperClasses()) { Element generalizationElem = new Element("generalization"); generalizationElem.setAttribute(new Attribute("type", "uml:Generalization", xmiNs)); generalizationElem.setAttribute(new Attribute("id", UUID.randomUUID().toString(), xmiNs)); clssElem.addContent(generalizationElem); Class baseClass = classMap.get(baseRef.getUri() + "#" + baseRef.getName()); generalizationElem.setAttribute(new Attribute("general", baseClass.getId())); /* --for an external reference Element generalElem = new Element("general"); generalizationElem.addContent(generalElem); generalElem.setAttribute(new Attribute("type", "uml:Class", xmiNs)); generalElem.setAttribute(new Attribute("type", "uml:Class")); generalElem.setAttribute(new Attribute("href", baseClass.getId())); */ } /* --for an external reference <generalization xmi:type='uml:Generalization' xmi:id='_16_0_1_1707042b_1325701279933_851156_1151'> <general xmi:type='uml:Class' href='plasma-platform-common.mdxml#_16_0_1_1707042b_1318367153137_813743_576'> </general> </generalization> */ if (clss.getBehaviors().size() > 0) addBehaviors(clss, clssElem, clss.getBehaviors()); return clssElem; } /** * Adds a UML owned opaque behavior ala. below for each provisioning * behavior. * * <ownedBehavior xmi:type='uml:OpaqueBehavior' xmi:id='_17_0_6_1707042b_1376433440849_3356_7405' name='create' visibility='public'> * <body>FOO BAR;</body> * <language>SQL</language> * </ownedBehavior> * * @param clss the * @param clssElem the element * @param behaviors the bahaviors */ private void addBehaviors(Class clss, Element clssElem, List<Behavior> behaviors) { for (Behavior behavior : behaviors) { Element ownedBehavior = new Element("ownedBehavior"); clssElem.addContent(ownedBehavior); ownedBehavior.setAttribute(new Attribute("type", "uml:OpaqueBehavior", xmiNs)); ownedBehavior.setAttribute(new Attribute("id", UUID.randomUUID().toString(), xmiNs)); ownedBehavior.setAttribute(new Attribute("visibility", "public")); ownedBehavior.setAttribute(new Attribute("name", behavior.getType().name())); Element language = new Element("language"); language.setText(behavior.getLanguage()); ownedBehavior.addContent(language); Element body = new Element("body"); Text text = new Text(behavior.getValue()); body.addContent(text); ownedBehavior.addContent(body); } } private void addAlias(Alias alias, String namedElementId) { Element aliasStereotype = new Element(SDOAlias.class.getSimpleName(), plasmaNs); this.xmiElem.addContent(aliasStereotype); aliasStereotype.setAttribute(new Attribute("id", UUID.randomUUID().toString(), xmiNs)); aliasStereotype.setAttribute(new Attribute(SDOAlias.BASE__NAMED_ELEMENT, namedElementId)); if (alias.getPhysicalName() != null) aliasStereotype.setAttribute(new Attribute(SDOAlias.PHYSICAL_NAME, alias.getPhysicalName())); if (alias.getLocalName() != null) aliasStereotype.setAttribute(new Attribute(SDOAlias.LOCAL_NAME, alias.getLocalName().trim())); if (alias.getBusinessName() != null) aliasStereotype.setAttribute(new Attribute(SDOAlias.BUSINESS_NAME, alias.getBusinessName().trim())); } private Element buildProperty(Package pkg, Class clss, Property property, Element parentElem) { if (log.isDebugEnabled()) log.debug("creating property " + property.getName()); Element ownedAttribute = new Element("ownedAttribute"); parentElem.addContent(ownedAttribute); ownedAttribute.setAttribute(new Attribute("type", "uml:Property", xmiNs)); ownedAttribute.setAttribute(new Attribute("id", property.getId(), xmiNs)); ownedAttribute.setAttribute(new Attribute("name", property.getName())); if (property.getVisibility() != null) ownedAttribute.setAttribute(new Attribute("visibility", property.getVisibility().value())); if (property.getDocumentations() != null) for (Documentation doc : property.getDocumentations()) { if (doc.getBody() != null) addOwnedComment(ownedAttribute, property.getId(), doc.getBody().getValue()); } Element upperValue = new Element("upperValue"); ownedAttribute.addContent(upperValue); upperValue.setAttribute(new Attribute("type", "uml:LiteralUnlimitedNatural", xmiNs)); upperValue.setAttribute(new Attribute("id", UUID.randomUUID().toString(), xmiNs)); upperValue.setAttribute(new Attribute("visibility", "public")); if (property.isMany()) upperValue.setAttribute(new Attribute("value", "*")); else upperValue.setAttribute(new Attribute("value", "1")); Element lowerValue = new Element("lowerValue"); ownedAttribute.addContent(lowerValue); lowerValue.setAttribute(new Attribute("type", "uml:LiteralInteger", xmiNs)); lowerValue.setAttribute(new Attribute("id", UUID.randomUUID().toString(), xmiNs)); lowerValue.setAttribute(new Attribute("visibility", "public")); if (property.isNullable()) lowerValue.setAttribute(new Attribute("value", "0")); else lowerValue.setAttribute(new Attribute("value", "1")); if (property.getType() instanceof DataTypeRef) { Element type = new Element("type"); ownedAttribute.addContent(type); type.setAttribute(new Attribute("type", "uml:DataType", xmiNs)); //type.setAttribute(new Attribute("id", UUID.randomUUID().toString(), xmiNs)); type.setAttribute( new Attribute("href", this.dataTypeHRefPrefix + ((DataTypeRef) property.getType()).getName())); } else { // set reference specific attribs ClassRef targetClassRef = (ClassRef) property.getType(); Class targetClass = classMap.get(targetClassRef.getUri() + "#" + targetClassRef.getName()); ownedAttribute.setAttribute(new Attribute("type", targetClass.getId())); } // add stereotypes in order of "priority" in terms of how we // would like them to appear in UML tools if (property.getKey() != null) { Element keyStereotype = new Element(SDOKey.class.getSimpleName(), plasmaNs); this.xmiElem.addContent(keyStereotype); keyStereotype.setAttribute(new Attribute("id", UUID.randomUUID().toString(), xmiNs)); keyStereotype.setAttribute(new Attribute(SDOKey.BASE__PROPERTY, property.getId())); keyStereotype.setAttribute(new Attribute(SDOKey.TYPE, // provisioning key-type is JAXB generated and upper-case property.getKey().getType().name().toLowerCase())); } if (property.getUniqueConstraint() != null) { Element uniqueStereotype = new Element(SDOUniqueConstraint.class.getSimpleName(), plasmaNs); this.xmiElem.addContent(uniqueStereotype); uniqueStereotype.setAttribute(new Attribute("id", UUID.randomUUID().toString(), xmiNs)); uniqueStereotype.setAttribute(new Attribute(SDOUniqueConstraint.BASE__PROPERTY, property.getId())); uniqueStereotype.setAttribute( new Attribute(SDOUniqueConstraint.GROUP, property.getUniqueConstraint().getGroup())); } if (property.getAlias() != null) { addAlias(property.getAlias(), property.getId()); } if (property.getSort() != null) { Element sequenceStereotype = new Element(SDOSort.class.getSimpleName(), plasmaNs); this.xmiElem.addContent(sequenceStereotype); sequenceStereotype.setAttribute(new Attribute("id", UUID.randomUUID().toString(), xmiNs)); sequenceStereotype.setAttribute(new Attribute(SDOSort.BASE__PROPERTY, property.getId())); sequenceStereotype .setAttribute(new Attribute(SDOSort.KEY, String.valueOf(property.getSort().getKey()))); } if (property.getXmlProperty() != null) { Element xmlPropertyStereotype = new Element(SDOXmlProperty.class.getSimpleName(), plasmaNs); this.xmiElem.addContent(xmlPropertyStereotype); xmlPropertyStereotype.setAttribute(new Attribute("id", UUID.randomUUID().toString(), xmiNs)); xmlPropertyStereotype.setAttribute(new Attribute(SDOXmlProperty.BASE__PROPERTY, property.getId())); xmlPropertyStereotype.setAttribute(new Attribute(SDOXmlProperty.NODE_TYPE, property.getXmlProperty().getNodeType().name().toLowerCase())); } if (property.getValueConstraint() != null) { Element valueContStereotype = new Element(SDOValueConstraint.class.getSimpleName(), plasmaNs); this.xmiElem.addContent(valueContStereotype); valueContStereotype.setAttribute(new Attribute("id", UUID.randomUUID().toString(), xmiNs)); valueContStereotype.setAttribute(new Attribute(SDOValueConstraint.BASE__PROPERTY, property.getId())); ValueConstraint vc = property.getValueConstraint(); if (vc.getTotalDigits() != null) valueContStereotype.setAttribute( new Attribute(SDOValueConstraint.TOTAL_DIGITS, String.valueOf(vc.getTotalDigits()))); if (vc.getFractionDigits() != null) valueContStereotype.setAttribute( new Attribute(SDOValueConstraint.FRACTION_DIGITS, String.valueOf(vc.getFractionDigits()))); if (vc.getMaxInclusive() != null) valueContStereotype.setAttribute( new Attribute(SDOValueConstraint.MAX_INCLUSIVE, String.valueOf(vc.getMaxInclusive()))); if (vc.getMaxExclusive() != null) valueContStereotype.setAttribute( new Attribute(SDOValueConstraint.MAX_EXCLUSIVE, String.valueOf(vc.getMaxExclusive()))); if (vc.getMaxLength() != null) valueContStereotype.setAttribute( new Attribute(SDOValueConstraint.MAX_LENGTH, String.valueOf(vc.getMaxLength()))); if (vc.getMinInclusive() != null) valueContStereotype.setAttribute( new Attribute(SDOValueConstraint.MIN_INCLUSIVE, String.valueOf(vc.getMinInclusive()))); if (vc.getMinExclusive() != null) valueContStereotype.setAttribute( new Attribute(SDOValueConstraint.MIN_EXCLUSIVE, String.valueOf(vc.getMinExclusive()))); if (vc.getMinLength() != null) valueContStereotype.setAttribute( new Attribute(SDOValueConstraint.MIN_LENGTH, String.valueOf(vc.getMinLength()))); if (vc.getPattern() != null) valueContStereotype .setAttribute(new Attribute(SDOValueConstraint.PATTERN, String.valueOf(vc.getPattern()))); } if (property.getEnumerationConstraint() != null) { Element enumConstraintStereotype = new Element(SDOEnumerationConstraint.class.getSimpleName(), plasmaNs); this.xmiElem.addContent(enumConstraintStereotype); enumConstraintStereotype.setAttribute(new Attribute("id", UUID.randomUUID().toString(), xmiNs)); enumConstraintStereotype .setAttribute(new Attribute(SDOUniqueConstraint.BASE__PROPERTY, property.getId())); EnumerationConstraint constraint = property.getEnumerationConstraint(); EnumerationRef enumRef = constraint.getValue(); String enumRefId = enumRef.getUri() + "#" + enumRef.getName(); Element enumeration = this.enumElementMap.get(enumRefId); if (enumeration == null) { enumeration = this.buildEnumeration(constraint); Element pkgElement = this.elementMap.get(pkg.getId()); pkgElement.addContent(enumeration); this.enumElementMap.put(enumRefId, enumeration); } Attribute enumId = enumeration.getAttribute("id", xmiNs); enumConstraintStereotype.setAttribute(new Attribute(SDOEnumerationConstraint.VALUE, enumId.getValue())); } return ownedAttribute; } private Element buildAssociation(Property property, Property targetProperty, Element parentElem, String uuid) { Element associationElem = new Element("packagedElement"); parentElem.addContent(associationElem); associationElementMap.put(property.getId(), associationElem); associationElementMap.put(targetProperty.getId(), associationElem); associationElem.setAttribute(new Attribute("type", "uml:Association", xmiNs)); associationElem.setAttribute(new Attribute("id", uuid, xmiNs)); associationElem.setAttribute(new Attribute("visibility", "public")); Element leftMemberEnd = new Element("memberEnd"); associationElem.addContent(leftMemberEnd); leftMemberEnd.setAttribute(new Attribute("idref", property.getId(), xmiNs)); Element rightMemberEnd = new Element("memberEnd"); associationElem.addContent(rightMemberEnd); rightMemberEnd.setAttribute(new Attribute("idref", targetProperty.getId(), xmiNs)); return associationElem; } private Element buildAssociation(Property property, Class targetClass, Element parentElem, String uuid) { Element association = new Element("packagedElement"); parentElem.addContent(association); association.setAttribute(new Attribute("type", "uml:Association", xmiNs)); association.setAttribute(new Attribute("id", uuid, xmiNs)); association.setAttribute(new Attribute("visibility", "public")); Element leftMemberEnd = new Element("memberEnd"); association.addContent(leftMemberEnd); leftMemberEnd.setAttribute(new Attribute("idref", property.getId(), xmiNs)); String rightPropId = UUID.randomUUID().toString(); Element rightMemberEnd = new Element("memberEnd"); association.addContent(rightMemberEnd); rightMemberEnd.setAttribute(new Attribute("idref", rightPropId, xmiNs)); Element navigableOwnedEnd = new Element("navigableOwnedEnd"); association.addContent(navigableOwnedEnd); navigableOwnedEnd.setAttribute(new Attribute("idref", rightPropId, xmiNs)); Element ownedEnd = new Element("ownedEnd"); association.addContent(ownedEnd); ownedEnd.setAttribute(new Attribute("type", "uml:Property", xmiNs)); ownedEnd.setAttribute(new Attribute("id", rightPropId, xmiNs)); ownedEnd.setAttribute(new Attribute("visibility", "private")); ownedEnd.setAttribute(new Attribute("type", targetClass.getId())); // if its external we'll need this goo /* { targetClassId = targetClassInfo.getSharedPackage().getExternalReferenceBase() + "#" + targetClassInfo.getUuid(); Element type = new Element("type"); ownedEnd.addContent(type); type.setAttribute(new Attribute("type", "uml:Class", xmiNs)); type.setAttribute(new Attribute("href", targetClassId)); } */ Element upperValue = new Element("upperValue"); ownedEnd.addContent(upperValue); upperValue.setAttribute(new Attribute("type", "uml:LiteralUnlimitedNatural", xmiNs)); upperValue.setAttribute(new Attribute("id", UUID.randomUUID().toString(), xmiNs)); upperValue.setAttribute(new Attribute("visibility", "public")); upperValue.setAttribute(new Attribute("value", "*")); Element lowerValue = new Element("lowerValue"); ownedEnd.addContent(lowerValue); lowerValue.setAttribute(new Attribute("type", "uml:LiteralInteger", xmiNs)); lowerValue.setAttribute(new Attribute("id", UUID.randomUUID().toString(), xmiNs)); lowerValue.setAttribute(new Attribute("visibility", "public")); return association; } private Element buildEnumeration(EnumerationConstraint constraint) { Enumeration enm = this.enumMap.get(constraint.getValue().getUri() + "#" + constraint.getValue().getName()); Element enumerationElem = new Element("packagedElement"); enumerationElem.setAttribute(new Attribute("type", "uml:Enumeration", xmiNs)); String enumId = UUID.randomUUID().toString(); enumerationElem.setAttribute(new Attribute("id", enumId, xmiNs)); enumerationElem.setAttribute(new Attribute("name", enm.getName())); enumerationElem.setAttribute(new Attribute("visibility", "public")); if (enm.getDocumentations() != null) for (Documentation doc : enm.getDocumentations()) { addOwnedComment(enumerationElem, enumId, doc.getBody().getValue()); } for (EnumerationLiteral lit : enm.getEnumerationLiterals()) { Element literal = new Element("ownedLiteral"); enumerationElem.addContent(literal); literal.setAttribute(new Attribute("type", "uml:EnumerationLiteral", xmiNs)); String literalId = UUID.randomUUID().toString(); literal.setAttribute(new Attribute("id", literalId, xmiNs)); literal.setAttribute(new Attribute("name", lit.getValue())); literal.setAttribute(new Attribute("visibility", "public")); if (lit.getDocumentations() != null) for (Documentation doc : lit.getDocumentations()) { addOwnedComment(literal, literalId, doc.getBody().getValue()); } if (lit.getAlias() != null && lit.getAlias().getPhysicalName() != null) { Element aliasStereotype = new Element(SDOAlias.class.getSimpleName(), plasmaNs); this.xmiElem.addContent(aliasStereotype); aliasStereotype.setAttribute(new Attribute("id", UUID.randomUUID().toString(), xmiNs)); aliasStereotype.setAttribute(new Attribute(SDOAlias.BASE__NAMED_ELEMENT, literalId)); aliasStereotype .setAttribute(new Attribute(SDOAlias.PHYSICAL_NAME, lit.getAlias().getPhysicalName())); } } return enumerationElem; } private void addOwnedComment(Element owner, String ownerId, String commentBody) { Element comment = new Element("ownedComment"); owner.addContent(comment); comment.setAttribute(new Attribute("type", "uml:Comment", xmiNs)); comment.setAttribute(new Attribute("id", UUID.randomUUID().toString(), xmiNs)); Element body = new Element("body"); comment.addContent(body); body.addContent(new CDATA(commentBody)); Element annotatedElement = new Element("annotatedElement"); comment.addContent(annotatedElement); annotatedElement.setAttribute(new Attribute("idref", ownerId, xmiNs)); } private Class getOppositeClass(Class def, Property propertyDef) { Class targetDef = classMap.get(propertyDef.getType().getUri() + "#" + propertyDef.getType().getName()); return targetDef; } private Property getOppositeProperty(Class def, Property propertyDef) { Class targetDef = classMap.get(propertyDef.getType().getUri() + "#" + propertyDef.getType().getName()); for (Property p : targetDef.getProperties()) { if (p.getName().equals(propertyDef.getOpposite())) return p; } return null; } }