/*****************************************************************************
* Copyright (c) 2010 ATOS ORIGIN.
*
* 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:
* Tristan Faure (ATOS ORIGIN INTEGRATION) tristan.faure@atosorigin.com - Initial API and implementation
*****************************************************************************/
package org.eclipse.papyrus.infra.services.resourceloading;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.papyrus.infra.core.resource.ModelSet;
import org.eclipse.papyrus.infra.core.resource.sasheditor.SashModel;
import org.eclipse.papyrus.infra.services.controlmode.mm.history.ControledResource;
/**
* This adapter maintains a map linking url and the corresponding ControledResource
*
* @author tfaure
*
*/
public class ControledResourceAdapter implements Adapter.Internal {
/**
* The map accesed
*/
private Map<String, List<ControledResource>> resources = new HashMap<String, List<ControledResource>>();
private ModelSet modelSet = null;
public ControledResourceAdapter(ModelSet modelSet) {
this.modelSet = modelSet;
manageAllControledResources();
modelSet.eAdapters().add(this);
}
protected void put(ControledResource controled) {
List<ControledResource> list = resources.get(controled.getResourceURL());
if(list == null) {
list = new LinkedList<ControledResource>();
resources.put(controled.getResourceURL(), list);
addAdapter(controled);
}
list.add(controled);
}
public void manageAllControledResources() {
for(Resource r : modelSet.getResources()) {
addResource(r);
}
}
protected void addResource(Resource r) {
if(SashModel.MODEL_FILE_EXTENSION.equals(r.getURI().fileExtension())) {
for(EObject e : r.getContents()) {
if(e instanceof ControledResource) {
ControledResource root = (ControledResource)e;
if(root != null) {
put(root);
for(Iterator<EObject> i = root.eAllContents(); i.hasNext();) {
EObject eobject = i.next();
if(eobject instanceof ControledResource) {
put((ControledResource)eobject);
}
}
}
}
}
if(!r.eAdapters().contains(this)) {
r.eAdapters().add(this);
}
}
}
public List<ControledResource> getControledResource(String locationURL) {
List<ControledResource> list = resources.get(locationURL);
if(list == null) {
return Collections.emptyList();
}
return list;
}
public void notifyChanged(Notification notification) {
Notifier aNotifier = (Notifier)notification.getNotifier();
if(aNotifier instanceof EObject) {
switch(notification.getEventType()) {
case Notification.ADD:
addControledResource(notification.getNewValue());
break;
case Notification.ADD_MANY:
List<?> list = (List<?>)notification.getNewValue();
for(Object o : list) {
addControledResource(o);
}
break;
case Notification.REMOVE:
removeControledResource(notification.getOldValue());
break;
case Notification.REMOVE_MANY:
List<?> list2 = (List<?>)notification.getOldValue();
for(Object o : list2) {
removeControledResource(o);
}
break;
default:
break;
}
} else if(aNotifier instanceof Resource) {
switch(notification.getFeatureID(Resource.class)) {
case Resource.RESOURCE__IS_LOADED:
addResource((Resource)aNotifier);
break;
}
} else if(aNotifier instanceof ModelSet) {
if(notification.getNewValue() instanceof Resource) {
Resource r = ((Resource)notification.getNewValue());
if(!r.eAdapters().contains(this)) {
r.eAdapters().add(this);
}
setTarget((Resource)notification.getNewValue());
}
}
}
protected void addControledResource(Object o) {
if(o instanceof ControledResource) {
ControledResource o2 = (ControledResource)o;
put(o2);
}
}
protected void removeControledResource(Object o) {
if(o instanceof ControledResource) {
ControledResource res = (ControledResource)o;
List<ControledResource> list = resources.get(res.getResourceURL());
if(list != null) {
list.remove(res);
if(list.isEmpty()) {
resources.remove(res.getResourceURL());
}
}
}
}
public Notifier getTarget() {
return modelSet;
}
public boolean isAdapterForType(Object type) {
return false;
}
/**
* Handles installation of the adapter on an EObject by adding the adapter
* to each of the directly contained objects.
*/
protected void setTarget(EObject target) {
for(@SuppressWarnings("unchecked")
Iterator<EObject> i = (Iterator<EObject>)((InternalEList<?>)target.eContents()).basicIterator(); i.hasNext();) {
Notifier notifier = i.next();
addAdapter(notifier);
}
}
protected void addAdapter(Notifier notifier) {
List<Adapter> eAdapters = notifier.eAdapters();
if(!eAdapters.contains(this)) {
eAdapters.add(this);
}
}
/**
* Handles installation of the adapter by adding the adapter to each of the
* directly contained objects.
*/
public void setTarget(Notifier target) {
if(target instanceof EObject) {
setTarget((EObject)target);
} else if(target instanceof Resource) {
setTarget((Resource)target);
} else if(target instanceof ResourceSet) {
setTarget((ResourceSet)target);
}
}
/**
* Handles installation of the adapter on a Resource by adding the adapter
* to each of the directly contained objects.
*/
protected void setTarget(Resource target) {
List<EObject> contents = target.getContents();
for(int i = 0, size = contents.size(); i < size; ++i) {
Notifier notifier = contents.get(i);
addAdapter(notifier);
}
}
/**
* Handles installation of the adapter on a ResourceSet by adding the
* adapter to each of the directly contained objects.
*/
protected void setTarget(ResourceSet target) {
List<Resource> resources = target.getResources();
for(int i = 0; i < resources.size(); ++i) {
Notifier notifier = resources.get(i);
addAdapter(notifier);
}
}
/**
* Handles undoing the installation of the adapter by removing the adapter
* to each of the directly contained objects.
*/
public void unsetTarget(Notifier target) {
if(target instanceof EObject) {
unsetTarget((EObject)target);
} else if(target instanceof Resource) {
unsetTarget((Resource)target);
} else if(target instanceof ResourceSet) {
unsetTarget((ResourceSet)target);
}
}
/**
* Handles undoing the installation of the adapter from an EObject by
* removing the adapter to each of the directly contained objects.
*/
protected void unsetTarget(EObject target) {
for(@SuppressWarnings("unchecked")
Iterator<InternalEObject> i = (Iterator<InternalEObject>)((InternalEList<?>)target.eContents()).basicIterator(); i.hasNext();) {
// Don't remove the adapter if the object is in a different resource
// and that resource (and hence all its contents) are being cross
// referenced.
//
InternalEObject internalEObject = i.next();
Resource eDirectResource = internalEObject.eDirectResource();
if(eDirectResource == null || !eDirectResource.eAdapters().contains(this)) {
removeAdapter(internalEObject);
}
}
}
/**
* Handles undoing the installation of the adapter from a Resource by
* removing the adapter to each of the directly contained objects.
*/
protected void unsetTarget(Resource target) {
List<EObject> contents = target.getContents();
for(int i = 0, size = contents.size(); i < size; ++i) {
Notifier notifier = contents.get(i);
removeAdapter(notifier);
}
}
protected void removeAdapter(Notifier notifier) {
notifier.eAdapters().remove(this);
}
/**
* Handles undoing the installation of the adapter from a ResourceSet by
* removing the adapter to each of the directly contained objects.
*/
protected void unsetTarget(ResourceSet target) {
List<Resource> resources = target.getResources();
for(int i = 0; i < resources.size(); ++i) {
Notifier notifier = resources.get(i);
removeAdapter(notifier);
}
}
}