/*******************************************************************************
* Copyright (c) 2010, 2014 Willink Transformations 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:
* E.D.Willink - Initial API and implementation
*******************************************************************************/
package org.eclipse.ocl.pivot.internal.delegate;
import java.util.List;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
/**
* DelegateResourceAdapter extends a Resource to load and unload DelegateDomains
* for each package with a delegate annotation, when the resource is loaded and
* unloaded.
*/
public class DelegateResourceAdapter extends AdapterImpl
{
public static @NonNull DelegateResourceAdapter getAdapter(@NonNull Resource resource) {
DelegateResourceAdapter adapter = (DelegateResourceAdapter) EcoreUtil.getAdapter(resource.eAdapters(), DelegateResourceAdapter.class);
if (adapter == null) {
adapter = new DelegateResourceAdapter();
resource.eAdapters().add(adapter);
}
return adapter;
}
@Override
public Resource getTarget() {
return (Resource) super.getTarget();
}
@Override
public boolean isAdapterForType(Object type) {
return type == DelegateResourceAdapter.class;
}
@Override
public void notifyChanged(Notification notification) {
int featureID = notification.getFeatureID(Resource.class);
int eventType = notification.getEventType();
if (featureID == Resource.RESOURCE__IS_LOADED)
{
if (eventType == Notification.SET)
{
Resource resource = getTarget();
EList<EObject> contents = ClassUtil.nonNullEMF(resource.getContents());
if (notification.getNewBooleanValue()) {
EPackage.Registry packageRegistry = resource.getResourceSet().getPackageRegistry();
installPackages(ClassUtil.nonNullEMF(packageRegistry), contents);
}
}
}
else if (featureID == Resource.RESOURCE__CONTENTS)
{
if (eventType == Notification.REMOVE) {
EObject oldValue = (EObject) ClassUtil.nonNullEMF(notification.getOldValue());
unloadDelegate(oldValue);
}
else if (eventType == Notification.REMOVE_MANY) {
@SuppressWarnings("unchecked")
List<? extends EObject> oldValues = ClassUtil.nonNullEMF((List<? extends EObject>) notification.getOldValue());
unloadDelegates(oldValues);
}
}
}
protected void installPackages(EPackage.@NonNull Registry packageRegistry, @NonNull List<? extends EObject> contents) {
for (EObject eObject : contents) {
if (eObject instanceof EPackage) {
EPackage ePackage = (EPackage)eObject;
packageRegistry.put(ePackage.getNsURI(), ePackage);
installPackages(packageRegistry, ClassUtil.nonNullEMF(ePackage.getESubpackages()));
}
}
}
@Override
public void setTarget(Notifier newTarget) {
Resource resource = (Resource)newTarget;
super.setTarget(resource);
}
protected void unloadDelegate(@NonNull EObject eObject) {
if (eObject instanceof EPackage) {
EPackage ePackage = (EPackage)eObject;
DelegateEPackageAdapter adapter = DelegateEPackageAdapter.findAdapter(ePackage);
if (adapter != null) {
adapter.unloadDelegates();
}
unloadDelegates(ClassUtil.nonNullEMF(ePackage.getESubpackages()));
}
}
protected void unloadDelegates(@NonNull List<? extends EObject> contents) {
for (EObject eObject : contents) {
if (eObject != null) {
unloadDelegate(eObject);
}
}
}
}