org.plasma.xml.uml.DefaultUMLModelAssembler Maven / Gradle / Ivy
/**
* 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
* .
*
*/
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.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventLocator;
import javax.xml.namespace.QName;
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.config.ConfigUtils;
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.provisioning.MetamodelAssembler;
import org.plasma.provisioning.MetamodelDataBinding;
import org.plasma.provisioning.SchemaMetamodelAssembler;
import org.plasma.query.Query;
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() {}
@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)
{
MetamodelAssembler stagingAssembler = new MetamodelAssembler(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;
}
};
MetamodelDataBinding binding =
new MetamodelDataBinding(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)
{
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()));
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;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy