KickJava   Java API By Example, From Geeks To Geeks.

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


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: CreateChildCommand.java,v 1.7 2005/06/08 06:17:05 nickb Exp $
16  */

17 package org.eclipse.emf.edit.command;
18
19
20 import java.util.Collection JavaDoc;
21 import java.util.Collections JavaDoc;
22
23 import org.eclipse.emf.common.command.Command;
24 import org.eclipse.emf.common.command.CommandWrapper;
25 import org.eclipse.emf.common.command.UnexecutableCommand;
26 import org.eclipse.emf.ecore.EObject;
27 import org.eclipse.emf.ecore.EStructuralFeature;
28 import org.eclipse.emf.ecore.util.FeatureMap;
29 import org.eclipse.emf.edit.EMFEditPlugin;
30 import org.eclipse.emf.edit.domain.EditingDomain;
31
32
33 /**
34  * This command wraps an {@link AddCommand} or {@link SetCommand} to
35  * provide the higher-level operation of "creating" an appropriate child
36  * object and adding it to a owner object. In fact, all of the possible
37  * child objects are created by the owner's item provider before this
38  * command is created, and specified in the <code>newChildDescriptor</code>
39  * argument to {@link #create create()} -- they must be, so that the user
40  * can specify which he actually wishes to create. As a result, this
41  * command essentially just creates and executes the appropriate lower-level
42  * EMF command, and delegates matters of appearance (text, icon, result) to
43  * the appropriate item provider, so that it may be handled correctly for
44  * the given model.
45  *
46  * <p>Note that this command makes no assumptions about the relationship
47  * between the <code>owner</code>, to which the new child will be added, and
48  * the selected object. This allows the command to be reused for sibling
49  * creation. As a result, the <code>selection</code> be explicitly
50  * specified, so that it can be restored when the command is undone.
51  */

52 public class CreateChildCommand extends CommandWrapper
53   implements CommandActionDelegate
54 {
55   /**
56    * This returns a command created by the editing domain to add the
57    * child described by <code>newChildDescriptor</code> to the given
58    * <code>object</code>.
59    */

60   public static Command create(EditingDomain domain, Object JavaDoc owner,
61                                Object JavaDoc newChildDescriptor,
62                                Collection JavaDoc selection)
63   {
64     return domain.createCommand(
65       CreateChildCommand.class,
66       new CommandParameter(owner, null, newChildDescriptor, selection));
67   }
68
69   /**
70    * This value is used to indicate that an optional positional index
71    * indicator is unspecified.
72    * @deprecated As of EMF 2.0, use {@link CommandParameter#NO_INDEX}, whose
73    * value is equal to this, instead.
74    */

75   protected static final int NO_INDEX = CommandParameter.NO_INDEX;
76
77   /**
78    * This is the editing doman in which this command operates.
79    */

80   protected EditingDomain domain;
81
82   /**
83    * This is the object to which the child will be added.
84    */

85   protected EObject owner;
86
87   /**
88    * This is the feature of the owner to which the child will be added.
89    */

90   protected EStructuralFeature feature;
91
92   /**
93    * This is the child object to be added.
94    */

95   protected Object JavaDoc child;
96
97   /**
98    * This is the index for the new object's position under the feature.
99    */

100   protected int index;
101
102   /**
103    * This is the helper object, usually the item provider for {@link #owner},
104    * to which parts of this command's functionality are delegated.
105    */

106   protected CreateChildCommand.Helper helper;
107
108   /**
109    * This is the value to be returned by {@link #getAffectedObjects}.
110    * The affected objects are different after an execute or redo from after
111    * an undo, so we record them.
112    */

113   protected Collection JavaDoc affectedObjects;
114
115   /**
116    * This is the collection of objects that were selected when this command
117    * was created. After an undo, these are considered the affected objects.
118    */

119   protected Collection JavaDoc selection;
120
121   /**
122    * This constructor initializes an instance that adds the specified
123    * <code>child</code> object to the <code>feature</code> of the
124    * <code>owner</code> object. If any of <code>owner</code>,
125    * <code>feature</code>, or <code>child</code> are <code>null</code>,
126    * {@link #createCommand} will return {@link UnexecutableCommand#INSTANCE}
127    * and, hence, {@link
128    * org.eclipse.emf.common.command.AbstractCommand#canExecute} will return
129    * <code>false</code>. If non-null, <code>selection</code> is the
130    * collection of selected objects. An internal default {@link Helper
131    * Helper} will provide generic implmentations for the delegated command
132    * methods.
133    */

134   public CreateChildCommand(EditingDomain domain,
135                             EObject owner,
136                             EStructuralFeature feature,
137                             Object JavaDoc child,
138                             Collection JavaDoc selection)
139   {
140     this(domain, owner, feature, child, CommandParameter.NO_INDEX, selection, null);
141   }
142
143   /**
144    * This constructor initializes an instance, as above, but the command
145    * delegates functionality to the specified {@link Helper Helper}.
146    * If <code>helper</code> is <code>null</code>, the internal default
147    * helper is used.
148    */

149   public CreateChildCommand(EditingDomain domain,
150                             EObject owner,
151                             EStructuralFeature feature,
152                             Object JavaDoc child,
153                             Collection JavaDoc selection,
154                             CreateChildCommand.Helper helper)
155   {
156     this(domain, owner, feature, child, CommandParameter.NO_INDEX, selection, helper);
157   }
158
159   /**
160    * This constructor initializes an instance that adds the specified
161    * <code>child</code> object to the <code>owner</code> object, at the
162    * specified <code>index</code> of its <code>feature</code> feature, if it
163    * is multi-valued. If any of <code>owner</code>, <code>feature</code>,
164    * or <code>child</code> are <code>null</code>, {@link #createCommand}
165    * will return {@link UnexecutableCommand#INSTANCE} and, hence, {@link
166    * org.eclipse.emf.common.command.AbstractCommand#canExecute} will return
167    * <code>false</code>. If non-null, <code>selection</code> is the
168    * collection of selected objects. The internal default helper is used by
169    * the command. If <code>index</code> is {@link CommandParameter#NO_INDEX},
170    * this behaves just like the first constructor form.
171    */

172   public CreateChildCommand(EditingDomain domain,
173                             EObject owner,
174                             EStructuralFeature feature,
175                             Object JavaDoc child,
176                             int index,
177                             Collection JavaDoc selection)
178   {
179     this(domain, owner, feature, child, index, selection, null);
180   }
181
182   /**
183    * This constructor initializes an instance, as above, but the command
184    * delegates functionality to the specified {@link Helper Helper}.
185    * If <code>helper</code> is <code>null</code>, the internal default
186    * helper is used.
187    */

188   public CreateChildCommand(EditingDomain domain,
189                             EObject owner,
190                             EStructuralFeature feature,
191                             Object JavaDoc child,
192                             int index,
193                             Collection JavaDoc selection,
194                             CreateChildCommand.Helper helper)
195   {
196     super();
197     this.domain = domain;
198     this.owner = owner;
199     this.feature = feature;
200     this.child = child;
201     this.index = index;
202     this.selection = selection == null ? Collections.EMPTY_LIST : selection;
203     this.helper = helper == null ? defaultHelper : helper;
204
205     // If we're creating a child under an object in a feature map, the selection will be the feature map entry.
206
// We want to replace it with the model object.
207
//
208
if (this.selection.size() == 1)
209     {
210       Object JavaDoc selObject = this.selection.iterator().next();
211       if (selObject instanceof FeatureMap.Entry && ((FeatureMap.Entry)selObject).getValue() == owner)
212       {
213         this.selection = Collections.singletonList(owner);
214       }
215     }
216
217     String JavaDoc text = this.helper.getCreateChildText(owner, feature, child, selection);
218     setLabel(EMFEditPlugin.INSTANCE.getString(
219       "_UI_CreateChildCommand_label", new Object JavaDoc[] { text }));
220     setDescription(EMFEditPlugin.INSTANCE.getString(
221       "_UI_CreateChildCommand_description"));
222   }
223
224   /**
225    * This creates the wrapped {@link AddCommand} or {@link SetCommand} that
226    * adds the child object to the model. If the owner, feature, or child
227    * is <code>null</code>, or if the feature is single-valued and has
228    * already been set to an object, {@link UnexecutableCommand#INSTANCE}
229    * will be returned.
230    */

231   protected Command createCommand()
232   {
233     if (owner == null || feature == null || child == null)
234     {
235       return UnexecutableCommand.INSTANCE;
236     }
237
238     if (feature.isMany())
239     {
240       return AddCommand.create(domain, owner, feature, child, index);
241     }
242     else if (owner.eGet(feature) == null)
243     {
244       return SetCommand.create(domain, owner, feature, child);
245     }
246     else
247     {
248       return UnexecutableCommand.INSTANCE;
249     }
250   }
251
252   /**
253    * This executes the wrapped command and sets the affected objects to the
254    * collection returned by <code>helper.getCreateChildResult()</code>.
255    */

256   public void execute()
257   {
258     super.execute();
259     affectedObjects = helper.getCreateChildResult(child);
260   }
261
262   /**
263    * This undoes the wrapped command and sets the affected objects to
264    * the original selection.
265    */

266   public void undo()
267   {
268     super.undo();
269     affectedObjects = selection;
270   }
271
272   /**
273    * This redoes the wrapped command and sets the affected objects to the
274    * collection returned by <code>helper.getCreateChildResult()</code>.
275    */

276   public void redo()
277   {
278     super.redo();
279     affectedObjects = helper.getCreateChildResult(child);
280   }
281
282   /**
283    * This returns the affected objects.
284    */

285   public Collection JavaDoc getAffectedObjects()
286   {
287     return affectedObjects == null ?
288       Collections.EMPTY_LIST : affectedObjects;
289   }
290
291   /**
292    * This returns the result of this command by delegating to
293    * <code>helper.getCreateChildResult()</code>.
294    */

295   public Collection JavaDoc getResult()
296   {
297     Collection JavaDoc result = helper.getCreateChildResult(child);
298     return result == null ? Collections.EMPTY_LIST : result;
299   }
300
301   /**
302    * This returns the label by delegating to
303    * <code>helper.getCreateChildText()</code>.
304    */

305   public String JavaDoc getText()
306   {
307     return helper.getCreateChildText(owner, feature, child, selection);
308   }
309
310   /**
311    * This returns the description by delegating to
312    * <code>helper.getCreateChildDescription()</code>.
313    */

314   public String JavaDoc getDescription()
315   {
316     return helper.getCreateChildDescription(owner, feature, child, selection);
317   }
318
319   /**
320    * This returns the tool tip text by delegating to
321    * <code>helper.getCreateChildToolTipText()</code>.
322    */

323   public String JavaDoc getToolTipText()
324   {
325     return helper.getCreateChildToolTipText(owner, feature, child, selection);
326   }
327
328   /**
329    * This returns the icon by delegating to
330    * <code>helper.getCreateChildImage()</code>.
331    */

332   public Object JavaDoc getImage()
333   {
334     return helper.getCreateChildImage(owner, feature, child, selection);
335   }
336
337   /**
338    * This is the helper interface to which <code>CreateChildCommand</code>
339    * functionality is delegated.
340    */

341   public static interface Helper
342   {
343     /**
344      * For a given child object, this returns the complete collection of
345      * objects to be presented as the command's result.
346      */

347     public Collection JavaDoc getCreateChildResult(Object JavaDoc child);
348     
349     /**
350      * This returns the text for the action of creating the specified
351      * <code>child</code> under the specified <code>feature</code> of the
352      * <code>owner</code>. The <code>selection</code> is given as context,
353      * from which the <code>Helper</code> can determine whether the object
354      * is being added as a child or a sibling, if it wishes.
355      */

356     public String JavaDoc getCreateChildText(Object JavaDoc owner, Object JavaDoc feature,
357                                      Object JavaDoc child, Collection JavaDoc selection);
358
359     /**
360      * This returns the description of the action of creating the specified
361      * <code>child</code> under the specified <code>feature</code> of the
362      * <code>owner</code>. The <code>selection</code> is given as context,
363      * from which the <code>Helper</code> can determine whether the object
364      * is being added as a child or a sibling, if it wishes.
365      */

366     public String JavaDoc getCreateChildDescription(Object JavaDoc owner,
367                                             Object JavaDoc feature,
368                                             Object JavaDoc child,
369                                             Collection JavaDoc selection);
370
371     /**
372      * This returns the tool tip text for the action of creating the
373      * specified <code>child</code> under the specified <code>feature</code>
374      * of the <code>owner</code>. The <code>selection</code> is given as
375      * context, from which the <code>Helper</code> can determine whether the
376      * object is being added as a child or a sibling, if it wishes.
377      */

378     public String JavaDoc getCreateChildToolTipText(Object JavaDoc owner,
379                                             Object JavaDoc feature,
380                                             Object JavaDoc child,
381                                             Collection JavaDoc selection);
382
383     /**
384      * This returns the icon for the action of creating the specified
385      * <code>child</code> under the specified <code>feature</code> of the
386      * <code>owner</code>. The <code>selection</code> is given as context,
387      * from which the <code>Helper</code> can determine whether the object
388      * is being added as a child or a sibling, if it wishes.
389      */

390     public Object JavaDoc getCreateChildImage(Object JavaDoc owner, Object JavaDoc feature,
391                                       Object JavaDoc child, Collection JavaDoc selection);
392   }
393
394   /**
395    * This is the default helper. It returns a singleton list of the child
396    * itself as a result; default text, description and tooltip text; and
397    * no image.
398    */

399   private static final Helper defaultHelper = new Helper()
400   {
401     public Collection JavaDoc getCreateChildResult(Object JavaDoc child)
402     {
403       return Collections.singletonList(child);
404     }
405
406     public String JavaDoc getCreateChildText(Object JavaDoc owner, Object JavaDoc feature,
407                                      Object JavaDoc child, Collection JavaDoc selection)
408     {
409       return EMFEditPlugin.INSTANCE.getString(
410         "_UI_CreateChild_text",
411         new Object JavaDoc[] {
412           EMFEditPlugin.INSTANCE.getString("_UI_Unknown_type"),
413           EMFEditPlugin.INSTANCE.getString("_UI_Unknown_feature"),
414           EMFEditPlugin.INSTANCE.getString("_UI_Unknown_type")
415         });
416     }
417     
418     public String JavaDoc getCreateChildDescription(Object JavaDoc owner, Object JavaDoc feature,
419                                             Object JavaDoc child, Collection JavaDoc selection)
420     {
421       return EMFEditPlugin.INSTANCE.getString(
422         "_UI_CreateChildCommand_description");
423     }
424
425     public String JavaDoc getCreateChildToolTipText(Object JavaDoc owner, Object JavaDoc feature,
426                                             Object JavaDoc child, Collection JavaDoc selection)
427     {
428       return EMFEditPlugin.INSTANCE.getString(
429         "_UI_CreateChild_tooltip",
430         new Object JavaDoc[] {
431           EMFEditPlugin.INSTANCE.getString("_UI_Unknown_type"),
432           EMFEditPlugin.INSTANCE.getString("_UI_Unknown_feature"),
433           EMFEditPlugin.INSTANCE.getString("_UI_Unknown_type")
434         });
435     }
436
437     public Object JavaDoc getCreateChildImage(Object JavaDoc owner, Object JavaDoc feature,
438                                       Object JavaDoc child, Collection JavaDoc selection)
439     {
440       return null;
441     }
442   };
443
444   /**
445    * This gives an abbreviated name using this object's own class name,
446    * without package qualification, followed by a space-separated list of
447    * <code>field:value</code> pairs.
448    */

449   public String JavaDoc toString()
450   {
451     StringBuffer JavaDoc result = new StringBuffer JavaDoc(super.toString());
452     result.append(" (domain: " + domain + ")");
453     result.append(" (owner: " + owner + ")");
454     result.append(" (feature: " + feature + ")");
455     result.append(" (child: " + child + ")");
456     result.append(" (index: " + index + ")");
457     result.append(" (helper: " + helper + ")");
458     result.append(" (affectedObjects: " + affectedObjects + ")");
459     result.append(" (selection: " + selection + ")");
460     return result.toString();
461   }
462 }
463
Popular Tags