blob: 36c8f4df4d21c9c69aa082c4893c8145741126db [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005 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
*******************************************************************************/
/*
* $$RCSfile: ProjectResourceSetImpl.java,v $$
* $$Revision: 1.8 $$ $$Date: 2005/03/18 18:52:06 $$
*/
package org.eclipse.jem.internal.util.emf.workbench;
import java.io.IOException;
import java.util.*;
import org.eclipse.core.resources.IProject;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.NotificationImpl;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.resource.impl.URIConverterImpl;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.jem.util.emf.workbench.*;
import org.eclipse.jem.util.emf.workbench.nature.EMFNature;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jem.util.plugin.JEMUtilPlugin;
public class ProjectResourceSetImpl extends ResourceSetImpl implements ProjectResourceSet {
private boolean isReleasing = false;
private IProject project;
protected List resourceHandlers = new ArrayList();
protected ResourceSetWorkbenchSynchronizer synchronizer;
protected ProjectResourceSetImpl() {
setURIResourceMap(new HashMap(10)); // Tell it to cache uri->resource access.
getLoadOptions().put(XMLResource.OPTION_USE_PARSER_POOL, EMFNature.SHARED_PARSER_POOL);
}
public ProjectResourceSetImpl(IProject aProject) {
this();
setProject(aProject);
initializeSharedCacheListener();
}
protected void initializeSharedCacheListener() {
JEMUtilPlugin.getSharedCache().beginListening(this);
}
protected boolean isReleasing() {
return isReleasing;
}
/**
* @see org.eclipse.emf.ecore.resource.impl.ResourceSetImpl#delegatedGetResource(URI, boolean)
*/
protected Resource delegatedGetResource(URI uri, boolean loadOnDemand) {
Resource res = super.delegatedGetResource(uri, loadOnDemand);
if (res == null)
res = getResourceFromHandlers(uri);
return res;
}
public Resource createResource(URI uri) {
if (isReleasing) return null;
//Check the map first when creating the resource and do not
//normalize if a value is found.
boolean isMapped = !(((URIConverterImpl.URIMap)getURIConverter().getURIMap()).getURI(uri).equals(uri));
URI converted = uri;
if (!isMapped)
converted = getURIConverter().normalize(uri);
Resource result = createResourceFromHandlers(converted);
if (result == null)
result = super.createResource(converted);
return result;
}
/**
* @see org.eclipse.emf.ecore.resource.impl.ResourceSetImpl#demandLoad(Resource)
*/
protected void demandLoad(Resource resource) throws IOException {
if (!isReleasing)
super.demandLoad(resource);
}
/**
* See if any resource handlers from the WorkbenchContext
* decide to create the Resource in another manner.
*/
protected Resource createResourceFromHandlers(URI uri) {
Resource resource = null;
ResourceHandler handler = null;
for (int i = 0; i < resourceHandlers.size(); i++) {
handler = (ResourceHandler) resourceHandlers.get(i);
resource = handler.createResource(this, uri);
if (resource != null)
return resource;
}
return null;
}
/**
* See if any resource handlers from the WorkbenchContext
* can return a Resource from a <code>uri</code>.
*/
protected Resource getResourceFromHandlers(URI uri) {
if (isReleasing) return null;
for (int i = 0; i < resourceHandlers.size(); i++) {
Resource resource = ((ResourceHandler) resourceHandlers.get(i)).getResource(this, uri);
if (resource != null)
return resource;
}
return null;
}
public void release() {
// Send out notification of release.
if (eNotificationRequired()) {
eNotify(new NotificationImpl(SPECIAL_NOTIFICATION_TYPE, null, null, Notification.NO_INDEX, false) {
/* (non-Javadoc)
* @see org.eclipse.emf.common.notify.impl.NotificationImpl#getFeatureID(java.lang.Class)
*/
public int getFeatureID(Class expectedClass) {
return PROJECTRESOURCESET_ABOUT_TO_RELEASE_ID;
}
/* (non-Javadoc)
* @see org.eclipse.emf.common.notify.impl.NotificationImpl#getNotifier()
*/
public Object getNotifier() {
return ProjectResourceSetImpl.this;
}
});
}
setIsReleasing(true);
if (synchronizer != null)
synchronizer.dispose();
synchronizer = null;
removeAndUnloadAllResources();
resourceHandlers = null;
eAdapters().clear();
setProject(null);
JEMUtilPlugin.getSharedCache().stopListening(this);
}
protected void removeAndUnloadAllResources() {
boolean caughtException = false;
if (getResources().isEmpty()) return;
List list = new ArrayList(getResources());
getResources().clear();
Resource res;
int size = list.size();
for (int i = 0; i < size; i++) {
res = (Resource) list.get(i);
try {
res.unload();
} catch (RuntimeException ex) {
Logger.getLogger().logError(ex);
caughtException = true;
}
}
if (caughtException)
throw new RuntimeException("Exception(s) unloading resources - check log files"); //$NON-NLS-1$
}
protected void setIsReleasing(boolean aBoolean) {
isReleasing = aBoolean;
}
/**
* Gets the project.
* @return Returns a IProject
*/
public IProject getProject() {
return project;
}
/**
* Sets the project.
* @param project The project to set
*/
protected void setProject(IProject project) {
this.project = project;
}
/*
* Javadoc copied from interface.
*/
public EObject getEObject(URI uri, boolean loadOnDemand) {
if (isReleasing) return null;
Resource resource = getResource(uri.trimFragment(), loadOnDemand);
EObject result = null;
if (resource != null && resource.isLoaded())
result = resource.getEObject(uri.fragment());
if (result == null)
result = getEObjectFromHandlers(uri, loadOnDemand);
return result;
}
/**
* See if any resource handlers from the WorkbenchContext
* can return a EObject from a <code>uri</code> after
* failing to find it using the normal mechanisms.
*/
protected EObject getEObjectFromHandlers(URI uri, boolean loadOnDemand) {
EObject obj = null;
ResourceHandler handler = null;
for (int i = 0; i < resourceHandlers.size(); i++) {
handler = (ResourceHandler) resourceHandlers.get(i);
obj = handler.getEObjectFailed(this, uri, loadOnDemand);
if (obj != null)
return obj;
}
return null;
}
public boolean add(ResourceHandler resourceHandler) {
return resourceHandlers.add(resourceHandler);
}
public void addFirst(ResourceHandler resourceHandler) {
resourceHandlers.add(0, resourceHandler);
}
public boolean remove(ResourceHandler resourceHandler) {
return resourceHandlers.remove(resourceHandler);
}
/**
* Returns the synchronizer.
* @return ResourceSetWorkbenchSynchronizer
*/
public ResourceSetWorkbenchSynchronizer getSynchronizer() {
return synchronizer;
}
/**
* Sets the synchronizer.
* @param synchronizer The synchronizer to set
*/
public void setSynchronizer(ResourceSetWorkbenchSynchronizer synchronizer) {
this.synchronizer = synchronizer;
}
/**
* @see org.eclipse.emf.ecore.resource.ResourceSet#setResourceFactoryRegistry(Resource.Factory.Registry)
*/
public void setResourceFactoryRegistry(Resource.Factory.Registry factoryReg) {
if (resourceFactoryRegistry != null && factoryReg != null) {
preserveEntries(factoryReg.getExtensionToFactoryMap(), resourceFactoryRegistry.getExtensionToFactoryMap());
preserveEntries(factoryReg.getProtocolToFactoryMap(), resourceFactoryRegistry.getProtocolToFactoryMap());
}
super.setResourceFactoryRegistry(factoryReg);
}
/*
* Preserve the entries from map2 in map1 if no collision.
*/
protected void preserveEntries(Map map1, Map map2) {
if (map2.isEmpty())
return;
Iterator it = map2.entrySet().iterator();
Map.Entry entry;
while (it.hasNext()) {
entry = (Map.Entry) it.next();
if (!map1.containsKey(entry.getKey()))
map1.put(entry.getKey(), entry.getValue());
}
}
/*
* Javadoc copied from interface.
*/
public Resource getResource(URI uri, boolean loadOnDemand) {
if (isReleasing) return null;
return super.getResource(uri, loadOnDemand);
}
/* (non-Javadoc)
* @see org.eclipse.jem.util.emf.workbench.ProjectResourceSet#resetNormalizedURICache()
*/
public void resetNormalizedURICache() {
if (getURIResourceMap() != null)
getURIResourceMap().clear();
}
}