
cb.xmi.XMIGenerator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.crazybeans Show documentation
Show all versions of org.crazybeans Show documentation
Java library to read, modify or create Rational Rose petal files
The newest version!
/**
* 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