DescriptorRegistry.java :  » IDE-Netbeans » vmd.analyzer » org » netbeans » modules » vmd » api » model » Java Open Source

Java Open Source » IDE Netbeans » vmd.analyzer 
vmd.analyzer » org » netbeans » modules » vmd » api » model » DescriptorRegistry.java
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common
 * Development and Distribution License("CDDL") (collectively, the
 * "License"). You may not use this file except in compliance with the
 * License. You can obtain a copy of the License at
 * http://www.netbeans.org/cddl-gplv2.html
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
 * specific language governing permissions and limitations under the
 * License.  When distributing the software, include this License Header
 * Notice in each file and include the License file at
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the GPL Version 2 section of the License file that
 * accompanied this code. If applicable, add the following below the
 * License Header, with the fields enclosed by brackets [] replaced by
 * your own identifying information:
 * "Portions Copyrighted [year] [name of copyright owner]"
 *
 * Contributor(s):
 *
 * The Original Software is NetBeans. The Initial Developer of the Original
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
 * Microsystems, Inc. All Rights Reserved.
 *
 * If you wish your version of this file to be governed by only the CDDL
 * or only the GPL Version 2, indicate your decision by adding
 * "[Contributor] elects to include this software in this distribution
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
 * single choice of license, a recipient has the option to distribute
 * your version of this file under either the CDDL, the GPL Version 2 or
 * to extend the choice of license to its licensees as provided above.
 * However, if you add GPL Version 2 code and therefore, elected the GPL
 * Version 2 license, then the option applies only if the new code is
 * made subject to such option by the copyright holder.
 */
package org.netbeans.modules.vmd.api.model;

import org.openide.util.Mutex;
import org.openide.util.WeakSet;
import org.openide.util.Exceptions;

import java.util.*;

/**
 * This class represents a registry for all component descriptors that could be used in the document. The registry consists of
 * two parts: global registry, project-dependent registry.
 * <p>
 * For registering a component descriptor in global registry you have to put its instance to "vmd/components" folder in layer filesystem.
 * These descriptors will be available for all documents in all projects.
 * <p>
 * For registering a component descriptor in project-dependent registry it is fully up-to the project interface what directory
 * it supply as a source of descriptors (usually it will be nbproject/private/components folder). These component descriptors
 * will be available only for documents that are located in the project.
 * <p>
 * Each component descriptor is registered with the type id that is resolved by
 * ComponentDescriptor.getTypeDescriptor ().getThisType () method call.
 * This type id must be unique across all component descriptors. If there is a conflict of type ids,
 * the one from global registry wins. Otherwise there is no stable rule or priority defined.
 * <p>
 * When a registry is update/refreshed/changed all its document (that are using it) resolves a new component descriptors
 * for all their components. If a component descriptor could not be resolved for some component that the component we still
 * contain all property values and presenters but they will not be accessible/modifiable.
 *
 * @author David Kaspar
 */
// TODO - unique producers by their ids
public final class DescriptorRegistry {

    // TODO - where to store, project-dependent descriptor registry - layer/vmd/projects/project_id/components folder?

//    private String projectType;
//    private String projectID;

    private final Mutex mutex = new Mutex ();
    private final WeakSet<DescriptorRegistryListener> listeners = new WeakSet<DescriptorRegistryListener> ();
    private HashMap<TypeID, ComponentDescriptor> descriptors = new HashMap<TypeID, ComponentDescriptor> ();
    private ArrayList<ComponentProducer> producers = new ArrayList<ComponentProducer> ();
    private GlobalDescriptorRegistry globalDescriptorRegistry;
    private DescriptorRegistryListener listener = new DescriptorRegistryListener() {
        public void descriptorRegistryUpdated () {
            reload ();
        }
    };

    /**
     * Returns a descriptor registry for specific project type and project id
     * @param projectType the project type
     * @param projectID the project id
     * @return the descriptor registry
     */
    public static DescriptorRegistry getDescriptorRegistry (String projectType, String projectID) {
        return GlobalDescriptorRegistry.getGlobalDescriptorRegistry (projectType).getProjectRegistry (projectID);
    }

    DescriptorRegistry (GlobalDescriptorRegistry globalDescriptorRegistry) { //, String projectType, String projectID) {
        assert Debug.isFriend (GlobalDescriptorRegistry.class, "getProjectRegistry"); // NOI18N

//        this.projectType = projectType;
//        this.projectID = projectID;
        this.globalDescriptorRegistry = globalDescriptorRegistry; // GlobalDescriptorRegistry.getGlobalDescriptorRegistry (projectType);
        globalDescriptorRegistry.addRegistryListener (listener);
        reload ();
    }

    private boolean isAccess () {
        return mutex.isReadAccess () || mutex.isWriteAccess ();
    }

    /**
     * Executes a Runnable.run method with read access.
     * @param runnable the runnable
     */
    public void readAccess (final Runnable runnable) {
        globalDescriptorRegistry.readAccess (new Runnable () {
            public void run () {
                mutex.readAccess (runnable);
            }
        });
    }

    private void writeAccess (final Runnable runnable) {
        globalDescriptorRegistry.readAccess (new Runnable() {
            public void run () {
                mutex.writeAccess (runnable);
            }
        });
    }

    private void reload () {
        writeAccess (new Runnable() {
            public void run () {
                reloadCore ();
            }
        });
    }

    private void reloadCore () {
        // TODO - reload from project descriptor registry

        HashMap<TypeID, ComponentDescriptor> tempDescriptors = new HashMap<TypeID, ComponentDescriptor> ();
        ArrayList<ComponentProducer> tempProducers = new ArrayList<ComponentProducer> ();

        Collection<ComponentDescriptor> _descriptors = globalDescriptorRegistry.getComponentDescriptors ();
        for (ComponentDescriptor descriptor : _descriptors)
            tempDescriptors.put (descriptor.getTypeDescriptor ().getThisType (), descriptor);

        tempProducers.addAll (globalDescriptorRegistry.getComponentProducers ());

        this.descriptors = tempDescriptors;
        this.producers = tempProducers;

        for (DescriptorRegistryListener _listener : listeners) {
            try {
                _listener.descriptorRegistryUpdated ();
            } catch (Exception e) {
                Exceptions.printStackTrace (e);
            }
        }
    }

//    /**
//     * Checks whether all specified component type ids are available in the descriptor registry. If some is missing there,
//     * it tries to resolve it from the sources.
//     * @param componentTypes the collection of component type ids that has to be checked
//     */
//    public void assertComponentDescriptors (Collection<TypeID> componentTypes) {
//        writeAccess (new Runnable () {
//            public void run () {
//                // TODO
//            }
//        });
//    }

    /**
     * Returns a component descriptor for a specified type id.
     * @param componentType the component type id
     * @return the component descriptor
     */
    public ComponentDescriptor getComponentDescriptor (TypeID componentType) {
        assert isAccess ();
        if (componentType == null)
            return null;
        return descriptors.get (componentType);
    }

    public void removeComponentDescriptor(final TypeID componentType) {
        if (componentType != null)
            globalDescriptorRegistry.writeAccess(new RemoveComponentDescriptorTask(componentType));
    }

    // TODO - proxy for GlobalDescriptorRegistry and ProjectRegistry
    // HINT - always up-to-date when any method is called (synchronize/refresh before working)

    /**
     * Returns a collection of all registered component descriptors.
     * @return the collection of all registered component descriptors
     */
    public Collection<ComponentDescriptor> getComponentDescriptors () {
        assert isAccess ();
        return Collections.unmodifiableCollection (descriptors.values ());
    }

    /**
     * Returns a list of all registered component producers.
     * @return the list of all registered component producers
     */
    public List<ComponentProducer> getComponentProducers () {
        assert isAccess ();
        return Collections.unmodifiableList (producers);
    }

    /**
     * Adds a registry listener.
     * The DescriptorRegistryListener.descriptorRegistryUpdated method is called everytime the content of registry is changed.
     * @param listener the listener
     */
    public void addRegistryListener (final DescriptorRegistryListener listener) {
        writeAccess (new Runnable() {
            public void run () {
                listeners.add (listener);
                listener.descriptorRegistryUpdated ();
            }
        });
    }

    /**
     * Removes a registry listener.
     * @param listener the listener
     */
    public void removeRegistryListener (final DescriptorRegistryListener listener) {
        writeAccess (new Runnable() {
            public void run () {
                listeners.remove (listener);
            }
        });
    }

    /**
     * Checks whether a component descriptor is compatible (descriptor analogy of instanceof operator) with a type id.
     * Means: Specified component descriptor or its super descriptor has the same type id as the specified one.
     * @param typeID the type id
     * @param componentDescriptor the component descriptor
     * @return true if compatible
     */
    private boolean isComponentDescriptorCompatibleWithTypeID (TypeID typeID, ComponentDescriptor componentDescriptor) {
        assert isAccess ();
        if (typeID == null)
            return false;
        for (;;) {
            if (componentDescriptor == null)
                return false;
            TypeDescriptor typeDescriptor = componentDescriptor.getTypeDescriptor ();
            TypeID checked = typeDescriptor.getThisType ();
            if (checked == null)
                return false;
            if (checked.equals (typeID))
                return true;
            componentDescriptor = getComponentDescriptor (typeDescriptor.getSuperType ());
        }
    }

    /**
     * Checks whether specified superTypeID is super type id of specified derivedTypeID
     * @param superTypeID the super type id
     * @param derivedTypeID the possible derived typeid
     * @return true if the superTypeID is one of super type ids of the derivedTypeID
     */
    public boolean isInHierarchy (TypeID superTypeID, TypeID derivedTypeID) {
        return isComponentDescriptorCompatibleWithTypeID (superTypeID, getComponentDescriptor (derivedTypeID));
    }
    
    final class RemoveComponentDescriptorTask implements Runnable {

        private TypeID componentType;

        public RemoveComponentDescriptorTask(TypeID componentType) {
            this.componentType = componentType;
        }

        public void run() {
            globalDescriptorRegistry.removeComponentDescriptor(componentType);
        }
        
    }

}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.