svn commit: r17329 - trunk/src/argouml-app/src/org/argouml/persistence/PGMLStackParser.java

Bob Tarling <[email protected]>
Newsgroups gmane.comp.lang.uml.argouml.cvs
Message-ID <[email protected]>
Author: bobtarling
Date: 2009-09-17 13:01:16-0700
New Revision: 17329

Modified:
   trunk/src/argouml-app/src/org/argouml/persistence/PGMLStackParser.java

Log:
Load the association ends of an association when reading PGML

Modified: trunk/src/argouml-app/src/org/argouml/persistence/PGMLStackParser.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/persistence/PGMLStackParser.java?view=diff&pathrev=17329&r1=17328&r2=17329
==============================================================================
--- trunk/src/argouml-app/src/org/argouml/persistence/PGMLStackParser.java	(original)
+++ trunk/src/argouml-app/src/org/argouml/persistence/PGMLStackParser.java	2009-09-17 13:01:16-0700
@@ -38,6 +38,7 @@
 import org.apache.log4j.Logger;
 import org.argouml.uml.diagram.ArgoDiagram;
 import org.argouml.uml.diagram.AttributesCompartmentContainer;
+import org.argouml.uml.diagram.DiagramEdgeSettings;
 import org.argouml.uml.diagram.DiagramSettings;
 import org.argouml.uml.diagram.ExtensionsCompartmentContainer;
 import org.argouml.uml.diagram.OperationsCompartmentContainer;
@@ -50,11 +51,23 @@
 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.FigLineHandler;
+import org.tigris.gef.persistence.pgml.FigPolyHandler;
+import org.tigris.gef.persistence.pgml.FigTextHandler;
+import org.tigris.gef.persistence.pgml.HandlerFactory;
 import org.tigris.gef.persistence.pgml.HandlerStack;
+import org.tigris.gef.persistence.pgml.PrivateHandler;
 import org.tigris.gef.presentation.Fig;
+import org.tigris.gef.presentation.FigCircle;
 import org.tigris.gef.presentation.FigEdge;
 import org.tigris.gef.presentation.FigGroup;
+import org.tigris.gef.presentation.FigLine;
 import org.tigris.gef.presentation.FigNode;
+import org.tigris.gef.presentation.FigPoly;
+import org.tigris.gef.presentation.FigRRect;
+import org.tigris.gef.presentation.FigRect;
+import org.tigris.gef.presentation.FigText;
+import org.tigris.gef.util.ColorFactory;
 import org.xml.sax.Attributes;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
@@ -168,7 +181,7 @@
         }
         
         DefaultHandler handler =
-            super.getHandler(stack, container, uri, localname, qname,
+            getHandlerSuper(stack, container, uri, localname, qname,
                     attributes);
 
         if (handler instanceof FigEdgeHandler) {
@@ -583,6 +596,227 @@
     }
 
     /**
+     * Returns ContentHandler objects appropriate for the standard set of
+     * elements that can appear within a PGML file.
+     * <p>
+     * 
+     * First, the <em>description</em> attribute is checked for a PGML-style
+     * class name specifier; if one is found, it is passed through the
+     * {@link #translateType translateClassName} method and the resulting class
+     * name is instantiated. If the resulting object is itself an instance of
+     * {@link HandlerFactory}, the method returns the result of calling
+     * {@link HandlerFactory#getHandler getHandler} on that object with the same
+     * arguments. This allows a Fig object to take complete control of its own
+     * parsing without imposing any change on the global parsing framework.
+     * <p>
+     * 
+     * If the element doesn't incorporate a class name, or if the instanced
+     * object does not implement {@link HandlerFactory}, the element name is
+     * compared with one of PGML's special element names. If a known element
+     * name is found, either the element is processed immediately and null
+     * returned, or the appropriate handler for that element is returned. If the
+     * element name is unknown, null is returned.
+     * <p>
+     * 
+     * @param stack
+     *                Implementation of the stack of content handlers
+     * @param container
+     *                An object that provides context for the element (most
+     *                often by providing an implementation of the
+     *                {@link Container} interface.
+     * @param uri
+     *                SAX uri argument
+     * @param localname
+     *                SAX local element name
+     * @param qname
+     *                SAX qualified element name
+     * @param attributes
+     *                The attributes that the SAX parser have identified for the
+     *                element.
+     * @return ContentHandler object appropriate for the element, or null if the
+     *         element can be skipped
+     * 
+     * @see org.tigris.gef.persistence.pgml.HandlerFactory#getHandler(
+     *      org.argouml.gef.HandlerStack, java.lang.Object, java.lang.String,
+     *      java.lang.String, java.lang.String, org.xml.sax.Attributes)
+     */
+    public DefaultHandler getHandlerSuper(HandlerStack stack, Object container,
+            String uri, String localname, String qname, Attributes attributes)
+            throws SAXException {
+
+        String href = attributes.getValue("href");
+
+        String clsNameBounds = attributes.getValue("description");
+        Object elementInstance = null;
+        if (clsNameBounds != null) {
+
+            StringTokenizer st = new StringTokenizer(clsNameBounds, ",;[] ");
+            String clsName = translateType(st.nextToken());
+            elementInstance = constructFig(clsName, href,
+                    getBounds(clsNameBounds), attributes);
+            if (elementInstance instanceof HandlerFactory) {
+                return ((HandlerFactory) elementInstance).getHandler(stack,
+                        container, uri, localname, qname, attributes);
+            }
+        }
+
+        // If we got here, one of the built-in handlers will apply
+        if (qname.equals("group")) {
+            if (elementInstance instanceof FigGroup) {
+                return getGroupHandler(container, (FigGroup) elementInstance,
+                        attributes);
+            }
+            if (elementInstance instanceof FigEdge) {
+                setAttrs((FigEdge) elementInstance, attributes);
+                if (container instanceof Container) {
+                    ((Container) container).addObject(elementInstance);
+                }
+                return new FigEdgeHandler(this, (FigEdge) elementInstance);
+            }
+        }
+
+        if (qname.equals("text")) {
+            if (elementInstance == null) {
+                elementInstance = new FigText(0, 0, 100, 100);
+            }
+            if (elementInstance instanceof FigText) {
+                FigText text = (FigText) elementInstance;
+                setAttrs(text, attributes);
+                if (container instanceof Container) {
+                    ((Container) container).addObject(text);
+                }
+                String font = attributes.getValue("font");
+                if (font != null && !font.equals("")) {
+                    text.setFontFamily(font);
+                }
+
+                String textsize = attributes.getValue("textsize");
+                if (textsize != null && !textsize.equals("")) {
+                    int textsizeInt = Integer.parseInt(textsize);
+                    text.setFontSize(textsizeInt);
+                }
+
+                String justification = attributes.getValue("justification");
+                if (justification != null && !justification.equals("")) {
+                    text.setJustificationByName(justification);
+                }
+                String italic = attributes.getValue("italic");
+                if (italic != null && !italic.equals("")) {
+                    text.setItalic(Boolean.valueOf(italic).booleanValue());
+                }
+                String bold = attributes.getValue("bold");
+                if (bold != null && !bold.equals("")) {
+                    text.setBold(Boolean.valueOf(bold).booleanValue());
+                }
+
+                String textColor = attributes.getValue("textcolor");
+                if (textColor != null && !textColor.equals("")) {
+                    text.setTextColor(ColorFactory.getColor(textColor));
+                }
+
+                return new FigTextHandler(this, text);
+            }
+        }
+
+        if (qname.equals("path") || qname.equals("line")) {
+            if (elementInstance == null) {
+                elementInstance = new FigPoly();
+            }
+            if (elementInstance instanceof FigLine) {
+                setAttrs((Fig) elementInstance, attributes);
+                if (container instanceof Container) {
+                    ((Container) container).addObject(elementInstance);
+                }
+                return new FigLineHandler(this, (FigLine) elementInstance);
+            }
+            if (elementInstance instanceof FigPoly) {
+                setAttrs((Fig) elementInstance, attributes);
+                if (container instanceof Container) {
+                    ((Container) container).addObject(elementInstance);
+                }
+                return new FigPolyHandler(this, (FigPoly) elementInstance);
+            }
+        }
+
+        if (qname.equals("private")) {
+            if (elementInstance != null) {
+                LOG.warn("private element unexpectedly generated instance: "
+                        + elementInstance.toString());
+            }
+            if (container instanceof Container) {
+                return new PrivateHandler(this, (Container) container);
+            } else {
+                LOG.warn("private element with inappropriate container: "
+                        + container.toString());
+            }
+        }
+
+        if (qname.equals("rectangle")) {
+            String cornerRadius = attributes.getValue("rounding");
+            int rInt = -1;
+            if (cornerRadius != null && cornerRadius.length() > 0) {
+                rInt = Integer.parseInt(cornerRadius);
+            }
+            if (elementInstance == null) {
+                if (rInt >= 0) {
+                    elementInstance = new FigRRect(0, 0, 80, 80);
+                } else {
+                    elementInstance = new FigRect(0, 0, 80, 80);
+                }
+            }
+            if (elementInstance instanceof FigRRect && rInt >= 0) {
+                ((FigRRect) elementInstance).setCornerRadius(rInt);
+            }
+            if (elementInstance instanceof Fig) {
+                setAttrs((Fig) elementInstance, attributes);
+                if (container instanceof Container) {
+                    ((Container) container).addObject(elementInstance);
+                }
+                return null;
+            }
+        }
+
+        if (qname.equals("ellipse")) {
+            System.out.println("Found an ellipse");
+            if (elementInstance == null) {
+                System.out.println("Created a FigCircle");
+                elementInstance = new FigCircle(0, 0, 50, 50);
+            }
+            if (elementInstance instanceof FigCircle) {
+                FigCircle f = (FigCircle) elementInstance;
+                setAttrs(f, attributes);
+                String rx = attributes.getValue("rx");
+                String ry = attributes.getValue("ry");
+                int rxInt = (rx == null || rx.equals("")) ? 10 : Integer
+                        .parseInt(rx);
+                int ryInt = (ry == null || ry.equals("")) ? 10 : Integer
+                        .parseInt(ry);
+                f.setBounds(f.getX() - rxInt, f.getY() - ryInt, rxInt * 2,
+                        ryInt * 2);
+                if (container instanceof Container) {
+                    ((Container) container).addObject(elementInstance);
+                }
+
+                return null;
+            }
+        }
+
+        // Don't know what to do; throw up our hands--usually this
+        // will mean that sub-elements are ignored
+        LOG.info("Unrecognized element " + qname);
+        if (elementInstance != null) {
+            // Implement reasonable default behavior
+            if (elementInstance instanceof Fig) {
+                setAttrs((Fig) elementInstance, attributes);
+            }
+            if (container instanceof Container) {
+                ((Container) container).addObject(elementInstance);
+            }
+        }
+        return null;
+    }
+    
+    /**
      * Construct a new instance of the named Fig with the owner represented
      * by the given href and the bounds parsed from the PGML file.  We look
      * for constructors of the form Fig(Object owner, Rectangle
@@ -596,12 +830,12 @@
      * @param className fully qualified name of class to instantiate
      * @param href string representing UUID of owning element
      * @param bounds position and size of figure
+     * @param attributes the XML attributes that made up the top level element
+     * in PGML
      * @return
      * @throws SAXException
-     * @see org.tigris.gef.persistence.pgml.PGMLStackParser#constructFig(java.lang.String, java.lang.String, java.awt.Rectangle)
      */
-    @Override
-    protected Fig constructFig(String className, String href, Rectangle bounds)
+    private Fig constructFig(String className, String href, Rectangle bounds, Attributes attributes)
         throws SAXException {
 	
 	Fig f = null;
@@ -631,7 +865,7 @@
                 }
                 // FigEdgeModelElements should match here (they have no bounds)
                 if (parameterTypes.length == 2
-                        && parameterTypes[0].equals(Object.class)
+                        && parameterTypes[0].equals(DiagramEdgeSettings.class)
                         && parameterTypes[1].equals(DiagramSettings.class)
                 ) {
                     Object parameters[] = new Object[2];
@@ -639,7 +873,30 @@
                     if (href != null) {
                         owner = findOwner(href);
                     }
-                    parameters[0] = owner;
+                    
+                    String sourceUuid =
+                        attributes.getValue("sourceConnector");
+                    String destinationUuid =
+                        attributes.getValue("destConnector");
+                    
+                    LOG.info("The source connector uuid is "
+                            + sourceUuid);
+                    LOG.info("The destination connector uuid is "
+                            + destinationUuid);
+                    
+                    final Object source;
+                    final Object destination;
+                    if (sourceUuid != null && destinationUuid != null) {
+                        source = findOwner(sourceUuid);
+                        destination = findOwner(destinationUuid);
+                    } else {
+                        source = null;
+                        destination = null;
+                    }
+                    
+                    DiagramEdgeSettings settings =
+                        new DiagramEdgeSettings(owner, source, destination);
+                    parameters[0] = settings;
                     parameters[1] = 
                         ((ArgoDiagram) getDiagram()).getDiagramSettings();
 
@@ -647,6 +904,29 @@
                     f =  (Fig) constructor.newInstance(parameters);
                 }
             }
+            if (f == null) {
+                // FigEdgeModelElements with the old style constructor should
+                // match here (they have no bounds)
+                for (Constructor constructor : figClass.getConstructors()) {
+                    Class[] parameterTypes = constructor.getParameterTypes();
+                    if (parameterTypes.length == 2
+                            && parameterTypes[0].equals(Object.class)
+                            && parameterTypes[1].equals(DiagramSettings.class)
+                    ) {
+                        Object parameters[] = new Object[2];
+                        Object owner = null;
+                        if (href != null) {
+                            owner = findOwner(href);
+                        }
+                        parameters[0] = owner;
+                        parameters[1] = 
+                            ((ArgoDiagram) getDiagram()).getDiagramSettings();
+
+                        constructor.setAccessible(true);
+                        f =  (Fig) constructor.newInstance(parameters);
+                    }
+                }
+            }
         } catch (ClassNotFoundException e) {
             throw new SAXException(e);
         } catch (IllegalAccessException e) {
@@ -664,13 +944,89 @@
             // have been upgraded.
             LOG.debug("No ArgoUML constructor found for " + className
                     + " falling back to GEF's default constructors");
-            f = super.constructFig(className, href, bounds);
+            f = constructFig(className, href, bounds);
         }
         
 	return f;
     }
     
     /**
+     * @param container
+     * @param group
+     * @param attributes
+     * @return
+     * @throws SAXException
+     */
+    private DefaultHandler getGroupHandler(Object container, FigGroup group,
+            Attributes attributes) throws SAXException {
+        if (container instanceof Container) {
+            ((Container) container).addObject(group);
+        }
+        StringTokenizer st = new StringTokenizer(attributes
+                .getValue("description"), ",;[] ");
+        setAttrs(group, attributes);
+        if (st.hasMoreElements()) {
+            st.nextToken();
+        }
+        String xStr = null;
+        String yStr = null;
+        String wStr = null;
+        String hStr = null;
+        if (st.hasMoreElements()) {
+            xStr = st.nextToken();
+            yStr = st.nextToken();
+            wStr = st.nextToken();
+            hStr = st.nextToken();
+        }
+        if (xStr != null && !xStr.equals("")) {
+            int x = Integer.parseInt(xStr);
+            int y = Integer.parseInt(yStr);
+            int w = Integer.parseInt(wStr);
+            int h = Integer.parseInt(hStr);
+            group.setBounds(x, y, w, h);
+        }
+        return new FigGroupHandler(this, group);
+    }
+
+    /**
+     * Retrieve a bounds Rectangle from its description where the description is
+     * in the form "anything[x,y,w,h]anything"
+     * 
+     * @param boundsDescription
+     * @return a bounds Rectangle or null is invalid
+     */
+    Rectangle getBounds(String boundsDescription) {
+        try {
+            int bracketPosn = boundsDescription.indexOf('[');
+            if (bracketPosn < 0)
+                return null;
+            boundsDescription = boundsDescription.substring(bracketPosn + 1);
+            StringTokenizer st = new StringTokenizer(boundsDescription, ", ]");
+            String xStr = null;
+            String yStr = null;
+            String wStr = null;
+            String hStr = null;
+            if (st.hasMoreElements()) {
+                xStr = st.nextToken();
+                yStr = st.nextToken();
+                wStr = st.nextToken();
+                hStr = st.nextToken();
+            }
+            if (xStr != null && !xStr.equals("")) {
+                int x = Integer.parseInt(xStr);
+                int y = Integer.parseInt(yStr);
+                int w = Integer.parseInt(wStr);
+                int h = Integer.parseInt(hStr);
+                return new Rectangle(x, y, w, h);
+            }
+        } catch (Exception e) {
+            LOG.warn("Exception extracting bounds from description", e);
+        }
+        return null;
+    }
+    
+    
+    /**
      * Save the newly created Diagram for use by the parser.  We take the 
      * opportunity to attach our default diagram settings to it so we'll have
      * them if needed when constructing Figs.

------------------------------------------------------
http://argouml.tigris.org/ds/viewMessage.do?dsForumId=5905&dsMessageId=2396182

To unsubscribe from this discussion, e-mail: [[email protected]].
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.