blob: b6ccaf68f7f75b4c119498c3d48d2e8f719845e1 [file] [log] [blame]
/*
* Licensed Material - Property of IBM
* (C) Copyright IBM Corp. 2001, 2005 - All Rights Reserved.
* US Government Users Restricted Rights - Use, duplication or disclosure
* restricted by GSA ADP Schedule Contract with IBM Corp.
*/
package org.eclipse.jst.j2ee.model;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.WeakHashMap;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.jst.j2ee.internal.common.J2EECommonMessages;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.internal.emf.resource.CompatibilityXMIResource;
import org.eclipse.wst.common.internal.emfworkbench.WorkbenchResourceHelper;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.IProjectFacet;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
public class ModelProviderManager {
public static class ModelProviderKey {
protected IProjectFacetVersion version;
protected int priority;
public ModelProviderKey() {
super();
}
@Override
public boolean equals(Object aOther){
if( this == aOther )
return true;
ModelProviderKey otherKey = (ModelProviderKey)aOther;
if( version.equals( otherKey.version) )
return true;
return false;
}
@Override
public int hashCode() {
return version.hashCode();
}
}
private static class ResourceSetListener extends AdapterImpl {
/*
* @see Adapter#notifyChanged(new ENotificationImpl((InternalEObject)Notifier,
* int,(EStructuralFeature) EObject, Object, Object, int))
*/
@Override
public void notifyChanged(Notification notification) {
switch (notification.getEventType()) {
case Notification.ADD :
addedResource((Resource) notification.getNewValue());
break;
case Notification.REMOVE :
removedResource((Resource) notification.getOldValue());
break;
case Notification.REMOVE_MANY :
removedResources((List) notification.getOldValue());
break;
}
}
}
private static WeakHashMap modelsProviders = new WeakHashMap();
private static final int DEFAULT_PRIORITY = 100;
private static HashMap providers;
protected static HashMap resourceSetListeners;
/**
*
* @param
* @param
* @return IModelProvider for the given project of the given version, NULL if no IModelProvider exists for project, version pair
*/
public static IModelProvider getModelProvider(IProject project, IProjectFacetVersion vers) {
IModelProviderFactory factory = getProvider(vers);
if(factory != null){
startListeningToResourceSet(project);
return factory.create(project);
}
String errorMessage = J2EECommonMessages.getResourceString(
J2EECommonMessages.ERR_NO_MODEL_PROVIDER_FOR_PROJECT, new Object[] {project, vers});
Throwable error = new NullPointerException(errorMessage);
J2EEPlugin.logError(error);
return null;
}
/**
*
* @param
* @param
* @return IModelProvider for the given component of the given version, NULL if no IModelProvider exists for virtual component/version pair
*/
public static IModelProvider getModelProvider(IVirtualComponent aModule, IProjectFacetVersion vers) {
IModelProviderFactory factory = getProvider(vers);
if(factory != null){
IModelProvider mp = factory.create(aModule);
addProvider(mp);
return mp;
}
String errorMessage = J2EECommonMessages.getResourceString(
J2EECommonMessages.ERR_NO_MODEL_PROVIDER_FOR_PROJECT, new Object[] {aModule, vers});
Throwable error = new NullPointerException(errorMessage);
J2EEPlugin.logError(error);
return null;
}
private static void addProvider(IModelProvider mp) {
modelsProviders.put(mp, null);
}
/**
* Notify all editModels of the change.
*/
private static void addedResource(Resource addedResource) {
if ((addedResource != null) && (addedResource instanceof CompatibilityXMIResource))
((CompatibilityXMIResource) addedResource).setFormat(CompatibilityXMIResource.FORMAT_MOF5);
IProject proj = WorkbenchResourceHelper.getProject(addedResource);
IModelProviderEvent event = new ModelProviderEvent(IModelProviderEvent.ADDED_RESOURCE, null,proj);
event.addResource(addedResource);
notifyModelProviders(event);
}
/**
* Notify all editModels of the change.
*/
protected static void notifyModelProviders(IModelProviderEvent anEvent) {
if ((anEvent == null) || (modelsProviders.size() == 0))
return;
List aList = new ArrayList();
synchronized (modelsProviders) {
aList.addAll(modelsProviders.keySet());
}
for (int i = 0; i < aList.size(); i++) {
IModelProvider mod;
mod = (IModelProvider) aList.get(i);
try {
if (mod instanceof IModelProviderListener)
{
((IModelProviderListener)mod).modelsChanged(anEvent);
}
} catch (Exception e) {
J2EEPlugin.logError(e);
}
}
}
/**
* Notify all editModels of the change.
*/
private static void removedResource(Resource removedResource) {
IProject proj = WorkbenchResourceHelper.getProject(removedResource);
IModelProviderEvent event = new ModelProviderEvent(IModelProviderEvent.REMOVED_RESOURCE, null,proj);
event.addResource(removedResource);
notifyModelProviders(event);
}
/**
* Notify all editModels of the change.
*/
private static void removedResources(List removedResources) {
Resource firstRes = (Resource)removedResources.get(0);
IProject proj = WorkbenchResourceHelper.getProject(firstRes);
IModelProviderEvent event = new ModelProviderEvent(IModelProviderEvent.REMOVED_RESOURCE, null,proj);
event.addResources(removedResources);
notifyModelProviders(event);
}
/**
* Used to register an IModelProviderFactory against a facet version
*
* @param providerFactory
* - {@link IModelProviderFactory}
* @param v
* - {@link IProjectFacetVersion}
* @param priority
* - {@link String}- Used to allow multiple instances, the
* highest priority is chosen. Priority '0' is higher that
* priority '1'. If priorities are equal the new providerFactory
* is chosen.
*/
public static void registerProvider(IModelProviderFactory providerFactory, IProjectFacetVersion v, String priority) {
int newPriority = (priority != null) ? Integer.parseInt(priority) : DEFAULT_PRIORITY;
int currentPriority = getProviderPriority(v);
if (newPriority <= currentPriority) {
ModelProviderKey key = createProviderKey(v, newPriority);
getProviders().put(key, providerFactory);
}
}
private static IModelProviderFactory getProvider(IProjectFacetVersion v) {
Set<ModelProviderKey> keys = getProviders().keySet();
for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
ModelProviderKey key = (ModelProviderKey) iterator.next();
if (key.version.equals(v))
return (IModelProviderFactory)providers.get(key);
}
return null;
}
public static IModelProviderFactory getProvider(IProject p) {
IProjectFacetVersion facetVersion = getDefaultFacet(p);
return getProvider(facetVersion);
}
private static int getProviderPriority(IProjectFacetVersion v) {
Set<ModelProviderKey> keys = getProviders().keySet();
for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
ModelProviderKey key = (ModelProviderKey) iterator.next();
if (key.version.equals(v))
return key.priority;
}
return DEFAULT_PRIORITY;
}
protected static Adapter getResourceSetListener(IProject project) {
if (resourceSetListeners == null)
resourceSetListeners = new HashMap();
Adapter listener = (Adapter)resourceSetListeners.get(project);
if (listener == null) {
listener = new ResourceSetListener();
resourceSetListeners.put(project, listener);
}
return listener;
}
private static J2EEModelProviderRegistry registry;
private static void initProviders() {
//Make sure both variables are null to prevent re-entrant behavior
if (registry == null && providers == null) {
providers = new HashMap();
registry = J2EEModelProviderRegistry.getInstance();
}
}
private static void startListeningToResourceSet(IProject project) {
ResourceSet set = WorkbenchResourceHelper.getResourceSet(project);
Adapter listener = getResourceSetListener(project);
if (set != null && !set.eAdapters().contains(listener))
set.eAdapters().add(listener);
}
private static ModelProviderKey createProviderKey(IProjectFacetVersion fv, int priority) {
ModelProviderKey key = new ModelProviderKey();
key.priority = priority;
key.version = fv;
return key;
}
public static IModelProvider getModelProvider(IProject proj) {
IProjectFacetVersion facetVersion = getDefaultFacet(proj);
return getModelProvider(proj, facetVersion);
}
public static IModelProvider getModelProvider(IVirtualComponent aModule) {
IProjectFacetVersion facetVersion = getDefaultFacet(aModule);
return getModelProvider(aModule, facetVersion);
}
private static IProjectFacetVersion getDefaultFacet(IProject proj) {
String type = J2EEProjectUtilities.getJ2EEProjectType(proj);
if( ProjectFacetsManager.isProjectFacetDefined(type)) {
IProjectFacet facet = ProjectFacetsManager.getProjectFacet(type);
IFacetedProject fp = null;
try {
fp = ProjectFacetsManager.create(proj);
} catch (CoreException e) {
J2EEPlugin.logError(e);
}
if (fp != null && facet != null) {
return fp.getInstalledVersion(facet);
}
}
return null;
}
private static IProjectFacetVersion getDefaultFacet(IVirtualComponent aModule) {
String type = J2EEProjectUtilities.getJ2EEComponentType(aModule);
IProjectFacet facet = ProjectFacetsManager.getProjectFacet(type);
IFacetedProject fp = null;
try {
if (aModule.isBinary())
{
}
else
{
fp = ProjectFacetsManager.create(aModule.getProject());
}
} catch (CoreException e) {
J2EEPlugin.logError(e);
}
if (fp != null && facet != null) {
return fp.getInstalledVersion(facet);
}
return null;
}
private synchronized static HashMap<ModelProviderKey, IModelProviderFactory> getProviders() {
if (registry == null)
initProviders();
return providers;
}
}