Index: build.xml =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/build.xml,v retrieving revision 1.1.1.2 retrieving revision 1.6 diff -u -r1.1.1.2 -r1.6 --- build.xml 18 Jul 2002 08:37:22 -0000 1.1.1.2 +++ build.xml 18 Jul 2002 10:06:31 -0000 1.6 @@ -14,17 +14,44 @@ + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + @@ -34,39 +61,35 @@ - - - + + + + - - + + - - + + - + - - - + + + + - - - - - - - - - - + + + - - - + + + + @@ -96,9 +119,10 @@ - - - + + + + @@ -106,7 +130,7 @@ - + @@ -118,7 +142,7 @@ manifest="manifest-mof-subst.mf" compress="false"> - + @@ -129,7 +153,7 @@ manifest="manifest-jmi-subst.mf" compress="false"> - + @@ -151,7 +175,7 @@ - + @@ -165,7 +189,7 @@ - + @@ -173,7 +197,7 @@ - + @@ -186,7 +210,7 @@ compress="false" manifest="manifest-mdr-subst.mf"> - + @@ -195,7 +219,7 @@ compress="false" manifest="manifest-toolkit-subst.mf"> - + @@ -205,13 +229,13 @@ compress="false" manifest="manifest-mdrapi-subst.mf"> - + - + @@ -220,16 +244,17 @@ compress="false" manifest="manifest-explorer-subst.mf"> - + - - - + + + + @@ -238,9 +263,10 @@ - - - + + + + @@ -255,7 +281,7 @@ module="netbeans/modules/autoload/mdrapi.jar" homepage="http://mdr.${homepage.base}/" distribution="http://${dist.base}/mdrapi.nbm"> - + @@ -272,7 +298,7 @@ module="netbeans/modules/mdrtoolkit.jar" homepage="http://mdr.${homepage.base}/" distribution="http://${dist.base}/mdrtoolkit.nbm"> - + @@ -283,7 +309,7 @@ module="netbeans/modules/mdr.jar" homepage="http://mdr.${homepage.base}/" distribution="http://${dist.base}/mdr.nbm"> - + @@ -332,7 +358,7 @@ module="netbeans/modules/mdrexplorer.jar" homepage="http://mdr.${homepage.base}/" distribution="http://${dist.base}/mdrexplorer.nbm"> - + @@ -388,9 +414,10 @@ - - - + + + + Index: src/org/netbeans/api/mdr/MDRepository.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/api/mdr/MDRepository.java,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- src/org/netbeans/api/mdr/MDRepository.java 2 Jul 2002 07:35:25 -0000 1.1.1.1 +++ src/org/netbeans/api/mdr/MDRepository.java 10 Jul 2002 15:25:24 -0000 1.2 @@ -63,6 +63,16 @@ */ public String[] getExtentNames(); + /** + * Returns the object with the given MOF ID. + * + * @param mofId the MOF ID of the object to be returned + * @return the object with the given MOF ID + * @throws java.util.NoSuchElementException if there is no object with + * the given MOF ID + */ + public RefBaseObject getByMofId(String mofId); + /** Starts a new transaction. This method causes that the repository will be locked * for read-only access or exclusive write access (depending on the value passed as * a parameter) and starts a new transaction. It is prefered to enclose any batch Index: src/org/netbeans/api/mdr/events/AttributeEvent.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/api/mdr/events/AttributeEvent.java,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- src/org/netbeans/api/mdr/events/AttributeEvent.java 2 Jul 2002 07:35:25 -0000 1.1.1.1 +++ src/org/netbeans/api/mdr/events/AttributeEvent.java 11 Jul 2002 08:52:42 -0000 1.2 @@ -28,13 +28,13 @@ /** Bitmask representing all event types related to classifier attribute changes */ public static final int EVENTMASK_CLASSATTR = 0x102FFFF; - /** Event type indicating that a value of a single-valued attribute is to be/was changed or - * a value element of a multi-valued attribute is to be/was changed. + /** Event type indicating that a value of a single-valued instance attribute is to be/was changed or + * a value element of a multi-valued instance attribute is to be/was changed. */ public static final int EVENT_ATTRIBUTE_SET = 0x1010001; - /** Event type indicating that a value element of a multi-valued attribute is to be/was added */ + /** Event type indicating that a value element of a multi-valued instance attribute is to be/was added */ public static final int EVENT_ATTRIBUTE_ADD = 0x1010002; - /** Event type indicating that a value element of a multi-valued attribute is to be/was removed */ + /** Event type indicating that a value element of a multi-valued instance attribute is to be/was removed */ public static final int EVENT_ATTRIBUTE_REMOVE = 0x1010004; /** Event type indicating that a value of a single-valued classifier attribute is to be/was changed or Index: src/org/netbeans/api/mdr/events/MDRChangeEvent.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/api/mdr/events/MDRChangeEvent.java,v retrieving revision 1.1.1.1 retrieving revision 1.4 diff -u -r1.1.1.1 -r1.4 --- src/org/netbeans/api/mdr/events/MDRChangeEvent.java 2 Jul 2002 07:35:25 -0000 1.1.1.1 +++ src/org/netbeans/api/mdr/events/MDRChangeEvent.java 18 Jul 2002 11:08:50 -0000 1.4 @@ -22,12 +22,36 @@ * This way the event listeners can filter the events using a bitmask. * * @author Martin Matula + * @author Holger Krug. */ public abstract class MDRChangeEvent extends EventObject { /** Bitmask representing all possible repository event types. * Can be used for registering listener to receive all kinds of events. */ public static final int EVENTMASK_ALL = 0x0FFFFFFF; + + /** Bitmask representing all event types which are initially fired on + * associations. */ + public static final int EVENTMASK_ON_ASSOCIATION = AssociationEvent.EVENTMASK_ASSOCIATION; + /** Bitmask representing all event types which are initially fired on + * instance objects. */ + public static final int EVENTMASK_ON_INSTANCE = InstanceEvent.EVENT_INSTANCE_CREATE | AttributeEvent.EVENTMASK_ATTRIBUTE; + /** Bitmask representing all event types which are initially fired on + * class proxies. */ + public static final int EVENTMASK_ON_CLASS = InstanceEvent.EVENT_INSTANCE_DELETE | AttributeEvent.EVENTMASK_CLASSATTR; + /** Bitmask representing all event types which are initially fired on + * package proxies. + * + *

Note: This bitmask is empty, because there are not + * events which originate on packages. Packages receive only events + * propagated from other objects. As a consequence this bitmask is + * useless. It is nevertheless part of the API to achieve greater + * uniformity of the API.

+ */ + public static final int EVENTMASK_ON_PACKAGE = 0x0000000; + /** Bitmask representing all event types which are initially fired on + * repositories. */ + public static final int EVENTMASK_ON_REPOSITORY = ExtentEvent.EVENTMASK_EXTENT | TransactionEvent.EVENTMASK_TRANSACTION; // event type private final int eventType; Index: src/org/netbeans/api/mdr/events/MDRChangeSource.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/api/mdr/events/MDRChangeSource.java,v retrieving revision 1.1.1.1 retrieving revision 1.3 diff -u -r1.1.1.1 -r1.3 --- src/org/netbeans/api/mdr/events/MDRChangeSource.java 2 Jul 2002 07:35:25 -0000 1.1.1.1 +++ src/org/netbeans/api/mdr/events/MDRChangeSource.java 18 Jul 2002 11:08:50 -0000 1.3 @@ -18,34 +18,65 @@ * The objects that have to be registered for event * notifications need to implement {@link MDRChangeListener} * or {@link MDRPreChangeListener} interface.

- * The repository should distribute all the events in the following way: + * + *

The repository distributes all the events recursively in the following way: *

    - *
  • Each event fired on an instance is also fired on the corresponding class proxy for this instance. + *
  • Event fired on an instance are also fired on the corresponding class proxy for this instance. *
  • Events fired on a class proxy are propagated to its immediate package proxy. *
  • Events fired on an association proxy are fired on all the instances affected by this event * (e.g. instances added/removed from a link) and also it is fired on the immediate package proxy. - *
  • Each event fired on a package proxy are propagated to its immediate package proxy. + *
  • Event fired on a package proxy are propagated to its immediate package proxy. * If the package proxy is outermost, the event is propagated to the MDRepository that contains * the proxy. *
- * All the events are propagated recursively till they reach the repository object (e.g. each + * Figure XXX: MARTIN, PLEASE ADD THE FIGURE, I'VE CREATED shows where the + * events are initially fired and how they propagate. + *

+ * + *

All the events are propagated recursively till they reach the repository object (e.g. each * instance event is as a result of propagation always fired on the instance itself, * on its class proxy, on its immediate package proxy, on all other package proxies containing * the immediate package proxy to the outermost package proxy and at the end on the repository containing - * instance).
- * In addition, any event is fired only once for each listener (so no matter how many objects + * instance).

+ * + *

In addition, any event is fired only once for each listener (so no matter how many objects * on the event's propagation path is a listener registered on - e.g. on both - * class proxy and its instances - it receives each notification only once per event). + * class proxy and its instances - it receives each notification only once per event).

+ * + *

Listeners may be added specifically for certain events only by calling + * {@link #addListener(MDRChangeListener, int) addListener(MDRChangeListener, int)}. + * If instead {@link #addListener(MDRChangeListener) addListener(MDRChangeListener)} + * is used for listener addition and, hence, no event mask is speficied, the listener + * receives all events which are propagated to the source it is registered for. * * @author Martin Matula + * @author Holger Krug. */ public interface MDRChangeSource { - /** Registers a listener for receiving event notifications. + + /** Registers a listener for receiving event notifications using the default + * event mask. The default event mask depends on the type of the change source + * and filters all events which are initially fired on this object. * @param listener Object that implements {@link MDRChangeListener} interface. */ public void addListener(MDRChangeListener listener); + /** Registers a listener for receiving notifications about events the type + * of which matches mask. + * @param listener Object that implements {@link MDRChangeListener} interface. + * @param eventMask bitmask to be used in a call to {@link MdrChangeEvent#isOfType()} + * to filter events based on the mask + */ + public void addListener(MDRChangeListener listener, int mask); /** Removes listener from the list of objects registered for events notifications. * @param listener Object that implements {@link MDRChangeListener} interface. */ public void removeListener(MDRChangeListener listener); + /** Removes listener only for events of types matching mask. + * If a listener is additionally registered for events of other types, it + * proceeds listening on the remaining event types. + * @param listener Object that implements {@link MDRChangeListener} interface. + * @param mask determines the types of events the listener shall stop + * to listen on + */ + public void removeListener(MDRChangeListener listener, int mask); } Index: src/org/netbeans/api/mdr/events/TransactionEvent.java =================================================================== RCS file: src/org/netbeans/api/mdr/events/TransactionEvent.java diff -N src/org/netbeans/api/mdr/events/TransactionEvent.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/netbeans/api/mdr/events/TransactionEvent.java 11 Jul 2002 08:53:42 -0000 1.2 @@ -0,0 +1,42 @@ +/* + * Sun Public License Notice + * + * The contents of this file are subject to the Sun Public License + * Version 1.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://www.sun.com/ + * + * The Original Code is NetBeans. The Initial Developer of the Original + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2001 Sun + * Microsystems, Inc. All Rights Reserved. + */ +package org.netbeans.api.mdr.events; + +import javax.jmi.reflect.RefFeatured; +import org.netbeans.api.mdr.MDRepository; + +/** Class representing MDR events related to start, commit and + * rollback of write transactions. + * + * @author Holger Krug. + */ +public class TransactionEvent extends MDRChangeEvent { + + /** Bitmask representing all event types related to write transactions */ + public static final int EVENTMASK_TRANSACTION = 0x011FFFF; + + /** Event type indicating that a write transaction has been started. */ + public static final int EVENT_TRANSACTION_START = 0x0110001; + /** Event type indicating that a write transaction has been committed. */ + public static final int EVENT_TRANSACTION_COMMIT = 0x0110002; + /** Event type indicating that a write transaction has been rolled back. */ + public static final int EVENT_TRANSACTION_ROLLBACK = 0x0110004; + + /** Creates new TransactionEvent instance. + * @param source the event source, an instance of MDRepository. + * @param type the event type. + */ + public TransactionEvent(MDRepository source, int type) { + super(source, type); + } +} Index: src/org/netbeans/mdr/NBMDRepositoryImpl.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/mdr/NBMDRepositoryImpl.java,v retrieving revision 1.1.1.3 retrieving revision 1.12 diff -u -r1.1.1.3 -r1.12 --- src/org/netbeans/mdr/NBMDRepositoryImpl.java 18 Jul 2002 08:37:24 -0000 1.1.1.3 +++ src/org/netbeans/mdr/NBMDRepositoryImpl.java 18 Jul 2002 11:16:52 -0000 1.12 @@ -1,11 +1,11 @@ /* * Sun Public License Notice - * + * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ - * + * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2001 Sun * Microsystems, Inc. All Rights Reserved. @@ -42,8 +42,8 @@ /* -------------------------------------------------------------------- */ /* -- Private static constants ---------------------------------------- */ /* -------------------------------------------------------------------- */ - -// private static final Collection instances = new HashSet(); + + // private static final Collection instances = new HashSet(); private static final URL MOF_XML_URL = ModelPackage.class.getResource("resources/mof.xml"); private static final URL BOOTMOF_XML_URL = ModelPackage.class.getResource("resources/mof.xml"); @@ -55,22 +55,22 @@ private static final String INTERCEPTABLE_TAG_ID = "org.netbeans.mdr.interceptable"; private static final String TRANSIENT_TAG_ID = "org.netbeans.mdr.transient"; private static final String TAG_VALUE_TRUE = "true"; - + public static final String BOOT_MOF = "BootMOF"; public static final String PURE_MOF = "MOF"; - + /* -------------------------------------------------------------------- */ /* -- Private attributes ---------------------------------------------- */ /* -------------------------------------------------------------------- */ - + private MdrStorage mdrStorage = null; - + private Map classProxies = null; private Map associationProxies = null; - private Map classProxiesMofIds = null; + private Map classProxiesMofIds = null; private final Map parameters; - + /* --------------------------------------------------------------------- */ /* -- Constructors ----------------------------------------------------- */ /* --------------------------------------------------------------------- */ @@ -95,18 +95,67 @@ * storage location * * - * */ - public NBMDRepositoryImpl () { +// *

Additionally the following properties allow to replace parts +// * of the MDR implementation by tailor-made classes, namely the base classes +// * for generated handler classes. This is an experimental feature, use +// * it with care. Currently no documentation is available about the features +// * the replacing classes must provide in order to cooperate with the generated code:

+// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// *
org.netbeans.mdr.handlers.PackageProxyHandler(no default)fully qualified name of the class replacing PackageProxyHandler +// * as base class for package proxy implementations
org.netbeans.mdr.handlers.ClassProxyHandler(no default)fully qualified name of the class replacing ClassProxyHandler +// * as default base class for class proxy implementations
org.netbeans.mdr.handlers.InstanceHandler(no default)fully qualified name of the class replacing InstanceHandler +// * as default base class for instance implementations
org.netbeans.mdr.handlers.AssociationHandler(no default)fully qualified name of the class replacing AssociationHandler +// * as default base class for association implementations
org.netbeans.mdr.handlers.StructureHandler(no default)fully qualified name of the class replacing StructImpl +// * as base class for structure implementations
+// * +// */ + public NBMDRepositoryImpl() { System.out.println("using default values..."); - + String storageClass = System.getProperty("org.netbeans.mdr.storagemodel.StorageFactoryClassName", "org.netbeans.mdr.persistence.btreeimpl.btreestorage.BtreeFactory"); String storageFile = System.getProperty("org.netbeans.mdr.persistence.Dir"); - +// String packageProxyHandler = System.getProperty("org.netbeans.mdr.handlers.PackageProxyHandler"); +// String classProxyHandler = System.getProperty("org.netbeans.mdr.handlers.ClassProxyHandler"); +// String instanceHandler = System.getProperty("org.netbeans.mdr.handlers.InstanceHandler"); +// String associationHandler = System.getProperty("org.netbeans.mdr.handlers.AssociationHandler"); +// String structureHandler = System.getProperty("org.netbeans.mdr.handlers.StructureHandler"); + parameters = new HashMap(); parameters.put("storage", storageClass); parameters.put(org.netbeans.mdr.persistence.btreeimpl.btreestorage.BtreeFactory.STORAGE_FILE_NAME, storageFile); -// instances.add(this); +// if ( packageProxyHandler != null ) parameters.put("PackageProxyHandler", packageProxyHandler); +// if ( classProxyHandler != null ) parameters.put("ClassProxyHandler", classProxyHandler); +// if ( instanceHandler != null ) parameters.put("InstanceHandler", instanceHandler); +// if ( associationHandler != null ) parameters.put("AssociationHandler", associationHandler); +// if ( structureHandler != null ) parameters.put("StructureHandler", structureHandler); + // instances.add(this); } /** Creates new {@link org.netbeans.api.mdr.MDRepository} with given parameters. @@ -116,35 +165,77 @@ *
  • storage: name of a class implementing {@link * org.netbeans.mdr.persistence.StorageFactory}
  • *
  • fileName: storage location
  • - * - * + *

    */ +// *

    Additionally the following parameters allow to replace parts +// * of the MDR implementation by tailor-made classes, namely the base classes +// * for generated handler classes. This is an experimental feature, use +// * it with care. Currently no documentation is available about the features +// * the replacing classes must provide in order to cooperate with the generated code:

    +// * +// *

      +// *
    1. PackageProxyHandler: fully qualified name of the super-class +// * for package proxy implementations (default: +// * org.netbeans.mdr.handler.PackageProxyHandler)
    2. +// *
    3. ClassProxyHandler: fully qualified name of the default super-class +// * for class proxy implementations (default: +// * org.netbeans.mdr.handler.ClassProxyHandler)
    4. +// *
    5. InstanceHandler: fully qualified name of the default super-class +// * for instance implementations (default: +// * org.netbeans.mdr.handler.InstanceHandler)
    6. +// *
    7. AssociationHandler: fully qualified name of the default super-class +// * for assocation proxy implementations (default: +// * org.netbeans.mdr.handler.AssociationHandler)
    8. +// *
    9. StructureHandler: fully qualified name of the super-class +// * for structure implementations (default: +// * org.netbeans.mdr.handler.StructImpl)
    10. +// *

    +// * +// */ public NBMDRepositoryImpl(Map parameters) { Log.out.println("Creating MDRepository implementation ..."); this.parameters = parameters; -// instances.add(this); + // instances.add(this); } - + /* -------------------------------------------------------------------- */ - /* -- Implementation of org.netbeans.api.mdr.event.MDRChangeSource ---- */ + /* -- Implementation of org.netbeans.api.mdr.events.MDRChangeSource --- */ /* -------------------------------------------------------------------- */ - /** Registers a listener for receiving event notifications. - * @param listener Object that implements {@link Listener} interface. + /** Registers a listener for receiving event notifications with are + * initially fired on this object. + * @param listener Object that implements {@link MDRChangeListener} interface. */ public void addListener(MDRChangeListener listener) { + addListener(listener, MDRChangeEvent.EVENTMASK_ALL); + } + + /** Registers a listener for receiving event notifications. + * @param listener Object that implements {@link MDRChangeListener} interface. + * @param mask bitmask to filter types of events the listener listens on + */ + public void addListener(MDRChangeListener listener, int mask) { initCheck(); - mdrStorage.getEventNotifier().REPOSITORY.addListener(listener, mdrStorage); + mdrStorage.getEventNotifier().REPOSITORY.addListener(listener, mask, mdrStorage); } - /** Removes listener from the list of objects registered for events notifications. - * @param listener Object that implements {@link Listener} interface. + /** Removes listener from the list of objects registered for event notifications. + * @param listener Object that implements {@link MDRChangeListener} interface. */ public void removeListener(MDRChangeListener listener) { initCheck(); mdrStorage.getEventNotifier().REPOSITORY.removeListener(listener, mdrStorage); } - + + /** Removes listener from the list of objects registered for event notifications. + * @param listener Object that implements {@link MDRChangeListener} interface. + * @param mask determines type of the events the listeners stops to listen on + */ + public void removeListener(MDRChangeListener listener, int mask) { + initCheck(); + mdrStorage.getEventNotifier().REPOSITORY.removeListener(listener, mask, mdrStorage); + } + /* -------------------------------------------------------------------- */ /* -- Implementation of org.netbeans.api.mdr.MDRepositry -------------- */ /* -------------------------------------------------------------------- */ @@ -163,12 +254,12 @@ initCheck(); mdrStorage.getRepositoryMutex().leave(rollback); } - + /** Instantiates the MOF model package. * * @param substName the name of the new model */ - public RefPackage createExtent(String substName) throws CreationFailedException { + public RefPackage createExtent(String substName) throws CreationFailedException { return createExtent(substName, null); } @@ -191,9 +282,9 @@ * package. * @param existingInstances */ - public RefPackage createExtent (String substName, RefObject metaPackage, RefPackage[] existingInstances) throws CreationFailedException { - return createExtent (substName, metaPackage, existingInstances, null); - } + public RefPackage createExtent(String substName, RefObject metaPackage, RefPackage[] existingInstances) throws CreationFailedException { + return createExtent(substName, metaPackage, existingInstances, null); + } /** Returns reference to an outermost package instance of a given name. * @param name name of package instance to be returned @@ -202,12 +293,12 @@ */ public RefPackage getExtent(String name) { StorablePackage pkg; - + initCheck(); - + try { beginTrans(false); - + try { // retrieve the package pkg = (StorablePackage) mdrStorage.getContextOutermostPackage(name); @@ -233,7 +324,7 @@ */ public String[] getExtentNames() { initCheck(); - + String result[] = new String[0]; try { beginTrans(false); @@ -246,7 +337,28 @@ endTrans(); } } - + + /** + * Returns the object with the given mofId. + */ + public RefBaseObject getByMofId(String mofId) { + initCheck(); + try { + beginTrans(false); + StorableBaseObject storable = mdrStorage.getObject(mofId); + if ( storable == null ) { + throw new NoSuchElementException("No object with MOF ID: " + mofId); + } else { + return BaseObjectHandler.getHandler(storable); + } + } catch (StorageException e) { + e.printStackTrace(); + throw new DebugException(); + } finally { + endTrans(); + } + } + /** * Called on repository exit. Should perform all needed finalization actions. */ @@ -261,16 +373,16 @@ } } } - + /* -------------------------------------------------------------------- */ /* -- Extending java.lang.Object -------------------------------------- */ - /* -------------------------------------------------------------------- */ + /* -------------------------------------------------------------------- */ public String toString() { StringBuffer sb = new StringBuffer("IDE MOF Repository"); return sb.toString(); } - + /* -------------------------------------------------------------------- */ /* -- Create an outermost package instance ---------------------------- */ /* -------------------------------------------------------------------- */ @@ -288,76 +400,63 @@ initCheck(); RefPackage result; - - if (substName.equals(BOOT_MOF) && mdrStorage.isBooting()) { - // instantiate BootMOF - // this piece of code does not need to be locked because it can be invoked - // only during booting and the booting process itself runs in a locked session - // [PENDING] probably this code should be removed from here and put - // directly into installFakeMof() - createBootMOF(); - result = getExtent(substName); - if (result == null) { - throw new CreationFailedException("Fatal error during bootstrapping."); + + boolean fail = true; + if (metaPackage == null) { + metaPackage = getMOFModelPackage(); + } + ExtentEvent event = new ExtentEvent( + this, + ExtentEvent.EVENT_EXTENT_CREATE, + substName, + metaPackage, + new ImmutableList(existingInstances) + ); + + try { + beginTrans(true); + mdrStorage.getEventNotifier().REPOSITORY.firePlannedChange(mdrStorage, event); + Map instancesToCluster = new HashMap(); + + // Traverse the metamodel containtment + classProxies = new HashMap(); + associationProxies = new HashMap(); + classProxiesMofIds = new HashMap(); + + if (existingInstances != null) { + for (int i = 0; i < existingInstances.length; i++) { + collectPackageInstances(existingInstances[i], instancesToCluster); + } } - } else { - boolean fail = true; - if (metaPackage == null) { - metaPackage = getMOFModelPackage(); - } - ExtentEvent event = new ExtentEvent( - this, - ExtentEvent.EVENT_EXTENT_CREATE, - substName, - metaPackage, - new ImmutableList(existingInstances) - ); - try { - beginTrans(true); - mdrStorage.getEventNotifier().REPOSITORY.firePlannedChange(mdrStorage, event); - Map instancesToCluster = new HashMap(); - - // Traverse the metamodel containtment - classProxies = new HashMap(); - associationProxies = new HashMap(); - classProxiesMofIds = new HashMap(); - - if (existingInstances != null) { - for (int i = 0; i < existingInstances.length; i++) { - collectPackageInstances(existingInstances[i], instancesToCluster); - } - } - try { - instantiatePackage(substName, null, (MofPackage) metaPackage, instancesToCluster, storageId, false); - } catch (RuntimeException e) { - e.printStackTrace(); - throw new CreationFailedException("Cannot instantiate package because of unexpected exception: " + e); - } - - classProxies = null; - associationProxies = null; - classProxiesMofIds = null; - - result = getExtent(substName); - if (result == null) { - throw new CreationFailedException("Cannot find created package."); - } - - fail = false; - } finally { - endTrans(fail); + instantiatePackage(substName, null, (MofPackage) metaPackage, instancesToCluster, storageId, false); + } catch (RuntimeException e) { + e.printStackTrace(); + throw new CreationFailedException("Cannot instantiate package because of unexpected exception: " + e); + } + + classProxies = null; + associationProxies = null; + classProxiesMofIds = null; + + result = getExtent(substName); + if (result == null) { + throw new CreationFailedException("Cannot find created package."); } + + fail = false; + } finally { + endTrans(fail); } - + return result; } - + /* -------------------------------------------------------------------- */ /* -- Storage partitions ---------------------------------------------- */ /* -------------------------------------------------------------------- */ - - /** + + /** * Mounts new partition into current repository, * The partition is created and initialized, if it does not exist. * @param String storageFactoryClass, name of storage factory class, which will create a new storage. @@ -365,48 +464,48 @@ * @return String id. * @exception MountFailedException thrown when mounting fails. */ - public String mountStorage (String storageFactoryClass, Map properties) throws MountFailedException { + public String mountStorage(String storageFactoryClass, Map properties) throws MountFailedException { boolean failed = true; try { - beginTrans (true); + beginTrans(true); // Firing of event is done inside a MdrStorage mountStorage method - String storageId = this.mdrStorage.mountStorage (storageFactoryClass, properties); + String storageId = this.mdrStorage.mountStorage(storageFactoryClass, properties); failed = false; return storageId; }catch (Exception e) { - throw new MountFailedException ("Partition mount failed.", e); + throw new MountFailedException("Partition mount failed.", e); } finally { - endTrans (failed); + endTrans(failed); } } - /** + /** * Umounts partition from current repository. - * Umounting partition can affect validity of association links + * Umounting partition can affect validity of association links * which cross partitions. Module developer is responsible for * either removing cross partition links or handling exceptions * caused by accessing these links. * @param String storageId, id of storage. */ - public void umountStorage (String storageId) { + public void umountStorage(String storageId) { boolean failed = true; try { - beginTrans (true); - Collection c = mdrStorage.getContexts (storageId); + beginTrans(true); + Collection c = mdrStorage.getContexts(storageId); for (Iterator it = c.iterator(); it.hasNext();) { String extentName = (String)it.next(); - RefPackage pkg = this.getExtent (extentName); - ExtentEvent event = new ExtentEvent (pkg, ExtentEvent.EVENT_EXTENT_DELETE, extentName, pkg.refMetaObject(), null); - this.mdrStorage.getEventNotifier().PACKAGE.firePlannedChange (pkg, event); + RefPackage pkg = this.getExtent(extentName); + ExtentEvent event = new ExtentEvent(pkg, ExtentEvent.EVENT_EXTENT_DELETE, extentName, pkg.refMetaObject(), null); + this.mdrStorage.getEventNotifier().PACKAGE.firePlannedChange(pkg, event); } - this.mdrStorage.umountStorage (storageId); + this.mdrStorage.umountStorage(storageId); failed = false; }catch (StorageException e) { - throw new DebugException ("Umounting failed: "+e.toString()); + throw new DebugException("Umounting failed: "+e.toString()); } finally { - endTrans (failed); + endTrans(failed); } } /* -------------------------------------------------------------------- */ @@ -419,7 +518,7 @@ public String getMOFInstanceName() { return PURE_MOF; } - + /* -------------------------------------------------------------------- */ /* -- Private helper methods ------------------------------------------ */ /* -------------------------------------------------------------------- */ @@ -429,7 +528,7 @@ private MofPackage getMOFModelPackage() { ModelPackage mofPackage = (ModelPackage) getExtent(getMOFInstanceName()); MofPackage result; - + for (Iterator it = mofPackage.getMofPackage().refAllOfClass().iterator(); it.hasNext();) { result = (MofPackage) it.next(); if (result.getName().equals("Model")) { @@ -440,7 +539,7 @@ return null; } - /** + /** * Initializes the repository, if not already initialized: creates and * initializes the {@link org.netbeans.mdr.storagemodel.MDRStorage}. If * necessary the repository is bootstrapped. @@ -448,7 +547,7 @@ private synchronized void initCheck() { if (mdrStorage == null) { String storageClass = (String) parameters.get(PARAM_STORAGE_CLASS); - + mdrStorage = new MdrStorage(this, storageClass, this.parameters); try { System.out.println("initializing..."); @@ -465,11 +564,11 @@ } } } - + /* -------------------------------------------------------------------- */ /* -- Helper methods for extent creation (private) -------------------- */ /* -------------------------------------------------------------------- */ - + /** * Helper method needed for the creation of a new outermost package instance. * Puts pkg and, recursively, all its nested packages @@ -480,9 +579,9 @@ * of their meta-objects as key * @exception CreationFailedException if two different packages with the * same keys are added to packages - * - */ - private void collectPackageInstances(RefPackage pkg, Map packages) throws CreationFailedException { + * + */ + private void collectPackageInstances(RefPackage pkg, Map packages) throws CreationFailedException { Object result = packages.put(pkg.refMetaObject().refMofId(), pkg); if (result != null && !result.equals(pkg)) { throw new CreationFailedException("The provided list of existing package instances contains duplicities."); @@ -492,7 +591,7 @@ collectPackageInstances(nested, packages); } } - + /** Instantiates given package, i.e. packageProxies, classProxies, * associationProxies. * @@ -500,18 +599,18 @@ * @param metaPackage outermost M2 package * @param clusteredInstances maps MOF IDs of M2 packages to M1 package instances * @param storageId ID of the storage partition - */ + */ private RefPackage instantiatePackage(String substName, StorablePackage immediatePackage, MofPackage metaPackage, Map clusteredInstances, String storageId, boolean clustered) { // Create package proxy StorablePackage newPackage = createPackageHandler(metaPackage, immediatePackage, substName, storageId, clustered); System.out.println("new package: " + newPackage.getMofId() + ", metapackage: " + metaPackage.refMofId()); - + Log.out.indent(); - + Set localAssocProxies = new HashSet(); Map localClassProxies = new HashMap(); instantiatePackageContent(metaPackage, newPackage, clusteredInstances, localClassProxies, localAssocProxies); - resolveSuperclasses(localClassProxies); + resolveSuperclasses(localClassProxies); // [PENDING] need to fix the mutex ordering and NPE and then uncomment this /* @@ -525,7 +624,7 @@ return (RefPackage) BaseObjectHandler.getHandler(newPackage); } - + /** * @param localClassProxies */ @@ -586,7 +685,7 @@ } sc.addSuperclass(current.getMofId()); current.addSubclass(sc.getMofId()); - } + } for (Iterator contents = cls.getContents().iterator(); contents.hasNext();) { me = (ModelElement) contents.next(); if (me instanceof Reference) { @@ -614,16 +713,16 @@ } if (indexTags.size() > 0) { try { - sc.buildAdditionalIndexes (indexTags, associationProxies); + sc.buildAdditionalIndexes(indexTags, associationProxies); } catch (StorageException e) { - throw new DebugException ("Storage exception: " + e); + throw new DebugException("Storage exception: " + e); } } */ } // for } - + /** * @param metaPackage * @param newPackage @@ -633,24 +732,24 @@ */ private void instantiatePackageContent(MofPackage metaPackage, StorablePackage newPackage, Map clusteredInstances, Map localClassProxies, Set localAssocProxies) { Iterator superTypes = metaPackage.allSupertypes().iterator(); - boolean thisTypeNotProcessed = true; + boolean thisTypeNotProcessed = true; while (thisTypeNotProcessed || superTypes.hasNext()) { Iterator it; if (thisTypeNotProcessed) { it = metaPackage.getContents().iterator(); thisTypeNotProcessed = false; - } else - it = ((MofPackage) superTypes.next ()).getContents().iterator(); - + } else + it = ((MofPackage) superTypes.next()).getContents().iterator(); + while (it.hasNext()) { Object o = it.next(); ModelElement element = (ModelElement) o; - + if (element instanceof javax.jmi.model.MofClass) { createClassProxyHandler((javax.jmi.model.MofClass) element, newPackage, localClassProxies); } else if (element instanceof javax.jmi.model.Association) { Association assoc = (Association) element; - + Collection content = assoc.getContents(); int i = 0; AssociationEnd ends[] = new AssociationEnd[2]; @@ -664,7 +763,7 @@ boolean orderA, orderB, uniqueA, uniqueB, aggrA, aggrB, indexedA, indexedB; int minA, maxA, minB, maxB; Class typeA, typeB; - + minA = ends[0].getMultiplicity().getLower(); maxA = ends[0].getMultiplicity().getUpper(); minB = ends[1].getMultiplicity().getLower(); @@ -680,36 +779,36 @@ orderB = (ends[1].getMultiplicity().isOrdered()); uniqueA = (ends[0].getMultiplicity().isUnique()); uniqueB = (ends[1].getMultiplicity().isUnique()); - + aggrA = ends[0].getAggregation().equals(AggregationKindEnum.COMPOSITE); aggrB = ends[1].getAggregation().equals(AggregationKindEnum.COMPOSITE); - indexedA = TagSupport.getTagValue ((StorableObject) ((BaseObjectHandler) ends[0])._getDelegate(), TAGID_INDEX) != null; - indexedB = TagSupport.getTagValue ((StorableObject) ((BaseObjectHandler) ends[1])._getDelegate(), TAGID_INDEX) != null; - if (TagProvider.getTagValue (ends[0].getType (), TRANSIENT_TAG_ID, "").equals (TAG_VALUE_TRUE) - || TagProvider.getTagValue (ends[1].getType (), TRANSIENT_TAG_ID, "").equals (TAG_VALUE_TRUE)) { - createTransientAssociationHandler((javax.jmi.model.Association) element, newPackage, ends[0].getName(), ends[0].refMofId(), ends[1].getName(), ends[1].refMofId(), typeA, typeB, minA, maxA, minB, maxB, orderA, orderB, uniqueA, uniqueB, aggrA, aggrB, localAssocProxies); + indexedA = TagSupport.getTagValue((StorableObject) ((BaseObjectHandler) ends[0])._getDelegate(), TAGID_INDEX) != null; + indexedB = TagSupport.getTagValue((StorableObject) ((BaseObjectHandler) ends[1])._getDelegate(), TAGID_INDEX) != null; + if (TagProvider.getTagValue(ends[0].getType(), TRANSIENT_TAG_ID, "").equals(TAG_VALUE_TRUE) + || TagProvider.getTagValue(ends[1].getType(), TRANSIENT_TAG_ID, "").equals(TAG_VALUE_TRUE)) { + createTransientAssociationHandler((javax.jmi.model.Association) element, newPackage, ends[0].getName(), ends[0].refMofId(), ends[1].getName(), ends[1].refMofId(), typeA, typeB, minA, maxA, minB, maxB, orderA, orderB, uniqueA, uniqueB, aggrA, aggrB, localAssocProxies); } else { createAssociationHandler((javax.jmi.model.Association) element, newPackage, ends[0].getName(), ends[0].refMofId(), ends[1].getName(), ends[1].refMofId(), typeA, typeB, minA, maxA, minB, maxB, orderA, orderB, uniqueA, uniqueB, aggrA, aggrB, indexedA, indexedB, localAssocProxies); } } else if (element instanceof MofPackage) { - // System.out.println("found inner package"); - // System.out.println("creating: META: " + element.refMofId() + ", IMMEDIATE: " + newPackage.refMofId() + ", CONTEXT: " + context); - String storageId = MdrStorage.getStorageIdFromMofId (newPackage.getMofId()); + // System.out.println("found inner package"); + // System.out.println("creating: META: " + element.refMofId() + ", IMMEDIATE: " + newPackage.refMofId() + ", CONTEXT: " + context); + String storageId = MdrStorage.getStorageIdFromMofId(newPackage.getMofId()); StorablePackage pkg = createPackageHandler((MofPackage) element, newPackage, null, storageId, false); instantiatePackageContent((MofPackage) element, pkg, clusteredInstances, localClassProxies, localAssocProxies); } else if (element instanceof Import) { Import imp = (Import) element; - + if (imp.isClustered()) { ModelElement metaElement = imp.getImportedNamespace(); if (metaElement instanceof MofPackage) { MofPackage metaPkg = (MofPackage) metaElement; RefPackage pkg = (RefPackage) clusteredInstances.get(metaPkg.refMofId()); if (pkg == null) { - String storageId = MdrStorage.getStorageIdFromMofId (newPackage.getMofId()); + String storageId = MdrStorage.getStorageIdFromMofId(newPackage.getMofId()); pkg = instantiatePackage(null, newPackage, metaPkg, clusteredInstances, storageId, true); clusteredInstances.put(metaPkg.refMofId(), pkg); } else { @@ -750,14 +849,14 @@ // this package was already collected return; } - classProxies.put((MofClass) cls.refMetaObject(), ((BaseObjectHandler) cls)._getDelegate()); + classProxies.put((MofClass) cls.refMetaObject(), ((BaseObjectHandler) cls)._getDelegate()); } for (Iterator it = pkg.refAllPackages().iterator(); it.hasNext();) { collectAllProxies((RefPackage) it.next()); } } - + /* -------------------------------------------------------------------- */ /* -- Helper methods for handler creation (private) ------------------- */ /* -------------------------------------------------------------------- */ @@ -778,7 +877,7 @@ ModelElement me; List members = new ArrayList(); List memberTypes = new ArrayList(); - + for (Iterator it2 = ((StructureType) element).getContents().iterator(); it2.hasNext();) { me = (ModelElement) it2.next(); if (me instanceof StructureField) { @@ -795,7 +894,7 @@ datatypes.put(element.getName(), new DatatypeDescriptor(mdrStorage, element.getQualifiedName(), members, memberTypes, ifcName, storageId)); } } - + StorablePackage result = null; if (storageId != null) { result = new StorablePackage(mdrStorage, immediatePackage == null ? null : immediatePackage.getMofId(), metaObject.refMofId(), context, datatypes, storageId); @@ -806,13 +905,13 @@ if (immediatePackage != null && !clustered) { immediatePackage.addPackage(metaObject.getName(), result.getMofId()); } - + return result; } catch ( StorageException e ) { throw new DebugException("Storage exception: " + e.getMessage()); } } - + /** Creates handler for Class Proxy */ private StorableClass createClassProxyHandler(javax.jmi.model.MofClass metaObject, StorablePackage immediatePackage, Map localClassProxies) { ModelElement element; @@ -854,12 +953,12 @@ if (element instanceof EnumerationType) { List members = new ArrayList(((EnumerationType) element).getLabels()); String ifcName = TagSupport.getTypeFullName((StorableObject) ((BaseObjectHandler) element)._getDelegate()); - datatypes.put(element.getName(), new DatatypeDescriptor(mdrStorage, members, ifcName, MdrStorage.getStorageIdFromMofId (immediatePackage.getMofId()))); + datatypes.put(element.getName(), new DatatypeDescriptor(mdrStorage, members, ifcName, MdrStorage.getStorageIdFromMofId(immediatePackage.getMofId()))); } else if (element instanceof StructureType) { ModelElement me; List members = new ArrayList(); List memberTypes = new ArrayList(); - + for (Iterator it2 = ((StructureType) element).getContents().iterator(); it2.hasNext();) { me = (ModelElement) it2.next(); if (me instanceof StructureField) { @@ -873,7 +972,7 @@ } } String ifcName = TagSupport.getTypeFullName((StorableObject) ((BaseObjectHandler) element)._getDelegate()); - datatypes.put(element.getName(), new DatatypeDescriptor(mdrStorage, element.getQualifiedName(), members, memberTypes, ifcName, MdrStorage.getStorageIdFromMofId (immediatePackage.getMofId()))); + datatypes.put(element.getName(), new DatatypeDescriptor(mdrStorage, element.getQualifiedName(), members, memberTypes, ifcName, MdrStorage.getStorageIdFromMofId(immediatePackage.getMofId()))); } isDerived = false; isInterceptable = false; @@ -888,60 +987,60 @@ } } - String tagValue = TagProvider.getTagValue (metaObject, TRANSIENT_TAG_ID, ""); - if (tagValue.equals (TAG_VALUE_TRUE)) { - storable = new TransientStorableClass(mdrStorage, immediatePackage.getMofId(), - metaObject.refMofId(), attrDescs, clAttrDescs, datatypes, classDerived, - instanceDerived, metaObject.isSingleton(), metaObject.isAbstract()); + String tagValue = TagProvider.getTagValue(metaObject, TRANSIENT_TAG_ID, ""); + if (tagValue.equals(TAG_VALUE_TRUE)) { + storable = new TransientStorableClass(mdrStorage, immediatePackage.getMofId(), + metaObject.refMofId(), attrDescs, clAttrDescs, datatypes, classDerived, + instanceDerived, metaObject.isSingleton(), metaObject.isAbstract()); } else { - storable = new StorableClass(mdrStorage, immediatePackage.getMofId(), - metaObject.refMofId(), attrDescs, clAttrDescs, datatypes, classDerived, - instanceDerived, metaObject.isSingleton(), metaObject.isAbstract()); + storable = new StorableClass(mdrStorage, immediatePackage.getMofId(), + metaObject.refMofId(), attrDescs, clAttrDescs, datatypes, classDerived, + instanceDerived, metaObject.isSingleton(), metaObject.isAbstract()); } - + immediatePackage.addClass(metaObject.getName(), storable.getMofId()); classProxies.put(metaObject, storable); classProxiesMofIds.put(metaObject.refMofId(), storable.getMofId()); localClassProxies.put(metaObject, storable); return storable; } catch ( StorageException e ) { - e.printStackTrace (); + e.printStackTrace(); throw new DebugException("Storage exception: " + e.getMessage()); } } - + /** Creates handler for Association */ private StorableAssociation createAssociationHandler( - javax.jmi.model.Association metaObject, - StorablePackage immediatePackage, - String assocationEnd1, String assocEnd1MofId, - String assocationEnd2, String assocEnd2MofId, - Class type1, Class type2, - int min1, int max1, - int min2, int max2, - boolean isOrdered1, - boolean isOrdered2, - boolean isUnique1, - boolean isUnique2, - boolean isAggr1, - boolean isAggr2, - boolean isIndexed1, - boolean isIndexed2, - Set localAssocProxies) { + javax.jmi.model.Association metaObject, + StorablePackage immediatePackage, + String assocationEnd1, String assocEnd1MofId, + String assocationEnd2, String assocEnd2MofId, + Class type1, Class type2, + int min1, int max1, + int min2, int max2, + boolean isOrdered1, + boolean isOrdered2, + boolean isUnique1, + boolean isUnique2, + boolean isAggr1, + boolean isAggr2, + boolean isIndexed1, + boolean isIndexed2, + Set localAssocProxies) { try { StorableAssociation result = new StorableAssociation( - mdrStorage, - immediatePackage.getMofId(), - metaObject.refMofId(), - assocationEnd1, assocEnd1MofId, assocationEnd2, assocEnd2MofId, - type1, type2, - min1, max1, min2, max2, - isOrdered1, isOrdered2, - isUnique1, isUnique2, - isAggr1, isAggr2, - isIndexed1, isIndexed2); + mdrStorage, + immediatePackage.getMofId(), + metaObject.refMofId(), + assocationEnd1, assocEnd1MofId, assocationEnd2, assocEnd2MofId, + type1, type2, + min1, max1, min2, max2, + isOrdered1, isOrdered2, + isUnique1, isUnique2, + isAggr1, isAggr2, + isIndexed1, isIndexed2); immediatePackage.addAssociation(metaObject.getName(), result.getMofId()); associationProxies.put(metaObject.refMofId(), result.getMofId()); localAssocProxies.add(result.getMofId()); @@ -952,32 +1051,32 @@ } private StorableAssociation createTransientAssociationHandler( - javax.jmi.model.Association metaObject, - StorablePackage immediatePackage, - String assocationEnd1, String assocEnd1MofId, - String assocationEnd2, String assocEnd2MofId, - Class type1, Class type2, - int min1, int max1, - int min2, int max2, - boolean isOrdered1, - boolean isOrdered2, - boolean isUnique1, - boolean isUnique2, - boolean isAggr1, - boolean isAggr2, - Set localAssocProxies) { + javax.jmi.model.Association metaObject, + StorablePackage immediatePackage, + String assocationEnd1, String assocEnd1MofId, + String assocationEnd2, String assocEnd2MofId, + Class type1, Class type2, + int min1, int max1, + int min2, int max2, + boolean isOrdered1, + boolean isOrdered2, + boolean isUnique1, + boolean isUnique2, + boolean isAggr1, + boolean isAggr2, + Set localAssocProxies) { try { StorableAssociation result = new TransientStorableAssociation( - mdrStorage, - immediatePackage.getMofId(), - metaObject.refMofId(), - assocationEnd1, assocEnd1MofId, assocationEnd2, assocEnd2MofId, - type1, type2, - min1, max1, min2, max2, - isOrdered1, isOrdered2, - isUnique1, isUnique2, - isAggr1, isAggr2); + mdrStorage, + immediatePackage.getMofId(), + metaObject.refMofId(), + assocationEnd1, assocEnd1MofId, assocationEnd2, assocEnd2MofId, + type1, type2, + min1, max1, min2, max2, + isOrdered1, isOrdered2, + isUnique1, isUnique2, + isAggr1, isAggr2); immediatePackage.addAssociation(metaObject.getName(), result.getMofId()); associationProxies.put(metaObject.refMofId(), result.getMofId()); localAssocProxies.add(result.getMofId()); @@ -990,7 +1089,7 @@ /* -------------------------------------------------------------------- */ /* -- Methods for bootstrapping (private) ----------------------------- */ /* -------------------------------------------------------------------- */ - + /** * Main bootstrapping method. */ @@ -1002,7 +1101,7 @@ try { beginTrans(true); installFakeMof(); - installPureMof(); + installPureMof(); fail = false; } catch (Throwable e) { e.printStackTrace(); @@ -1011,27 +1110,25 @@ endTrans(fail); } Log.out.unindent(); - } - + } + /** Installs the fake MOF - */ + */ private void installFakeMof() { Log.out.println("Creating boot MOF metamodel ..."); - - try { - RefPackage p = createExtent(BOOT_MOF, null, null); - } catch (CreationFailedException e) { - e.printStackTrace(); - throw new DebugException("Cannot create instance of BOOT_MOF: " + e.getMessage()); + + createBootMOF(); + if (getExtent(BOOT_MOF) == null) { + throw new DebugException("Cannot create instance of BOOT_MOF: Fatal error during bootstrapping."); } } - + /** Programatically installs the pure MOF model. */ private void installPureMof() { Log.out.println("Installing pure MOF Metamodel ... "); Log.out.indent(); - + try { Log.out.println("Parsing MOF model to DOM represtentation ...."); ModelPackage modelPackage = (ModelPackage) createExtent(PURE_MOF, getBMModelPackage()); @@ -1045,7 +1142,7 @@ Log.out.unindent(); } } - + /** * Returns the MOF Model package as a model element of the * bootstrapping MOF model. Needed only during bootstrapping. @@ -1063,9 +1160,9 @@ } return null; } - + /** Reads the XMI description of the mof directly into reporitory - */ + */ private void createBootMOF() { try { BootReader br = new BootReader(mdrStorage, BOOTMOF_XML_URL); Index: src/org/netbeans/mdr/handlers/AssociationHandler.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/mdr/handlers/AssociationHandler.java,v retrieving revision 1.1.1.2 retrieving revision 1.4 diff -u -r1.1.1.2 -r1.4 --- src/org/netbeans/mdr/handlers/AssociationHandler.java 18 Jul 2002 08:37:25 -0000 1.1.1.2 +++ src/org/netbeans/mdr/handlers/AssociationHandler.java 18 Jul 2002 11:08:50 -0000 1.4 @@ -302,20 +302,45 @@ /* public void replace(RefObject oldEnd1, RefObject oldEnd2, RefObject newEnd1, RefObject newEnd2) { } + + /* -------------------------------------------------------------------- */ + /* -- Implementation of org.netbeans.api.mdr.events.MDRChangeSource --- */ + /* -------------------------------------------------------------------- */ + + /** Registers a listener for receiving event notifications with are + * initially fired on this object. + * @param listener Object that implements {@link MDRChangeListener} interface. */ + public void addListener(MDRChangeListener listener) { + addListener(listener, MDRChangeEvent.EVENTMASK_ALL); + } + /** Registers a listener for receiving event notifications. - * @param listener Object that implements {@link Listener} interface. + * @param listener Object that implements {@link MDRChangeListener} interface. + * @param mask bitmask to filter types of events the listener listens on */ - public void addListener(MDRChangeListener listener) { - _getMdrStorage().getEventNotifier().ASSOCIATION.addListener(listener, this); + public void addListener(MDRChangeListener listener, int mask) { + _getMdrStorage().getEventNotifier().ASSOCIATION.addListener(listener, mask, this); } - /** Removes listener from the list of objects registered for events notifications. - * @param listener Object that implements {@link Listener} interface. + /** Removes listener from the list of objects registered for event notifications. + * @param listener Object that implements {@link MDRChangeListener} interface. */ public void removeListener(MDRChangeListener listener) { _getMdrStorage().getEventNotifier().ASSOCIATION.removeListener(listener, this); } + + /** Removes listener from the list of objects registered for event notifications. + * @param listener Object that implements {@link MDRChangeListener} interface. + * @param mask determines type of the events the listeners stops to listen on + */ + public void removeListener(MDRChangeListener listener, int mask) { + _getMdrStorage().getEventNotifier().ASSOCIATION.removeListener(listener, mask, this); + } + + /* --------------------------------------------------------------------- */ + /* -- -- */ + /* --------------------------------------------------------------------- */ static void _removeExternalLink(AssociationHandler associationHandler, RefObject thisEnd, RefObject otherEnd) { if (MdrStorage.isTransientMofId (thisEnd.refMofId ()) || MdrStorage.isTransientMofId (otherEnd.refMofId ())) Index: src/org/netbeans/mdr/handlers/BaseObjectHandler.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/mdr/handlers/BaseObjectHandler.java,v retrieving revision 1.1.1.1 retrieving revision 1.3 diff -u -r1.1.1.1 -r1.3 --- src/org/netbeans/mdr/handlers/BaseObjectHandler.java 2 Jul 2002 07:35:26 -0000 1.1.1.1 +++ src/org/netbeans/mdr/handlers/BaseObjectHandler.java 4 Jul 2002 12:49:40 -0000 1.3 @@ -34,57 +34,77 @@ * @version */ public abstract class BaseObjectHandler extends ImplClass implements MDRObject/*, OclAny*/ { + + /* --------------------------------------------------------------------- */ + /* -- Static attributes ------------------------------------------------ */ + /* --------------------------------------------------------------------- */ + + /** + * Maps storage objects (instances of {@link StorableBaseObject}) to + * JMI compliant handler objects (instances of {@link RefBaseObject}). + */ private static final Map facilityCache = new FacilityCache(); + + /** + * Maps mof ids of meta-objects to the appropriate JMI interfaces (String => Class). + */ private static final Hashtable classCache = new Hashtable(); private static MDRClassLoader defaultLoader = null; private static ClassLoaderProvider provider = null; - - /** The object in strorage to delegate to - */ -// private final StorableBaseObject storableDelegate; - private final String mofId; - private final MdrStorage mdrStorage; - private StorableBaseObject storable; - protected final void _lock() { - _lock(true); - } + /* --------------------------------------------------------------------- */ + /* -- Static setters/getters ------------------------------------------- */ + /* --------------------------------------------------------------------- */ - protected final void _lock(boolean write) { - mdrStorage.getRepositoryMutex().enter(write); + public static synchronized void setClassLoaderProvider(ClassLoaderProvider provider) { + BaseObjectHandler.provider = provider; } - protected final void _unlock() { - mdrStorage.getRepositoryMutex().leave(); - } - - protected final void _unlock(boolean fail) { - mdrStorage.getRepositoryMutex().leave(fail); + public static synchronized MDRClassLoader getDefaultClassLoader() { + if (defaultLoader == null) { + defaultLoader = new MDRClassLoader(provider); + } +// System.out.println(defaultLoader.toString() + " : " + defaultLoader.getClass().getName()); + return defaultLoader; } - public final MDRepository repository() { - return mdrStorage.getRepository(); - } - + /* --------------------------------------------------------------------- */ + /* -- Static helper methods (private) ---------------------------------- */ + /* --------------------------------------------------------------------- */ + + /** + * Returns the handler class for JMI interface ifc and storage object s. + * + * @param loader the class loader for the definition of new classes + * @param ifc JMI interface to be implemented by the class + * @param s storage object to be wrapped by an instances of the class + * @return class implementing ifc + */ private static Class getHandlerClass(MDRClassLoader loader, Class ifc, StorableBaseObject s) throws IllegalArgumentException { + /* check if the loader may load the interface */ check(loader, ifc); + /* try to load from cache */ Map cache = getLoaderCache(loader); String className = getName(ifc); Class result = getFromCache(cache, ifc, className); if (result == null) { try { + /* generate and define handler class */ byte[] handlerClassFile = HandlerGenerator.generateHandler(className, ifc, s); -/* - try { - java.io.FileOutputStream file = new java.io.FileOutputStream("e:/classes/" + className.substring(className.lastIndexOf('.') + 1) + ".class"); - file.write(handlerClassFile); - file.close(); - } catch (Exception e) { - e.printStackTrace(); - } -*/ + + /* [XXX] Allow the use of a system property org.netbeans.mdr.byteCodeDir, write class + * files to that directory, if the system property is set. + */ +// try { +// java.io.FileOutputStream file = new java.io.FileOutputStream("e:/classes/" + className.substring(className.lastIndexOf('.') + 1) + ".class"); +// file.write(handlerClassFile); +// file.close(); +// } catch (Exception e) { +// e.printStackTrace(); +// } + result = loader.defineClass(className, handlerClassFile); } finally { releaseCache(cache, result, className); @@ -94,11 +114,18 @@ return result; } + /** + * Returns the JMI interface to be implemented by the handler of s. + * + * @param s a storage object + * @return the JMI interface for s + */ private static Class resolveClass(StorableBaseObject s) { try { StorableObject metaObject = s.getMetaObject(); String suffix; + /* cache lookup */ if (s instanceof StorableObject || s instanceof StorableAssociation) { suffix = ""; } else if (s instanceof StorablePackage) { @@ -112,6 +139,7 @@ String key = metaObject.getMofId() + ":" + suffix; Class result = (Class) classCache.get(key); + /* interface resolution */ if (result == null) { try { String metaName = TagSupport.getTypeFullName(metaObject); @@ -128,12 +156,26 @@ throw new DebugException(); } } - + + /* --------------------------------------------------------------------- */ + /* -- Static methods (public) ------------------------------------------ */ + /* --------------------------------------------------------------------- */ + + /** + * Frees the caches of JMI compliant handler objects (for storage objects) + * and of JMI implementation classes (for meta-objects). + */ public static void _freeCache() { facilityCache.clear(); classCache.clear(); } + /** + * Returns JMI compliant handler object for s. + * + * @param s the storage object to be wrapped or null + * @return handler implementing JMI interface or null + */ public static RefBaseObject getHandler(StorableBaseObject s) throws IllegalArgumentException { if (s == null) { return null; @@ -151,11 +193,30 @@ return getHandler(s, ifc); } + /** + * Returns JMI compliant handler object for s. + * + * @param s the storage object to be wrapped or null + * @param ifc the JMI interface to be implemented by the handler + * @return handler implementing JMI interface or null + */ public static RefBaseObject getHandler(StorableBaseObject s, Class ifc) throws IllegalArgumentException { if (s == null) { return null; } + + /* [XXX] For performance reasons the following piece of code should + * be enabled, when it is expected that cache lookup succeeds quite + * often. hkrug@rationalizer.com */ +// Object oldRecord; +// synchronized (facilityCache) { +// oldRecord = facilityCache.get(s.getMofId()); +// } +// if ( oldRecord != null ) { +// return oldRecord; +// } + /* load the handler class */ MDRClassLoader loader = getDefaultClassLoader(); Class cl = getHandlerClass(loader, ifc, s); @@ -170,6 +231,7 @@ else if (cls.equals (TransientStorableAssociation.class)) { cls = StorableAssociation.class; } + /* create handler object, if necessary */ Constructor cons = cl.getConstructor(new Class[] {cls}); synchronized (facilityCache) { @@ -196,18 +258,14 @@ } } - public static synchronized void setClassLoaderProvider(ClassLoaderProvider provider) { - BaseObjectHandler.provider = provider; - } - - public static synchronized MDRClassLoader getDefaultClassLoader() { - if (defaultLoader == null) { - defaultLoader = new MDRClassLoader(provider); - } -// System.out.println(defaultLoader.toString() + " : " + defaultLoader.getClass().getName()); - return defaultLoader; - } - + /** + * Returns interface ifcName. The interface is not generated on the + * fly, but must be available for loading by the default class-loader + * (see {@link #getDefaultClassLoader()}). + * + * @param ifcName name of the interface to be loaded + * @return the interface named ifcName + */ public static Class resolveInterface(String ifcName) throws ClassNotFoundException { try { return Class.forName(ifcName, true, getDefaultClassLoader()); @@ -222,6 +280,12 @@ } } + /** + * Loads the class implName from the default class loader. + * + * @param implName class name + * @return the class + */ public static Class resolveImplementation(String implName) throws ClassNotFoundException { try { return Class.forName(implName, true, getDefaultClassLoader()); @@ -238,6 +302,21 @@ throw e; } } + + /* --------------------------------------------------------------------- */ + /* -- Private attributes ----------------------------------------------- */ + /* --------------------------------------------------------------------- */ + +// /** The object in strorage to delegate to +// */ +// private final StorableBaseObject storableDelegate; + private final String mofId; + private final MdrStorage mdrStorage; + private StorableBaseObject storable; + + /* --------------------------------------------------------------------- */ + /* -- Constructor(s) --------------------------------------------------- */ + /* --------------------------------------------------------------------- */ /** Creates new RefBaseObjectHandler */ protected BaseObjectHandler(StorableBaseObject storable) { @@ -255,37 +334,38 @@ this.storable = null; } } - - public final StorableBaseObject _getDelegate() { -/* - StorableBaseObject storable = (StorableBaseObject) storableDelegate.get(); - if (storable == null) { - try { - storable = mdrStorage.getObject(mofId); - storableDelegate = new SoftReference(storable); - } catch (StorageException e) { - throw new DebugException("Storage exception: " + e); - } - } - */ - try { - if (this.storable != null) - return this.storable; - else - return mdrStorage.getObject(mofId); - } catch (StorageBadRequestException e) { - throw new InvalidObjectException(null, "Object with MOFID " + mofId + " no longer exists."); - } catch (StorageException e) { - throw new DebugException(e.toString()); - } - //return storableDelegate; + + /* --------------------------------------------------------------------- */ + /* -- Transaction related methods -------------------------------------- */ + /* --------------------------------------------------------------------- */ + + protected final void _lock() { + _lock(true); } - protected final MdrStorage _getMdrStorage() { - return mdrStorage; + protected final void _lock(boolean write) { + mdrStorage.getRepositoryMutex().enter(write); + } + + protected final void _unlock() { + mdrStorage.getRepositoryMutex().leave(); } - // Overriding the java.lang.object methods ----------------------------------- + protected final void _unlock(boolean fail) { + mdrStorage.getRepositoryMutex().leave(fail); + } + + /* --------------------------------------------------------------------- */ + /* -- Implements org.netbeans.api.mdr.MDRObject ------------------------ */ + /* --------------------------------------------------------------------- */ + + public final MDRepository repository() { + return mdrStorage.getRepository(); + } + + /* --------------------------------------------------------------------- */ + /* -- Extends java.lang.Object ----------------------------------------- */ + /* --------------------------------------------------------------------- */ public final boolean equals(Object obj) { if (obj instanceof BaseObjectHandler) { @@ -316,8 +396,10 @@ public final int hashCode() { return refMofId().hashCode(); } - - // Implementation of the RefBaseObject --------------------------------------- + + /* --------------------------------------------------------------------- */ + /* -- Implements javax.jmi.reflect.RefBaseObject ----------------------- */ + /* --------------------------------------------------------------------- */ public final RefObject refMetaObject() { try { @@ -360,10 +442,49 @@ else return _verify(new ArrayList()); } + /* --------------------------------------------------------------------- */ + /* -- --------------------------------------------------- */ + /* --------------------------------------------------------------------- */ + + public final StorableBaseObject _getDelegate() { +/* + StorableBaseObject storable = (StorableBaseObject) storableDelegate.get(); + if (storable == null) { + try { + storable = mdrStorage.getObject(mofId); + storableDelegate = new SoftReference(storable); + } catch (StorageException e) { + throw new DebugException("Storage exception: " + e); + } + } + */ + try { + if (this.storable != null) + return this.storable; + else + return mdrStorage.getObject(mofId); + } catch (StorageBadRequestException e) { + throw new InvalidObjectException(null, "Object with MOFID " + mofId + " no longer exists."); + } catch (StorageException e) { + throw new DebugException(e.toString()); + } + //return storableDelegate; + } + + protected final MdrStorage _getMdrStorage() { + return mdrStorage; + } + + /* --------------------------------------------------------------------- */ + /* -- Methods to be overridden by sub-classes -------------------------- */ + /* --------------------------------------------------------------------- */ + protected abstract Collection _recursiveVerify(Collection violations, Set visited); protected abstract Collection _verify(Collection violations); - // private classes --------------------------------------------- + /* --------------------------------------------------------------------- */ + /* -- FacilityCache (static inner class) ------------------------------- */ + /* --------------------------------------------------------------------- */ /** Weak cache for created Handlers */ Index: src/org/netbeans/mdr/handlers/ClassProxyHandler.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/mdr/handlers/ClassProxyHandler.java,v retrieving revision 1.1.1.2 retrieving revision 1.4 diff -u -r1.1.1.2 -r1.4 --- src/org/netbeans/mdr/handlers/ClassProxyHandler.java 18 Jul 2002 08:37:25 -0000 1.1.1.2 +++ src/org/netbeans/mdr/handlers/ClassProxyHandler.java 18 Jul 2002 11:08:50 -0000 1.4 @@ -259,19 +259,37 @@ /* -- Implementation of org.netbeans.api.mdr.events.MDRChangeSource --- */ /* -------------------------------------------------------------------- */ - /** Registers a listener for receiving event notifications. - * @param listener Object that implements {@link Listener} interface. + /** Registers a listener for receiving event notifications with are + * initially fired on this object. + * @param listener Object that implements {@link MDRChangeListener} interface. */ public void addListener(MDRChangeListener listener) { - _getMdrStorage().getEventNotifier().CLASS.addListener(listener, this); + addListener(listener, MDRChangeEvent.EVENTMASK_ALL); + } + + /** Registers a listener for receiving event notifications. + * @param listener Object that implements {@link MDRChangeListener} interface. + * @param mask bitmask to filter types of events the listener listens on + */ + public void addListener(MDRChangeListener listener, int mask) { + _getMdrStorage().getEventNotifier().CLASS.addListener(listener, mask, this); } - /** Removes listener from the list of objects registered for events notifications. - * @param listener Object that implements {@link Listener} interface. + /** Removes listener from the list of objects registered for event notifications. + * @param listener Object that implements {@link MDRChangeListener} interface. */ public void removeListener(MDRChangeListener listener) { _getMdrStorage().getEventNotifier().CLASS.removeListener(listener, this); } + + /** Removes listener from the list of objects registered for event notifications. + * @param listener Object that implements {@link MDRChangeListener} interface. + * @param mask determines type of the events the listeners stops to listen on + */ + public void removeListener(MDRChangeListener listener, int mask) { + _getMdrStorage().getEventNotifier().CLASS.removeListener(listener, mask, this); + } + /* -------------------------------------------------------------------- */ /* -- ClassProxyHandler.CreateInstanceEvent (inner class) ------------- */ /* -------------------------------------------------------------------- */ Index: src/org/netbeans/mdr/handlers/FeaturedHandler.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/mdr/handlers/FeaturedHandler.java,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- src/org/netbeans/mdr/handlers/FeaturedHandler.java 2 Jul 2002 07:35:27 -0000 1.1.1.1 +++ src/org/netbeans/mdr/handlers/FeaturedHandler.java 4 Jul 2002 12:50:07 -0000 1.2 @@ -88,7 +88,7 @@ } - // Methods to refine for classes with the intercaptable tag set -------------- + // Methods to refine for classes with the interceptable tag set -------------- protected void _interceptPreSet(String featureName, Object newValue) { } Index: src/org/netbeans/mdr/handlers/InstanceHandler.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/mdr/handlers/InstanceHandler.java,v retrieving revision 1.1.1.2 retrieving revision 1.4 diff -u -r1.1.1.2 -r1.4 --- src/org/netbeans/mdr/handlers/InstanceHandler.java 18 Jul 2002 08:37:25 -0000 1.1.1.2 +++ src/org/netbeans/mdr/handlers/InstanceHandler.java 18 Jul 2002 11:08:50 -0000 1.4 @@ -391,18 +391,35 @@ /* -- Implementation of org.netbeans.api.mdr.events.MDRChangeSource --- */ /* -------------------------------------------------------------------- */ - /** Registers a listener for receiving event notifications. - * @param listener Object that implements {@link Listener} interface. + /** Registers a listener for receiving event notifications with are + * initially fired on this object. + * @param listener Object that implements {@link MDRChangeListener} interface. */ public void addListener(MDRChangeListener listener) { - _getMdrStorage().getEventNotifier().INSTANCE.addListener(listener, this); + addListener(listener, MDRChangeEvent.EVENTMASK_ALL); + } + + /** Registers a listener for receiving event notifications. + * @param listener Object that implements {@link MDRChangeListener} interface. + * @param mask bitmask to filter types of events the listener listens on + */ + public void addListener(MDRChangeListener listener, int mask) { + _getMdrStorage().getEventNotifier().INSTANCE.addListener(listener, mask, this); } - /** Removes listener from the list of objects registered for events notifications. - * @param listener Object that implements {@link Listener} interface. + /** Removes listener from the list of objects registered for event notifications. + * @param listener Object that implements {@link MDRChangeListener} interface. */ public void removeListener(MDRChangeListener listener) { _getMdrStorage().getEventNotifier().INSTANCE.removeListener(listener, this); + } + + /** Removes listener from the list of objects registered for event notifications. + * @param listener Object that implements {@link MDRChangeListener} interface. + * @param mask determines type of the events the listeners stops to listen on + */ + public void removeListener(MDRChangeListener listener, int mask) { + _getMdrStorage().getEventNotifier().INSTANCE.removeListener(listener, mask, this); } /* ---------------------------------------------------------------- */ Index: src/org/netbeans/mdr/handlers/PackageProxyHandler.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/mdr/handlers/PackageProxyHandler.java,v retrieving revision 1.1.1.2 retrieving revision 1.4 diff -u -r1.1.1.2 -r1.4 --- src/org/netbeans/mdr/handlers/PackageProxyHandler.java 18 Jul 2002 08:37:25 -0000 1.1.1.2 +++ src/org/netbeans/mdr/handlers/PackageProxyHandler.java 18 Jul 2002 11:08:50 -0000 1.4 @@ -387,19 +387,36 @@ /* -------------------------------------------------------------------- */ /* -- Implementation of org.netbeans.api.mdr.events.MDRChangeSource --- */ /* -------------------------------------------------------------------- */ - - /** Registers a listener for receiving event notifications. - * @param listener Object that implements {@link Listener} interface. + + /** Registers a listener for receiving event notifications with are + * initially fired on this object. + * @param listener Object that implements {@link MDRChangeListener} interface. */ public void addListener(MDRChangeListener listener) { - _getMdrStorage().getEventNotifier().PACKAGE.addListener(listener, this); + addListener(listener, MDRChangeEvent.EVENTMASK_ALL); } - /** Removes listener from the list of objects registered for events notifications. - * @param listener Object that implements {@link Listener} interface. + /** Registers a listener for receiving event notifications. + * @param listener Object that implements {@link MDRChangeListener} interface. + * @param mask bitmask to filter types of events the listener listens on + */ + public void addListener(MDRChangeListener listener, int mask) { + _getMdrStorage().getEventNotifier().PACKAGE.addListener(listener, mask, this); + } + + /** Removes listener from the list of objects registered for event notifications. + * @param listener Object that implements {@link MDRChangeListener} interface. */ public void removeListener(MDRChangeListener listener) { _getMdrStorage().getEventNotifier().PACKAGE.removeListener(listener, this); + } + + /** Removes listener from the list of objects registered for event notifications. + * @param listener Object that implements {@link MDRChangeListener} interface. + * @param mask determines type of the events the listeners stops to listen on + */ + public void removeListener(MDRChangeListener listener, int mask) { + _getMdrStorage().getEventNotifier().PACKAGE.removeListener(listener, mask, this); } /* ---------------------------------------------------------------- */ Index: src/org/netbeans/mdr/handlers/StructGenerator.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/mdr/handlers/StructGenerator.java,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- src/org/netbeans/mdr/handlers/StructGenerator.java 2 Jul 2002 07:35:27 -0000 1.1.1.1 +++ src/org/netbeans/mdr/handlers/StructGenerator.java 10 Jul 2002 08:35:59 -0000 1.2 @@ -19,6 +19,7 @@ import java.util.*; /** + * [XXX]: put this class into correct package ! * * @author mmatula * @version @@ -32,12 +33,12 @@ private static final String CONSTRUCTOR_DESCRIPTOR = "(Ljava/util/List;Ljava/util/Map;Ljava/util/List;)V"; - private StructGenerator(String className, Class ifc) { - super(className, ifc, StructImpl.class); + private StructGenerator(String className, Class ifc, Class superClass) { + super(className, ifc, superClass); } - public static byte[] generateStruct(final String name, Class ifc) { - StructGenerator gen = new StructGenerator(name, ifc); + public static byte[] generateStruct(final String name, Class ifc, Class superClass) { + StructGenerator gen = new StructGenerator(name, ifc, superClass); final byte[] classFile = gen.generateClassFile(); return classFile; Index: src/org/netbeans/mdr/handlers/StructImpl.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/mdr/handlers/StructImpl.java,v retrieving revision 1.1.1.1 retrieving revision 1.4 diff -u -r1.1.1.1 -r1.4 --- src/org/netbeans/mdr/handlers/StructImpl.java 2 Jul 2002 07:35:27 -0000 1.1.1.1 +++ src/org/netbeans/mdr/handlers/StructImpl.java 10 Jul 2002 08:38:57 -0000 1.4 @@ -1,11 +1,11 @@ /* * Sun Public License Notice - * + * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ - * + * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2001 Sun * Microsystems, Inc. All Rights Reserved. @@ -22,18 +22,30 @@ import org.netbeans.mdr.storagemodel.*; /** + * Abstract base class for generated structure implementations. + * + *

    [XXX]: Replacing this class by a repository parameter is not yet + * implemented. The problem is, that in {@link #newInstance(Class, List, Map, List)} + * there is no access to the MdrStorage which holds this parameter.

    * * @author mmatula - * @version + * @version */ public abstract class StructImpl extends ImplClass implements RefStruct { - private final List fields; - // field values - private final Map values; - // fully qualified name of metaobject - private final List qualifiedName; - - private static Class getStructClass(MDRClassLoader loader, Class ifc) throws IllegalArgumentException { + + /* -------------------------------------------------------------------- */ + /* -- Factory methods (static) ---------------------------------------- */ + /* -------------------------------------------------------------------- */ + + /** + * Returns the structure implementation implementing ifc. + * + * @param loader the class-loader for the definition of the implementation class + * @param ifc the interface to be implementated by the implementation class + * @param superClass the super class for structure implementations + * @return a class implementing ifc + */ + private static Class getStructClass(MDRClassLoader loader, Class ifc, Class superClass) throws IllegalArgumentException { check(loader, ifc); Map cache = getLoaderCache(loader); String className = getName(ifc); @@ -41,7 +53,7 @@ if (result == null) { try { - byte[] structClassFile = StructGenerator.generateStruct(className, ifc); + byte[] structClassFile = StructGenerator.generateStruct(className, ifc, superClass); result = loader.defineClass(className, structClassFile); } finally { releaseCache(cache, result, className); @@ -51,6 +63,10 @@ return result; } + private static Class getStructClass(MDRClassLoader loader, Class ifc) throws IllegalArgumentException { + return getStructClass(loader, ifc, StructImpl.class); + } + public static RefStruct newInstance(DatatypeDescriptor dataType, Object fieldValues[]) { try { HashMap values = new HashMap(fieldValues.length, 1); @@ -70,50 +86,81 @@ } } + /** + * @param ifc the specific JMI interface for the structure type + * @param fields list of field names + * @param values maps field names to field values + * @param qualifiedName fully qualified name of the structure type + */ public static RefStruct newInstance(Class ifc, List fields, Map values, List qualifiedName) { MDRClassLoader loader = BaseObjectHandler.getDefaultClassLoader(); - Class cl = getStructClass(loader, ifc); - + Class cl = getStructClass(loader, ifc, StructImpl.class); + try { Constructor cons = cl.getConstructor(new Class[] {List.class, Map.class, List.class}); RefStruct struct = (RefStruct) cons.newInstance(new Object[] {fields, values, qualifiedName}); - + return struct; - } catch (NoSuchMethodException e) { + } catch (NoSuchMethodException e) { e.printStackTrace(); - throw new DebugException(e.toString()); - } catch (IllegalAccessException e) { + throw new DebugException(e.toString()); + } catch (IllegalAccessException e) { e.printStackTrace(); - throw new DebugException(e.toString()); - } catch (InstantiationException e) { + throw new DebugException(e.toString()); + } catch (InstantiationException e) { e.printStackTrace(); - throw new DebugException(e.toString()); - } catch (InvocationTargetException e) { + throw new DebugException(e.toString()); + } catch (InvocationTargetException e) { e.printStackTrace(); - throw new DebugException(e.toString()); - } + throw new DebugException(e.toString()); + } } - + + /* -------------------------------------------------------------------- */ + /* -- Attributes (private) -------------------------------------------- */ + /* -------------------------------------------------------------------- */ + + /** + * Field names + */ + private final List fields; + /** + * Field names => values + */ + private final Map values; + /** + * Fully qualified name of metaobject + */ + private final List qualifiedName; + + /* -------------------------------------------------------------------- */ + /* -- Constructor (protected) ----------------------------------------- */ + /* -------------------------------------------------------------------- */ + /** Creates new StructHandler */ protected StructImpl(List fields, Map values, List qualifiedName) { this.values = values; - this.qualifiedName = Collections.unmodifiableList(qualifiedName); - this.fields = Collections.unmodifiableList(fields); + this.qualifiedName = qualifiedName; + this.fields = fields; } - - // --- handler methods - + + /* -------------------------------------------------------------------- */ + /* -- Methods to be called by generated classes ----------------------- */ + /* -------------------------------------------------------------------- */ + protected Object handleGet(String memberName) { return refGetValue(memberName); } - - // --- implementation of RefStruct interface ------------------------------- - + + /* -------------------------------------------------------------------- */ + /* -- Implements of javax.jmi.reflect.RefStruct ----------------------- */ + /* -------------------------------------------------------------------- */ + public Object refGetValue(String memberName) { if (values.containsKey(memberName)) { return values.get(memberName); } else { - throw new DebugException("Wrong item name: " + memberName); + throw new InvalidNameException(memberName); } } @@ -124,7 +171,13 @@ public List refTypeName() { return this.qualifiedName; } - + + /* -------------------------------------------------------------------- */ + /* -- Extends java.lang.Object ---------------------------------------- */ + /* -------------------------------------------------------------------- */ + + // [XXX]: hashCode() must be implemented, too ! + public boolean equals(Object other) { // check whether other is instance of the same structure if ((other instanceof RefStruct) && ((RefStruct) other).refTypeName().equals(qualifiedName)) { Index: src/org/netbeans/mdr/handlers/gen/HandlerGenerator.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/mdr/handlers/gen/HandlerGenerator.java,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- src/org/netbeans/mdr/handlers/gen/HandlerGenerator.java 2 Jul 2002 07:35:27 -0000 1.1.1.1 +++ src/org/netbeans/mdr/handlers/gen/HandlerGenerator.java 4 Jul 2002 13:00:57 -0000 1.2 @@ -56,6 +56,11 @@ /** * Generate a handler class given a name, interface and storable object to * be wrapped by a handler object. + * + * @param name the name of the handler class + * @param ifc JMI interface to be implemented by the handler class + * @param storable informs about the super-class for the handler class + * @return the byte code for the class implementing ifc */ public static byte[] generateHandler(final String name, Class ifc, StorableBaseObject storable) { HandlerGenerator gen; @@ -65,7 +70,7 @@ } else if (storable instanceof StorableClass) { gen = new ClassGenerator(name, ifc, ((StorableClass) storable).getClassSuperclass(), (StorableClass)storable); } else if (storable instanceof StorablePackage) { - gen = new PackageGenerator(name, ifc, PackageProxyHandler.class, (StorablePackage)storable); + gen = new PackageGenerator(name, ifc, ((StorablePackage)storable).getPackageSuperclass(), (StorablePackage)storable); } else if (storable instanceof StorableObject) { gen = new InstanceGenerator(name, ifc, ((StorableObject) storable).getClassProxy().getInstanceSuperclass(), (StorableObject)storable); } else { Index: src/org/netbeans/mdr/persistence/MultivaluedIndex.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/mdr/persistence/MultivaluedIndex.java,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- src/org/netbeans/mdr/persistence/MultivaluedIndex.java 2 Jul 2002 07:35:27 -0000 1.1.1.1 +++ src/org/netbeans/mdr/persistence/MultivaluedIndex.java 10 Jul 2002 14:56:48 -0000 1.2 @@ -19,7 +19,7 @@ */ public interface MultivaluedIndex extends Index { /** Returns a collection view of the values associated in the index with specified key. - * Returned collection is read only and may not be modified. + * Returned collection is live and modifiable. * If there are no values associated with the key empty collection is returned. * @return * @param key Index: src/org/netbeans/mdr/persistence/MultivaluedOrderedIndex.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/mdr/persistence/MultivaluedOrderedIndex.java,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- src/org/netbeans/mdr/persistence/MultivaluedOrderedIndex.java 2 Jul 2002 07:35:27 -0000 1.1.1.1 +++ src/org/netbeans/mdr/persistence/MultivaluedOrderedIndex.java 10 Jul 2002 14:56:48 -0000 1.2 @@ -19,7 +19,7 @@ */ public interface MultivaluedOrderedIndex extends MultivaluedIndex { /** Returns a list view of the values assosiated in the index with specified key. - * Returned collection is read only and may not be modified. + * Returned collection is live and modifiable. * If there are no values associated with the key empty collection is returned. * @param key * @return Index: src/org/netbeans/mdr/shell/Main.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/mdr/shell/Main.java,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- src/org/netbeans/mdr/shell/Main.java 2 Jul 2002 07:35:29 -0000 1.1.1.1 +++ src/org/netbeans/mdr/shell/Main.java 4 Jul 2002 06:24:44 -0000 1.2 @@ -1,17 +1,21 @@ /* * Sun Public License Notice - * + * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ - * + * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2001 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.mdr.shell; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; + import java.util.Collection; import java.util.ArrayList; import java.util.Iterator; @@ -29,12 +33,46 @@ import javax.jmi.reflect.*; public class Main extends Object { - public static void main( String[] args ) { + + /** + * Resources names of the standard library files + */ + public static String[] STANDARD_LIBS = new String[] { "resources/start.ms", "resources/ext.ms" }; + + /** + * Command line interface of the MDRShell. The MDRShell is a + * Dynamic Java shell with preprocessor. Before user input + * is processed the files start.ms and ext.ms + * in the package org.netbeans.mdr.shell.resources and the + * files given as command line arguments are processed. + * + * @param args a list of file names read into the shell + * @throws FileNotFoundException if one of the arguments does not denote a + * valid file name + * @throws SecurityException if there is no read access to a file given as + * argument + */ + public static void main( String[] args ) throws FileNotFoundException { + /* the input streams */ + InputStream[] iss = new InputStream[STANDARD_LIBS.length+args.length+1]; + + /* standard library files */ + for ( int i=0; inull + * System.in is used. */ public void run( InputStream is ) { + run( new InputStream[] { is } ); + } + + /** Starts interpretting commands in the InputStreams. + * @param iss InputStreams to read commands from. If null + * System.in is used. + */ + public void run( InputStream[] iss ) { - pushInput( is == null ? System.in : is ); + if ( iss == null ) { + pushInput(System.in); + } else { + for ( int i = iss.length-1; i >= 0; i-- ) { + pushInput(iss[i]); + } + } DJava.initialize(); DJava.declareVariable( "SHELL", this ); Index: src/org/netbeans/mdr/storagemodel/BootReader.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/mdr/storagemodel/BootReader.java,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- src/org/netbeans/mdr/storagemodel/BootReader.java 2 Jul 2002 07:35:30 -0000 1.1.1.1 +++ src/org/netbeans/mdr/storagemodel/BootReader.java 9 Jul 2002 14:44:52 -0000 1.2 @@ -159,7 +159,6 @@ private Collection createInstances(Node xmiContent) { XmiUtils.XmiNodeIterator classes = new XmiUtils.XmiNodeIterator(xmiContent); Collection result = createInstances(classes, null, "", null); - classes = new XmiUtils.XmiNodeIterator(xmiContent); resolveSuperClasses(); resolveReferences(); setValues(); Index: src/org/netbeans/mdr/storagemodel/CompositeCollection.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/mdr/storagemodel/CompositeCollection.java,v retrieving revision 1.1.1.1 retrieving revision 1.3 diff -u -r1.1.1.1 -r1.3 --- src/org/netbeans/mdr/storagemodel/CompositeCollection.java 2 Jul 2002 07:35:30 -0000 1.1.1.1 +++ src/org/netbeans/mdr/storagemodel/CompositeCollection.java 11 Jul 2002 09:26:54 -0000 1.3 @@ -23,8 +23,8 @@ import org.netbeans.mdr.util.*; /** - * Instances of CompositeCollection are collections uniting several - * other collections. The methods of this class must be called in the following + * Instances of CompositeCollection are immutable collections uniting + * several other collections. The methods of this class must be called in the following * order: * *

      @@ -32,10 +32,18 @@ *
    1. {@link addCollection(Collection} to add a collection forming a part of * the current collection
    2. *
    3. any accessor method
    4. - *
    + *

    * - * It is not allowed to add further collections after any of the accessors has - * been called. + *

    It is not allowed to add further collections after any of the accessors has + * been called.

    + * + *

    Because the collections added using @link addCollection(Collection} are added + * as is and their members are accessed only, when to be returned by methods of + * this class resp. its {@link Iterator}, instances of CompositeCollection + * are live if and only if all of the composed collections are live.

    + * + *

    [XXX]: Put this class into org.netbeans.mdr.util + * package.

    * * @author mm109185 */ @@ -44,13 +52,13 @@ private final ArrayList innerCollections = new ArrayList(); private volatile boolean canChange = true; - CompositeCollection() { + public CompositeCollection() { } /** * Adds a new collection. Can only be called before any accessor call. */ - void addCollection(Collection collection) { + public void addCollection(Collection collection) { if (canChange) { innerCollections.add(collection); } else { @@ -122,30 +130,52 @@ public Object[] toArray() { return toArray(new Object[0]); } - + + /** + * operation not supported + */ public void clear() { throw new UnsupportedOperationException(); } + /** + * operation not supported + */ public boolean addAll(Collection collection) { throw new UnsupportedOperationException(); } + /** + * operation not supported + */ public boolean remove(Object obj) { throw new UnsupportedOperationException(); } + /** + * operation not supported + */ public boolean add(Object obj) { throw new UnsupportedOperationException(); } + /** + * operation not supported + */ public boolean retainAll(Collection collection) { throw new UnsupportedOperationException(); } + /** + * operation not supported + */ public boolean removeAll(Collection collection) { throw new UnsupportedOperationException(); } + + /* --------------------------------------------------------------------- */ + /* -- CompositeIterator (inner class) ---------------------------------- */ + /* --------------------------------------------------------------------- */ protected class CompositeIterator implements Iterator { private final Iterator innerIterators; @@ -174,6 +204,9 @@ return result; } + /** + * operation not supported + */ public void remove() { throw new UnsupportedOperationException(); } Index: src/org/netbeans/mdr/storagemodel/DatatypeDescriptor.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/mdr/storagemodel/DatatypeDescriptor.java,v retrieving revision 1.1.1.1 retrieving revision 1.3 diff -u -r1.1.1.1 -r1.3 --- src/org/netbeans/mdr/storagemodel/DatatypeDescriptor.java 2 Jul 2002 07:35:30 -0000 1.1.1.1 +++ src/org/netbeans/mdr/storagemodel/DatatypeDescriptor.java 10 Jul 2002 08:24:54 -0000 1.3 @@ -1,11 +1,11 @@ /* * Sun Public License Notice - * + * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ - * + * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2001 Sun * Microsystems, Inc. All Rights Reserved. @@ -24,26 +24,74 @@ */ public class DatatypeDescriptor extends Object { + + /* --------------------------------------------------------------------- */ + /* -- Attributes (private) --------------------------------------------- */ + /* --------------------------------------------------------------------- */ + + /** + * + */ private final int memberIDs[]; + + /** + * + */ private final int memberTypeIDs[]; + + /** + * + */ private final int ifcIndex; + + /** + * + */ private final int typeNameIndex; + /** + * + */ private final transient MdrStorage storage; - // name of the interface that the datatype maps to + /** + * name of the interface that the datatype maps to + */ private transient String ifcName = null; - // list of datatype members (enum. literals/structure fields) + + /** + * list of datatype members (enum. literals/structure fields) + */ private transient List members = null; - // list of datatypes of members (applicable for structure fields only) + + /** + * list of datatypes of members (applicable for structure fields only) + */ private transient List memberTypes = null; - // fully qualified name of datatype - // (stored only for structs - FQNs for enums are hardcoded in their impls) + + /** fully qualified name of datatype + * (stored only for structs - FQNs for enums are hardcoded in their impls) + **/ private transient List typeName = null; - // storage id + + /** + * storage id + */ private transient String storageId = null; - - // used for constructing structure descriptor + + /* --------------------------------------------------------------------- */ + /* -- Constructors (public/private) ------------------------------------ */ + /* --------------------------------------------------------------------- */ + + /** + * Creates a new structure descriptor. + * + * @param storage + * @param typeName + * @param memberTypes + * @param ifcName + * @param storageId + */ public DatatypeDescriptor(MdrStorage storage, List typeName, List members, List memberTypes, String ifcName, String storageId) { this.storage = storage; this.ifcName = ifcName; @@ -58,7 +106,7 @@ this.typeNameIndex = 0; } else { this.typeName = Collections.unmodifiableList(typeName); - this.typeNameIndex = storage.storageValues (this.storageId).store(typeName); + this.typeNameIndex = storage.storageValues(this.storageId).store(typeName); } if (memberTypes == null) { this.memberTypeIDs = null; @@ -71,11 +119,28 @@ } } - // used for creating enumeration descriptor + /** + * Create a new enumeration descriptor. + * + * @param storage + * @param members + * @param ifcName + * @param storageId + */ public DatatypeDescriptor(MdrStorage storage, List members, String ifcName, String storageId) { this(storage, null, members, null, ifcName, storageId); } - + + /** + * Constructor used during deserialization. + * + * @param storage + * @param typeNameIndex + * @param memberIDs + * @param memberTypeIDs + * @param ifcIndex + * @param storageId + */ private DatatypeDescriptor(MdrStorage storage, int typeNameIndex, int[] memberIDs, int[] memberTypeIDs, int ifcIndex, String storageId) { this.storage = storage; this.typeNameIndex = typeNameIndex; @@ -85,49 +150,88 @@ this.storageId = storageId; } - public synchronized List getMembers() { + /* --------------------------------------------------------------------- */ + /* -- Getters (with lazy initialization) ------------------------------- */ + /* --------------------------------------------------------------------- */ + + /** + * + */ + public List getMembers() { if (members == null) { - members = new ArrayList(memberIDs.length); - for (int i = 0; i < memberIDs.length; i++) { - members.add(storage.storageValues(this.storageId).resolve(memberIDs[i])); + synchronized(this) { + if (members == null ) { + members = new ArrayList(memberIDs.length); + for (int i = 0; i < memberIDs.length; i++) { + members.add(storage.storageValues(this.storageId).resolve(memberIDs[i])); + } + members = Collections.unmodifiableList(members); + } } - members = Collections.unmodifiableList(members); } return members; } - - public synchronized List getMemberTypes() { - if (memberTypeIDs == null) return null; + + /** + * + */ + public List getMemberTypes() { if (memberTypes == null) { - memberTypes = new ArrayList(memberTypeIDs.length); - for (int i = 0; i < memberTypeIDs.length; i++) { - try { - memberTypes.add(BaseObjectHandler.resolveInterface((String) storage.storageValues(this.storageId).resolve(memberTypeIDs[i]))); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - throw new DebugException(); + if (memberTypeIDs == null) return null; + synchronized(this) { + if (memberTypes == null) { + memberTypes = new ArrayList(memberTypeIDs.length); + for (int i = 0; i < memberTypeIDs.length; i++) { + try { + memberTypes.add(BaseObjectHandler.resolveInterface((String) storage.storageValues(this.storageId).resolve(memberTypeIDs[i]))); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + throw new DebugException(); + } + } + memberTypes = Collections.unmodifiableList(memberTypes); } } - memberTypes = Collections.unmodifiableList(memberTypes); } return memberTypes; } - - public synchronized List getTypeName() { + + /** + * + */ + public List getTypeName() { if (typeName == null) { - typeName = (List) storage.storageValues(this.storageId).resolve(typeNameIndex); + synchronized(this) { + if (typeName == null ) { + typeName = (List) storage.storageValues(this.storageId).resolve(typeNameIndex); + typeName = Collections.unmodifiableList(typeName); + } + } } return typeName; } - - public synchronized String getIfcName() { + + /** + * + */ + public String getIfcName() { if (ifcName == null) { - ifcName = (String) storage.storageValues(this.storageId).resolve(ifcIndex); + synchronized(this) { + if (ifcName == null) { + ifcName = (String) storage.storageValues(this.storageId).resolve(ifcIndex); + } + } } - return ifcName; } - + + /* --------------------------------------------------------------------- */ + /* -- Read/Write ------------------------------------------------------- */ + /* --------------------------------------------------------------------- */ + + /** + * + */ static DatatypeDescriptor readResolve(java.io.InputStream inputStream, StorableBaseObject storable) throws java.io.IOException { int typeNameIndex = IOUtils.readInt(inputStream); int[] memberIDs = new int[IOUtils.readInt(inputStream)]; @@ -146,6 +250,9 @@ return new DatatypeDescriptor(storable.getMdrStorage(), typeNameIndex, memberIDs, memberTypeIDs, IOUtils.readInt(inputStream), MdrStorage.getStorageIdFromMofId(storable.getMofId())); } + /** + * + */ void write(java.io.OutputStream outputStream) throws java.io.IOException { IOUtils.writeInt(outputStream, typeNameIndex); IOUtils.writeInt(outputStream, memberIDs.length); Index: src/org/netbeans/mdr/storagemodel/IndexImmutSet.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/mdr/storagemodel/IndexImmutSet.java,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- src/org/netbeans/mdr/storagemodel/IndexImmutSet.java 2 Jul 2002 07:35:30 -0000 1.1.1.1 +++ src/org/netbeans/mdr/storagemodel/IndexImmutSet.java 10 Jul 2002 14:58:34 -0000 1.2 @@ -18,19 +18,39 @@ import org.netbeans.mdr.util.DebugException; /** + * Instances of this class are immutable, live collections representing + * results of index access. * * @author mm109185 */ public class IndexImmutSet implements Collection { + + /* --------------------------------------------------------------------- */ + /* -- Attributes (protected) ------------------------------------------- */ + /* --------------------------------------------------------------------- */ + protected final MdrStorage storage; protected final MultivaluedIndex index; protected final Object indexKey; + /* --------------------------------------------------------------------- */ + /* -- Constructor (protected) ------------------------------------------ */ + /* --------------------------------------------------------------------- */ + + /** + * @param storage + * @param index the index where to look up the members of the current collection + * @param indexKey the key under which to look up the members of the current collection + */ protected IndexImmutSet(MdrStorage storage, MultivaluedIndex index, Object indexKey) { this.storage = storage; this.index = index; this.indexKey = indexKey; } + + /* --------------------------------------------------------------------- */ + /* -- Methods for index access ----------------------------------------- */ + /* --------------------------------------------------------------------- */ protected Collection getItems() { try { @@ -50,6 +70,10 @@ } } + /* --------------------------------------------------------------------- */ + /* -- implements java.util.Collection ---------------------------------- */ + /* --------------------------------------------------------------------- */ + public int size() { return getItems().size(); } @@ -78,30 +102,55 @@ return getObjects().toArray(); } + /** + * operation not supported + */ public boolean remove(Object o) { throw new UnsupportedOperationException(); } + /** + * operation not supported + */ public boolean add(Object obj) { throw new UnsupportedOperationException(); } + /** + * operation not supported + */ public boolean removeAll(Collection collection) { throw new UnsupportedOperationException(); } + /** + * operation not supported + */ public boolean addAll(Collection collection) { throw new UnsupportedOperationException(); } + /** + * operation not supported + */ public boolean retainAll(Collection collection) { throw new UnsupportedOperationException(); } + /** + * operation not supported + */ public void clear() { throw new UnsupportedOperationException(); } + /* --------------------------------------------------------------------- */ + /* -- IndexImmutIterator (inner class) --------------------------------- */ + /* --------------------------------------------------------------------- */ + + /** + * Wrapper for the index access iterator diabling modifying accesses. + */ protected class IndexImmutIterator implements Iterator { protected Iterator innerIterator; @@ -117,6 +166,9 @@ return innerIterator.next(); } + /** + * operation not supported + */ public void remove() { throw new UnsupportedOperationException(); } Index: src/org/netbeans/mdr/storagemodel/MdrStorage.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/mdr/storagemodel/MdrStorage.java,v retrieving revision 1.1.1.2 retrieving revision 1.6 diff -u -r1.1.1.2 -r1.6 --- src/org/netbeans/mdr/storagemodel/MdrStorage.java 10 Jul 2002 08:05:48 -0000 1.1.1.2 +++ src/org/netbeans/mdr/storagemodel/MdrStorage.java 18 Jul 2002 11:16:51 -0000 1.6 @@ -48,7 +48,7 @@ /* -------------------------------------------------------------------- */ /* -- Private static constants ---------------------------------------- */ /* -------------------------------------------------------------------- */ - + private static final int STORAGE_VERSION = 12; // names of global storage indexes @@ -156,6 +156,34 @@ /* -- Transient support ---*/ private long transientSerialNumber = 0; + /** + * The default super-class for package proxy implementations. + */ + private Class packageProxyHandlerClass = null; + + /** + * The default super-class for class proxy implementations. + */ + private Class classProxyHandlerClass = null; + + /** + * The default super-class for instance implementations. + */ + private Class instanceHandlerClass = null; + + /** + * The default super-class for association implementations. + */ + private Class associationHandlerClass = null; + + /** + * The super-class for structure implementations. + */ + private Class structureHandlerClass = null; + + /** The constructor parameters */ + private Map params; + /* -- boot specific stuff --------------------------------------------- */ /** @@ -169,7 +197,6 @@ /** boot association proxies */ private Collection bootAssociations = null; - /* -------------------------------------------------------------------- */ /* -- Setters/Getters (public) ---------------------------------------- */ /* -------------------------------------------------------------------- */ @@ -199,21 +226,150 @@ } /* -------------------------------------------------------------------- */ + /* -- Getters for names of implementation classes --------------------- */ + /* -------------------------------------------------------------------- */ + + /** + * Returns the class to be used as base class for package proxy + * implementations. + */ + Class getPackageProxyHandlerClass() throws ClassNotFoundException { + if (packageProxyHandlerClass == null) { + synchronized ( this ) { + if (packageProxyHandlerClass == null) { +// String className = (String) params.get("PackageProxyHandler"); +// if ( className != null ) { +// try { +// packageProxyHandlerClass = BaseObjectHandler.resolveImplementation(className); +// } catch (ClassNotFoundException e) { +// e.printStackTrace(); +// } +// } +// if ( packageProxyHandlerClass == null ) { + packageProxyHandlerClass = PackageProxyHandler.class; +// } + } + } + } + return packageProxyHandlerClass; + } + + /** + * Returns the default class to be used as base class for class proxy + * implementations. + */ + Class getClassProxyHandlerClass() throws ClassNotFoundException { + if (classProxyHandlerClass == null) { + synchronized(this) { + if (classProxyHandlerClass == null) { +// String className = (String) params.get("ClassProxyHandler"); +// if ( className != null ) { +// try { +// classProxyHandlerClass = BaseObjectHandler.resolveImplementation(className); +// } catch (ClassNotFoundException e) { +// e.printStackTrace(); +// } +// } +// if ( classProxyHandlerClass == null ) { + classProxyHandlerClass = ClassProxyHandler.class; +// } + } + } + } + return classProxyHandlerClass; + } + + /** + * Returns the default class to be used as base class for instance + * implementations. + */ + Class getInstanceHandlerClass() throws ClassNotFoundException { + if (instanceHandlerClass == null) { + synchronized(this) { + if (instanceHandlerClass == null) { +// String className = (String) params.get("InstanceHandler"); +// if ( className != null ) { +// try { +// instanceHandlerClass = BaseObjectHandler.resolveImplementation(className); +// } catch (ClassNotFoundException e) { +// e.printStackTrace(); +// } +// } +// if ( instanceHandlerClass == null ) { + instanceHandlerClass = InstanceHandler.class; +// } + } + } + } + return instanceHandlerClass; + } + + /** + * Returns the default class to be used as base class for association proxy + * implementations. + */ + Class getAssociationHandlerClass() throws ClassNotFoundException { + if (associationHandlerClass == null) { + synchronized(this) { + if (associationHandlerClass == null) { +// String className = (String) params.get("AssociationHandler"); +// if ( className != null ) { +// try { +// associationHandlerClass = BaseObjectHandler.resolveImplementation(className); +// } catch (ClassNotFoundException e) { +// e.printStackTrace(); +// } +// } +// if ( associationHandlerClass == null ) { + associationHandlerClass = AssociationHandler.class; +// } + } + } + } + return associationHandlerClass; + } + + /** + * Returns the class to be used as base class for structure + * implementations. + */ + public Class getStructureHandlerClass() throws ClassNotFoundException { + if (structureHandlerClass == null) { + synchronized(this) { + if (structureHandlerClass == null) { +// String className = (String) params.get("StructureHandler"); +// if ( className != null ) { +// try { +// structureHandlerClass = BaseObjectHandler.resolveImplementation(className); +// } catch (ClassNotFoundException e) { +// e.printStackTrace(); +// } +// } +// if ( structureHandlerClass == null ) { + structureHandlerClass = StructImpl.class; +// } + } + } + } + return structureHandlerClass; + } + + /* -------------------------------------------------------------------- */ /* -- Constructor (public) -------------------------------------------- */ /* -------------------------------------------------------------------- */ - /** Creates a new MdrStorage using factory storageClass - * and parameters properties. Creates a default storage, if the - * storageClass is not a + /** Creates a new MdrStorage using factory storageFactoryClassName + * and parameters params. Creates a default storage, if the + * storageFactoryClassName is not a * {@link org.netbeans.mdr.persistence.StorageFactory} or cannot be instantiated. * * @param repository - * @param storageClass fully qualified name of class implementing + * @param storageFactoryClassName fully qualified name of class implementing * {@link org.netbeans.mdr.persistence.StorageFactory} - * @param properties parameters for storage creation + * @param params parameters for storage creation * @exception DebugException if the storage cannot be created */ - public MdrStorage(NBMDRepositoryImpl repository, String storageClass, Map properties) { + public MdrStorage(NBMDRepositoryImpl repository, String storageFactoryClassName, Map params) { this.storages = new HashMap(); this.nullMofId = new HashMap(); this.objects = new HashMap(); @@ -223,10 +379,12 @@ this.valuesObjects = new HashMap(); this.repository = repository; + + this.params = params; StorageFactory storageFactory = null; try { // try to instantiate storage factory (its class name was passed as storageClass argument) - Class storageFactoryClass = Class.forName(storageClass); + Class storageFactoryClass = Class.forName(storageFactoryClassName); // does the class implement StorageFactory interface? if (StorageFactory.class.isAssignableFrom(storageFactoryClass)) { // yes - create new instance @@ -234,7 +392,7 @@ } else { // no - throw exception // (this exception will not be propagated - it will be caught immediately - see following lines) - throw new Exception("class "+storageClass+" does not implement StorageFactory"); + throw new Exception("class "+storageFactoryClassName+" does not implement StorageFactory"); } } catch (Exception e) { // in case the passed StorageFactory class could not be created, create default implementation @@ -246,7 +404,7 @@ try { // create storage passing the parameters to the factory method - this.bootStorage = storageFactory.createStorage(properties); + this.bootStorage = storageFactory.createStorage(params); // cache the NULL MOFID of the boot storage this.bootNullMofId = storageFactory.createNullMOFID(); } catch (StorageException e) { @@ -256,7 +414,7 @@ // create the utilities for storage management eventNotifier = new EventNotifier(); - repositoryMutex = new TransactionMutex(this, eventNotifier); + repositoryMutex = new TransactionMutex(this, eventNotifier, repository); } /* -------------------------------------------------------------------- */ @@ -329,7 +487,6 @@ /* -- Methods for initialization and reinitialization (public/private) */ /* -------------------------------------------------------------------- */ - /** Initializes MdrStorage instance. * This method is called by the {@link org.netbeans.mdr.NBMDRepositoryImpl repository} * during its initialization. It initializes resp. creates the boot storage. @@ -910,7 +1067,7 @@ * * @param context * @param indexName - * @return the index for the given attribute or null */ + * @return the index for the given attribute or null */ private MultivaluedIndex getAdditionalIndex(String context, String indexName) { try { Storage storage = getStorageByMofId(context); @@ -1234,7 +1391,7 @@ Hashtable temp = new Hashtable(); Object key; String extent = getContextOutermostPackage(mofContext).getMofId(); - + // rebuild attribute indexes SinglevaluedIndex attributeIndexes = bootStorage.getSinglevaluedIndex(PREFIX_ATTR_INDEXES_BY_NAME + extent); String oldValue; @@ -1255,7 +1412,7 @@ } bootStorage.dropIndex(oldAttributeIndex.getName()); } - */ + */ Object key; String newValue; @@ -1515,7 +1672,7 @@ private String getContextAssocEndIndexName(String context, String assocMofId, int end) { return PREFIX_ASSOC_END + context + ":" + assocMofId + end; } - + public Storage getStorageByMofId(String mofId) { String storageId = getStorageIdFromMofId(mofId); if (storageId == null) { @@ -1564,13 +1721,13 @@ /** Transient support **/ void registerTransientObjectsContainer(String mofId, TransientStorableClass tsc) { - org.netbeans.mdr.storagemodel.transientimpl.TransientObjectResolverIndex tir = (org.netbeans.mdr.storagemodel.transientimpl.TransientObjectResolverIndex) - this.objects.get (org.netbeans.mdr.storagemodel.transientimpl.MOFID.TRANSIENT_STORAGE_PREFIX); + org.netbeans.mdr.storagemodel.transientimpl.TransientObjectResolverIndex tir = (org.netbeans.mdr.storagemodel.transientimpl.TransientObjectResolverIndex) + this.objects.get(org.netbeans.mdr.storagemodel.transientimpl.MOFID.TRANSIENT_STORAGE_PREFIX); if (tir == null) { - tir = new org.netbeans.mdr.storagemodel.transientimpl.TransientObjectResolverIndex (); - this.objects.put (org.netbeans.mdr.storagemodel.transientimpl.MOFID.TRANSIENT_STORAGE_PREFIX, tir); + tir = new org.netbeans.mdr.storagemodel.transientimpl.TransientObjectResolverIndex(); + this.objects.put(org.netbeans.mdr.storagemodel.transientimpl.MOFID.TRANSIENT_STORAGE_PREFIX, tir); } - tir.register (mofId, tsc); + tir.register(mofId, tsc); } void unregisterTransientObjectsContainer(String mofId) throws StorageException { Index: src/org/netbeans/mdr/storagemodel/StorableAssociation.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/mdr/storagemodel/StorableAssociation.java,v retrieving revision 1.1.1.2 retrieving revision 1.5 diff -u -r1.1.1.2 -r1.5 --- src/org/netbeans/mdr/storagemodel/StorableAssociation.java 10 Jul 2002 08:05:48 -0000 1.1.1.2 +++ src/org/netbeans/mdr/storagemodel/StorableAssociation.java 12 Jul 2002 10:02:58 -0000 1.5 @@ -150,7 +150,7 @@ if (((Boolean) getMetaObject().getAttribute(MOFConstants.SH_MODEL_ASSOCIATION_IS_DERIVED)).booleanValue() || TagSupport.getTagValue(getMetaObject(), INTERCEPTABLE_TAG_ID, "").equals("true")) return BaseObjectHandler.resolveImplementation(TagSupport.getImplFullName(getMetaObject(), TagSupport.ASSOCIATION)); else - return AssociationHandler.class; + return getMdrStorage().getAssociationHandlerClass(); } /** Returns multiplicity of the first association end. @@ -246,26 +246,14 @@ } /** + * Returns immutable, live collection of all links managed by this association + * proxy. + * * @throws StorageException - * @return + * @return immutable, live collection of all links */ public Collection getAllLinks() throws StorageException { - ArrayList allLinks = new ArrayList (); - - for (Iterator it = bIndex.keySet().iterator (); it.hasNext();) { - String a = (String) it.next(); - if (isMultivaluedB()) { - Collection bees = getMdrStorage().getObjectsFromIndex((MultivaluedIndex) bIndex, a); - for (Iterator it2 = bees.iterator (); it2.hasNext();){ - AssociationLink oneLink = new AssociationLink((StorableObject) getMdrStorage().getObject(a), (StorableObject) it2.next()); - allLinks.add(oneLink); - } - } else { - AssociationLink oneLink = new AssociationLink((StorableObject) getMdrStorage().getObject(a), (StorableObject) getMdrStorage().getObjectFromIndexIfExists((SinglevaluedIndex) bIndex, a)); - allLinks.add(oneLink); - } - } - return Collections.unmodifiableCollection(allLinks); + return new LinkSetCollection(); } /** @@ -567,5 +555,155 @@ e.printStackTrace(); throw new RuntimeException(); } + } + + /* --------------------------------------------------------------------- */ + /* -- LinkSetCollection (inner class) ---------------------------------- */ + /* --------------------------------------------------------------------- */ + + protected class LinkSetCollection extends AbstractCollection { + + public Iterator iterator() { + return new LinkSetIterator(); + } + + public int size() { + int size = 0; + LinkSetIterator it = new LinkSetIterator(); + it.initCheck(); + while (it.b != null) { + size++; + it.fetchNext(); + } + return size; + } + } + + /* --------------------------------------------------------------------- */ + /* -- LinkSetIterator (inner class) ------------------------------------ */ + /* --------------------------------------------------------------------- */ + + protected class LinkSetIterator implements Iterator { + + boolean initialized = false; + + /** + * Iterator through all instances at the a-side of this association or + * null before the first access or if a storage problem + * occured. + */ + Iterator as = null; + + /** + * MOF ID of the current instance at the a side. null + * only before the first call to fetchNext(). + */ + String aID = null; + + /** + * Object with ID aID or null if not yet + * retrieved. + */ + StorableObject a = null; + + /** + * If the association if multi-valued at b's end, bs + * contains the iterator for the b's associated with the current a. + * Shall only be accessed inside fetchNext(). + */ + Iterator bs = null; + + /** + * The current b object, null initially and after the + * last link has been retrieved. + */ + StorableObject b = null; + + private void initCheck() { + if ( ! initialized ) { + initialized = true; + try { + as = bIndex.keySet().iterator(); + } catch ( StorageException se ) { + // [XXX]: probably throw a DebugException here + as = null; + } + fetchNext(); + } + } + + private void fetchNext() { + if ( as == null ) { + return; + } + b = null; + // check if there is yet another b for the current a + if ( bs != null ) { + if ( bs.hasNext() ) { + b = (StorableObject) bs.next(); + return; + } + } + + try { + // fetch the next a + while ( as.hasNext() ) { + aID = (String) as.next(); + a = null; + // fetch the first b for the given a, if exists + if ( isMultivaluedB() ) { + bs = getMdrStorage().getObjectsFromIndex((MultivaluedIndex) bIndex, aID).iterator(); + if ( bs.hasNext() ) { + b = (StorableObject) bs.next(); + } + } else { + b = (StorableObject) getMdrStorage().getObjectFromIndexIfExists((SinglevaluedIndex) bIndex, aID); + } + // check, if a b was found, return, if yes + if ( b != null ) { + return; + } + } + } catch (StorageException se) { + // [XXX]: probably throw a DebugException here + as = null; + b = null; + } + + // there are not more links ! + return; + } + + public boolean hasNext() { + initCheck(); + return b != null; + } + + public Object next() { + initCheck(); + if ( b == null ) { + throw new NoSuchElementException(); + } + if ( a == null ) { + try { + a = (StorableObject) getMdrStorage().getObject(aID); + } catch (StorageException se) { + // {XXX]: better exception handling + se.printStackTrace(); + throw new DebugException(); + } + } + AssociationLink link = new AssociationLink(a,b); + fetchNext(); + return link; + } + + /** + * operation not supported + */ + public void remove() { + throw new UnsupportedOperationException(); + } + } } Index: src/org/netbeans/mdr/storagemodel/StorableClass.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/mdr/storagemodel/StorableClass.java,v retrieving revision 1.1.1.3 retrieving revision 1.5 diff -u -r1.1.1.3 -r1.5 --- src/org/netbeans/mdr/storagemodel/StorableClass.java 18 Jul 2002 08:37:28 -0000 1.1.1.3 +++ src/org/netbeans/mdr/storagemodel/StorableClass.java 18 Jul 2002 10:06:32 -0000 1.5 @@ -224,9 +224,13 @@ return (DatatypeDescriptor) datatypes.get(name); } - /** Returns all instances of MOF class represented by this proxy within the current context. + /** Returns immutable, live collection of all instances of MOF class + * represented by this proxy. + * + * @param subclasses if true also the instances of sub-classes + * will be returned, otherwise only the instances of the current class + * @return collection of instances of this class (and its sub-classes) * @throws StorageException problem in storage - * @return collection of instances */ public Collection allObjects(boolean subclasses) throws StorageException { if (subclasses) { @@ -240,10 +244,18 @@ } } + /** + * Adds the instances of this class and its super-classes to result + * and adds the MOF IDs of all visited class proxies to visited. + * Instances of a class already being a member of visited are + * not added to result a second time. + * + * @param result the collection where to add the instances + * @param visited MOF IDs of class proxies already visited + */ private void collectObjects(CompositeCollection result, Set visited) throws StorageException { - if (!visited.contains(getMofId())) { + if (visited.add(getMofId())) { result.addCollection(allObjects(false)); - visited.add(getMofId()); for (Iterator it = subclasses.iterator(); it.hasNext();) { ((StorableClass) getMdrStorage().getObject((String) it.next())).collectObjects(result, visited); } @@ -449,6 +461,9 @@ visited.add(getMofId()); } + /** + * Returns the super-class for generated handler classes. + */ public Class getClassSuperclass() throws StorageException, ClassNotFoundException { if (classSuperclass == null) { synchronized (superclassMutex) { @@ -485,6 +500,23 @@ return false; } + /** + * Returns the implementation super-class for the generated handler. + * + *

    If the class has derived or inceptable members, {@link + * TagSupport#getImplFullName(StorableObject, int)} determines the class + * name.

    + * + *

    If this model class has model super-classes then the return value + * depends on if there is a most specific implementation class among the + * implementation classes of those super-classes. If yes, this most + * specific implementation class is returned, otherwise {@link + * TagSupport#getImplFullName(StorableObject, int)} determines the class + * name.

    + * + *

    If non of the cases above applies, ClassProxyHandler.class + * is returned as default value.

    + */ private Class resolveClassSuperclass() throws StorageException, ClassNotFoundException { Class result = null; if (classDerived) { @@ -505,16 +537,12 @@ } } if (result == null) { - result = ClassProxyHandler.class; + result = getMdrStorage().getClassProxyHandlerClass(); } } return result; } - private Class resolveClass(String className) throws ClassNotFoundException { - return BaseObjectHandler.resolveImplementation(className); - } - private Class resolveInstanceSuperclass() throws StorageException, ClassNotFoundException { Class result = null; if (instanceDerived || TagSupport.getTagValue(getMetaObject(), INTERCEPTABLE_TAG_ID, "").equals("true")) try { @@ -540,11 +568,15 @@ } } } - if (result == null) { - result = InstanceHandler.class; + if ( result == null ) { + result = getMdrStorage().getInstanceHandlerClass(); } } return result; + } + + private Class resolveClass(String className) throws ClassNotFoundException { + return BaseObjectHandler.resolveImplementation(className); } protected void deleteRecursive() throws StorageException { Index: src/org/netbeans/mdr/storagemodel/StorablePackage.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/mdr/storagemodel/StorablePackage.java,v retrieving revision 1.1.1.2 retrieving revision 1.3 diff -u -r1.1.1.2 -r1.3 --- src/org/netbeans/mdr/storagemodel/StorablePackage.java 18 Jul 2002 08:37:28 -0000 1.1.1.2 +++ src/org/netbeans/mdr/storagemodel/StorablePackage.java 18 Jul 2002 10:06:32 -0000 1.3 @@ -54,6 +54,13 @@ } /** + * Returns the super-class for generated handler classes. + */ + public Class getPackageSuperclass() throws StorageException, ClassNotFoundException { + return getMdrStorage().getPackageProxyHandlerClass(); + } + + /** * @param pkgMeta * @param clustered * @throws StorageException Index: src/org/netbeans/mdr/util/EventNotifier.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/mdr/util/EventNotifier.java,v retrieving revision 1.1.1.1 retrieving revision 1.7 diff -u -r1.1.1.1 -r1.7 --- src/org/netbeans/mdr/util/EventNotifier.java 2 Jul 2002 07:35:30 -0000 1.1.1.1 +++ src/org/netbeans/mdr/util/EventNotifier.java 16 Jul 2002 13:28:08 -0000 1.7 @@ -1,11 +1,11 @@ /* * Sun Public License Notice - * + * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ - * + * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2001 Sun * Microsystems, Inc. All Rights Reserved. @@ -14,6 +14,7 @@ import org.netbeans.api.mdr.events.*; import org.netbeans.mdr.handlers.BaseObjectHandler; +import org.netbeans.mdr.storagemodel.CompositeCollection; import java.util.*; import javax.jmi.reflect.*; @@ -22,413 +23,978 @@ * after transactions. * * @author mmatula - * @version + * @author
    "; + } + /** + * Pretty prints a event type mask. + * + *

    [XXX]: Probably this method should be used to a test utility + * class ?!

    + */ + public static String prettyPrintMask(int mask) { + StringBuffer buf = new StringBuffer(); + if ( (mask & AttributeEvent.EVENT_ATTRIBUTE_ADD) == AttributeEvent.EVENT_ATTRIBUTE_ADD ) buf.append("IAA "); + if ( (mask & AttributeEvent.EVENT_ATTRIBUTE_REMOVE) == AttributeEvent.EVENT_ATTRIBUTE_REMOVE ) buf.append("IAR "); + if ( (mask & AttributeEvent.EVENT_ATTRIBUTE_SET) == AttributeEvent.EVENT_ATTRIBUTE_SET ) buf.append("IAS "); + if ( (mask & AttributeEvent.EVENT_CLASSATTR_ADD) == AttributeEvent.EVENT_CLASSATTR_ADD ) buf.append("CAA "); + if ( (mask & AttributeEvent.EVENT_CLASSATTR_REMOVE) == AttributeEvent.EVENT_CLASSATTR_REMOVE ) buf.append("CAR "); + if ( (mask & AttributeEvent.EVENT_CLASSATTR_SET) == AttributeEvent.EVENT_CLASSATTR_SET ) buf.append("CAS "); + if ( (mask & InstanceEvent.EVENT_INSTANCE_CREATE) == InstanceEvent.EVENT_INSTANCE_CREATE ) buf.append("IC "); + if ( (mask & InstanceEvent.EVENT_INSTANCE_DELETE) == InstanceEvent.EVENT_INSTANCE_DELETE ) buf.append("ID "); + if ( (mask & AssociationEvent.EVENT_ASSOCIATION_ADD) == AssociationEvent.EVENT_ASSOCIATION_ADD ) buf.append("AA "); + if ( (mask & AssociationEvent.EVENT_ASSOCIATION_REMOVE) == AssociationEvent.EVENT_ASSOCIATION_REMOVE ) buf.append("AR "); + if ( (mask & AssociationEvent.EVENT_ASSOCIATION_SET) == AssociationEvent.EVENT_ASSOCIATION_SET ) buf.append("AS "); + if ( (mask & ExtentEvent.EVENT_EXTENT_CREATE) == ExtentEvent.EVENT_EXTENT_CREATE ) buf.append("EC "); + if ( (mask & ExtentEvent.EVENT_EXTENT_DELETE) == ExtentEvent.EVENT_EXTENT_DELETE ) buf.append("ED "); + if ( (mask & TransactionEvent.EVENT_TRANSACTION_COMMIT) == TransactionEvent.EVENT_TRANSACTION_COMMIT ) buf.append("TC "); + if ( (mask & TransactionEvent.EVENT_TRANSACTION_ROLLBACK) == TransactionEvent.EVENT_TRANSACTION_ROLLBACK ) buf.append("TR "); + if ( (mask & TransactionEvent.EVENT_TRANSACTION_START) == TransactionEvent.EVENT_TRANSACTION_START ) buf.append("TS "); + if ( buf.length() > 0 ) buf.deleteCharAt(buf.length()-1); + return buf.toString(); + } + + /* -------------------------------------------------------------------- */ + /* -- Public attributes ----------------------------------------------- */ + /* -------------------------------------------------------------------- */ + + public final Association ASSOCIATION = new Association(); + public final Clazz CLASS = new Clazz(); + public final Instance INSTANCE = new Instance(); + public final Package PACKAGE = new Package(); + public final Repository REPOSITORY = new Repository(); + + /* -------------------------------------------------------------------- */ + /* -- Private attributes ---------------------------------------------- */ + /* -------------------------------------------------------------------- */ + + /** + * Thread for the dispatching of events after transaction success. + */ + private final Thread dispatcher = new Thread(new EventsDelivery()); + + /** + * Maps: event => instance of QueuedListenerSet. + */ + private final Hashtable queuedListenerMap = new Hashtable(); + + /** + * Queue for the events of the currently running write transaction. + * The events are stored to inform their listeners either about + * rollback or success. + */ + private final LinkedList localQueue = new LinkedList(); + + /** + * Queue for the events of successfully finished transactions, the + * listeners of which still have to be informed. + */ + private final LinkedList globalQueue = new LinkedList(); + + /* -------------------------------------------------------------------- */ + /* -- Constructor (public) -------------------------------------------- */ + /* -------------------------------------------------------------------- */ + + /** + * Starts the dispatcher thread as daemon. + */ + public EventNotifier() { + dispatcher.setDaemon(true); + dispatcher.start(); + } + + /* -------------------------------------------------------------------- */ + /* -- Methods to fire events at transaction commit or rollback time --- */ + /* -------------------------------------------------------------------- */ + + /** + * Calls {@link MDRPreChangeListener.changeCancelled(MDRChangeEvent)} for + * all pre-change listeners on event to inform them + * about cancelling the event. + */ + public void fireCancelled(MDRChangeEvent event) { + localQueue.remove(event); + QueuedListenerSet collected = (QueuedListenerSet) queuedListenerMap.remove(event); + if (collected == null) { + System.err.println("Change cancelled event not corresponding to any planned change event."); + Thread.dumpStack(); + return; + } + // fire changeCancelled event + for (QueuedListenerSet.PreListenerIterator it = collected.preListenerIterator(); it.hasNext();) { + try { + it.next().changeCancelled(event); + } catch (RuntimeException e) { + // log the exception + e.printStackTrace(); + } + } + } + + /** + * Calls {@link MDRPreChangeListener.changeCancelled(MDRChangeEvent)} + * on all pre-change listeners of all events of the transaction to be + * rolled back. + */ + public void fireCancelled() { + while (!localQueue.isEmpty()) { + MDRChangeEvent event = (MDRChangeEvent) localQueue.getFirst(); + fireCancelled(event); + } + } + + /** + * Enqueues all events of a transaction successfully finished to inform + * the listeners in a separate thread. + */ + public void fireChanged() { + synchronized (globalQueue) { + globalQueue.addAll(localQueue); + globalQueue.notify(); + } + localQueue.clear(); + } + + /* -------------------------------------------------------------------- */ + /* -- EventNotifier.EventDelivery (inner class, private) -------------- */ + /* -------------------------------------------------------------------- */ + + /** + * Runnable to be executed by the event dispatcher thread. Waits on the + * global queue if it is empty. Informs the listeners on queued events. + * Catches all exceptions and logs the stack trace. + * + *

    Returns if a queued change event was not planned before (i.e. does + * not correspond to an entry in {@link #changeListeners}. + */ + private class EventsDelivery implements Runnable { /** - * Maps: event => set of change listeners. + * */ - private final Hashtable changeListeners = new Hashtable(); + public void run() { + QueuedListenerSet collected; + MDRChangeEvent event; + + while (true) { + synchronized (globalQueue) { + while (globalQueue.isEmpty()) { + try { + globalQueue.wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + collected = (QueuedListenerSet) queuedListenerMap.remove(event = (MDRChangeEvent) globalQueue.removeFirst()); + } + if (collected == null) { + System.err.println("Change event not corresponding to any planned change event."); + Thread.dumpStack(); + return; + } + for (QueuedListenerSet.AllListenerIterator it = collected.allListenerIterator(); it.hasNext();) { + try { + it.next().change(event); + } catch (RuntimeException e) { + // log the exception + e.printStackTrace(); + } + } + } + } + } + + /* -------------------------------------------------------------------- */ + /* -- EventNotifier.Abstract (inner class, public abstract) ----------- */ + /* -------------------------------------------------------------------- */ + + /** + * This class and its derived classes are used to enqueue all changes into + * the local queue and to fire the pre-change events. + */ + public abstract class Abstract { + /** + * Maps repository objects to instances of RegisteredListenerSet. + */ + private final HashMap RegisteredListenerSets = new HashMap(); + + /** + * Adds listener to source for event types + * matching mask. + */ + public void addListener(MDRChangeListener listener, int mask, Object source) { + //System.out.println("-- CALLED: addListener on " + source + " with " + prettyPrintMask(mask)); + if ( (listener == null) || (mask == 0) ) return; + + synchronized (RegisteredListenerSets) { + RegisteredListenerSet value = (RegisteredListenerSet) RegisteredListenerSets.get(source); + if ( value == null ) { + value = new RegisteredListenerSet(); + RegisteredListenerSets.put(source, value); + } + value.addListener(listener, mask); + } + } + + /** + * Removes listener from source for all event types. + */ + public void removeListener(MDRChangeListener listener, Object source) { + if ( listener == null ) return; + + synchronized (RegisteredListenerSets) { + RegisteredListenerSet value = (RegisteredListenerSet) RegisteredListenerSets.get(source); + if ( value != null ) { + value.removeListener(listener); + if ( value.isEmpty() ) { + RegisteredListenerSets.remove(source); + } + } + } + } + + /** + * Removes listener from source for event types + * matching mask. + */ + public void removeListener(MDRChangeListener listener, int mask, Object source) { + if ( (listener == null) || (mask == 0) ) return; + + synchronized (RegisteredListenerSets) { + RegisteredListenerSet value = (RegisteredListenerSet) RegisteredListenerSets.get(source); + if ( value != null ) { + value.removeListener(listener, mask); + if ( value.isEmpty() ) { + RegisteredListenerSets.remove(source); + } + } + } + } + + /** Informs pre-change listeners about the given event. Internally the + * event is stored together with its pre-change listeners and change + * listeners to allow further event processing at transaction rollback + * resp. commit time. + * + * @param current The source object of this event. + * @param event Event object. + * @exception DebugException if the event was already fired + */ + public void firePlannedChange(Object current, MDRChangeEvent event) { + //System.out.println("-- CALLED: firePlannedChange on " + current + " with type " + prettyPrintType(event)); + localQueue.addLast(event); + // collect all listeners + QueuedListenerSet queuedListeners = new QueuedListenerSet(event); + collectListeners(current, event, queuedListeners); + for (QueuedListenerSet.PreListenerIterator it = queuedListeners.preListenerIterator(); it.hasNext();) { + try { + it.next().plannedChange(event); + } catch (RuntimeException e) { + // log the exception + e.printStackTrace(); + } + } + if (queuedListenerMap.put(event,queuedListeners) != null) { + throw new DebugException("Same event fired twice."); + } + } /** - * Queue for the events of the currently running write transaction. - * The events are stored to inform their listeners either about - * rollback or success. - */ - private final LinkedList localQueue = new LinkedList(); + * Collects the listeners for the given event on object + * current. This method has to be overwritten by derived + * classes to inform listeners on objects to which the events are + * propagated. Overwriting methods shall call this method first and + * then add any further listeners. + * + * @param current the object on which the event was fired + * @param event the event + * @param post if false, listeners implementing + * {@link org.netbeans.api.mdr.events.MDRPreChangeListener} are + * collected, otherwise listeners implementing only + * {@link org.netbeans.api.mdr.events.MDRChangeListener} + * @param preChange the set where the pre-change listeners are collected + * @param postChange the set where the post-change only listeners are collected + */ + protected void collectListeners(Object current, MDRChangeEvent event, QueuedListenerSet queuedListeners) { + // fire event on all listeners registered on this object + synchronized (RegisteredListenerSets) { + RegisteredListenerSet value = (RegisteredListenerSet) RegisteredListenerSets.get(current); + if (value != null) { + value.collectListeners(queuedListeners); + } + } + } + } + + /* -------------------------------------------------------------------- */ + /* -- EventNotifier.Assocation (inner class, public) ------------------ */ + /* -------------------------------------------------------------------- */ + + /** + * Handles events for associations. + */ + public final class Association extends Abstract { + private Association() { + super(); + } + + public void addListener(MDRChangeListener listener, int mask, Object source) { + super.addListener(listener, mask & EventNotifier.EVENTMASK_BY_ASSOCIATION, source); + } + public void removeListener(MDRChangeListener listener, int mask, Object source) { + super.removeListener(listener, mask & EventNotifier.EVENTMASK_BY_ASSOCIATION, source); + } + + /** + * Adds listeners on the instances participating in the association link + * added resp. removed and on the owning package. + */ + protected void collectListeners(Object current, MDRChangeEvent event, QueuedListenerSet queuedListeners) { + super.collectListeners(current, event, queuedListeners); + + // fire event on all listeners registered on instances that were affected + if (event instanceof AssociationEvent) { + AssociationEvent assocEvent = (AssociationEvent) event; + if (assocEvent.getFixedElement() != null) INSTANCE.collectListeners(assocEvent.getFixedElement(), event, queuedListeners); + if (assocEvent.getOldElement() != null) INSTANCE.collectListeners(assocEvent.getOldElement(), event, queuedListeners); + if (assocEvent.getNewElement() != null) INSTANCE.collectListeners(assocEvent.getNewElement(), event, queuedListeners); + } + + // fire event on the immediate package extent + PACKAGE.collectListeners(((RefAssociation) current).refImmediatePackage(), event, queuedListeners); + } + } + + /* -------------------------------------------------------------------- */ + /* -- EventNotifier.Clazz (inner class, public) ----------------------- */ + /* -------------------------------------------------------------------- */ + + /** + * Handles events for class proxies. + */ + public final class Clazz extends Abstract { + private Clazz() { + super(); + } + + public void addListener(MDRChangeListener listener, int mask, Object source) { + super.addListener(listener, mask & EventNotifier.EVENTMASK_BY_CLASS, source); + } + public void removeListener(MDRChangeListener listener, int mask, Object source) { + super.removeListener(listener, mask & EventNotifier.EVENTMASK_BY_CLASS, source); + } + + /** + * Adds listeners on the owning package. + */ + protected void collectListeners(Object current, MDRChangeEvent event, QueuedListenerSet queuedListeners) { + super.collectListeners(current, event, queuedListeners); + PACKAGE.collectListeners(((RefClass) current).refImmediatePackage(), event, queuedListeners); + } + } + + /* -------------------------------------------------------------------- */ + /* -- EventNotifier.Instance (inner class, public) -------------------- */ + /* -------------------------------------------------------------------- */ + + /** + * Handles events for instances. + */ + public final class Instance extends Abstract { + private Instance() { + super(); + } + + public void addListener(MDRChangeListener listener, int mask, Object source) { + super.addListener(listener, mask & EventNotifier.EVENTMASK_BY_INSTANCE, source); + } + public void removeListener(MDRChangeListener listener, int mask, Object source) { + super.removeListener(listener, mask & EventNotifier.EVENTMASK_BY_INSTANCE, source); + } + + /** + * Adds listeners on the owning class proxy. + */ + protected void collectListeners(Object current, MDRChangeEvent event, QueuedListenerSet queuedListeners) { + super.collectListeners(current, event, queuedListeners); + CLASS.collectListeners(((RefObject) current).refClass(), event, queuedListeners); + } + } + + /* -------------------------------------------------------------------- */ + /* -- EventNotifier.Package (inner class, public) --------------------- */ + /* -------------------------------------------------------------------- */ + + /** + * Handles events for packages. + */ + public final class Package extends Abstract { + private Package() { + super(); + } + + public void addListener(MDRChangeListener listener, int mask, Object source) { + super.addListener(listener, mask & EventNotifier.EVENTMASK_BY_PACKAGE, source); + } + public void removeListener(MDRChangeListener listener, int mask, Object source) { + super.removeListener(listener, mask & EventNotifier.EVENTMASK_BY_PACKAGE, source); + } + + /** + * Adds listeners on the owning package resp., if this package is + * outermost, on the repository. + */ + protected void collectListeners(Object current, MDRChangeEvent event, QueuedListenerSet queuedListeners) { + super.collectListeners(current, event, queuedListeners); + RefPackage immediate = ((RefPackage) current).refImmediatePackage(); + if (immediate != null) { + collectListeners(immediate, event, queuedListeners); + } else { + REPOSITORY.collectListeners(((BaseObjectHandler) current)._getDelegate().getMdrStorage(), event, queuedListeners); + } + } + } + + /* -------------------------------------------------------------------- */ + /* -- EventNotifier.Repository (inner class, public) ------------------ */ + /* -------------------------------------------------------------------- */ + + /** + * Handles events for repositories. + */ + public final class Repository extends Abstract { + private Repository() { + super(); + } + + public void addListener(MDRChangeListener listener, int mask, Object source) { + super.addListener(listener, mask & EventNotifier.EVENTMASK_BY_REPOSITORY, source); + } + public void removeListener(MDRChangeListener listener, int mask, Object source) { + super.removeListener(listener, mask & EventNotifier.EVENTMASK_BY_REPOSITORY, source); + } + } + + /* ===================================================================== */ + /* == INNER CLASS CONTAINING OPTIMIZED/OPTIMIZABLE DATASTRUCTURES ====== */ + /* == FOR LISTENER MANAGEMENT ========================================== */ + /* ===================================================================== */ + Index: src/org/netbeans/mdr/util/ImplClass.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/mdr/util/ImplClass.java,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- src/org/netbeans/mdr/util/ImplClass.java 2 Jul 2002 07:35:30 -0000 1.1.1.1 +++ src/org/netbeans/mdr/util/ImplClass.java 4 Jul 2002 12:50:46 -0000 1.2 @@ -24,6 +24,8 @@ * @version */ public abstract class ImplClass { + + /* Suffix for the names of implementation classes. */ protected static final String classNameSuffix = "$Impl"; private static final ProtectionDomain pd; Index: src/org/netbeans/mdr/util/TransactionMutex.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/mdr/util/TransactionMutex.java,v retrieving revision 1.1.1.1 retrieving revision 1.3 diff -u -r1.1.1.1 -r1.3 --- src/org/netbeans/mdr/util/TransactionMutex.java 2 Jul 2002 07:35:30 -0000 1.1.1.1 +++ src/org/netbeans/mdr/util/TransactionMutex.java 11 Jul 2002 09:41:27 -0000 1.3 @@ -13,6 +13,8 @@ package org.netbeans.mdr.util; import java.util.HashMap; +import org.netbeans.api.mdr.events.TransactionEvent; +import org.netbeans.mdr.NBMDRepositoryImpl; import org.netbeans.mdr.storagemodel.MdrStorage; import org.netbeans.mdr.persistence.StorageException; @@ -52,14 +54,18 @@ // events notifier private final EventNotifier notifier; + // the repository (used as event source for transaction events) + private final NBMDRepositoryImpl repository; + /* -------------------------------------------------------------------- */ /* -- Constructor (public) -------------------------------------------- */ /* -------------------------------------------------------------------- */ /** Creates new TransactionMutex */ - public TransactionMutex(MdrStorage storage, EventNotifier notifier) { + public TransactionMutex(MdrStorage storage, EventNotifier notifier, NBMDRepositoryImpl repository) { this.storage = storage; this.notifier = notifier; + this.repository = repository; } /* -------------------------------------------------------------------- */ @@ -107,8 +113,15 @@ } if (writeAccess || counter > 0) { + if ( counter == 0 ) { + writer = thread; + TransactionEvent event = new TransactionEvent( + repository, + TransactionEvent.EVENT_TRANSACTION_START + ); + notifier.REPOSITORY.firePlannedChange(storage, event); + } counter++; - writer = thread; } else { Counter rCount = (Counter) readers.get(thread); if (rCount == null) { @@ -129,7 +142,7 @@ /** * Leave a transaction. If an outermost (i.e. not nested) write * transaction is left, the listeners are informed and the transaction - * is committed resp. rolled back. Finally all waiting thread are + * is committed resp. rolled back. Finally all waiting threads are * notified. * * @param fail false indicates transaction @@ -146,11 +159,21 @@ // left the last write lock -> commit/rollback and send events try { if (this.fail) { + TransactionEvent event = new TransactionEvent( + repository, + TransactionEvent.EVENT_TRANSACTION_ROLLBACK + ); + notifier.REPOSITORY.firePlannedChange(storage, event); notifier.fireCancelled(); storage.rollback(); Thread.dumpStack(); System.out.println("rolled back!"); } else { + TransactionEvent event = new TransactionEvent( + repository, + TransactionEvent.EVENT_TRANSACTION_COMMIT + ); + notifier.REPOSITORY.firePlannedChange(storage, event); notifier.fireChanged(); storage.commit(); //System.out.println("commited"); @@ -189,7 +212,7 @@ /* -------------------------------------------------------------------- */ /** - * Instances Counter are integer with {@link #dec() decrement} + * Instances Counter are integers with {@link #dec() decrement} * and {@link #inc() increment} methods. */ private static class Counter { Index: src/org/netbeans/modules/mdrexplorer/looks/MDREventHandler.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/src/org/netbeans/modules/mdrexplorer/looks/MDREventHandler.java,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- src/org/netbeans/modules/mdrexplorer/looks/MDREventHandler.java 2 Jul 2002 07:35:32 -0000 1.1.1.1 +++ src/org/netbeans/modules/mdrexplorer/looks/MDREventHandler.java 11 Jul 2002 09:26:54 -0000 1.2 @@ -26,24 +26,55 @@ import org.netbeans.api.looks.Look; /** + * Instances of MDREventHandler are event handlers which listen + * on repository changes on behalf of {@link org.netbeans.api.looks.LookNodeSubstitutes + * node substitutes}. They manage a map from repository objects to node substitutes + * to be able to access the node substitute for a given repository object. Looks + * have to register their node subsitutes by calling {@link #addNodeSubstitute(Look.NodeSubstitute)} + * or {@link #addNodeSubstitute(Object, Look.NodeSubstitute)} from within + * {@link org.netbeans.api.looks.Look#attachTo(ook.NodeSubstitute)}. * + * @deprecated register NodeSubstitutes directly on repository objects instead, see + * issue 25186 * @author Tomas Zezula */ public class MDREventHandler implements MDRPreChangeListener { + /* --------------------------------------------------------------------- */ + /* -- Attributes ------------------------------------------------------- */ + /* --------------------------------------------------------------------- */ + + /** + * Maps repository content to node substitutes. + */ private HashMap registeredNodeSubstitutes; + + /** + * Map storing the parents of objects to be deleted. After an object has + * been deleted, its parent node is not accessible any more. Nevertheless it + * must be refreshed to reflect the deletion of the node representing the object. + * Hence the parents of the objects to be deleted are stored in the map. + */ private HashMap pendingEvents; private ReferenceQueue queue; private MDRepository repository; + /* --------------------------------------------------------------------- */ + /* -- Constructor ------------------------------------------------------ */ + /* --------------------------------------------------------------------- */ + public MDREventHandler (MDRepository repository) { this.queue = new ReferenceQueue(); this.registeredNodeSubstitutes = new HashMap(); this.pendingEvents = new HashMap(); this.repository = repository; - this.repository.addListener(this); + this.repository.addListener(this, MDRChangeEvent.EVENTMASK_ALL); } + /* --------------------------------------------------------------------- */ + /* -- Management of NodeSubstitutes ------------------------------------ */ + /* --------------------------------------------------------------------- */ + public synchronized void addNodeSubstitute(Look.NodeSubstitute substitute) { if (substitute == null) return; @@ -56,32 +87,25 @@ this.registeredNodeSubstitutes.put(key, new WeakReference(substitute,this.queue)); } - /** This method is called when the node was garbage collected. You shoud - * unregister from all objects where this object was registered as a - * listener. - */ - - /** This method gets called if a planned change (which was already announced - * by calling {@link #plannedChange} was cancelled (e.g. the operation that was - * going to perform the change failed). This method is called synchronously by - * the operation that tried to perform the change.

    - * Any run-time exception thrown by the implementation of this method should - * not affect the events dispatching (i.e. it should be ignored by the event source). - * @param e Object describing the cancelled change (has to be the same instance - * as passed to the {@link #plannedChange} method). - */ - public void changeCancelled(MDRChangeEvent e) { - if ((e.getType() & 2) == 2) { - this.pendingEvents.remove(e.getSource()); + private synchronized Look.NodeSubstitute getNodeSubstituteForObject(Object object) { + if (object ==null) + return null; + Reference ref = (Reference) this.registeredNodeSubstitutes.get(object); + if (ref == null) { + return null; // Not registered object } + Look.NodeSubstitute substitute = (Look.NodeSubstitute) ref.get(); + return substitute; } - /** This method gets called when a repository change is planned to occur. - * Any operation that performs a change in MDR has to fire this notification - * synchronously on each registered pre-change listener before the change is performed.

    - * Any run-time exception thrown by the implementation of this method should - * not affect the events dispatching (i.e. it should be ignored by the event source). - * @param e Object describing the planned change. + /* --------------------------------------------------------------------- */ + /* -- Implements org.netbeans.api.mdr.MDRPreChangeListener ------------- */ + /* --------------------------------------------------------------------- */ + + /** + * Handles deletion events only. Stores the parents of objects to be deleted. + * This is necessary to refresh parent nodes when the object to be deleted + * has been deleted. */ public void plannedChange(MDRChangeEvent e) { if ((e.getType() & ExtentEvent.EVENT_EXTENT_DELETE) == ExtentEvent.EVENT_EXTENT_DELETE) { @@ -107,16 +131,18 @@ } } - /** This method gets called after a repository change is performed. This method - * is called asynchronously. - * If a listener implements {@link MDRPreChangeListener} which is a descedant - * of this interface, the event object passed to this method must be the same - * instance as the event object previously passed to the corresponding - * {@link MDRPreChangeListener#plannedChange} method call of the listener.

    - * Any run-time exception thrown by the implementation of this method should - * not affect the events dispatching (i.e. it should be ignored by the event source). - * - * @param e Object describing the performed change. + /** + * Removes the information stored for the pending event e. + * @see #plannedChange(MDRChangeEvent) + */ + public void changeCancelled(MDRChangeEvent e) { + if ((e.getType() & 2) == 2) { + this.pendingEvents.remove(e.getSource()); + } + } + + /** + * Refreshes the nodes affected by e. */ public void change(MDRChangeEvent e) { if ((e.getType() & ExtentEvent.EVENT_EXTENT_CREATE) == ExtentEvent.EVENT_EXTENT_CREATE) { @@ -171,6 +197,14 @@ } } + /* --------------------------------------------------------------------- */ + /* -- Clean-up dangling map entries ------------------------------------ */ + /* --------------------------------------------------------------------- */ + + /** + * Removes entries with garbage collected values from the map associating + * repository objects with node substitutes. + */ synchronized void flushReferenceQueue() { if (this.queue.poll()!=null) { Iterator values = this.registeredNodeSubstitutes.values().iterator(); @@ -184,17 +218,6 @@ } } - - private synchronized Look.NodeSubstitute getNodeSubstituteForObject(Object object) { - if (object ==null) - return null; - Reference ref = (Reference) this.registeredNodeSubstitutes.get(object); - if (ref == null) { - return null; // Not registered object - } - Look.NodeSubstitute substitute = (Look.NodeSubstitute) ref.get(); - return substitute; - } } Index: test/build-qa-functional.xml =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/test/build-qa-functional.xml,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- test/build-qa-functional.xml 2 Jul 2002 07:35:41 -0000 1.1.1.1 +++ test/build-qa-functional.xml 2 Jul 2002 16:31:01 -0000 1.2 @@ -158,7 +158,7 @@ - + @@ -204,7 +204,7 @@ - + Index: test/build-unit.xml =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/test/build-unit.xml,v retrieving revision 1.1.1.2 retrieving revision 1.3 diff -u -r1.1.1.2 -r1.3 --- test/build-unit.xml 18 Jul 2002 08:37:38 -0000 1.1.1.2 +++ test/build-unit.xml 18 Jul 2002 10:06:32 -0000 1.3 @@ -158,7 +158,7 @@ - + @@ -207,7 +207,7 @@ - + Index: test/build.xml =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/test/build.xml,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- test/build.xml 2 Jul 2002 07:35:41 -0000 1.1.1.1 +++ test/build.xml 2 Jul 2002 16:31:01 -0000 1.2 @@ -14,6 +14,9 @@ + + + Index: test/unit/src/org/netbeans/mdr/test/MDRTestAssociationEvents.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/test/unit/src/org/netbeans/mdr/test/MDRTestAssociationEvents.java,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- test/unit/src/org/netbeans/mdr/test/MDRTestAssociationEvents.java 2 Jul 2002 07:35:42 -0000 1.1.1.1 +++ test/unit/src/org/netbeans/mdr/test/MDRTestAssociationEvents.java 11 Jul 2002 09:33:52 -0000 1.2 @@ -68,7 +68,7 @@ EventsDataGenerator generator = new EventsDataGenerator(repository.getExtent(PKG_NAME)); - ((MDRChangeSource) repository).addListener(this); + ((MDRChangeSource) repository).addListener(this, MDRChangeEvent.EVENTMASK_ALL); Collection allMOFAssociations = testMOFPackage.refAllAssociations(); Iterator iterAssoc = allMOFAssociations.iterator(); @@ -106,7 +106,7 @@ EventsDataGenerator generator = new EventsDataGenerator(repository.getExtent(PKG_NAME)); - ((MDRChangeSource) repository).addListener(this); + ((MDRChangeSource) repository).addListener(this, MDRChangeEvent.EVENTMASK_ALL); Collection allMOFAssociations = testMOFPackage.refAllAssociations(); Iterator iterAssoc = allMOFAssociations.iterator(); Index: test/unit/src/org/netbeans/mdr/test/MDRTestAssociationPreEvents.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/test/unit/src/org/netbeans/mdr/test/MDRTestAssociationPreEvents.java,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- test/unit/src/org/netbeans/mdr/test/MDRTestAssociationPreEvents.java 2 Jul 2002 07:35:42 -0000 1.1.1.1 +++ test/unit/src/org/netbeans/mdr/test/MDRTestAssociationPreEvents.java 11 Jul 2002 09:33:52 -0000 1.2 @@ -68,7 +68,7 @@ EventsDataGenerator generator = new EventsDataGenerator(repository.getExtent(PKG_NAME)); - ((MDRChangeSource) repository).addListener(this); + ((MDRChangeSource) repository).addListener(this, MDRChangeEvent.EVENTMASK_ALL); Collection allMOFAssociations = testMOFPackage.refAllAssociations(); Iterator iterAssoc = allMOFAssociations.iterator(); @@ -106,7 +106,7 @@ EventsDataGenerator generator = new EventsDataGenerator(repository.getExtent(PKG_NAME)); - ((MDRChangeSource) repository).addListener(this); + ((MDRChangeSource) repository).addListener(this, MDRChangeEvent.EVENTMASK_ALL); Collection allMOFAssociations = testMOFPackage.refAllAssociations(); Iterator iterAssoc = allMOFAssociations.iterator(); Index: test/unit/src/org/netbeans/mdr/test/MDRTestAttributeEvents.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/test/unit/src/org/netbeans/mdr/test/MDRTestAttributeEvents.java,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- test/unit/src/org/netbeans/mdr/test/MDRTestAttributeEvents.java 2 Jul 2002 07:35:42 -0000 1.1.1.1 +++ test/unit/src/org/netbeans/mdr/test/MDRTestAttributeEvents.java 11 Jul 2002 09:33:52 -0000 1.2 @@ -68,7 +68,7 @@ EventsDataGenerator generator = new EventsDataGenerator(repository.getExtent(PKG_NAME)); - ((MDRChangeSource) repository).addListener(this); + ((MDRChangeSource) repository).addListener(this, MDRChangeEvent.EVENTMASK_ALL); RefObject newRefObj = null; Collection allMOFClasses = testMOFPackage.refAllClasses(); @@ -125,7 +125,7 @@ if (!metaClass.isAbstract()) { log("Creating instance for class: " + metaClass.getName()); newRefObj = generator.generateInstance(metaClass); - ((MDRChangeSource) newRefObj).addListener(listener); + ((MDRChangeSource) newRefObj).addListener(listener, MDRChangeEvent.EVENTMASK_ALL); generator.addAttribute(newRefObj, true, goldenPass, false); } else { log("Abstract class: " + metaClass.getName()); @@ -160,7 +160,7 @@ EventsDataGenerator generator = new EventsDataGenerator(repository.getExtent(PKG_NAME)); - ((MDRChangeSource) repository).addListener(this); + ((MDRChangeSource) repository).addListener(this, MDRChangeEvent.EVENTMASK_ALL); RefObject newRefObj = null; Collection allMOFClasses = testMOFPackage.refAllClasses(); @@ -218,7 +218,7 @@ log("Creating instance for class: " + metaClass.getName()); newRefObj = generator.generateInstance(metaClass); // listening on class instance and repository too - ((MDRChangeSource) newRefObj).addListener(listener); + ((MDRChangeSource) newRefObj).addListener(listener, MDRChangeEvent.EVENTMASK_ALL); generator.setAttribute(newRefObj, goldenPass, false); } else { log("Abstract class: " + metaClass.getName()); Index: test/unit/src/org/netbeans/mdr/test/MDRTestAttributePreEvents.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/test/unit/src/org/netbeans/mdr/test/MDRTestAttributePreEvents.java,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- test/unit/src/org/netbeans/mdr/test/MDRTestAttributePreEvents.java 2 Jul 2002 07:35:42 -0000 1.1.1.1 +++ test/unit/src/org/netbeans/mdr/test/MDRTestAttributePreEvents.java 11 Jul 2002 09:33:52 -0000 1.2 @@ -68,7 +68,7 @@ EventsDataGenerator generator = new EventsDataGenerator(repository.getExtent(PKG_NAME)); - ((MDRChangeSource) repository).addListener(this); + ((MDRChangeSource) repository).addListener(this, MDRChangeEvent.EVENTMASK_ALL); RefObject newRefObj = null; Collection allMOFClasses = testMOFPackage.refAllClasses(); @@ -126,7 +126,7 @@ log("Creating instance for class: " + metaClass.getName()); newRefObj = generator.generateInstance(metaClass); // listening on class instance and repository too - ((MDRChangeSource) newRefObj).addListener(listener); + ((MDRChangeSource) newRefObj).addListener(listener, MDRChangeEvent.EVENTMASK_ALL); generator.setAttribute(newRefObj, goldenPass, true); } else { log("Abstract class: " + metaClass.getName()); @@ -161,7 +161,7 @@ EventsDataGenerator generator = new EventsDataGenerator(repository.getExtent(PKG_NAME)); - ((MDRChangeSource) repository).addListener(this); + ((MDRChangeSource) repository).addListener(this, MDRChangeEvent.EVENTMASK_ALL); RefObject newRefObj = null; Collection allMOFClasses = testMOFPackage.refAllClasses(); @@ -218,7 +218,7 @@ if (!metaClass.isAbstract()) { log("Creating instance for class: " + metaClass.getName()); newRefObj = generator.generateInstance(metaClass); - ((MDRChangeSource) newRefObj).addListener(listener); + ((MDRChangeSource) newRefObj).addListener(listener, MDRChangeEvent.EVENTMASK_ALL); generator.addAttribute(newRefObj, true, goldenPass, true); } else { log("Abstract class: " + metaClass.getName()); Index: test/unit/src/org/netbeans/mdr/test/MDRTestExtentEvents.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/test/unit/src/org/netbeans/mdr/test/MDRTestExtentEvents.java,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- test/unit/src/org/netbeans/mdr/test/MDRTestExtentEvents.java 2 Jul 2002 07:35:43 -0000 1.1.1.1 +++ test/unit/src/org/netbeans/mdr/test/MDRTestExtentEvents.java 11 Jul 2002 09:33:52 -0000 1.2 @@ -42,7 +42,7 @@ protected void setUp() { super.setUp(); - ((MDRChangeSource) repository).addListener(this); + ((MDRChangeSource) repository).addListener(this, MDRChangeEvent.EVENTMASK_ALL); } protected void tearDown() { Index: test/unit/src/org/netbeans/mdr/test/MDRTestExtentPreEvents.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/test/unit/src/org/netbeans/mdr/test/MDRTestExtentPreEvents.java,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- test/unit/src/org/netbeans/mdr/test/MDRTestExtentPreEvents.java 2 Jul 2002 07:35:43 -0000 1.1.1.1 +++ test/unit/src/org/netbeans/mdr/test/MDRTestExtentPreEvents.java 11 Jul 2002 09:33:52 -0000 1.2 @@ -42,7 +42,7 @@ protected void setUp() { super.setUp(); - ((MDRChangeSource) repository).addListener(this); + ((MDRChangeSource) repository).addListener(this, MDRChangeEvent.EVENTMASK_ALL); } protected void tearDown() { Index: test/unit/src/org/netbeans/mdr/test/MDRTestInstanceEvents.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/test/unit/src/org/netbeans/mdr/test/MDRTestInstanceEvents.java,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- test/unit/src/org/netbeans/mdr/test/MDRTestInstanceEvents.java 2 Jul 2002 07:35:43 -0000 1.1.1.1 +++ test/unit/src/org/netbeans/mdr/test/MDRTestInstanceEvents.java 11 Jul 2002 09:33:52 -0000 1.2 @@ -68,7 +68,7 @@ EventsDataGenerator generator = new EventsDataGenerator(repository.getExtent(PKG_NAME)); - ((MDRChangeSource) repository).addListener(this); + ((MDRChangeSource) repository).addListener(this, MDRChangeEvent.EVENTMASK_ALL); RefObject newRefObj = null; Collection allMOFClasses = testMOFPackage.refAllClasses(); @@ -118,7 +118,7 @@ EventsDataGenerator generator = new EventsDataGenerator(repository.getExtent(PKG_NAME)); - ((MDRChangeSource) repository).addListener(this); + ((MDRChangeSource) repository).addListener(this, MDRChangeEvent.EVENTMASK_ALL); RefObject newRefObj = null; Collection allMOFClasses = testMOFPackage.refAllClasses(); Index: test/unit/src/org/netbeans/mdr/test/MDRTestInstancePreEvents.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/test/unit/src/org/netbeans/mdr/test/MDRTestInstancePreEvents.java,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- test/unit/src/org/netbeans/mdr/test/MDRTestInstancePreEvents.java 2 Jul 2002 07:35:43 -0000 1.1.1.1 +++ test/unit/src/org/netbeans/mdr/test/MDRTestInstancePreEvents.java 11 Jul 2002 09:33:52 -0000 1.2 @@ -68,7 +68,7 @@ EventsDataGenerator generator = new EventsDataGenerator(repository.getExtent(PKG_NAME)); - ((MDRChangeSource) repository).addListener(this); + ((MDRChangeSource) repository).addListener(this, MDRChangeEvent.EVENTMASK_ALL); RefObject newRefObj = null; Collection allMOFClasses = testMOFPackage.refAllClasses(); @@ -119,7 +119,7 @@ EventsDataGenerator generator = new EventsDataGenerator(repository.getExtent(PKG_NAME)); - ((MDRChangeSource) repository).addListener(this); + ((MDRChangeSource) repository).addListener(this, MDRChangeEvent.EVENTMASK_ALL); RefObject newRefObj = null; Collection allMOFClasses = testMOFPackage.refAllClasses(); @@ -174,7 +174,7 @@ EventsDataGenerator generator = new EventsDataGenerator(repository.getExtent(PKG_NAME)); - ((MDRChangeSource) repository).addListener(this); + ((MDRChangeSource) repository).addListener(this, MDRChangeEvent.EVENTMASK_ALL); RefObject newRefObj = null; Collection allMOFClasses = testMOFPackage.refAllClasses(); Index: test/unit/src/org/netbeans/mdr/test/StaticFeaturesTest.java =================================================================== RCS file: /usr/local/cvs/case/netbeans/mdr/test/unit/src/org/netbeans/mdr/test/StaticFeaturesTest.java,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- test/unit/src/org/netbeans/mdr/test/StaticFeaturesTest.java 2 Jul 2002 07:35:43 -0000 1.1.1.1 +++ test/unit/src/org/netbeans/mdr/test/StaticFeaturesTest.java 4 Jul 2002 06:29:56 -0000 1.2 @@ -61,7 +61,7 @@ // classifier-level attribute test public void test_1 () { - ModelPackage modelPackage = loadMOFModel ("StaticFeatures.xml", "model"); + ModelPackage modelPackage = loadMOFModel ("staticFeatures.xml", "model"); StaticFeaturesPackage pkg = (StaticFeaturesPackage) createExtent (findMofPackage (modelPackage, "StaticFeatures"), "staticFeatures"); int x, y; @@ -102,7 +102,7 @@ // static operator test public void test_2 () { - ModelPackage modelPackage = loadMOFModel ("StaticFeatures.xml", "model"); + ModelPackage modelPackage = loadMOFModel ("staticFeatures.xml", "model"); StaticFeaturesPackage pkg = (StaticFeaturesPackage) createExtent (findMofPackage (modelPackage, "StaticFeatures"), "staticFeatures"); ClassAClass proxyA = pkg.getClassA (); // staticFieldA (String), staticFieldB (int) @@ -142,7 +142,7 @@ // derived classifier-level attribute test public void test_3 () { - ModelPackage modelPackage = loadMOFModel ("StaticFeatures.xml", "model"); + ModelPackage modelPackage = loadMOFModel ("staticFeatures.xml", "model"); StaticFeaturesPackage pkg = (StaticFeaturesPackage) createExtent (findMofPackage (modelPackage, "StaticFeatures"), "staticFeatures"); ClassDClass proxyD = pkg.getClassD (); // staticFieldD (String), staticDerivedField (int), op. compute @@ -151,4 +151,44 @@ fail(); } + // classifier-level attribute test using reflective methods + public void test_reflective () { + ModelPackage modelPackage = loadMOFModel ("staticFeatures.xml", "model"); + StaticFeaturesPackage pkg = (StaticFeaturesPackage) createExtent (findMofPackage (modelPackage, "StaticFeatures"), "staticFeatures"); + + int x, y; + final int MAX = 100; + final int INT_VALUE = 678; + Random random = new Random (0); + + RefClass proxyA = pkg.getClassA (); // staticFieldA (String), staticFieldB (int) + RefClass proxyB = pkg.getClassB (); + RefClass proxyC = pkg.getClassC (); // staticFieldC (int), op. returnParam + RefClass proxyD = pkg.getClassD (); // staticFieldD (String), staticDerivedField (int), op. compute + + if (proxyD.refGetValue("staticFieldD") != null) + fail (); + proxyD.refSetValue("staticFieldD", "123"); + proxyB.refSetValue("staticFieldA", "abcdef"); + + for (x = 0; x < MAX; x++) { + int value = random.nextInt (); + proxyD.refSetValue("staticFieldB", new Integer(value)); + if ( (((Integer)proxyA.refGetValue("staticFieldB")).intValue() != value) || (((Integer)proxyD.refGetValue("staticFieldB")).intValue() != value)) + fail (); + } + + proxyD.refSetValue("staticFieldC", new Integer(INT_VALUE)); + + if (!proxyD.refGetValue("staticFieldD").equals("123")) + fail(); + if (!proxyB.refGetValue("staticFieldA").equals("abcdef")) + fail(); + if (((Integer)proxyD.refGetValue("staticFieldC")).intValue() != INT_VALUE) + fail(); + + proxyD.refSetValue("staticFieldC", new Integer(22)); + if (!proxyB.refGetValue("staticFieldA").equals("abcdef")) + fail(); + } }