blob: 390efe698f90f6f2ebc96650da7af2684c773c6b [file] [log] [blame]
/**
* Copyright (c) 2009-2010 Thales Corporate Services S.A.S.
* 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
* https://www.eclipse.org/legal/epl-v2.0
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Thales Corporate Services S.A.S - initial API and implementation
*/
package org.eclipse.egf.model.fcore.provider;
import java.util.ArrayList;
import java.util.Collection;
import org.eclipse.egf.common.helper.EMFHelper;
import org.eclipse.egf.core.fcore.IPlatformFcore;
import org.eclipse.egf.core.fcore.IPlatformFcoreProvider;
import org.eclipse.egf.core.platform.pde.IPlatformBundle;
import org.eclipse.egf.model.edit.EGFModelEditPlugin;
import org.eclipse.egf.model.fcore.FcoreFactory;
import org.eclipse.egf.model.fcore.FcorePackage;
import org.eclipse.egf.model.fcore.commands.resource.FcoreResourceAddCommand;
import org.eclipse.egf.model.fcore.commands.resource.ResourceFeatureAddCommand;
import org.eclipse.egf.model.fcore.commands.resource.ResourceMoveCommand;
import org.eclipse.egf.model.fcore.commands.resource.ResourceRemoveCommand;
import org.eclipse.egf.model.fcore.util.FcoreResourceImpl;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.common.command.UnexecutableCommand;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.ResourceLocator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.UniqueEList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.emf.edit.command.CommandParameter;
import org.eclipse.emf.edit.command.CreateChildCommand;
import org.eclipse.emf.edit.command.MoveCommand;
import org.eclipse.emf.edit.command.RemoveCommand;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.provider.IChildCreationExtender;
import org.eclipse.emf.edit.provider.ViewerNotification;
import org.eclipse.emf.edit.provider.resource.ResourceItemProvider;
/**
* @author Xavier Maysonnave
*/
public class FcoreResourceItemProvider extends ResourceItemProvider {
protected ResourceChildCreationExtenderManager _resourceExtenderManager;
protected Collection<EClass> _roots;
/**
* This constructs an instance from a factory and a notifier.
*/
public FcoreResourceItemProvider(AdapterFactory adapterFactory, ResourceChildCreationExtenderManager resourceExtenderManager) {
super(adapterFactory);
_resourceExtenderManager = resourceExtenderManager;
}
public Collection<EClass> getRoots() {
if (_roots == null) {
_roots = new UniqueEList<EClass>();
_roots.add(FcorePackage.Literals.FACTORY_COMPONENT);
// Add roots defined by extenders
_roots.addAll(_resourceExtenderManager.getRoots());
}
return _roots;
}
@Override
public Collection<?> getNewChildDescriptors(Object object, EditingDomain editingDomain, Object sibling) {
// Resource
FcoreResourceImpl resource = (FcoreResourceImpl) object;
// Build the collection of new child descriptors.
Collection<Object> newChildDescriptors = new ArrayList<Object>();
collectNewChildDescriptors(newChildDescriptors, object);
// Add child descriptors contributed by extenders.
if (adapterFactory instanceof IChildCreationExtender) {
newChildDescriptors.addAll(((IChildCreationExtender) adapterFactory).getNewChildDescriptors(object, editingDomain));
}
// If a sibling has been specified, add the best index possible to each CommandParameter.
if (sibling != null) {
// Unwrap
sibling = unwrap(sibling);
// Find the index of the sibling.
Collection<EObject> children = resource.getContents();
// For each CommandParameter with a non-null, multi-valued structural feature...
int i = 0;
DESCRIPTORS_LOOP: for (Object descriptor : newChildDescriptors) {
if (descriptor instanceof CommandParameter) {
CommandParameter parameter = (CommandParameter) descriptor;
// Look for the sibling value or an equivalent in the new child's feature.
// If it is found, the child should immediately follow it.
i = 0;
for (Object innerObject : children) {
if (isEquivalentValue(sibling, innerObject)) {
parameter.index = i + 1;
continue DESCRIPTORS_LOOP;
}
++i;
}
}
}
}
return newChildDescriptors;
}
/**
* This adds to <code>newChildDescriptors</code>, a collection of new child
* descriptors. Typically, {@link org.eclipse.emf.edit.command.CommandParameter}s
* will be used as descriptors. This implementation adds nothing to the
* collection, but derived classes should override this method, invoking the
* superclass implementation and then adding to the collection.
*/
@Override
protected void collectNewChildDescriptors(Collection<Object> newChildDescriptors, Object object) {
newChildDescriptors.add(createChildParameter(FcorePackage.Literals.FACTORY_COMPONENT, FcoreFactory.eINSTANCE.createFactoryComponent()));
}
/**
* This is a convenience method that creates a <code>CommandParameter</code>
* for a given parent feature and child object.
*/
@Override
protected CommandParameter createChildParameter(Object feature, Object child) {
return new CommandParameter(null, feature, child);
}
/**
* This returns the label text for the adapted class.
*/
@Override
public String getText(Object object) {
Resource resource = (Resource) object;
StringBuffer buffer = new StringBuffer(resource.getURI() == null ? "" : URI.decode(resource.getURI().toString())); //$NON-NLS-1$
if (resource instanceof IPlatformFcoreProvider) {
IPlatformFcore fcore = ((IPlatformFcoreProvider) resource).getIPlatformFcore();
if (fcore != null) {
IPlatformBundle platformBundle = fcore.getPlatformBundle();
if (platformBundle.isTarget())
buffer.append(" [Target]"); //$NON-NLS-1$
else if (platformBundle.isRuntime())
buffer.append(" [Runtime]"); //$NON-NLS-1$
else
buffer.append(" [Workspace]"); //$NON-NLS-1$
buffer.append(" ["); //$NON-NLS-1$
buffer.append(platformBundle.getInstallLocation());
buffer.append("]"); //$NON-NLS-1$
}
}
return buffer.toString();
}
/**
* This returns Fcore.gif.
*/
@Override
public Object getImage(Object object) {
return URI.createURI(EGFModelEditPlugin.INSTANCE.getPluginResourceLocator().getImage("full/obj16/Fcore").toString()); //$NON-NLS-1$
}
/**
* Return the resource locator for this item provider's resources.
*/
@Override
public ResourceLocator getResourceLocator() {
return ((IChildCreationExtender) adapterFactory).getResourceLocator();
}
/**
* This implements delegated command creation for the given object.
*/
@Override
public Command createCommand(Object object, EditingDomain domain, Class<? extends Command> commandClass, CommandParameter commandParameter) {
// Commands should operate on the values, not their wrappers. If the command's values needed to be unwrapped,
// we'll back get a new CommandParameter.
CommandParameter oldCommandParameter = commandParameter;
commandParameter = unwrapCommandValues(commandParameter, commandClass);
Command result = UnexecutableCommand.INSTANCE;
if (commandParameter.owner instanceof FcoreResourceImpl) {
if (commandClass == RemoveCommand.class) {
result = createRemoveCommand(domain, (FcoreResourceImpl) commandParameter.owner, commandParameter.getCollection());
} else if (commandClass == AddCommand.class) {
result = createAddCommand(domain, (FcoreResourceImpl) commandParameter.owner, commandParameter.getCollection(), commandParameter.getIndex());
} else if (commandClass == MoveCommand.class) {
result = createMoveCommand(domain, (FcoreResourceImpl) commandParameter.owner, commandParameter.getValue(), commandParameter.getIndex());
} else if (commandClass == CreateChildCommand.class) {
CommandParameter newChildParameter = (CommandParameter) commandParameter.getValue();
result = createCreateChildCommand(domain, (FcoreResourceImpl) commandParameter.owner, newChildParameter.getEStructuralFeature(), newChildParameter.getValue(), newChildParameter.getIndex(), commandParameter.getCollection());
} else {
return super.createCommand(object, domain, commandClass, commandParameter);
}
} else {
return super.createCommand(object, domain, commandClass, commandParameter);
}
// If necessary, get a command that replaces unwrapped values by their wrappers in the result and affected objects.
return wrapCommand(result, object, commandClass, commandParameter, oldCommandParameter);
}
/**
* This creates a primitive {@link org.eclipse.emf.edit.command.RemoveCommand}.
*/
protected Command createRemoveCommand(EditingDomain domain, FcoreResourceImpl resource, Collection<?> collection) {
CompoundCommand removeCommand = new CompoundCommand(CompoundCommand.MERGE_COMMAND_ALL);
removeCommand.append(new ResourceRemoveCommand(domain, resource, collection));
for (Object object : collection) {
EObject eObject = (EObject) object;
if (eObject.eContents().isEmpty() == false) {
removeCommand.append(domain.createCommand(RemoveCommand.class, new CommandParameter(eObject, null, eObject.eContents())));
}
}
return removeCommand;
}
/**
* This creates a primitive {@link org.eclipse.emf.edit.command.AddCommand}.
*/
protected Command createAddCommand(EditingDomain domain, FcoreResourceImpl resource, Collection<?> collection, int index) {
Collection<EClass> roots = getRoots();
if (collection != null) {
for (Object object : collection) {
if (object instanceof EObject) {
EObject eObject = (EObject) object;
if (roots.contains(EMFHelper.solveAgainstStaticPackage(eObject.eClass())) == false) {
return UnexecutableCommand.INSTANCE;
}
}
}
return new FcoreResourceAddCommand(domain, resource, collection, index);
}
return UnexecutableCommand.INSTANCE;
}
/**
* This creates a primitive {@link org.eclipse.emf.edit.command.MoveCommand}.
*/
protected Command createMoveCommand(EditingDomain domain, FcoreResourceImpl resource, Object value, int index) {
if (value instanceof EObject) {
Collection<EClass> roots = getRoots();
EObject eObject = (EObject) value;
if (roots.contains(EMFHelper.solveAgainstStaticPackage(eObject.eClass()))) {
return new ResourceMoveCommand(domain, resource, value, index);
}
}
return UnexecutableCommand.INSTANCE;
}
/**
* This creates a primitive {@link org.eclipse.emf.edit.command.CreateChildCommand}.
*/
protected Command createCreateChildCommand(EditingDomain domain, FcoreResourceImpl resource, EStructuralFeature feature, Object value, int index, Collection<?> collection) {
if (collection != null && collection.size() == 1) {
Object object = collection.iterator().next();
if (object instanceof EObject) {
Collection<EClass> roots = getRoots();
EObject eObject = (EObject) object;
if (roots.contains(EMFHelper.solveAgainstStaticPackage(eObject.eClass()))) {
return new ResourceFeatureAddCommand(domain, resource, feature, value, resource.getContents().indexOf(eObject) == CommandParameter.NO_INDEX ? CommandParameter.NO_INDEX : resource.getContents().indexOf(eObject) + 1);
}
}
}
return UnexecutableCommand.INSTANCE;
}
/**
* This handles notification by calling {@link #fireNotifyChanged(Notification) fireNotifyChanged}.
*/
@Override
public void notifyChanged(Notification notification) {
switch (notification.getFeatureID(Resource.class)) {
case Resource.RESOURCE__URI:
// case Resource.RESOURCE__IS_MODIFIED:
// case Resource.RESOURCE__IS_TRACKING_MODIFICATION:
// case Resource.RESOURCE__RESOURCE_SET:
{
fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), false, true));
return;
}
case Resource.RESOURCE__IS_LOADED:
case Resource.RESOURCE__CONTENTS: {
fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), true, false));
return;
}
}
super.notifyChanged(notification);
}
}