svn commit: r16563 - branches/work_issue1048_dthompson/src/argouml-app/src/org/argouml/persistence/PrivateHandler.java
Dave Thompson <[email protected]>
| Newsgroups | gmane.comp.lang.uml.argouml.cvs |
|---|---|
| Message-ID | <[email protected]> |
Author: dthompson
Date: 2009-01-10 13:05:35-0800
New Revision: 16563
Modified:
branches/work_issue1048_dthompson/src/argouml-app/src/org/argouml/persistence/PrivateHandler.java
Log:
Implemented loading of PathItemPlacement data for FigAssociations (working).
Modified: branches/work_issue1048_dthompson/src/argouml-app/src/org/argouml/persistence/PrivateHandler.java
Url: http://argouml.tigris.org/source/browse/argouml/branches/work_issue1048_dthompson/src/argouml-app/src/org/argouml/persistence/PrivateHandler.java?view=diff&pathrev=16563&r1=16562&r2=16563
==============================================================================
--- branches/work_issue1048_dthompson/src/argouml-app/src/org/argouml/persistence/PrivateHandler.java (original)
+++ branches/work_issue1048_dthompson/src/argouml-app/src/org/argouml/persistence/PrivateHandler.java 2009-01-10 13:05:35-0800
@@ -26,12 +26,17 @@
import java.util.StringTokenizer;
import org.apache.log4j.Logger;
+import org.argouml.uml.diagram.ui.FigEdgeModelElement;
+import org.argouml.uml.diagram.ui.PathItemPlacement;
import org.argouml.util.IItemUID;
import org.argouml.util.ItemUID;
+import org.tigris.gef.base.PathItemPlacementStrategy;
import org.tigris.gef.persistence.pgml.Container;
import org.tigris.gef.persistence.pgml.FigEdgeHandler;
import org.tigris.gef.persistence.pgml.FigGroupHandler;
import org.tigris.gef.persistence.pgml.PGMLHandler;
+import org.tigris.gef.presentation.Fig;
+import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
/**
@@ -109,8 +114,159 @@
// Handle other uses of <private> contents
super.gotElement(contents);
}
+
+ /**
+ * Process starting elements within the private tag.
+ * This method handles all attributes within tags within private methods.
+ * The only specific tags we handle here at the moment are pathitems.
+ *
+ * The strategy for handling pathitems is as follows:
+ * <ul>
+ * <li>Data is saved for each path item using one <argouml:pathitem ... />
+ * tag per path item.
+ * <li>The code that defines what is stored is in
+ * org.argouml.persistence.PGML.tee
+ * <li>Each <argouml:pathitem> tag stores
+ * <ul>
+ * <li>The class name of the PathItemPlacementStrategy
+ * <li>The class name of the fig which it places.
+ * <li>The href of the model element which owns the fig being placed.
+ * <li>The angle of the placement vector (PathItemPlacement.angle)
+ * <li>The distance along the displacement vector to place the fig
+ * (PathItemPlacement.vectorOffset).
+ * </ul>
+ * </li>
+ * <li>No specific data is stored to match pathitem tags to the
+ * diagram figs which they control.
+ * <li>The matching during file load depends entirely on
+ * there being a unique figclassname and ownerhref combination
+ * for each pathitem on the diagram. For example, For a
+ * FigAssociation, the main label is a FigTextGroup, and it's
+ * owner is assigned to the Association. This combination is
+ * unique, and is used to match the parsed pathitem data back
+ * to the instantiated PathItemPlacement.
+ * Another example is the source multiplicity, which is a
+ * FigMultiplicity, and it's owner is assigned to the
+ * source model element.
+ * In each case, the combination is unique, so there is only
+ * one pathitem that matches when rebuilding the diagram.
+ * </ul>
+ *
+ * @param uri
+ * @param localname
+ * @param qname
+ * @param attributes
+ * @throws SAXException
+ * @see org.tigris.gef.persistence.pgml.BaseHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
+ */
+ public void startElement(String uri, String localname, String qname,
+ Attributes attributes) throws SAXException {
+ if ("argouml:pathitem".equals(qname)
+ && container instanceof FigEdgeHandler) {
+ if (((FigEdgeHandler) container).getFigEdge()
+ instanceof FigEdgeModelElement) {
+ String classname = attributes.getValue("classname");
+ String figclassname =
+ attributes.getValue("figclassname");
+ String ownerhref = attributes.getValue("ownerhref");
+ String angle = attributes.getValue("angle");
+ String offset = attributes.getValue("offset");
+ if ( classname != null
+ && figclassname != null
+ && ownerhref != null
+ && angle != null
+ && offset != null ) {
+ // Method 2: (assign data immediately, see end of file).
+ // TODO: if we ever want to extend PathItemPlacement,
+ // we should modify this, so that we also recognise any
+ // subclass of PathItemPlacement.
+ // Is the class name a PathItemPlacment?
+ if ("org.argouml.uml.diagram.ui.PathItemPlacement".equals(
+ classname)) {
+ PathItemPlacementStrategy pips
+ = getPips(figclassname, ownerhref);
+ // Sanity check - the returned path item placement
+ // strategy should match the one in the UML.
+ // If it doesn't, it could be that the UML was
+ // created with an older argo version, and the new
+ // argo version use a different placement strategy.
+ // If they don't match, just use the default.
+ if (pips.getClass().getName().equals(classname)) {
+ // Now we're into processing each specific path
+ // item strategy.
+ // At the moment, we only know PathItemPlacement
+ if (pips instanceof PathItemPlacement) {
+ PathItemPlacement pip =
+ (PathItemPlacement) pips;
+ pip.setDisplacementVector(
+ Double.parseDouble(angle),
+ Integer.parseInt(offset));
+ }
+ // Continue (future PathItemPlacementStrategy impl)
+ //else if (...) {
+ //}
+ }
+ // If the PathItemPlacement was unknown, leave the
+ // diagram with the default settings.
+ else {
+ LOG.warn("PGML stored pathitem class name does "
+ + "not match the class name on the "
+ + "diagram. Label position will revert "
+ + "to defaults.");
+ }
+ }
+ }
+ // If any of the values are null, ignore the element.
+ else {
+ LOG.warn("Could not find all attributes for <"
+ + qname + "> tag, ignoring.");
+ //System.out.println("Error - one of these is null:"
+ // + "classname=" + classname
+ // + " figclassname=" + figclassname
+ // + " ownerhref=" + ownerhref
+ // + " angle=" + angle
+ // + " offset=" + offset);
+ }
+ }
+ }
+
+ super.startElement(uri, localname, qname, attributes);
+ }
/**
+ * Finds the path item placement strategy for a sub Fig, by its class name,
+ * and it's owner href.
+ * @param figclassname The class name of the fig being placed.
+ * @param ownerhref The href of the owner of the fig being placed.
+ * @return The path item placement strategy.
+ */
+ private PathItemPlacementStrategy getPips(String figclassname,
+ String ownerhref) {
+ if (container instanceof FigEdgeHandler) {
+ FigEdgeHandler feh = ((FigEdgeHandler) container);
+ if (feh.getFigEdge() instanceof FigEdgeModelElement) {
+ FigEdgeModelElement feme =
+ (FigEdgeModelElement) feh.getFigEdge();
+ Object owner = getPGMLStackParser().findOwner(ownerhref);
+
+ for (Object o : feme.getPathItemFigs()) {
+ Fig f = (Fig) o;
+ // For a match to be found, it has to have the same
+ // owner, and the same long class name.
+ if (owner.equals(f.getOwner())
+ && figclassname.equals(f.getClass().getName())) {
+ //System.out.println("MATCHED! " + figclassname);
+ return feme.getPathItemPlacementStrategy(f);
+ }
+ }
+ }
+ }
+ LOG.warn("Could not load path item for fig '" + figclassname
+ + "', using default placement.");
+ return null;
+ }
+
+ /**
* Determine if the string contains an ItemUID.
*
* @return a newly created ItemUID (or <code>null</code>).
@@ -199,3 +355,86 @@
return rv;
}
}
+
+// An alternative implementation of the parsing of pathitems is to collect
+// everything at the start, then iterate through it all at the end.
+// The code below does this - it works, but it is currently not used,
+// since it is a unnecessarily complicated.
+// There are probably better ways to implement this than using an
+// ArrayList of Hashtables.
+// see option 1 in
+// http://argouml.tigris.org/issues/show_bug.cgi?id=1048#desc66
+//
+
+///**
+// * A list of the path item attributes for this container.
+// * The list is populated during parsing, them processed at endElement()
+// */
+//private List<Hashtable<String, String>> pathItemAttrs =
+// new ArrayList<Hashtable<String, String>>();
+
+// This code has to go within the startElement block after the strings
+// have been matched.
+
+//// Method 1:
+//// (collect data and assign later in endElement() method).
+//Hashtable<String, String> ht =
+// new Hashtable<String, String>();
+//ht.put("classname", classname);
+//ht.put("figclassname", figclassname);
+//ht.put("ownerhref", ownerhref);
+//ht.put("angle", angle);
+//ht.put("offset", offset);
+//pathItemAttrs.add(ht);
+
+//public void endElement(String uri, String localname, String qname)
+//throws SAXException {
+////System.out.print("Got endElement: "
+//// + "uri='" + uri + "'\n"
+//// + "localname='" + localname + "'\n"
+//// + "qname='" + qname + "'\n"
+////);
+//// If we collected any path items for a FigEdgeModelElement,
+//// process them now, and assign their values to real Figs on the diag.
+//if (!(pathItemAttrs.isEmpty())) {
+// for (Hashtable<String, String> attrs : pathItemAttrs) {
+// // Is the class name a PathItemPlacment?
+// // TODO: if we ever want to extend PathItemPlacement,
+// // we should modify this, so that we also recognise any
+// // subclass of PathItemPlacement.
+// if ("org.argouml.uml.diagram.ui.PathItemPlacement".
+// equals(attrs.get("classname"))) {
+// //System.out.println("figclassname=" + attrs.get("figclassname"));
+//
+// PathItemPlacementStrategy pips
+// = getPips(attrs.get("figclassname"),
+// attrs.get("ownerhref"));
+// // Sanity check - the returned path item placement straty
+// // should match the one in the uml.
+// if (pips.getClass().getName().equals(attrs.get("classname"))) {
+// // Now we're into processing each specific path item
+// // strategy.
+// // At the moment, we only know about PathItemPlacement
+// if (pips instanceof PathItemPlacement) {
+// PathItemPlacement pip = (PathItemPlacement) pips;
+// pip.setDisplacementVector(
+// Double.parseDouble(attrs.get("angle")),
+// Integer.parseInt(attrs.get("offset")));
+// }
+// // Continue (future PathItemPlacementStrategy impl)
+// //else if (...) {
+// //
+// //}
+//
+// }
+// else {
+// LOG.warn("PGML stored pathitem class name does not "
+// + "match the class name on the diagram."
+// + "Label position will revert to defaults.");
+// }
+// }
+// }
+//}
+//
+//super.endElement(uri, localname, qname);
+//}
------------------------------------------------------
http://argouml.tigris.org/ds/viewMessage.do?dsForumId=5905&dsMessageId=1015808
To unsubscribe from this discussion, e-mail: [[email protected]].