blob: ced0f6773c84a1e89556b3bdc5dfb026205cbdbb [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2005, 2006 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
****************************************************************************/
package org.eclipse.gmf.runtime.emf.type.core.internal.impl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.gmf.runtime.common.core.util.Log;
import org.eclipse.gmf.runtime.emf.type.core.IClientContext;
import org.eclipse.gmf.runtime.emf.type.core.IContainerDescriptor;
import org.eclipse.gmf.runtime.emf.type.core.IElementMatcher;
import org.eclipse.gmf.runtime.emf.type.core.IElementType;
import org.eclipse.gmf.runtime.emf.type.core.IElementTypeDescriptor;
import org.eclipse.gmf.runtime.emf.type.core.IMetamodelType;
import org.eclipse.gmf.runtime.emf.type.core.ISpecializationType;
import org.eclipse.gmf.runtime.emf.type.core.ISpecializationTypeDescriptor;
import org.eclipse.gmf.runtime.emf.type.core.edithelper.IEditHelperAdvice;
import org.eclipse.gmf.runtime.emf.type.core.internal.EMFTypePlugin;
import org.eclipse.gmf.runtime.emf.type.core.internal.EMFTypePluginStatusCodes;
import org.eclipse.gmf.runtime.emf.type.core.internal.descriptors.AdviceBindingDescriptor;
import org.eclipse.gmf.runtime.emf.type.core.internal.descriptors.AdviceBindingInheritance;
import org.eclipse.gmf.runtime.emf.type.core.internal.descriptors.ElementTypeDescriptor;
import org.eclipse.gmf.runtime.emf.type.core.internal.descriptors.IEditHelperAdviceDescriptor;
import org.eclipse.gmf.runtime.emf.type.core.internal.descriptors.MetamodelDescriptor;
import org.eclipse.gmf.runtime.emf.type.core.internal.descriptors.MetamodelTypeDescriptor;
import org.eclipse.gmf.runtime.emf.type.core.internal.descriptors.SpecializationTypeDescriptor;
import org.eclipse.gmf.runtime.emf.type.core.internal.l10n.EMFTypeCoreMessages;
/**
* Registry of specialization types populated by the
* <code>ElementTypeRegistry</code>. Keeps track of the specializations and
* advice bindings and provides methods for finding matching edit helper advice.
* <P>
* This class is for internal use only.
*
* @author ldamus
*/
public class SpecializationTypeRegistry {
/**
* Set containing the ALL advice binding inheritance.
*/
private final static Set ALL = Collections
.singleton(AdviceBindingInheritance.ALL);
/**
* Set containing the ALL and NONE advice binding inheritance.
*/
private final static Set ALL_NONE = new HashSet(
Arrays
.asList(new AdviceBindingInheritance[] {
AdviceBindingInheritance.NONE,
AdviceBindingInheritance.ALL }));
/**
* Specialization type descriptors stored by ID. Each value is a
* <code>SpecializationTypeDescriptor</code>.
*/
private final Map specializationTypeDescriptors;
/**
* Specialization type descriptors stored by the ID of the type that has
* been specialized. Each value is a Set of type descriptors for the types
* that specialize the key type ID.
*/
private final Map specializationsForTypeId;
/**
* Edit helper advice stored by target element type ID. Each value is a set
* of IEditHelperAdviceDescriptors.
*/
private final Map adviceBindings;
/**
* Constructs a new specialization type registry.
*/
public SpecializationTypeRegistry() {
super();
specializationTypeDescriptors = new HashMap();
specializationsForTypeId = new HashMap();
adviceBindings = new HashMap();
}
/**
* Registers <code>specializationType</code> if it has a unique ID in the
* registry.
*
* @param specializationType
* the element type
* @return <code>true</code> if the element type was registered,
* <code>false</code> otherwise.
*/
public boolean registerSpecializationType(ISpecializationType specializationType) {
if (specializationType == null
|| specializationTypeDescriptors.containsKey(specializationType
.getId())) {
return false;
}
SpecializationTypeDescriptor descriptor = new SpecializationTypeDescriptor(
specializationType);
return registerSpecializationType(descriptor);
}
/**
* Registers the specialization element type described by
* <code>configElement</code>.
*
* @param configElement
* the configutation element
* @param metamodelDescriptor
* the descriptor for the metamodel containing the EClass for the
* new element type
* @return the new specialization type descriptor if it has been registered,
* <code>null</code> otherwise.
*
* @throws CoreException
* on any problem accessing a configuration element
*/
public SpecializationTypeDescriptor registerSpecializationType(
IConfigurationElement configElement,
MetamodelDescriptor metamodelDescriptor)
throws CoreException {
SpecializationTypeDescriptor descriptor = new SpecializationTypeDescriptor(
configElement, metamodelDescriptor);
boolean wasRegistered = registerSpecializationType(descriptor);
return wasRegistered ? descriptor
: null;
}
/**
* Registers <code>descriptor</code> if it has a unique ID in the
* registry.
*
* @param descriptor
* @return <code>true</code> if the element was registered,
* <code>false</code> otherwise.
*/
private boolean registerSpecializationType(
SpecializationTypeDescriptor descriptor) {
if (checkForDuplicate(descriptor)) {
return false;
}
// Put the type in the main specialization map.
specializationTypeDescriptors.put(descriptor.getId(), descriptor);
// Register its edit helper advice
IEditHelperAdviceDescriptor editHelperAdvice = descriptor
.getEditHelperAdviceDescriptor();
if (editHelperAdvice != null) {
register(editHelperAdvice);
}
// Put the type in the map of specialized types for a given ID
String[] specializedTypes = descriptor.getSpecializationTypeIds();
for (int i = 0; i < specializedTypes.length; i++) {
Set specializations = (Set) specializationsForTypeId
.get(specializedTypes[i]);
if (specializations == null) {
specializations = new HashSet();
specializationsForTypeId.put(specializedTypes[i],
specializations);
}
specializations.add(descriptor);
}
return true;
}
/**
* Loads the edit helper advice binding described by
* <code>configElement</code>.
*
* @param configElement
* the configutation element
* @throws CoreException
* on any problem accessing a configuration element
*/
public void registerAdviceBinding(IConfigurationElement configElement,
MetamodelDescriptor metamodelDescriptor)
throws CoreException {
IEditHelperAdviceDescriptor descriptor = new AdviceBindingDescriptor(
configElement, metamodelDescriptor);
register(descriptor);
}
/**
* Registers the descriptor with the advice bindings for the target ID.
*
* @param descriptor
* the edit helper advice descriptor
*/
private void register(IEditHelperAdviceDescriptor descriptor) {
String targetId = descriptor.getTypeId();
Set bindings = (Set) adviceBindings.get(targetId);
if (bindings == null) {
bindings = new HashSet();
adviceBindings.put(targetId, bindings);
}
bindings.add(descriptor);
}
/**
* Removes the specialization type <code>specializationTypeDescriptor</code>.
*
* @param specializationTypeDescriptor
* the specialization type to remove
*/
public void removeSpecializationType(
SpecializationTypeDescriptor specializationTypeDescriptor) {
specializationTypeDescriptors.remove(specializationTypeDescriptor.getId());
String[] specializedTypes = specializationTypeDescriptor
.getSpecializationTypeIds();
for (int j = 0; j < specializedTypes.length; j++) {
Set specializations = (Set) specializationsForTypeId
.get(specializedTypes[j]);
specializations.remove(specializationTypeDescriptor);
}
}
/**
* Gets a list containing the immediate specializations of <code>type</code>.
*
* @param type
* the element type for which to find specializations
* @param clientContext
* the client context
* @return the list of all <code>SpecializationTypeDescriptor</code> s of
* <code>type</code>
*/
private List getImmediateSpecializationTypeDescriptors(
ElementTypeDescriptor type, IClientContext clientContext) {
return getSpecializationTypeDescriptors(type, false, clientContext);
}
/**
* Gets a list containing all specializations of <code>type</code>, in
* breadth-first order.
*
* @param type
* the element type
* @param clientContext
* the client context
* @return the array of all specializations of <code>type</code>
*/
public ISpecializationType[] getAllSpecializationTypes(
IElementTypeDescriptor type, IClientContext clientContext) {
List descriptors = getSpecializationTypeDescriptors(type, true, clientContext);
ISpecializationType[] result = new ISpecializationType[descriptors.size()];
int index = 0;
for (Iterator i = descriptors.iterator(); i.hasNext(); index++) {
SpecializationTypeDescriptor next = (SpecializationTypeDescriptor) i.next();
result[index] = (ISpecializationType) next.getElementType();
}
return result;
}
/**
* Gets a list containing all specializations of <code>type</code>, in
* breadth-first order.
*
* @param type
* the element type
* @param clientContext
* the client context
* @return the list of all specializations of <code>type</code>
*/
private List getAllSpecializationTypeDescriptors(
IElementTypeDescriptor type, IClientContext clientContext) {
return getSpecializationTypeDescriptors(type, true, clientContext);
}
/**
* Gets a list containing the descriptors for specializations of
* <code>type</code>, in breadth-first order. There are no duplicates in
* the list.
*
* @param type
* the element type
* @param deep
* <code>true</code> if all specializations are to be found,
* recursively, <code>false</code> if only the immediate
* (direct) specializations are to be found.
* @return the collection of <code>SpecializationTypeDescriptors</code> of
* <code>type</code>
*/
private List getSpecializationTypeDescriptors(IElementTypeDescriptor type,
boolean deep, IClientContext clientContext) {
LinkedHashSet result = new LinkedHashSet();
if (type != null) {
// Get the immediate specializations
Set specializationDescriptors = (Set) specializationsForTypeId.get(type
.getId());
if (specializationDescriptors != null) {
Set specializations = new HashSet();
for (Iterator i = specializationDescriptors.iterator(); i.hasNext();) {
SpecializationTypeDescriptor nextDescriptor = (SpecializationTypeDescriptor) i
.next();
if (clientContext.includes(nextDescriptor)) {
if (nextDescriptor != null) {
specializations.add(nextDescriptor);
if (deep) {
// Recursively search for specializations
result.addAll(getSpecializationTypeDescriptors(
nextDescriptor, deep, clientContext));
}
}
}
}
// Add the immediate specializations last, so that a breadth-first
// order is maintained
result.addAll(specializations);
}
}
return new ArrayList(result);
}
/**
* Gets the array of specialization types that match <code>eObject</code>,
* in order of decreasing specialization.
* <P>
* Returns an empty list if the <code>clientContext</code> is not bound to
* the <code>metamodelTypeDescriptor</code>.
*
* @param eObject
* the model element for which to find specializations
* @param metamodelTypeDescriptor
* the metamodel type descriptor for <code>eObject</code>
* @return the list of <code>SpecializationTypeDescriptor</code> s that
* match <code>eObject</code>
*/
public List getSpecializationDescriptorsMatching(EObject eObject,
MetamodelTypeDescriptor metamodelTypeDescriptor, IClientContext clientContext) {
List result = new ArrayList();
// Get all of the specializations of the metamodel type that matches the
// eObject
List specializations = getAllSpecializationTypeDescriptors(
metamodelTypeDescriptor, clientContext);
// Get the edit helper specialization descriptors that have matching
// advice
for (Iterator i = specializations.iterator(); i.hasNext();) {
SpecializationTypeDescriptor nextDescriptor = (SpecializationTypeDescriptor) i
.next();
IEditHelperAdviceDescriptor adviceDescriptor = nextDescriptor
.getEditHelperAdviceDescriptor();
if (adviceDescriptor != null) {
// See if the advice from this descriptor matches the model
// element
if (adviceMatches(eObject, adviceDescriptor)) {
result.add(nextDescriptor);
}
} else {
// No restrictions
result.add(nextDescriptor);
}
}
return result;
}
/**
* Gets the list of specializations of <code>type</code> whose matching
* criteria match the given <code>eContainer</code> and
* <code>reference</code>.
* <P>
* Returns an empty list if the <code>clientContext</code> is not bound to
* the <code>type</code>.
*
* @param type
* the element type
* @param eContainer
* the container
* @param reference
* the reference feature.
* @param clientContext
* the client context
* @return the list of matching specializations
*/
public List getMatchingSpecializations(ElementTypeDescriptor type,
EObject eContainer, EReference reference, IClientContext clientContext) {
List result = new ArrayList();
// Get the specializations of the element type that match the given
// feature of the container
List matchingSpecializations = getSpecializationDescriptorsMatching(
type, eContainer, reference, clientContext);
result.addAll(matchingSpecializations);
// Repeat for only the matching specializations
for (Iterator i = matchingSpecializations.iterator(); i.hasNext();) {
result.addAll(getMatchingSpecializations((ElementTypeDescriptor) i
.next(), eContainer, reference, clientContext));
}
return result;
}
/**
* Queries whether the specified edit helper advice descriptor matches an
* <code>eObject</code>.
*
* @param eObject
* the model element for which to find matching advice
* @param editHelperAdviceDescriptor
* an advice descriptor that may opr may not match <code>eObject</code>
* @return <code>true</code> if the advice matches; <code>false</code>, otherwise
*/
private boolean adviceMatches(EObject eObject,
IEditHelperAdviceDescriptor editHelperAdviceDescriptor) {
EReference containmentFeature = eObject.eContainmentFeature();
IContainerDescriptor container = editHelperAdviceDescriptor
.getContainerDescriptor();
if (container != null) {
IElementMatcher containerMatcher = container.getMatcher();
if (containerMatcher != null
&& !containerMatcher.matches(eObject.eContainer())) {
return false;
}
}
EReference[] features = null;
if (container != null) {
features = container.getContainmentFeatures();
}
if (features == null || features.length < 1) {
// All features that can contain this type's EClass are valid
IElementMatcher matcher = editHelperAdviceDescriptor.getMatcher();
return (matcher == null) || matcher.matches(eObject);
} else {
for (int j = 0; j < features.length; j++) {
if (features[j] == containmentFeature) {
IElementMatcher matcher = editHelperAdviceDescriptor
.getMatcher();
return (matcher == null) || matcher.matches(eObject);
}
}
}
return false;
}
/**
* Gets the list descriptors of the specializations that match the
* <code>eContainer</code> and <code>feature</code>.
*
* @param eContainer
* the container to match
* @param feature
* the containment feature to match
* @param clientContext
* the client context
* @return the list of <code>SpecializationTypeDescriptor</code> s that
* match
*/
private List getSpecializationDescriptorsMatching(
ElementTypeDescriptor typeDescriptor, EObject eContainer,
EReference feature, IClientContext clientContext) {
List result = new ArrayList();
Collection specializationDescriptors = getImmediateSpecializationTypeDescriptors(
typeDescriptor, clientContext);
for (Iterator i = specializationDescriptors.iterator(); i.hasNext();) {
SpecializationTypeDescriptor nextDescriptor = (SpecializationTypeDescriptor) i
.next();
if (!clientContext.includes(nextDescriptor)) {
// descriptor isn't bound to the client context
continue;
}
IContainerDescriptor container = nextDescriptor
.getContainerDescriptor();
// First, match the container
IElementMatcher containerMatcher = container != null ? container
.getMatcher()
: null;
if (containerMatcher != null
&& !containerMatcher.matches(eContainer)) {
continue;
}
// Second, match the containing feature(s)
EReference[] features = container != null ? container
.getContainmentFeatures()
: null;
if (features == null || features.length < 1) {
// All features that can contain this type's EClass are valid
EClass specializedType = nextDescriptor.getElementType()
.getEClass();
if (canContain(eContainer.eClass(), feature, specializedType)) {
result.add(nextDescriptor);
continue;
}
} else {
for (int j = 0; j < features.length; j++) {
if (features[j] == feature) {
result.add(nextDescriptor);
break;
}
}
}
}
return result;
}
/**
* Answers whether or not <code>container</code> can contain
* <code>contained</code> in its <code>reference</code> feature.
*
* @param container
* the container
* @param reference
* the reference feature
* @param contained
* the element to be contained
* @return <code>true</code> if <code>container</code> can contain
* <code>contained</code> in its <code>reference</code> feature,
* <code>false</code> otherwise.
*/
private boolean canContain(EClass container, EReference reference,
EClass contained) {
if ((reference.isContainment())
&& (container.getEAllReferences().contains(reference))) {
EClass eType = (EClass) reference.getEType();
if ((eType.equals(contained)) || (eType.isSuperTypeOf(contained))) {
return true;
}
}
return false;
}
/**
* Gets the edit helper advice bound to the <code>elementTypes</code> that
* match <code>eObject</code>. The advice will be that which is bound to
* the <code>clientContext</code>, and is ordered from most general
* advice (inherited from metamodel supertypes) to most specific advice
* (bound to specializations).
* <P>
* Returns an empty list if the <code>clientContext</code> is not bound to
* the <code>metamodelTypeDescriptor</code>.
*
* @param eObject
* the model element to match
* @param metamodelTypeDescriptor
* the metamodel type descriptor for the model element
* @param clientContext
* the client context
* @return the collection of matching <code>IEditHelperAdvice</code>.
*/
public List getEditHelperAdvice(EObject eObject,
MetamodelTypeDescriptor metamodelTypeDescriptor, IClientContext clientContext) {
LinkedHashSet result = new LinkedHashSet();
// Look at advice bound to the metamodel supertypes
IElementType[] metamodelSupertypes = metamodelTypeDescriptor
.getElementType().getAllSuperTypes();
for (int i = 0; i < metamodelSupertypes.length; i++) {
IElementType nextSupertype = metamodelSupertypes[i];
result.addAll(getMatchingAdvice(nextSupertype.getId(), eObject,
ALL, clientContext));
}
// Add the advice bound to the metamodel type
result.addAll(getMatchingAdvice(metamodelTypeDescriptor.getId(),
eObject, ALL_NONE, clientContext));
// Get the specializations that match
List specializationDescriptors = getSpecializationDescriptorsMatching(
eObject, metamodelTypeDescriptor, clientContext);
Collections.reverse(specializationDescriptors);
for (Iterator i = specializationDescriptors.iterator(); i.hasNext();) {
SpecializationTypeDescriptor nextSpecialization = (SpecializationTypeDescriptor) i
.next();
// Look for advice bound to the matching specialization type
result.addAll(getMatchingAdvice(nextSpecialization.getId(),
eObject, ALL_NONE, clientContext));
}
return new ArrayList(result);
}
/**
* Gets the edit helper advice bound to the <code>elementType</code> and
* the inheritable advice bounds to its supertypes. The advice will be that
* which is bound to the <code>clientContext</code>, and is ordered from
* most general advice (inherited from metamodel supertypes) to most
* specific advice (bound to specializations).
* <P>
* Returns an empty list if the <code>clientContext</code> is not bound to
* the <code>elementType</code>.
*
* @param elementType
* the element type whose bound edit helper advice will be
* considered
* @param metamodelTypeDescriptor
* the metamodel type descriptor for the eClass
* @param clientContext
* the client context
* @return the collection of matching <code>IEditHelperAdvice</code>.
*/
public List getEditHelperAdvice(IElementType elementType,
MetamodelTypeDescriptor metamodelTypeDescriptor, IClientContext clientContext) {
LinkedHashSet result = new LinkedHashSet();
String metamodelTypeId = (metamodelTypeDescriptor != null) ? metamodelTypeDescriptor.getId() : null;
// Look at advice bound to the supertypes
IElementType[] metamodelSupertypes = elementType.getAllSuperTypes();
for (int i = 0; i < metamodelSupertypes.length; i++) {
IElementType nextSupertype = metamodelSupertypes[i];
if (nextSupertype instanceof ISpecializationType || nextSupertype.getId().equals(metamodelTypeId)) {
result
.addAll(getMatchingAdvice(nextSupertype.getId(),
ALL_NONE, clientContext));
} else if (nextSupertype instanceof IMetamodelType) {
result.addAll(getMatchingAdvice(nextSupertype.getId(), ALL, clientContext));
}
}
// Add the advice bound to the element type itself
result.addAll(getMatchingAdvice(elementType.getId(), ALL_NONE, clientContext));
return new ArrayList(result);
}
/**
* Gets the edit helper advice bound to the element type with ID
* <code>elementTypeId</code> that matches <code>eObject</code>.
*
* @param elementTypeId
* the element type id
* @param eObject
* the model element to match
* @param considerApplicationToSubtypes
* <code>true</code> if only those advice bindings that apply
* to subtypes should be returned, <code>false</code>
* otherwise.
* @param clientContext
* the client context
* @return the list of matching <code>IEditHelperAdvice</code>
*/
private List getMatchingAdvice(String elementTypeId, EObject eObject,
Set adviceInheritanceToConsider, IClientContext clientContext) {
List result = new ArrayList();
for (Iterator j = getAdviceBindings(elementTypeId); j.hasNext();) {
IEditHelperAdviceDescriptor nextAdviceDescriptor = (IEditHelperAdviceDescriptor) j
.next();
if (clientContext.includes(nextAdviceDescriptor)) {
// Filter out any of the bound advice that doesn't match
if (!adviceMatches(eObject, nextAdviceDescriptor)) {
continue;
}
if (adviceInheritanceToConsider.contains(nextAdviceDescriptor
.getInheritance())) {
IEditHelperAdvice nextAdvice = nextAdviceDescriptor
.getEditHelperAdvice();
if (nextAdvice != null) {
result.add(nextAdvice);
}
}
}
}
return result;
}
/**
* Gets the edit helper advice bound to the element type with ID
* <code>elementTypeId</code> that matches <code>eObject</code>.
*
* @param elementTypeId
* the element type id
* @param considerApplicationToSubtypes
* <code>true</code> if only those advice bindings that apply
* to subtypes should be returned, <code>false</code>
* otherwise.
* @param clientContext
* the client context
* @return the list of matching <code>IEditHelperAdvice</code>
*/
private List getMatchingAdvice(String elementTypeId,
Set adviceInheritanceToConsider, IClientContext clientContext) {
List result = new ArrayList();
for (Iterator j = getAdviceBindings(elementTypeId); j.hasNext();) {
IEditHelperAdviceDescriptor nextAdviceDescriptor = (IEditHelperAdviceDescriptor) j
.next();
if (clientContext.includes(nextAdviceDescriptor)) {
if (adviceInheritanceToConsider.contains(nextAdviceDescriptor
.getInheritance())) {
IEditHelperAdvice nextAdvice = nextAdviceDescriptor
.getEditHelperAdvice();
if (nextAdvice != null) {
result.add(nextAdvice);
}
}
}
}
return result;
}
/**
* Obtains an iterator over the advices bound exactly to the specified element
* type ID and also to patterns matching the element type ID. Advice bindings
* are returned for all client contexts. The caller should filter the list
* by context.
* <p>
* <b>Note</b> for now, in the interest of simplicity and performance, the
* only pattern supported is <code>"*"</code> to match all element types.
* </p>
*
* @param elementTypeId the element type ID for which to get advice
*
* @return an immutable iterator of the advice bindings (cannot
* {@linkplain Iterator#remove() remove} from it)
*/
private Iterator getAdviceBindings(String elementTypeId) {
class MultiIterator implements Iterator {
private Iterator current;
private Collection[] collections;
private int index = 0;
MultiIterator(Collection[] collections) {
this.collections = collections;
current = nextIterator();
}
public boolean hasNext() {
while (current != null) {
if (current.hasNext()) {
return true;
}
current = nextIterator();
}
return false;
}
public Object next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return current.next();
}
public void remove() {
throw new UnsupportedOperationException();
}
private Iterator nextIterator() {
Iterator result = null;
while ((result == null) && (index < collections.length)) {
if (collections[index] != null) {
result = collections[index].iterator();
collections[index] = null; // free memory
}
index++;
}
return result;
}
}
return new MultiIterator(new Collection[] {
(Collection) adviceBindings.get(elementTypeId),
(Collection) adviceBindings.get("*") //$NON-NLS-1$
});
}
/**
* Gets the specialization type for a given ID.
*
* @param id
* the type ID
* @return the specialization type, or <code>null</code> if there is none
* registered with this ID.
*/
public SpecializationTypeDescriptor getSpecializationTypeDescriptor(
String id) {
return (SpecializationTypeDescriptor) specializationTypeDescriptors
.get(id);
}
/**
* Gets the collection of all registered specialization type descriptors.
*
* @return the registered specialization type descriptors. Each element in
* the collection is a <code>SpecializationTypeDescriptor</code>.
*/
public Collection getSpecializationTypeDescriptors() {
return specializationTypeDescriptors.values();
}
/**
* Gets the collection of all registered specialization type descriptors
* bound to the <code>clientContext</code>.
*
* @return the registered specialization type descriptors. Each element in
* the collection is a <code>SpecializationTypeDescriptor</code>.
*/
public Collection getSpecializationTypeDescriptors(
IClientContext clientContext) {
Collection result = new ArrayList();
for (Iterator i = getSpecializationTypeDescriptors().iterator(); i
.hasNext();) {
ISpecializationTypeDescriptor next = (ISpecializationTypeDescriptor) i
.next();
if (clientContext.includes(next)) {
result.add(next);
}
}
return result;
}
/**
* Checks to see if an element type with the same ID as
* <code>typeDescriptor</code> has already been registered.
*
* @param typeDescriptor
* @return <code>true</code> if the element type is duplicated,
* <code>false</code> otherwise.
*/
private boolean checkForDuplicate(ElementTypeDescriptor typeDescriptor) {
if (specializationTypeDescriptors.containsKey(typeDescriptor.getId())) {
Log
.error(
EMFTypePlugin.getPlugin(),
EMFTypePluginStatusCodes.TYPE_NOT_INITED,
EMFTypeCoreMessages
.bind(
EMFTypeCoreMessages.type_not_init_WARN_,
typeDescriptor.getId(),
EMFTypeCoreMessages.type_reason_duplicate_id_WARN_));
return true;
}
return false;
}
}