KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > emf > edit > provider > FeatureMapEntryWrapperItemProvider


1 /**
2  * <copyright>
3  *
4  * Copyright (c) 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: FeatureMapEntryWrapperItemProvider.java,v 1.5 2005/06/08 06:17:05 nickb Exp $
16  */

17 package org.eclipse.emf.edit.provider;
18
19
20 import java.util.Collections JavaDoc;
21 import java.util.Iterator JavaDoc;
22 import java.util.List JavaDoc;
23
24 import org.eclipse.emf.common.command.Command;
25 import org.eclipse.emf.common.command.UnexecutableCommand;
26 import org.eclipse.emf.common.notify.AdapterFactory;
27 import org.eclipse.emf.common.util.ResourceLocator;
28 import org.eclipse.emf.ecore.EAttribute;
29 import org.eclipse.emf.ecore.EDataType;
30 import org.eclipse.emf.ecore.EObject;
31 import org.eclipse.emf.ecore.EStructuralFeature;
32 import org.eclipse.emf.ecore.util.EcoreUtil;
33 import org.eclipse.emf.ecore.util.ExtendedMetaData;
34 import org.eclipse.emf.ecore.util.FeatureMap;
35 import org.eclipse.emf.ecore.util.FeatureMapUtil;
36 import org.eclipse.emf.ecore.xml.type.XMLTypePackage;
37 import org.eclipse.emf.edit.EMFEditPlugin;
38 import org.eclipse.emf.edit.command.CommandParameter;
39 import org.eclipse.emf.edit.command.CopyCommand;
40 import org.eclipse.emf.edit.command.SetCommand;
41 import org.eclipse.emf.edit.domain.EditingDomain;
42
43
44 /**
45  * A wrapper for {@link org.eclipse.emf.ecore.util.FeatureMap.Entry}s. Feature map entry values can be either simple
46  * attribute values or model objects, so this wrapper provides behaviours appropriate for both, depending on the type
47  * of the entry feature. If it is a reference with a non-null value, an item provider will be obtained for that value,
48  * and most methods will delegate to that item provider. Otherwise, simple attribute-value-like implementations
49  * generally suffice. This wrapper's text and image values reflect the primary use of feature maps: to represent XML
50  * mixed content and choice model groups.
51  */

52 public class FeatureMapEntryWrapperItemProvider extends DelegatingWrapperItemProvider
53 {
54   /**
55    * The resource locator from the owner's item provider.
56    */

57   protected ResourceLocator resourceLocator;
58
59   /**
60    * Creates an instance for the feature map entry. If the entry's feature is a reference, a delegate item provider
61    * is created and set up to repeat notifications, decorating them, so that they will update this wrapper, rather
62    * than the model object they originate from. If the entry's feature is an attribute or a null reference, no delegate
63    * will be created.
64    *
65    * @exception IllegalArgumentException If the specified feature map entry is null.
66    */

67   public FeatureMapEntryWrapperItemProvider(
68       FeatureMap.Entry entry,
69       EObject owner,
70       EAttribute attribute,
71       int index,
72       AdapterFactory adapterFactory,
73       ResourceLocator resourceLocator)
74   {
75     super(entry, owner, attribute, index, adapterFactory);
76   }
77
78   /**
79    * Creates an instance for the feature map entry. If the entry's feature is not a reference, the item property
80    * descriptor that will be created for the value should get a resource. So, this constructor has been deprecated.
81    *
82    * @exception IllegalArgumentException If the specified feature map entry is null.
83    *
84    * @deprecated As of EMF 2.0.1, replaced by {@link #FeatureMapEntryWrapperItemProvider(FeatureMap.Entry, EObject, EAttribute, int index, AdapterFactory, ResourceLocator)
85    * this form}.
86    */

87   public FeatureMapEntryWrapperItemProvider(
88       FeatureMap.Entry entry,
89       EObject owner,
90       EAttribute attribute,
91       int index,
92       AdapterFactory adapterFactory)
93   {
94     this(entry, owner, attribute, index, adapterFactory, null);
95   }
96
97   /**
98    * Returns the value of the wrapped feature map entry.
99    */

100   protected Object JavaDoc getEntryValue()
101   {
102     return ((FeatureMap.Entry)value).getValue();
103   }
104
105   /**
106    * Returns the feature of the wrapped feature map entry.
107    */

108   protected EStructuralFeature getEntryFeature()
109   {
110     return ((FeatureMap.Entry)value).getEStructuralFeature();
111   }
112
113   /**
114    * Returns whether the feature of the wrapped feature map entry is an attribute.
115    */

116   protected boolean isEntryAttribute()
117   {
118     return getEntryFeature() instanceof EAttribute;
119   }
120
121   /**
122    * If the entry's feature is a reference, returns its value as the value from which to obtain and which to pass to a
123    * delegate item provider. If the entry's feature is an attribute, null is returned.
124    */

125   protected Object JavaDoc getDelegateValue()
126   {
127     return isEntryAttribute() ? null : getEntryValue();
128   }
129
130   /**
131    * Returns the appropriate text for the entry value. If the entry represents XML text, CDATA, or comment, it is
132    * appropriately decorated and {@link #encode encoded} to remove non-printable characters. Otherwise, the feature
133    * name is prepended to the text returned by the item provider decorator, for a reference value, or the factory
134    * method, for an attribute value.
135    */

136   public String JavaDoc getText(Object JavaDoc object)
137   {
138     String JavaDoc text = null;
139     XMLTypePackage xmlPackage = XMLTypePackage.eINSTANCE;
140
141     if (getEntryFeature() == xmlPackage.getXMLTypeDocumentRoot_Text())
142     {
143       text = encode(getEntryValue().toString());
144     }
145     else if (getEntryFeature() == xmlPackage.getXMLTypeDocumentRoot_CDATA())
146     {
147       text = "<![CDATA[" + encode(getEntryValue().toString()) + "]]>";
148     }
149     else if (getEntryFeature() == xmlPackage.getXMLTypeDocumentRoot_Comment())
150     {
151       text = "<!--" + encode(getEntryValue().toString()) + "-->";
152     }
153     else if (ExtendedMetaData.INSTANCE.getFeatureKind(feature) == ExtendedMetaData.ATTRIBUTE_WILDCARD_FEATURE && isEntryAttribute())
154     {
155       text = getEntryFeature().getName() + "='" +
156         EcoreUtil.convertToString((EDataType)getEntryFeature().getEType(), getEntryValue()) + "'";
157     }
158     else if (getEntryValue() == null)
159     {
160       text = "<" + getEntryFeature().getName() + " xsi:nil=\"true\"/>";
161     }
162     else if (isEntryAttribute())
163     {
164       text = addEntryFeature(EcoreUtil.convertToString((EDataType)getEntryFeature().getEType(), getEntryValue()));
165     }
166     else
167     {
168       text = addEntryFeature(super.getText(object));
169     }
170     return text;
171   }
172
173   /**
174    * Prepends the entry feature name to the given text and returns the result.
175    */

176   protected String JavaDoc addEntryFeature(String JavaDoc text)
177   {
178     return "<" + getEntryFeature().getName() + "> " + text;
179   }
180
181   /**
182    * Returns the appropriate image for the entry value: the text property icon for text, CDATA, or comment; the generic
183    * property icon for an attribute value; the generic item icon for a null reference value; or the icon returned by
184    * the delegate item provider for a non-null reference value.
185    */

186   public Object JavaDoc getImage(Object JavaDoc object)
187   {
188     Object JavaDoc image = null;
189     XMLTypePackage xmlPackage = XMLTypePackage.eINSTANCE;
190
191     if (getEntryFeature() == xmlPackage.getXMLTypeDocumentRoot_Text() ||
192         getEntryFeature() == xmlPackage.getXMLTypeDocumentRoot_CDATA() ||
193         getEntryFeature() == xmlPackage.getXMLTypeDocumentRoot_Comment())
194     {
195       image = EMFEditPlugin.INSTANCE.getImage("full/obj16/TextValue");
196     }
197     else if (isEntryAttribute())
198     {
199       image = EMFEditPlugin.INSTANCE.getImage("full/obj16/GenericValue");
200     }
201     else if (getDelegateValue() == null)
202     {
203       image = EMFEditPlugin.INSTANCE.getImage("full/obj16/Item");
204     }
205     else
206     {
207       image = super.getImage(object);
208     }
209     return image;
210   }
211
212   /**
213    * Encodes the given string by replacing any occurences of non-printable characters by the corresponding Java escape
214    * sequence.
215    */

216   protected String JavaDoc encode(String JavaDoc s)
217   {
218     StringBuffer JavaDoc result = new StringBuffer JavaDoc(s.length());
219     for (int i = 0, len = s.length(); i < len; i++)
220     {
221       char c = s.charAt(i);
222       switch (c)
223       {
224         case '\\':
225         {
226           result.append("\\\\");
227           break;
228         }
229         case '\b':
230         {
231           result.append("\\b");
232           break;
233         }
234         case '\t':
235         {
236           result.append("\\t");
237           break;
238         }
239         case '\n':
240         {
241           result.append("\\n");
242           break;
243         }
244         case '\f':
245         {
246           result.append("\\f");
247           break;
248         }
249         case '\r':
250         {
251           result.append("\\r");
252           break;
253         }
254         default:
255         {
256           result.append(c);
257           break;
258         }
259       }
260     }
261     return result.toString();
262   }
263
264   /**
265    * Decodes the given string by replacing any occurences Java escape sequences to actual characters.
266    */

267   protected String JavaDoc decode(String JavaDoc s)
268   {
269     StringBuffer JavaDoc result = new StringBuffer JavaDoc(s.length());
270     for (int i = 0, len = s.length(); i < len; i++)
271     {
272       char c = s.charAt(i);
273       switch (c)
274       {
275         case '\\':
276         {
277           if (++i < len)
278           {
279             c = s.charAt(i);
280             switch (c)
281             {
282               case '\\':
283               {
284                 result.append('\\');
285                 break;
286               }
287               case 'b':
288               {
289                 result.append('\b');
290                 break;
291               }
292               case 't':
293               {
294                 result.append('\t');
295                 break;
296               }
297               case 'n':
298               {
299                 result.append('\n');
300                 break;
301               }
302               case 'f':
303               {
304                 result.append('\f');
305                 break;
306               }
307               case '\r':
308               {
309                 result.append('\r');
310                 break;
311               }
312               default:
313               {
314                 result.append('\\');
315                 --i;
316                 break;
317               }
318             }
319           }
320           else
321           {
322             result.append(c);
323           }
324           break;
325         }
326         default:
327         {
328           result.append(c);
329           break;
330         }
331       }
332     }
333     return result.toString();
334   }
335
336   /**
337    * Uses the delegate item provider for a reference value or creates a single property descriptor for an attribute
338    * value.
339    */

340   public List JavaDoc getPropertyDescriptors(Object JavaDoc object)
341   {
342     if (isEntryAttribute())
343     {
344       if (propertyDescriptors == null)
345       {
346         propertyDescriptors = Collections.singletonList(
347           new WrapperItemPropertyDescriptor(resourceLocator, getEntryFeature())
348           {
349             protected Object JavaDoc getValue(EObject object, EStructuralFeature feature)
350             {
351               // When the value is changed, the property sheet page doesn't update the property sheet viewer input
352
// before refreshing, and this gets called on the obsolete wrapper. So, we need to read directly from the
353
// model object.
354
//
355
//return needsEncoding(feature) ? encode((String)getEntryValue()) : getEntryValue();
356

357               FeatureMap featureMap = (FeatureMap)((EObject)owner).eGet(FeatureMapEntryWrapperItemProvider.this.feature);
358               Object JavaDoc result = index >= 0 && index < featureMap.size() ? featureMap.getValue(index) : getEntryValue();
359               return needsEncoding(feature) ? encode((String JavaDoc)result) : result;
360             }
361             
362             protected void setValue(EObject object, EStructuralFeature feature, Object JavaDoc value)
363             {
364               if (needsEncoding(feature))
365               {
366                 value = decode((String JavaDoc)value);
367               }
368               ((FeatureMap)((EObject)owner).eGet(FeatureMapEntryWrapperItemProvider.this.feature)).setValue(index, value);
369             }
370
371             protected Command createSetCommand(EditingDomain domain, Object JavaDoc owner, Object JavaDoc feature, Object JavaDoc value)
372             {
373               if (needsEncoding(feature))
374               {
375                 value = decode((String JavaDoc)value);
376               }
377               return SetCommand.create(domain, getCommandOwner(FeatureMapEntryWrapperItemProvider.this), null, value);
378             }
379
380             protected boolean needsEncoding(Object JavaDoc feature)
381             {
382               return
383                 feature == XMLTypePackage.eINSTANCE.getXMLTypeDocumentRoot_Text() ||
384                 feature == XMLTypePackage.eINSTANCE.getXMLTypeDocumentRoot_CDATA() ||
385                 feature == XMLTypePackage.eINSTANCE.getXMLTypeDocumentRoot_Comment();
386             }
387           });
388       }
389       return propertyDescriptors;
390     }
391     else
392     {
393       return super.getPropertyDescriptors(object);
394     }
395   }
396
397   /**
398    * Uses the delegate item provider for a reference value or returns the attribute value itself.
399    */

400   public Object JavaDoc getEditableValue(Object JavaDoc object)
401   {
402     return isEntryAttribute() ? getEntryValue() : super.getEditableValue(object);
403   }
404
405   /**
406    * Returns whether the entry attribute is changeable.
407    */

408   protected boolean isPropertySettable()
409   {
410     return getEntryFeature().isChangeable();
411   }
412
413   /**
414    * Calls {@link WrapperItemProvider#getPropertyImage(Class) getPropertyImage} to obtain the property image for the
415    * entry attribute's type.
416    */

417   protected Object JavaDoc getPropertyImage()
418   {
419     return getPropertyImage(getEntryFeature().getEType().getInstanceClass());
420   }
421
422   /**
423    * Uses the delegate item provider or the base wrapper implementation to create a command.
424    */

425   public Command createCommand(Object JavaDoc object, EditingDomain domain, Class JavaDoc commandClass, CommandParameter commandParameter)
426   {
427     if (getDelegateValue() == null)
428     {
429       return baseCreateCommand(object, domain, commandClass, commandParameter);
430     }
431     return super.createCommand(object, domain, commandClass, commandParameter);
432   }
433
434   /**
435    * For a copy command, creates a {@link WrapperItemProvider.WrappingCopyCommand}, which copies the feature map entry
436    * and wrapper along with the entry value; for other commands, the wrapper-substituting command wrapper supplied by
437    * the base implementation is used. This method is only called for non-null reference values to wrap a command
438    * returned by the delegate item provider.
439    */

440   protected Command wrapCommand(Command command, Class JavaDoc commandClass)
441   {
442     if (commandClass == CopyCommand.class)
443     {
444       return new WrappingCopyCommand(command)
445       {
446         public IWrapperItemProvider copy()
447         {
448           Iterator JavaDoc i = getCommand().getResult().iterator();
449           return new FeatureMapEntryWrapperItemProvider(
450             FeatureMapUtil.createEntry(getEntryFeature(), i.next()), (EObject)owner, (EAttribute)feature, index, adapterFactory);
451         }
452       };
453     }
454     return super.wrapCommand(command, commandClass);
455   }
456
457   /**
458    * Returns a wrapped set command that returns as its affected object the replacement wrapper for the value.
459    * A feature map entry is also created for the value, and used as the value of the set command.
460    */

461   protected Command createSetCommand(EditingDomain domain, Object JavaDoc owner, Object JavaDoc feature, Object JavaDoc value, int index)
462   {
463     // Check that the value is type compatible with the entry feature.
464
//
465
if (getEntryFeature().getEType().isInstance(value))
466     {
467       FeatureMap.Entry entry = FeatureMapUtil.createEntry(getEntryFeature(), value);
468       return new ReplacementAffectedObjectCommand(SetCommand.create(domain, this.owner, this.feature, entry, this.index));
469     }
470     return UnexecutableCommand.INSTANCE;
471   }
472
473   /**
474    * This is only called for null or attribute values; it returns a {@link
475    * WrapperItemProvider.SimpleCopyCommand} that copies the wrapper.
476    */

477   protected Command createCopyCommand(EditingDomain domain, Object JavaDoc owner, CopyCommand.Helper helper)
478   {
479     return new SimpleCopyCommand(domain)
480     {
481       public IWrapperItemProvider copy()
482       {
483         Object JavaDoc entryValueCopy = null;
484         Object JavaDoc entryValue = getEntryValue();
485
486         if (entryValue != null)
487         {
488           EDataType dataType = (EDataType)getEntryFeature().getEType();
489           String JavaDoc serialization = EcoreUtil.convertToString(dataType, entryValue);
490           entryValueCopy = EcoreUtil.createFromString(dataType, serialization);
491           if (serialization == entryValue && serialization == entryValueCopy)
492           {
493             entryValueCopy = new String JavaDoc((String JavaDoc)entryValue);
494           }
495         }
496
497         return new FeatureMapEntryWrapperItemProvider(
498           FeatureMapUtil.createEntry(getEntryFeature(), entryValueCopy),
499           (EObject)FeatureMapEntryWrapperItemProvider.this.owner,
500           (EAttribute)feature,
501           index,
502           adapterFactory);
503       }
504     };
505   }
506 }
507
Popular Tags