alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 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;

import org.netbeans.api.mdr.CreationFailedException;
import org.netbeans.api.mdr.MDRepository;
import org.netbeans.api.mdr.events.ExtentEvent;
import org.netbeans.api.mdr.events.MDRChangeEvent;
import org.netbeans.api.mdr.events.MDRChangeListener;
import org.netbeans.mdr.handlers.BaseObjectHandler;
import org.netbeans.mdr.handlers.ImmutableList;
import org.netbeans.mdr.handlers.InstanceHandler;
import org.netbeans.mdr.handlers.gen.TagSupport;
import org.netbeans.mdr.persistence.MOFID;
import org.netbeans.mdr.persistence.StorageBadRequestException;
import org.netbeans.mdr.persistence.StorageException;
import org.netbeans.mdr.persistence.btreeimpl.btreestorage.BtreeFactory;
import org.netbeans.mdr.storagemodel.*;
import org.netbeans.mdr.storagemodel.StorableClass.AttributeDescriptor;
import org.netbeans.mdr.util.DebugException;
import org.netbeans.mdr.util.Logger;
import org.netbeans.mdr.util.MountFailedException;
import org.netbeans.mdr.util.TransactionMutex;
import org.openide.util.Lookup;
import javax.jmi.model.*;
import javax.jmi.reflect.*;
import javax.jmi.xmi.XmiReader;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.*;

/** This is an implementation of MOF based repository.
 *
 * @author Petr Hrebejk, Martin Matula
 */
public class NBMDRepositoryImpl implements MDRepository {
    
    /* -------------------------------------------------------------------- */
    /* -- Private static constants ---------------------------------------- */
    /* -------------------------------------------------------------------- */
    
    //    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");
    
    private static final String TAGID_INDEX = "org.netbeans.attributeIndex";
    
    private static final String PARAM_STORAGE_CLASS = "storage";
    
    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 int waitCount = 0;

    private final Map parameters;
    
    private Set shutdownListeners = new HashSet();
    
    /* -------------------------------------------------------------------- */
    /* -- Chaches for JMI interfactes and implementation creation --------- */
    /* -------------------------------------------------------------------- */
    
    /**
     * Maps storage objects (instances of {@link StorableBaseObject}) to
     * JMI compliant handler objects (instances of {@link RefBaseObject}).
     */
    private final Map facilityCache = new FacilityCache();
    
    /**
     * Maps mof ids of meta-objects to the appropriate JMI interfaces (String => Class).
     */
    private final Hashtable classCache = new Hashtable();

    /* --------------------------------------------------------------------- */
    /* -- Constructors ----------------------------------------------------- */
    /* --------------------------------------------------------------------- */
    
    /** Creates new {@link org.netbeans.api.mdr.MDRepository} with parameters
     *  given by system properties. The following system properties are
     *  evaluated:
     *
     * 
     *   
     *     
     *    
     *   
     *     
     *     
     *     
     *   
     *   
     *     
     *     
     *     
     *   
     * 
PropertyDefaultDescription
org.netbeans.mdr.storagemodel.StorageFactoryClassNameorg.netbeans.mdr.persistence.btreeimpl.btreestorage.BtreeFactoryname of a class implementing {@link * org.netbeans.mdr.persistence.StorageFactory}
org.netbeans.mdr.persistence.Dir(no default)storage location
*/ public NBMDRepositoryImpl() { Properties props = System.getProperties(); String storageClass = props.getProperty("org.netbeans.mdr.storagemodel.StorageFactoryClassName", "org.netbeans.mdr.persistence.btreeimpl.btreestorage.BtreeFactory"); String storageFile = props.getProperty("org.netbeans.mdr.persistence.Dir"); String storageUUID = props.getProperty("org.netbeans.mdr.persistence.UUID"); Logger.getDefault().log("Storage factory: " + storageClass); parameters = new HashMap(); parameters.put("storage", storageClass); parameters.put(BtreeFactory.STORAGE_FILE_NAME, storageFile); parameters.put(BtreeFactory.STORAGE_UUID, storageUUID); for (Enumeration e = props.propertyNames(); e.hasMoreElements();) { String name = (String) e.nextElement(); if (name.startsWith("MDRStorageProperty.")) { parameters.put(name.substring(19), props.getProperty(name)); } } // instances.add(this); } /** Creates new {@link org.netbeans.api.mdr.MDRepository} with given parameters. * The following parameters are processed: * *

    *
  1. storage: name of a class implementing {@link * org.netbeans.mdr.persistence.StorageFactory}
  2. *
  3. fileName: storage location
  4. *

*/ public NBMDRepositoryImpl(Map parameters) { Logger.getDefault().log("Creating MDRepository implementation ..."); this.parameters = parameters; // instances.add(this); } /* -------------------------------------------------------------------- */ /* -- Implementation of org.netbeans.api.mdr.events.MDRChangeSource --- */ /* -------------------------------------------------------------------- */ /** Registers a listener for receiving all event notifications. * * @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, mask, mdrStorage); } /** 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); } public void enableEvents() { initCheck(); mdrStorage.enableEvents(); } public void disableEvents() { beginTrans(false); mdrStorage.disableEvents(); endTrans(); } public MdrStorage getMdrStorage() { initCheck(); return mdrStorage; } /* -------------------------------------------------------------------- */ /* -- Implementation of org.netbeans.api.mdr.MDRepositry -------------- */ /* -------------------------------------------------------------------- */ public TransactionMutex getTransactionMutex() { initCheck(); return mdrStorage.getRepositoryMutex(); } public void beginTrans(boolean writeAccess) { synchronized (this) { initCheck(); waitCount++; } try { mdrStorage.getRepositoryMutex().enter(writeAccess); } catch (RuntimeException e) { decrementWait(); throw e; } catch (Error e) { decrementWait(); throw e; } } private synchronized void decrementWait() { waitCount--; } public void endTrans() { endTrans(false); } public void endTrans(boolean rollback) { initCheck(); try { if (mdrStorage.getRepositoryMutex().leave(rollback)) { mdrStorage.enableEvents(); } } catch (RuntimeException e) { mdrStorage.enableEvents(); throw e; } finally { decrementWait(); } } /** Instantiates the MOF model package. * * @param substName the name of the new model */ public RefPackage createExtent(String substName) throws CreationFailedException { return createExtent(substName, null); } /** Instantiates the outermost M2 package metaPackage * * @param substName the name of the new model * @param metaPackage The meta-model to be instantiated. null * is interpreted as the request to instantiate the MOF model * package. */ public RefPackage createExtent(String substName, RefObject metaPackage) throws CreationFailedException { return createExtent(substName, metaPackage, null); } /** Instantiates the outermost M2 package metaPackage * * @param substName the name of the new model * @param metaPackage The meta-model to be instantiated. null * is interpreted as the request to instantiate the MOF model * package. * @param existingInstances */ 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 * @return reference to the outermost package instance or * null if there is no package with the given name */ public RefPackage getExtent(String name) { StorablePackage pkg; initCheck(); beginTrans(false); try { try { // retrieve the package pkg = mdrStorage.getContextOutermostPackage(name); } catch (NullPointerException e) { pkg = null; } catch ( StorageBadRequestException e ) { pkg = null; } catch ( StorageException e ) { throw new DebugException("Storage exception: " + e); } // return the handler for the package return (RefPackage) getHandler(pkg); } finally { endTrans(); } } /** Returns all name of registered outermost package instances, * which can be passed to the {@link #getExtent(String)} method to obtain * an outermost package instance. * * @return array of names of outermost package instances. */ public String[] getExtentNames() { initCheck(); String result[] = new String[0]; beginTrans(false); try { result = (String[]) mdrStorage.getContexts().toArray(result); return result; } catch (StorageException e) { throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); } finally { endTrans(); } } /** * Returns the object with the given mofId. */ public RefBaseObject getByMofId(String mofId) { return getByMofId(MOFID.fromString(mofId)); } public RefBaseObject getByMofId(MOFID mofId) { initCheck(); beginTrans(false); try { StorableBaseObject storable = mdrStorage.getObject(mofId); return getHandler(storable); } catch (StorageException e) { // ignore } finally { endTrans(); } return null; } public void removeHandler(MOFID mofId) { synchronized (facilityCache) { facilityCache.remove(mofId); } } public void addHandler(BaseObjectHandler handler) { StorableBaseObject s = handler._getDelegate(); MOFID mofId = s.getMofId(); Object lock = s.getMdrStorage().getStorageByMofId(mofId); if (lock == null) lock = facilityCache; synchronized (lock) { synchronized (facilityCache) { facilityCache.put(mofId, handler); } } } /** * Called on repository exit. Should perform all needed finalization actions. */ public synchronized void shutdown() { if (mdrStorage != null) { try { while (waitCount > 0) { try { this.wait(100); } catch (InterruptedException e) { Logger.getDefault().notify(Logger.INFORMATIONAL, e); } } mdrStorage.shutDown(); } catch (StorageException e) { throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); } finally { mdrStorage = null; } } notifyShutdownListeners(); notifyShutdownStep(); } /* -------------------------------------------------------------------- */ /* -- Extending java.lang.Object -------------------------------------- */ /* -------------------------------------------------------------------- */ public String toString() { StringBuffer sb = new StringBuffer("IDE MOF Repository"); return sb.toString(); } /* -------------------------------------------------------------------- */ /* -- Create an outermost package instance ---------------------------- */ /* -------------------------------------------------------------------- */ /** Instantiates the outermost M2 package metaPackage * * @param substName the name of the new model * @param metaPackage The meta-model to be instantiated. null * is interpreted as the request to instantiate the MOF model * package. * @param existingInstances * @param storageId id of the storage partition */ public RefPackage createExtent(String substName, RefObject metaPackage, RefPackage[] existingInstances, String storageId) throws CreationFailedException { initCheck(); RefPackage result; boolean fail = true; if (metaPackage == null) { metaPackage = getMOFModelPackage(); } beginTrans(true); try { if (getExtent(substName) != null) { throw new CreationFailedException("Package extent named \'" + substName + "\' already exists."); } if (mdrStorage.eventsEnabled()) { ExtentEvent event = new ExtentEvent( this, ExtentEvent.EVENT_EXTENT_CREATE, substName, metaPackage, new ImmutableList(existingInstances) ); 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) { throw (CreationFailedException) Logger.getDefault().annotate(new CreationFailedException("Cannot instantiate package because of unexpected exception: " + e), 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 storageFactoryClass name of storage factory class, which will create a new storage. * Mounts new partition into current repository, * The partition is created and initialized, if it does not exist. * @param properties storage specific parameters (e.g. name of file for BTree) * @return String id. * @exception MountFailedException thrown when mounting fails. */ public String mountStorage(String storageFactoryClass, Map properties) throws MountFailedException { boolean failed = true; beginTrans(true); try { // Firing of event is done inside a MdrStorage mountStorage method String storageId = this.mdrStorage.mountStorage(storageFactoryClass, properties); failed = false; return storageId; }catch (Exception e) { e.printStackTrace(); throw new MountFailedException("Partition mount failed.", e); } finally { endTrans(failed); } } /** * Unmounts partition from current repository. * Unmounting 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 storageId id of storage. */ public void unmountStorage(String storageId) { boolean failed = true; beginTrans(true); try { if (mdrStorage.eventsEnabled()) { 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); } } this.mdrStorage.unmountStorage(storageId); failed = false; }catch (StorageException e) { throw new DebugException("Unmounting failed: "+e.toString()); } finally { endTrans(failed); } } /* -------------------------------------------------------------------- */ /* -- Public methods not specified by any interface ------------------- */ /* -------------------------------------------------------------------- */ /** Gets JNDI name of connection to MOF model package. This package * should be instantiated to create new metamodels. */ public String getMOFInstanceName() { return PURE_MOF; } public String getParameter(String name) { return (String) parameters.get(name); } /* --------------------------------------------------------------------- */ /* -- Methods for working with handlers -------------------------------- */ /* --------------------------------------------------------------------- */ /** * Frees the caches of JMI compliant handler objects (for storage objects) * and of JMI implementation classes (for meta-objects). */ public void freeCache() { facilityCache.clear(); classCache.clear(); } public RefBaseObject getHandler(MOFID mofId) { synchronized (facilityCache) { return (BaseObjectHandler) (facilityCache.get(mofId)); } } /** * 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 RefBaseObject getHandler(StorableBaseObject s) { if (s == null) { return null; } RefBaseObject refBO = getHandler(s.getMofId()); if (refBO == null) { Class ifc = BaseObjectHandler.resolveClass(s); refBO = getHandler(s, ifc); } return refBO; } /** * 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 RefBaseObject getHandler(StorableBaseObject s, Class ifc) { if (s == null) { return null; } /* load the handler class */ Class cl = BaseObjectHandler.getHandlerClass(ifc, s); try { Class cls = s.getClass(); if (cls.equals (TransientStorableClass.class)) { cls = StorableClass.class; } else if (cls.equals (TransientStorableObject.class)) { cls = StorableObject.class; } else if (cls.equals (TransientStorableAssociation.class)) { cls = StorableAssociation.class; } else if ((cls != StorableObject.class) && (StorableObject.class.isAssignableFrom(cls))) { cls = StorableObject.class; } /* create handler object, if necessary */ Constructor cons = cl.getConstructor(new Class[] {cls}); MOFID mofId = s.getMofId(); Object lock = s.getMdrStorage().getStorageByMofId(mofId); if (lock == null) lock = facilityCache; synchronized (lock) { synchronized (facilityCache) { Object oldRecord = facilityCache.get(mofId); if (oldRecord == null) { oldRecord = cons.newInstance(new Object[] {s}); facilityCache.put(mofId, oldRecord); } return (BaseObjectHandler) oldRecord; } } } catch (NoSuchMethodException e) { throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); } catch (IllegalAccessException e) { throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); } catch (InstantiationException e) { throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); } catch (InvocationTargetException e) { throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); } } /* -------------------------------------------------------------------- */ /* -- Shutdown listeners support -------------------------------------- */ /* -------------------------------------------------------------------- */ public void addShutdownListener(ShutdownListener listener) { synchronized (shutdownListeners) { shutdownListeners.add(listener); } } public void removeShutdownListener(ShutdownListener listener) { synchronized (shutdownListeners) { shutdownListeners.remove(listener); } } private void notifyShutdownListeners() { synchronized (shutdownListeners) { for (Iterator iter = shutdownListeners.iterator(); iter.hasNext();) { ShutdownListener listener = (ShutdownListener) iter.next(); listener.shutdown(); } } } public int getShutdownSteps() { return mdrStorage != null ? mdrStorage.getShutdownSteps() + 1 : 1; } public void notifyShutdownStep() { synchronized (shutdownListeners) { for (Iterator iter = shutdownListeners.iterator(); iter.hasNext();) { ShutdownListener listener = (ShutdownListener) iter.next(); listener.stepFinished(); } } } /* -------------------------------------------------------------------- */ /* -- Private helper methods ------------------------------------------ */ /* -------------------------------------------------------------------- */ /** Returns the M3 version of the MOF Model package, i.e. the MOF Model * as a model element of the MOF model. */ 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")) { return result; } } 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. */ private synchronized void initCheck() { if (mdrStorage == null) { String storageClass = (String) parameters.get(PARAM_STORAGE_CLASS); mdrStorage = new MdrStorage(this, storageClass, this.parameters); try { Logger.getDefault().log("initializing..."); // initialize storage if (!mdrStorage.init()) { Logger.getDefault().log("booting..."); // bootstrapping the repository boot(); } return; } catch (StorageException e) { throw (DebugException) Logger.getDefault().annotate(new DebugException("Fatal error: Repository boot/initialization failed with message: " + e.getMessage()), e); } } } /* -------------------------------------------------------------------- */ /* -- 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 * into packages. * * @param pkg package instance * @param packages map containing package instances as value and the MOF IDs * 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 { Object result = packages.put(((BaseObjectHandler)pkg.refMetaObject())._getDelegate().getMofId(), pkg); if (result != null && !result.equals(pkg)) { throw new CreationFailedException("The provided list of existing package instances contains duplicities."); } for (Iterator it = pkg.refAllPackages().iterator(); it.hasNext();) { RefPackage nested = (RefPackage) it.next(); collectPackageInstances(nested, packages); } } /** Instantiates given package, i.e. packageProxies, classProxies, * associationProxies. * * @param substName the name of the new model * @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); RefPackage result = (RefPackage) getHandler(newPackage); Logger.getDefault().log("new package: " + newPackage.getMofId() + ", metapackage: " + metaPackage.refMofId()); Set localAssocProxies = new HashSet(); List localClassProxies = new ArrayList(); instantiatePackageContent(metaPackage, newPackage, clusteredInstances, localClassProxies, localAssocProxies, storageId); resolveSuperclasses(metaPackage, localClassProxies); resolveAssociations(localAssocProxies); return result; } private void resolveAssociations(Collection localAssocProxies) { try { for (Iterator it = localAssocProxies.iterator(); it.hasNext();) { MOFID saMofId = (MOFID) it.next(); StorableAssociation sa = (StorableAssociation) mdrStorage.getObject(saMofId); if (!((Association) getHandler(sa.getMetaObject())).isDerived()) { Object metaCls = ((AssociationEnd) getByMofId(sa.getEnd1Id())).getType(); StorableClass cls = (StorableClass) classProxies.get(metaCls); cls.addAssociationEnd(saMofId, sa.getEnd1Name(), sa.isAggregateA()); metaCls = ((AssociationEnd) getByMofId(sa.getEnd2Id())).getType(); cls = (StorableClass) classProxies.get(metaCls); if (cls != null) { cls.addAssociationEnd(saMofId, sa.getEnd2Name(), sa.isAggregateB()); } } } } catch (StorageException e) { throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); } } /** * @param localClassProxies */ private void resolveSuperclasses(MofPackage metaPackage, List localClassProxies) { StorableClass sc; ModelElement me; AssociationEnd end; StorableClass current; MofClass cls; List indexTags; Map indexes = new HashMap (); if (!localClassProxies.isEmpty ()) { ModelPackage modelPackage = (ModelPackage) metaPackage.refImmediatePackage(); Iterator iter = modelPackage.getTag ().refAllOfClass ().iterator (); while (iter.hasNext ()) { Tag tag = (Tag) iter.next (); if (TAGID_INDEX.equals (tag.getTagId ())) { Iterator elements = tag.getElements ().iterator (); MofClass tempOwner = null, owner = null; boolean oneClass = true; while (elements.hasNext ()) { ModelElement elem = (ModelElement) elements.next (); if (elem instanceof MofClass) { oneClass = true; owner = (MofClass) elem; break; } else { if (elem instanceof Attribute) tempOwner = (MofClass) elem.getContainer (); else if (elem instanceof AssociationEnd) tempOwner = (MofClass) ((AssociationEnd) elem).otherEnd ().getType (); if ((owner == null) && (tempOwner != null)) owner = tempOwner; else oneClass = oneClass && (owner == tempOwner); } } // while if ((owner != null) && oneClass) { List tags = (List) indexes.get (owner); if (tags == null) indexes.put (owner, tags = new LinkedList ()); tags.add (tag); } } // if } // while } // if for (Iterator it = localClassProxies.iterator(); it.hasNext();) { sc = (StorableClass) it.next(); try { cls = (MofClass) getHandler(sc.getMetaObject()); } catch (StorageException e) { throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); } for (Iterator supers = cls.getSupertypes().iterator(); supers.hasNext();) { Object superMeta = supers.next(); current = ((StorableClass) classProxies.get(superMeta)); if (current == null) { throw new DebugException("Package definition is incomplete: class " + cls.getName() + " super = " + ((superMeta instanceof MofClass) ? ((MofClass) superMeta).getName() : superMeta)); } sc.addSuperclass(current.getMofId()); current.addSubclass(sc.getMofId()); } for (Iterator contents = cls.getContents().iterator(); contents.hasNext();) { me = (ModelElement) contents.next(); if (me instanceof Reference) { end = ((Reference) me).getExposedEnd(); //Logger.getDefault().log("registering reference: " + me.getName() + " for end: " + end.getName()); sc.addReferenceDescriptor(((BaseObjectHandler)me)._getDelegate().getMofId(), me.getName(), (MOFID) associationProxies.get(((BaseObjectHandler)end.getContainer())._getDelegate().getMofId()), end.getName()); } } // for indexTags = (List) indexes.get (cls); if (indexTags != null) { try { sc.buildAdditionalIndexes (indexTags, associationProxies); } catch (StorageException e) { throw new DebugException ("Storage exception: " + e); } } } // for Class iface[] = new Class[1]; for (Iterator it = localClassProxies.iterator(); it.hasNext();) { sc = (StorableClass) it.next(); try { iface[0] = null; sc.initInstanceSuperclass(iface); sc.initClassSuperclass(null); } catch (Exception e) { throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); } } } /** * @param metaPackage * @param newPackage * @param clusteredInstances * @param localClassProxies * @param localAssocProxies */ private void instantiatePackageContent(MofPackage metaPackage, StorablePackage newPackage, Map clusteredInstances, List localClassProxies, Set localAssocProxies, String storageId) { Iterator superTypes = metaPackage.allSupertypes().iterator(); boolean thisTypeNotProcessed = true; while (thisTypeNotProcessed || superTypes.hasNext()) { Iterator it; if (thisTypeNotProcessed) { it = metaPackage.getContents().iterator(); thisTypeNotProcessed = false; } else it = ((MofPackage) superTypes.next()).getContents().iterator(); while (it.hasNext()) { Object o = it.next(); ModelElement element = (ModelElement) o; if (element instanceof MofClass) { createClassProxyHandler((MofClass) element, newPackage, localClassProxies); } else if (element instanceof Association) { Association assoc = (Association) element; Collection content = assoc.getContents(); int i = 0; AssociationEnd ends[] = new AssociationEnd[2]; for(Iterator cit = content.iterator(); i < 2 && cit.hasNext();) { ModelElement containedElement = (ModelElement) cit.next(); if (containedElement instanceof AssociationEnd) { ends[i++] = (AssociationEnd) containedElement; } } // Change multiplicities 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(); maxB = ends[1].getMultiplicity().getUpper(); try { typeA = BaseObjectHandler.resolveInterface(TagSupport.getDataTypeName((StorableObject)((InstanceHandler)ends[0].getType())._getDelegate())); typeB = BaseObjectHandler.resolveInterface(TagSupport.getDataTypeName((StorableObject)((InstanceHandler)ends[1].getType())._getDelegate())); } catch (java.lang.Exception e) { throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); } orderA = (ends[0].getMultiplicity().isOrdered()); 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 (TagSupport.getTagValue((StorableObject) ((BaseObjectHandler) ends[0].getType())._getDelegate(), TRANSIENT_TAG_ID, "").equals(TAG_VALUE_TRUE) || TagSupport.getTagValue((StorableObject) ((BaseObjectHandler) ends[1].getType())._getDelegate(), TRANSIENT_TAG_ID, "").equals(TAG_VALUE_TRUE)) { createTransientAssociationHandler((Association) element, newPackage, ends[0].getName(), ((BaseObjectHandler)ends[0])._getDelegate().getMofId(), ends[1].getName(),((BaseObjectHandler)ends[1])._getDelegate().getMofId(), typeA, typeB, minA, maxA, minB, maxB, orderA, orderB, uniqueA, uniqueB, aggrA, aggrB, localAssocProxies); } else { createAssociationHandler((Association) element, newPackage, ends[0].getName(), ((BaseObjectHandler)ends[0])._getDelegate().getMofId(), ends[1].getName(), ((BaseObjectHandler)ends[1])._getDelegate().getMofId(), typeA, typeB, minA, maxA, minB, maxB, orderA, orderB, uniqueA, uniqueB, aggrA, aggrB, indexedA, indexedB, localAssocProxies); } } else if (element instanceof MofPackage) { // Logger.getDefault().log("found inner package"); // Logger.getDefault().log("creating: META: " + element.refMofId() + ", IMMEDIATE: " + newPackage.refMofId() + ", CONTEXT: " + context); StorablePackage pkg = createPackageHandler((MofPackage) element, newPackage, null, storageId, false); instantiatePackageContent((MofPackage) element, pkg, clusteredInstances, localClassProxies, localAssocProxies, storageId); } else if (element instanceof Import) { Import imp = (Import) element; ModelElement metaElement = imp.getImportedNamespace(); if (metaElement instanceof MofPackage) { MofPackage metaPkg = (MofPackage) metaElement; collectDTDescriptors(storageId, metaPkg, new HashSet()); if (imp.isClustered()) { RefPackage pkg = (RefPackage) clusteredInstances.get(((BaseObjectHandler)metaPkg)._getDelegate().getMofId()); if (pkg == null) { pkg = instantiatePackage(null, newPackage, metaPkg, clusteredInstances, storageId, true); clusteredInstances.put(((BaseObjectHandler)metaPkg)._getDelegate().getMofId(), pkg); } else { collectAllProxies(pkg); } try { newPackage.clusterPackage(imp.getName(), ((BaseObjectHandler)pkg)._getDelegate().getMofId()); } catch (StorageException e) { throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); } } // if } else if (metaElement instanceof EnumerationType) { createDTDescriptor(storageId, (EnumerationType) metaElement); } else if (metaElement instanceof StructureType) { createDTDescriptor(storageId, (StructureType) metaElement); } else if (metaElement instanceof MofClass) { collectDTDescriptors(storageId, (MofClass) metaElement, new HashSet()); } } // if } // while } // while } private void collectDTDescriptors(String storageId, GeneralizableElement metaElement, Set visited) { Iterator superTypes = metaElement.allSupertypes().iterator(); boolean thisTypeNotProcessed = true; while (thisTypeNotProcessed || superTypes.hasNext()) { Iterator it; if (thisTypeNotProcessed) { it = metaElement.getContents().iterator(); thisTypeNotProcessed = false; } else { GeneralizableElement ge = (GeneralizableElement) superTypes.next(); if (!visited.add(ge)) continue; it = ge.getContents().iterator(); } collectDTDescriptors(storageId, it, visited); } } private void collectDTDescriptors(String storageId, Iterator it, Set visited) { while (it.hasNext()) { Object element = it.next(); if (element instanceof MofPackage || element instanceof MofClass) { if (visited.add(element)) { collectDTDescriptors(storageId, (GeneralizableElement) element, visited); } } else if (element instanceof EnumerationType) { createDTDescriptor(storageId, (EnumerationType) element); } else if (element instanceof StructureType) { createDTDescriptor(storageId, (StructureType) element); } } } /** * Fills {@link #associationProxies}, {@link #classProxies} and * {@link #classProxiesMofIds} with the proxies contained in pkg * and all nested packages. * * @param pkg the package for which to collect all proxies */ private void collectAllProxies(RefPackage pkg) { for (Iterator it = pkg.refAllAssociations().iterator(); it.hasNext();) { RefAssociation assoc = (RefAssociation) it.next(); if (associationProxies.put(((BaseObjectHandler)assoc.refMetaObject())._getDelegate().getMofId(), ((BaseObjectHandler)assoc)._getDelegate().getMofId()) != null) { // this package was already collected return; } } for (Iterator it = pkg.refAllClasses().iterator(); it.hasNext();) { RefClass cls = (RefClass) it.next(); if (classProxiesMofIds.put(((BaseObjectHandler)cls.refMetaObject())._getDelegate().getMofId(), ((BaseObjectHandler)cls)._getDelegate().getMofId()) != null) { // this package was already collected return; } classProxies.put(cls.refMetaObject(), ((BaseObjectHandler) cls)._getDelegate()); } for (Iterator it = pkg.refAllPackages().iterator(); it.hasNext();) { collectAllProxies((RefPackage) it.next()); } } /* -------------------------------------------------------------------- */ /* -- Helper methods for handler creation (private) ------------------- */ /* -------------------------------------------------------------------- */ // --- creators /** Creates handler for Package Proxy */ private StorablePackage createPackageHandler(MofPackage metaObject,StorablePackage immediatePackage, String context, String storageId, boolean clustered) { try { Map datatypes = new HashMap(); // collect datatypes Iterator supers = null; while (supers == null || supers.hasNext()) { MofPackage metaPackage; if (supers == null) { supers = metaObject.allSupertypes().iterator(); metaPackage = metaObject; } else { metaPackage = (MofPackage) supers.next(); } for (Iterator it = metaPackage.getContents().iterator(); it.hasNext();) { ModelElement element = (ModelElement) it.next(); if (element instanceof EnumerationType) { datatypes.put(element.getName(), createDTDescriptor(storageId, (EnumerationType) element)); } else if (element instanceof StructureType) { datatypes.put(element.getName(), createDTDescriptor(storageId, (StructureType) element)); } } } StorablePackage result = null; if (storageId != null) { result = new StorablePackage(mdrStorage, immediatePackage == null ? null : immediatePackage.getMofId(), ((BaseObjectHandler)metaObject)._getDelegate().getMofId(), context, datatypes, storageId); } else { result = new StorablePackage(mdrStorage, immediatePackage == null ? null : immediatePackage.getMofId(), ((BaseObjectHandler)metaObject)._getDelegate().getMofId(), context, datatypes); } if (immediatePackage != null && !clustered) { immediatePackage.addPackage(metaObject.getName(), result.getMofId()); } return result; } catch ( StorageException e ) { throw new DebugException("Storage exception: " + e.getMessage()); } } private DatatypeDescriptor createDTDescriptor(String storageId, EnumerationType enum) { List members = new ArrayList(enum.getLabels()); String ifcName = TagSupport.getTypeFullName((StorableObject) ((BaseObjectHandler) enum)._getDelegate()); return new DatatypeDescriptor(mdrStorage, members, ifcName, storageId); } private DatatypeDescriptor createDTDescriptor(String storageId, StructureType struct) { ModelElement me; List members = new ArrayList(); List memberTypes = new ArrayList(); for (Iterator it2 = struct.getContents().iterator(); it2.hasNext();) { me = (ModelElement) it2.next(); if (me instanceof StructureField) { members.add(me.getName()); try { memberTypes.add(BaseObjectHandler.resolveInterface(TagSupport.getDataTypeName((StorableObject) ((BaseObjectHandler) ((StructureField) me).getType())._getDelegate()))); } catch (ClassNotFoundException e) { throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); } } } String ifcName = TagSupport.getTypeFullName((StorableObject) ((BaseObjectHandler) struct)._getDelegate()); return new DatatypeDescriptor(mdrStorage, struct.getQualifiedName(), members, memberTypes, ifcName, storageId); } /** Creates handler for Class Proxy */ private StorableClass createClassProxyHandler(MofClass metaObject, StorablePackage immediatePackage, List localClassProxies) { ModelElement element; StorableClass storable; boolean classDerived = false; boolean instanceDerived = false; boolean isDerived = false; try { ArrayList attrDescs = new ArrayList(); ArrayList clAttrDescs = new ArrayList(); Map datatypes = new HashMap(); // create attribute indexes, collect information about attributes and references for (Iterator it = metaObject.getContents().iterator(); it.hasNext();) { element = (ModelElement) it.next(); if (element instanceof Attribute) { Attribute attr = (Attribute) element; isDerived = attr.isDerived(); if (!isDerived) { Class type; try { type = BaseObjectHandler.resolveInterface(TagSupport.getDataTypeName((StorableObject)((InstanceHandler)attr.getType())._getDelegate())); } catch (java.lang.Exception e) { throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); } AttributeDescriptor desc = new AttributeDescriptor(mdrStorage, ((BaseObjectHandler)attr)._getDelegate().getMofId(), attr.getName(), type, attr.getMultiplicity().getLower(), attr.getMultiplicity().getUpper(), attr.getMultiplicity().isUnique(), attr.getMultiplicity().isOrdered(), attr.isChangeable(), MdrStorage.getStorageIdFromMofId(immediatePackage.getMofId())); if (ScopeKindEnum.INSTANCE_LEVEL.equals(attr.getScope())) { attrDescs.add(desc); } else { clAttrDescs.add(desc); } } } else if (element instanceof Operation) { isDerived = true; } else { 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()))); } 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) { members.add(me.getName()); try { memberTypes.add(BaseObjectHandler.resolveInterface(TagSupport.getDataTypeName((StorableObject) ((BaseObjectHandler) ((StructureField) me).getType())._getDelegate()))); } catch (ClassNotFoundException e) { throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); } } } String ifcName = TagSupport.getTypeFullName((StorableObject) ((BaseObjectHandler) element)._getDelegate()); datatypes.put(element.getName(), new DatatypeDescriptor(mdrStorage, element.getQualifiedName(), members, memberTypes, ifcName, MdrStorage.getStorageIdFromMofId(immediatePackage.getMofId()))); } isDerived = false; } if (isDerived) { if (((Feature) element).getScope().equals(ScopeKindEnum.CLASSIFIER_LEVEL)) { classDerived = true; } else { instanceDerived = true; } } } String tagValue = TagSupport.getTagValue((StorableObject) ((BaseObjectHandler) metaObject)._getDelegate(), TRANSIENT_TAG_ID, ""); if (tagValue.equals(TAG_VALUE_TRUE)) { storable = new TransientStorableClass(mdrStorage, immediatePackage.getMofId(), ((BaseObjectHandler)metaObject)._getDelegate().getMofId(), attrDescs, clAttrDescs, datatypes, classDerived, instanceDerived, metaObject.isSingleton(), metaObject.isAbstract()); } else { storable = new StorableClass(mdrStorage, immediatePackage.getMofId(), ((BaseObjectHandler)metaObject)._getDelegate().getMofId(), attrDescs, clAttrDescs, datatypes, classDerived, instanceDerived, metaObject.isSingleton(), metaObject.isAbstract()); } immediatePackage.addClass(metaObject.getName(), storable.getMofId()); classProxies.put(metaObject, storable); classProxiesMofIds.put(((BaseObjectHandler)metaObject)._getDelegate().getMofId(), storable.getMofId()); localClassProxies.add(storable); return storable; } catch ( StorageException e ) { throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); } } /** Creates handler for Association */ private StorableAssociation createAssociationHandler(Association metaObject, StorablePackage immediatePackage, String assocationEnd1, MOFID assocEnd1MofId, String assocationEnd2, MOFID 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(), ((BaseObjectHandler)metaObject)._getDelegate().getMofId(), 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(((BaseObjectHandler)metaObject)._getDelegate().getMofId(), result.getMofId()); localAssocProxies.add(result.getMofId()); return result; } catch ( StorageException e ) { throw new DebugException("Storage exception: " + e); } } private StorableAssociation createTransientAssociationHandler(Association metaObject, StorablePackage immediatePackage, String assocationEnd1, MOFID assocEnd1MofId, String assocationEnd2, MOFID 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(), ((BaseObjectHandler)metaObject)._getDelegate().getMofId(), assocationEnd1, assocEnd1MofId, assocationEnd2, assocEnd2MofId, type1, type2, min1, max1, min2, max2, isOrdered1, isOrdered2, isUnique1, isUnique2, isAggr1, isAggr2); immediatePackage.addAssociation(metaObject.getName(), result.getMofId()); associationProxies.put(((BaseObjectHandler)metaObject)._getDelegate().getMofId(), result.getMofId()); localAssocProxies.add(result.getMofId()); return result; } catch ( StorageException e ) { throw new DebugException("Storage exception: " + e); } } /* -------------------------------------------------------------------- */ /* -- Methods for bootstrapping (private) ----------------------------- */ /* -------------------------------------------------------------------- */ /** * Main bootstrapping method. */ private void boot() { boolean fail = true; Logger.getDefault().log( "Booting repository ..." ); mdrStorage.setBooting(true); beginTrans(true); try { installFakeMof(); installPureMof(); fail = false; } catch (Throwable e) { Logger.getDefault().notify(Logger.INFORMATIONAL, e); } finally { mdrStorage.setBooting(false); endTrans(fail); } } /** Installs the fake MOF */ private void installFakeMof() { Logger.getDefault().log("Creating boot MOF metamodel ..."); 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() { Logger.getDefault().log("Installing pure MOF Metamodel ... "); try { Logger.getDefault().log("Parsing MOF model to DOM represtentation ...."); ModelPackage modelPackage = (ModelPackage) createExtent(PURE_MOF, getBMModelPackage()); XmiReader xmiReader = (XmiReader) Lookup.getDefault().lookup(XmiReader.class); xmiReader.read(MOF_XML_URL.toString(), modelPackage); mdrStorage.rebuildMofContext(); } catch (Exception e) { throw (DebugException) Logger.getDefault().annotate(new DebugException("Boot failed."), e); } } /** * Returns the MOF Model package as a model element of the * bootstrapping MOF model. Needed only during bootstrapping. * *

[PENDING]: Common code of this method and of {@link #getMOFModelPackage()} * should be factored out. */ private MofPackage getBMModelPackage() { MofPackage result; for (Iterator it = ((ModelPackage) getExtent(BOOT_MOF)).getMofPackage().refAllOfClass().iterator(); it.hasNext();) { result = (MofPackage) it.next(); if (result.getName().equals("Model")) { return result; } } return null; } /** Reads the XMI description of the mof directly into reporitory */ private void createBootMOF() { try { BootReader br = new BootReader(mdrStorage, BOOTMOF_XML_URL); br.read(); } catch (Exception e) { throw (DebugException) Logger.getDefault().annotate(new DebugException("Unable to read MOF XMI: " + e.getMessage()), e); } } /* --------------------------------------------------------------------- */ /* -- FacilityCache (static inner class) ------------------------------- */ /* --------------------------------------------------------------------- */ /** Weak cache for created Handlers */ private static class FacilityCache extends HashMap { private final ReferenceQueue queue = new ReferenceQueue(); private boolean cleaningUp = false; private class HandlerReference extends WeakReference { private MOFID mofId; // hard reference on an element when it should not be garbagecollected private RefBaseObject baseObject; public HandlerReference(BaseObjectHandler handler) { super(handler, queue); mofId = handler._getMofId(); if (handler.refImmediatePackage() instanceof javax.jmi.model.ModelPackage || !(handler instanceof RefObject)) { // the object is from a metamodel or it is a proxy => we will keep "hard" reference baseObject = handler; } else { // the object is not a metamodel object => we will not keep "hard" reference on it baseObject = null; } } public MOFID getProxyMofId() { return mofId; } } private void cleanUp() { assert !cleaningUp; HandlerReference reference; cleaningUp = true; try { while ((reference = (HandlerReference) queue.poll()) != null) { // Logger.getDefault().log("Removing: " + reference.getProxyMofId()); MOFID mofId = reference.getProxyMofId(); java.lang.ref.Reference currentRef = (java.lang.ref.Reference) super.remove(mofId); if (currentRef != null && currentRef != reference && currentRef.get() != null) { super.put(mofId, currentRef); } } } finally { cleaningUp = false; } } public Object put(Object key, Object value) { cleanUp(); Object result = super.put(key, new HandlerReference((BaseObjectHandler) value)); assert result == null || ((HandlerReference) result).get() == null : "replacing non-null reference"; return null; } public Object remove(Object key) { cleanUp(); Object result = super.remove(key); return result == null ? null : ((HandlerReference) result).get(); } public Object get(Object key) { cleanUp(); Object result = super.get(key); return result == null ? null : ((HandlerReference) result).get(); } } /* --------------------------------------------------------------------- */ /* -- ShutdownListener ------------------------------------------------- */ /* --------------------------------------------------------------------- */ public interface ShutdownListener { public void shutdown(); public void stepFinished(); } }

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.