KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > emf > mapping > impl > MappingRootImpl


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: MappingRootImpl.java,v 1.5 2005/06/08 06:21:43 nickb Exp $
16  */

17 package org.eclipse.emf.mapping.impl;
18
19
20 import java.util.ArrayList JavaDoc;
21 import java.util.Collection JavaDoc;
22 import java.util.Collections JavaDoc;
23 import java.util.HashSet JavaDoc;
24 import java.util.Iterator JavaDoc;
25
26 import org.eclipse.emf.common.notify.Adapter;
27 import org.eclipse.emf.common.notify.AdapterFactory;
28 import org.eclipse.emf.common.notify.Notification;
29 import org.eclipse.emf.common.notify.NotificationChain;
30 import org.eclipse.emf.common.notify.Notifier;
31 import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl;
32 import org.eclipse.emf.common.notify.impl.AdapterImpl;
33 import org.eclipse.emf.common.notify.impl.NotificationImpl;
34 import org.eclipse.emf.common.notify.impl.NotifyingListImpl;
35 import org.eclipse.emf.common.util.TreeIterator;
36 import org.eclipse.emf.ecore.EClass;
37 import org.eclipse.emf.ecore.EObject;
38 import org.eclipse.emf.ecore.EStructuralFeature;
39 import org.eclipse.emf.ecore.InternalEObject;
40 import org.eclipse.emf.ecore.impl.ENotificationImpl;
41 import org.eclipse.emf.ecore.util.InternalEList;
42 import org.eclipse.emf.edit.provider.ChangeNotifier;
43 import org.eclipse.emf.edit.provider.Disposable;
44 import org.eclipse.emf.edit.provider.IDisposable;
45 import org.eclipse.emf.edit.provider.INotifyChangedListener;
46 import org.eclipse.emf.mapping.MappedObjectState;
47 import org.eclipse.emf.mapping.Mapping;
48 import org.eclipse.emf.mapping.MappingFactory;
49 import org.eclipse.emf.mapping.MappingHelper;
50 import org.eclipse.emf.mapping.MappingPackage;
51 import org.eclipse.emf.mapping.MappingRoot;
52 import org.eclipse.emf.mapping.domain.MappingDomain;
53
54
55 /**
56  * <!-- begin-user-doc -->
57  * An implementation of the model object '<em><b>Root</b></em>'.
58  * <!-- end-user-doc -->
59  * <p>
60  * The following features are implemented:
61  * <ul>
62  * <li>{@link org.eclipse.emf.mapping.impl.MappingRootImpl#isOutputReadOnly <em>Output Read Only</em>}</li>
63  * <li>{@link org.eclipse.emf.mapping.impl.MappingRootImpl#isTopToBottom <em>Top To Bottom</em>}</li>
64  * <li>{@link org.eclipse.emf.mapping.impl.MappingRootImpl#getCommandStack <em>Command Stack</em>}</li>
65  * </ul>
66  * </p>
67  *
68  * @generated
69  */

70 public class MappingRootImpl extends MappingImpl implements MappingRoot
71 {
72   /**
73    * The default value of the '{@link #isOutputReadOnly() <em>Output Read Only</em>}' attribute.
74    * <!-- begin-user-doc -->
75    * <!-- end-user-doc -->
76    * @see #isOutputReadOnly()
77    * @generated
78    * @ordered
79    */

80   protected static final boolean OUTPUT_READ_ONLY_EDEFAULT = false;
81
82   /**
83    * The cached value of the '{@link #isOutputReadOnly() <em>Output Read Only</em>}' attribute.
84    * <!-- begin-user-doc -->
85    * <!-- end-user-doc -->
86    * @see #isOutputReadOnly()
87    * @generated
88    * @ordered
89    */

90   protected boolean outputReadOnly = OUTPUT_READ_ONLY_EDEFAULT;
91
92   /**
93    * The default value of the '{@link #isTopToBottom() <em>Top To Bottom</em>}' attribute.
94    * <!-- begin-user-doc -->
95    * <!-- end-user-doc -->
96    * @see #isTopToBottom()
97    * @generated
98    * @ordered
99    */

100   protected static final boolean TOP_TO_BOTTOM_EDEFAULT = false;
101
102   /**
103    * The cached value of the '{@link #isTopToBottom() <em>Top To Bottom</em>}' attribute.
104    * <!-- begin-user-doc -->
105    * <!-- end-user-doc -->
106    * @see #isTopToBottom()
107    * @generated
108    * @ordered
109    */

110   protected boolean topToBottom = TOP_TO_BOTTOM_EDEFAULT;
111
112   /**
113    * The default value of the '{@link #getCommandStack() <em>Command Stack</em>}' attribute.
114    * <!-- begin-user-doc -->
115    * <!-- end-user-doc -->
116    * @see #getCommandStack()
117    * @generated
118    * @ordered
119    */

120   protected static final String JavaDoc COMMAND_STACK_EDEFAULT = null;
121
122   /**
123    * The cached value of the '{@link #getCommandStack() <em>Command Stack</em>}' attribute.
124    * <!-- begin-user-doc -->
125    * <!-- end-user-doc -->
126    * @see #getCommandStack()
127    * @generated
128    * @ordered
129    */

130   protected String JavaDoc commandStack = COMMAND_STACK_EDEFAULT;
131   
132   /**
133    * This keeps track of the mapping domain that uses this mapping root.
134    */

135   protected MappingDomain domain;
136
137   /**
138    * This keeps track of whether the output has been modified.
139    */

140   protected boolean outputDirty = false;
141
142   /**
143    * This allows this listen for changes to inputs or outputs.
144    */

145   protected AdapterImpl mappedObjectListener;
146
147   /**
148    * This keeps track of the factory for creating the {@link org.eclipse.emf.mapping.MappedObjectState}.
149    */

150   protected AdapterFactory mappedObjectStateAdapterFactory;
151
152
153   /**
154    * <!-- begin-user-doc -->
155    * <!-- end-user-doc -->
156    */

157   protected MappingRootImpl()
158   {
159     super();
160     this.mappedObjectStateAdapterFactory = createMappedObjectStateAdapterFactory();
161   }
162
163   /**
164    * <!-- begin-user-doc -->
165    * <!-- end-user-doc -->
166    * @generated
167    */

168   protected EClass eStaticClass()
169   {
170     return MappingPackage.eINSTANCE.getMappingRoot();
171   }
172
173   /**
174    * <!-- begin-user-doc -->
175    * <!-- end-user-doc -->
176    * @generated
177    */

178   public boolean isOutputReadOnly()
179   {
180     return outputReadOnly;
181   }
182
183   /**
184    * <!-- begin-user-doc -->
185    * <!-- end-user-doc -->
186    * @generated
187    */

188   public void setOutputReadOnly(boolean newOutputReadOnly)
189   {
190     boolean oldOutputReadOnly = outputReadOnly;
191     outputReadOnly = newOutputReadOnly;
192     if (eNotificationRequired())
193       eNotify(new ENotificationImpl(this, Notification.SET, MappingPackage.MAPPING_ROOT__OUTPUT_READ_ONLY, oldOutputReadOnly, outputReadOnly));
194   }
195
196   /**
197    * <!-- begin-user-doc -->
198    * <!-- end-user-doc -->
199    * @generated
200    */

201   public boolean isTopToBottom()
202   {
203     return topToBottom;
204   }
205
206   /**
207    * <!-- begin-user-doc -->
208    * <!-- end-user-doc -->
209    * @generated
210    */

211   public void setTopToBottom(boolean newTopToBottom)
212   {
213     boolean oldTopToBottom = topToBottom;
214     topToBottom = newTopToBottom;
215     if (eNotificationRequired())
216       eNotify(new ENotificationImpl(this, Notification.SET, MappingPackage.MAPPING_ROOT__TOP_TO_BOTTOM, oldTopToBottom, topToBottom));
217   }
218
219   /**
220    * <!-- begin-user-doc -->
221    * <!-- end-user-doc -->
222    * @generated
223    */

224   public String JavaDoc getCommandStack()
225   {
226     return commandStack;
227   }
228
229   /**
230    * <!-- begin-user-doc -->
231    * <!-- end-user-doc -->
232    * @generated
233    */

234   public void setCommandStack(String JavaDoc newCommandStack)
235   {
236     String JavaDoc oldCommandStack = commandStack;
237     commandStack = newCommandStack;
238     if (eNotificationRequired())
239       eNotify(new ENotificationImpl(this, Notification.SET, MappingPackage.MAPPING_ROOT__COMMAND_STACK, oldCommandStack, commandStack));
240   }
241
242   /**
243    * <!-- begin-user-doc -->
244    * <!-- end-user-doc -->
245    * @generated
246    */

247   public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, Class JavaDoc baseClass, NotificationChain msgs)
248   {
249     if (featureID >= 0)
250     {
251       switch (eDerivedStructuralFeatureID(featureID, baseClass))
252       {
253         case MappingPackage.MAPPING_ROOT__HELPER:
254           if (helper != null)
255             msgs = ((InternalEObject)helper).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - MappingPackage.MAPPING_ROOT__HELPER, null, msgs);
256           return basicSetHelper((MappingHelper)otherEnd, msgs);
257         case MappingPackage.MAPPING_ROOT__NESTED:
258           return ((InternalEList)getNested()).basicAdd(otherEnd, msgs);
259         case MappingPackage.MAPPING_ROOT__NESTED_IN:
260           if (eContainer != null)
261             msgs = eBasicRemoveFromContainer(msgs);
262           return eBasicSetContainer(otherEnd, MappingPackage.MAPPING_ROOT__NESTED_IN, msgs);
263         default:
264           return eDynamicInverseAdd(otherEnd, featureID, baseClass, msgs);
265       }
266     }
267     if (eContainer != null)
268       msgs = eBasicRemoveFromContainer(msgs);
269     return eBasicSetContainer(otherEnd, featureID, msgs);
270   }
271
272   /**
273    * <!-- begin-user-doc -->
274    * <!-- end-user-doc -->
275    * @generated
276    */

277   public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, Class JavaDoc baseClass, NotificationChain msgs)
278   {
279     if (featureID >= 0)
280     {
281       switch (eDerivedStructuralFeatureID(featureID, baseClass))
282       {
283         case MappingPackage.MAPPING_ROOT__HELPER:
284           return basicSetHelper(null, msgs);
285         case MappingPackage.MAPPING_ROOT__NESTED:
286           return ((InternalEList)getNested()).basicRemove(otherEnd, msgs);
287         case MappingPackage.MAPPING_ROOT__NESTED_IN:
288           return eBasicSetContainer(null, MappingPackage.MAPPING_ROOT__NESTED_IN, msgs);
289         default:
290           return eDynamicInverseRemove(otherEnd, featureID, baseClass, msgs);
291       }
292     }
293     return eBasicSetContainer(null, featureID, msgs);
294   }
295
296   /**
297    * <!-- begin-user-doc -->
298    * <!-- end-user-doc -->
299    * @generated
300    */

301   public NotificationChain eBasicRemoveFromContainer(NotificationChain msgs)
302   {
303     if (eContainerFeatureID >= 0)
304     {
305       switch (eContainerFeatureID)
306       {
307         case MappingPackage.MAPPING_ROOT__NESTED_IN:
308           return eContainer.eInverseRemove(this, MappingPackage.MAPPING__NESTED, Mapping.class, msgs);
309         default:
310           return eDynamicBasicRemoveFromContainer(msgs);
311       }
312     }
313     return eContainer.eInverseRemove(this, EOPPOSITE_FEATURE_BASE - eContainerFeatureID, null, msgs);
314   }
315
316   /**
317    * <!-- begin-user-doc -->
318    * <!-- end-user-doc -->
319    * @generated
320    */

321   public Object JavaDoc eGet(EStructuralFeature eFeature, boolean resolve)
322   {
323     switch (eDerivedStructuralFeatureID(eFeature))
324     {
325       case MappingPackage.MAPPING_ROOT__HELPER:
326         return getHelper();
327       case MappingPackage.MAPPING_ROOT__NESTED:
328         return getNested();
329       case MappingPackage.MAPPING_ROOT__NESTED_IN:
330         return getNestedIn();
331       case MappingPackage.MAPPING_ROOT__INPUTS:
332         return getInputs();
333       case MappingPackage.MAPPING_ROOT__OUTPUTS:
334         return getOutputs();
335       case MappingPackage.MAPPING_ROOT__TYPE_MAPPING:
336         if (resolve) return getTypeMapping();
337         return basicGetTypeMapping();
338       case MappingPackage.MAPPING_ROOT__OUTPUT_READ_ONLY:
339         return isOutputReadOnly() ? Boolean.TRUE : Boolean.FALSE;
340       case MappingPackage.MAPPING_ROOT__TOP_TO_BOTTOM:
341         return isTopToBottom() ? Boolean.TRUE : Boolean.FALSE;
342       case MappingPackage.MAPPING_ROOT__COMMAND_STACK:
343         return getCommandStack();
344     }
345     return eDynamicGet(eFeature, resolve);
346   }
347
348   /**
349    * <!-- begin-user-doc -->
350    * <!-- end-user-doc -->
351    * @generated
352    */

353   public void eSet(EStructuralFeature eFeature, Object JavaDoc newValue)
354   {
355     switch (eDerivedStructuralFeatureID(eFeature))
356     {
357       case MappingPackage.MAPPING_ROOT__HELPER:
358         setHelper((MappingHelper)newValue);
359         return;
360       case MappingPackage.MAPPING_ROOT__NESTED:
361         getNested().clear();
362         getNested().addAll((Collection JavaDoc)newValue);
363         return;
364       case MappingPackage.MAPPING_ROOT__NESTED_IN:
365         setNestedIn((Mapping)newValue);
366         return;
367       case MappingPackage.MAPPING_ROOT__INPUTS:
368         getInputs().clear();
369         getInputs().addAll((Collection JavaDoc)newValue);
370         return;
371       case MappingPackage.MAPPING_ROOT__OUTPUTS:
372         getOutputs().clear();
373         getOutputs().addAll((Collection JavaDoc)newValue);
374         return;
375       case MappingPackage.MAPPING_ROOT__TYPE_MAPPING:
376         setTypeMapping((Mapping)newValue);
377         return;
378       case MappingPackage.MAPPING_ROOT__OUTPUT_READ_ONLY:
379         setOutputReadOnly(((Boolean JavaDoc)newValue).booleanValue());
380         return;
381       case MappingPackage.MAPPING_ROOT__TOP_TO_BOTTOM:
382         setTopToBottom(((Boolean JavaDoc)newValue).booleanValue());
383         return;
384       case MappingPackage.MAPPING_ROOT__COMMAND_STACK:
385         setCommandStack((String JavaDoc)newValue);
386         return;
387     }
388     eDynamicSet(eFeature, newValue);
389   }
390
391   /**
392    * <!-- begin-user-doc -->
393    * <!-- end-user-doc -->
394    * @generated
395    */

396   public void eUnset(EStructuralFeature eFeature)
397   {
398     switch (eDerivedStructuralFeatureID(eFeature))
399     {
400       case MappingPackage.MAPPING_ROOT__HELPER:
401         setHelper((MappingHelper)null);
402         return;
403       case MappingPackage.MAPPING_ROOT__NESTED:
404         getNested().clear();
405         return;
406       case MappingPackage.MAPPING_ROOT__NESTED_IN:
407         setNestedIn((Mapping)null);
408         return;
409       case MappingPackage.MAPPING_ROOT__INPUTS:
410         getInputs().clear();
411         return;
412       case MappingPackage.MAPPING_ROOT__OUTPUTS:
413         getOutputs().clear();
414         return;
415       case MappingPackage.MAPPING_ROOT__TYPE_MAPPING:
416         setTypeMapping((Mapping)null);
417         return;
418       case MappingPackage.MAPPING_ROOT__OUTPUT_READ_ONLY:
419         setOutputReadOnly(OUTPUT_READ_ONLY_EDEFAULT);
420         return;
421       case MappingPackage.MAPPING_ROOT__TOP_TO_BOTTOM:
422         setTopToBottom(TOP_TO_BOTTOM_EDEFAULT);
423         return;
424       case MappingPackage.MAPPING_ROOT__COMMAND_STACK:
425         setCommandStack(COMMAND_STACK_EDEFAULT);
426         return;
427     }
428     eDynamicUnset(eFeature);
429   }
430
431   /**
432    * <!-- begin-user-doc -->
433    * <!-- end-user-doc -->
434    * @generated
435    */

436   public boolean eIsSet(EStructuralFeature eFeature)
437   {
438     switch (eDerivedStructuralFeatureID(eFeature))
439     {
440       case MappingPackage.MAPPING_ROOT__HELPER:
441         return helper != null;
442       case MappingPackage.MAPPING_ROOT__NESTED:
443         return nested != null && !nested.isEmpty();
444       case MappingPackage.MAPPING_ROOT__NESTED_IN:
445         return getNestedIn() != null;
446       case MappingPackage.MAPPING_ROOT__INPUTS:
447         return inputs != null && !inputs.isEmpty();
448       case MappingPackage.MAPPING_ROOT__OUTPUTS:
449         return outputs != null && !outputs.isEmpty();
450       case MappingPackage.MAPPING_ROOT__TYPE_MAPPING:
451         return typeMapping != null;
452       case MappingPackage.MAPPING_ROOT__OUTPUT_READ_ONLY:
453         return outputReadOnly != OUTPUT_READ_ONLY_EDEFAULT;
454       case MappingPackage.MAPPING_ROOT__TOP_TO_BOTTOM:
455         return topToBottom != TOP_TO_BOTTOM_EDEFAULT;
456       case MappingPackage.MAPPING_ROOT__COMMAND_STACK:
457         return COMMAND_STACK_EDEFAULT == null ? commandStack != null : !COMMAND_STACK_EDEFAULT.equals(commandStack);
458     }
459     return eDynamicIsSet(eFeature);
460   }
461
462   /**
463    * <!-- begin-user-doc -->
464    * <!-- end-user-doc -->
465    * @generated
466    */

467   public String JavaDoc toString()
468   {
469     if (eIsProxy()) return super.toString();
470
471     StringBuffer JavaDoc result = new StringBuffer JavaDoc(super.toString());
472     result.append(" (outputReadOnly: ");
473     result.append(outputReadOnly);
474     result.append(", topToBottom: ");
475     result.append(topToBottom);
476     result.append(", commandStack: ");
477     result.append(commandStack);
478     result.append(')');
479     return result.toString();
480   }
481
482   public MappingDomain getDomain()
483   {
484     return domain;
485   }
486
487   public void setDomain(MappingDomain domain)
488   {
489     if (this.domain != domain)
490     {
491       if (this.domain != null)
492       {
493         eAdapters.remove(mappedObjectListener);
494       }
495
496       this.domain = domain;
497       domain.setMappingRoot(this);
498
499       mappedObjectListener =
500         new AdapterImpl()
501         {
502           public void notifyChanged(Notification notification)
503           {
504             Object JavaDoc feature = notification.getFeature();
505             if (feature == MappingPackage.eINSTANCE.getMapping_Inputs() || feature == MappingPackage.eINSTANCE.getMapping_Outputs())
506             {
507               initializeMappedObjectStates();
508             }
509           }
510         };
511         eAdapters().add(mappedObjectListener);
512
513       initializeMappedObjectStates();
514     }
515   }
516
517   public void refreshMappedObjectStates(Mapping subtree)
518   {
519     for (Iterator JavaDoc inputs = subtree.getInputs().iterator(); inputs.hasNext(); )
520     {
521       for (Iterator JavaDoc objects = domain.treeIterator(inputs.next()); objects.hasNext(); )
522       {
523         Object JavaDoc object = objects.next();
524         MappedObjectState mappedObjectState = getMappedObjectState(object);
525         if (mappedObjectState != null)
526         {
527           mappedObjectState.setInput();
528         }
529       }
530     }
531
532     for (Iterator JavaDoc outputs = subtree.getOutputs().iterator(); outputs.hasNext(); )
533     {
534       for (Iterator JavaDoc objects = domain.treeIterator(outputs.next()); objects.hasNext(); )
535       {
536         MappedObjectState mappedObjectState = getMappedObjectState(objects.next());
537         if (mappedObjectState != null)
538         {
539           mappedObjectState.setOutput();
540         }
541       }
542     }
543
544     for (Iterator JavaDoc mappings = subtree.treeIterator(); mappings.hasNext(); )
545     {
546       Mapping mapping = (Mapping)mappings.next();
547       for (Iterator JavaDoc inputs = mapping.getInputs().iterator(); inputs.hasNext(); )
548       {
549         Object JavaDoc input = inputs.next();
550         MappedObjectState mappedObjectState = getMappedObjectState(input);
551         if (mappedObjectState != null)
552         {
553           mappedObjectState.getMappings().add(mapping);
554         }
555       }
556
557       for (Iterator JavaDoc outputs = mapping.getOutputs().iterator(); outputs.hasNext(); )
558       {
559         Object JavaDoc output = outputs.next();
560         MappedObjectState mappedObjectState = getMappedObjectState(output);
561         if (mappedObjectState != null)
562         {
563           mappedObjectState.getMappings().add(mapping);
564         }
565       }
566     }
567   }
568
569   protected void initializeMappedObjectStates()
570   {
571     refreshMappedObjectStates(this);
572
573     if (getTypeMapping() instanceof MappingRootImpl)
574     {
575       ((MappingRootImpl)getTypeMapping()).initializeMappedObjectStates();
576     }
577   }
578
579   public Mapping getParentMapping(Collection JavaDoc collection)
580   {
581     // Barring a better result, this will be the result.
582
//
583
Mapping result = this;
584
585     // Cache the tree path for each object.
586
//
587
final Collection JavaDoc allTreePaths = new ArrayList JavaDoc();
588     for (Iterator JavaDoc objects = collection.iterator(); objects.hasNext(); )
589     {
590       allTreePaths.add(domain.getTreePath(objects.next()));
591     }
592
593     // Iterate over the mappings in the tree.
594
//
595
OuterLoop: for (TreeIterator mappings = treeIterator(); mappings.hasNext(); )
596     {
597       Mapping mapping = (Mapping)mappings.next();
598
599       // Check to make sure that every object in the collection has an ancestor that is contained in this mapping.
600
//
601
for (Iterator JavaDoc treePaths = allTreePaths.iterator(); treePaths.hasNext(); )
602       {
603         Collection JavaDoc treePath = (Collection JavaDoc)treePaths.next();
604         Collection JavaDoc mappedObjects = mapping.getMappedObjects();
605         mappedObjects.retainAll(treePath);
606
607         // If the intersection is empty, i.e., no ancestor is in the mapping...
608
//
609
if (mappedObjects.isEmpty())
610         {
611           // If this mapping isn't a parent, it's children definitely won't be either.
612
//
613
mappings.prune();
614           continue OuterLoop;
615         }
616       }
617
618       // Make sure the collections aren't identical...
619
//
620
Collection JavaDoc mappedObjects = mapping.getMappedObjects();
621       if (!collection.containsAll(mappedObjects) || !mappedObjects.containsAll(collection))
622       {
623         result = mapping;
624       }
625     }
626
627     return result;
628   }
629
630   public boolean isDirty()
631   {
632     /**
633     if (getRuleList() != null)
634     {
635       return getRuleList().isDirty();
636     }
637     **/

638     return false;
639   }
640
641   public boolean isOutputDirty()
642   {
643     return outputDirty;
644   }
645
646   public void register(Mapping mapping)
647   {
648     for (Iterator JavaDoc inputs = mapping.getInputs().iterator(); inputs.hasNext(); )
649     {
650       Object JavaDoc input = inputs.next();
651       MappedObjectState mappedObjectState = getMappedObjectState(input);
652       if (mappedObjectState != null)
653       {
654         mappedObjectState.getMappings().add(mapping);
655       }
656     }
657
658     for (Iterator JavaDoc outputs = mapping.getOutputs().iterator(); outputs.hasNext(); )
659     {
660       Object JavaDoc output = outputs.next();
661       MappedObjectState mappedObjectState = getMappedObjectState(output);
662       if (mappedObjectState != null)
663       {
664         mappedObjectState.getMappings().add(mapping);
665       }
666     }
667   }
668
669   public void deregister(Mapping mapping)
670   {
671     for (Iterator JavaDoc inputs = mapping.getInputs().iterator(); inputs.hasNext(); )
672     {
673       Object JavaDoc input = inputs.next();
674       MappedObjectState mappedObjectState = getMappedObjectState(input);
675       if (mappedObjectState != null)
676       {
677         mappedObjectState.getMappings().remove(mapping);
678       }
679     }
680
681     for (Iterator JavaDoc outputs = mapping.getOutputs().iterator(); outputs.hasNext(); )
682     {
683       Object JavaDoc output = outputs.next();
684       MappedObjectState mappedObjectState = getMappedObjectState(output);
685       if (mappedObjectState != null)
686       {
687         mappedObjectState.getMappings().remove(mapping);
688       }
689     }
690   }
691
692   public boolean canCreateMapping(Collection JavaDoc inputs, Collection JavaDoc outputs, Mapping mapping)
693   {
694     int enablementFlags = domain.getMappingEnablementFlags();
695     if ((enablementFlags & MappingDomain.ENABLE_EMPTY_INPUTS) == 0 && inputs.size() == 0 ||
696         (enablementFlags & MappingDomain.ENABLE_EMPTY_OUTPUTS) == 0 && outputs.size() == 0 ||
697         inputs.size() == 0 && outputs.size() == 0 ||
698         (enablementFlags & MappingDomain.ENABLE_MULTIPLE_INPUTS) == 0 && inputs.size() > 1 ||
699         (enablementFlags & MappingDomain.ENABLE_MULTIPLE_OUTPUTS) == 0 && outputs.size() > 1 ||
700         (enablementFlags & MappingDomain.ENABLE_MULTIPLE_INPUT_MAPPINGS) == 0 && isMapped(inputs, mapping) ||
701         (enablementFlags & MappingDomain.ENABLE_MULTIPLE_OUTPUT_MAPPINGS) == 0 && isMapped(outputs, mapping) ||
702         (enablementFlags & MappingDomain.ENABLE_UNMAPPED_PARENTS) == 0 && !hasMappedParents(inputs, outputs) ||
703         (enablementFlags & MappingDomain.ENABLE_INCOMPATIBLE_METAOBJECTS) == 0 && !hasCompatibleMetaObjects(inputs, outputs) ||
704         (enablementFlags & MappingDomain.ENABLE_INCOMPATIBLE_TYPE_CLASSIFIERS) == 0 && !hasCompatibleTypes(inputs, outputs))
705     {
706       return false;
707     }
708
709     for (Iterator JavaDoc i = inputs.iterator(); i.hasNext(); )
710     {
711       if (!isAttachedObject(i.next()))
712       {
713         return false;
714       }
715     }
716
717     for (Iterator JavaDoc i = outputs.iterator(); i.hasNext(); )
718     {
719       if (!isAttachedObject(i.next()))
720       {
721         return false;
722       }
723     }
724
725     return true;
726   }
727
728   public boolean canRemoveMapping(Mapping mapping)
729   {
730     int enablementFlags = domain.getMappingEnablementFlags();
731     if (mapping.getNestedIn() == null ||
732         (enablementFlags & MappingDomain.ENABLE_UNMAPPED_PARENTS) == 0 && hasMappedChildren(mapping))
733     {
734       return false;
735     }
736
737     return true;
738   }
739
740   protected boolean hasMappedChildren(Mapping mapping)
741   {
742     return !mapping.getNested().isEmpty();
743   }
744
745   protected boolean hasMappedParents(Collection JavaDoc inputs, Collection JavaDoc outputs)
746   {
747     Collection JavaDoc parents = new HashSet JavaDoc();
748     for (Iterator JavaDoc inputIter = inputs.iterator(); inputIter.hasNext(); )
749     {
750       parents.add(domain.getParent(inputIter.next()));
751     }
752     for (Iterator JavaDoc outputIter = outputs.iterator(); outputIter.hasNext(); )
753     {
754       parents.add(domain.getParent(outputIter.next()));
755     }
756     return !getAllMappings(parents).isEmpty();
757   }
758
759   protected boolean isMapped(Collection JavaDoc collection, Mapping mapping)
760   {
761     for (Iterator JavaDoc objects = collection.iterator(); objects.hasNext(); )
762     {
763       Collection JavaDoc mappings = getMappings(objects.next());
764       if (!mappings.isEmpty())
765       {
766         if (mapping == null || mappings.size() > 1 || !mappings.contains(mapping))
767         {
768           return true;
769         }
770       }
771     }
772     return false;
773   }
774
775   protected boolean hasCompatibleMetaObjects(Collection JavaDoc inputs, Collection JavaDoc outputs)
776   {
777     for (Iterator JavaDoc inputIter = inputs.iterator(); inputIter.hasNext(); )
778     {
779       EObject inputType = ((EObject)inputIter.next()).eClass();
780       EObject convertedInputType = domain.getOutputMetaObject(inputType);
781       for (Iterator JavaDoc outputIter = outputs.iterator(); outputIter.hasNext(); )
782       {
783         EObject outputType = ((EObject)outputIter.next()).eClass();
784         if (convertedInputType != outputType)
785         {
786           return false;
787         }
788       }
789     }
790     return true;
791   }
792
793   protected boolean hasCompatibleTypes(Collection JavaDoc inputs, Collection JavaDoc outputs)
794   {
795     MappingRoot typeMappingRoot = getTypeMappingRoot();
796     if (typeMappingRoot != null)
797     {
798       Collection JavaDoc inputTypes = getTypeClassifiers(inputs);
799       Collection JavaDoc outputTypes = getTypeClassifiers(outputs);
800
801       if (inputTypes.equals(outputTypes))
802         return true;
803
804       if (inputTypes.size() != inputs.size() || outputTypes.size() != outputs.size())
805         return false;
806
807       if (getTypeMappings(inputTypes, outputTypes).isEmpty() &&
808           hasTypeMappings(inputTypes) && hasTypeMappings(outputTypes))
809       {
810         return false;
811       }
812     }
813     return true;
814   }
815
816   protected Collection JavaDoc getTypeMappings(Collection JavaDoc inputTypes, Collection JavaDoc outputTypes)
817   {
818     Collection JavaDoc typeMappings;
819     if (outputTypes.isEmpty())
820     {
821       typeMappings = getTypeMappingRoot().getAllMappings(inputTypes);
822     }
823     else
824     {
825       Collection JavaDoc allTypes = new ArrayList JavaDoc(inputTypes);
826       allTypes.addAll(outputTypes);
827       typeMappings = getTypeMappingRoot().getExactMappings(allTypes);
828     }
829     return typeMappings;
830   }
831
832   protected boolean hasTypeMappings(Collection JavaDoc types)
833   {
834     return !getTypeMappingRoot().getAllMappings(types).isEmpty();
835   }
836
837   protected Collection JavaDoc getTypeClassifiers(Collection JavaDoc collection)
838   {
839     Collection JavaDoc types = new ArrayList JavaDoc();
840     for (Iterator JavaDoc iter = collection.iterator(); iter.hasNext(); )
841     {
842       Object JavaDoc type = domain.getTypeClassifier(iter.next());
843       if (type != null)
844       {
845         types.add(type);
846       }
847     }
848     return types;
849   }
850
851   public Mapping createMapping(Collection JavaDoc inputs, Collection JavaDoc outputs)
852   {
853     Mapping newMapping = createMapping();
854     initializeNewMapping(newMapping, inputs, outputs);
855     return newMapping;
856   }
857
858   protected Mapping createMapping()
859   {
860     return MappingFactory.eINSTANCE.createMapping();
861   }
862
863   protected void initializeNewMapping(Mapping newMapping, Collection JavaDoc inputs, Collection JavaDoc outputs)
864   {
865     newMapping.getInputs().addAll(inputs);
866     newMapping.getOutputs().addAll(outputs);
867
868     if (getTypeMappingRoot() != null)
869     {
870       Collection JavaDoc inputTypes = getTypeClassifiers(inputs);
871       if (!inputTypes.isEmpty())
872       {
873         Collection JavaDoc outputTypes = getTypeClassifiers(outputs);
874
875         Collection JavaDoc typeMappings = getTypeMappings(inputTypes, outputTypes);
876         if (!typeMappings.isEmpty())
877         {
878           newMapping.setTypeMapping((Mapping)typeMappings.iterator().next());
879         }
880       }
881     }
882   }
883
884   public void resetDirty()
885   {
886     this.setOutputDirty(false);
887   }
888
889   public void setOutputDirty(boolean dirty)
890   {
891     outputDirty = dirty;
892   }
893
894   public boolean isInputObject(Object JavaDoc object)
895   {
896     MappedObjectState mappedObjectState = (MappedObjectState)mappedObjectStateAdapterFactory.adapt(object, MappedObjectState.class);
897     return
898       mappedObjectState != null && mappedObjectState.isInput();
899   }
900
901   public boolean isOutputObject(Object JavaDoc object)
902   {
903     MappedObjectState mappedObjectState = (MappedObjectState)mappedObjectStateAdapterFactory.adapt(object, MappedObjectState.class);
904     return
905       mappedObjectState != null && mappedObjectState.isOutput();
906   }
907
908   public boolean isTopObject(Object JavaDoc object)
909   {
910     MappedObjectState mappedObjectState = (MappedObjectState)mappedObjectStateAdapterFactory.adapt(object, MappedObjectState.class);
911     if (mappedObjectState != null)
912       return isTopToBottom() ? mappedObjectState.isInput() : mappedObjectState.isOutput();
913     return false;
914   }
915
916   public boolean isBottomObject(Object JavaDoc object)
917   {
918     MappedObjectState mappedObjectState = (MappedObjectState)mappedObjectStateAdapterFactory.adapt(object, MappedObjectState.class);
919     if (mappedObjectState != null)
920       return !isTopToBottom() ? mappedObjectState.isInput() : mappedObjectState.isOutput();
921     return false;
922   }
923
924   public boolean isAttachedObject(Object JavaDoc object)
925   {
926     Object JavaDoc root = object;
927     //FB used to check for parent != null.
928
// Need to find the top most model object not including the resource.
929
// parent instanceof Eobject only checks for trees in model object space.
930
for (Object JavaDoc parent = domain.getParent(object); parent instanceof EObject; parent = domain.getParent(parent))
931     {
932       root = parent;
933     }
934
935     return getInputs().contains(root) || getOutputs().contains(root);
936   }
937
938   public Collection JavaDoc getMappings(Object JavaDoc object)
939   {
940     MappedObjectState mappedObjectState = getMappedObjectState(object);
941     return
942       mappedObjectState == null ?
943         Collections.EMPTY_SET :
944         mappedObjectState.getMappings();
945   }
946
947   public Collection JavaDoc getAllMappings(Collection JavaDoc collection)
948   {
949     Iterator JavaDoc objects = collection.iterator();
950     if (objects.hasNext())
951     {
952       Collection JavaDoc result = new ArrayList JavaDoc(getMappings(objects.next()));
953       while (objects.hasNext() && !result.isEmpty())
954       {
955         result.retainAll(getMappings(objects.next()));
956       }
957       return result;
958     }
959     else
960     {
961       return Collections.EMPTY_SET;
962     }
963   }
964
965   public Collection JavaDoc getExactMappings(Collection JavaDoc collection)
966   {
967     Collection JavaDoc result = new ArrayList JavaDoc();
968     for (Iterator JavaDoc mappings = getAllMappings(collection).iterator(); mappings.hasNext(); )
969     {
970       Mapping mapping = (Mapping)mappings.next();
971       if (collection.containsAll(mapping.getMappedObjects()))
972       {
973         result.add(mapping);
974       }
975     }
976
977     return result;
978   }
979
980   /**
981    * This is a simple implementation of the basic information that needs to be maintained for any mapped object.
982    */

983   protected class MappedObjectStateAdapter extends AdapterImpl implements MappedObjectState, IDisposable
984   {
985     /**
986      * This indicates whether the mapped object is an input.
987      */

988     protected boolean isInput;
989
990     /**
991      * This indicates whether the object is an output.
992      */

993     protected boolean isOutput;
994
995     /**
996      * This keeps track of the originating input of the mapped object, if any.
997      */

998     protected Object JavaDoc originatingInput;
999
1000    /**
1001     * This keeps track of all the mappings that involve the mapped object.
1002     */

1003    protected Collection JavaDoc mappings =
1004      new NotifyingListImpl()
1005      {
1006        public Object JavaDoc getNotifier()
1007        {
1008          return getTarget();
1009        }
1010
1011        protected boolean isNotificationRequired()
1012        {
1013          return true;
1014        }
1015
1016        protected NotificationImpl createNotification(int eventType, Object JavaDoc oldObject, Object JavaDoc newObject, int index, boolean wasSet)
1017        {
1018          Object JavaDoc object = oldObject == null ? newObject : oldObject;
1019          // Ensure that this is a touch notification so to resource aren't marked as dirty.
1020
//
1021
ENotificationImpl notification =
1022            new ENotificationImpl
1023              ((InternalEObject)getTarget(),
1024               Notification.SET,
1025               Notification.NO_FEATURE_ID - 1,
1026               object,
1027               object,
1028               Notification.NO_INDEX,
1029               wasSet);
1030          MappedObjectStateAdapter.this.fireNotifyChanged(notification);
1031          return notification;
1032        }
1033
1034        protected boolean isUnique()
1035        {
1036          return true;
1037        }
1038      };
1039
1040    /**
1041     * This is where {@link org.eclipse.emf.edit.provider.IChangeNotifier} is delegated.
1042     */

1043    protected ChangeNotifier changeNotifier = new ChangeNotifier();
1044   
1045    /**
1046     * This returns when type is the {@link #mappedObjectStateAdapterFactory}.
1047     */

1048    public boolean isAdapterForType(Object JavaDoc type)
1049    {
1050      return type == mappedObjectStateAdapterFactory;
1051    }
1052
1053    public boolean isInput()
1054    {
1055      return isInput;
1056    }
1057
1058    public void setInput()
1059    {
1060      isInput = true;
1061    }
1062
1063    public boolean isOutput()
1064    {
1065      return isOutput;
1066    }
1067
1068    public void setOutput()
1069    {
1070      isOutput = true;
1071      ENotificationImpl note =
1072         new ENotificationImpl
1073           ((InternalEObject)getTarget(),
1074            Notification.SET,
1075            Notification.NO_FEATURE_ID - 2,
1076            Boolean.TRUE,
1077            Boolean.TRUE,
1078            Notification.NO_INDEX);
1079      changeNotifier.fireNotifyChanged(note);
1080    }
1081
1082    public Object JavaDoc getOriginatingInput()
1083    {
1084      return originatingInput;
1085    }
1086
1087    public void setOriginatingInput(Object JavaDoc originatingInput)
1088    {
1089      setOutput();
1090      this.originatingInput = originatingInput;
1091    }
1092
1093    public Collection JavaDoc getMappings()
1094    {
1095      return mappings;
1096    }
1097
1098    public void addListener(INotifyChangedListener notifyChangedListener)
1099    {
1100      changeNotifier.addListener(notifyChangedListener);
1101    }
1102  
1103    public void removeListener(INotifyChangedListener notifyChangedListener)
1104    {
1105      changeNotifier.removeListener(notifyChangedListener);
1106    }
1107
1108    public void fireNotifyChanged(Notification notification)
1109    {
1110      changeNotifier.fireNotifyChanged(notification);
1111    }
1112
1113    public void dispose()
1114    {
1115      if (target != null)
1116      {
1117        target.eAdapters().remove(this);
1118      }
1119    }
1120  }
1121
1122  /**
1123   * This uses the {@link #mappedObjectStateAdapterFactory} to get an adapter that implements this interface.
1124   */

1125  public MappedObjectState getMappedObjectState(Object JavaDoc object)
1126  {
1127    return (MappedObjectState)mappedObjectStateAdapterFactory.adapt(object, MappedObjectState.class);
1128  }
1129
1130  public MappingRoot getTypeMappingRoot()
1131  {
1132    return (MappingRoot)getTypeMapping();
1133  }
1134
1135  /**
1136   * By default, this creates an adapter factory that delegates {@link AdapterFactoryImpl#createAdapter(Notifier) createAdapter}
1137   * to {@link #createMappedObjectStateAdapter createMappedObjectStateAdapter}.
1138   */

1139  protected AdapterFactory createMappedObjectStateAdapterFactory()
1140  {
1141    return new MappedObjectStateAdapterFactory();
1142  }
1143
1144  /**
1145   * This is the factory that creates adapters for the objects being mapped.
1146   * It must be disposed if the lifetime of the mapped objects is longer than the lifetime of the mapping root.
1147   */

1148  protected class MappedObjectStateAdapterFactory extends AdapterFactoryImpl implements IDisposable
1149  {
1150    protected Disposable disposable = new Disposable();
1151
1152    public MappedObjectStateAdapterFactory()
1153    {
1154    }
1155
1156    public Adapter createAdapter(Notifier target)
1157    {
1158      return createMappedObjectStateAdapter(target);
1159    }
1160
1161    public boolean isFactoryForType(Object JavaDoc type)
1162    {
1163      return super.isFactoryForType(type) || type == MappedObjectState.class;
1164    }
1165
1166    public Adapter adapt(Notifier notifier, Object JavaDoc type)
1167    {
1168      return super.adapt(notifier, this);
1169    }
1170
1171    public Object JavaDoc adapt(Object JavaDoc object, Object JavaDoc type)
1172    {
1173      Object JavaDoc result = super.adapt(object, type);
1174      return
1175        result instanceof MappedObjectState ? result : null;
1176    }
1177
1178    public Adapter adaptNew(Notifier object, Object JavaDoc type)
1179    {
1180      Adapter result = super.adaptNew(object, type);
1181      disposable.add(result);
1182      return result;
1183    }
1184
1185    public void dispose()
1186    {
1187      disposable.dispose();
1188    }
1189  }
1190
1191  /**
1192   * By default, this creates a new instance of {@link MappedObjectStateAdapter}.
1193   */

1194  protected Adapter createMappedObjectStateAdapter(Notifier target)
1195  {
1196    return new MappedObjectStateAdapter();
1197  }
1198
1199  public void dispose()
1200  {
1201    if (mappedObjectStateAdapterFactory instanceof IDisposable)
1202    {
1203      ((IDisposable)mappedObjectStateAdapterFactory).dispose();
1204    }
1205
1206    MappingRoot typeMappingRoot = getTypeMappingRoot();
1207    if (typeMappingRoot != null)
1208    {
1209      typeMappingRoot.dispose();
1210    }
1211
1212    // printAdapters();
1213
}
1214
1215  protected void printAdapters()
1216  {
1217    walk(this);
1218    for (TreeIterator mappings = treeIterator(); mappings.hasNext(); )
1219    {
1220      for (Iterator JavaDoc objects = ((Mapping)mappings.next()).getMappedObjects().iterator(); objects.hasNext(); )
1221      {
1222        walk((EObject)objects.next());
1223      }
1224    }
1225  }
1226
1227  protected void walk(EObject object)
1228  {
1229
1230    for (Iterator JavaDoc iterator = object.eContents().iterator(); iterator.hasNext(); )
1231    {
1232      EObject child = (EObject)iterator.next();
1233      Collection JavaDoc adapters = child.eAdapters();
1234      if (adapters != null)
1235      {
1236        boolean once = false;
1237        for (Iterator JavaDoc i = adapters.iterator(); i.hasNext(); )
1238        {
1239          Object JavaDoc adapter = i.next();
1240          if (adapter != null)
1241          {
1242            if (!once)
1243            {
1244              System.out.println("*** " + child);
1245              once = true;
1246            }
1247            System.out.println(" * " + adapter);
1248          }
1249        }
1250      }
1251      walk(child);
1252    }
1253  }
1254
1255} //MappingRootImpl
1256
Popular Tags