blob: be172163f33d1717425e43ba978ae3bcf4a94f8b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2011 Mia-Software.
* 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:
* Gregoire DUPE (Mia-Software)
* Nicolas Bros (Mia-Software)
*******************************************************************************/
package org.eclipse.gmt.modisco.infra.common.core.internal.resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.ContentHandler;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.resource.URIHandler;
import org.eclipse.emf.ecore.resource.impl.ExtensibleURIConverterImpl;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.gmt.modisco.infra.common.core.internal.CommonModiscoActivator;
import org.eclipse.gmt.modisco.infra.common.core.internal.builder.AbstractMoDiscoCatalog;
import org.eclipse.gmt.modisco.infra.common.core.internal.protocol.ModiscoProtocolException;
import org.eclipse.gmt.modisco.infra.common.core.internal.protocol.ModiscoURIHandler;
/**
* @author Gregoire DUPE
*/
public final class MoDiscoResourceSet extends ResourceSetImpl {
private static final String DEBUG_ID = "org.eclipse.gmt.modisco.infra.common.core/debug/MoDiscoResoureSet/debug"; //$NON-NLS-1$
public static final boolean DEBUG = CommonModiscoActivator.getDefault().isDebugging()
&& Boolean.parseBoolean(Platform.getDebugOption(MoDiscoResourceSet.DEBUG_ID));
private static MoDiscoResourceSet resourceSet = null;
private final Map<URI, MoDiscoResourceListenerGroup> listenerGroupMap = new HashMap<URI, MoDiscoResourceListenerGroup>();
private MoDiscoResourceSet() {
super();
}
public static synchronized MoDiscoResourceSet getResourceSetSingleton() {
if (MoDiscoResourceSet.resourceSet == null) {
MoDiscoResourceSet.resourceSet = new MoDiscoResourceSet();
}
return MoDiscoResourceSet.resourceSet;
}
/**
* Return a loaded (or reloaded) EMF resource.
*
* @param uri
* the resource
* @param listener
* a listener that will be notified of each update to the
* returned resource.
* @return an EMF resource
* @throws IOException
*/
public synchronized Resource getResource(final URI uri, final IMoDiscoResourceListener listener)
throws IOException {
setPackageRegistry(EPackage.Registry.INSTANCE);
if (MoDiscoResourceSet.DEBUG) {
String message = this.getClass().getSimpleName() + ".getResource(URI,Listener): uri=" //$NON-NLS-1$
+ uri.toString();
System.out.println(message);
// IStatus status = new Status(IStatus.INFO,
// CommonModiscoActivator.PLUGIN_ID, message);
// CommonModiscoActivator.getDefault().getLog().log(status);
}
ListIterator<Resource> resourcesIterator = getResources().listIterator();
while (resourcesIterator.hasNext()) {
Resource existingResource = resourcesIterator.next();
if (existingResource == null) {
resourcesIterator.remove();
} else if (existingResource.getURI().equals(uri)) {
existingResource.unload();
break;
}
}
Resource resource = super.getResource(uri, true);
resource.load(Collections.EMPTY_MAP);
try {
addListenerToReferedResource(resource, listener);
} catch (Exception e) {
throw new RuntimeException(e);
}
return resource;
}
private synchronized void addListenerToReferedResource(final Resource resource,
final IMoDiscoResourceListener listener) throws Exception {
TreeIterator<EObject> treeIterator = resource.getAllContents();
while (treeIterator.hasNext()) {
try {
EObject eObject = treeIterator.next();
for (EStructuralFeature feature : eObject.eClass().getEAllStructuralFeatures()) {
Object object = eObject.eGet(feature);
if (object instanceof EObject) {
readEObject(resource, listener, eObject, (EObject) object);
} else if (object instanceof EList<?>) {
EList<?> list = (EList<?>) object;
for (Object listObject : list) {
if (object instanceof EObject) {
readEObject(resource, listener, eObject, (EObject) listObject);
}
}
}
}
} catch (BrokenRefException e) {
resource.getErrors().add(e);
} catch (Exception e) {
if (e instanceof ModiscoProtocolException) {
ModiscoProtocolException mpe = (ModiscoProtocolException) e;
resource.getErrors().add(mpe);
} else {
throw e;
}
}
}
}
private synchronized void readEObject(final Resource resource, final IMoDiscoResourceListener listener,
final EObject referringEObject, final EObject referredEObject)
throws BrokenRefException {
Resource referredObjectResource = referredEObject.eResource();
if (referredObjectResource != resource) {
MoDiscoResourceListenerGroup listenerGroup;
if (listener != null) {
URI referredURI;
if (referredObjectResource != null) {
referredURI = referredObjectResource.getURI();
} else {
// see bugs 311684 and 312456
referredURI = EcoreUtil.getURI(referredEObject).trimFragment();
}
listenerGroup = getListenerGroup(referredURI);
listenerGroup.addListener(listener, resource.getURI());
}
if (referredObjectResource == null) {
EObject resolved = EcoreUtil.resolve(referredEObject, this);
if (resolved.eIsProxy()) {
throw new BrokenRefException(referringEObject, referredEObject);
}
}
}
}
public synchronized MoDiscoResourceListenerGroup getListenerGroup(final URI watchedResourceUri) {
MoDiscoResourceListenerGroup listenerGroup = this.listenerGroupMap.get(watchedResourceUri);
if (listenerGroup == null) {
listenerGroup = new MoDiscoResourceListenerGroup(watchedResourceUri);
this.listenerGroupMap.put(watchedResourceUri, listenerGroup);
}
return listenerGroup;
}
/**
* This method is used to notify the resource set that one of its resources
* has been reloaded.
*
* This method is used by the
* {@link AbstractMoDiscoCatalog#addWSFile(IFile)} method.
*
* @param resource
* a reloaded resource
*/
public void aResourceHasBeenLoaded(final Resource resource) {
URI uri = resource.getURI();
if (MoDiscoResourceSet.DEBUG) {
String message = this.getClass().getSimpleName()
+ ".aResourceHasBeenLoaded(Resource)] resource.getURI()=" //$NON-NLS-1$
+ uri.toString();
System.out.println(message);
// IStatus status = new Status(IStatus.INFO,
// CommonModiscoActivator.PLUGIN_ID, message);
// CommonModiscoActivator.getDefault().getLog().log(status);
}
MoDiscoResourceListenerGroup listenerGroup = getListenerGroup(uri);
listenerGroup.notifyChange();
}
public void aResourceHasBeenUnLoaded(final Resource resource) {
URI uri = resource.getURI();
if (MoDiscoResourceSet.DEBUG) {
String message = this.getClass().getSimpleName()
+ ".aResourceHasBeenUnLoaded(Resource): resource.getURI()=" //$NON-NLS-1$
+ uri.toString();
System.out.println(message);
// IStatus status = new Status(IStatus.INFO,
// CommonModiscoActivator.PLUGIN_ID, message );
// CommonModiscoActivator.getDefault().getLog().log(status);
}
MoDiscoResourceListenerGroup listenerGroup = getListenerGroup(uri);
listenerGroup.notifyChange();
}
@Override
public synchronized URIConverter getURIConverter() {
if (this.uriConverter == null) {
this.uriConverter = MoDiscoResourceSet.createURIConverter();
}
return this.uriConverter;
}
/**
* Create a URI converter that includes the {@link ModiscoURIHandler}
*
* @author nbros
*/
public static synchronized URIConverter createURIConverter() {
final List<URIHandler> defaultHandlers = URIHandler.DEFAULT_HANDLERS;
final List<URIHandler> uriHandlers = new ArrayList<URIHandler>();
// note: disabling the default URI handler caused problems resolving
// queries in the browser
uriHandlers.add(new ModiscoURIHandler());
uriHandlers.addAll(defaultHandlers);
return new ExtensibleURIConverterImpl(uriHandlers,
ContentHandler.Registry.INSTANCE.contentHandlers());
}
public synchronized void removeListener(final IMoDiscoResourceListener listener, final URI dependingResource) {
for (MoDiscoResourceListenerGroup group : this.listenerGroupMap.values()) {
group.remove(listener, dependingResource);
}
}
}