
cb.xmi.XMIGenerator Maven / Gradle / Ivy
/**
* Copyright (c) 2001 Markus Dahm
* Copyright (C) 2015-2018 BITPlan GmbH http://www.bitplan.com
*
* This source is part of
* https://github.com/BITPlan/CrazyBeans
* and the license as outlined there applies
*/
package cb.xmi;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Stack;
import ru.novosoft.uml.foundation.core.MAbstraction;
import ru.novosoft.uml.foundation.core.MAssociation;
import ru.novosoft.uml.foundation.core.MAttribute;
import ru.novosoft.uml.foundation.core.MClassifier;
import ru.novosoft.uml.foundation.core.MDependency;
import ru.novosoft.uml.foundation.core.MGeneralization;
import ru.novosoft.uml.foundation.core.MModelElement;
import ru.novosoft.uml.foundation.core.MOperation;
import ru.novosoft.uml.foundation.core.MUsage;
import ru.novosoft.uml.model_management.MModel;
import ru.novosoft.uml.model_management.MPackage;
import ru.novosoft.uml.xmi.XMIWriter;
import cb.generator.Generator;
import cb.generator.GeneratorVisitor;
import cb.petal.Association;
import cb.petal.ClassAttribute;
import cb.petal.DependencyRelationship;
import cb.petal.DescendingVisitor;
import cb.petal.InheritanceRelationship;
import cb.petal.LogicalCategory;
import cb.petal.Module;
import cb.petal.Operation;
import cb.petal.PetalFile;
import cb.petal.PetalObject;
import cb.petal.QuidObject;
import cb.petal.RealizeRelationship;
import cb.petal.SubSystem;
import cb.petal.UseCase;
import cb.petal.UseCaseCategory;
import cb.petal.UsesRelationship;
/**
* Convert a Rose petal file into the XMI format using NovoSoft's NSUML package which implements the
* entities defined in the UML
* specification 1.3.
*
* @version $Id: XMIGenerator.java,v 1.8 2005/05/09 20:34:55 moroff Exp $
* @author M. Dahm
*/
public class XMIGenerator extends GeneratorVisitor implements Generator {
/**
* Which factory to use
*/
protected XMIFactory factory;
/**
* The XMI model being set up
*/
protected MModel model;
/**
* Stack
*/
private Stack packages = new Stack();
/**
* The current package level (may be nested)
*/
private MPackage pack;
/**
* Register created objects by the quid of the petal object.
*/
protected Map quid_map = new HashMap(); // Map
/**
* link Categories to MPackages
*/
protected Map package_map = new HashMap(); // Map
/**
* add the given classifier object to the by-Quid lookup map
* @param quid
* @param obj
*/
protected final void addObject(String quid, MClassifier obj) {
quid_map.put(quid, obj);
}
/**
* remove an Object
* @param quid
*/
protected void removeObject(String quid) {
quid_map.remove(quid);
}
/**
* lookup a classifier by quid
* @param quid
* @return - the classifier found
*/
protected final MClassifier getClassifier(String quid) {
return quid_map.get(quid);
}
/**
* get the Package for the given quid
* @param quid - the quid to lookup
* @return - the package
*/
@SuppressWarnings("rawtypes")
protected final MPackage getPackage(String quid) {
// FIXME performance and readbility could be improved with another Map
for (Iterator iter = package_map.values().iterator(); iter.hasNext();) {
java.lang.Object element = (java.lang.Object) iter.next();
if (element instanceof MPackage) {
MPackage modelPackage = (MPackage) element;
if (modelPackage.getUUID().equals(quid))
return modelPackage;
}
}
return null;
}
/**
* @param tree
* the Rose petal file to convert
* @param dump
* where to dump the generated XMI file
*/
public XMIGenerator(PetalFile tree, String dump) {
setDumpPath(dump);
setTree(tree);
}
@Override
public void init() {
factory = getFactory();
model = factory.createModel();
pack = model;
}
/**
* Start generation of XMI code.
*/
@Override
public void start() {
/*
* Run a first pass visitor to add all packages, classes, use cases, etc.
* that may be referenced from different places, or even be referenced in a
* forward declaration.
*/
getTree().accept(new DescendingVisitor() {
private void addPackage(QuidObject obj, MPackage p) {
package_map.put(obj, p);
pack.addOwnedElement(p);
packages.push(pack); // Save old value
pack = p;
super.visitObject(obj); // Default traversal
pack = (MPackage) packages.pop();
}
public void visit(LogicalCategory obj) {
addPackage(obj, factory.createPackage(obj));
}
public void visit(UseCaseCategory obj) {
addPackage(obj, factory.createPackage(obj));
}
public void visit(SubSystem sub) {
/**
* ArgoUML can't handle subsystems
*/
addPackage(sub, factory.createPackage(sub));
}
public void visit(cb.petal.Class clazz) {
String quid = clazz.getQuid();
MClassifier cl = factory.createClass(clazz);
pack.addOwnedElement(cl);
addObject(quid, cl);
}
public void visit(UseCase caze) {
String quid = caze.getQuid();
MClassifier cl = factory.createUseCase(caze);
pack.addOwnedElement(cl);
addObject(quid, cl);
}
public void visit(Module module) {
String quid = module.getQuid();
MClassifier cl = factory.createComponent(module);
pack.addOwnedElement(cl);
addObject(quid, cl);
}
});
getTree().accept(this);
}
/**
* Override this if you don't like the default factory
*/
protected XMIFactory getFactory() {
return new XMIFactory(getTree(), this);
}
private void setPackage(QuidObject obj) {
MPackage p = (MPackage) package_map.get(obj);
packages.push(pack); // Save old value
pack = p;
visitObject(obj); // Default traversal
pack = (MPackage) packages.pop();
}
public void visit(LogicalCategory obj) {
setPackage(obj);
}
public void visit(UseCaseCategory obj) {
setPackage(obj);
}
public void visit(SubSystem obj) {
/**
* ArgoUML can't handle subsystems
*/
setPackage(obj);
}
public void visit(ClassAttribute attr) {
MAttribute a = factory.createAttribute(attr);
MClassifier clazz = getContainingClassifier(attr);
clazz.addFeature(a);
}
public void visit(Operation op) {
MOperation m = factory.createOperation(op);
MClassifier clazz = getContainingClassifier(op);
clazz.addFeature(m);
}
public void visit(InheritanceRelationship rel) {
MGeneralization gen = factory.createGeneralization(rel);
pack.addOwnedElement(gen);
}
public void visit(UsesRelationship rel) {
MUsage usage = factory.createUsage(rel);
pack.addOwnedElement(usage);
}
public void visit(DependencyRelationship rel) {
MDependency dependency = factory.createDependency(rel);
pack.addOwnedElement(dependency);
}
public void visit(RealizeRelationship rel) {
MAbstraction real = factory.createRealization(rel);
pack.addOwnedElement(real);
}
/**
* If this association contains an association class, use that object,
* otherwise create new object.
*/
public void visit(Association assoc) {
MAssociation a;
/*
* ArgoUML/Poseidon can't handle AssociationClass correctly
*/
cb.petal.Class clazz = assoc.getAssociationClass();
if (clazz != null) {
a = (MAssociation) getClassifier(clazz.getQuid());
factory.setupAssociation(assoc, a);
} else {
a = factory.createAssociation(assoc);
pack.addOwnedElement(a);
}
}
/*************************** Utility method *******************************/
/**
* Search for element of given name in model (and all sub-packages)
*
* @param name
* name to look for with getName()
* @param clazz
* Class searched element is an instance of
* @return found element or null
*/
public MModelElement searchElement(String name, java.lang.Class> clazz) {
return searchElement(model, name, clazz);
}
private static MModelElement searchElement(MPackage pack, String name,
java.lang.Class> clazz) {
for (@SuppressWarnings("unchecked")
Iterator i = pack.getOwnedElements().iterator(); i.hasNext();) {
MModelElement elem = i.next();
if (name.indexOf("::") > 0 && getQualifiedName(elem).equals(name)
&& clazz.isInstance(elem))
return elem;
else if (name.equals(elem.getName()) && clazz.isInstance(elem))
return elem;
else if (elem instanceof MPackage) {
MModelElement found = searchElement((MPackage) elem, name, clazz);
if (found != null)
return found;
}
}
return null;
}
/**
* @return XMI object for containing class of obj
*/
protected final MClassifier getContainingClassifier(PetalObject obj) {
return getClassifier(((QuidObject) obj.getParent()).getQuid());
}
/**
* @return XMI object for containing class of obj
*/
protected final MPackage getContainingPackage(PetalObject obj) {
return getPackage(((QuidObject) obj.getParent()).getQuid());
}
/**
* dump the xmi result
* @throws IOException
* @throws ru.novosoft.uml.xmi.IncompleteXMIException
*/
@Override
public void dump() throws IOException,
ru.novosoft.uml.xmi.IncompleteXMIException {
XMIWriter writer;
PrintWriter outwriter = null;
if (getDumpPath() == null || "-".equals(getDumpPath())) {
outwriter = new PrintWriter(System.out);
writer = new XMIWriter(model, outwriter);
} else {
writer = new XMIWriter(model, getDumpPath());
}
writer.gen();
writer.close();
if (outwriter!=null) {
outwriter.close();
}
}
/**
* @return generated model
*/
public MModel getModel() {
return model;
}
/**
* @return current package
*/
public MPackage getPackage() {
return pack;
}
/**
* get a qualifiedName for the given model element
* @param modelElement
* @return - the qualified name for a model element
*/
private static String getQualifiedName(MModelElement modelElement) {
StringBuffer buffer = new StringBuffer();
buffer.append(modelElement.getName());
while (modelElement.getNamespace() != null
&& !(modelElement.getNamespace() instanceof MModel)) {
modelElement = modelElement.getNamespace();
buffer.insert(0, "::");
buffer.insert(0, modelElement.getName());
}
return buffer.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy