Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.plasma.xml.uml.DefaultUMLModelAssembler Maven / Gradle / Ivy
/**
* Copyright 2017 TerraMeta Software, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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.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.metamodel.Alias;
import org.plasma.metamodel.Behavior;
import org.plasma.metamodel.Class;
import org.plasma.metamodel.ClassRef;
import org.plasma.metamodel.DataTypeRef;
import org.plasma.metamodel.Documentation;
import org.plasma.metamodel.Enumeration;
import org.plasma.metamodel.EnumerationConstraint;
import org.plasma.metamodel.EnumerationLiteral;
import org.plasma.metamodel.EnumerationRef;
import org.plasma.metamodel.Model;
import org.plasma.metamodel.Package;
import org.plasma.metamodel.Property;
import org.plasma.metamodel.ValueConstraint;
import org.plasma.runtime.ConfigUtils;
//import org.plasma.provisioning.MetamodelAssembler;
//import org.plasma.provisioning.MetamodelDataBinding;
//import org.plasma.provisioning.xsd.SchemaMetamodelAssembler;
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 packageMap = new HashMap();
private Map classMap = new HashMap();
private Map classPackageMap = new HashMap();
private Map enumMap = new HashMap();
private Map enumPackageMap = new HashMap();
private Element xmiElem;
private Element modelElem;
private Map elementMap = new HashMap();
private Map associationElementMap = new HashMap();
private Map enumElementMap = new HashMap();
@SuppressWarnings("unused")
private DefaultUMLModelAssembler() {
}
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(Schema schema, String destNamespaceURI,
// String destNamespacePrefix) {
// SchemaMetamodelAssembler stagingAssembler = new
// SchemaMetamodelAssembler(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));
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);
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);
}
}
}
// add profile applications
Element profileApplicationElem = buildProfileApplication();
if (profileApplicationElem != null)
this.modelElem.addContent(profileApplicationElem);
return document;
}
private void collectPackages(Package pkg) {
if (pkg.getUri() != null) {
packageMap.put(pkg.getUri() + "#" + pkg.getName(), pkg);
}
for (Package child : pkg.getPackages()) {
collectPackages(child);
}
}
private void collectClasses(Package pkg) {
mapClasses(pkg);
for (Package child : pkg.getPackages())
collectClasses(child);
}
private void mapClasses(Package pkg) {
for (Class clss : pkg.getClazzs()) {
classMap.put(clss.getUri() + "#" + clss.getName(), clss);
classPackageMap.put(clss, pkg);
}
}
private void collectEnumerations(Package pkg) {
mapEnumerations(pkg);
for (Package child : pkg.getPackages())
collectEnumerations(child);
}
private void mapEnumerations(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 stereotype, 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());
} else {
for (Package child : model.getPackages())
addPackages(child, modelElem);
}
return modelElem;
}
private void addPackages(Package pkg, Element parent) {
Element pkgElem = new Element("packagedElement");
parent.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());
if (pkg.getUri() != null && pkg.getUri().length() > 0) {
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 : pkg.getDocumentations()) {
addOwnedComment(pkgElem, pkg.getId(), doc.getBody().getValue());
}
for (Package child : pkg.getPackages())
addPackages(child, pkgElem);
}
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()));
if (clss.isAbstract())
clssElem.setAttribute(new Attribute("isAbstract", "true"));
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);
String ref = baseRef.getUri() + "#" + baseRef.getName();
Class baseClass = classMap.get(ref);
if (baseClass != null) {
generalizationElem.setAttribute(new Attribute("general", baseClass.getId()));
} else { // assume an external reference
Element generalElem = new Element("general");
generalizationElem.addContent(generalElem);
generalElem.setAttribute(new Attribute("type", "uml:Class", xmiNs));
generalElem.setAttribute(new Attribute("href", ref));
}
}
/*
* --e.g. XMI for an external reference
*
*/
if (clss.getBehaviors().size() > 0)
addBehaviors(clss, clssElem, clss.getBehaviors());
return clssElem;
}
/**
* Adds a UML owned opaque behavior ala. below for each provisioning behavior.
*
* FOO BAR; SQL
*
*
* @param clss
* the
* @param clssElem
* the element
* @param behaviors
* the bahaviors
*/
private void addBehaviors(Class clss, Element clssElem, List 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;
}
}