Lines 11-18
Link Here
|
11 |
|
11 |
|
12 |
package org.eclipse.gmf.runtime.emf.core.internal.resources; |
12 |
package org.eclipse.gmf.runtime.emf.core.internal.resources; |
13 |
|
13 |
|
|
|
14 |
import org.eclipse.emf.common.notify.Adapter; |
15 |
import org.eclipse.emf.common.notify.Notification; |
14 |
import org.eclipse.emf.common.util.URI; |
16 |
import org.eclipse.emf.common.util.URI; |
15 |
import org.eclipse.emf.ecore.EObject; |
17 |
import org.eclipse.emf.ecore.EObject; |
|
|
18 |
import org.eclipse.emf.ecore.EStructuralFeature; |
16 |
|
19 |
|
17 |
import org.eclipse.gmf.runtime.emf.core.edit.MEditingDomain; |
20 |
import org.eclipse.gmf.runtime.emf.core.edit.MEditingDomain; |
18 |
import org.eclipse.gmf.runtime.emf.core.internal.util.MSLConstants; |
21 |
import org.eclipse.gmf.runtime.emf.core.internal.util.MSLConstants; |
Lines 26-38
Link Here
|
26 |
extends LogicalResource { |
29 |
extends LogicalResource { |
27 |
|
30 |
|
28 |
private boolean useIDAttributes = false; |
31 |
private boolean useIDAttributes = false; |
29 |
|
32 |
|
30 |
/** |
33 |
/** |
31 |
* Constructor. |
34 |
* Constructor. |
32 |
*/ |
35 |
*/ |
33 |
public MSLResource(URI uri) { |
36 |
public MSLResource(URI uri) { |
34 |
|
37 |
|
35 |
super(MEditingDomain.INSTANCE.convertURI(uri)); |
38 |
super(MEditingDomain.INSTANCE.convertURI(uri)); |
|
|
39 |
|
40 |
setTrackingModification(true); |
36 |
} |
41 |
} |
37 |
|
42 |
|
38 |
protected LogicalResourceUnit createUnit(URI unitUri) { |
43 |
protected LogicalResourceUnit createUnit(URI unitUri) { |
Lines 98-101
Link Here
|
98 |
|
103 |
|
99 |
super.setURI(uri); |
104 |
super.setURI(uri); |
100 |
} |
105 |
} |
|
|
106 |
|
107 |
/** |
108 |
* The inherited implementation creates an adapter that <em>always</em> sets |
109 |
* the modified state. We prefer to check, first, whether the resource |
110 |
* is already modified so that we don't generate redundant notifications. |
111 |
* Moreover, we additionally set modified state only for changes that are |
112 |
* in non-transient features of objects contained (recursively) by |
113 |
* non-transient references. |
114 |
*/ |
115 |
protected Adapter createModificationTrackingAdapter() { |
116 |
return new ModificationTrackingAdapter() { |
117 |
public void notifyChanged(Notification notification) { |
118 |
if (!isModified() && !isTransient( |
119 |
notification.getNotifier(), notification.getFeature())) { |
120 |
|
121 |
super.notifyChanged(notification); |
122 |
} |
123 |
} |
124 |
|
125 |
/** |
126 |
* Check if the feature or one of the notifier's containers is |
127 |
* transient. |
128 |
* |
129 |
* @param notifier a notifier |
130 |
* @param feature the feature that changed |
131 |
* |
132 |
* @return <code>true</code> if the feature is transient or if the |
133 |
* notifier or any of its ancestors is contained by a transient |
134 |
* reference; <code>false</code>, otherwise |
135 |
*/ |
136 |
private boolean isTransient(Object notifier, Object feature) { |
137 |
if (feature instanceof EStructuralFeature) { |
138 |
if (((EStructuralFeature) feature).isTransient()) |
139 |
return true; |
140 |
else |
141 |
// calling isTransient could be a lengthy operation. |
142 |
// It is safe to cast because the adapter is only |
143 |
// attached to EObjects, not to the resource |
144 |
return isTransient((EObject) notifier); |
145 |
} |
146 |
return false; |
147 |
} |
148 |
|
149 |
/** |
150 |
* Is object transient? |
151 |
*/ |
152 |
private boolean isTransient(EObject eObject) { |
153 |
EStructuralFeature containmentFeature = eObject.eContainmentFeature(); |
154 |
while (containmentFeature != null) { |
155 |
if (containmentFeature.isTransient()) |
156 |
return true; |
157 |
eObject = eObject.eContainer(); |
158 |
if (eObject != null) |
159 |
containmentFeature = eObject.eContainmentFeature(); |
160 |
else |
161 |
break; |
162 |
} |
163 |
return false; |
164 |
}}; |
165 |
} |
101 |
} |
166 |
} |