| /*******************************************************************************
|
| * Copyright (c) 2009, 2019 Mia-Software and others.
|
| * All rights reserved. This program and the accompanying materials
|
| * are made available under the terms of the Eclipse Public License v2.0
|
| * which accompanies this distribution, and is available at
|
| * http://www.eclipse.org/legal/epl-v20.html
|
| *
|
| * Contributors:
|
| * Gregoire DUPE (Mia-Software)
|
| * Nicolas Bros (Mia-Software)
|
| *******************************************************************************/ |
| package org.eclipse.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.modisco.infra.common.core.internal.CommonModiscoActivator;
|
| import org.eclipse.modisco.infra.common.core.internal.builder.AbstractMoDiscoCatalog;
|
| import org.eclipse.modisco.infra.common.core.internal.protocol.ModiscoProtocolException;
|
| import org.eclipse.modisco.infra.common.core.internal.protocol.ModiscoURIHandler;
|
|
|
| /**
|
| * @author Gregoire DUPE
|
| */
|
| public final class MoDiscoResourceSet extends ResourceSetImpl {
|
|
|
| private static final String DEBUG_ID = "org.eclipse.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);
|
| }
|
|
|
| }
|
|
|
| }
|