/*****************************************************************************
* Copyright (c) 2012 Atos.
*
*
* 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:
* Olivier Melois (ATOS) olivier.melois@atos.net - Initial API and implementation
*
*****************************************************************************/
package org.eclipse.papyrus.infra.table.controlmode.helpers;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature.Setting;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.facet.widgets.nattable.instance.tableinstance.TableInstance;
import org.eclipse.emf.facet.widgets.nattable.instance.tableinstance.TableinstancePackage;
import org.eclipse.emf.facet.widgets.nattable.instance.tableinstance2.TableInstance2;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.papyrus.commands.wrappers.GMFtoEMFCommandWrapper;
import org.eclipse.papyrus.infra.core.utils.PapyrusEcoreUtils;
import org.eclipse.papyrus.infra.table.instance.papyrustableinstance.PapyrusTableInstance;
import org.eclipse.papyrus.infra.table.instance.papyrustableinstance.PapyrustableinstancePackage;
import org.eclipse.papyrus.views.modelexplorer.commands.MoveOpenableCommand;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import com.google.common.collect.Sets;
/**
* Helper used to move the tables into the right resources when controlling a package.
*/
public class TableMoveHelper {
/**
* Adds commands to move every table that descend from the selection to the target resource.
*/
public static void addAllTableMoveCommands(EditingDomain domain, EObject selection, Resource target, CompoundCommand commandToModify) {
/*
* All the tables in the tables that descend from the selection.
*/
Iterable<EObject> allDescendingPapyrusTables = createDescendantTablesIterable(selection);
/*
* Making sure the editing domain is transactional.
*/
if(!(domain instanceof TransactionalEditingDomain)) {
throw new RuntimeException("Unable to retrieve the transactional editing domain");////$NON-NLS-1$
}
TransactionalEditingDomain editingDomain = (TransactionalEditingDomain)domain;
/*
* Moving every table from the new resource.
*/
for(EObject descendant : allDescendingPapyrusTables) {
if(descendant instanceof PapyrusTableInstance) {
PapyrusTableInstance papyrusTable = (PapyrusTableInstance)descendant;
addMoveTableCommand(editingDomain, papyrusTable, target, commandToModify);
}
}
}
/**
* Adds a command to move a papyrus table and the matching table2 instance, to the compound command.
*/
protected static void addMoveTableCommand(TransactionalEditingDomain editingDomain, PapyrusTableInstance papyrusTable, Resource target, CompoundCommand commandToModify) {
//The command has to move both the table and its table2.
TableInstance2 papyrusTable2 = papyrusTable.getTable();
/*
* Has the target resource been loaded, and is it in read only mode ?
*/
if(editingDomain.isReadOnly(target)) {
return;
}
/*
* Moving both the table instance and the table2 instance.
*/
if(target != null) {
MoveOpenableCommand mvTabCmd = new MoveOpenableCommand(editingDomain, "moving table", papyrusTable, target);//$NON-NLS-1$
if(mvTabCmd != null && mvTabCmd.canExecute()) {
commandToModify.append(new GMFtoEMFCommandWrapper(mvTabCmd));
}
MoveOpenableCommand mvTab2Cmd = new MoveOpenableCommand(editingDomain, "moving table2", papyrusTable2, target);//$NON-NLS-1$
if(mvTab2Cmd != null && mvTab2Cmd.canExecute()) {
commandToModify.append(new GMFtoEMFCommandWrapper(mvTab2Cmd));
}
}
}
/**
* Creates an iterable containing all the Papyrus Tables that are descending from the context.
*
* @author olivier melois (Atos)
*/
public static Iterable<EObject> createDescendantTablesIterable(EObject context) {
Set<EObject> result = Sets.newHashSet();
TreeIterator<EObject> eAllContents = EcoreUtil.getAllProperContents(context, true); // was context.eAllContents().
Iterator<EObject> contextAndDescendants = Iterators.concat(eAllContents, Iterators.singletonIterator(context));
final Predicate<Setting> keepPapyrusTableInstances = new Predicate<Setting>() {
public boolean apply(Setting setting) {
boolean result = true;
if(setting != null) {
EObject settingEObject = setting.getEObject();
result &= settingEObject instanceof PapyrusTableInstance;
result &= PapyrustableinstancePackage.Literals.PAPYRUS_TABLE_INSTANCE__TABLE == setting.getEStructuralFeature();
} else {
result = false;
}
return result;
}
};
/*
* Predicate used to keep the usages which are PapyrusTableInstances
*/
Predicate<Setting> keepTableInstances = new Predicate<Setting>() {
public boolean apply(Setting setting) {
boolean result = true;
if(setting != null) {
EObject settingEObject = setting.getEObject();
result &= settingEObject instanceof TableInstance;
result &= setting.getEStructuralFeature() == TableinstancePackage.Literals.TABLE_INSTANCE__CONTEXT;
Collection<Setting> references = PapyrusEcoreUtils.getUsages(settingEObject);
Iterable<Setting> papyrusTableInstances = Iterables.filter(references, keepPapyrusTableInstances);
//Veryfing that there is at least one papyrusTableInstance
result = result && !Iterables.isEmpty(papyrusTableInstances);
} else {
result = false;
}
return result;
}
};
/*
* Function to get the eObject from a setting
*/
Function<Setting, EObject> getEObject = new Function<Setting, EObject>() {
public EObject apply(Setting input) {
EObject settingEObject = input.getEObject();
Collection<Setting> references = PapyrusEcoreUtils.getUsages(settingEObject);
Iterable<Setting> papyrusTableInstances = Iterables.filter(references, keepPapyrusTableInstances);
//Getting the eobject of thie first element of this iterable.
return Iterables.get(papyrusTableInstances, 0).getEObject();
}
};
/*
* For the context and his descendants :
*/
while(contextAndDescendants.hasNext()) {
EObject current = contextAndDescendants.next();
//Usages
Iterable<Setting> usages = PapyrusEcoreUtils.getUsages(current);
//Filtering to keep only papyrus table instances.
Iterable<Setting> tableInstanceSettings = Iterables.filter(usages, keepTableInstances);
//Getting the eObjects
Iterable<EObject> papyrusTableInstances = Iterables.transform(tableInstanceSettings, getEObject);
//Adding all the kept usages.
Iterables.addAll(result, papyrusTableInstances);
}
return result;
}
}