blob: 273f41ff370ffedb5680013d051ecb031f13eca4 [file] [log] [blame]
package org.eclipse.gmf.internal.xpand.migration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.gmf.internal.xpand.ResourceManager;
import org.eclipse.gmf.internal.xpand.RootManager;
import org.eclipse.gmf.internal.xpand.build.MetaModelSource;
import org.osgi.framework.BundleContext;
/**
* The activator class controls the plug-in life cycle
*/
public class Activator extends Plugin {
// The plug-in ID
public static final String PLUGIN_ID = "org.eclipse.gmf.xpand.migration";
// The shared instance
private static Activator plugin;
private final Set<MetaModelSource> modelSources = new LinkedHashSet<MetaModelSource>();
/**
* The constructor
*/
public Activator() {
}
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
ResourcesPlugin.getWorkspace().addResourceChangeListener(myRootsTracker);
}
public void stop(BundleContext context) throws Exception {
ResourcesPlugin.getWorkspace().removeResourceChangeListener(myRootsTracker);
plugin = null;
super.stop(context);
}
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static Activator getDefault() {
return plugin;
}
public static void logError(Exception e) {
if (e instanceof CoreException) {
log(((CoreException) e).getStatus());
} else {
log(new Status(IStatus.ERROR, getId(), 0, e.getMessage(), e));
}
}
public static void log(IStatus status) {
getDefault().getLog().log(status);
}
public static void logWarn(String message) {
log(new Status(IStatus.WARNING, getId(), 0, message, null));
}
private static String getId() {
return getDefault().getBundle().getSymbolicName();
}
public static void registerModelSource(MetaModelSource modelSource) {
assert modelSource != null;
getDefault().modelSources.add(modelSource);
}
public static EPackage findMetaModel(String nsURI) {
if (getDefault() == null) {
// this is for tests execution (which doesn't take place in plugin
// env)
return null;
}
for (MetaModelSource s : getDefault().modelSources) {
EPackage p = s.find(nsURI);
if (p != null) {
return p;
}
}
return EPackage.Registry.INSTANCE.getEPackage(nsURI);
}
/* Root managers are necessary for legacy xpand builders only */
private final Map<IProject, RootManager> rootManagers = new HashMap<IProject, RootManager>();
public static ResourceManager getResourceManager(final IFile file) {
// TODO: return a delegating resource manager to XpandEditor, to
// silently change context when roots change.
RootManager manager = getRootManager(file.getProject());
ResourceManager result = manager.getResourceManager(file);
assert result != null;
return result;
}
public static RootManager getRootManager(IProject project) {
synchronized (plugin.myRootsTracker) {
RootManager result = plugin.rootManagers.get(project);
if (result == null) {
result = new RootManager(project);
plugin.rootManagers.put(project, result);
}
return result;
}
}
private final IResourceChangeListener myRootsTracker = new IResourceChangeListener() {
public synchronized void resourceChanged(IResourceChangeEvent event) {
if (event == null || event.getDelta() == null) {
return;
}
Set<RootManager> affectedRootManagers = new HashSet<RootManager>();
IResourceDelta rootDelta = event.getDelta();
for (IResourceDelta projectDelta : rootDelta.getAffectedChildren()) {
IProject affectedProject = (IProject) projectDelta.getResource();
if (isRemovedOrClosed(projectDelta)) {
rootManagers.remove(affectedProject);
} else {
IResourceDelta configFileDelta = projectDelta.findMember(RootManager.PROJECT_RELATIVE_PATH_TO_CONFIG_FILE);
if (configFileDelta != null && rootManagers.containsKey(affectedProject) && affectsConfigFile(configFileDelta)) {
affectedRootManagers.add(getRootManager(affectedProject));
}
}
}
// Opening/closing or creating/deleting a project may affect roots
// with absolute paths.
for (IResourceDelta projectDelta : rootDelta.getAffectedChildren()) {
if (mayAffectOtherResourceManagers(projectDelta)) {
IPath projectPath = projectDelta.getFullPath();
for (RootManager nextManager : rootManagers.values()) {
if (nextManager.containsProject(projectPath)) {
affectedRootManagers.add(nextManager);
}
}
}
}
for (RootManager nextManager : affectedRootManagers) {
nextManager.rootsChanged();
}
}
private boolean affectsConfigFile(IResourceDelta configFileDelta) {
if ((configFileDelta.getKind() & (IResourceDelta.ADDED | IResourceDelta.REMOVED)) > 0) {
return true;
}
if ((configFileDelta.getFlags() & (IResourceDelta.CONTENT | IResourceDelta.ENCODING | IResourceDelta.SYNC | IResourceDelta.TYPE | IResourceDelta.REPLACED)) > 0) {
return true;
}
return false;
}
private boolean isRemovedOrClosed(IResourceDelta projectDelta) {
if (projectDelta.getKind() == IResourceDelta.REMOVED) {
return true;
}
if ((projectDelta.getFlags() & IResourceDelta.OPEN) > 0) {
return !projectDelta.getResource().isAccessible();
}
return false;
}
private boolean mayAffectOtherResourceManagers(IResourceDelta projectDelta) {
if ((projectDelta.getKind() & (IResourceDelta.REMOVED | IResourceDelta.ADDED)) > 0) {
return true;
}
if ((projectDelta.getFlags() & IResourceDelta.OPEN) > 0) {
return !projectDelta.getResource().isAccessible();
}
return false;
}
};
private LegacyTemplateRootRegistry legacyTemplateRootRegistry;
public LegacyTemplateRootRegistry getLegacyTemplateRootRegistry() {
if (legacyTemplateRootRegistry == null) {
legacyTemplateRootRegistry = new LegacyTemplateRootRegistry();
}
return legacyTemplateRootRegistry;
}
}