Author: tfmorris
Date: 2008-07-27 22:59:23-0700
New Revision: 15385
Modified:
trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/MDRModelImplementation.java
trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/ModelEventPumpMDRImpl.java
trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/ModelManagementFactoryMDRImpl.java
trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/XmiReaderImpl.java
Log:
Issue 4994: Add support for read-only extents
Modified: trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/MDRModelImplementation.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/MDRModelImplementation.java?view=diff&rev=15385&p1=trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/MDRModelImplementation.java&p2=trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/MDRModelImplementation.java&r1=15384&r2=15385
==============================================================================
--- trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/MDRModelImplementation.java (original)
+++ trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/MDRModelImplementation.java 2008-07-27 22:59:23-0700
@@ -35,6 +35,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import javax.jmi.model.ModelPackage;
import javax.jmi.model.MofPackage;
@@ -187,15 +188,66 @@
Collections.synchronizedMap(new HashMap<String, String>());
private List<String> searchDirs = new ArrayList<String>();
+
+
+ /**
+ * Set of extents which are readonly. For now we assume that the set is
+ * small and keep it in a simple list that we do a linear search of.
+ */
+ private Map<UmlPackage, Boolean> extents =
+ new ConcurrentHashMap<UmlPackage, Boolean>(10, (float).5, 1);
/**
* @return Returns the root UML Factory package for user model.
+ * @deprecated for 0.26. Use RefObject.refOutermostPackage instead if at all
+ * possible. In some cases (like an unqualified createClass()),
+ * additional infrastructure work is required in the ArgoUML app
+ * before this will be possible.
*/
UmlPackage getUmlPackage() {
return umlPackage;
}
+
/**
+ * Set the current user model extent.
+ *
+ * @param uPackage extent/UmlPackage containing latest user model loaded
+ */
+ private void setUmlPackage(UmlPackage uPackage) {
+ // TODO: This will need to change when we support multiple user models.
+ // Currently too much code depends on having a single model to change at
+ // the last minute.
+
+ // Delete the old extent first
+ extents.remove(umlPackage);
+ umlPackage.refDelete();
+
+ umlPackage = uPackage;
+ extents.put(umlPackage, Boolean.FALSE);
+ LOG.debug("Registered new extent " + umlPackage);
+ LOG.debug("All registered extents = " + repository.getExtentNames());
+ }
+
+
+ void addExtent(UmlPackage extent, boolean readOnly) {
+ if (readOnly) {
+ extents.put(extent, Boolean.TRUE);
+ } else {
+ setUmlPackage(extent);
+ }
+ }
+
+ boolean isReadOnly(Object extent) {
+ Boolean result = extents.get(extent);
+ if (result == null) {
+ LOG.warn("Unable to find extent " + extent);
+ return false;
+ }
+ return result.booleanValue();
+ }
+
+ /**
* @return MOF Package containing UML metamodel (M2).
*/
MofPackage getMofPackage() {
@@ -305,24 +357,7 @@
}
}
- // Create an extent for the uml data
- umlPackage = (UmlPackage) repository.getExtent(MODEL_EXTENT_NAME);
- LOG.debug("MDR Init - tried to get UML extent");
- if (umlPackage != null) {
- // NOTE: If we switch to a persistent repository like the b-tree
- // repository we'll want to keep the old extent(s) around
- umlPackage.refDelete();
- umlPackage = null;
- LOG.debug("MDR Init - UML extent existed - "
- + "deleted it and all UML data");
- }
- try {
- umlPackage =
- (UmlPackage) repository.createExtent(
- MODEL_EXTENT_NAME, mofPackage);
- } catch (CreationFailedException e) {
- throw new UmlException(e);
- }
+ createDefaultExtent();
LOG.debug("MDR Init - created UML extent");
if (umlPackage == null) {
@@ -371,6 +406,29 @@
}
+
+ private void createDefaultExtent() throws UmlException {
+ // Create a default extent for the user UML model. This will get
+ // replaced if a new model is read in from an XMI file.
+ umlPackage = (UmlPackage) repository.getExtent(MODEL_EXTENT_NAME);
+ LOG.debug("MDR Init - tried to get UML extent");
+ if (umlPackage != null) {
+ // NOTE: If we switch to a persistent repository like the b-tree
+ // repository we'll want to keep the old extent(s) around
+ umlPackage.refDelete();
+ umlPackage = null;
+ LOG.debug("MDR Init - UML extent existed - "
+ + "deleted it and all UML data");
+ }
+ try {
+ umlPackage =
+ (UmlPackage) repository.createExtent(
+ MODEL_EXTENT_NAME, mofPackage);
+ } catch (CreationFailedException e) {
+ throw new UmlException(e);
+ }
+ }
+
/**
* Shutdown repository in a graceful fashion
* (currently unused).
@@ -629,7 +687,7 @@
public XmiReader getXmiReader() throws UmlException {
- XmiReader reader = new XmiReaderImpl(this, umlPackage);
+ XmiReader reader = new XmiReaderImpl(this);
return reader;
}
Modified: trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/ModelEventPumpMDRImpl.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/ModelEventPumpMDRImpl.java?view=diff&rev=15385&p1=trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/ModelEventPumpMDRImpl.java&p2=trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/ModelEventPumpMDRImpl.java&r1=15384&r2=15385
==============================================================================
--- trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/ModelEventPumpMDRImpl.java (original)
+++ trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/ModelEventPumpMDRImpl.java 2008-07-27 22:59:23-0700
@@ -46,6 +46,7 @@
import javax.jmi.model.Reference;
import javax.jmi.reflect.InvalidObjectException;
import javax.jmi.reflect.RefAssociation;
+import javax.jmi.reflect.RefBaseObject;
import javax.jmi.reflect.RefObject;
import org.apache.log4j.Logger;
@@ -65,6 +66,7 @@
import org.netbeans.api.mdr.events.MDRChangeEvent;
import org.netbeans.api.mdr.events.MDRPreChangeListener;
import org.netbeans.api.mdr.events.TransactionEvent;
+import org.netbeans.api.mdr.events.VetoChangeException;
/**
* The ModelEventPump for the MDR implementation.<p>
@@ -353,6 +355,10 @@
}
}
+ private boolean isReadOnly(RefBaseObject object) {
+ return modelImpl.isReadOnly(object.refOutermostPackage());
+ }
+
/**
* @param e Event from MDR indicating a planned change.
* @see org.netbeans.api.mdr.events.MDRPreChangeListener#plannedChange
@@ -362,6 +368,30 @@
synchronized (eventCountMutex) {
pendingEvents++;
}
+ if (e instanceof InstanceEvent) {
+ if (e.isOfType(InstanceEvent.EVENT_INSTANCE_CREATE)) {
+ RefBaseObject element = (RefBaseObject) ((InstanceEvent) e).getSource();
+ if (isReadOnly(element)) {
+ throw new VetoChangeException(e.getSource(), null);
+ }
+ } else {
+ RefObject element = ((InstanceEvent) e).getInstance();
+ if (isReadOnly(element)) {
+ throw new VetoChangeException(e.getSource(), element);
+ }
+ }
+ } else if (e instanceof AssociationEvent) {
+ RefObject element = ((AssociationEvent) e).getFixedElement();
+ if (isReadOnly(element)) {
+ throw new VetoChangeException(element, element);
+ }
+ } else if (e instanceof AttributeEvent) {
+ RefObject element = (RefObject) ((AttributeEvent) e).getSource();
+ if (isReadOnly(element)) {
+ throw new VetoChangeException(element, element);
+ }
+ }
+
// Prototypical logging code that can be enabled and modified to
// discover who's creating certain types of events
Modified: trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/ModelManagementFactoryMDRImpl.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/ModelManagementFactoryMDRImpl.java?view=diff&rev=15385&p1=trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/ModelManagementFactoryMDRImpl.java&p2=trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/ModelManagementFactoryMDRImpl.java&r1=15384&r2=15385
==============================================================================
--- trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/ModelManagementFactoryMDRImpl.java (original)
+++ trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/ModelManagementFactoryMDRImpl.java 2008-07-27 22:59:23-0700
@@ -59,14 +59,9 @@
private Object theRootModel;
/**
- * The ModelManagement package.
- */
- private ModelManagementPackage modelManagementPackage;
-
- /**
* The model implementation.
*/
- private ModelImplementation modelImpl;
+ private MDRModelImplementation modelImpl;
/**
* Constructor.
@@ -75,18 +70,20 @@
* The MDRModelImplementation.
*/
public ModelManagementFactoryMDRImpl(MDRModelImplementation mi) {
- modelManagementPackage = mi.getUmlPackage().getModelManagement();
modelImpl = mi;
}
public Model createModel() {
- Model myModel = modelManagementPackage.getModel().createModel();
+ Model myModel = getModelManagementPackage().getModel().createModel();
super.initialize(myModel);
return myModel;
}
-
+ private ModelManagementPackage getModelManagementPackage() {
+ return modelImpl.getUmlPackage().getModelManagement();
+ }
+
public void setRootModel(Object rootModel) {
if (rootModel != null && !(rootModel instanceof Model)) {
throw new IllegalArgumentException(
@@ -104,7 +101,7 @@
public ElementImport createElementImport() {
ElementImport myElementImport =
- modelManagementPackage.getElementImport().createElementImport();
+ getModelManagementPackage().getElementImport().createElementImport();
super.initialize(myElementImport);
return myElementImport;
}
@@ -125,7 +122,7 @@
public UmlPackage createPackage() {
UmlPackage myUmlPackage =
- modelManagementPackage.getUmlPackage().createUmlPackage();
+ getModelManagementPackage().getUmlPackage().createUmlPackage();
super.initialize(myUmlPackage);
return myUmlPackage;
}
@@ -150,7 +147,7 @@
public Object createSubsystem() {
Subsystem mySubsystem =
- modelManagementPackage.getSubsystem().createSubsystem();
+ getModelManagementPackage().getSubsystem().createSubsystem();
super.initialize(mySubsystem);
return mySubsystem;
}
Modified: trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/XmiReaderImpl.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/XmiReaderImpl.java?view=diff&rev=15385&p1=trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/XmiReaderImpl.java&p2=trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/XmiReaderImpl.java&r1=15384&r2=15385
==============================================================================
--- trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/XmiReaderImpl.java (original)
+++ trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/XmiReaderImpl.java 2008-07-27 22:59:23-0700
@@ -57,11 +57,13 @@
import org.argouml.model.UmlException;
import org.argouml.model.XmiException;
import org.argouml.model.XmiReader;
+import org.netbeans.api.mdr.CreationFailedException;
import org.netbeans.api.xmi.XMIReader;
import org.netbeans.api.xmi.XMIReaderFactory;
import org.netbeans.lib.jmi.xmi.InputConfig;
import org.netbeans.lib.jmi.xmi.UnknownElementsListener;
import org.netbeans.lib.jmi.xmi.XMIHeaderConsumer;
+import org.omg.uml.UmlPackage;
import org.openide.ErrorManager;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
@@ -87,7 +89,7 @@
private XmiReferenceResolverImpl resolver;
- private RefPackage modelPackage;
+ private RefPackage modelPackage;
/**
* Flag indicating unknown element was found in XMI file.
@@ -122,26 +124,43 @@
/**
* Constructor for XMIReader.
* @param parentModelImplementation The ModelImplementation
- * @param mp extent to read user models into
+ * @param mp extent to read user models into. Ignored.
+ * @deprecated for 0.26 by tfmorris. Use
+ * {@link #XmiReaderImpl(MDRModelImplementation)}.
*/
- public XmiReaderImpl(MDRModelImplementation parentModelImplementation,
+ XmiReaderImpl(MDRModelImplementation parentModelImplementation,
RefPackage mp) {
+ this(parentModelImplementation);
+ }
+ /**
+ * Constructor for XMIReader.
+ * @param parentModelImplementation The ModelImplementation
+ */
+ XmiReaderImpl(MDRModelImplementation parentModelImplementation) {
modelImpl = parentModelImplementation;
- modelPackage = mp;
}
-
+
@Deprecated
public Collection parse(InputSource inputSource) throws UmlException {
return parse(inputSource, false);
}
- public Collection parse(InputSource inputSource, boolean profile)
+ public Collection parse(InputSource inputSource, boolean readOnly)
throws UmlException {
Collection<RefObject> newElements = Collections.emptyList();
- RefPackage extent = modelPackage;
+ RefPackage extent;
+ try {
+ extent = modelImpl.getRepository().createExtent(
+ inputSource.getSystemId(), modelImpl.getMofPackage());
+ } catch (CreationFailedException e1) {
+ throw new UmlException("Extent creation failed", e1);
+ }
+
+ modelImpl.addExtent((UmlPackage) extent, readOnly);
+
try {
LOG.info("Loading '" + inputSource.getSystemId() + "'");
@@ -152,7 +171,7 @@
resolver = new XmiReferenceResolverImpl(new RefPackage[] {extent},
config, modelImpl.getObjectToId(),
modelImpl.getPublic2SystemIds(), modelImpl.getSearchPath(),
- profile,
+ readOnly,
inputSource.getPublicId(), inputSource.getSystemId());
config.setReferenceResolver(resolver);
config.setHeaderConsumer(this);
@@ -191,12 +210,6 @@
// Disable event delivery during model load
modelImpl.getModelEventPump().stopPumpingEvents();
- Collection<RefObject> startTopElements =
- modelImpl.getFacade().getRootElements();
- int numElements = startTopElements.size();
- LOG.debug("Number of top level elements before import: "
- + numElements);
-
try {
String systemId = inputSource.getSystemId();
File file = copySource(inputSource);
@@ -212,23 +225,11 @@
// Clear the associated ID maps & reset starting collection
resolver.clearIdMaps();
- startTopElements = modelImpl.getFacade().getRootElements();
newElements = convertAndLoadUml13(inputSource.getSystemId(),
extent, xmiReader, inputSource);
}
- numElements = modelImpl.getFacade().getRootElements().size()
- - numElements;
-
- // This indicates a malformed XMI file. Log the error.
- if (newElements.size() != numElements) {
- LOG.error("Mismatch between number of elements returned by"
- + " XMIReader ("
- + newElements.size()
- + ") and number of new top level elements found ("
- + numElements + ")");
- }
} finally {
@@ -264,7 +265,7 @@
throw new XmiException(e);
}
- if (profile) {
+ if (readOnly) {
modelImpl.setProfileElements(newElements);
}
return newElements;
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.