KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > emf > edit > command > CopyCommand


1 /**
2  * <copyright>
3  *
4  * Copyright (c) 2002-2004 IBM Corporation and others.
5  * All rights reserved. This program and the accompanying materials
6  * are made available under the terms of the Eclipse Public License v1.0
7  * which accompanies this distribution, and is available at
8  * http://www.eclipse.org/legal/epl-v10.html
9  *
10  * Contributors:
11  * IBM - Initial API and implementation
12  *
13  * </copyright>
14  *
15  * $Id: CopyCommand.java,v 1.5 2005/06/08 06:17:05 nickb Exp $
16  */

17 package org.eclipse.emf.edit.command;
18
19
20 import java.util.ArrayList JavaDoc;
21 import java.util.Collection JavaDoc;
22 import java.util.HashMap JavaDoc;
23 import java.util.Iterator JavaDoc;
24
25 import org.eclipse.emf.common.command.Command;
26 import org.eclipse.emf.common.command.CompoundCommand;
27 import org.eclipse.emf.common.command.StrictCompoundCommand;
28 import org.eclipse.emf.common.command.UnexecutableCommand;
29 import org.eclipse.emf.ecore.EObject;
30 import org.eclipse.emf.edit.EMFEditPlugin;
31 import org.eclipse.emf.edit.domain.EditingDomain;
32
33
34 /**
35  * The copy command logically acts upon an owner object or collection or owner objects
36  * and copies the tree structured implied by the MOF containment hierarchy.
37  * The static create methods delegate command creation to {@link EditingDomain#createCommand EditingDomain.createCommand}.
38  *
39  * <p>
40  * The copy implementation is, at each level, delegated to {@link CreateCopyCommand} and
41  * {@link InitializeCopyCommand} which can be overriden to control the copy's object creation
42  * and initialization respectively.
43  */

44 public class CopyCommand extends StrictCompoundCommand
45 {
46   /**
47    * This creates a command that copies the given object.
48    */

49   public static Command create(EditingDomain domain, Object JavaDoc owner)
50   {
51     return domain.createCommand(CopyCommand.class, new CommandParameter(owner, null, new Helper()));
52   }
53
54   /**
55    * This creates a command that copies the given collection of objects. If the collection contains more than one object,
56    * then a compound command will be created containing individual copy commands for each object.
57    */

58   public static Command create(final EditingDomain domain, final Collection JavaDoc collection)
59   {
60     if (collection == null || collection.isEmpty())
61     {
62       return UnexecutableCommand.INSTANCE;
63     }
64
65     Helper copyHelper = new Helper();
66     CompoundCommand copyCommand = new CompoundCommand(CompoundCommand.MERGE_COMMAND_ALL);
67     for (Iterator JavaDoc objects = collection.iterator(); objects.hasNext(); )
68     {
69       copyCommand.append(domain.createCommand(CopyCommand.class, new CommandParameter(objects.next(), null, copyHelper)));
70     }
71
72     return copyCommand.unwrap();
73   }
74
75   /**
76    * This caches the label.
77    */

78   protected static final String JavaDoc LABEL = EMFEditPlugin.INSTANCE.getString("_UI_CopyCommand_label");
79
80   /**
81    * This caches the description.
82    */

83   protected static final String JavaDoc DESCRIPTION = EMFEditPlugin.INSTANCE.getString("_UI_CopyCommand_description");
84
85   /**
86    * This keeps track of the domain in which this command is created.
87    */

88   protected EditingDomain domain;
89
90   /**
91    * This keeps track of the owner in the command parameter from the constructor.
92    */

93   protected EObject owner;
94
95   /**
96    * This is a map of objects to their copies
97    */

98   protected Helper copyHelper;
99
100   /**
101    * This controls whether or not to optimize the canExecute (prepare)
102    */

103   protected boolean optimize;
104
105   /**
106    * This creates and instance in the given domain and for the given owner
107    */

108   public CopyCommand(EditingDomain domain, EObject owner, Helper copyHelper)
109   {
110     this(domain, owner, copyHelper, true);
111   }
112
113   /**
114    * This creates and instance in the given domain and for the given owner
115    */

116   public CopyCommand(EditingDomain domain, EObject owner, Helper copyHelper, boolean optimize)
117   {
118     super(LABEL, DESCRIPTION);
119
120     this.resultIndex = 0;
121     this.domain = domain;
122     this.owner = owner;
123     this.copyHelper = copyHelper;
124     this.optimize = optimize;
125
126     copyHelper.incrementDeferredInitializationCount();
127   }
128
129   protected boolean prepare()
130   {
131     if (owner == null)
132     {
133       return false;
134     }
135     
136     // Create commands to create the copy object(s).
137
//
138
CompoundCommand createCommand = new CompoundCommand(0);
139
140     addCreateCopyCommands(createCommand, owner);
141     append(createCommand.unwrap());
142
143     // Create an initialize copy command for each of the created objects.
144
//
145
if (copyHelper.decrementDeferredInitializationCount() == 0)
146     {
147       Command initializeCommand =
148         new CompoundCommand()
149         {
150           public boolean prepare()
151           {
152             for (Iterator JavaDoc copiedObjects = copyHelper.initializationIterator(); copiedObjects.hasNext(); )
153             {
154               EObject object = (EObject)copiedObjects.next();
155               Command initializeCopyCommand = InitializeCopyCommand.create(domain, object, copyHelper);
156   
157               // Record it for execution.
158
//
159
if (!this.appendIfCanExecute(initializeCopyCommand))
160               {
161                 return false;
162               }
163   
164               copiedObjects.remove();
165             }
166   
167             return true;
168           }
169         };
170       append(initializeCommand);
171     }
172
173     // This will execute the CreateCopyCommand's and then call canExecute on the InitializeCopyCommand's.
174
//
175
boolean result = super.prepare();
176
177     return result;
178   }
179
180   public boolean canExecute()
181   {
182     boolean result;
183     if (optimize)
184     {
185       // We'll assume that all the CreateCopyCommand's and InitializeCopyCommand's can execute.
186
//
187
result = true;
188     }
189     else
190     {
191       // This will call prepare() which will partially execute the command.
192
//
193
result = super.canExecute();
194     }
195
196     return result;
197   }
198
199   public void execute()
200   {
201     // We need to check canExecute() in case optimize is true.
202
//
203
if (super.canExecute())
204     {
205       super.execute();
206     }
207     else
208     {
209       // Thread.dumpStack();
210
}
211   }
212
213   protected void addCreateCopyCommands(CompoundCommand compoundCommand, EObject object)
214   {
215     // Create a command to create a copy of the object.
216
//
217
Command createCopyCommand = CreateCopyCommand.create(domain, object, copyHelper);
218     compoundCommand.append(createCopyCommand);
219
220     if (createCopyCommand instanceof ChildrenToCopyProvider && createCopyCommand.canExecute())
221     {
222       for (Iterator JavaDoc children = ((ChildrenToCopyProvider)createCopyCommand).getChildrenToCopy().iterator(); children.hasNext(); )
223       {
224         addCreateCopyCommands(compoundCommand, (EObject)children.next());
225       }
226     }
227     else
228     {
229       // Create commands to create copies of the children.
230
//
231
for (Iterator JavaDoc children = object.eContents().iterator(); children.hasNext(); )
232       {
233         addCreateCopyCommands(compoundCommand, (EObject)children.next());
234       }
235     }
236   }
237
238   /**
239    * This gives an abbreviated name using this object's own class' name, without package qualification,
240    * followed by a space separated list of <tt>field:value</tt> pairs.
241    */

242   public String JavaDoc toString()
243   {
244     StringBuffer JavaDoc result = new StringBuffer JavaDoc(super.toString());
245     result.append(" (domain: " + domain + ")");
246     result.append(" (owner: " + owner + ")");
247
248     return result.toString();
249   }
250
251   /**
252    * This helper class is used to keep track of copied objects and their associated copies.
253    */

254   public static class Helper extends HashMap JavaDoc
255   {
256     protected ArrayList JavaDoc initializationList = new ArrayList JavaDoc();
257     protected int deferredInitializationCount;
258
259     /**
260      * Return the copy of the specified object if it has one.
261      */

262     public EObject getCopy(EObject object)
263     {
264       return (EObject) get(object);
265     }
266
267     /**
268      * Return the copy of the specified object or the object itself if it has no copy.
269      */

270     public EObject getCopyTarget(EObject target, boolean copyRequired)
271     {
272       EObject copied = getCopy(target);
273       if (copied == null)
274       {
275         copied = copyRequired ? null : target;
276       }
277       return copied;
278     }
279
280     public Object JavaDoc put(Object JavaDoc key, Object JavaDoc value)
281     {
282       initializationList.add(key);
283       return super.put(key, value);
284     }
285
286     public Object JavaDoc remove(Object JavaDoc key)
287     {
288       initializationList.remove(key);
289       return super.remove(key);
290     }
291
292     public Iterator JavaDoc initializationIterator()
293     {
294       return initializationList.iterator();
295     }
296
297     public void incrementDeferredInitializationCount()
298     {
299       ++deferredInitializationCount;
300     }
301
302     public int decrementDeferredInitializationCount()
303     {
304       return --deferredInitializationCount;
305     }
306   }
307 }
308
Popular Tags