All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.emf.edit.command.CopyCommand Maven / Gradle / Ivy

/**
 * 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 v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 * 
 * Contributors: 
 *   IBM - Initial API and implementation
 */
package org.eclipse.emf.edit.command;


import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;

import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.common.command.IdentityCommand;
import org.eclipse.emf.common.command.StrictCompoundCommand;
import org.eclipse.emf.common.command.UnexecutableCommand;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.EMFEditPlugin;
import org.eclipse.emf.edit.domain.EditingDomain;


/**
 * The copy command logically acts upon an owner object or collection or owner objects 
 * and copies the tree structured implied by the MOF containment hierarchy.
 * The static create methods delegate command creation to {@link EditingDomain#createCommand EditingDomain.createCommand}.
 *
 * 

* The copy implementation is, at each level, delegated to {@link CreateCopyCommand} and * {@link InitializeCopyCommand} which can be overridden to control the copy's object creation * and initialization respectively. */ public class CopyCommand extends StrictCompoundCommand { /** * This creates a command that copies the given object. */ public static Command create(EditingDomain domain, Object owner) { return domain.createCommand(CopyCommand.class, new CommandParameter(owner, null, new Helper())); } /** * This creates a command that copies the given collection of objects. If the collection contains more than one object, * then a compound command will be created containing individual copy commands for each object. */ public static Command create(final EditingDomain domain, final Collection collection) { if (collection == null || collection.isEmpty()) { return UnexecutableCommand.INSTANCE; } Helper copyHelper = new Helper(); CompoundCommand copyCommand = new CompoundCommand(CompoundCommand.MERGE_COMMAND_ALL); for (Object object : collection) { copyCommand.append(domain.createCommand(CopyCommand.class, new CommandParameter(object, null, copyHelper))); } return copyCommand.unwrap(); } /** * This caches the label. */ protected static final String LABEL = EMFEditPlugin.INSTANCE.getString("_UI_CopyCommand_label"); /** * This caches the description. */ protected static final String DESCRIPTION = EMFEditPlugin.INSTANCE.getString("_UI_CopyCommand_description"); /** * This keeps track of the domain in which this command is created. */ protected EditingDomain domain; /** * This keeps track of the owner in the command parameter from the constructor. */ protected EObject owner; /** * This is a map of objects to their copies */ protected Helper copyHelper; /** * This controls whether or not to optimize the canExecute (prepare) */ protected boolean optimize; /** * This creates and instance in the given domain and for the given owner */ public CopyCommand(EditingDomain domain, EObject owner, Helper copyHelper) { this(domain, owner, copyHelper, true); } /** * This creates and instance in the given domain and for the given owner */ public CopyCommand(EditingDomain domain, EObject owner, Helper copyHelper, boolean optimize) { super(LABEL, DESCRIPTION); this.resultIndex = 0; this.domain = domain; this.owner = owner; this.copyHelper = copyHelper; this.optimize = optimize; copyHelper.incrementDeferredInitializationCount(); } @Override protected boolean prepare() { if (owner == null) { return false; } // Create commands to create the copy object(s). // CompoundCommand createCommand = new CompoundCommand(0); addCreateCopyCommands(createCommand, owner); append(createCommand.unwrap()); // Create an initialize copy command for each of the created objects. // if (copyHelper.decrementDeferredInitializationCount() == 0) { Command initializeCommand = new CompoundCommand() { @Override public boolean prepare() { for (Iterator copiedObjects = copyHelper.initializationIterator(); copiedObjects.hasNext(); ) { EObject object = copiedObjects.next(); Command initializeCopyCommand = InitializeCopyCommand.create(domain, object, copyHelper); // Record it for execution. // if (!this.appendIfCanExecute(initializeCopyCommand)) { return false; } copiedObjects.remove(); } return true; } }; append(initializeCommand); } else if (!optimize) { // This ensures that the CreateCopyCommand will be executed by StrictCompoundCommand.prepare(). // append(IdentityCommand.INSTANCE); } // This will execute the CreateCopyCommand's and then call canExecute on the InitializeCopyCommand's. // boolean result = super.prepare(); return result; } @Override public boolean canExecute() { boolean result; if (optimize) { // We'll assume that all the CreateCopyCommand's and InitializeCopyCommand's can execute. // result = true; } else { // This will call prepare() which will partially execute the command. // result = super.canExecute(); } return result; } @Override public void execute() { // We need to check canExecute() in case optimize is true. // if (super.canExecute()) { super.execute(); } else { // Thread.dumpStack(); } } protected void addCreateCopyCommands(CompoundCommand compoundCommand, EObject object) { // Create a command to create a copy of the object. // Command createCopyCommand = CreateCopyCommand.create(domain, object, copyHelper); compoundCommand.append(createCopyCommand); if (createCopyCommand instanceof ChildrenToCopyProvider && createCopyCommand.canExecute()) { for (Object child : ((ChildrenToCopyProvider)createCopyCommand).getChildrenToCopy()) { addCreateCopyCommands(compoundCommand, (EObject)child); } } else { // Create commands to create copies of the children. // for (EObject child : object.eContents()) { addCreateCopyCommands(compoundCommand, child); } } } /** * This gives an abbreviated name using this object's own class' name, without package qualification, * followed by a space separated list of field:value pairs. */ @Override public String toString() { StringBuilder result = new StringBuilder(super.toString()); result.append(" (domain: " + domain + ")"); result.append(" (owner: " + owner + ")"); return result.toString(); } /** * This helper class is used to keep track of copied objects and their associated copies. */ public static class Helper extends HashMap { private static final long serialVersionUID = 1L; protected ArrayList initializationList = new ArrayList(); protected int deferredInitializationCount; /** * Return the copy of the specified object if it has one. */ public EObject getCopy(EObject object) { return get(object); } /** * Return the copy of the specified object or the object itself if it has no copy. */ public EObject getCopyTarget(EObject target, boolean copyRequired) { EObject copied = getCopy(target); if (copied == null) { copied = copyRequired ? null : target; } return copied; } @Override public EObject put(EObject key, EObject value) { initializationList.add(key); return super.put(key, value); } @Override public EObject remove(Object key) { initializationList.remove(key); return super.remove(key); } public Iterator initializationIterator() { return initializationList.iterator(); } public void incrementDeferredInitializationCount() { ++deferredInitializationCount; } public int decrementDeferredInitializationCount() { return --deferredInitializationCount; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy