svn commit: r13168 - trunk/src/model-mdr/src/org/argouml/model/mdr

[email protected]
Newsgroups gmane.comp.lang.uml.argouml.cvs
Message-ID <[email protected]>
Author: tfmorris
Date: 2007-07-27 15:26:25-0700
New Revision: 13168

Modified:
   trunk/src/model-mdr/src/org/argouml/model/mdr/MDRModelImplementation.java
   trunk/src/model-mdr/src/org/argouml/model/mdr/XmiReaderImpl.java
   trunk/src/model-mdr/src/org/argouml/model/mdr/XmiReferenceProviderImpl.java
   trunk/src/model-mdr/src/org/argouml/model/mdr/XmiReferenceResolverImpl.java
   trunk/src/model-mdr/src/org/argouml/model/mdr/XmiWriterMDRImpl.java

Log:
Add support profiles & user models with:

 - multiple linked XMI files

 - multiple top level packages

Modified: trunk/src/model-mdr/src/org/argouml/model/mdr/MDRModelImplementation.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/model-mdr/src/org/argouml/model/mdr/MDRModelImplementation.java?view=diff&rev=13168&p1=trunk/src/model-mdr/src/org/argouml/model/mdr/MDRModelImplementation.java&p2=trunk/src/model-mdr/src/org/argouml/model/mdr/MDRModelImplementation.java&r1=13167&r2=13168
==============================================================================
--- trunk/src/model-mdr/src/org/argouml/model/mdr/MDRModelImplementation.java	(original)
+++ trunk/src/model-mdr/src/org/argouml/model/mdr/MDRModelImplementation.java	2007-07-27 15:26:25-0700
@@ -28,6 +28,7 @@
 import java.io.OutputStream;
 import java.io.Writer;
 import java.net.URL;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -167,13 +168,14 @@
      * (as indicated by the calling application) will be treated specially and
      * will not be written back out with the rest of the model data.
      */
-    private RefObject profileModel;
+    private Collection<RefObject> profileElements;
 
     /**
      * Map of model elements to xmi.ids used to keep xmi.ids stable
      * across read/write cycles.
      */
-    private Map objectToId = Collections.synchronizedMap(new HashMap());
+    private Map<String, XmiReference> objectToId = 
+        Collections.synchronizedMap(new HashMap<String, XmiReference>());
 
     /**
      * @return Returns the root UML Factory package for user model.
@@ -630,16 +632,16 @@
     /**
      * @return the collection of model elements which make up the profile.
      */
-    protected RefObject getProfileModel() {
-        return profileModel;
+    protected Collection<RefObject> getProfileElements() {
+        return profileElements;
     }
 
     /**
      * Save the given elements as belonging to the profile.
-     * @param element collection of model elements.
+     * @param elements collection of model elements.
      */
-    protected void setProfileModel(RefObject element) {
-        this.profileModel = element;
+    protected void setProfileElements(Collection<RefObject> elements) {
+        profileElements = elements;
     }
 
     /**
@@ -647,7 +649,7 @@
      *
      * @return the map
      */
-    protected Map getObjectToId() {
+    protected Map<String, XmiReference> getObjectToId() {
         return objectToId;
     }
 

Modified: trunk/src/model-mdr/src/org/argouml/model/mdr/XmiReaderImpl.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/model-mdr/src/org/argouml/model/mdr/XmiReaderImpl.java?view=diff&rev=13168&p1=trunk/src/model-mdr/src/org/argouml/model/mdr/XmiReaderImpl.java&p2=trunk/src/model-mdr/src/org/argouml/model/mdr/XmiReaderImpl.java&r1=13167&r2=13168
==============================================================================
--- trunk/src/model-mdr/src/org/argouml/model/mdr/XmiReaderImpl.java	(original)
+++ trunk/src/model-mdr/src/org/argouml/model/mdr/XmiReaderImpl.java	2007-07-27 15:26:25-0700
@@ -26,6 +26,7 @@
 
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -33,7 +34,6 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Iterator;
 import java.util.Map;
 
 import javax.jmi.reflect.InvalidObjectException;
@@ -60,9 +60,6 @@
 import org.netbeans.api.xmi.XMIReaderFactory;
 import org.netbeans.lib.jmi.xmi.InputConfig;
 import org.netbeans.lib.jmi.xmi.UnknownElementsListener;
-import org.omg.uml.UmlPackage;
-import org.omg.uml.foundation.core.ModelElement;
-import org.omg.uml.modelmanagement.Model;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 import org.xml.sax.XMLFilter;
@@ -126,21 +123,16 @@
         modelPackage = mp;
     }
 
-
-    /*
-     * @see org.argouml.model.XmiReader#parse(org.xml.sax.InputSource)
-     */
+    
     public Collection parse(InputSource pIs) throws UmlException {
         return parse(pIs, false);
     }
 
-    /*
-     * @see org.argouml.model.XmiReader#parse(org.xml.sax.InputSource, boolean)
-     */
+    
     public Collection parse(InputSource pIs, boolean profile)
         throws UmlException {
 
-        Collection newElements = Collections.EMPTY_LIST;
+        Collection<RefObject> newElements = Collections.EMPTY_LIST;
         RefPackage extent = modelPackage;
 
         try {
@@ -190,7 +182,8 @@
             // Disable event delivery during model load
             modelImpl.getModelEventPump().stopPumpingEvents();
 
-            Collection startTopElements = getTopLevelElements();
+            Collection<RefObject> startTopElements = 
+                modelImpl.getFacade().getRootElements();
             int numElements = startTopElements.size();
             LOG.debug("Number of top level elements before import: "
                     + numElements);
@@ -202,46 +195,18 @@
                 // If a UML 1.3 file, attempt to upgrade it to UML 1.4
                 if (uml13) {
                     // First delete model data from our first attempt
-                    Collection toDelete = new ArrayList();
-                    toDelete.addAll(newElements);
-                    for (Iterator it = toDelete.iterator(); it.hasNext();) {
-                        try {
-                            ((RefObject) it.next()).refDelete();
-                        } catch (InvalidObjectException e) {
-                            // Just continue.  We tried to delete something 
-                            // twice, probably because it was contained in 
-                            // another element that we already deleted.
-                        }
-                    }
+                    deleteElements(newElements);
 
                     // Clear the associated ID maps & reset starting collection
                     resolver.clearIdMaps();
-                    startTopElements = getTopLevelElements();
+                    startTopElements = modelImpl.getFacade().getRootElements();
 
-                    LOG.info("XMI file doesn't appear to be UML 1.4 - "
-                            + "attempting UML 1.3->UML 1.4 conversion");
-                    final String[] transformFiles =
-                        new String[] {
-                            "NormalizeNSUML.xsl",
-                            "uml13touml14.xsl",
-                        };
-
-                    unknownElement = false;
-                    // InputSource xformedInput =
-                    //        chainedTransform(transformFiles, pIs);
-                    InputSource originalInput = 
-                        new InputSource(new FileInputStream(tmpFile));
-                    // Use the original file for the system ID
-                    // so any references resolve correctly
-                    originalInput.setSystemId(pIs.getSystemId());
-                    InputSource xformedInput = 
-                        serialTransform(transformFiles, originalInput);
-                    newElements =
-                        xmiReader.read(xformedInput.getByteStream(),
-                            xformedInput.getSystemId(), extent);
+                    newElements = convertAndLoadUml13(pIs.getSystemId(),
+                            extent, xmiReader, tmpFile);
                 }
 
-                numElements = getTopLevelElements().size() - numElements;
+                numElements = modelImpl.getFacade().getRootElements().size()
+                        - numElements;
 
                 // This indicates a malformed XMI file.  Log the error.
                 if (newElements.size() != numElements) {
@@ -252,19 +217,6 @@
                             + numElements + ")");
                 }
 
-                // ArgoUML only deals correctly with a single top level model.
-                // If we got more elements, force them to be contained by top.
-                // TODO:  This is a workaround for more general support.
-                if (numElements > 1) {
-                    LOG.warn("Forcing all model elements to be contained by"
-                            + " top level Model");
-                    Collection newTopElements = getTopLevelElements();
-                    newTopElements.removeAll(startTopElements);
-                    forceContainment(newTopElements);
-                    // Return our element list (of 1) rather than XMIreader's
-                    newElements = getTopLevelElements();
-                    newElements.removeAll(startTopElements);
-                }
 
             } finally {
                 modelImpl.getModelEventPump().startPumpingEvents();
@@ -287,83 +239,53 @@
         }
 
         if (profile) {
-            if (newElements.size() != 1) {
-                LOG.error("Unexpected number of profile model elements"
-                        + " (must be 1) : "
-                        + newElements.size());
-                return Collections.EMPTY_LIST;
-            } else {
-                RefObject model = (RefObject) newElements.iterator().next();
-                if (!(model instanceof Model)) {
-                    LOG.error("Profile XMI doesn't contain Model as top level"
-                            + " element.");
-                    return Collections.EMPTY_LIST;
-                } else {
-                    LOG.debug("Saving profile with MofID : "
-                            + model.refMofId());
-                    modelImpl.setProfileModel(model);
-                }
-            }
-
+            modelImpl.setProfileElements(newElements);
         }
         return newElements;
     }
 
-    /**
-     * Force containment of all elements by the first Model that is found.
-     * ArgoUML doesn't know how to deal with anything else.
-     * @param elements collection of elements
-     */
-    private void forceContainment(Collection elements) {
-        Model model = null;
-        for (Iterator it = elements.iterator(); it.hasNext();) {
-            Object o = it.next();
-            if (o instanceof Model) {
-                model = (Model) o;
-                break;
-            }
-        }
-        if (model == null) {
-            LOG.error("Collection of objects  doesn't contain"
-                    + " any elements of type Model");
-            return;
-        }
-        for (Iterator it = elements.iterator(); it.hasNext();) {
-            Object o = it.next();
-            if (!o.equals(model)) {
-                if (o instanceof ModelElement) {
-                    ((ModelElement) o).setNamespace(model);
-                } else {
-                    LOG.warn("Skipping setting namespace of element of type"
-                            + o.getClass().getName());
-                }
+    
+    private void deleteElements(Collection<RefObject> elements) {
+        Collection<RefObject> toDelete = new ArrayList<RefObject>(elements);
+        for (RefObject refObject : toDelete) {
+            try {
+                refObject.refDelete();
+            } catch (InvalidObjectException e) {
+                // Just continue.  We tried to delete something 
+                // twice, probably because it was contained in 
+                // another element that we already deleted.
             }
         }
     }
 
-    /**
-     * Returns a collection of all objects which are Elements or one of
-     * its subclasses and which are not contained in another object.
-     */
-    private Collection getTopLevelElements() {
-        Collection elements = new ArrayList();
-        UmlPackage pkg = modelImpl.getUmlPackage();
-        for (Iterator it =
-                pkg.getCore().getElement().refAllOfType().iterator();
-                it.hasNext();) {
-            RefObject obj = (RefObject) it.next();
-            if (obj.refImmediateComposite() == null) {
-                elements.add(obj);
-            }
-        }
-        return elements;
+    private Collection<RefObject> convertAndLoadUml13(String systemId,
+            RefPackage extent, XMIReader xmiReader, File file)
+        throws FileNotFoundException, UmlException, IOException,
+            MalformedXMIException {
+        
+        LOG.info("XMI file doesn't appear to be UML 1.4 - "
+                + "attempting UML 1.3->UML 1.4 conversion");
+        final String[] transformFiles = new String[] { 
+            "NormalizeNSUML.xsl",
+            "uml13touml14.xsl", };
+
+        unknownElement = false;
+        // InputSource xformedInput = chainedTransform(transformFiles, pIs);
+        InputSource originalInput = new InputSource(
+                new FileInputStream(file));
+        // Use the original file for the system ID
+        // so any references resolve correctly
+        originalInput.setSystemId(systemId);
+        InputSource xformedInput = serialTransform(transformFiles,
+                originalInput);
+        return xmiReader.read(xformedInput.getByteStream(), xformedInput
+                .getSystemId(), extent);
     }
 
-
     /*
      * @see org.argouml.model.XmiReader#getXMIUUIDToObjectMap()
      */
-    public Map getXMIUUIDToObjectMap() {
+    public Map<String, Object> getXMIUUIDToObjectMap() {
         if (resolver != null) {
             return resolver.getIdToObjectMap();
         }

Modified: trunk/src/model-mdr/src/org/argouml/model/mdr/XmiReferenceProviderImpl.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/model-mdr/src/org/argouml/model/mdr/XmiReferenceProviderImpl.java?view=diff&rev=13168&p1=trunk/src/model-mdr/src/org/argouml/model/mdr/XmiReferenceProviderImpl.java&p2=trunk/src/model-mdr/src/org/argouml/model/mdr/XmiReferenceProviderImpl.java&r1=13167&r2=13168
==============================================================================
--- trunk/src/model-mdr/src/org/argouml/model/mdr/XmiReferenceProviderImpl.java	(original)
+++ trunk/src/model-mdr/src/org/argouml/model/mdr/XmiReferenceProviderImpl.java	2007-07-27 15:26:25-0700
@@ -1,5 +1,5 @@
 // $Id$
-// Copyright (c) 2005-2006 The Regents of the University of California. All
+// Copyright (c) 2005-2007 The Regents of the University of California. All
 // Rights Reserved. Permission to use, copy, modify, and distribute this
 // software and its documentation without fee, and without a written
 // agreement is hereby granted, provided that the above copyright notice
@@ -39,22 +39,17 @@
  */
 class XmiReferenceProviderImpl implements XMIReferenceProvider {
     
-    private Map mofIdToXmiId;
+    private Map<String, XmiReference> mofIdToXmiId;
     
     /**
      * Create a new reference provider which uses the given map for lookups.
      * 
      * @param idMap
      */
-    XmiReferenceProviderImpl(Map idMap) {
+    XmiReferenceProviderImpl(Map<String, XmiReference> idMap) {
         mofIdToXmiId = idMap;
     }
 
-    /**
-     * The document for the objects.
-     */
-    private final String systemId = null;
-
     /*
      * @see org.netbeans.api.xmi.XMIReferenceProvider#getReference(javax.jmi.reflect.RefObject)
      */
@@ -62,14 +57,17 @@
         String mofId = object.refMofId();
         
         // Look for an existing reference matching our MofID
-        XmiReference ref = ((XmiReference) mofIdToXmiId.get(mofId));
+        XmiReference ref = mofIdToXmiId.get(mofId);
 
-        // Create a new ref if none found, otherwise create one with our sysID
+        // Anything not found is newly created, so return a null SystemID
+        // indicating that it is in the parent document.  Otherwise return
+        // the same reference that we read in originally.
         if (ref == null) {
-            return new XMIReferenceProvider.XMIReference(systemId, mofId);
+            return new XMIReferenceProvider.XMIReference(null, mofId);
         } else {
-            return new XMIReferenceProvider.XMIReference(systemId, 
+            return new XMIReferenceProvider.XMIReference(ref.getSystemId(), 
                     ref.getXmiId());
         }
     }
+
 }

Modified: trunk/src/model-mdr/src/org/argouml/model/mdr/XmiReferenceResolverImpl.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/model-mdr/src/org/argouml/model/mdr/XmiReferenceResolverImpl.java?view=diff&rev=13168&p1=trunk/src/model-mdr/src/org/argouml/model/mdr/XmiReferenceResolverImpl.java&p2=trunk/src/model-mdr/src/org/argouml/model/mdr/XmiReferenceResolverImpl.java&r1=13167&r2=13168
==============================================================================
--- trunk/src/model-mdr/src/org/argouml/model/mdr/XmiReferenceResolverImpl.java	(original)
+++ trunk/src/model-mdr/src/org/argouml/model/mdr/XmiReferenceResolverImpl.java	2007-07-27 15:26:25-0700
@@ -28,6 +28,8 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -48,9 +50,9 @@
  * 
  * This provides two functions:
  * <nl>
- * <li>Records the mapping of <code>xmi.id</code>'s to MDR's object as they
+ * <li>Records the mapping of <code>xmi.id</code>'s to MDR objects as they
  * are resolved so that the map can be used to lookup objects by xmi.id later
- * (used by diagram subsystem to associated GEF/PGML objects with model
+ * (used by diagram subsystem to associate GEF/PGML objects with model
  * elements).
  * <li>Resolves a System ID to a fully specified URL which can be used by MDR
  * to open and read the referenced content. The standard MDR resolver is
@@ -70,16 +72,26 @@
  */
 class XmiReferenceResolverImpl extends XmiContext {
 
+    private static final Logger LOG =
+        Logger.getLogger(XmiReferenceResolverImpl.class);
+    
     private Map<String, Object> idToObjects = 
         Collections.synchronizedMap(new HashMap<String, Object>());
 
-    private Map<Object, XmiReference> objectsToId;
+    /**
+     * Map indexed by MOF ID.
+     */
+    private Map<String, XmiReference> objectsToId;
 
     /**
-     * Logger.
+     * System ID of top level document
      */
-    private static final Logger LOG =
-        Logger.getLogger(XmiReferenceResolverImpl.class);
+    private String topSystemId;
+
+    /**
+     * URI form of topSystemID for use in relativization.
+     */
+    private URI baseUri;
 
     /**
      * The array of paths in which the models references in other models will be
@@ -95,7 +107,14 @@
      * 
      * see org.andromda.repositories.mdr.MDRXmiReferenceResolverContext
      */
-    private static Map<String, URL> urlMap = new HashMap<String, URL>();
+    private Map<String, URL> urlMap = new HashMap<String, URL>();
+    
+    /**
+     * Mapping from URL or absolute reference back to the original SystemID
+     * that was read from the input file.  We'll preserve this mapping when
+     * we write things back out again.
+     */
+    private Map<String, String> reverseUrlMap = new HashMap<String, String>();
     
     /**
      * Constructor.
@@ -103,7 +122,7 @@
      * (see also {link org.netbeans.api.xmi.XMIReferenceResolver})
      */
     XmiReferenceResolverImpl(RefPackage[] extents, 
-            XMIInputConfig config, Map<Object, XmiReference> objectToIdMap) {
+            XMIInputConfig config, Map<String, XmiReference> objectToIdMap) {
         super(extents, config);
         registerSearchPath();
         objectsToId = objectToIdMap;
@@ -120,24 +139,53 @@
      *            referenced object
      */
     public void register(String systemId, String xmiId, RefObject object) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Registering XMI ID '" + xmiId 
+                    + "' in system ID '" + systemId + "'");
+        }
         super.register(systemId, xmiId, object);
-        if (!idToObjects.containsKey(xmiId)) {
-            // TODO: This needs to include the SystemID as well - tfm
-            idToObjects.put(xmiId, object);
+        if (topSystemId == null) {
+            topSystemId = systemId;
+            try {
+                baseUri = new URI(
+                        systemId.substring(0, systemId.lastIndexOf('/') + 1));
+            } catch (URISyntaxException e) {
+                LOG.error("Bad URI syntax for base URI from XMI document", e);
+            }
+            LOG.debug("Top system ID set to " + topSystemId);
+        }
+
+        if (systemId == topSystemId) {
+            systemId = null;
+        } else {
+            systemId = reverseUrlMap.get(systemId);
+        }
+        String key;
+        if (systemId == null) {
+            // No # here because PGML parser needs bare UUID/xmi.id
+            key = xmiId;            
+        } else {
+            key = systemId + "#" + xmiId;                
+        }
+
+        if (!idToObjects.containsKey(key)) {
+            idToObjects.put(key, object);
             objectsToId.put(object.refMofId(),
                     new XmiReference(systemId, xmiId));
         } else {
-            LOG.error("Collision - multiple elements with same xmi.id : " 
-                    + xmiId);
+            if (idToObjects.get(key) != object) {
+                LOG.error("Collision - multiple elements with same xmi.id : "
+                        + xmiId);
+            }
         }
     }
 
     /**
      * Return complete map of all registered objects.
      * 
-     * @return map of xmi.id to RefObject correspondances
+     * @return map of xmi.id to RefObject correspondences
      */
-    public Map getIdToObjectMap() {
+    public Map<String, Object> getIdToObjectMap() {
         return idToObjects;
     }
 
@@ -149,11 +197,11 @@
         objectsToId.clear();
     }
     
-    /*
+    /**
      * Set up module search path to be used by AndroMDA URL resolver.
      * The path is retrieved from shared state (a system property) which
      * is set up externally (currently by 
-     * @link org.argouml.uml.ProfileJava#loadProfile() which is probably
+     * org.argouml.uml.ProfileJava#loadProfile() which is probably
      * the wrong place for it)
      */
     private void registerSearchPath() {
@@ -225,7 +273,7 @@
         // Several tries to construct a URL that really exists.
         if (modelUrl == null) {
             // If systemId is a valid URL, simply use it
-            modelUrl = this.getValidURL(systemId);
+            modelUrl = this.getValidURL(fixupURL(systemId));
             if (modelUrl == null) {
                 // Try to find suffix in module list.
                 String modelUrlAsString = findModuleURL(suffix);
@@ -248,6 +296,20 @@
             if (modelUrl != null) {
                 LOG.info("Referenced model --> '" + modelUrl + "'");
                 urlMap.put(suffixWithExt, modelUrl);
+                String relativeUri = systemId;
+                try {
+                    relativeUri = baseUri.relativize(new URI(systemId))
+                            .toString();
+                    LOG.debug("       system ID " + systemId 
+                            + "\n  relativized as " + relativeUri);
+                } catch (URISyntaxException e) {
+                    LOG.error("Error relativizing system ID " + systemId, e);
+                }
+                // MDR will register the first form in the actual file that it
+                // reads in and the second form when it resolves 
+                // an external reference
+                reverseUrlMap.put(modelUrl.toString(), relativeUri);
+                reverseUrlMap.put(systemId, relativeUri);
             }
         }
         return modelUrl;
@@ -289,24 +351,21 @@
                     return null;
                 }
 
-                if (moduleName.endsWith(".zip") 
-                        || moduleName.endsWith(".jar")) {
-                    // typical case for MagicDraw
-                    urlString = "jar:" + urlString + "!/"
-                            + moduleName.substring(0, moduleName.length() - 4);
-                }
-                return urlString;
+                return fixupURL(urlString);
             }
         }
         return null;
     }
 
+
+    
     /**
-     * Gets the suffix of the <code>systemId</code>.<p>
-     * Copied from AndroMDA 3.1 by Ludo (rastaman).
-     * see org.andromda.repositories.mdr.MDRXmiReferenceResolverContext
-     * @param systemId
-     *            the system identifier.
+     * Gets the suffix of the <code>systemId</code>.
+     * <p>
+     * Copied from AndroMDA 3.1 by Ludo (rastaman). see
+     * org.andromda.repositories.mdr.MDRXmiReferenceResolverContext
+     * 
+     * @param systemId the system identifier.
      * @return the suffix as a String.
      */
     private String getSuffix(String systemId) {
@@ -342,6 +401,10 @@
     private URL findModelUrlOnClasspath(String systemId) {
         String modelName = systemId.substring(systemId.lastIndexOf("/") + 1,
                 systemId.length());
+
+        // TODO: The following will fail to find files with embedded dots such
+        // as andromda-profile-datatype-3.1.xml - tfm
+        
         String dot = ".";
         // remove the first prefix because it may be an archive
         // (like magicdraw)
@@ -399,4 +462,19 @@
     ////////// End AndroMDA Code //////////////////////
     /////////////////////////////////////////////////////
 
+    /**
+     * Fix up a file URL for a Zip file or Jar.  Assume it is a single
+     * file archive with the entry name the same as the base name.
+     */
+    private String fixupURL(String url) {
+        final String suffix = getSuffix(url);
+        if (suffix.endsWith(".zargo")) {
+            url = "jar:" + url + "!/"
+                    + suffix.substring(0, suffix.length() - 6) + ".xmi";
+        } else if (suffix.endsWith(".zip") || suffix.endsWith(".jar")) {
+            url = "jar:" + url + "!/"
+                    + suffix.substring(0, suffix.length() - 4);
+        }
+        return url;
+    }
 }

Modified: trunk/src/model-mdr/src/org/argouml/model/mdr/XmiWriterMDRImpl.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/model-mdr/src/org/argouml/model/mdr/XmiWriterMDRImpl.java?view=diff&rev=13168&p1=trunk/src/model-mdr/src/org/argouml/model/mdr/XmiWriterMDRImpl.java&p2=trunk/src/model-mdr/src/org/argouml/model/mdr/XmiWriterMDRImpl.java&r1=13167&r2=13168
==============================================================================
--- trunk/src/model-mdr/src/org/argouml/model/mdr/XmiWriterMDRImpl.java	(original)
+++ trunk/src/model-mdr/src/org/argouml/model/mdr/XmiWriterMDRImpl.java	2007-07-27 15:26:25-0700
@@ -29,6 +29,7 @@
 import java.io.Writer;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Iterator;
 
 import javax.jmi.reflect.RefObject;
@@ -84,8 +85,7 @@
      * except for the profile model(s), ignoring the model specified by the 
      * caller.
      */
-    private static final boolean WRITE_ALL = false;
-
+    private static final boolean WRITE_ALL = true;
 
     /*
      * Private constructor for common work needed by both public
@@ -166,14 +166,14 @@
                 elements.add(model);
                 LOG.info("Saving model '" + ((Model) model).getName() + "'");
             } else {
-                RefObject profile = modelImpl.getProfileModel();
+                Collection<RefObject> profileElements = modelImpl.getProfileElements();
                 UmlPackage pkg = modelImpl.getUmlPackage();
                 for (Iterator it = pkg.getCore().getElement().refAllOfType()
                         .iterator(); it.hasNext();) {
                     RefObject obj = (RefObject) it.next();
                     // Find top level objects which aren't part of profile
                     if (obj.refImmediateComposite() == null ) {
-                        if (!obj.equals(profile)) {
+                        if (!profileElements.contains(obj)) {
                             elements.add(obj);
                         }
                     }
@@ -189,7 +189,7 @@
                 stream = oStream;
             }
 
-            xmiWriter.write(stream, elements, XMI_VERSION);
+            xmiWriter.write(stream, "file:///ThisIsADummyName.xmi", elements, XMI_VERSION);
         } catch (IOException e) {
             throw new UmlException(e);
         }
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.