/** * Copyright (c) 2002-2006 IBM Corporation 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: * IBM - Initial API and implementation */ package org.eclipse.emf.mapping.command; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import org.eclipse.emf.common.command.AbstractCommand; import org.eclipse.emf.common.command.Command; import org.eclipse.emf.common.command.CompoundCommand; import org.eclipse.emf.edit.command.AddCommand; import org.eclipse.emf.edit.command.CommandParameter; import org.eclipse.emf.edit.command.RemoveCommand; import org.eclipse.emf.mapping.Mapping; import org.eclipse.emf.mapping.MappingPackage; import org.eclipse.emf.mapping.MappingPlugin; import org.eclipse.emf.mapping.domain.MappingDomain; /** * The create mapping command creates a new mapping in a {@link MappingDomain} * from a set of the domain's input and output objects. */ public class AddMappingCommand extends AbstractCommand { /** * This creates a command that adds the new mappings in the collection into the appropriate place in the mapping root's. */ public static Command create(MappingDomain domain, Collection<?> collection) { return domain.createCommand (AddMappingCommand.class, new CommandParameter(domain.getMappingRoot(), null, collection)); } /** * This creates a command that adds the new mappings in the collection into the appropriate place in the mapping root's. */ public static Command create(MappingDomain domain, Mapping mapping) { return create(domain, Collections.singleton(mapping)); } /** * This caches the label. */ protected static final String LABEL = MappingPlugin.getPlugin().getString("_UI_AddMappingCommand_label"); /** * This cachaes the description. */ protected static final String DESCRIPTION = MappingPlugin.getPlugin().getString("_UI_AddMappingCommand_description"); /** * This keeps track of the mapping domain in which the command operates. */ protected MappingDomain domain; /** * This keeps track of the input and output objects that are to be mapped. */ protected Collection<?> collection; /** * This keeps track of all the subcommand(s) use to implement this command. */ Command subcommand; /** * This creates a command instance that adds the new mappings in the collection into the appropriate place in the mapping root's. */ public AddMappingCommand(MappingDomain domain, Collection<?> collection) { super(LABEL, DESCRIPTION); this.domain = domain; this.collection = collection; } @Override protected boolean prepare() { boolean result = domain != null; for (Object object : collection) { if (!(object instanceof Mapping)) { result = false; break; } } return result; } public void execute() { // This will deal with all the subcommands to modifying the root mapping tree. // CompoundCommand subcommands = new CompoundCommand(); // For each mapping being added... // for (Object object : collection) { Mapping mapping = (Mapping)object; // Find the appropriate parent mapping, which at the very least, should be the mapping root itself. // Mapping parentMapping = domain.getMappingRoot().getParentMapping(mapping.getMappedObjects()); // Make sure the back pointers to this mapping from the mapped objects is set. // domain.getMappingRoot().register(mapping); // Create a command to do parentMapping.getNested().add(mapping). // //if (subcommands.appendAndExecute(new AddCommand(domain, parentMapping, parentMapping.ePackageMapping().getMapping_Nested(), mapping))) if (subcommands.appendAndExecute(new AddCommand(domain, parentMapping, MappingPackage.eINSTANCE.getMapping_Nested(), mapping))) { // Check all the siblings to see which if any should now be nested under this new mapping. // The are accumulated into a list so that they can be removed as a single command with a single notification. // Collection<Mapping> siblingsToReparent = new ArrayList<Mapping>(); for (Mapping siblingMapping : parentMapping.getNested()) { if (siblingMapping != mapping) { if (domain.getMappingRoot().getParentMapping(siblingMapping.getMappedObjects()) == mapping) { siblingsToReparent.add(siblingMapping); } } } // If there are siblings that need to be reparented. // if (!siblingsToReparent.isEmpty()) { // Create commands to do parentMapping.getNested().removeAll(siblingsToReparent). // subcommands.appendAndExecute //(new RemoveCommand(domain, parentMapping, parentMapping.ePackageMapping().getMapping_Nested(), siblingsToReparent)); (new RemoveCommand(domain, parentMapping, MappingPackage.eINSTANCE.getMapping_Nested(), siblingsToReparent)); // Create commands to do mapping.getNested().addAll(siblingsToReparent). // subcommands.appendAndExecute //(new AddCommand(domain, mapping, mapping.ePackageMapping().getMapping_Nested(), siblingsToReparent)); (new AddCommand(domain, mapping, MappingPackage.eINSTANCE.getMapping_Nested(), siblingsToReparent)); } } } subcommand = subcommands.unwrap(); } @Override public void undo() { for (Object object : collection) { Mapping mapping = (Mapping)object; domain.getMappingRoot().deregister(mapping); } subcommand.undo(); } public void redo() { for (Object object : collection) { Mapping mapping = (Mapping)object; domain.getMappingRoot().register(mapping); } subcommand.redo(); } @Override public Collection<?> getResult() { return collection; } @Override public Collection<?> getAffectedObjects() { return collection; } @Override public void dispose() { if (subcommand != null) { subcommand.dispose(); } super.dispose(); } /** * This gives an abbreviated name using this object's own class' name, without package qualification, * followed by a space separated list of <tt>field:value</tt> pairs. */ @Override public String toString() { StringBuffer result = new StringBuffer(super.toString()); result.append(" (domain: " + domain + ")"); result.append(" (collection: " + collection + ")"); result.append(" (subcommand: " + subcommand + ")"); return result.toString(); } }