cb.util.PetalObjectFactory 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.util;
import cb.petal.AssocAttachView;
import cb.petal.Association;
import cb.petal.AssociationViewNew;
import cb.petal.AttachView;
import cb.petal.ClassAttribute;
import cb.petal.ClassDiagram;
import cb.petal.ClassUtility;
import cb.petal.ClassView;
import cb.petal.Font;
import cb.petal.InheritView;
import cb.petal.Inheritable;
import cb.petal.InheritanceRelationship;
import cb.petal.ItemLabel;
import cb.petal.LogicalCategory;
import cb.petal.NoteView;
import cb.petal.Operation;
import cb.petal.PetalFile;
import cb.petal.PetalNode;
import cb.petal.QuidObject;
import cb.petal.RealizeRelationship;
import cb.petal.RealizeView;
import cb.petal.Relationship;
import cb.petal.RelationshipView;
import cb.petal.Role;
import cb.petal.RoleView;
import cb.petal.SegLabel;
import cb.petal.StringLiteral;
import cb.petal.UseCase;
import cb.petal.UseCaseCategory;
import cb.petal.UseCaseDiagram;
import cb.petal.UseCaseView;
import cb.petal.UsesRelationship;
import cb.petal.UsesView;
import java.io.*;
import java.util.*;
import java.awt.Dimension;
/**
* Create empty Petal objects with just some initial properties (the quid in
* particular) set up. The user can then add them to model, i.e. PetalFile
* object. Some objects are created by reading serialized templates from the
* templates directory. init() is called on them usually automagically when
* they're added to the model.
*
* @see PetalFile
* @version $Id: PetalObjectFactory.java,v 1.13 2001/07/30 15:49:37 dahm Exp $
* @author M. Dahm
*/
public class PetalObjectFactory {
private static PetalObjectFactory instance = new PetalObjectFactory();
private static String templateRoot;
public static PetalObjectFactory getInstance() {
return instance;
}
public static void setInstance(PetalObjectFactory inst) {
instance = inst;
}
/**
* @return the templateRoot
*/
public String getTemplateRoot() {
return templateRoot;
}
public void setTemplateRoot(String templateRoot) {
this.templateRoot = templateRoot;
}
protected PetalObjectFactory() {
}
/**
* Read the object of the given type (name) from templates directory looking
* for a file with suffix ".ser"
*
* @param name - template file name path
* @return - the petalNode that was initialized from the given serialized java object template
*/
public PetalNode getTemplate(String name) {
PetalNode obj = null;
try {
String file = templateRoot + name + ".ser";
InputStream is = PetalObjectFactory.class.getResourceAsStream(file);
if (is == null)
throw new RuntimeException("File not found: " + file);
ObjectInputStream ois = new ObjectInputStream(is);
obj = (PetalNode) ois.readObject();
ois.close();
} catch (Exception e) {
throw new RuntimeException("Could not create template for " + name
+ ":\n" + e);
}
return obj;
}
/******************* Data model create methods ********************/
/**
* Creates empty model.
*/
public PetalFile createModel() {
PetalFile file = (PetalFile) getTemplate("PetalFile");
return file;
}
/**
* Creates empty class object with just the name and the quid set. init() is
* called on it after has been added to a model.
*
* @see LogicalCategory#addToModel(cb.petal.Class)
*/
public cb.petal.Class createClass(String name) {
cb.petal.Class clazz = new cb.petal.Class();
clazz.setQuid(PetalFile.getQuid());
clazz.setParameterList(new ArrayList(Arrays.asList(new String[] { name })));
return clazz;
}
/**
* Creates use case object with just the name and the quid set. init() is
* called on it after has been added to a model.
*
* @see UseCaseCategory#addToModel(UseCase)
*/
public UseCase createUseCase(String name) {
UseCase caze = new UseCase();
caze.setQuid(PetalFile.getQuid());
caze.setParameterList(new ArrayList(Arrays.asList(new String[] { name })));
return caze;
}
/**
* Just like createClass() except that it sets the stereotype to "Interface".
*/
public cb.petal.Class createInterface(String name) {
cb.petal.Class clazz = createClass(name);
clazz.setStereotype("Interface");
return clazz;
}
/**
* Creates empty utility class object with just the name and the quid set.
* init() is called on it after has been added to a model.
*
* @see LogicalCategory#addToModel(cb.petal.Class)
*/
public cb.petal.ClassUtility createClassUtility(String name) {
ClassUtility clazz = new ClassUtility();
clazz.setParameterList(new ArrayList(Arrays.asList(new String[] { name })));
clazz.setQuid(PetalFile.getQuid());
return clazz;
}
/**
* Creates new operation (aka method)
*
* @see cb.petal.Class#addOperation(cb.petal.Operation)
*/
public Operation createOperation(String name, String result,
cb.petal.PetalNodeList params) {
Operation op = (Operation) getTemplate("Operation");
op.setQuid(PetalFile.getQuid());
op.setNameParameter(name);
if (result != null)
op.setResult(result);
else
op.removeProperty("result");
op.setParameters(params);
return op;
}
/**
* Creates new class attribute (aka field)
*
* @see cb.petal.Class#addClassAttribute(cb.petal.ClassAttribute)
*/
public ClassAttribute createClassAttribute(String name, String type) {
ClassAttribute attr = new ClassAttribute(null,
Arrays.asList(new String[] { name }));
attr.setQuid(PetalFile.getQuid());
attr.setType(type);
return attr;
}
/**
* Creates empty class category (use case view).
*/
public UseCaseCategory createUseCaseCategory(String name) {
UseCaseCategory cat = (UseCaseCategory) getTemplate("UseCaseCategory");
cat.setQuid(PetalFile.getQuid());
cat.setNameParameter(name);
cat.getFirstUseCaseDiagram().setQuid(PetalFile.getQuid());
return cat;
}
/**
* Creates empty class category (logical view).
*
* @see LogicalCategory#addToModel(cb.petal.LogicalCategory)
*/
public LogicalCategory createLogicalCategory(String name) {
LogicalCategory cat = (LogicalCategory) getTemplate("LogicalCategory");
cat.setQuid(PetalFile.getQuid());
cat.setNameParameter(name);
cat.getFirstClassDiagram().setQuid(PetalFile.getQuid());
cat.removeProperty("quidu");
cat.removeProperty("subsystem");
cat.removeProperty("global");
return cat;
}
private void setupRelationship(Relationship rel, Inheritable clazz, // Should
// be
// Inheritable
Inheritable super_class) {
rel.setQuid(PetalFile.getQuid());
rel.setSupplier(super_class.getQualifiedName());
rel.setQuidu(super_class.getQuid());
rel.setParent(clazz);
}
/**
* Create InheritanceRelationship between two classes, this method is called
* by Class.addSuperClass(). Shouldn't be called directly I think. If you
* really want to, don't forget to call init().
*
* @see cb.petal.Inheritable#addSuperClassifier(cb.petal.Inheritable)
*/
public InheritanceRelationship createInheritanceRelationship(
Inheritable clazz, Inheritable super_class) {
InheritanceRelationship rel = new InheritanceRelationship();
setupRelationship(rel, clazz, super_class);
return rel;
}
/**
* Create RealizeRelationship between class and an interface, called by
* Class.addImplementedInterface(). Shouldn't be called directly I think. If
* you really want to, don't forget to call init().
*
* @see cb.petal.Class#addImplementedInterface(cb.petal.Class)
*/
public RealizeRelationship createRealizeRelationship(cb.petal.Class clazz,
cb.petal.Class inter) {
RealizeRelationship rel = new RealizeRelationship();
setupRelationship(rel, clazz, inter);
return rel;
}
/**
* Create UsesRelationship between class and an interface, called by
* Class.addUsedClass(). Shouldn't be called directly I think. If you really
* want to, don't forget to call init().
*
* @see cb.petal.Class#addUsedClass(cb.petal.Class)
*/
public UsesRelationship createUsesRelationship(cb.petal.Class clazz,
cb.petal.Class clazz2) {
UsesRelationship rel = new UsesRelationship();
setupRelationship(rel, clazz, clazz2);
return rel;
}
private int assoc_counter = 1;
public final String getAnonymousName() {
return "$UNNAMED$" + assoc_counter++;
}
/**
* Create Association between two classes. Cardinality and other properties
* can be configured in the roles of the returned object. Classes must have
* already been added to the model.
*/
public Association createAssociation(String name, cb.petal.Class clazz1,
cb.petal.Class clazz2) {
return createAssociation_(name, clazz1, clazz2);
}
/**
* Create association without explicit name, it will have an invisible
* anonymous name.
*/
public Association createAssociation(cb.petal.Class clazz1,
cb.petal.Class clazz2) {
return createAssociation_(getAnonymousName(), clazz1, clazz2);
}
/**
* Create Association between two use cases. Use cases must have already been
* added to the model.
*/
public Association createAssociation(String name, UseCase case1, UseCase case2) {
return createAssociation_(name, case1, case2);
}
public Association createAssociation(String name, cb.petal.Class clazz,
UseCase caze) {
return createAssociation_(name, clazz, caze);
}
public Association createAssociation(cb.petal.Class clazz, UseCase caze) {
return createAssociation_(getAnonymousName(), clazz, caze);
}
/**
* Create association without explicit name, it will have an invisible
* anonymous name.
*/
public Association createAssociation(UseCase case1, UseCase case2) {
return createAssociation_(getAnonymousName(), case1, case2);
}
private Association createAssociation_(String name, QuidObject clazz1,
QuidObject clazz2) {
Association assoc = (Association) getTemplate("Association");
assoc.setQuid(PetalFile.getQuid());
assoc.setNameParameter(name);
Role first = assoc.getFirstRole();
Role second = assoc.getSecondRole();
first.setNameParameter(getAnonymousName());
second.setNameParameter(getAnonymousName());
first.setQuid(PetalFile.getQuid());
second.setQuid(PetalFile.getQuid());
first.setQuidu(clazz1.getQuid());
second.setQuidu(clazz2.getQuid());
first.setParent(assoc);
second.setParent(assoc);
first.setSupplier(clazz1.getQualifiedName());
second.setSupplier(clazz2.getQualifiedName());
return assoc;
}
/******************* View create methods ********************/
/**
* Creates class view for given class and sets the qualified name and quidu
* for the referenced class accordingly. The tag, i.e., the index in the views
* list (@12, e.g.), is set when the view is added to the model. It is also
* set them for the ItemLabel objects associated with the view.
*
*
* These properties/view objects will be set (if defined in given class):
* quidu, label, stereotype, QualifiedNameParameter
*
*
* @see ClassDiagram#addToView(ClassView)
*/
public ClassView createClassView(cb.petal.Class clazz) {
ClassView view;
String stereo = clazz.getStereotype();
if (clazz.isActor()) {
view = (ClassView) getTemplate("ActorView");
} else if (stereo != null) {
view = (ClassView) getTemplate("StereotypeView");
ItemLabel label = (ItemLabel) view.getProperty("stereotype");
label.setLabel("<<" + stereo + ">>");
} else
view = (ClassView) getTemplate("ClassView");
view.setQuidu(clazz.getQuid());
view.setNameParameter(clazz.getClassType());
view.setQualifiedNameParameter(clazz.getQualifiedName());
ItemLabel label = (ItemLabel) view.getProperty("label");
label.setLabel(clazz.getNameParameter());
return view;
}
private static Dimension getNoteViewSize(StringLiteral text) {
int rows = 0, max_columns = 1;
for (Iterator i = text.getLines().iterator(); i.hasNext();) {
String line = (String) i.next();
if (line.length() > max_columns)
max_columns = line.length();
rows++;
}
return new Dimension(max_columns * 30, rows * 50);
}
/**
* create a note view
* @return new note view with given text
*/
public NoteView createNoteView(String text) {
NoteView view = (NoteView) getTemplate("NoteView");
StringLiteral literal = new StringLiteral(text);
Dimension dim = getNoteViewSize(literal);
ItemLabel label = view.getLabel();
label.setParent(view);
label.setNlines(literal.getLines().size());
label.setMaxWidth((int) dim.getWidth());
label.defineProperty("label", literal);
view.setWidth((int) dim.getWidth() + 20);
view.setHeight((int) dim.getHeight() + 20);
return view;
}
public AttachView createAttachView() {
AttachView view = (AttachView) getTemplate("AttachView");
return view;
}
/**
* @return new item label with given text
*/
public ItemLabel createItemLabel(String text) {
ItemLabel label = (ItemLabel) getTemplate("ItemLabel");
label.setLabel(text);
label.setMaxWidth(getMaxWidth(text));
return label;
}
/**
* @return new segment abel with given text
*/
public SegLabel createSegLabel(String text) {
SegLabel label = (SegLabel) getTemplate("SegLabel");
label.setLabel(text);
label.setMaxWidth(getMaxWidth(text));
return label;
}
private static int getMaxWidth(String s) {
return s.length() * 25; // Heuristic!
}
public AssocAttachView createAssocAttachView() {
AssocAttachView view = (AssocAttachView) getTemplate("AssocAttachView");
return view;
}
private void setupRelationshipView(RelationshipView view, Relationship rel) {
String label = rel.getLabel();
if (label != null) {
ItemLabel l = createItemLabel(label);
l.setParent(view);
view.setLabel(l);
view.setNameParameter(label);
}
String stereo = rel.getStereotype();
if (stereo != null) {
SegLabel l = createSegLabel("<<" + stereo + ">>");
l.setParent(view);
view.setStereotype(l);
}
}
/**
* @return list of inherit view objects since a class may extend multiple
* classes (not in Java, I know). The client and supplier tags (@5,
* e.g. which are references to the corresponding class view indexes)
* are set when the views are added to the model.
*
* @see ClassDiagram#addToView(cb.petal.InheritView)
*/
public java.util.List createInheritViews(Inheritable clazz) {
ArrayList list = new ArrayList();
for (Iterator i = clazz.getSuperclassList().getElements().iterator(); i
.hasNext();) {
InheritanceRelationship rel = (InheritanceRelationship) i.next();
InheritView view = (InheritView) getTemplate("InheritView");
view.setQuidu(rel.getQuid());
setupRelationshipView(view, rel);
list.add(view);
}
return list;
}
/**
* @return list of realize view objects since a class may implement multiple
* interfaces. The client and supplier tags (@5, e.g. which are
* references to the corresponding class view indexes) are set when
* the views are added to the model.
*
* @see ClassDiagram#addToView(cb.petal.RealizeView)
*/
public java.util.List createRealizeViews(cb.petal.Class clazz) {
ArrayList list = new ArrayList();
for (Iterator i = clazz.getRealizedInterfacesList().getElements()
.iterator(); i.hasNext();) {
RealizeRelationship rel = (RealizeRelationship) i.next();
RealizeView view = (RealizeView) getTemplate("RealizeView");
view.setQuidu(rel.getQuid());
setupRelationshipView(view, rel);
list.add(view);
}
return list;
}
/**
* @return list of uses view objects. The client and supplier tags (@5, e.g.
* which are references to the corresponding class view indexes) are
* set when the views are added to the model.
*
* @see ClassDiagram#addToView(cb.petal.UsesView)
*/
public java.util.List createUsesViews(cb.petal.Class clazz) {
ArrayList list = new ArrayList();
for (Iterator i = clazz.getUsedClassesList().getElements().iterator(); i
.hasNext();) {
UsesRelationship rel = (UsesRelationship) i.next();
UsesView view = (UsesView) getTemplate("UsesView");
view.setQuidu(rel.getQuid());
setupRelationshipView(view, rel);
list.add(view);
}
return list;
}
/**
* Creates view for given association.
*
* @param show_label
* show association name
* @see ClassDiagram#addToView(cb.petal.ClassView)
*/
public AssociationViewNew createAssociationView(Association assoc,
boolean show_label) {
AssociationViewNew view = (AssociationViewNew) getTemplate("AssociationViewNew");
view.setQuidu(assoc.getQuid());
view.setNameParameter(assoc.getNameParameter());
if (show_label) {
SegLabel label = createSegLabel(assoc.getNameParameter());
label.setParent(view);
label.setAnchor(1);
label.setMaxWidth(200);
Font font = new Font();
font.setParent(label);
font.setItalics(true);
label.setFont(font);
view.setLabel(label);
}
Role role1 = assoc.getFirstRole();
Role role2 = assoc.getSecondRole();
RoleView first = view.getFirstRoleView();
RoleView second = view.getSecondRoleView();
first.setNameParameter(role1.getNameParameter());
second.setNameParameter(role2.getNameParameter());
first.setQuidu(role1.getQuid());
second.setQuidu(role2.getQuid());
first.setParent(view);
second.setParent(view);
addLabels(first, role1);
addLabels(second, role2);
return view;
}
private void addLabels(RoleView view, Role role) {
String name = role.getRoleName();
if (name != null) {
SegLabel label = createSegLabel("+" + name);
label.setParent(view);
label.setMaxWidth(200);
label.setAnchor(1);
view.addProperty("label", label);
view.setNameParameter(name);
}
String constraint = role.getConstraints();
if (constraint != null) {
SegLabel label = createSegLabel("{" + constraint + "}");
label.setParent(view);
label.setAnchor(2);
view.addProperty("label", label);
}
}
public AssociationViewNew createAssociationView(Association assoc) {
return createAssociationView(assoc,
!assoc.getNameParameter().startsWith("$"));
}
/**
* Creates use case view for given class and sets the qualified name and quidu
* for the referenced class accordingly. The tag, i.e., the index in the views
* list (@12, e.g.), is set when the view is added to the model. It is also
* set them for the ItemLabel objects associated with the view.
*
* @see UseCaseDiagram#addToView(UseCaseView)
*/
public UseCaseView createUseCaseView(UseCase caze) {
UseCaseView view;
String stereo = caze.getStereotype();
if (stereo != null) {
view = (UseCaseView) getTemplate("UseCaseStereotypeView");
ItemLabel label = (ItemLabel) view.getProperty("stereotype");
label.setLabel("<<" + stereo + ">>");
} else
view = (UseCaseView) getTemplate("UseCaseView");
view.setQuidu(caze.getQuid());
view.setQualifiedNameParameter(caze.getQualifiedName());
ItemLabel label = (ItemLabel) view.getProperty("label");
label.setLabel(caze.getNameParameter());
return view;
}
}