View | Details | Raw Unified | Return to bug 113863 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/gmf/runtime/emf/core/internal/resources/MSLHelper.java (-3 / +4 lines)
Lines 14-20 Link Here
14
import org.eclipse.emf.common.util.URI;
14
import org.eclipse.emf.common.util.URI;
15
import org.eclipse.emf.ecore.EObject;
15
import org.eclipse.emf.ecore.EObject;
16
import org.eclipse.emf.ecore.resource.Resource;
16
import org.eclipse.emf.ecore.resource.Resource;
17
17
import org.eclipse.emf.ecore.xmi.XMLResource;
18
import org.eclipse.emf.ecore.xmi.impl.XMIHelperImpl;
18
import org.eclipse.gmf.runtime.emf.core.internal.util.MSLConstants;
19
import org.eclipse.gmf.runtime.emf.core.internal.util.MSLConstants;
19
import org.eclipse.gmf.runtime.emf.core.internal.util.MSLUtil;
20
import org.eclipse.gmf.runtime.emf.core.internal.util.MSLUtil;
20
import org.eclipse.gmf.runtime.emf.core.util.EObjectUtil;
21
import org.eclipse.gmf.runtime.emf.core.util.EObjectUtil;
Lines 26-37 Link Here
26
 * @author rafikj
27
 * @author rafikj
27
 */
28
 */
28
public class MSLHelper
29
public class MSLHelper
29
	extends LogicalHelper {
30
	extends XMIHelperImpl {
30
31
31
	/**
32
	/**
32
	 * Constructor.
33
	 * Constructor.
33
	 */
34
	 */
34
	public MSLHelper(MSLResourceUnit resource) {
35
	public MSLHelper(XMLResource resource) {
35
		super(resource);
36
		super(resource);
36
	}
37
	}
37
38
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resources/MSLSave.java (-1 / +3 lines)
Lines 17-22 Link Here
17
import org.eclipse.emf.ecore.EObject;
17
import org.eclipse.emf.ecore.EObject;
18
import org.eclipse.emf.ecore.xmi.XMLHelper;
18
import org.eclipse.emf.ecore.xmi.XMLHelper;
19
import org.eclipse.emf.ecore.xmi.XMLResource;
19
import org.eclipse.emf.ecore.xmi.XMLResource;
20
import org.eclipse.emf.ecore.xmi.impl.XMISaveImpl;
20
import org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl;
21
import org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl;
21
22
22
import org.eclipse.gmf.runtime.emf.core.internal.util.MSLConstants;
23
import org.eclipse.gmf.runtime.emf.core.internal.util.MSLConstants;
Lines 28-34 Link Here
28
 * @author rafikj
29
 * @author rafikj
29
 */
30
 */
30
public class MSLSave
31
public class MSLSave
31
	extends LogicalSave {
32
	extends XMISaveImpl {
32
33
33
	/**
34
	/**
34
	 * Discards control characters 0x00 - 0x1F except for TAB, CR, and LF, which
35
	 * Discards control characters 0x00 - 0x1F except for TAB, CR, and LF, which
Lines 120-125 Link Here
120
	public Object writeTopObjects(List contents) {
121
	public Object writeTopObjects(List contents) {
121
122
122
		writeCCToken();
123
		writeCCToken();
124
		writeArtifactVersionToken();
123
		return super.writeTopObjects(contents);
125
		return super.writeTopObjects(contents);
124
	}
126
	}
125
127
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resources/LogicalHelper.java (-88 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
13
package org.eclipse.gmf.runtime.emf.core.internal.resources;
14
15
import org.eclipse.emf.common.util.URI;
16
import org.eclipse.emf.ecore.EObject;
17
import org.eclipse.emf.ecore.resource.Resource;
18
import org.eclipse.emf.ecore.util.EcoreUtil;
19
import org.eclipse.emf.ecore.xmi.impl.XMIHelperImpl;
20
21
22
public class LogicalHelper
23
	extends XMIHelperImpl {
24
25
	private final LogicalResource logicalResource;
26
	private final LogicalResourceUnit unit;
27
	private boolean urisRelativeToRoot = true;
28
	
29
	public LogicalHelper(LogicalResourceUnit resource) {
30
		super(resource);
31
		
32
		logicalResource = resource.getLogicalResource();
33
		unit = resource;
34
	}
35
	
36
	LogicalResource getLogicalResource() {
37
		return logicalResource;
38
	}
39
	
40
	LogicalResourceUnit getUnit() {
41
		return unit;
42
	}
43
	
44
	boolean urisRelativeToRoot() {
45
		return urisRelativeToRoot;
46
	}
47
	
48
	void setUrisRelativeToRoot(boolean b) {
49
		urisRelativeToRoot = b;
50
	}
51
52
	protected URI getHREF(Resource otherResource, EObject obj) {
53
		if (otherResource instanceof LogicalResource) {
54
			LogicalResource otherLogical = (LogicalResource) otherResource;
55
			URI uri;
56
			
57
			if (urisRelativeToRoot()) {
58
				uri = otherLogical.getURI();
59
			} else {
60
				uri = otherLogical.getUnit(obj).getURI();
61
			}
62
			
63
			return uri.appendFragment(otherResource.getURIFragment(obj));
64
		}
65
		
66
		return super.getHREF(otherResource, obj);
67
	}
68
	
69
	/**
70
	 * Extends the superclass implementation to ensure that proxies for elements
71
	 * in unloaded resources are not discarded.
72
	 */
73
	protected URI handleDanglingHREF(EObject object) {
74
		URI result;
75
		
76
		URI proxyUri = EcoreUtil.getURI(object);
77
		if ((proxyUri != null)
78
				&& proxyUri.trimFragment().equals(getLogicalResource().getURI())) {
79
			// do not discard unresolved references to unloaded units
80
			//   of the logical resource
81
			result = proxyUri;
82
		} else {
83
			result = super.handleDanglingHREF(object);
84
		}
85
		
86
		return result;
87
	}
88
}
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resources/LogicalLoad.java (-48 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
13
package org.eclipse.gmf.runtime.emf.core.internal.resources;
14
15
import org.eclipse.emf.ecore.xmi.XMLHelper;
16
import org.eclipse.emf.ecore.xmi.impl.SAXWrapper;
17
import org.eclipse.emf.ecore.xmi.impl.XMILoadImpl;
18
import org.xml.sax.helpers.DefaultHandler;
19
20
21
/**
22
 * Loader implementation for logical resources.  This implementation ensures
23
 * that XML namespace EPackages are loaded in the same resource set as the
24
 * logical resource, not its internal resource set for the physical resources.
25
 *
26
 * @author Christian W. Damus (cdamus)
27
 */
28
public class LogicalLoad
29
	extends XMILoadImpl {
30
31
	/**
32
	 * Initializes me with my helper helper.
33
	 * 
34
	 * @param helper my helper
35
	 */
36
	public LogicalLoad(XMLHelper helper) {
37
		super(helper);
38
	}
39
	
40
	/**
41
	 * Creates a {@link LogicalHandler}.
42
	 */
43
	protected DefaultHandler makeDefaultHandler() {
44
		return new SAXWrapper(
45
			new LogicalHandler((LogicalResourceUnit) resource, helper, options));
46
	}
47
48
}
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resources/LogicalResourcePolicyManager.java (-510 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
13
package org.eclipse.gmf.runtime.emf.core.internal.resources;
14
15
import java.util.Iterator;
16
import java.util.List;
17
import java.util.Map;
18
19
import org.eclipse.core.runtime.CoreException;
20
import org.eclipse.core.runtime.IConfigurationElement;
21
import org.eclipse.core.runtime.IStatus;
22
import org.eclipse.core.runtime.Platform;
23
import org.eclipse.emf.common.util.URI;
24
import org.eclipse.emf.ecore.EClass;
25
import org.eclipse.emf.ecore.EFactory;
26
import org.eclipse.emf.ecore.EObject;
27
import org.eclipse.emf.ecore.EPackage;
28
import org.eclipse.gmf.runtime.common.core.util.Log;
29
import org.eclipse.gmf.runtime.emf.core.internal.l10n.EMFCoreMessages;
30
import org.eclipse.gmf.runtime.emf.core.internal.plugin.MSLDebugOptions;
31
import org.eclipse.gmf.runtime.emf.core.internal.plugin.MSLPlugin;
32
import org.eclipse.gmf.runtime.emf.core.internal.plugin.MSLStatusCodes;
33
import org.eclipse.gmf.runtime.emf.core.internal.util.Trace;
34
import org.eclipse.gmf.runtime.emf.core.resources.AbstractLogicalResourcePolicy;
35
import org.eclipse.gmf.runtime.emf.core.resources.CannotAbsorbException;
36
import org.eclipse.gmf.runtime.emf.core.resources.CannotSeparateException;
37
import org.eclipse.gmf.runtime.emf.core.resources.ILogicalResource;
38
import org.eclipse.gmf.runtime.emf.core.resources.ILogicalResourcePolicy;
39
import org.eclipse.osgi.util.NLS;
40
41
42
/**
43
 * Manager of {@link ILogicalResourcePolicy} implementations registered on the
44
 * <tt>org.eclipse.gmf.runtime.emf.core.resourcePolicies</tt> extension point.
45
 *
46
 * @author Christian W. Damus (cdamus)
47
 */
48
public class LogicalResourcePolicyManager implements ILogicalResourcePolicy {
49
	private static final String EXT_POINT = "resourcePolicies"; //$NON-NLS-1$
50
	private static final String E_POLICY = "policy"; //$NON-NLS-1$
51
	private static final String E_EPACKAGE = "epackage"; //$NON-NLS-1$
52
	private static final String E_EFACTORY = "efactory"; //$NON-NLS-1$
53
	private static final String A_NSURI = "nsURI"; //$NON-NLS-1$
54
	private static final String A_CLASS = "class"; //$NON-NLS-1$
55
	
56
	private static final LogicalResourcePolicyManager INSTANCE =
57
		new LogicalResourcePolicyManager();
58
	
59
	private static final ILogicalResourcePolicy[] EMPTY_ARRAY =
60
		new ILogicalResourcePolicy[0];
61
	
62
	private final Map policyMap = new java.util.HashMap();
63
	private final Map factoryMap = new java.util.HashMap();
64
	
65
	/**
66
	 * Not instantiable by clients.
67
	 */
68
	private LogicalResourcePolicyManager() {
69
		super();
70
		initializePolicyExtensions();
71
	}
72
73
	/**
74
	 * Obtains the singleton policy manager instance.
75
	 * 
76
	 * @return the policy manager
77
	 */
78
	public static LogicalResourcePolicyManager getInstance() {
79
		return INSTANCE;
80
	}
81
	
82
	/**
83
	 * Initializes me from the extension point.
84
	 */
85
	private void initializePolicyExtensions() {
86
		IConfigurationElement[] elements =
87
			Platform.getExtensionRegistry().getConfigurationElementsFor(
88
			MSLPlugin.getPluginId(), EXT_POINT);
89
		
90
		for (int i = 0; i < elements.length; i++) {
91
			if (E_POLICY.equals(elements[i].getName())) {
92
				initializePolicy(elements[i]);
93
			} else if (E_EFACTORY.equals(elements[i].getName())) {
94
				initializeFactory(elements[i]);
95
			} else {
96
				Log.log(
97
					MSLPlugin.getDefault(),
98
					IStatus.WARNING,
99
					MSLStatusCodes.LOGICAL_INVALID_POLICY_ELEMENT,
100
					NLS.bind(EMFCoreMessages.resourcePolicy_element_WARN_,
101
						new Object[] {
102
							elements[i].getName(),
103
							elements[i].getNamespace()}),
104
					null);
105
			}
106
		}
107
		
108
		// convert the policy map's lists to arrays
109
		for (Iterator iter = policyMap.entrySet().iterator(); iter.hasNext();) {
110
			Map.Entry next = (Map.Entry) iter.next();
111
			List list = (List) next.getValue();
112
			
113
			next.setValue(list.toArray(new ILogicalResourcePolicy[list.size()]));
114
		}
115
	}
116
	
117
	private void initializePolicy(IConfigurationElement element) {
118
		PolicyDescriptor descriptor = new PolicyDescriptor(element);
119
		
120
		List nsUris = descriptor.getNamespaceUris();
121
		
122
		if (nsUris.isEmpty()) {
123
			Log.warning(
124
				MSLPlugin.getDefault(),
125
				MSLStatusCodes.LOGICAL_INVALID_POLICY_ELEMENT,
126
				NLS.bind(EMFCoreMessages.resourcePolicy_nsUris_WARN_, element.getNamespace())
127
			);
128
		} else {
129
			for (Iterator iter = nsUris.iterator(); iter.hasNext();) {
130
				String nsUri = (String) iter.next();
131
				
132
				List list = (List) policyMap.get(nsUri);
133
				if (list == null) {
134
					list = new java.util.ArrayList();
135
					policyMap.put(nsUri, list);
136
				}
137
				
138
				list.add(descriptor);
139
			}
140
		}
141
	}
142
	
143
	private void initializeFactory(IConfigurationElement element) {
144
		FactoryDescriptor descriptor = new FactoryDescriptor(element);
145
		factoryMap.put(descriptor.getNamespaceUri(), descriptor);
146
	}
147
	
148
	/**
149
	 * Gets the policies pertaining to the specified model element.
150
	 * 
151
	 * @param eObject an element
152
	 * @return the policies or an empty array if none (never <code>null</code>)
153
	 */
154
	ILogicalResourcePolicy[] getPolicies(EObject eObject) {
155
		return getPolicies(eObject.eClass().getEPackage().getNsURI());
156
	}
157
	
158
	/**
159
	 * Gets the policies pertaining to the specified metamodel.
160
	 * 
161
	 * @param nsUri a metamodel namespace URI
162
	 * @return the policies or an empty array if none (never <code>null</code>)
163
	 */
164
	ILogicalResourcePolicy[] getPolicies(String nsUri) {
165
		ILogicalResourcePolicy[] result =
166
			(ILogicalResourcePolicy[]) policyMap.get(nsUri);
167
		
168
		if (result == null) {
169
			result = EMPTY_ARRAY;
170
			policyMap.put(nsUri, result);
171
		}
172
		
173
		return result;
174
	}
175
176
	public boolean canSeparate(ILogicalResource resource, EObject eObject) {
177
		boolean result = true;
178
		ILogicalResourcePolicy[] policies = getPolicies(eObject);
179
		
180
		for (int i = 0; result && (i < policies.length); i++) {
181
			try {
182
				if (Trace.isEnabled(MSLDebugOptions.RESOURCES)) {
183
					Trace.trace(
184
						MSLDebugOptions.RESOURCES,
185
						"Invoking canSeparate() on policy: " + policies[i]); //$NON-NLS-1$
186
				}
187
				
188
				result = policies[i].canSeparate(resource, eObject);
189
			} catch (RuntimeException e) {
190
				Trace.catching(getClass(), "canSeparate", e); //$NON-NLS-1$
191
				Log.warning(
192
					MSLPlugin.getDefault(),
193
					MSLStatusCodes.LOGICAL_POLICY_FAILED,
194
					EMFCoreMessages.resource_policy_EXC_,
195
					e);
196
			}
197
		}
198
		
199
		return result;
200
	}
201
202
	public URI preSeparate(ILogicalResource resource, EObject eObject, URI uri)
203
		throws CannotSeparateException {
204
		
205
		URI result = uri;
206
		ILogicalResourcePolicy[] policies = getPolicies(eObject);
207
		
208
		for (int i = 0; i < policies.length; i++) {
209
			try {
210
				if (Trace.isEnabled(MSLDebugOptions.RESOURCES)) {
211
					Trace.trace(
212
						MSLDebugOptions.RESOURCES,
213
						"Invoking preSeparate() on policy: " + policies[i]); //$NON-NLS-1$
214
				}
215
				
216
				URI suggestion = policies[i].preSeparate(resource, eObject, uri);
217
				
218
				if (result == null) {
219
					result = suggestion;
220
				}
221
			} catch (RuntimeException e) {
222
				Trace.catching(getClass(), "preSeparate", e); //$NON-NLS-1$
223
				Log.warning(
224
					MSLPlugin.getDefault(),
225
					MSLStatusCodes.LOGICAL_POLICY_FAILED,
226
					EMFCoreMessages.resource_policy_EXC_,
227
					e);
228
			}
229
		}
230
		
231
		return result;
232
	}
233
234
	public void postSeparate(ILogicalResource resource, EObject eObject, URI uri) {
235
		ILogicalResourcePolicy[] policies = getPolicies(eObject);
236
		
237
		for (int i = 0; i < policies.length; i++) {
238
			try {
239
				if (Trace.isEnabled(MSLDebugOptions.RESOURCES)) {
240
					Trace.trace(
241
						MSLDebugOptions.RESOURCES,
242
						"Invoking postSeparate() on policy: " + policies[i]); //$NON-NLS-1$
243
				}
244
				
245
				policies[i].postSeparate(resource, eObject, uri);
246
			} catch (RuntimeException e) {
247
				Trace.catching(getClass(), "postSeparate", e); //$NON-NLS-1$
248
				Log.warning(
249
					MSLPlugin.getDefault(),
250
					MSLStatusCodes.LOGICAL_POLICY_FAILED,
251
					EMFCoreMessages.resource_policy_EXC_,
252
					e);
253
			}
254
		}
255
	}
256
257
	public void preAbsorb(ILogicalResource resource, EObject eObject)
258
		throws CannotAbsorbException {
259
		
260
		ILogicalResourcePolicy[] policies = getPolicies(eObject);
261
		
262
		for (int i = 0; i < policies.length; i++) {
263
			try {
264
				if (Trace.isEnabled(MSLDebugOptions.RESOURCES)) {
265
					Trace.trace(
266
						MSLDebugOptions.RESOURCES,
267
						"Invoking preAbsorb() on policy: " + policies[i]); //$NON-NLS-1$
268
				}
269
				
270
				policies[i].preAbsorb(resource, eObject);
271
			} catch (RuntimeException e) {
272
				Trace.catching(getClass(), "preAbsorb", e); //$NON-NLS-1$
273
				Log.warning(
274
					MSLPlugin.getDefault(),
275
					MSLStatusCodes.LOGICAL_POLICY_FAILED,
276
					EMFCoreMessages.resource_policy_EXC_,
277
					e);
278
			}
279
		}
280
	}
281
282
	public void postAbsorb(ILogicalResource resource, EObject eObject) {
283
		ILogicalResourcePolicy[] policies = getPolicies(eObject);
284
		
285
		for (int i = 0; i < policies.length; i++) {
286
			try {
287
				if (Trace.isEnabled(MSLDebugOptions.RESOURCES)) {
288
					Trace.trace(
289
						MSLDebugOptions.RESOURCES,
290
						"Invoking postAbsorb() on policy: " + policies[i]); //$NON-NLS-1$
291
				}
292
				
293
				policies[i].postAbsorb(resource, eObject);
294
			} catch (RuntimeException e) {
295
				Trace.catching(getClass(), "postAbsorb", e); //$NON-NLS-1$
296
				Log.warning(
297
					MSLPlugin.getDefault(),
298
					MSLStatusCodes.LOGICAL_POLICY_FAILED,
299
					EMFCoreMessages.resource_policy_EXC_,
300
					e);
301
			}
302
		}
303
	}
304
	
305
	/**
306
	 * Instantiates the specified <code>EClass</code> in order to create an
307
	 * unloaded element.  This method will use a factory registered on the
308
	 * extension point for this purpose, if any.  Otherwise, it will use the
309
	 * package's default factory.
310
	 * 
311
	 * @param eClass the <code>EClass</code> to create
312
	 * @return a new instance of it
313
	 */
314
	public EObject create(EClass eClass) {
315
		EFactory factory = getEFactory(eClass.getEPackage());
316
		return factory.create(eClass);
317
	}
318
	
319
	/**
320
	 * Gets the most appropriate factory for the specified package.  This might
321
	 * be one that is registered on the extension point, or it might not.
322
	 * 
323
	 * @param epackage the <code>EPackage</code> to get a factory for
324
	 * @return the corresponding factory
325
	 */
326
	public EFactory getEFactory(EPackage epackage) {
327
		EFactory result;
328
		FactoryDescriptor descriptor = (FactoryDescriptor) factoryMap.get(
329
			epackage.getNsURI());
330
		
331
		if (descriptor == null) {
332
			result = epackage.getEFactoryInstance();
333
		} else {
334
			result = descriptor.instantiate();
335
		}
336
		
337
		return result;
338
	}
339
	
340
	/**
341
	 * Extension descriptor that lazily initializes the delegate policy instance
342
	 * when required.  It replaces itself by the delegate for efficiency.
343
	 *
344
	 * @author Christian W. Damus (cdamus)
345
	 */
346
	private class PolicyDescriptor implements ILogicalResourcePolicy {
347
		private IConfigurationElement config;
348
		private List namespaceUris = new java.util.ArrayList();
349
		private ILogicalResourcePolicy delegate;
350
		
351
		PolicyDescriptor(IConfigurationElement config) {
352
			this.config = config;
353
			
354
			IConfigurationElement[] elements = config.getChildren();
355
			for (int i = 0; i < elements.length; i++) {
356
				if (E_EPACKAGE.equals(elements[i].getName())) {
357
					String nsUri = elements[i].getAttribute(A_NSURI);
358
					
359
					if ((nsUri != null) && (nsUri.length() > 0)) {
360
						namespaceUris.add(nsUri);
361
					}
362
				} else {
363
					Log.log(
364
						MSLPlugin.getDefault(),
365
						IStatus.WARNING,
366
						MSLStatusCodes.LOGICAL_INVALID_POLICY_ELEMENT,
367
						NLS.bind(EMFCoreMessages.resourcePolicy_element_WARN_,
368
							new Object[] {
369
								elements[i].getName(),
370
								elements[i].getNamespace()}),
371
						null);
372
				}
373
			}
374
		}
375
		
376
		List getNamespaceUris() {
377
			return namespaceUris;
378
		}
379
		
380
		/**
381
		 * Ensures that my delegate is instantiated and replaces me in the
382
		 * manager's map.
383
		 * 
384
		 * @return the actual policy, or a null implementation if the real one
385
		 *     failed to initialize
386
		 */
387
		ILogicalResourcePolicy instantiate() {
388
			if (delegate == null) {
389
				try {
390
					delegate = (ILogicalResourcePolicy) config.createExecutableExtension(A_CLASS);
391
				} catch (CoreException e) {
392
					Trace.catching(getClass(), "instantiate", e); //$NON-NLS-1$
393
					
394
					Log.log(MSLPlugin.getDefault(), e.getStatus());
395
					
396
					delegate = new NullPolicy();
397
				}
398
				
399
				for (Iterator iter = getNamespaceUris().iterator(); iter.hasNext();) {
400
					String nsUri = (String) iter.next();
401
					
402
					ILogicalResourcePolicy[] policies = getPolicies(nsUri);
403
					for (int i = 0; i < policies.length; i++) {
404
						if (policies[i] == this) {
405
							policies[i] = delegate;
406
						}
407
					}
408
				}
409
			}
410
			
411
			return delegate;
412
		}
413
414
		public boolean canSeparate(ILogicalResource resource, EObject eObject) {
415
			instantiate();
416
			
417
			return delegate.canSeparate(resource, eObject);
418
		}
419
420
		public URI preSeparate(ILogicalResource resource, EObject eObject, URI uri)
421
			throws CannotSeparateException {
422
			
423
			instantiate();
424
			
425
			return delegate.preSeparate(resource, eObject, uri);
426
		}
427
428
		public void postSeparate(ILogicalResource resource, EObject eObject, URI uri) {
429
			instantiate();
430
			
431
			delegate.postSeparate(resource, eObject, uri);
432
		}
433
434
		public void preAbsorb(ILogicalResource resource, EObject eObject)
435
			throws CannotAbsorbException {
436
			
437
			instantiate();
438
			
439
			delegate.preAbsorb(resource, eObject);
440
		}
441
442
		public void postAbsorb(ILogicalResource resource, EObject eObject) {
443
			instantiate();
444
			
445
			delegate.postAbsorb(resource, eObject);
446
		}
447
		
448
		public String toString() {
449
			instantiate();
450
			
451
			return delegate.toString();
452
		}
453
	}
454
	
455
	/**
456
	 * Extension descriptor that lazily initializes the delegate factory instance
457
	 * when required.
458
	 *
459
	 * @author Christian W. Damus (cdamus)
460
	 */
461
	private class FactoryDescriptor {
462
		private IConfigurationElement config;
463
		private String namespaceUri;
464
		private EFactory factory;
465
		
466
		FactoryDescriptor(IConfigurationElement config) {
467
			this.config = config;
468
			namespaceUri = config.getAttribute(A_NSURI);
469
		}
470
		
471
		String getNamespaceUri() {
472
			return namespaceUri;
473
		}
474
		
475
		/**
476
		 * Ensures that my delegate is instantiated and replaces me in the
477
		 * manager's map.
478
		 * 
479
		 * @return the actual factory, or the default implementation if the
480
		 *     configured one failed to initialize
481
		 */
482
		EFactory instantiate() {
483
			if (factory == null) {
484
				try {
485
					factory = (EFactory) config.createExecutableExtension(A_CLASS);
486
				} catch (CoreException e) {
487
					Trace.catching(getClass(), "instantiate", e); //$NON-NLS-1$
488
					
489
					Log.log(MSLPlugin.getDefault(), e.getStatus());
490
					
491
					factory = EPackage.Registry.INSTANCE.getEPackage(
492
						getNamespaceUri()).getEFactoryInstance();
493
				}
494
			}
495
			
496
			return factory;
497
		}
498
	}
499
	
500
	/**
501
	 * Placeholder for policy extensions that could not be instantiated.
502
	 *
503
	 * @author Christian W. Damus (cdamus)
504
	 */
505
	private static final class NullPolicy extends AbstractLogicalResourcePolicy {
506
		NullPolicy() {
507
			super();
508
		}
509
	}
510
}
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resources/LogicalResource.java (-1047 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
13
package org.eclipse.gmf.runtime.emf.core.internal.resources;
14
15
import java.io.IOException;
16
import java.io.InputStream;
17
import java.io.OutputStream;
18
import java.util.Collection;
19
import java.util.Comparator;
20
import java.util.Iterator;
21
import java.util.List;
22
import java.util.Map;
23
import java.util.Set;
24
25
import org.eclipse.core.runtime.Platform;
26
import org.eclipse.emf.common.notify.Notification;
27
import org.eclipse.emf.common.util.ECollections;
28
import org.eclipse.emf.common.util.EList;
29
import org.eclipse.emf.common.util.URI;
30
import org.eclipse.emf.ecore.EObject;
31
import org.eclipse.emf.ecore.EPackage;
32
import org.eclipse.emf.ecore.EReference;
33
import org.eclipse.emf.ecore.EStructuralFeature;
34
import org.eclipse.emf.ecore.resource.Resource;
35
import org.eclipse.emf.ecore.resource.ResourceSet;
36
import org.eclipse.emf.ecore.resource.URIConverter;
37
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
38
import org.eclipse.emf.ecore.util.EContentAdapter;
39
import org.eclipse.emf.ecore.util.EcoreUtil;
40
import org.eclipse.gmf.runtime.common.core.util.Log;
41
import org.eclipse.gmf.runtime.emf.core.internal.l10n.EMFCoreMessages;
42
import org.eclipse.gmf.runtime.emf.core.internal.plugin.MSLDebugOptions;
43
import org.eclipse.gmf.runtime.emf.core.internal.plugin.MSLPlugin;
44
import org.eclipse.gmf.runtime.emf.core.internal.plugin.MSLStatusCodes;
45
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry;
46
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry;
47
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap;
48
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage;
49
import org.eclipse.gmf.runtime.emf.core.internal.util.Trace;
50
import org.eclipse.gmf.runtime.emf.core.resources.AbstractLogicalResource;
51
import org.eclipse.gmf.runtime.emf.core.resources.CannotAbsorbException;
52
import org.eclipse.gmf.runtime.emf.core.resources.CannotSeparateException;
53
import org.eclipse.gmf.runtime.emf.core.resources.ILogicalResource;
54
import org.eclipse.gmf.runtime.emf.core.resources.MResourceFactory;
55
import org.eclipse.osgi.util.NLS;
56
57
/**
58
 * Implementation of the {@linkplain ILogicalResource logical resource} API.
59
 * <p>
60
 * <b>Note</b> that subclasses are encouraged to define also a companion unit
61
 * class extending {@link LogicalResourceUnit}, in case they have any need to
62
 * customize the serialization of their physical resources.  If a custom unit
63
 * class is implemented, then the logical resource class must override the
64
 * {@link #createUnit(URI)} method to create instances of the appropriate unit
65
 * class.
66
 * </p>
67
 * <p>
68
 * For example:
69
 * </p><pre>
70
 *     public class MyResource extends LogicalResource {
71
 *         // ... fields and stuff ...
72
 *         
73
 *         public MyResource(URI uri) {
74
 *             super(root, uri);
75
 *             
76
 *             // ... other initialization ...
77
 *         }
78
 *         
79
 *         protected LogicalResourceUnit createUnit(URI uri) {
80
 *             return new MyResourceUnit(uri, this);
81
 *         }
82
 *         
83
 *         // ... other methods and stuff ...
84
 *     }
85
 *     
86
 *     public class MyResourceUnit extends LogicalResourceUnit {
87
 *         public MyResourceUnit(URI uri, MyResource logical) {
88
 *             super(uri, logical);
89
 *         }
90
 *         
91
 *         // ... other stuff here ...
92
 *     }
93
 * </pre>
94
 *
95
 * @see LogicalResourceUnit
96
 * @see #createUnit(URI)
97
 * 
98
 * @author Christian W. Damus (cdamus)
99
 */
100
public class LogicalResource
101
	extends AbstractLogicalResource
102
	implements ILogicalResource {
103
104
	private DirtyAdapter dirtyAdapter;
105
	
106
	// stores the individual sub-unit resources.  All resources share one copy
107
	//    so that they can resolve x-refs to the same physical resource
108
	private final ResourceSet subunitResourceSet;
109
	
110
	private boolean autoLoadEnabled = true;
111
	
112
	/**
113
	 * Initializes me with my URI.
114
	 * 
115
	 * @param uri my URI
116
	 */
117
	protected LogicalResource(URI uri) {
118
		super(uri);
119
		
120
		dirtyAdapter = new DirtyAdapter();
121
		eAdapters().add(dirtyAdapter);
122
		subunitResourceSet = new SubunitResourceSet();
123
		contents = new LogicalContentsList();
124
	}
125
126
	protected boolean useUUIDs() {
127
		return true;
128
	}
129
	
130
	/**
131
	 * Creates a new unit of this logical resource.  Subclasses must override
132
	 * to create an instance of their companion unit class.
133
	 * 
134
	 * @param uri the URI of the new unit
135
	 * @return the new unit
136
	 */
137
	protected LogicalResourceUnit createUnit(URI unitUri) {
138
		return new LogicalResourceUnit(unitUri, this);
139
	}
140
	
141
	public boolean isSeparate(EObject eObject) {
142
		return LogicalResourceUtil.isSeparate(this, eObject);
143
	}
144
	
145
	protected void doSeparate(EObject eObject, URI physUri) throws CannotSeparateException {
146
		LogicalResourceUtil.separate(this, eObject, physUri);
147
	}
148
	
149
	protected void doAbsorb(EObject eObject) throws CannotAbsorbException {
150
		LogicalResourceUtil.absorb(this, eObject);
151
	}
152
	
153
	public boolean isLoaded(EObject eObject) {
154
		return LogicalResourceUtil.isLoaded(this, eObject);
155
	}
156
	
157
	protected void doLoad(EObject eObject) throws IOException {
158
		LogicalResourceUtil.load(this, eObject);
159
		
160
		LogicalResourceUnit unit = getUnit(eObject);
161
		
162
		// Propagate content adapters to the now-loaded object.
163
		//    Make sure that the adapters' propagation, if they encounter any
164
		//    more unloaded objects, doesn't cause the rest of the tree
165
		//    to load prematurely
166
		try {
167
			unit.disableAutoLoad();
168
			eObject.eAdapters().addAll(
169
				0,
170
				getContentAdapters(eObject.eContainer()));
171
		} finally {
172
			unit.enableAutoLoad();
173
		}
174
	}
175
	
176
	// overridden to make it visible in this package
177
	protected void addMappedResource(EObject object, Resource subunit) {
178
		super.addMappedResource(object, subunit);
179
	}
180
181
	// overridden to make it visible in this package
182
	protected void removeMappedResource(EObject object) {
183
		super.removeMappedResource(object);
184
	}
185
	
186
	// overridden to make it visible in this package
187
	protected Map getResourceMap() {
188
		return super.getResourceMap();
189
	}
190
	
191
	protected Resource getPhysicalResource(URI physUri) {
192
		Resource result = getSubunitResourceSet().getResource(physUri, false);
193
		
194
		if (result != null) {
195
			result = UnmodifiableResourceView.get(result);
196
		}
197
		
198
		return result;
199
	}
200
	
201
	/**
202
	 * Extends the inherited method to revert the logical resource to a single,
203
	 * monolithic logical resource on the new URI.  This ensures that saving the
204
	 * resource under a new URI does not leave the former root resource
205
	 * disconnected from its sub-units (as they would be subordinate to the
206
	 * new URI).  It also ensures that there will be no need to check out all of
207
	 * the sub-units in an SCM environment.
208
	 */
209
	public void setURI(URI uri) {
210
		super.setURI(uri);
211
		
212
		// load any as-yet-unloaded sub-units
213
		try {
214
			LogicalResourceUtil.loadAllUnloadedUnits(this);
215
		} catch (IOException e) {
216
			Trace.catching(getClass(), "setURI(URI)", e); //$NON-NLS-1$
217
			
218
			Log.error(
219
				MSLPlugin.getDefault(),
220
				MSLStatusCodes.LOGICAL_SETURI_UNLOADED_FAILED,					
221
				NLS.bind(EMFCoreMessages.setUri_unloaded_failed_EXC_, uri),
222
				e);
223
		}
224
		
225
		// forget all of my sub-units
226
		clearMappedResources();
227
		getSubunitResourceSet().getResources().clear();
228
		
229
		// create my new physical root
230
		LogicalResourceUnit phys = getRootUnit();
231
		phys.setDirty();
232
		
233
		// all of my roots are in the new physical root
234
		phys.getContents().addAll(getContents());
235
	}
236
	
237
	public Object getAdapter(Class adapter) {
238
		if (adapter == ResourceSet.class) {
239
			// I do represent a resource set, in a sense
240
			return getSubunitResourceSet();
241
		} else {
242
			return Platform.getAdapterManager().getAdapter(this, adapter);
243
		}
244
	}
245
	
246
	/**
247
	 * Finds and, if necessary, creates the physical resource corresponding
248
	 * to the logical resource URI.  This is the "root" of the physical resource
249
	 * structure.
250
	 * 
251
	 * @return the root physical resource
252
	 */
253
	LogicalResourceUnit getRootUnit() {
254
		LogicalResourceUnit result =
255
			(LogicalResourceUnit) getSubunitResourceSet().getResource(
256
				getURI(),
257
				false);
258
		
259
		if (result == null) {
260
			result = (LogicalResourceUnit) getSubunitResourceSet().createResource(
261
				getURI());
262
		}
263
		
264
		return result;
265
	}
266
	
267
	/**
268
	 * Obtains the resource set that maintains my physical resources.
269
	 * 
270
	 * @return my physical resource set
271
	 */
272
	ResourceSet getSubunitResourceSet() {
273
		return subunitResourceSet;
274
	}
275
	
276
	/**
277
	 * Ensures that the specified element has all of the content adapters
278
	 * attached to it that its container has.
279
	 * 
280
	 * @param eObject the element
281
	 */
282
	void propagateContentAdapters(EObject eObject) {
283
		eObject.eAdapters().addAll(getContentAdapters(eObject.eContainer()));
284
	}
285
	
286
	/**
287
	 * Ensures that the specified element does not have my dirty adapter
288
	 * attached to it.
289
	 * 
290
	 * @param eObject the element
291
	 */
292
	void removeContentAdapters(EObject eObject) {
293
		eObject.eAdapters().removeAll(getContentAdapters(eObject));
294
	}
295
	
296
	/**
297
	 * Gets those of the adapters attached to an element that are content
298
	 * adapters.  If the element is <code>null</code>, then the adapters on the
299
	 * logical resource are returned, for convenience when an element's
300
	 * container (which normally would propagate) is <code>null</code>.
301
	 * 
302
	 * @param eObject an element, or <code>null</code> to get the adapters on
303
	 *      the logical resource
304
	 * @return the content adapters (and not other kinds of adapters)
305
	 */
306
	List getContentAdapters(EObject eObject) {
307
		Collection adapters;
308
		if (eObject == null) {
309
			adapters = eAdapters();
310
		} else {
311
			adapters = eObject.eAdapters();
312
		}
313
		
314
		List result = new java.util.ArrayList(adapters.size());
315
		for (Iterator iter = adapters.iterator(); iter.hasNext();) {
316
			Object next = iter.next();
317
			
318
			if (next instanceof EContentAdapter) {
319
				result.add(next);
320
			}
321
		}
322
		
323
		return result;
324
	}
325
	
326
	private void initCustomLoadOptions(Map options) {
327
		if (!options.containsKey(OPTION_LOAD_AS_LOGICAL)) {
328
			options.put(OPTION_LOAD_AS_LOGICAL, Boolean.TRUE);
329
		}
330
		
331
		if (!Boolean.TRUE.equals(options.get(OPTION_LOAD_AS_LOGICAL))) {
332
			// don't load any sub-units
333
			options.put(OPTION_LOAD_ALL_UNITS, Boolean.FALSE);
334
			options.put(OPTION_AUTO_LOAD_UNITS, Boolean.FALSE);
335
		} else {
336
			if (!options.containsKey(OPTION_LOAD_ALL_UNITS)) {
337
				options.put(OPTION_LOAD_ALL_UNITS, Boolean.FALSE);
338
			}
339
			
340
			if (!options.containsKey(OPTION_AUTO_LOAD_UNITS)) {
341
				options.put(OPTION_AUTO_LOAD_UNITS, Boolean.TRUE);
342
			}
343
		}
344
		
345
		// propagate to demand-loaded sub-units
346
		((SubunitResourceSet) getSubunitResourceSet()).clearLoadOptions();
347
		getSubunitResourceSet().getLoadOptions().putAll(options);
348
	}
349
	
350
	public void doLoad(InputStream inputStream, Map options)
351
		throws IOException {
352
		
353
		try {
354
			disableAutoLoad();
355
			dirtyAdapter.disable();
356
			
357
			initCustomLoadOptions(options);
358
			
359
			final boolean loadAsLogical = Boolean.TRUE.equals(
360
				options.get(OPTION_LOAD_AS_LOGICAL));
361
			
362
			// do the loading
363
			
364
			LogicalResourceUnit physicalRoot = getRootUnit();
365
			
366
			LogicalResourceUtil.loadUnit(physicalRoot, inputStream);
367
			
368
			if (loadAsLogical && (physicalRoot.getResourceIndex() != null)) {
369
				// if we're loading ourselves as a logical resource, then
370
				//    check whether we are opening the root resource
371
				ResourceMap rootIndex = physicalRoot.getResourceIndex().getRootMap();
372
				
373
				if ((rootIndex != null) && (rootIndex != physicalRoot.getResourceIndex())) {
374
					
375
					// I am not the root of the logical resource.  I need to
376
					//   load it and become it.  Be sure to load the whole
377
					//   containment chain up to the root
378
					
379
					// This handles the case where rootIndex is a proxy
380
					URI rootUri = EcoreUtil.getURI(rootIndex).trimFragment();
381
					
382
					// Be careful not to set the URI of the physical resource
383
					//    that I have already loaded
384
					super.setURI(rootUri);
385
					
386
					physicalRoot = getRootUnit();
387
					
388
					if (!physicalRoot.isLoaded()) {
389
						// this shouldn't happen, because we should have
390
						//    resolved the rootIndex reference by loading
391
						//    the root resource already!
392
						LogicalResourceUtil.loadUnit(physicalRoot);
393
					}
394
				}
395
			} else if (!loadAsLogical && getContents().isEmpty()) {
396
				// we didn't get any of the logical roots, yet, from the true
397
				//    root unit, so we should fake it
398
				EList actualRoots = physicalRoot.getContents();
399
				int offset = 1 + actualRoots.indexOf(
400
					physicalRoot.getResourceIndex());
401
				
402
				getContents().addAll(actualRoots.subList(
403
					offset, actualRoots.size()));
404
			}
405
		} finally {
406
			dirtyAdapter.enable();
407
		}
408
		
409
		if (Trace.isEnabled(MSLDebugOptions.RESOURCES)) {
410
			Trace.trace(
411
				MSLDebugOptions.RESOURCES,
412
				"Loaded logical resource: " + getURI()); //$NON-NLS-1$
413
		}
414
	}
415
	
416
	public void save(Map options)
417
		throws IOException {
418
		
419
		if (getRootUnit().isDirty() || isMonolithic()) {
420
			// for compatibility with the defaultXMI resource implementation,
421
			//   we will force the save even when we are not dirty, if we
422
			//   are monolithic
423
			super.save(options);
424
		} else {
425
			// we're not dirty, so we don't need an output stream to write to,
426
			//    but we probably have sub-units that need saving
427
			doSave((OutputStream)null, options);
428
			setModified(false);
429
		}
430
	}
431
	
432
	public void doSave(OutputStream outputStream, Map options)
433
		throws IOException {
434
		
435
		try {
436
			dirtyAdapter.disable();
437
			
438
			cleanupResourceIndices();
439
			
440
			LogicalResourceUnit phys = getRootUnit();
441
			
442
			if (phys.isDirty() ||(outputStream != null)) {
443
				// use this output stream to save my physical root resource
444
				phys.save(outputStream, options);
445
			}
446
			
447
			saveSubunits(options, getSubunitResourceSet());
448
			
449
			if (Trace.isEnabled(MSLDebugOptions.RESOURCES)) {
450
				Trace.trace(
451
					MSLDebugOptions.RESOURCES,
452
					"Saved logical resource: " + getURI()); //$NON-NLS-1$
453
			}
454
		} finally {
455
			dirtyAdapter.enable();
456
			
457
			if (errors != null) {
458
				// look for an IOException that indicates a save problem, and
459
				//    throw it
460
				for (Iterator iter = errors.iterator(); iter.hasNext();) {
461
					Object next = iter.next();
462
					
463
					if (next instanceof IOException) {
464
						IOException e = (IOException) next;
465
						Trace.throwing(getClass(), "doSave(OutputStream, Map)", e); //$NON-NLS-1$
466
						throw e;
467
					}
468
				}
469
			}
470
		}
471
	}
472
	
473
	/**
474
	 * Queries whether auto-loading of sub-units is enabled.
475
	 * 
476
	 * @return <code>true</code> if auto-loading of sub-units is enabled;
477
	 *     <code>false</code>, otherwise
478
	 */
479
	boolean isAutoLoadEnabled() {
480
		return autoLoadEnabled;
481
	}
482
	
483
	/**
484
	 * Turns off auto-loading of unloaded sub-units.
485
	 */
486
	void disableAutoLoad() {
487
		autoLoadEnabled = false;
488
	}
489
	
490
	/**
491
	 * Turns on auto-loading of unloaded sub-units.  This should only be
492
	 * invoked either by the root resource when it first becomes unmodified
493
	 * after loading.
494
	 */
495
	void enableAutoLoad() {
496
		autoLoadEnabled = true;
497
	}
498
	
499
	/**
500
	 * Used by the root of the logical resource to save all of its sub-unit
501
	 * resources that are dirty.
502
	 * 
503
	 * @param options the current save options (all units saved with the same
504
	 *    options
505
	 * @param rset the resource set containing the sub-unit resources
506
	 * @throws IOException if anything goes wrong in saving a resource
507
	 */
508
	private void saveSubunits(Map options, ResourceSet rset) {
509
		for (Iterator iter = rset.getResources().iterator(); iter.hasNext();) {
510
			LogicalResourceUnit next = (LogicalResourceUnit) iter.next();
511
			
512
			if (next.isDirty()) {
513
				try {
514
					next.save(options);
515
				} catch (IOException e) {
516
					Trace.catching(getClass(), "saveSubunits(Map, ResourceSet)", e); //$NON-NLS-1$
517
					error(e);
518
				}
519
			}
520
		}
521
	}
522
	
523
	/**
524
	 * Adds a throwable to my list of error-severity exceptions.
525
	 * 
526
	 * @param t a throwable to add to my errors
527
	 */
528
	protected void error(Throwable t) {
529
		getErrors().add(t);
530
	}
531
	
532
	protected void doUnload() {
533
		super.doUnload();
534
		
535
		clearMappedResources();
536
		
537
		ResourceSet rset = getSubunitResourceSet();
538
		List toUnload = new java.util.ArrayList(rset.getResources());
539
		
540
		for (Iterator iter = toUnload.iterator(); iter.hasNext();) {
541
			((Resource) iter.next()).unload();
542
		}
543
		
544
		rset.getResources().clear();
545
	}
546
	
547
	/**
548
	 * Queries whether I am a monolithic logical resource, comprising only a
549
	 * single physical resource.
550
	 * 
551
	 * @return whether I do not comprise more than one physical resource
552
	 */
553
	boolean isMonolithic() {
554
		return getSubunitResourceSet().getResources().size() < 2;
555
	}
556
	
557
	/**
558
	 * Cleans up my resource indices to ensure that they are up-to-date when we
559
	 * save.  This should only be invoked on the root resource.
560
	 */
561
	private void cleanupResourceIndices() {
562
		Set resources = new java.util.HashSet(
563
			getSubunitResourceSet().getResources());
564
		
565
		// let each resource recompute its resource index if it is dirty.
566
		//   This may even involve moving sub-units between parent units
567
		for (Iterator iter = resources.iterator(); iter.hasNext();) {
568
			LogicalResourceUnit subunit = (LogicalResourceUnit) iter.next();
569
		
570
			if (subunit.isDirty()) {
571
				subunit.cleanupResourceIndex();
572
			} else {
573
				iter.remove(); // don't process in the next loop
574
			}
575
		}
576
		
577
		// now, we must sort the sub-unit entries for each parent object
578
		//    by position, so that we will not try to insert them out of
579
		//    sequence on next loading (which would access invalid indices).
580
		//    Do this in a separate loop once all resources know their
581
		//    sub-units
582
		Comparator comp = new Comparator() {
583
			public int compare(Object o1, Object o2) {
584
				return ((ResourceEntry) o1).getChildPosition()
585
					- ((ResourceEntry) o2).getChildPosition();
586
			}};
587
			
588
		for (Iterator iter = resources.iterator(); iter.hasNext();) {
589
			LogicalResourceUnit subunit = (LogicalResourceUnit) iter.next();
590
			ResourceMap index = subunit.getResourceIndex();
591
			
592
			if (index != null) {
593
				List toSort = index.getParentEntries();
594
				
595
				for (Iterator jter = toSort.iterator(); jter.hasNext();) {
596
					ParentEntry next = (ParentEntry) jter.next();
597
					ECollections.sort(next.getResourceEntries(), comp);
598
				}
599
			}
600
		}
601
	}
602
	
603
	/**
604
	 * Ensures that I know (and that adapters listening know) that I am loaded.
605
	 */
606
	void loaded() {
607
		if (!isLoaded()) {
608
			Notification notification = setLoaded(true);
609
			if (notification != null) {
610
				eNotify(notification);
611
			}
612
		}
613
	}
614
	
615
	public void setModified(boolean isModified) {
616
		super.setModified(isModified);
617
		
618
		if (!isModified) {
619
			// NOTE: Must do this only after firing the notification (in the
620
			// super method) because that is when the MSL's indexer traverses
621
			// the content tree, and it would force all of my sub-units to load
622
			enableAutoLoad();
623
		}
624
	}
625
	
626
	/**
627
	 * Finds and returns the physical resource that stores the specified
628
	 * element.
629
	 * 
630
	 * @param eObject an element in the logical resource
631
	 * @return the corresponding physical resource
632
	 * 
633
	 * @throws IllegalArgumentException if the <code>eObject</code> is not
634
	 *     in the logical resource
635
	 */
636
	public LogicalResourceUnit getUnit(EObject eObject) {
637
		return LogicalResourceUtil.getUnitFor(this, eObject);
638
	}
639
	
640
	/**
641
	 * Listens for changes in the contents of the logical resource, to set the
642
	 * dirty flag on the appropriate physical resource and to keep the physical
643
	 * mapping metadata up to date.
644
	 *
645
	 * @author Christian W. Damus (cdamus)
646
	 */
647
	private class DirtyAdapter extends EContentAdapter {
648
		private boolean enabled;
649
		
650
		public boolean isAdapterForType(Object type) {
651
			return type == DirtyAdapter.class;
652
		}
653
		
654
		/**
655
		 * Extends the inherited method to mark sub-units (physical resources)
656
		 * as dirty when their logical contents change, but only when dirty
657
		 * tracking is enabled.
658
		 */
659
		public void notifyChanged(Notification notification) {
660
			super.notifyChanged(notification);
661
			
662
			if (isEnabled() && !notification.isTouch()) {
663
				Object feature = notification.getFeature();
664
				if (feature instanceof EStructuralFeature &&
665
						((EStructuralFeature) feature).isTransient()) {
666
					// don't respond to transient features
667
					return;
668
				}
669
				
670
				Object notifier = notification.getNotifier();
671
				
672
				if (notifier instanceof EObject) {
673
					EObject eObject = (EObject) notifier;
674
					
675
					if ((eObject.eResource() != null)
676
							&& (eObject.eClass().getEPackage() != ResourceMapPackage.eINSTANCE)) {
677
						LogicalResourceUnit dirtyUnit = getUnit((EObject) notifier);
678
						dirtyUnit.setDirty();
679
					}
680
				} else if (notifier instanceof LogicalResource) {
681
					if (notification.getFeatureID(Resource.class) == Resource.RESOURCE__CONTENTS) {
682
						// any change in the contents list means that either the
683
						//    root unit's contents list is changed or its resource
684
						//    map is changed
685
						getRootUnit().setDirty();
686
					}
687
				}
688
			}
689
		}
690
691
		/**
692
		 * Extends the inherited method to update the resource index metadata
693
		 * whenever a separate element is removed from or added to the logical
694
		 * content tree.
695
		 */
696
		protected void handleContainment(Notification notification) {
697
			super.handleContainment(notification);
698
			
699
			if (isEnabled()) {
700
				Object notifier = notification.getNotifier();
701
				Object feature = notification.getFeature();
702
				
703
				switch (notification.getEventType()) {
704
					case Notification.SET:
705
					case Notification.UNSET: {
706
						Object value = notification.getOldValue();
707
						if (value != null) {
708
							removeFromResourceIndex(notifier, feature, value);
709
						}
710
						value = notification.getNewValue();
711
						if (value != null) {
712
							addToResourceIndex(value);
713
						}
714
						break;
715
					}
716
					case Notification.ADD: {
717
						addToResourceIndex(notification.getNewValue());
718
						break;
719
					}
720
					case Notification.MOVE: {
721
						updateResourceIndex(
722
							notification.getNewValue(),
723
							notification.getPosition());
724
						break;
725
					}
726
					case Notification.ADD_MANY: {
727
						Collection c = (Collection) notification.getNewValue();
728
						for (Iterator iter = c.iterator(); iter.hasNext(); ) {
729
							Object next = iter.next();
730
							addToResourceIndex(next);
731
						}
732
						break;
733
					}
734
					case Notification.REMOVE: {
735
						removeFromResourceIndex(
736
							notifier, feature, notification.getOldValue());
737
						break;
738
					}
739
					case Notification.REMOVE_MANY: {
740
						Collection c = (Collection) notification.getOldValue();
741
						for (Iterator iter = c.iterator(); iter.hasNext(); ) {
742
							Object next = iter.next();
743
							removeFromResourceIndex(notifier, feature, next);
744
						}
745
						break;
746
					}
747
				}
748
			}
749
		}
750
		
751
		/**
752
		 * Updates the resource index metadata when an element that was
753
		 * separate is added back into the content tree.  This recomputes the
754
		 * index in reparenting scenarios.
755
		 * 
756
		 * @param object an object added to the logical content tree
757
		 */
758
		private void addToResourceIndex(Object object) {
759
			if (object instanceof EObject) {
760
				EObject eObject = (EObject) object;
761
				EObject parent = eObject.eContainer();
762
				
763
				// is this a separate element that we are being added to?  If so,
764
				//    then we need to update the resource map for it
765
				addMappedResource(eObject, null);
766
				
767
				LogicalResourceUnit subunit =
768
					(LogicalResourceUnit) getResourceMap().get(eObject);
769
				
770
				if ((subunit != null) && !subunit.isRoot()) {
771
					subunit.getContents().add(eObject);
772
					
773
					LogicalResourceUnit parentUnit = getUnit(parent);
774
					if (parentUnit != null) {
775
						parentUnit.setDirty();
776
						updateChildPositions(parentUnit, parent, eObject.eContainmentFeature());
777
					}
778
				}
779
			}
780
		}
781
		
782
		/**
783
		 * Updates the resource index metadata when an element that was
784
		 * separate is removed from the content tree.  This recomputes the
785
		 * index in reparenting scenarios.
786
		 * 
787
		 * @param notifier the notifier from which an object was removed
788
		 * @param feature the containment feature from which an object was removed
789
		 * @param object an object removed from the logical content tree
790
		 */
791
		private void removeFromResourceIndex(Object notifier, Object feature, Object object) {
792
			if (object instanceof EObject) {
793
				EObject eObject = (EObject) object;
794
				EObject parent = null;
795
				EReference containment = null;
796
				
797
				if (notifier instanceof EObject) {
798
					parent = (EObject) notifier;
799
					containment = (EReference) feature;
800
				} // else the notifier is a resource, so the parent is null
801
				 
802
				// is this a separate element that we are being removed from?  If so,
803
				//    then we need to update the resource map for it
804
				LogicalResourceUnit subunit =
805
					(LogicalResourceUnit) getResourceMap().get(eObject);
806
				
807
				if ((subunit != null) && !subunit.isRoot()) {
808
					subunit.getContents().remove(eObject);
809
					
810
					// the adapter will afterwards find the new unit and dirty it
811
					subunit.setDirty();
812
					
813
					removeMappedResource(eObject);
814
					
815
					LogicalResourceUnit parentUnit = getUnit(parent);
816
					
817
					if (parentUnit != null) {
818
						parentUnit.setDirty();
819
						updateChildPositions(parentUnit, parent, containment);
820
					}
821
				}
822
			}
823
		}
824
		
825
		/**
826
		 * Updates the resource index metadata when an element is moved within
827
		 * a containment collection.  This recomputes the child position.
828
		 * 
829
		 * @param object an object moved in a containment collection
830
		 * @param position the new child position
831
		 */
832
		private void updateResourceIndex(Object object, int position) {
833
			if (object instanceof EObject) {
834
				EObject eObject = (EObject) object;
835
					
836
				// is this a separate element that we are being added to?  If so,
837
				//    then we need to update the resource map for it
838
				LogicalResourceUnit subunit =
839
					(LogicalResourceUnit) getResourceMap().get(eObject);
840
				
841
				if ((subunit != null) && !subunit.isRoot()) {
842
					LogicalResourceUnit parentUnit = getUnit(eObject.eContainer());
843
					ResourceEntry entry = parentUnit.getResourceIndex().getResourceEntry(
844
						eObject);
845
					
846
					if (entry != null) {
847
						entry.setChildPosition(position);
848
					}
849
				}
850
			}
851
		}
852
		
853
		/**
854
		 * Updates the positions in the physical resource map of the separate
855
		 * children in a containment reference in which an element has been
856
		 * added or removed.
857
		 * 
858
		 * @param unit the unit that owns <code>parent</code> element
859
		 * @param parent an element that had a child added or removed
860
		 * @param containment the containment reference
861
		 */
862
		private void updateChildPositions(
863
				LogicalResourceUnit unit,
864
				EObject parent,
865
				EReference containment) {
866
			
867
			if (unit != null) {
868
				// must update the positions of all other separate
869
				//    elements in the same container and feature, because
870
				//    they have been moved (though no MOVE event occurs)
871
				ResourceMap index = unit.getResourceIndex();
872
				if (index != null) {
873
					ParentEntry entry = index.getParentEntry(
874
						parent,
875
						containment);
876
					
877
					if (entry != null) {
878
						LogicalResourceUtil.updateChildPositions(unit, entry);
879
					}
880
				}
881
			}
882
		}
883
		
884
		final boolean isEnabled() {
885
			return enabled;
886
		}
887
		
888
		void enable() {
889
			enabled = true;
890
		}
891
		
892
		void disable() {
893
			enabled = false;
894
		}
895
	}
896
	
897
	/**
898
	 * Special resource set implementation to manage the physical resources
899
	 * comprising a logical resource.  This resource set delegates several
900
	 * features to the logical resource's containing resource set:
901
	 * <ul>
902
	 *   <li>URI converter:  to get the uri mappings (such as pathmaps)</li>
903
	 *   <li>load options:  for consistent deserialization characteristics</li>
904
	 *   <li>package registry:  for consistent resolution of demand-loaded
905
	 *       packages (such as for XML namespaces)</li>
906
	 *   <li>resource factory registry:  just in case, though a sub-unit
907
	 *       resource set will always create resources of the same actual type
908
	 *       as the logical resource</li>
909
	 * </ul>
910
	 *
911
	 * @author Christian W. Damus (cdamus)
912
	 */
913
	private class SubunitResourceSet extends ResourceSetImpl {
914
		private Map options;
915
		
916
		SubunitResourceSet() {
917
			super();
918
		}
919
		
920
		public URIConverter getURIConverter() {
921
			// we need to use the same URI converter as the logical resource's
922
			//    resource set in order to access path maps
923
			return LogicalResource.this.getURIConverter();
924
		}
925
		
926
		public Map getLoadOptions() {
927
			if (options == null) {
928
				options = new java.util.HashMap();
929
				
930
				// get default load options from the outer resource set
931
				ResourceSet rset = LogicalResource.this.getResourceSet();
932
				
933
				if (rset != null) {
934
					options.putAll(rset.getLoadOptions());
935
				} else {
936
					options.putAll(MResourceFactory.getDefaultLoadOptions());
937
				}
938
			}
939
			
940
			return options;
941
		}
942
		
943
		void clearLoadOptions() {
944
			options = null;
945
		}
946
		
947
		public EPackage.Registry getPackageRegistry() {
948
			EPackage.Registry result;
949
			
950
			// delegate package registry to the outer resource set
951
			ResourceSet rset = LogicalResource.this.getResourceSet();
952
			
953
			if (rset != null) {
954
				result = rset.getPackageRegistry();
955
			} else {
956
				result = super.getPackageRegistry();
957
			}
958
			
959
			return result;
960
		}
961
		
962
		public Resource.Factory.Registry getResourceFactoryRegistry() {
963
			Resource.Factory.Registry result;
964
			
965
			// delegate resource factory registry to the outer resource set
966
			ResourceSet rset = LogicalResource.this.getResourceSet();
967
			
968
			if (rset != null) {
969
				result = rset.getResourceFactoryRegistry();
970
			} else {
971
				result = Resource.Factory.Registry.INSTANCE;
972
			}
973
			
974
			return result;
975
		}
976
		
977
		protected void demandLoad(Resource resource)
978
			throws IOException {
979
			
980
			if (resource instanceof LogicalResourceUnit) {
981
				// we always want to load sub-units using the method that
982
				//   correctly links their roots into the content tree (where
983
				//   the parent unit is already loaded)
984
				LogicalResourceUtil.loadUnit((LogicalResourceUnit) resource);
985
			} else {
986
				// shouldn't happen, but just in case ...
987
				super.demandLoad(resource);
988
			}
989
		}
990
		
991
		public Resource createResource(URI newUri) {
992
			LogicalResourceUnit result = createUnit(newUri);
993
			
994
			getResources().add(result);
995
			
996
			return result;
997
		}
998
	}
999
	
1000
	/**
1001
	 * Contents list for the logical resource.  This list does have an inverse,
1002
	 * according to the usual EMF resource contents.  Thus, the contents of
1003
	 * a logical resource really do consider the logical resource to be their
1004
	 * ultimate container.
1005
	 *
1006
	 * @author Christian W. Damus (cdamus)
1007
	 */
1008
	private class LogicalContentsList extends ContentsEList {
1009
		private static final long serialVersionUID = 1L;
1010
		
1011
		protected void didAdd(int index, Object object) {
1012
			super.didAdd(index, object);
1013
			didAddImpl(index, object);
1014
		}
1015
		
1016
		private void didAddImpl(int index, Object object) {
1017
			if (!getResourceMap().containsKey(object)) {
1018
				// do not put a separate logical root into the root unit
1019
				
1020
				LogicalResourceUnit phys = getRootUnit();
1021
				EList actualRoots = phys.getContents();
1022
				
1023
				if (!phys.getContents().contains(object)) {
1024
					int offset = 1 + actualRoots.indexOf(
1025
						phys.getResourceIndex());
1026
					
1027
					phys.getContents().add(offset + index, object);
1028
				}
1029
			}
1030
		}
1031
		
1032
		protected void didRemove(int index, Object object) {
1033
			super.didRemove(index, object);
1034
			didRemoveImpl(index, object);
1035
		}
1036
		
1037
		private void didRemoveImpl(int index, Object object) {
1038
			getRootUnit().getContents().remove(object);
1039
		}
1040
		
1041
		protected void didSet(int index, Object newObject, Object oldObject) {
1042
			super.didSet(index, newObject, oldObject);
1043
			didRemoveImpl(index, oldObject);
1044
			didAddImpl(index, newObject);
1045
		}
1046
	}
1047
}
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resources/LogicalResourceWrapper.java (-56 / +5 lines)
Lines 13-30 Link Here
13
package org.eclipse.gmf.runtime.emf.core.internal.resources;
13
package org.eclipse.gmf.runtime.emf.core.internal.resources;
14
14
15
import java.io.IOException;
15
import java.io.IOException;
16
import java.util.Collection;
17
import java.util.Collections;
16
import java.util.Collections;
18
import java.util.Iterator;
19
import java.util.Map;
17
import java.util.Map;
20
18
21
import org.eclipse.core.runtime.Platform;
19
import org.eclipse.core.runtime.Platform;
22
import org.eclipse.emf.common.notify.Notification;
23
import org.eclipse.emf.common.notify.impl.AdapterImpl;
24
import org.eclipse.emf.common.util.URI;
20
import org.eclipse.emf.common.util.URI;
25
import org.eclipse.emf.ecore.EObject;
21
import org.eclipse.emf.ecore.EObject;
26
import org.eclipse.emf.ecore.resource.Resource;
22
import org.eclipse.emf.ecore.resource.Resource;
27
28
import org.eclipse.gmf.runtime.emf.core.resources.ILogicalResource;
23
import org.eclipse.gmf.runtime.emf.core.resources.ILogicalResource;
29
24
30
25
Lines 35-40 Link Here
35
 * @author Christian W. Damus (cdamus)
30
 * @author Christian W. Damus (cdamus)
36
 * 
31
 * 
37
 * @see #canSeparate(EObject)
32
 * @see #canSeparate(EObject)
33
 * 
34
 * @deprecated Use the cross-resource containment support provided by EMF,
35
 *     instead, by defining containment features that are capable of storing
36
 *     proxies.
38
 */
37
 */
39
public class LogicalResourceWrapper
38
public class LogicalResourceWrapper
40
	extends AbstractResourceWrapper
39
	extends AbstractResourceWrapper
Lines 45-52 Link Here
45
			return new LogicalResourceWrapper(resource);
44
			return new LogicalResourceWrapper(resource);
46
		}};
45
		}};
47
	
46
	
48
	private Map resourceMap;
49
	
50
	/**
47
	/**
51
	 * Initializes me with the delegate that I wrap.
48
	 * Initializes me with the delegate that I wrap.
52
	 * 
49
	 * 
Lines 117-171 Link Here
117
	}
114
	}
118
115
119
	public Map getMappedResources() {
116
	public Map getMappedResources() {
120
		if (resourceMap == null) {
117
		return Collections.EMPTY_MAP;
121
			resourceMap = new java.util.HashMap() {
122
				{
123
					eAdapters().add(new AdapterImpl() {
124
						public void notifyChanged(Notification msg) {
125
							if (msg.getFeatureID(null) == RESOURCE__CONTENTS) {
126
								switch (msg.getEventType()) {
127
								case Notification.ADD:
128
									add(msg.getNewValue());
129
									break;
130
								case Notification.ADD_MANY:
131
									addAll((Collection) msg.getNewValue());
132
									break;
133
								case Notification.REMOVE:
134
									remove(msg.getOldValue());
135
									break;
136
								case Notification.REMOVE_MANY:
137
									removeAll((Collection) msg.getOldValue());
138
									break;
139
								case Notification.SET:
140
									remove(msg.getOldValue());
141
									add(msg.getNewValue());
142
								}
143
							}
144
						}});
145
					
146
					addAll(getContents());
147
				}
148
				
149
				void add(Object o) {
150
					put(o, UnmodifiableResourceView.get(getWrappedResource()));
151
				}
152
				
153
				void addAll(Collection c) {
154
					for (Iterator iter = c.iterator(); iter.hasNext();) {
155
						add(iter.next());
156
					}
157
				}
158
				
159
				void removeAll(Collection c) {
160
					for (Iterator iter = c.iterator(); iter.hasNext();) {
161
						remove(c);
162
					}
163
				}};
164
			
165
			resourceMap = Collections.unmodifiableMap(resourceMap);
166
		}
167
		
168
		return resourceMap;
169
	}
118
	}
170
119
171
	public Object getAdapter(Class adapter) {
120
	public Object getAdapter(Class adapter) {
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resources/LogicalResourceUnit.java (-695 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
13
package org.eclipse.gmf.runtime.emf.core.internal.resources;
14
15
import java.io.IOException;
16
import java.io.InputStream;
17
import java.io.OutputStream;
18
import java.util.Iterator;
19
import java.util.List;
20
import java.util.ListIterator;
21
import java.util.Map;
22
23
import org.eclipse.emf.common.notify.Notification;
24
import org.eclipse.emf.common.notify.NotificationChain;
25
import org.eclipse.emf.common.util.BasicEList;
26
import org.eclipse.emf.common.util.EList;
27
import org.eclipse.emf.common.util.URI;
28
import org.eclipse.emf.ecore.EObject;
29
import org.eclipse.emf.ecore.EReference;
30
import org.eclipse.emf.ecore.InternalEObject;
31
import org.eclipse.emf.ecore.resource.Resource;
32
import org.eclipse.emf.ecore.util.EcoreUtil;
33
import org.eclipse.emf.ecore.util.InternalEList;
34
import org.eclipse.emf.ecore.xmi.XMLHelper;
35
import org.eclipse.emf.ecore.xmi.XMLLoad;
36
import org.eclipse.emf.ecore.xmi.XMLSave;
37
import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
38
39
import org.eclipse.gmf.runtime.emf.core.internal.plugin.MSLDebugOptions;
40
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ChildEntry;
41
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry;
42
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry;
43
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap;
44
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapFactory;
45
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage;
46
import org.eclipse.gmf.runtime.emf.core.internal.util.MSLUtil;
47
import org.eclipse.gmf.runtime.emf.core.internal.util.Trace;
48
import org.eclipse.gmf.runtime.emf.core.resources.ILogicalResource;
49
import org.eclipse.gmf.runtime.emf.core.util.EObjectUtil;
50
51
/**
52
 * Implementation of a physical unit of a {@link LogicalResource}.  Units are
53
 * serialized as XMI.  It is recommended (though not required) that subclasses
54
 * of the logical resource provide companion unit classes extending this one.
55
 * See the <code>LogicalResource</code> documentation for details.
56
 * 
57
 * @see LogicalResource
58
 *
59
 * @author Christian W. Damus (cdamus)
60
 */
61
public class LogicalResourceUnit
62
	extends XMIResourceImpl {
63
64
	private final LogicalResource logical;
65
	private boolean dirty = false;
66
	
67
	private boolean autoLoadEnabled = true;
68
	
69
	// this list has no inverse references
70
	private EList roots = new ContentsList();
71
	
72
	private ResourceMap resourceIndex;
73
	
74
	/**
75
	 * Initializes me with as a child of the specified <code>logical</code>
76
	 * resource.
77
	 * 
78
	 * @param uri my URI
79
	 * @param logical my logical resource
80
	 */
81
	protected LogicalResourceUnit(URI uri, LogicalResource logical) {
82
		super(uri);
83
		
84
		this.logical = logical;
85
	}
86
87
	protected boolean useUUIDs() {
88
		return true;
89
	}
90
	
91
	/**
92
	 * Gets the logical resource that owns me.
93
	 * 
94
	 * @return my logical resource
95
	 */
96
	LogicalResource getLogicalResource() {
97
		return logical;
98
	}
99
	
100
	/**
101
	 * Queries whether I am the root unit.
102
	 * 
103
	 * @return whether I am the root unit
104
	 */
105
	boolean isRoot() {
106
		ResourceMap index = getResourceIndex();
107
		
108
		// don't resolve the proxy, because we want to avoid loading this
109
		//    resource if possible (in case of loading as physical)
110
		return (index == null) ||
111
			(index.eGet(ResourceMapPackage.eINSTANCE.getResourceMap_RootMap(), false) == null);
112
	}
113
	
114
	public void doLoad(InputStream inputStream, Map options)
115
		throws IOException {
116
		
117
		try {
118
			disableAutoLoad();
119
			Map idMap = LogicalResourceUtil.getUnloadedElements(this);
120
			
121
			super.doLoad(inputStream, options);
122
			
123
			// must reconcile my roots with any unloaded "proxies" in parent
124
			//   units before loading my sub-units, otherwise I will
125
			//     - try to splice sub-units into the wrong indices in empty
126
			//       collections in the unloaded elements
127
			//     - if the previous worked, I will lose the sub-units when
128
			//       replacing the proxy's collections with my own
129
			LogicalResourceUtil.reconcileUnloadedUnits(this, idMap);
130
			
131
			if (getResourceIndex() != null) {
132
				loadParentUnits(getResourceIndex(), options);
133
				loadSubunits(getResourceIndex(), options);
134
			}
135
		} finally {
136
			// We will finally propagate any errors or warnings to
137
			//  the parent logical resource so that it obeys the regular
138
			//  EMF resource contract by providing all errors and warnings
139
			//  that occurred during a load.
140
			getLogicalResource().getErrors().addAll(getErrors());
141
			getLogicalResource().getWarnings().addAll(getWarnings());
142
			setClean();
143
			enableAutoLoad();
144
		}
145
		
146
		if (Trace.isEnabled(MSLDebugOptions.RESOURCES)) {
147
			URI base = getLogicalResource().getURI();
148
			String relative = getURI().deresolve(base).toString();
149
			
150
			if (relative.length() == 0) {
151
				relative = "(root)"; //$NON-NLS-1$
152
			}
153
			
154
			Trace.trace(
155
				MSLDebugOptions.RESOURCES,
156
				"Loaded unit: " + relative + " of: " + base); //$NON-NLS-1$ //$NON-NLS-2$
157
		}
158
	}
159
	
160
	public void doSave(OutputStream outputStream, Map options)
161
		throws IOException {
162
		
163
		try {
164
			if (isDirty() || (outputStream != null)) {
165
				// don't try to write if I don't need it, unless somebody has
166
				//   already created an output stream, in which case we would
167
				//   erase the contents of our file if we didn't proceed
168
				super.doSave(outputStream, options);
169
				
170
				if (Trace.isEnabled(MSLDebugOptions.RESOURCES)) {
171
					URI base = getLogicalResource().getURI();
172
					String relative = getURI().deresolve(base).toString();
173
					
174
					if (relative.length() == 0) {
175
						relative = "(root)"; //$NON-NLS-1$
176
					}
177
					
178
					Trace.trace(
179
						MSLDebugOptions.RESOURCES,
180
						"Saved unit: " + relative + " of: " + base); //$NON-NLS-1$ //$NON-NLS-2$
181
				}
182
			}
183
		} finally {
184
			setClean();
185
		}
186
	}
187
	
188
	/**
189
	 * Queries whether auto-loading of sub-units is enabled.
190
	 * 
191
	 * @return <code>true</code> if auto-loading of sub-units is enabled;
192
	 *     <code>false</code>, otherwise
193
	 */
194
	boolean isAutoLoadEnabled() {
195
		return autoLoadEnabled && getLogicalResource().isAutoLoadEnabled();
196
	}
197
	
198
	/**
199
	 * Turns off auto-loading of unloaded sub-units.
200
	 */
201
	void disableAutoLoad() {
202
		autoLoadEnabled = false;
203
	}
204
	
205
	/**
206
	 * Turns on auto-loading of unloaded sub-units.  After the resource has
207
	 * finished loading (this distinguishes this flag from the
208
	 * <code>isLoaded</code> state).
209
	 */
210
	void enableAutoLoad() {
211
		autoLoadEnabled = true;
212
	}
213
	
214
	/**
215
	 * If we are loading as a logical resource, ensures that the parent units
216
	 * of my roots are loaded.
217
	 * 
218
	 * @param index my physical resource map
219
	 * @param options my load options
220
	 */
221
	private void loadParentUnits(ResourceMap index, Map options) {
222
		final boolean loadUnits = Boolean.TRUE.equals(
223
			options.get(ILogicalResource.OPTION_LOAD_AS_LOGICAL));
224
		
225
		for (Iterator iter = index.getChildEntries().iterator(); iter.hasNext();) {
226
			ChildEntry childEntry = (ChildEntry) iter.next();
227
			
228
			// be sure to resolve this reference
229
			childEntry.getChildObject();
230
			
231
			if (loadUnits) {
232
				// dereference parent resource map to force parent unit to load,
233
				//    if that load option is enabled
234
				childEntry.getParentMap();
235
			}
236
		}
237
	}
238
	
239
	/**
240
	 * Loads separate elements from sub-units according to the load options.
241
	 * At a minimum, unloaded "proxies" are created that will be filled in
242
	 * later.
243
	 * <p>
244
	 * <b>Note</b> that, as a special case, logical roots that are separate
245
	 * elements are always loaded because we must have all logical roots
246
	 * (at least) accounted for.
247
	 * </p>
248
	 * 
249
	 * @param index my physical resource map
250
	 * @param options my load options
251
	 */
252
	private void loadSubunits(ResourceMap index, Map options) {
253
		final boolean loadUnits = Boolean.TRUE.equals(
254
			options.get(ILogicalResource.OPTION_LOAD_ALL_UNITS));
255
		
256
		for (Iterator iter = index.getParentEntries().iterator(); iter.hasNext();) {
257
			ParentEntry parentEntry = (ParentEntry) iter.next();
258
			
259
			EObject parent = parentEntry.getParentObject();
260
			EReference slot = parentEntry.getChildSlot();
261
			
262
			if ((parent != null) && parent.eIsProxy()) {
263
				// this should not happen, because the parent must be in me
264
				parent = EcoreUtil.resolve(parent, getResourceSet());
265
			}
266
			
267
			for (Iterator iter2 = parentEntry.getResourceEntries().iterator(); iter2.hasNext();) {
268
				ResourceEntry subunit = (ResourceEntry) iter2.next();
269
				
270
				int pos = subunit.getChildPosition();
271
				
272
				EObject child;
273
				if (loadUnits || (parent == null)) {
274
					// may result in proxy if unit not found
275
					child = subunit.getChildObject();
276
				} else {
277
					// just get the proxy without resolving it
278
					child = (EObject) subunit.eGet(
279
						ResourceMapPackage.eINSTANCE.getResourceEntry_ChildObject(),
280
						false);
281
				}
282
				
283
				if (child.eIsProxy()) {
284
					// we may have loaded this unit already, by reaching
285
					//   another of its roots
286
					URI physUri = EcoreUtil.getURI(child).trimFragment();
287
					Resource res = getResourceSet().getResource(
288
						physUri, false);
289
					if (res == null) {
290
						res = getResourceSet().createResource(physUri);
291
					}
292
					subunit.setResource(res);
293
					
294
					if (res.isLoaded()) {
295
						// try to resolve the reference to the sub-unit in the
296
						//   dedicated resource set
297
						child = EcoreUtil.resolve(child, getResourceSet());
298
					} else {
299
						// create a stand-in for the child element
300
						//   but do not load its resource
301
						getLogicalResource().addMappedResource(child, res);
302
						
303
						// grab the object's ID while it is still a proxy
304
						String id = MSLUtil.getProxyID(child);
305
						String name = MSLUtil.getProxyName(child);
306
						
307
						// this object will do nicely for the time being, so
308
						// de-proxyize it now that we know the resource
309
						((InternalEObject) child).eSetProxyURI(null);
310
						addToParent(parent, slot, pos, child);
311
						
312
						// remove the dirty adapter because we don't care about
313
						//    changes in the "proxy" object
314
						getLogicalResource().removeContentAdapters(child);
315
316
						if (id != null) {
317
							setID(child, id);
318
						}
319
						if (name != null) {
320
							EObjectUtil.setName(child, name);
321
						}
322
					}
323
				}
324
				
325
				if (!child.eIsProxy() && (child.eContainer() == null)) {
326
					// we resolved to the root of a sub-unit resource (and
327
					//    didn't create an unloaded element, because it has
328
					//    a container).
329
					// Don't ask for eResource() because the child doesn't
330
					//    know it
331
					LogicalResourceUnit res = getLogicalResource().getUnit(child);
332
					
333
					subunit.setResource(res);
334
					addToParent(parent, slot, pos, child);
335
					
336
					if (res.getContents().get(0) instanceof ResourceMap) {
337
						// load its sub-units, recursively
338
						res.loadSubunits(
339
							(ResourceMap) res.getContents().get(0),
340
							options);
341
					}
342
					
343
					res.setClean();
344
				}
345
			}
346
		}
347
	}
348
	
349
	/**
350
	 * Inserts the specified <code>child</code> object (loaded from a sub-unit)
351
	 * into the correct <code>pos</code>ition in the correct <code>slot</code>
352
	 * of its <code>parent</code> element.
353
	 * 
354
	 * @param parent the parent element to insert the <code>child</code> into,
355
	 *    or <code>null</code> to insert as a logical root
356
	 * @param slot the containment reference to hold the <code>child</code>,
357
	 *    or <code>null</code> to insert into the logical resource contents
358
	 * @param pos the position in the reference, if it is a list
359
	 * @param child the child object to insert into the content tree
360
	 */
361
	private void addToParent(EObject parent, EReference slot, int pos, EObject child) {
362
		LogicalResource res = getLogicalResource();
363
		
364
		try {
365
			if (parent != null) {
366
				parent.eSetDeliver(false);
367
			} else {
368
				res.eSetDeliver(false);
369
			}
370
			child.eSetDeliver(false);
371
			
372
			if (slot == null) {
373
				// this is a logical root element
374
				res.getContents().add(pos, child);
375
			} else if (slot.isMany()) {
376
				EList values = (EList) parent.eGet(slot);
377
				
378
				if (!values.contains(child)) {
379
					values.add(pos, child);
380
				}
381
			} else {
382
				parent.eSet(slot, child);
383
			}
384
		} finally {
385
			child.eSetDeliver(true);
386
			if (parent != null) {
387
				parent.eSetDeliver(true);
388
			} else {
389
				res.eSetDeliver(true);
390
			}
391
			
392
			// manually propagate content adapters because we didn't deliver
393
			//    notifications
394
			res.propagateContentAdapters(child);
395
		}
396
	}
397
	
398
	/**
399
	 * Retrieves the index map of my physical resource structure.  This is
400
	 * either the map that I deserialized when I was loaded, or it is lazily
401
	 * created (only if there are multiple physical resources in the logical
402
	 * resource).  The resource map is an index of the locations in each
403
	 * parent where separate children belong.
404
	 * 
405
	 * @return my physical resource map
406
	 */
407
	ResourceMap getResourceIndex() {
408
		if (resourceIndex == null) {
409
			if (!getContents().isEmpty() && (getContents().get(0) instanceof ResourceMap)) {
410
				resourceIndex = (ResourceMap) getContents().get(0);
411
			} else if (!getLogicalResource().isMonolithic()) { // don't create one for a monolithic resource
412
				resourceIndex = ResourceMapFactory.eINSTANCE.createResourceMap();
413
				getContents().add(0, resourceIndex); // add as first root
414
				ResourceMap rootIndex = getLogicalResource().getRootUnit().getResourceIndex();
415
				if (rootIndex != resourceIndex) {
416
					resourceIndex.setRootMap(rootIndex);
417
				}
418
			}
419
		}
420
		
421
		return resourceIndex;
422
	}
423
	
424
	/**
425
	 * Cleans out of my resource index any separate elements that 
426
	 * are no longer attached to the logical content tree.  Note that we should
427
	 * only do this when we save, because otherwise, some operation might be
428
	 * about to reattach a temporarily detached sub-unit.
429
	 */
430
	void cleanupResourceIndex() {
431
		ResourceMap index = getResourceIndex();
432
		
433
		if (index != null) {
434
			// take this opportunity to hook the index up to its root resource
435
			//   index, if any
436
			ResourceMap rootIndex = getLogicalResource().getRootUnit()
437
				.getResourceIndex();
438
			
439
			if ((rootIndex != null) && (rootIndex != getResourceIndex())) {
440
				index.setRootMap(rootIndex);
441
			}
442
			
443
			// clean up the parent entries
444
			for (Iterator iter = index.getParentEntries().iterator(); iter.hasNext();) {
445
				ParentEntry parentEntry = (ParentEntry) iter.next();
446
				
447
				for (Iterator jter = parentEntry.getResourceEntries().iterator(); jter.hasNext();) {
448
					ResourceEntry subunitEntry = (ResourceEntry) jter.next();
449
					
450
					EObject child = subunitEntry.getChildObject();
451
					if (child.eResource() != getLogicalResource()) {
452
						// child has been disconnected.  Forget about its sub-unit
453
						jter.remove();  // remove the sub-unit resource entry
454
						
455
						LogicalResourceUnit subunit = getLogicalResource().getUnit(child);
456
						if ((subunit != null) && !subunit.isDirty()) {
457
							// ensure that it is cleaned up
458
							subunit.cleanupResourceIndex();
459
						}
460
					}
461
				}
462
				
463
				if (parentEntry.getResourceEntries().isEmpty()) {
464
					iter.remove();  // no need for a parent entry without sub-units
465
				}
466
			}
467
			
468
			// clean up the child entries.  This works in reverse:  we look for
469
			//    roots that have no corresponding child entries, and delete them
470
			if (this != getLogicalResource().getRootUnit()) {
471
				for (Iterator iter = getContents().iterator(); iter.hasNext();) {
472
					EObject next = (EObject) iter.next();
473
					
474
					if (next != index) {
475
						ChildEntry childEntry = index.getChildEntry(next);
476
						
477
						if (childEntry == null) {
478
							// child has been disconnected.  Remove it
479
							iter.remove();
480
						}
481
					}
482
				}
483
			}
484
		}
485
	}
486
	
487
	/**
488
	 * Queries whether I need to be saved.
489
	 * 
490
	 * @return <code>true</code> if I have changes that need to be saved;
491
	 *    <code>false</code>, otherwise
492
	 */
493
	boolean isDirty() {
494
		return dirty && isLoaded();  // unloaded resources cannot be dirty
495
	}
496
	
497
	/**
498
	 * Sets me as needing to be saved.
499
	 */
500
	void setDirty() {
501
		super.setModified(true); // do not propagate to logical resource
502
		dirty = true;
503
	}
504
	
505
	/**
506
	 * Sets me as not needing to be saved; I have no pending changes.
507
	 */
508
	void setClean() {
509
		super.setModified(false); // do not propagate to logical resource
510
		dirty = false;
511
	}
512
	
513
	/**
514
	 * Ensures that I know (and that adapters listening know) that I am loaded.
515
	 */
516
	void loaded() {
517
		if (!isLoaded()) {
518
			Notification notification = setLoaded(true);
519
			if (notification != null) {
520
				eNotify(notification);
521
			}
522
		}
523
	}
524
	
525
	public void setModified(boolean isModified) {
526
		super.setModified(isModified);
527
		
528
		if (isModified && getLogicalResource().isTrackingModification()) {
529
			// propagate modified state to the root
530
			getLogicalResource().setModified(isModified);
531
		}
532
	}
533
	
534
	protected XMLHelper createXMLHelper() {
535
		return new LogicalHelper(this);
536
	}
537
	
538
	protected XMLLoad createXMLLoad() {
539
		return new LogicalLoad(createXMLHelper());
540
	}
541
	
542
	protected XMLSave createXMLSave() {
543
		return new LogicalSave(createXMLHelper());
544
	}
545
	
546
	public EObject getEObject(String uriFragment) {
547
		return getLogicalResource().getEObject(uriFragment);
548
	}
549
	
550
	public String getID(EObject eObject) {
551
		return getLogicalResource().getID(eObject);
552
	}
553
	
554
	public void setID(EObject eObject, String id) {
555
		getLogicalResource().setID(eObject, id);
556
	}
557
	
558
	public String getEncoding() {
559
		return getLogicalResource().getEncoding();
560
	}
561
	
562
	public Map getIDToEObjectMap() {
563
		return getLogicalResource().getIDToEObjectMap();
564
	}
565
	
566
	public Map getEObjectToIDMap() {
567
		return getLogicalResource().getEObjectToIDMap();
568
	}
569
	
570
	public EList getContents() {
571
		return roots;
572
	}
573
	
574
	/**
575
	 * <p>
576
	 * A contents list for the physical resources in a logical resource.
577
	 * This list does not maintain an inverse relationship:  the roots of a
578
	 * physical resource do not know what physical resource they are in, but
579
	 * only the logical resource.
580
	 * </p><p>
581
	 * This contents list is also responsible for synchronizing the logical
582
	 * resource's {@linkplain LogicalResource#getResourceMap() resource map}.
583
	 * </p>
584
	 *
585
	 * @author Christian W. Damus (cdamus)
586
	 */
587
	private class ContentsList extends BasicEList implements InternalEList {
588
		private static final long serialVersionUID = 1L;
589
		
590
		protected boolean isUnique() {
591
			return true;
592
		}
593
		
594
		protected void didAdd(int index, Object object) {
595
			super.didAdd(index, object);
596
			didAddImpl(index, object);
597
		}
598
599
		private void didAddImpl(int index, Object object) {
600
			loaded();  // ensure that we know that we're loaded
601
			
602
			if (object instanceof ResourceMap) {
603
				InternalEObject eObject = (InternalEObject) object;
604
				
605
				// the resource map is properly contained by me
606
				eObject.eSetResource(LogicalResourceUnit.this, null);
607
				attached(eObject);
608
			} else {
609
				EObject eObject = (EObject) object;
610
				
611
				getLogicalResource().addMappedResource(
612
					eObject,
613
					LogicalResourceUnit.this);
614
				
615
				// don't create sub-unit entries in the root unit, and
616
				//   also don't do it while we are deserializing ourselves
617
				if (!isRoot() && isAutoLoadEnabled()) {
618
					EObject parent = eObject.eContainer();
619
					
620
					LogicalResourceUnit parentUnit =
621
						getLogicalResource().getUnit(parent);
622
					
623
					LogicalResourceUtil.createSubunitEntry(
624
						eObject, parentUnit, LogicalResourceUnit.this);
625
				} else if (isRoot() && !getLogicalResource().getContents().contains(eObject)) {
626
					// this is a logical root element.  Add it
627
					getLogicalResource().getContents().add(eObject);
628
				}
629
			}
630
		}
631
		
632
		protected void didRemove(int index, Object object) {
633
			super.didRemove(index, object);
634
			didRemoveImpl(index, object);
635
		}
636
		
637
		private void didRemoveImpl(int index, Object object) {
638
			if (object instanceof ResourceMap) {
639
				InternalEObject eObject = (InternalEObject) object;
640
				
641
				// the resource map was properly contained by me
642
				eObject.eSetResource(null, null);
643
				detached(eObject);
644
			} else {
645
				EObject eObject = (EObject) object;
646
				
647
				getLogicalResource().removeMappedResource(eObject);
648
				
649
				// don't remove child entries in the root unit, and
650
				//   also don't do it while we are deserializing ourselves
651
				if (!isRoot() && isAutoLoadEnabled()) {
652
					LogicalResourceUtil.removeChildEntry(
653
						LogicalResourceUnit.this,
654
						eObject);
655
				}
656
			}
657
		}
658
		
659
		protected void didSet(int index, Object newObject, Object oldObject) {
660
			super.didSet(index, newObject, oldObject);
661
			didRemoveImpl(index, oldObject);
662
			didAddImpl(index, newObject);
663
		}
664
665
		//
666
		// Delegate the internal interface to the inherited implementations.
667
		//
668
		
669
		public NotificationChain basicRemove(Object object, NotificationChain notifications) {
670
			remove(object);
671
			return notifications;
672
		}
673
674
		public NotificationChain basicAdd(Object object, NotificationChain notifications) {
675
			add(object);
676
			return notifications;
677
		}
678
		
679
		public List basicList() {
680
			return super.basicList();
681
		}
682
		
683
		public Iterator basicIterator() {
684
			return super.basicIterator();
685
		}
686
		
687
		public ListIterator basicListIterator() {
688
			return super.basicListIterator();
689
		}
690
		
691
		public ListIterator basicListIterator(int index) {
692
			return super.basicListIterator(index);
693
		}
694
	}
695
}
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resources/UnmodifiableResourceView.java (-203 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
13
package org.eclipse.gmf.runtime.emf.core.internal.resources;
14
15
import java.io.IOException;
16
import java.io.InputStream;
17
import java.io.OutputStream;
18
import java.util.Map;
19
20
import org.eclipse.emf.common.util.BasicEList;
21
import org.eclipse.emf.common.util.ECollections;
22
import org.eclipse.emf.common.util.EList;
23
import org.eclipse.emf.common.util.TreeIterator;
24
import org.eclipse.emf.common.util.URI;
25
import org.eclipse.emf.ecore.resource.Resource;
26
import org.eclipse.emf.ecore.resource.ResourceSet;
27
import org.eclipse.emf.ecore.util.EcoreUtil;
28
29
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap;
30
31
32
/**
33
 * An unmodifiable view of a resource, used for presenting sub-units safely
34
 * to clients of the logical resource API.  This class maintains a canonical
35
 * mapping of unmodifiable views to resources, accessed by the
36
 * {@link #get(Resource)} method.
37
 *
38
 * @author Christian W. Damus (cdamus)
39
 */
40
public class UnmodifiableResourceView
41
	extends AbstractResourceWrapper
42
	implements Resource {
43
44
	private static final CanonicalMap instances = new CanonicalMap() {
45
		protected AbstractResourceWrapper createWrapper(Resource resource) {
46
			return new UnmodifiableResourceView(resource);
47
		}};
48
	
49
	/**
50
	 * Initializes me with the resource that I wrap.
51
	 * 
52
	 * @param resource the wrapped resource
53
	 */
54
	private UnmodifiableResourceView(Resource resource) {
55
		super(resource);
56
	}
57
	
58
	/**
59
	 * Gets the canonical unmodifiable view of the specified
60
	 * <code>resource</code>.  Note that, if the <code>resource</code>
61
	 * argument is already an unmodifiable resource, then it is returned as is.
62
	 * 
63
	 * @param resource the resource to get an unmodifiable view of
64
	 * @return its unmodifiable view
65
	 */
66
	public static Resource get(Resource resource) {
67
		Resource result = null;
68
		
69
		if (resource instanceof UnmodifiableResourceView) {
70
			result = resource;
71
		} else {
72
			result = instances.get(resource);
73
		}
74
		
75
		return result;
76
	}
77
	
78
	/**
79
	 * No access to the resource set is provided.
80
	 * 
81
	 * @return <code>null</code>, always
82
	 */
83
	public ResourceSet getResourceSet() {
84
		return null;
85
	}
86
87
	/**
88
	 * Not allowed.
89
	 * 
90
	 * @throws UnsupportedOperationException, always
91
	 */
92
	public void setURI(URI uri) {
93
		throw new UnsupportedOperationException("setURI(URI)"); //$NON-NLS-1$
94
	}
95
96
	/**
97
	 * Returns an unmodifiable view of the wrapped resource's contents, excluding
98
	 * the first root (which is the resource map).
99
	 */
100
	public EList getContents() {
101
		EList contents = super.getContents();
102
		EList result;
103
		
104
		if (!contents.isEmpty() && (contents.get(0) instanceof ResourceMap)) {
105
			// too bad ELists don't support sub-lists as ELists
106
			result = new BasicEList(contents.size() - 1);
107
			ECollections.setEList(result, contents.subList(1, contents.size()));
108
		} else {
109
			result = contents;
110
		}
111
		
112
		return ECollections.unmodifiableEList(result);
113
	}
114
115
	public TreeIterator getAllContents() {
116
		return EcoreUtil.getAllContents(getContents());
117
	}
118
119
	/**
120
	 * Not allowed.
121
	 * 
122
	 * @throws UnsupportedOperationException, always
123
	 */
124
	public void save(Map options)
125
		throws IOException {
126
		throw new UnsupportedOperationException("save(Map)"); //$NON-NLS-1$
127
	}
128
129
	/**
130
	 * Not allowed.
131
	 * 
132
	 * @throws UnsupportedOperationException, always
133
	 */
134
	public void load(Map options)
135
		throws IOException {
136
		throw new UnsupportedOperationException("load(Map)"); //$NON-NLS-1$
137
	}
138
139
	/**
140
	 * Not allowed.
141
	 * 
142
	 * @throws UnsupportedOperationException, always
143
	 */
144
	public void save(OutputStream outputStream, Map options)
145
		throws IOException {
146
		throw new UnsupportedOperationException("save(OutputStream, Map)"); //$NON-NLS-1$
147
	}
148
149
	/**
150
	 * Not allowed.
151
	 * 
152
	 * @throws UnsupportedOperationException, always
153
	 */
154
	public void load(InputStream inputStream, Map options)
155
		throws IOException {
156
		throw new UnsupportedOperationException("load(InputStream, Map)"); //$NON-NLS-1$
157
	}
158
159
	/**
160
	 * Not allowed.
161
	 * 
162
	 * @throws UnsupportedOperationException, always
163
	 */
164
	public void setTrackingModification(boolean isTrackingModification) {
165
		throw new UnsupportedOperationException("setTrackingModification(boolean)"); //$NON-NLS-1$
166
	}
167
168
	/**
169
	 * Not allowed.
170
	 * 
171
	 * @throws UnsupportedOperationException, always
172
	 */
173
	public void setModified(boolean isModified) {
174
		throw new UnsupportedOperationException("setModified(boolean)"); //$NON-NLS-1$
175
	}
176
177
	/**
178
	 * Not allowed.
179
	 * 
180
	 * @throws UnsupportedOperationException, always
181
	 */
182
	public void unload() {
183
		throw new UnsupportedOperationException("unload()"); //$NON-NLS-1$
184
	}
185
186
	/**
187
	 * Returns an unmodifiable view of the wrapped resource's errors.
188
	 */
189
	public EList getErrors() {
190
		return ECollections.unmodifiableEList(super.getErrors());
191
	}
192
193
	/**
194
	 * Returns an unmodifiable view of the wrapped resource's warnings.
195
	 */
196
	public EList getWarnings() {
197
		return ECollections.unmodifiableEList(super.getWarnings());
198
	}
199
	
200
	public String toString() {
201
		return "Unmodifiable(" + getWrappedResource().toString() + ')'; //$NON-NLS-1$
202
	}
203
}
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resources/MSLResourceUnit.java (-82 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2004 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
package org.eclipse.gmf.runtime.emf.core.internal.resources;
13
14
import org.eclipse.emf.common.util.URI;
15
import org.eclipse.emf.ecore.xmi.XMLHelper;
16
import org.eclipse.emf.ecore.xmi.XMLLoad;
17
import org.eclipse.emf.ecore.xmi.XMLSave;
18
19
import org.eclipse.gmf.runtime.emf.core.edit.MEditingDomain;
20
21
/**
22
 * Companion sub-unit class for the MSL resource implementation.
23
 *
24
 * @author Christian W. Damus (cdamus)
25
 */
26
public class MSLResourceUnit
27
	extends LogicalResourceUnit {
28
29
	private MSLResource logicalMslResource;
30
	
31
	/**
32
	 * Initializes me.
33
	 */
34
	public MSLResourceUnit(URI uri, LogicalResource logicalResource) {
35
		super(MEditingDomain.INSTANCE.convertURI(uri), logicalResource);
36
		
37
		logicalMslResource = (MSLResource) logicalResource;
38
	}
39
40
	protected boolean useIDAttributes() {
41
		return logicalMslResource.useIDAttributes();
42
	}
43
44
	protected boolean useUUIDs() {
45
		return logicalMslResource.useUUIDs();
46
	}
47
48
	protected XMLHelper createXMLHelper() {
49
		return new MSLHelper(this);
50
	}
51
52
	protected XMLLoad createXMLLoad() {
53
		return new MSLLoad(createXMLHelper());
54
	}
55
56
	protected XMLSave createXMLSave() {
57
		return new MSLSave(createXMLHelper());
58
	}
59
60
	public void setURI(URI uri) {
61
62
		MEditingDomain domain = MEditingDomain.getEditingDomain(this);
63
64
		if (domain == null)
65
			domain = MEditingDomain.INSTANCE;
66
67
		setRawURI(domain.convertURI(uri));
68
	}
69
70
	/**
71
	 * Set the URI of the resource without processing it.
72
	 */
73
	public void setRawURI(URI uri) {
74
75
		URI oldURI = getURI();
76
77
		if ((uri == oldURI) || ((uri != null) && (uri.equals(oldURI))))
78
			return;
79
80
		super.setURI(uri);
81
	}
82
}
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resources/MSLLoad.java (-2 / +3 lines)
Lines 20-25 Link Here
20
import org.eclipse.emf.ecore.xmi.XMLHelper;
20
import org.eclipse.emf.ecore.xmi.XMLHelper;
21
import org.eclipse.emf.ecore.xmi.XMLResource;
21
import org.eclipse.emf.ecore.xmi.XMLResource;
22
import org.eclipse.emf.ecore.xmi.impl.SAXWrapper;
22
import org.eclipse.emf.ecore.xmi.impl.SAXWrapper;
23
import org.eclipse.emf.ecore.xmi.impl.XMILoadImpl;
23
import org.xml.sax.helpers.DefaultHandler;
24
import org.xml.sax.helpers.DefaultHandler;
24
25
25
/**
26
/**
Lines 29-35 Link Here
29
 * @author rafikj
30
 * @author rafikj
30
 */
31
 */
31
public class MSLLoad
32
public class MSLLoad
32
	extends LogicalLoad {
33
	extends XMILoadImpl {
33
34
34
	/**
35
	/**
35
	 * Constructor.
36
	 * Constructor.
Lines 60-65 Link Here
60
	 * @see org.eclipse.emf.ecore.xmi.impl.XMLLoadImpl#makeDefaultHandler()
61
	 * @see org.eclipse.emf.ecore.xmi.impl.XMLLoadImpl#makeDefaultHandler()
61
	 */
62
	 */
62
	protected DefaultHandler makeDefaultHandler() {
63
	protected DefaultHandler makeDefaultHandler() {
63
		return new SAXWrapper(new MSLHandler((MSLResourceUnit) resource, helper, options));
64
		return new SAXWrapper(new MSLHandler(resource, helper, options));
64
	}
65
	}
65
}
66
}
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resources/MSLResource.java (-4 / +74 lines)
Lines 11-24 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 java.io.IOException;
15
import java.util.Collections;
16
import java.util.Map;
17
18
import org.eclipse.core.runtime.Platform;
14
import org.eclipse.emf.common.notify.Adapter;
19
import org.eclipse.emf.common.notify.Adapter;
15
import org.eclipse.emf.common.notify.Notification;
20
import org.eclipse.emf.common.notify.Notification;
16
import org.eclipse.emf.common.util.URI;
21
import org.eclipse.emf.common.util.URI;
17
import org.eclipse.emf.ecore.EObject;
22
import org.eclipse.emf.ecore.EObject;
18
import org.eclipse.emf.ecore.EStructuralFeature;
23
import org.eclipse.emf.ecore.EStructuralFeature;
19
24
import org.eclipse.emf.ecore.xmi.XMLHelper;
25
import org.eclipse.emf.ecore.xmi.XMLLoad;
26
import org.eclipse.emf.ecore.xmi.XMLSave;
27
import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
20
import org.eclipse.gmf.runtime.emf.core.edit.MEditingDomain;
28
import org.eclipse.gmf.runtime.emf.core.edit.MEditingDomain;
21
import org.eclipse.gmf.runtime.emf.core.internal.util.MSLConstants;
29
import org.eclipse.gmf.runtime.emf.core.internal.util.MSLConstants;
30
import org.eclipse.gmf.runtime.emf.core.resources.ILogicalResource;
22
31
23
/**
32
/**
24
 * Custom implementation of an XMIResource.
33
 * Custom implementation of an XMIResource.
Lines 26-32 Link Here
26
 * @author rafikj
35
 * @author rafikj
27
 */
36
 */
28
public class MSLResource
37
public class MSLResource
29
	extends LogicalResource {
38
	extends XMIResourceImpl
39
	implements ILogicalResource {
30
40
31
	private boolean useIDAttributes = false;
41
	private boolean useIDAttributes = false;
32
	
42
	
Lines 40-47 Link Here
40
		setTrackingModification(true);
50
		setTrackingModification(true);
41
	}
51
	}
42
52
43
	protected LogicalResourceUnit createUnit(URI unitUri) {
53
	protected boolean useUUIDs() {
44
		return new MSLResourceUnit(unitUri, this);
54
		return true;
45
	}
55
	}
46
	
56
	
47
	/**
57
	/**
Lines 58-63 Link Here
58
		return useIDAttributes;
68
		return useIDAttributes;
59
	}
69
	}
60
70
71
	protected XMLHelper createXMLHelper() {
72
		return new MSLHelper(this);
73
	}
74
75
	protected XMLLoad createXMLLoad() {
76
		return new MSLLoad(createXMLHelper());
77
	}
78
79
	protected XMLSave createXMLSave() {
80
		return new MSLSave(createXMLHelper());
81
	}
82
61
	/**
83
	/**
62
	 * @see org.eclipse.emf.ecore.resource.Resource#getEObject(java.lang.String)
84
	 * @see org.eclipse.emf.ecore.resource.Resource#getEObject(java.lang.String)
63
	 */
85
	 */
Lines 163-166 Link Here
163
				return false;
185
				return false;
164
			}};
186
			}};
165
	}
187
	}
188
189
	//
190
	// ILogicalResource methods
191
	//
192
	
193
	/**
194
	 * I cannot separate any elements.
195
	 * 
196
	 * @return <code>false</code>, always
197
	 */
198
	public boolean canSeparate(EObject eObject) {
199
		return false;
200
	}
201
202
	/**
203
	 * I cannot separate any elements.
204
	 * 
205
	 * @return <code>false</code>, always
206
	 */
207
	public boolean isSeparate(EObject eObject) {
208
		return false;
209
	}
210
211
	public void separate(EObject eObject, URI uri) {
212
		throw new IllegalArgumentException("cannot separate eObject"); //$NON-NLS-1$
213
	}
214
215
	public void absorb(EObject eObject) {
216
		throw new IllegalArgumentException("eObject is not separate"); //$NON-NLS-1$
217
	}
218
	
219
	public boolean isLoaded(EObject eObject) {
220
		return true;  // no object in a non-logical-resource can be unloaded
221
	}
222
	
223
	public void load(EObject eObject)
224
		throws IOException {
225
		
226
		throw new IllegalArgumentException("eObject is not separate"); //$NON-NLS-1$
227
	}
228
229
	public Map getMappedResources() {
230
		return Collections.EMPTY_MAP;
231
	}
232
233
	public Object getAdapter(Class adapter) {
234
		return Platform.getAdapterManager().getAdapter(this, adapter);
235
	}
166
}
236
}
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resources/LogicalHandler.java (-90 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2004 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
package org.eclipse.gmf.runtime.emf.core.internal.resources;
13
14
import java.util.Map;
15
16
import org.eclipse.emf.ecore.EFactory;
17
import org.eclipse.emf.ecore.EObject;
18
import org.eclipse.emf.ecore.xmi.XMLHelper;
19
import org.eclipse.emf.ecore.xmi.impl.SAXXMIHandler;
20
21
import org.eclipse.gmf.runtime.emf.core.resources.ILogicalResource;
22
23
/**
24
 * The SAX handler for logical resources.  Ensures that XML namespace EPackages
25
 * are loaded in the same resource set as the logical resource, rather than in
26
 * the logical resource's internal resource set (for the physical resources).
27
 * 
28
 * @author Christian W. Damus (cdamus)
29
 */
30
public class LogicalHandler
31
	extends SAXXMIHandler {
32
	
33
	boolean isAutoLoading;
34
	
35
	/**
36
	 * Initializes me.
37
	 * 
38
	 * @param resource the logical resource that I am handling
39
	 * @param helper the <code>resource</code>'s helper
40
	 * @param options the load options
41
	 */
42
	public LogicalHandler(LogicalResourceUnit resource, XMLHelper helper, Map options) {
43
		
44
		super(resource, helper, options);
45
		
46
		// use the logical resource's resource set for finding and
47
		//    loading EPackages (for XML namespaces)
48
		resourceSet = resource.getLogicalResource().getResourceSet();
49
		
50
		isAutoLoading =
51
			Boolean.FALSE.equals(
52
				options.get(ILogicalResource.OPTION_LOAD_ALL_UNITS))
53
			&&
54
			Boolean.TRUE.equals(
55
				options.get(ILogicalResource.OPTION_AUTO_LOAD_UNITS));
56
	}
57
58
	protected EFactory getFactoryForPrefix(String prefix) {
59
		EFactory factory = (EFactory) prefixesToFactories.get(prefix);
60
		
61
		if (factory == null) {
62
			factory = super.getFactoryForPrefix(prefix);
63
			
64
			if (isAutoLoading && (factory != null)) {
65
				// substitute with our alternative
66
				EFactory alt = LogicalResourcePolicyManager.getInstance().getEFactory(
67
					factory.getEPackage());
68
				if ((alt != null) && (alt != factory)) {
69
					prefixesToFactories.put(prefix, alt);
70
					factory = alt;
71
				}
72
			}
73
		}
74
75
		return factory;
76
	}
77
	
78
	protected EObject createObjectFromFactory(EFactory factory, String typeName) {
79
		if (isAutoLoading && (factory != null)) {
80
			EFactory alt = LogicalResourcePolicyManager.getInstance().getEFactory(
81
				factory.getEPackage());
82
			
83
			if ((alt != null) && (alt != factory)) {
84
				factory = alt;
85
			}
86
		}
87
		
88
		return super.createObjectFromFactory(factory, typeName);
89
	}
90
}
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resources/LogicalSave.java (-125 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
13
package org.eclipse.gmf.runtime.emf.core.internal.resources;
14
15
import java.util.Iterator;
16
17
import org.eclipse.emf.ecore.EObject;
18
import org.eclipse.emf.ecore.EStructuralFeature;
19
import org.eclipse.emf.ecore.resource.Resource;
20
import org.eclipse.emf.ecore.util.InternalEList;
21
import org.eclipse.emf.ecore.xmi.XMLHelper;
22
import org.eclipse.emf.ecore.xmi.impl.XMISaveImpl;
23
import org.eclipse.emf.ecore.xml.type.AnyType;
24
25
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap;
26
27
/**
28
 * Customization of the XML serialization (saving) for logical resources.
29
 * Special requirements for logical resources include:
30
 * <ul>
31
 *   <li>the determination of what is a cross-doc and what is a same-doc
32
 *       reference is based on the physical URI rather than the logical URI</li>
33
 *   <li>elements in the content tree that are stored in other resources are
34
 *       skipped (not saved in this resource)</li>
35
 * </ul>
36
 *
37
 * @author Christian W. Damus (cdamus)
38
 */
39
public class LogicalSave
40
	extends XMISaveImpl {
41
42
	private LogicalHelper logicalHelper;
43
	private LogicalResource logicalResource;
44
	private boolean savingResourceMap = false;
45
	
46
	public LogicalSave(XMLHelper helper) {
47
		super(helper);
48
		
49
		if (helper instanceof LogicalHelper) {
50
			logicalHelper = (LogicalHelper) helper;
51
			logicalResource = logicalHelper.getLogicalResource();
52
		}
53
	}
54
55
	protected void saveElementID(EObject o) {
56
		if (o instanceof ResourceMap && logicalHelper != null) {
57
			// writing the sub-unit map.  It needs to encode child references
58
			//    using physical URIs.  The rest of the resource
59
			//    needs to encode intra-logical-model references as relative
60
			//    to the root resource URI
61
			savingResourceMap = true;
62
			logicalHelper.setUrisRelativeToRoot(false);
63
			super.saveElementID(o);
64
			logicalHelper.setUrisRelativeToRoot(true);
65
			savingResourceMap = false;
66
		} else {
67
			super.saveElementID(o);
68
		}
69
	}
70
71
	protected void saveElement(EObject o, EStructuralFeature f) {
72
		// if we're saving an AnyType, then it is coming from the extended
73
		//    data (compatibility mode), so we cannot check for separateness
74
		//    (which it wouldn't be, anyway)
75
		if (savingResourceMap || logicalResource == null ||
76
				(o instanceof AnyType) || !logicalResource.isSeparate(o)) {
77
			super.saveElement(o, f);
78
		}
79
	}
80
	
81
	protected int sameDocSingle(EObject o, EStructuralFeature f) {
82
	    EObject value = (EObject) helper.getValue(o, f);
83
		if (value == null) {
84
			return SKIP;
85
		} else if (value.eIsProxy()) {
86
			return CROSS_DOC;
87
		} else {
88
			return isSameDocument(o, value) ? SAME_DOC : CROSS_DOC;
89
		}
90
	}
91
	
92
	private boolean isSameDocument(EObject source, EObject target) {
93
		boolean result = false;
94
		
95
	      Resource targetRes = target.eResource();
96
	      if (targetRes instanceof LogicalResource && logicalHelper != null) {
97
	    	  // can only have same-doc ref if both resources are logical
98
	    	  LogicalResourceUnit sourceRes = logicalHelper.getUnit();
99
		      
100
		      result = sourceRes == ((LogicalResource) targetRes).getUnit(target);
101
	      } else {
102
	    	  result = targetRes == helper.getResource();
103
	      }
104
		
105
		return result;
106
	}
107
	
108
	protected int sameDocMany(EObject o, EStructuralFeature f) {
109
		InternalEList values = (InternalEList) helper.getValue(o, f);
110
		if (values.isEmpty()) {
111
			return SKIP;
112
		}
113
114
		for (Iterator i = values.basicIterator(); i.hasNext();) {
115
			EObject value = (EObject) i.next();
116
			if (value.eIsProxy()) {
117
				return CROSS_DOC;
118
			} else if (!isSameDocument(o, value)) {
119
				return CROSS_DOC;
120
			}
121
		}
122
123
		return SAME_DOC;
124
	}
125
}
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resources/LogicalResourceUtil.java (-993 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
13
package org.eclipse.gmf.runtime.emf.core.internal.resources;
14
15
import java.io.IOException;
16
import java.io.InputStream;
17
import java.util.Iterator;
18
import java.util.List;
19
import java.util.Map;
20
import java.util.Set;
21
22
import org.eclipse.core.resources.IFile;
23
import org.eclipse.emf.common.notify.Notification;
24
import org.eclipse.emf.common.notify.Notifier;
25
import org.eclipse.emf.common.util.EList;
26
import org.eclipse.emf.common.util.URI;
27
import org.eclipse.emf.ecore.EObject;
28
import org.eclipse.emf.ecore.EReference;
29
import org.eclipse.emf.ecore.EStructuralFeature;
30
import org.eclipse.emf.ecore.InternalEObject;
31
import org.eclipse.emf.ecore.impl.ENotificationImpl;
32
import org.eclipse.emf.ecore.resource.Resource;
33
import org.eclipse.emf.ecore.resource.ResourceSet;
34
import org.eclipse.emf.ecore.util.EcoreUtil;
35
import org.eclipse.gmf.runtime.common.core.util.Log;
36
import org.eclipse.gmf.runtime.emf.core.EventTypes;
37
import org.eclipse.gmf.runtime.emf.core.internal.l10n.EMFCoreMessages;
38
import org.eclipse.gmf.runtime.emf.core.internal.plugin.MSLDebugOptions;
39
import org.eclipse.gmf.runtime.emf.core.internal.plugin.MSLPlugin;
40
import org.eclipse.gmf.runtime.emf.core.internal.plugin.MSLStatusCodes;
41
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ChildEntry;
42
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry;
43
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry;
44
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap;
45
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapFactory;
46
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage;
47
import org.eclipse.gmf.runtime.emf.core.internal.util.Trace;
48
import org.eclipse.gmf.runtime.emf.core.resources.CannotSeparateException;
49
import org.eclipse.gmf.runtime.emf.core.resources.ILogicalResource;
50
import org.eclipse.gmf.runtime.emf.core.util.ResourceUtil;
51
52
/**
53
 * <p>
54
 * Utilities for working with "logical resources."  Logical resources can
55
 * comprise multiple separate resources, primarily for the purpose of
56
 * decomposing files in source control.  Individual physical resources in a
57
 * logical resource can be separately version-controlled to assist a smooth
58
 * team development workflow.
59
 * </p><p>
60
 * When a logical resource is loaded, it automatically loads its constituent
61
 * physical resources and combines them into a single in-memory representation.
62
 * All of the objects in this logical resource are addressed by a single URI.
63
 * </p><p>
64
 * Particular EMF metamodels (<code>EPackage</code>s) can restrict which
65
 * elements are permitted to form the roots of separate resources.  The
66
 * {@link #canSeparate(EObject)} method is used to determine whether an element
67
 * is permitted to root a separate resource.
68
 * </p><p>
69
 * Given an element that may be separated, the {@link #separate(EObject)} method
70
 * will create a separate resource for it if none is defined already.  A
71
 * separate element can be re-incorporated into the resource of its container
72
 * by the {@link #absorb(EObject)} method.  To determine whether an element
73
 * currently is separated, use the {@link #isSeparate(EObject)} method.
74
 * </p>
75
 * 
76
 * @author Christian W. Damus (cdamus)
77
 */
78
public class LogicalResourceUtil {
79
	private LogicalResourceUtil() {
80
		super();
81
	}
82
	
83
	/**
84
	 * Queries whether the specified <code>eObject</code> is the root of a
85
	 * separate resource in a larger logical resource.
86
	 * 
87
	 * @param res the logical resource
88
	 * @param eObject a model element in the logical resource
89
	 * 
90
	 * @return whether it is the root of a separate resource
91
	 */
92
	static boolean isSeparate(LogicalResource res, EObject eObject) {
93
		assert eObject.eResource() == res : "eObject is not in res" ; //$NON-NLS-1$
94
		
95
		LogicalResourceUnit unit = (LogicalResourceUnit) res.getResourceMap().get(eObject);
96
		
97
		return (unit != null) && (unit != res.getRootUnit());
98
	}
99
	
100
	/**
101
	 * Ensures that the specified <code>eObject</code> is the root of a
102
	 * separate resource, if it is {@linkplain #canSeparate(EObject) allowed}
103
	 * to be such.
104
	 * 
105
	 * @param res the logical resource
106
	 * @param eObject a model element
107
	 * @param uri URI for the physical resource to store the
108
	 *    <code>eObject</code> in, or <code>null</code> for the default
109
	 * 
110
	 * @throws CannotSeparateException if something unforeseen goes wrong in
111
	 *     the separation of the element.  This may be failure to make a
112
	 *     version-controlled file writeable, failure to meet metamodel-specific
113
	 *     constraints on separation, etc.
114
	 * 
115
	 * @see #canSeparate(LogicalResource, EObject)
116
	 * @see #absorb(LogicalResource, EObject)
117
	 */
118
	static void separate(LogicalResource res, EObject eObject, URI uri) throws CannotSeparateException {
119
		LogicalResourceUnit oldUnit = getUnitFor(res, eObject);
120
		LogicalResourceUnit newUnit = initializeUnit(res, eObject, uri);
121
		
122
		if (newUnit == oldUnit) {
123
			// not allowed to separate into current storage unit
124
			CannotSeparateException e = new CannotSeparateException(
125
				EMFCoreMessages.separate_sameUnit_ERROR_);
126
			Trace.throwing(LogicalResourceUtil.class, "separate", e); //$NON-NLS-1$
127
			throw e;
128
		}
129
		
130
		if (eObject.eContainer() == null) {
131
			// this was a root of the root unit
132
			oldUnit.getContents().remove(eObject);
133
			
134
			// add back to the map because we just removed it
135
			res.addMappedResource(eObject, oldUnit);
136
		}
137
		newUnit.getContents().add(eObject);
138
		
139
		// ensure that both units are dirty
140
		oldUnit.setDirty();
141
		newUnit.setDirty();
142
		
143
		reparentChildUnits(oldUnit, newUnit, eObject);
144
	}
145
	
146
	/**
147
	 * Ensures that any separate elements in the containment tree of a
148
	 * recently-separated or -absorbed element that reference the element's old
149
	 * unit as their parent now reference the new sub-unit.
150
	 * 
151
	 * @param oldUnit a separated or absorbed <code>element</code>'s old unit
152
	 * @param newUnit a separated or absorbed <code>element</code>'s new unit
153
	 * @param element the recently-separated/absorbed element
154
	 */
155
	private static void reparentChildUnits(
156
			LogicalResourceUnit oldUnit, LogicalResourceUnit newUnit,
157
			EObject element) {
158
		
159
		// must make a defensive copy to protect against concurrent
160
		//   modifications in the absorption case
161
		List parentEntries = new java.util.ArrayList(
162
			oldUnit.getResourceIndex().getParentEntries());
163
		
164
		for (Iterator iter = parentEntries.iterator(); iter.hasNext();) {
165
			ParentEntry next = (ParentEntry) iter.next();
166
			EObject parent = next.getParentObject();
167
			
168
			if (EcoreUtil.isAncestor(element, parent)) {
169
				// this parent is in another unit, now
170
				newUnit.getResourceIndex().getParentEntries().add(next);
171
				
172
				// mark the child resources dirty so that they will save
173
				for (Iterator jter = next.getResourceEntries().iterator(); jter.hasNext();) {
174
					ResourceEntry re = (ResourceEntry) jter.next();
175
					
176
					LogicalResourceUnit child = (LogicalResourceUnit) re.getResource();
177
					
178
					// must load it in order to save it, unless we are in
179
					//    physical mode
180
					if (child.isLoaded() || !isPhysicalMode(child.getLogicalResource())) {
181
						// proxy resolution loads the child resource
182
						EObject childObj = re.getChildObject();
183
						
184
						// point the child unit to its new parent unit
185
						ChildEntry ce = child.getResourceIndex().getChildEntry(childObj);
186
						ce.setParentMap(newUnit.getResourceIndex());
187
						child.setDirty();
188
					}
189
				}
190
			}
191
		}
192
	}
193
	
194
	/**
195
	 * Queries whether the specified logical resource was loaded in physical
196
	 * mode.
197
	 * 
198
	 * @param res the logical resource
199
	 * @return <code>true</code> if it was loaded in physical mode;
200
	 *     <code>false</code>, otherwise
201
	 */
202
	static boolean isPhysicalMode(LogicalResource res) {
203
		return !Boolean.TRUE.equals(
204
			res.getSubunitResourceSet().getLoadOptions().get(
205
				ILogicalResource.OPTION_LOAD_AS_LOGICAL));
206
	}
207
	
208
	/**
209
	 * Queries whether the specified <code>eObject</code> is currently loaded.
210
	 * If it is not loaded, then it is just a stand-in for the absent sub-tree
211
	 * of the logical model.
212
	 * 
213
	 * @param res a logical resource
214
	 * @param eObject an element in the logical resource.  It may be a separate
215
	 *      element (in which case the question of loaded is interesting) or
216
	 *      it may not.  In the latter case, the element is necessarily
217
	 *      to be considered as loaded
218
	 * @return <code>true</code> if the <code>eObject</code> is fully loaded
219
	 *      from its physical resource; <code>false</code>, otherwise
220
	 * 
221
	 * @throws IllegalArgumentException if the <code>eObject</code> is not
222
	 *     contained within me
223
	 *     
224
	 * @see #load(LogicalResource, EObject)
225
	 */
226
	static boolean isLoaded(LogicalResource res, EObject eObject) {
227
		assert eObject.eResource() == res : "eObject is not in res" ; //$NON-NLS-1$
228
		
229
		boolean result;
230
		
231
		if (!isSeparate(res, eObject)) {
232
			result = true;
233
		} else {
234
			LogicalResourceUnit unit = getUnitFor(res, eObject);
235
			result = unit.isLoaded() && unit.getContents().contains(eObject);
236
		}
237
		
238
		return result;
239
	}
240
	
241
	/**
242
	 * Loads the specified eObject from its physical resource.
243
	 * 
244
	 * @param res the logical resource
245
	 * @param eObject a separate element in the logical resource
246
	 * 
247
	 * @throws IllegalArgumentException if the <code>eObject</code> is not
248
	 *     separate or if it is not contained within me
249
	 * @throws IOException if any exception occurs while loading the
250
	 *     <code>eObject</code>'s physical resource
251
	 *     
252
	 * @see #isLoaded(LogicalResource, EObject)
253
	 */
254
	static void load(LogicalResource res, EObject eObject) throws IOException {
255
		LogicalResourceUnit unit = getUnitFor(res, eObject);
256
		
257
		if (!unit.isLoaded()) {
258
			loadUnit(unit);
259
		}
260
	}
261
	
262
	/**
263
	 * Convenience method to load a sub-unit into the logical resource with
264
	 * the correct load options.
265
	 * 
266
	 * @param unit a sub-unit to be loaded
267
	 * @throws IOException if anything goes wrong in loading it
268
	 * 
269
	 * @see #loadUnit(LogicalResourceUnit, InputStream)
270
	 */
271
	static void loadUnit(LogicalResourceUnit unit) throws IOException {
272
		unit.load(unit.getResourceSet().getLoadOptions());
273
	}
274
	
275
	/**
276
	 * Convenience method to load a sub-unit into the logical resource with
277
	 * the correct load options.
278
	 * 
279
	 * @param unit a sub-unit to be loaded
280
	 * @param inputStream the input stream to load the unit from
281
	 * @throws IOException if anything goes wrong in loading it
282
	 */
283
	static void loadUnit(LogicalResourceUnit unit, InputStream inputStream) throws IOException {
284
		unit.load(inputStream, unit.getResourceSet().getLoadOptions());
285
	}
286
	
287
	/**
288
	 * Gets a mapping of objects as yet unloaded in the logical resource
289
	 * that resolve to roots of the specified <code>unit</code>.
290
	 * 
291
	 * @param unit a unit in a logical resource
292
	 * @return map of {@link String} ID ==&gt; unloaded {@link EObject}
293
	 */
294
	static Map getUnloadedElements(LogicalResourceUnit unit) {
295
		LogicalResource logical = unit.getLogicalResource();
296
		Map result = new java.util.HashMap();
297
		
298
		for (Iterator iter = logical.getResourceMap().entrySet().iterator();
299
				iter.hasNext();) {
300
			
301
			Map.Entry entry = (Map.Entry) iter.next();
302
			if (entry.getValue() == unit) {
303
				// this is an element whose ID we need
304
				EObject element = (EObject) entry.getKey();
305
				
306
				result.put(logical.getID(element), element);
307
			}
308
		}
309
		
310
		return result;
311
	}
312
	
313
	/**
314
	 * Reconciles existing unloaded units from the specified map with the roots
315
	 * of the just-loaded <code>unit</code>.  This merges the features of the
316
	 * <code>unit</code>'s roots into existing unloaded elements; this
317
	 * effectively loads these elements.  The original unloaded elements (now
318
	 * loaded) then replace the <code>unit</code>'s existing roots.
319
	 * <p>
320
	 * The ID mapping provided maps IDs of the roots of the <code>unit</code> to
321
	 * the IDs of the unloaded units that match them, to preserve their IDs
322
	 * (because loading the <code>unit</code> replaced the existing IDs in the
323
	 * XML resource's ID-to-element map).
324
	 * </p>
325
	 * 
326
	 * @param unit a logical resource unit that was just loaded
327
	 * @param idMap mapping of 
328
	 */
329
	static void reconcileUnloadedUnits(LogicalResourceUnit unit, Map idMap) {
330
		LogicalResource logical = unit.getLogicalResource();
331
		
332
		EObject[] roots = (EObject[]) unit.getContents().toArray(
333
			new EObject[unit.getContents().size()]);  // safe copy
334
		
335
		for (int i = 0; i < roots.length; i++) {
336
			// the logical resource now knows the actual sub-unit roots under
337
			//   the IDs previously retrieved
338
			String id = logical.getID(roots[i]);
339
			EObject oldObject = (EObject) idMap.get(id);
340
			
341
			// only do replacement if they are not the same object
342
			if ((oldObject != null) && (oldObject != roots[i])) {
343
				become(oldObject, roots[i], id, unit);
344
				fireLoadEvent(oldObject);
345
			}
346
		}	
347
	}
348
349
	/**
350
	 * Auto-loads the specified element of the specified resource, if it is
351
	 * an unloaded separate element.
352
	 * 
353
	 * @param res a resource, which may or may not be a logical resource
354
	 * @param eObject an element of the resource, which may or may not be
355
	 *     an unloaded separate element
356
	 */
357
	public static void autoload(Resource res, EObject eObject) {
358
		if (res instanceof ILogicalResource) {
359
			ILogicalResource logical = (ILogicalResource) res;
360
			Resource unit = AbstractResourceWrapper.unwrap(
361
				getPhysicalResource(logical, eObject.eContainer()));
362
			
363
			if (isAutoLoadable(unit) && !logical.isLoaded(eObject)) {
364
				try {
365
					if (Trace.isEnabled(MSLDebugOptions.RESOURCES)) {
366
						URI base = logical.getURI();
367
						URI relative = unit.getURI().deresolve(base);
368
						
369
						Trace.trace(
370
							MSLDebugOptions.RESOURCES,
371
							"Auto-loading unit: " + relative + " of: " + base); //$NON-NLS-1$ //$NON-NLS-2$
372
					}
373
					
374
					logical.load(eObject);
375
				} catch (IOException e) {
376
					Trace.catching(
377
						LogicalResourceUtil.class,
378
						"autoload(Resource, EObject)", e); //$NON-NLS-1$
379
					
380
					Log.error(
381
						MSLPlugin.getDefault(),
382
						MSLStatusCodes.LOGICAL_AUTOLOAD_FAILED,					
383
						EMFCoreMessages.autoload_failed_EXC_,
384
						e);
385
				}
386
			}
387
		}
388
	}
389
	
390
	/**
391
	 * Queries whether the specified <code>unit</code> can be auto-loaded.
392
	 * Instances of {@link LogicalResourceUnit} have configurable auto-loading
393
	 * support; other implementations are implicitly auto-loadable.
394
	 * 
395
	 * @param unit a unit
396
	 * @return <code>true</code> if it can be auto-loaded;
397
	 *     <code>false</code>, otherwise
398
	 */
399
	private static boolean isAutoLoadable(Resource unit) {
400
		boolean result = true;
401
		
402
		if (unit instanceof LogicalResourceUnit) {
403
			result = ((LogicalResourceUnit) unit).isAutoLoadEnabled();
404
		}
405
		
406
		return result;
407
	}
408
	
409
	/**
410
	 * Quietly loads the specified newly loaded object's features into the
411
	 * old object, and replaces the loaded object with the old one in the
412
	 * <code>subunit</code>.
413
	 * 
414
	 * @param oldObj the old object that we are loading
415
	 * @param newObj the newly loaded object that the <code>oldObj</code>
416
	 *      is to become
417
	 * @param id the ID object of the object that was loaded
418
	 * @param subunit the resource from which <code>newObj</code> was loaded
419
	 */
420
	private static void become(EObject oldObj, EObject newObj, String id,
421
			LogicalResourceUnit subunit) {
422
		// do this quietly
423
		oldObj.eSetDeliver(false);
424
		
425
		boolean wasClean = !subunit.isDirty();
426
		
427
		// transfer all features from the new object
428
		for (Iterator iter = newObj.eClass().getEAllStructuralFeatures().iterator();
429
				iter.hasNext();) {
430
			
431
			EStructuralFeature feature = (EStructuralFeature) iter.next();
432
			
433
			if (isTransferableFeature(feature)) {
434
				if (!feature.isMany()) {
435
					// simple case.  Just eSet without resolving the value
436
					oldObj.eSet(feature, newObj.eGet(feature, false));
437
				} else {
438
					// must transfer the EList contents without resolving anything
439
					//   or gathering any notifications.  Must copy the source
440
					//   list to avoid concurrent modification
441
					List oldValue = (List) oldObj.eGet(feature, false);
442
					List newValue = new java.util.ArrayList((List) newObj.eGet(feature, false));
443
					
444
					oldValue.clear();
445
					for (Iterator xfer = newValue.iterator(); xfer.hasNext();) {
446
						oldValue.add(xfer.next());
447
					}
448
				}
449
			}
450
		}
451
		
452
		// set the old object into the sub-unit resource.  This has the
453
		//    side-effect of updating the object-to-subunit map
454
		int pos = subunit.getContents().indexOf(newObj);
455
		subunit.getContents().set(pos, oldObj);
456
		
457
		// update the child entry to point to the right object.  If we can't
458
		//   find it, then it was already up-to-date
459
		ChildEntry childEntry = subunit.getResourceIndex().getChildEntry(newObj);
460
		if (childEntry != null) {
461
			childEntry.setChildObject(oldObj);
462
		}
463
		
464
		// the old object must re-assume the ID of the new one
465
		subunit.setID(oldObj, id);
466
		
467
		if (wasClean) {
468
			// the sub-unit should not be considered as dirty by this operation
469
			subunit.setClean();
470
		}
471
		
472
		oldObj.eSetDeliver(true);
473
	}
474
	
475
	/**
476
	 * Determines whether the specified feature is transferable from one object
477
	 * to another.  Transferable features are those that meet the following
478
	 * criteria:
479
	 * <ul>
480
	 *   <li>they are {@link EStructuralFeature#isChangeable() changeable}</li>
481
	 *   <li>they are not {@link EStructuralFeature#isDerived() derived}</li>
482
	 *   <li>they are not {@link EReference#isContainer() container} references</li>
483
	 * </ul>
484
	 * 
485
	 * @param feature a structural feature
486
	 * @return whether it is transferable, according to the criteria, above
487
	 */
488
	private static boolean isTransferableFeature(EStructuralFeature feature) {
489
		boolean result = feature.isChangeable() && !feature.isDerived();
490
491
		if (result && (feature instanceof EReference)) {
492
			result = !((EReference) feature).isContainer();
493
		}
494
		
495
		return result;
496
	}
497
	
498
	/**
499
	 * Loads all units of a logical resource that are not already loaded.
500
	 * 
501
	 * @param res a logical resource
502
	 * 
503
	 * @throws IOException if anything goes wrong in loading any unloaded
504
	 *     units
505
	 */
506
	public static void loadAllUnloadedUnits(ILogicalResource res) throws IOException {
507
		// must always iterate a separate collection to prevent concurrent mods
508
		Set newElements = new java.util.HashSet(
509
			res.getMappedResources().keySet());
510
		int lastCount = newElements.size();
511
		boolean foundNewElements = true;
512
		
513
		while (foundNewElements) {
514
			Set elements = newElements;
515
			
516
			for (Iterator iter = elements.iterator(); iter.hasNext();) {
517
				EObject next = (EObject) iter.next();
518
				
519
				if (!res.isLoaded(next)) {
520
					res.load(next);
521
				}
522
			}
523
			
524
			// found any new unloaded elements?
525
			int newCount = res.getMappedResources().size();
526
			foundNewElements = newCount > lastCount;
527
			
528
			if (foundNewElements) {
529
				// compute the new elements, and iterate again
530
				newElements = new java.util.HashSet(
531
					res.getMappedResources().keySet());
532
				newElements.removeAll(elements);
533
				lastCount = newCount;
534
			}
535
		}
536
	}
537
538
	/**
539
	 * Finds the unit within a logical resource that physically contains the
540
	 * specified element.
541
	 * 
542
	 * @param res a logical resource, or a unit in a logical resource
543
	 * @param eObject an element in the logical resource
544
	 * @return the unit of the logical resource that contains the element 
545
	 */
546
	static LogicalResourceUnit getUnitFor(LogicalResource res, EObject eObject) {
547
		LogicalResourceUnit result = null;
548
		
549
		if (eObject == null) {
550
			result = res.getRootUnit();
551
		} else {
552
			result = (LogicalResourceUnit) AbstractResourceWrapper.unwrap(
553
				getPhysicalResource(res, eObject));
554
		}
555
		
556
		return result;
557
	}
558
559
	/**
560
	 * A convenience method for retrieving the physical resource (as an
561
	 * unmodifiable view) that stores the specified element.
562
	 * 
563
	 * @param eObject an element in the logical resource.  It needs not be
564
	 *     a separate element (i.e., the root of a physical resource)
565
	 * @return an unmodifiable view of the resource that stores the element
566
	 */
567
	public static Resource getPhysicalResource(ILogicalResource res, EObject eObject) {
568
		Resource result = null;
569
		Map map = res.getMappedResources();
570
		
571
		while ((eObject != null) && (result == null)) {
572
			if (map.containsKey(eObject)) {
573
				result = (Resource) map.get(eObject);
574
			}
575
			
576
			eObject = eObject.eContainer();
577
		}
578
		
579
		return result;
580
	}
581
	
582
	/**
583
	 * Ensures that the specified <code>eObject</code> is not the root of a
584
	 * separate resource.
585
	 * 
586
	 * @param res the logical resource
587
	 * @param eObject a model element
588
	 * 
589
	 * @see #separate(LogicalResource, EObject, URI)
590
	 */
591
	static void absorb(LogicalResource res, EObject eObject) {
592
		LogicalResourceUnit oldUnit = getUnitFor(res, eObject);
593
		
594
		// dirty the former unit
595
		oldUnit.getContents().remove(eObject);
596
		oldUnit.setDirty();
597
		
598
		// must also dirty the new unit
599
		LogicalResourceUnit newUnit = getUnitFor(res, eObject.eContainer());
600
		if (eObject.eContainer() == null) {
601
			// this is now a root of the root unit
602
			newUnit.getContents().add(eObject);
603
		}
604
		newUnit.setDirty();
605
		
606
		reparentChildUnits(oldUnit, newUnit, eObject);
607
	}
608
	
609
	/**
610
	 * Removes the specified element's child entry from the old unit's resource
611
	 * index.
612
	 * 
613
	 * @param oldUnit the element's old unit
614
	 * @param eObject the element
615
	 */
616
	static void removeChildEntry(LogicalResourceUnit oldUnit, EObject eObject) {
617
		ResourceMap index = oldUnit.getResourceIndex();
618
		
619
		if (index != null) {
620
			ChildEntry childEntry = index.getChildEntry(eObject);
621
			
622
			if (childEntry != null) {
623
				index.getChildEntries().remove(childEntry);
624
				
625
				ResourceMap parentIndex = childEntry.getParentMap();
626
				if (parentIndex != null) {
627
					ResourceEntry resourceEntry =
628
						parentIndex.getResourceEntry(eObject);
629
					
630
					if (resourceEntry != null) {
631
						ParentEntry parentEntry = resourceEntry.getParentEntry();
632
						
633
						parentEntry.getResourceEntries().remove(
634
							resourceEntry);
635
						
636
						if (parentEntry.getResourceEntries().isEmpty()) {
637
							// don't need this parent entry any more if it
638
							//    has no sub-units remaining
639
							parentEntry.getResourceMap().getParentEntries().remove(
640
								parentEntry);
641
						}
642
					}
643
				}
644
			}
645
		}
646
	}
647
	
648
	/**
649
	 * Creates a resource entry for the sub-unit storing the specified
650
	 * <code>eObject</code> in the parent unit's resource <code>index</code>.
651
	 * This has the side-effect of creating the corresponding child entry
652
	 * in the sub-unit's own resource index.
653
	 * 
654
	 * @param eObject the sub-unit element
655
	 * @param parentUnit the <code>eObject</code>'s old physical unit
656
	 * @param subunit the <code>eObject</code>'s new physical unit
657
	 */
658
	static void createSubunitEntry(
659
			EObject eObject,
660
			LogicalResourceUnit parentUnit,
661
			LogicalResourceUnit subunit) {
662
		
663
		ResourceMap parentIndex = parentUnit.getResourceIndex();
664
		
665
		EObject parent = eObject.eContainer();
666
		EReference containment = eObject.eContainmentFeature();
667
		
668
		ParentEntry parentEntry = createParentEntry(parentIndex, parent, containment);
669
		
670
		ResourceEntry entry = parentEntry.getResourceEntry(eObject);
671
		
672
		if (entry == null) {
673
			entry = ResourceMapFactory.eINSTANCE.createResourceEntry();
674
			parentEntry.getResourceEntries().add(entry);
675
			entry.setChildObject(eObject);
676
		}
677
		
678
		updateChildPosition(subunit, entry);
679
		
680
		ResourceMap childIndex = subunit.getResourceIndex();
681
		if (childIndex != null) {
682
			// really shouldn't be null!
683
			ChildEntry childEntry = childIndex.getChildEntry(eObject);
684
			
685
			if (childEntry == null) {
686
				childEntry = ResourceMapFactory.eINSTANCE.createChildEntry();
687
				childIndex.getChildEntries().add(childEntry);
688
				childEntry.setChildObject(eObject);
689
			}
690
			
691
			childEntry.setParentMap(parentIndex);
692
		}
693
	}
694
	
695
	/**
696
	 * Creates the parent entry in a resource <code>index</code> for the
697
	 * specified container and reference.  If the <code>parent</code> and
698
	 * <code>containment</code> reference are both <code>null</code>, then
699
	 * we are creating an entry for the resource, itself (to separate a root).
700
	 * 
701
	 * @param index the resource index to create the entry in
702
	 * @param parent the container element (may be <code>null</code>)
703
	 * @param containment the containment reference (may be <code>null</code>)
704
	 * 
705
	 * @return the new parent entry, added to the <code>index</code>
706
	 */
707
	private static ParentEntry createParentEntry(ResourceMap index, EObject parent, EReference containment) {
708
		ParentEntry result = index.getParentEntry(parent, containment);
709
		
710
		if (result == null) {
711
			result = ResourceMapFactory.eINSTANCE.createParentEntry();
712
			result.setParentObject(parent);
713
			result.setChildSlot(containment);
714
			index.getParentEntries().add(result);
715
		}
716
		
717
		return result;
718
	}
719
	
720
	/**
721
	 * Initializes a sub-unit resource to prepare it for adding a new root
722
	 * element to it.
723
	 * 
724
	 * @param res the logical resource
725
	 * @param eObject the physical resource's new root
726
	 * @param uri the the physical resource's URI
727
	 * 
728
	 * @return the physical resource, ready to receive its new root
729
	 */
730
	private static LogicalResourceUnit initializeUnit(LogicalResource res,
731
			EObject eObject, URI uri) {
732
		
733
		ResourceSet rset = res.getSubunitResourceSet();
734
		LogicalResourceUnit result = (LogicalResourceUnit) rset.getResource(uri, false); 
735
		if (result == null) {
736
			result = (LogicalResourceUnit) rset.createResource(uri);
737
		}
738
		
739
		if (!result.isLoaded()) {
740
			IFile file = ResourceUtil.getFile(result);
741
			
742
			if ((file != null) && file.exists()) {
743
				try {
744
					loadUnit(result);
745
				} catch (IOException e) {
746
					Trace.catching(
747
						LogicalResourceUtil.class,
748
						"initResource(LogicalResource, EObject, URI)", e); //$NON-NLS-1$
749
					
750
					Log.warning(
751
						MSLPlugin.getDefault(),
752
						MSLStatusCodes.LOGICAL_LOAD_FAILED,				
753
						EMFCoreMessages.load_failed_EXC_,
754
						e);
755
				}
756
			}
757
		}
758
		
759
		return result;
760
	}
761
	
762
	/**
763
	 * Set the child position of the specified resource <code>entry</code>
764
	 * from its index in the containment feature (if it is a list).
765
	 * 
766
	 * @param subunit the sub-unit that the <code>entry</code> references
767
	 * @param entry the entry whose child position is to be set
768
	 */
769
	static void updateChildPosition(LogicalResourceUnit subunit, ResourceEntry entry) {
770
		EObject child = entry.getChildObject();
771
		EReference containment = entry.getParentEntry().getChildSlot();
772
		
773
		// ensure that the resource is set
774
		entry.setResource(subunit);
775
		
776
		if (containment == null) {
777
			Resource res = subunit.getLogicalResource();
778
			entry.setChildPosition(res.getContents().indexOf(child));
779
		} else if (containment.isMany()) {
780
			EList values = (EList) child.eContainer().eGet(containment);
781
			entry.setChildPosition(values.indexOf(child));
782
		} else {
783
			entry.eUnset(ResourceMapPackage.eINSTANCE.getResourceEntry_ChildPosition());
784
		}
785
	}
786
	
787
	/**
788
	 * Sets the child positions of the resources in a parent <code>entry</code>
789
	 * from their indices in the containment feature (if it is a list).  This is
790
	 * useful when all existing entries need to be recomputed because of the
791
	 * addition or removal of an element from the list
792
	 * 
793
	 * @param unit the unit that owns the parent <code>entry</code>
794
	 * @param entry the parent entry whose child positions are to be set
795
	 */
796
	static void updateChildPositions(LogicalResourceUnit unit, ParentEntry entry) {
797
		EObject parent = entry.getParentObject();
798
		EReference containment = entry.getChildSlot();
799
		
800
		for (Iterator iter = entry.getResourceEntries().iterator(); iter.hasNext();) {
801
			ResourceEntry resEntry = (ResourceEntry) iter.next();
802
			EObject child = resEntry.getChildObject();
803
			
804
			if (containment == null) {
805
				Resource res = unit.getLogicalResource();
806
				resEntry.setChildPosition(res.getContents().indexOf(child));
807
			} else if (containment.isMany()) {
808
				EList values = (EList) parent.eGet(containment);
809
				resEntry.setChildPosition(values.indexOf(child));
810
			} else {
811
				resEntry.eUnset(
812
					ResourceMapPackage.eINSTANCE.getResourceEntry_ChildPosition());
813
			}
814
		}
815
	}
816
	
817
	/**
818
	 * Computes the index of a <code>child</code> object in its
819
	 * <code>parent</code>'s <code>containment</code> reference.
820
	 * 
821
	 * @param child an element
822
	 * @param parent its container
823
	 * @param containment the containment feature of the <code>child</code>
824
	 * 
825
	 * @return the index, or -1 if the <code>containment</code> reference is not
826
	 *     a collection
827
	 */
828
	private static int indexOf(EObject child, EObject parent, EReference containment) {
829
		int result = -1;
830
		
831
		if (containment.isMany()) {
832
			// it's a containment reference, so no worries about proxy resolution
833
			EList value = (EList) parent.eGet(containment);
834
			result = value.indexOf(child);
835
		}
836
		
837
		return result;
838
	}
839
	
840
	/**
841
	 * Fires an artificial {@link EventTypes#SEPARATE} notification for the
842
	 * separation of the specified object.
843
	 * 
844
	 * @param eObject the newly separated object
845
	 * @param oldResource the object's old resource
846
	 * @param newResource its new resource
847
	 */
848
	public static void fireSeparationEvent(EObject eObject,
849
			Resource oldResource, Resource newResource) {
850
		Notification notification = createNotification(
851
			eObject,
852
			EventTypes.SEPARATE,
853
			oldResource,
854
			newResource);
855
		
856
		dispatch(notification);
857
	}
858
	
859
	/**
860
	 * Fires an artificial {@link EventTypes#ABSORB} notification for the
861
	 * absorption of the specified object.
862
	 * 
863
	 * @param eObject the newly separated object
864
	 * @param oldResource the object's old resource
865
	 * @param newResource its new resource
866
	 */
867
	public static void fireAbsorptionEvent(EObject eObject,
868
			Resource oldResource, Resource newResource) {
869
		Notification notification = createNotification(
870
			eObject,
871
			EventTypes.ABSORB,
872
			oldResource,
873
			newResource);
874
		
875
		dispatch(notification);
876
	}
877
	
878
	/**
879
	 * Fires an artificial {@link EventTypes#LOADED} notification for the
880
	 * loading of the specified object.
881
	 * 
882
	 * @param eObject the newly loaded object
883
	 */
884
	public static void fireLoadEvent(EObject eObject) {
885
		Notification notification = createNotification(
886
			eObject,
887
			EventTypes.LOAD,
888
			eObject,
889
			eObject);
890
		
891
		dispatch(notification);
892
	}
893
	
894
	/**
895
	 * Creates a notification of the specified type for the specified element,
896
	 * with old and new values.
897
	 * 
898
	 * @param eObject the element to create the notification for
899
	 * @param type the notification type
900
	 * @param oldValue the old value
901
	 * @param newValue the new value
902
	 * 
903
	 * @return the new notification
904
	 */
905
	private static Notification createNotification(
906
			EObject eObject, int type, Object oldValue, Object newValue) {
907
		
908
		EObject container = eObject.eContainer();
909
		EReference containment = eObject.eContainmentFeature();
910
		
911
		Notification result;
912
		int index;
913
		
914
		if (containment != null) {
915
			index = indexOf(eObject, container, containment);
916
			result = new NotificationImpl(
917
				(InternalEObject) container,
918
				type,
919
				containment,
920
				oldValue, newValue,
921
				index);
922
		} else {
923
			// it's a logical root
924
			Resource res = eObject.eResource();
925
			index = res.getContents().indexOf(eObject);
926
			result = new ResourceNotificationImpl(
927
				res,
928
				type,
929
				oldValue, newValue,
930
				index);
931
		}
932
		
933
		return result;
934
	}
935
	
936
	/**
937
	 * Dispatches the specified <code>notification</code> to adapters.
938
	 * 
939
	 * @param notification the notification to dispatch
940
	 */
941
	private static void dispatch(Notification notification) {
942
		Notifier notifier = (Notifier) notification.getNotifier();
943
		notifier.eNotify(notification);
944
	}
945
	
946
	/**
947
	 * Notification implementation for notification of changes to the physical
948
	 * structure of a logical resource.
949
	 *
950
	 * @author Christian W. Damus (cdamus)
951
	 */
952
	private static class NotificationImpl extends ENotificationImpl {
953
		NotificationImpl(InternalEObject notifier, int eventType,
954
			EStructuralFeature feature, Object oldValue, Object newValue,
955
			int index) {
956
			
957
			super(notifier, eventType, feature, oldValue, newValue, index);
958
		}
959
		
960
		public boolean isTouch() {
961
			// changes in the physical resource structure do not affect the
962
			//   resource's logical contents
963
			return true;
964
		}
965
	}
966
	
967
	private static class ResourceNotificationImpl
968
		extends org.eclipse.emf.common.notify.impl.NotificationImpl {
969
970
		private final Resource notifier;
971
		
972
		public ResourceNotificationImpl(Resource notifier,
973
				int eventType, Object oldValue, Object newValue, int position) {
974
			// consider the resource contents to be always set
975
			super(eventType, oldValue, newValue, position, true);
976
			this.notifier = notifier;
977
		}
978
		
979
		public Object getNotifier() {
980
			return notifier;
981
		}
982
		
983
		public int getFeatureID(Class expectedClass) {
984
			return Resource.RESOURCE__CONTENTS;
985
		}
986
		
987
		public boolean isTouch() {
988
			// changes in the physical resource structure do not affect the
989
			//   resource's logical contents
990
			return true;
991
		}
992
	}
993
}
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resources/MSLHandler.java (-2 / +4 lines)
Lines 24-29 Link Here
24
import org.eclipse.emf.ecore.resource.Resource;
24
import org.eclipse.emf.ecore.resource.Resource;
25
import org.eclipse.emf.ecore.resource.impl.ResourceImpl;
25
import org.eclipse.emf.ecore.resource.impl.ResourceImpl;
26
import org.eclipse.emf.ecore.xmi.XMLHelper;
26
import org.eclipse.emf.ecore.xmi.XMLHelper;
27
import org.eclipse.emf.ecore.xmi.XMLResource;
28
import org.eclipse.emf.ecore.xmi.impl.SAXXMIHandler;
27
import org.eclipse.emf.ecore.xml.type.AnyType;
29
import org.eclipse.emf.ecore.xml.type.AnyType;
28
30
29
/**
31
/**
Lines 33-39 Link Here
33
 * @author khussey
35
 * @author khussey
34
 */
36
 */
35
public class MSLHandler
37
public class MSLHandler
36
	extends LogicalHandler {
38
	extends SAXXMIHandler {
37
39
38
	protected final Map urisToProxies;
40
	protected final Map urisToProxies;
39
41
Lines 48-54 Link Here
48
	 * @param options
50
	 * @param options
49
	 *            The load options for the new handler.
51
	 *            The load options for the new handler.
50
	 */
52
	 */
51
	public MSLHandler(MSLResourceUnit xmiResource, XMLHelper helper, Map options) {
53
	public MSLHandler(XMLResource xmiResource, XMLHelper helper, Map options) {
52
		super(xmiResource, helper, options);
54
		super(xmiResource, helper, options);
53
55
54
		urisToProxies = new HashMap();
56
		urisToProxies = new HashMap();
(-)src/org/eclipse/gmf/runtime/emf/core/edit/MEditingDomain.java (+8 lines)
Lines 371-376 Link Here
371
	 * @return whether the <code>resource</code> is a logical resource
371
	 * @return whether the <code>resource</code> is a logical resource
372
	 * 
372
	 * 
373
	 * @see ILogicalResource
373
	 * @see ILogicalResource
374
	 * 
375
	 * @deprecated Use the cross-resource containment support provided by EMF,
376
	 *     instead, by defining containment features that are capable of storing
377
	 *     proxies.
374
	 */
378
	 */
375
	public abstract boolean isLogicalResource(Resource resource);
379
	public abstract boolean isLogicalResource(Resource resource);
376
380
Lines 383-388 Link Here
383
	 * 
387
	 * 
384
	 * @param resource a resource for which we want to obtain a logical view
388
	 * @param resource a resource for which we want to obtain a logical view
385
	 * @return the logical view of the resource
389
	 * @return the logical view of the resource
390
	 * 
391
	 * @deprecated Use the cross-resource containment support provided by EMF,
392
	 *     instead, by defining containment features that are capable of storing
393
	 *     proxies.
386
	 */
394
	 */
387
	public abstract ILogicalResource asLogicalResource(Resource resource);
395
	public abstract ILogicalResource asLogicalResource(Resource resource);
388
396
(-)src/org/eclipse/gmf/runtime/emf/core/edit/DemuxedMListener.java (+12 lines)
Lines 173-178 Link Here
173
173
174
	/**
174
	/**
175
	 * Does nothing.
175
	 * Does nothing.
176
	 * 
177
	 * @deprecated Use the cross-resource containment support provided by EMF,
178
	 *     instead, by defining containment features that are capable of storing
179
	 *     proxies.
176
	 */
180
	 */
177
	public void handleElementSeparatedEvent(Notification notification,
181
	public void handleElementSeparatedEvent(Notification notification,
178
			ILogicalResource resource, EObject eObject, Resource newResource) {
182
			ILogicalResource resource, EObject eObject, Resource newResource) {
Lines 181-186 Link Here
181
	
185
	
182
	/**
186
	/**
183
	 * Does nothing.
187
	 * Does nothing.
188
	 * 
189
	 * @deprecated Use the cross-resource containment support provided by EMF,
190
	 *     instead, by defining containment features that are capable of storing
191
	 *     proxies.
184
	 */
192
	 */
185
	public void handleElementAbsorbedEvent(Notification notification,
193
	public void handleElementAbsorbedEvent(Notification notification,
186
			ILogicalResource resource, EObject eObject, Resource oldResource) {
194
			ILogicalResource resource, EObject eObject, Resource oldResource) {
Lines 189-194 Link Here
189
	
197
	
190
	/**
198
	/**
191
	 * Does nothing.
199
	 * Does nothing.
200
	 * 
201
	 * @deprecated Use the cross-resource containment support provided by EMF,
202
	 *     instead, by defining containment features that are capable of storing
203
	 *     proxies.
192
	 */
204
	 */
193
	public void handleElementLoadedEvent(Notification notification,
205
	public void handleElementLoadedEvent(Notification notification,
194
			ILogicalResource resource, EObject eObject) {
206
			ILogicalResource resource, EObject eObject) {
(-)src/org/eclipse/gmf/runtime/emf/core/edit/IDemuxedMListener2.java (+12 lines)
Lines 39-44 Link Here
39
	 *     separated into a subordinate resource with the specified <code>uri</code>
39
	 *     separated into a subordinate resource with the specified <code>uri</code>
40
	 * @param newResource the new subordinate resource (within the logical
40
	 * @param newResource the new subordinate resource (within the logical
41
	 *     <code>resource</code>) that stores the <code>eObject</code>
41
	 *     <code>resource</code>) that stores the <code>eObject</code>
42
	 * 
43
	 * @deprecated Use the cross-resource containment support provided by EMF,
44
	 *     instead, by defining containment features that are capable of storing
45
	 *     proxies.
42
	 */
46
	 */
43
	public void handleElementSeparatedEvent(Notification notification,
47
	public void handleElementSeparatedEvent(Notification notification,
44
		ILogicalResource resource, EObject eObject, Resource newResource);
48
		ILogicalResource resource, EObject eObject, Resource newResource);
Lines 53-58 Link Here
53
	 *     absorbed from a subordinate resource with the specified <code>uri</code>
57
	 *     absorbed from a subordinate resource with the specified <code>uri</code>
54
	 * @param oldResource the subordinate resource (within the logical
58
	 * @param oldResource the subordinate resource (within the logical
55
	 *     <code>resource</code>) that formerly stored the <code>eObject</code>
59
	 *     <code>resource</code>) that formerly stored the <code>eObject</code>
60
	 * 
61
	 * @deprecated Use the cross-resource containment support provided by EMF,
62
	 *     instead, by defining containment features that are capable of storing
63
	 *     proxies.
56
	 */
64
	 */
57
	public void handleElementAbsorbedEvent(Notification notification,
65
	public void handleElementAbsorbedEvent(Notification notification,
58
			ILogicalResource resource, EObject eObject, Resource oldResource);
66
			ILogicalResource resource, EObject eObject, Resource oldResource);
Lines 65-70 Link Here
65
	 * @param resource the logical resource into which the object was loaded
73
	 * @param resource the logical resource into which the object was loaded
66
	 * @param eObject an object in the <code>resource</code>, which is
74
	 * @param eObject an object in the <code>resource</code>, which is
67
	 *     newly loaded from a previously unloaded physical resource
75
	 *     newly loaded from a previously unloaded physical resource
76
	 * 
77
	 * @deprecated Use the cross-resource containment support provided by EMF,
78
	 *     instead, by defining containment features that are capable of storing
79
	 *     proxies.
68
	 */
80
	 */
69
	public void handleElementLoadedEvent(Notification notification,
81
	public void handleElementLoadedEvent(Notification notification,
70
			ILogicalResource resource, EObject eObject);
82
			ILogicalResource resource, EObject eObject);
(-)src/org/eclipse/gmf/runtime/emf/core/edit/MResourceOption.java (+8 lines)
Lines 48-53 Link Here
48
	 * {@linkplain org.eclipse.gmf.runtime.emf.core.resources.ILogicalResource logical resource}.
48
	 * {@linkplain org.eclipse.gmf.runtime.emf.core.resources.ILogicalResource logical resource}.
49
	 * 
49
	 * 
50
	 * @see #DONT_AUTO_LOAD_SUBUNITS
50
	 * @see #DONT_AUTO_LOAD_SUBUNITS
51
	 * 
52
	 * @deprecated Use the cross-resource containment support provided by EMF,
53
	 *     instead, by defining containment features that are capable of storing
54
	 *     proxies.
51
	 */
55
	 */
52
	public static final int LOAD_ALL_SUBUNITS = 16;
56
	public static final int LOAD_ALL_SUBUNITS = 16;
53
57
Lines 57-62 Link Here
57
	 * This option is ignored if all units are loaded initially.
61
	 * This option is ignored if all units are loaded initially.
58
	 * 
62
	 * 
59
	 * @see #LOAD_ALL_SUBUNITS
63
	 * @see #LOAD_ALL_SUBUNITS
64
	 * 
65
	 * @deprecated Use the cross-resource containment support provided by EMF,
66
	 *     instead, by defining containment features that are capable of storing
67
	 *     proxies.
60
	 */
68
	 */
61
	public static final int DONT_AUTO_LOAD_SUBUNITS = 32;
69
	public static final int DONT_AUTO_LOAD_SUBUNITS = 32;
62
	
70
	
(-)src/org/eclipse/gmf/runtime/emf/core/edit/MFilter.java (+8 lines)
Lines 129-134 Link Here
129
129
130
	/**
130
	/**
131
	 * Filter for element separated or absorbed events.
131
	 * Filter for element separated or absorbed events.
132
	 * 
133
	 * @deprecated Use the cross-resource containment support provided by EMF,
134
	 *     instead, by defining containment features that are capable of storing
135
	 *     proxies.
132
	 */
136
	 */
133
	public final static MFilter SEPARATED_ABSORBED_FILTER = new MFilter.Or(
137
	public final static MFilter SEPARATED_ABSORBED_FILTER = new MFilter.Or(
134
			new MFilter.EventType(EventTypes.SEPARATE), new MFilter.EventType(
138
			new MFilter.EventType(EventTypes.SEPARATE), new MFilter.EventType(
Lines 168-173 Link Here
168
172
169
	/**
173
	/**
170
	 * Filter for element loaded events.
174
	 * Filter for element loaded events.
175
	 * 
176
	 * @deprecated Use the cross-resource containment support provided by EMF,
177
	 *     instead, by defining containment features that are capable of storing
178
	 *     proxies.
171
	 */
179
	 */
172
	public final static MFilter ELEMENT_LOADED_FILTER = 
180
	public final static MFilter ELEMENT_LOADED_FILTER = 
173
			new MFilter.EventType(EventTypes.LOAD);
181
			new MFilter.EventType(EventTypes.LOAD);
(-)src/org/eclipse/gmf/runtime/emf/core/edit/DemuxingMListener.java (-80 lines)
Lines 16-29 Link Here
16
import java.util.List;
16
import java.util.List;
17
17
18
import org.eclipse.emf.common.notify.Notification;
18
import org.eclipse.emf.common.notify.Notification;
19
import org.eclipse.emf.common.util.EList;
20
import org.eclipse.emf.ecore.EObject;
19
import org.eclipse.emf.ecore.EObject;
21
import org.eclipse.emf.ecore.EReference;
20
import org.eclipse.emf.ecore.EReference;
22
import org.eclipse.emf.ecore.resource.Resource;
21
import org.eclipse.emf.ecore.resource.Resource;
23
24
import org.eclipse.gmf.runtime.emf.core.EventTypes;
22
import org.eclipse.gmf.runtime.emf.core.EventTypes;
25
import org.eclipse.gmf.runtime.emf.core.internal.notifications.MSLResourceListener;
23
import org.eclipse.gmf.runtime.emf.core.internal.notifications.MSLResourceListener;
26
import org.eclipse.gmf.runtime.emf.core.resources.ILogicalResource;
27
import org.eclipse.gmf.runtime.emf.core.util.ResourceUtil;
24
import org.eclipse.gmf.runtime.emf.core.util.ResourceUtil;
28
25
29
/**
26
/**
Lines 146-184 Link Here
146
					Resource resource = (Resource) notifier;
143
					Resource resource = (Resource) notifier;
147
					eventListener
144
					eventListener
148
						.handleResourceExportedEvent(notification, resource);
145
						.handleResourceExportedEvent(notification, resource);
149
				} else if (notification.getEventType() == EventTypes.SEPARATE) {
150
					int featureID = notification.getFeatureID(Resource.class);
151
					if ((featureID == Resource.RESOURCE__CONTENTS) && (eventListener2 != null)) {
152
						ILogicalResource res = (ILogicalResource) notifier;
153
						Resource newRes = (Resource) notification.getNewValue();
154
						int position = notification.getPosition();
155
						
156
						EObject element = (EObject) res.getContents().get(position);
157
						
158
						eventListener2.handleElementSeparatedEvent(
159
							notification, res, element, newRes);
160
					}
161
				} else if (notification.getEventType() == EventTypes.ABSORB) {
162
					int featureID = notification.getFeatureID(Resource.class);
163
					if ((featureID == Resource.RESOURCE__CONTENTS) && (eventListener2 != null)) {
164
						ILogicalResource res = (ILogicalResource) notifier;
165
						Resource oldRes = (Resource) notification.getOldValue();
166
						int position = notification.getPosition();
167
						
168
						EObject element = (EObject) res.getContents().get(position);
169
						
170
						eventListener2.handleElementAbsorbedEvent(
171
							notification, res, element, oldRes);
172
					}
173
				} else if (notification.getEventType() == EventTypes.LOAD) {
174
					int featureID = notification.getFeatureID(Resource.class);
175
					if ((featureID == Resource.RESOURCE__CONTENTS) && (eventListener2 != null)) {
176
						EObject element = (EObject) notification.getNewValue();
177
						ILogicalResource res = (ILogicalResource) notifier;
178
						
179
						eventListener2.handleElementLoadedEvent(
180
							notification, res, element);
181
					}
182
				}
146
				}
183
			} else if (notifier instanceof EObject) {
147
			} else if (notifier instanceof EObject) {
184
				if (notification.getEventType() == EventTypes.ADD) {
148
				if (notification.getEventType() == EventTypes.ADD) {
Lines 265-314 Link Here
265
					EObject element = (EObject) notifier;
229
					EObject element = (EObject) notifier;
266
					eventListener.handleElementModifiedEvent(notification,
230
					eventListener.handleElementModifiedEvent(notification,
267
						element);
231
						element);
268
				} else if (notification.getEventType() == EventTypes.SEPARATE) {
269
					if (eventListener2 != null) {
270
						EObject element = (EObject) notifier;
271
						ILogicalResource res = (ILogicalResource) element.eResource();
272
						EReference feature = (EReference) notification.getFeature();
273
						Resource newRes = (Resource) notification.getNewValue();
274
						int position = notification.getPosition();
275
						
276
						if (position < 0) {
277
							// scalar reference
278
							element = (EObject) element.eGet(feature);
279
						} else {
280
							element = (EObject) ((EList) element.eGet(feature)).get(position);
281
						}
282
						
283
						eventListener2.handleElementSeparatedEvent(
284
							notification, res, element, newRes);
285
					}
286
				} else if (notification.getEventType() == EventTypes.ABSORB) {
287
					if (eventListener2 != null) {
288
						EObject element = (EObject) notifier;
289
						ILogicalResource res = (ILogicalResource) element.eResource();
290
						EReference feature = (EReference) notification.getFeature();
291
						Resource oldRes = (Resource) notification.getOldValue();
292
						int position = notification.getPosition();
293
						
294
						if (position < 0) {
295
							// scalar reference
296
							element = (EObject) element.eGet(feature);
297
						} else {
298
							element = (EObject) ((EList) element.eGet(feature)).get(position);
299
						}
300
						
301
						eventListener2.handleElementAbsorbedEvent(
302
							notification, res, element, oldRes);
303
					}
304
				} else if (notification.getEventType() == EventTypes.LOAD) {
305
					if (eventListener2 != null) {
306
						EObject element = (EObject) notification.getNewValue();
307
						ILogicalResource res = (ILogicalResource) element.eResource();
308
						
309
						eventListener2.handleElementLoadedEvent(
310
							notification, res, element);
311
					}
312
				}
232
				}
313
			} else if (notifier instanceof MUndoInterval) {
233
			} else if (notifier instanceof MUndoInterval) {
314
				MUndoInterval undoInterval = (MUndoInterval) notifier;
234
				MUndoInterval undoInterval = (MUndoInterval) notifier;
(-)META-INF/MANIFEST.MF (-3 lines)
Lines 18-26 Link Here
18
 org.eclipse.gmf.runtime.emf.core.internal.l10n,
18
 org.eclipse.gmf.runtime.emf.core.internal.l10n,
19
 org.eclipse.gmf.runtime.emf.core.internal.notifications,
19
 org.eclipse.gmf.runtime.emf.core.internal.notifications,
20
 org.eclipse.gmf.runtime.emf.core.internal.plugin,
20
 org.eclipse.gmf.runtime.emf.core.internal.plugin,
21
 org.eclipse.gmf.runtime.emf.core.internal.resourcemap;x-friends:="org.eclipse.gmf.tests.runtime.emf.core",
22
 org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl;x-friends:="org.eclipse.gmf.tests.runtime.emf.core",
23
 org.eclipse.gmf.runtime.emf.core.internal.resourcemap.util;x-friends:="org.eclipse.gmf.tests.runtime.emf.core",
24
 org.eclipse.gmf.runtime.emf.core.internal.resources,
21
 org.eclipse.gmf.runtime.emf.core.internal.resources,
25
 org.eclipse.gmf.runtime.emf.core.internal.services.metamodel,
22
 org.eclipse.gmf.runtime.emf.core.internal.services.metamodel,
26
 org.eclipse.gmf.runtime.emf.core.internal.type,
23
 org.eclipse.gmf.runtime.emf.core.internal.type,
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resourcemap/util/package.html (-16 lines)
Removed Link Here
1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
2
<html>
3
<head>
4
<!--
5
6
/******************************************************************************
7
 * Copyright (c) 2004,2005 IBM Corporation and others.
8
 * All rights reserved. This program and the accompanying materials
9
 * are made available under the terms of the Eclipse Public License v1.0
10
 * which accompanies this distribution, and is available at
11
 * http://www.eclipse.org/legal/epl-v10.html
12
 *
13
 * Contributors:
14
 *    IBM Corporation - initial API and implementation 
15
 ****************************************************************************/
16
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resourcemap/util/ResourceMapSwitch.java (-203 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
package org.eclipse.gmf.runtime.emf.core.internal.resourcemap.util;
13
14
import java.util.List;
15
16
import org.eclipse.emf.ecore.EClass;
17
import org.eclipse.emf.ecore.EObject;
18
19
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ChildEntry;
20
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry;
21
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry;
22
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap;
23
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage;
24
25
/**
26
 * <!-- begin-user-doc -->
27
 * The <b>Switch</b> for the logical resource physical mapping metamodel's
28
 * inheritance hierarchy.
29
 * It supports the call {@link #doSwitch(EObject) doSwitch(object)}
30
 * to invoke the <code>caseXXX</code> method for each class of the metamodel,
31
 * starting with the actual class of the object
32
 * and proceeding up the inheritance hierarchy
33
 * until a non-null result is returned,
34
 * which is the result of the switch.
35
 * <!-- end-user-doc -->
36
 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage
37
 * @generated
38
 */
39
public class ResourceMapSwitch {
40
	/**
41
	 * The cached model package
42
	 * <!-- begin-user-doc -->
43
	 * <!-- end-user-doc -->
44
	 * @generated
45
	 */
46
	protected static ResourceMapPackage modelPackage;
47
48
	/**
49
	 * Creates an instance of the switch.
50
	 * <!-- begin-user-doc -->
51
	 * <!-- end-user-doc -->
52
	 * @generated
53
	 */
54
	public ResourceMapSwitch() {
55
		if (modelPackage == null) {
56
			modelPackage = ResourceMapPackage.eINSTANCE;
57
		}
58
	}
59
60
	/**
61
	 * Calls <code>caseXXX</code> for each class of the model until one returns a non null result; it yields that result.
62
	 * <!-- begin-user-doc -->
63
	 * <!-- end-user-doc -->
64
	 * @return the first non-null result returned by a <code>caseXXX</code> call.
65
	 * @generated
66
	 */
67
	public Object doSwitch(EObject theEObject) {
68
		return doSwitch(theEObject.eClass(), theEObject);
69
	}
70
71
	/**
72
	 * Calls <code>caseXXX</code> for each class of the model until one returns a non null result; it yields that result.
73
	 * <!-- begin-user-doc -->
74
	 * <!-- end-user-doc -->
75
	 * @return the first non-null result returned by a <code>caseXXX</code> call.
76
	 * @generated
77
	 */
78
	protected Object doSwitch(EClass theEClass, EObject theEObject) {
79
		if (theEClass.eContainer() == modelPackage) {
80
			return doSwitch(theEClass.getClassifierID(), theEObject);
81
		}
82
		else {
83
			List eSuperTypes = theEClass.getESuperTypes();
84
			return
85
				eSuperTypes.isEmpty() ?
86
					defaultCase(theEObject) :
87
					doSwitch((EClass)eSuperTypes.get(0), theEObject);
88
		}
89
	}
90
91
	/**
92
	 * Calls <code>caseXXX</code> for each class of the model until one returns a non null result; it yields that result.
93
	 * <!-- begin-user-doc -->
94
	 * <!-- end-user-doc -->
95
	 * @return the first non-null result returned by a <code>caseXXX</code> call.
96
	 * @generated
97
	 */
98
	protected Object doSwitch(int classifierID, EObject theEObject) {
99
		switch (classifierID) {
100
			case ResourceMapPackage.RESOURCE_MAP: {
101
				ResourceMap resourceMap = (ResourceMap)theEObject;
102
				Object result = caseResourceMap(resourceMap);
103
				if (result == null) result = defaultCase(theEObject);
104
				return result;
105
			}
106
			case ResourceMapPackage.RESOURCE_ENTRY: {
107
				ResourceEntry resourceEntry = (ResourceEntry)theEObject;
108
				Object result = caseResourceEntry(resourceEntry);
109
				if (result == null) result = defaultCase(theEObject);
110
				return result;
111
			}
112
			case ResourceMapPackage.PARENT_ENTRY: {
113
				ParentEntry parentEntry = (ParentEntry)theEObject;
114
				Object result = caseParentEntry(parentEntry);
115
				if (result == null) result = defaultCase(theEObject);
116
				return result;
117
			}
118
			case ResourceMapPackage.CHILD_ENTRY: {
119
				ChildEntry childEntry = (ChildEntry)theEObject;
120
				Object result = caseChildEntry(childEntry);
121
				if (result == null) result = defaultCase(theEObject);
122
				return result;
123
			}
124
			default: return defaultCase(theEObject);
125
		}
126
	}
127
128
	/**
129
	 * Returns the result of interpretting the object as an instance of '<em>Resource Map</em>'.
130
	 * <!-- begin-user-doc -->
131
	 * This implementation returns null;
132
	 * returning a non-null result will terminate the switch.
133
	 * <!-- end-user-doc -->
134
	 * @param object the target of the switch.
135
	 * @return the result of interpretting the object as an instance of '<em>Resource Map</em>'.
136
	 * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
137
	 * @generated
138
	 */
139
	public Object caseResourceMap(ResourceMap object) {
140
		return null;
141
	}
142
143
	/**
144
	 * Returns the result of interpretting the object as an instance of '<em>Resource Entry</em>'.
145
	 * <!-- begin-user-doc -->
146
	 * This implementation returns null;
147
	 * returning a non-null result will terminate the switch.
148
	 * <!-- end-user-doc -->
149
	 * @param object the target of the switch.
150
	 * @return the result of interpretting the object as an instance of '<em>Resource Entry</em>'.
151
	 * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
152
	 * @generated
153
	 */
154
	public Object caseResourceEntry(ResourceEntry object) {
155
		return null;
156
	}
157
158
	/**
159
	 * Returns the result of interpretting the object as an instance of '<em>Parent Entry</em>'.
160
	 * <!-- begin-user-doc -->
161
	 * This implementation returns null;
162
	 * returning a non-null result will terminate the switch.
163
	 * <!-- end-user-doc -->
164
	 * @param object the target of the switch.
165
	 * @return the result of interpretting the object as an instance of '<em>Parent Entry</em>'.
166
	 * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
167
	 * @generated
168
	 */
169
	public Object caseParentEntry(ParentEntry object) {
170
		return null;
171
	}
172
173
	/**
174
	 * Returns the result of interpretting the object as an instance of '<em>Child Entry</em>'.
175
	 * <!-- begin-user-doc -->
176
	 * This implementation returns null;
177
	 * returning a non-null result will terminate the switch.
178
	 * <!-- end-user-doc -->
179
	 * @param object the target of the switch.
180
	 * @return the result of interpretting the object as an instance of '<em>Child Entry</em>'.
181
	 * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
182
	 * @generated
183
	 */
184
	public Object caseChildEntry(ChildEntry object) {
185
		return null;
186
	}
187
188
	/**
189
	 * Returns the result of interpretting the object as an instance of '<em>EObject</em>'.
190
	 * <!-- begin-user-doc -->
191
	 * This implementation returns null;
192
	 * returning a non-null result will terminate the switch, but this is the last case anyway.
193
	 * <!-- end-user-doc -->
194
	 * @param object the target of the switch.
195
	 * @return the result of interpretting the object as an instance of '<em>EObject</em>'.
196
	 * @see #doSwitch(org.eclipse.emf.ecore.EObject)
197
	 * @generated
198
	 */
199
	public Object defaultCase(EObject object) {
200
		return null;
201
	}
202
203
} //ResourceMapSwitch
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resourcemap/util/ResourceMapAdapterFactory.java (-177 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
package org.eclipse.gmf.runtime.emf.core.internal.resourcemap.util;
13
14
import org.eclipse.emf.common.notify.Adapter;
15
import org.eclipse.emf.common.notify.Notifier;
16
import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl;
17
import org.eclipse.emf.ecore.EObject;
18
19
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ChildEntry;
20
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry;
21
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry;
22
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap;
23
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage;
24
25
/**
26
 * <!-- begin-user-doc -->
27
 * The <b>Adapter Factory</b> for the logical resource physical mapping metamodel.
28
 * <!-- end-user-doc -->
29
 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage
30
 * @generated
31
 */
32
public class ResourceMapAdapterFactory extends AdapterFactoryImpl {
33
	/**
34
	 * The cached model package.
35
	 * <!-- begin-user-doc -->
36
	 * <!-- end-user-doc -->
37
	 * @generated
38
	 */
39
	protected static ResourceMapPackage modelPackage;
40
41
	/**
42
	 * Creates an instance of the adapter factory.
43
	 * <!-- begin-user-doc -->
44
	 * <!-- end-user-doc -->
45
	 * @generated
46
	 */
47
	public ResourceMapAdapterFactory() {
48
		if (modelPackage == null) {
49
			modelPackage = ResourceMapPackage.eINSTANCE;
50
		}
51
	}
52
53
	/**
54
	 * Returns whether this factory is applicable for the type of the object.
55
	 * <!-- begin-user-doc -->
56
	 * This implementation returns <code>true</code> if the object is either the model's package or is an instance object of the model.
57
	 * <!-- end-user-doc -->
58
	 * @return whether this factory is applicable for the type of the object.
59
	 * @generated
60
	 */
61
	public boolean isFactoryForType(Object object) {
62
		if (object == modelPackage) {
63
			return true;
64
		}
65
		if (object instanceof EObject) {
66
			return ((EObject)object).eClass().getEPackage() == modelPackage;
67
		}
68
		return false;
69
	}
70
71
	/**
72
	 * The switch the delegates to the <code>createXXX</code> methods.
73
	 * <!-- begin-user-doc -->
74
	 * <!-- end-user-doc -->
75
	 * @generated
76
	 */
77
	protected ResourceMapSwitch modelSwitch =
78
		new ResourceMapSwitch() {
79
			public Object caseResourceMap(ResourceMap object) {
80
				return createResourceMapAdapter();
81
			}
82
			public Object caseResourceEntry(ResourceEntry object) {
83
				return createResourceEntryAdapter();
84
			}
85
			public Object caseParentEntry(ParentEntry object) {
86
				return createParentEntryAdapter();
87
			}
88
			public Object caseChildEntry(ChildEntry object) {
89
				return createChildEntryAdapter();
90
			}
91
			public Object defaultCase(EObject object) {
92
				return createEObjectAdapter();
93
			}
94
		};
95
96
	/**
97
	 * Creates an adapter for the <code>target</code>.
98
	 * <!-- begin-user-doc -->
99
	 * <!-- end-user-doc -->
100
	 * @param target the object to adapt.
101
	 * @return the adapter for the <code>target</code>.
102
	 * @generated
103
	 */
104
	public Adapter createAdapter(Notifier target) {
105
		return (Adapter)modelSwitch.doSwitch((EObject)target);
106
	}
107
108
109
	/**
110
	 * Creates a new adapter for an object of class '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap <em>Resource Map</em>}'.
111
	 * <!-- begin-user-doc -->
112
	 * This default implementation returns null so that we can easily ignore cases;
113
	 * it's useful to ignore a case when inheritance will catch all the cases anyway.
114
	 * <!-- end-user-doc -->
115
	 * @return the new adapter.
116
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap
117
	 * @generated
118
	 */
119
	public Adapter createResourceMapAdapter() {
120
		return null;
121
	}
122
123
	/**
124
	 * Creates a new adapter for an object of class '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry <em>Resource Entry</em>}'.
125
	 * <!-- begin-user-doc -->
126
	 * This default implementation returns null so that we can easily ignore cases;
127
	 * it's useful to ignore a case when inheritance will catch all the cases anyway.
128
	 * <!-- end-user-doc -->
129
	 * @return the new adapter.
130
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry
131
	 * @generated
132
	 */
133
	public Adapter createResourceEntryAdapter() {
134
		return null;
135
	}
136
137
	/**
138
	 * Creates a new adapter for an object of class '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry <em>Parent Entry</em>}'.
139
	 * <!-- begin-user-doc -->
140
	 * This default implementation returns null so that we can easily ignore cases;
141
	 * it's useful to ignore a case when inheritance will catch all the cases anyway.
142
	 * <!-- end-user-doc -->
143
	 * @return the new adapter.
144
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry
145
	 * @generated
146
	 */
147
	public Adapter createParentEntryAdapter() {
148
		return null;
149
	}
150
151
	/**
152
	 * Creates a new adapter for an object of class '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ChildEntry <em>Child Entry</em>}'.
153
	 * <!-- begin-user-doc -->
154
	 * This default implementation returns null so that we can easily ignore cases;
155
	 * it's useful to ignore a case when inheritance will catch all the cases anyway.
156
	 * <!-- end-user-doc -->
157
	 * @return the new adapter.
158
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ChildEntry
159
	 * @generated
160
	 */
161
	public Adapter createChildEntryAdapter() {
162
		return null;
163
	}
164
165
	/**
166
	 * Creates a new adapter for the default case.
167
	 * <!-- begin-user-doc -->
168
	 * This default implementation returns null.
169
	 * <!-- end-user-doc -->
170
	 * @return the new adapter.
171
	 * @generated
172
	 */
173
	public Adapter createEObjectAdapter() {
174
		return null;
175
	}
176
177
} //ResourceMapAdapterFactory
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resourcemap/impl/ChildEntryImpl.java (-221 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
package org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl;
13
14
import org.eclipse.emf.common.notify.Notification;
15
import org.eclipse.emf.ecore.EClass;
16
import org.eclipse.emf.ecore.EObject;
17
import org.eclipse.emf.ecore.EStructuralFeature;
18
import org.eclipse.emf.ecore.InternalEObject;
19
import org.eclipse.emf.ecore.impl.ENotificationImpl;
20
import org.eclipse.emf.ecore.impl.EObjectImpl;
21
22
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ChildEntry;
23
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap;
24
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage;
25
26
/**
27
 * <!-- begin-user-doc -->
28
 * An implementation of the model object '<em><b>Child Entry</b></em>'.
29
 * <!-- end-user-doc -->
30
 * <p>
31
 * The following features are implemented:
32
 * <ul>
33
 *   <li>{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl.ChildEntryImpl#getChildObject <em>Child Object</em>}</li>
34
 *   <li>{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl.ChildEntryImpl#getParentMap <em>Parent Map</em>}</li>
35
 * </ul>
36
 * </p>
37
 *
38
 * @generated
39
 */
40
public class ChildEntryImpl extends EObjectImpl implements ChildEntry {
41
	/**
42
	 * The cached value of the '{@link #getChildObject() <em>Child Object</em>}' reference.
43
	 * <!-- begin-user-doc -->
44
	 * <!-- end-user-doc -->
45
	 * @see #getChildObject()
46
	 * @generated
47
	 * @ordered
48
	 */
49
	protected EObject childObject = null;
50
51
	/**
52
	 * The cached value of the '{@link #getParentMap() <em>Parent Map</em>}' reference.
53
	 * <!-- begin-user-doc -->
54
	 * <!-- end-user-doc -->
55
	 * @see #getParentMap()
56
	 * @generated
57
	 * @ordered
58
	 */
59
	protected ResourceMap parentMap = null;
60
61
	/**
62
	 * <!-- begin-user-doc -->
63
	 * <!-- end-user-doc -->
64
	 * @generated
65
	 */
66
	protected ChildEntryImpl() {
67
		super();
68
	}
69
70
	/**
71
	 * <!-- begin-user-doc -->
72
	 * <!-- end-user-doc -->
73
	 * @generated
74
	 */
75
	protected EClass eStaticClass() {
76
		return ResourceMapPackage.eINSTANCE.getChildEntry();
77
	}
78
79
	/**
80
	 * <!-- begin-user-doc -->
81
	 * <!-- end-user-doc -->
82
	 * @generated
83
	 */
84
	public EObject getChildObject() {
85
		if (childObject != null && childObject.eIsProxy()) {
86
			EObject oldChildObject = childObject;
87
			childObject = eResolveProxy((InternalEObject)childObject);
88
			if (childObject != oldChildObject) {
89
				if (eNotificationRequired())
90
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, ResourceMapPackage.CHILD_ENTRY__CHILD_OBJECT, oldChildObject, childObject));
91
			}
92
		}
93
		return childObject;
94
	}
95
96
	/**
97
	 * <!-- begin-user-doc -->
98
	 * <!-- end-user-doc -->
99
	 * @generated
100
	 */
101
	public EObject basicGetChildObject() {
102
		return childObject;
103
	}
104
105
	/**
106
	 * <!-- begin-user-doc -->
107
	 * <!-- end-user-doc -->
108
	 * @generated
109
	 */
110
	public void setChildObject(EObject newChildObject) {
111
		EObject oldChildObject = childObject;
112
		childObject = newChildObject;
113
		if (eNotificationRequired())
114
			eNotify(new ENotificationImpl(this, Notification.SET, ResourceMapPackage.CHILD_ENTRY__CHILD_OBJECT, oldChildObject, childObject));
115
	}
116
117
	/**
118
	 * <!-- begin-user-doc -->
119
	 * <!-- end-user-doc -->
120
	 * @generated
121
	 */
122
	public ResourceMap getParentMap() {
123
		if (parentMap != null && parentMap.eIsProxy()) {
124
			ResourceMap oldParentMap = parentMap;
125
			parentMap = (ResourceMap)eResolveProxy((InternalEObject)parentMap);
126
			if (parentMap != oldParentMap) {
127
				if (eNotificationRequired())
128
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, ResourceMapPackage.CHILD_ENTRY__PARENT_MAP, oldParentMap, parentMap));
129
			}
130
		}
131
		return parentMap;
132
	}
133
134
	/**
135
	 * <!-- begin-user-doc -->
136
	 * <!-- end-user-doc -->
137
	 * @generated
138
	 */
139
	public ResourceMap basicGetParentMap() {
140
		return parentMap;
141
	}
142
143
	/**
144
	 * <!-- begin-user-doc -->
145
	 * <!-- end-user-doc -->
146
	 * @generated
147
	 */
148
	public void setParentMap(ResourceMap newParentMap) {
149
		ResourceMap oldParentMap = parentMap;
150
		parentMap = newParentMap;
151
		if (eNotificationRequired())
152
			eNotify(new ENotificationImpl(this, Notification.SET, ResourceMapPackage.CHILD_ENTRY__PARENT_MAP, oldParentMap, parentMap));
153
	}
154
155
	/**
156
	 * <!-- begin-user-doc -->
157
	 * <!-- end-user-doc -->
158
	 * @generated
159
	 */
160
	public Object eGet(EStructuralFeature eFeature, boolean resolve) {
161
		switch (eDerivedStructuralFeatureID(eFeature)) {
162
			case ResourceMapPackage.CHILD_ENTRY__CHILD_OBJECT:
163
				if (resolve) return getChildObject();
164
				return basicGetChildObject();
165
			case ResourceMapPackage.CHILD_ENTRY__PARENT_MAP:
166
				if (resolve) return getParentMap();
167
				return basicGetParentMap();
168
		}
169
		return eDynamicGet(eFeature, resolve);
170
	}
171
172
	/**
173
	 * <!-- begin-user-doc -->
174
	 * <!-- end-user-doc -->
175
	 * @generated
176
	 */
177
	public void eSet(EStructuralFeature eFeature, Object newValue) {
178
		switch (eDerivedStructuralFeatureID(eFeature)) {
179
			case ResourceMapPackage.CHILD_ENTRY__CHILD_OBJECT:
180
				setChildObject((EObject)newValue);
181
				return;
182
			case ResourceMapPackage.CHILD_ENTRY__PARENT_MAP:
183
				setParentMap((ResourceMap)newValue);
184
				return;
185
		}
186
		eDynamicSet(eFeature, newValue);
187
	}
188
189
	/**
190
	 * <!-- begin-user-doc -->
191
	 * <!-- end-user-doc -->
192
	 * @generated
193
	 */
194
	public void eUnset(EStructuralFeature eFeature) {
195
		switch (eDerivedStructuralFeatureID(eFeature)) {
196
			case ResourceMapPackage.CHILD_ENTRY__CHILD_OBJECT:
197
				setChildObject((EObject)null);
198
				return;
199
			case ResourceMapPackage.CHILD_ENTRY__PARENT_MAP:
200
				setParentMap((ResourceMap)null);
201
				return;
202
		}
203
		eDynamicUnset(eFeature);
204
	}
205
206
	/**
207
	 * <!-- begin-user-doc -->
208
	 * <!-- end-user-doc -->
209
	 * @generated
210
	 */
211
	public boolean eIsSet(EStructuralFeature eFeature) {
212
		switch (eDerivedStructuralFeatureID(eFeature)) {
213
			case ResourceMapPackage.CHILD_ENTRY__CHILD_OBJECT:
214
				return childObject != null;
215
			case ResourceMapPackage.CHILD_ENTRY__PARENT_MAP:
216
				return parentMap != null;
217
		}
218
		return eDynamicIsSet(eFeature);
219
	}
220
221
} //ChildEntryImpl
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resourcemap/impl/ResourceMapPackageImpl.java (-398 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
package org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl;
13
14
import org.eclipse.emf.ecore.EAttribute;
15
import org.eclipse.emf.ecore.EClass;
16
import org.eclipse.emf.ecore.EOperation;
17
import org.eclipse.emf.ecore.EPackage;
18
import org.eclipse.emf.ecore.EReference;
19
import org.eclipse.emf.ecore.impl.EPackageImpl;
20
21
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ChildEntry;
22
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry;
23
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry;
24
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap;
25
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapFactory;
26
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage;
27
28
/**
29
 * <!-- begin-user-doc -->
30
 * An implementation of the model <b>Package</b>.
31
 * <!-- end-user-doc -->
32
 * @generated
33
 */
34
public class ResourceMapPackageImpl extends EPackageImpl implements ResourceMapPackage {
35
	/**
36
	 * <!-- begin-user-doc -->
37
	 * <!-- end-user-doc -->
38
	 * @generated
39
	 */
40
	private EClass resourceMapEClass = null;
41
42
	/**
43
	 * <!-- begin-user-doc -->
44
	 * <!-- end-user-doc -->
45
	 * @generated
46
	 */
47
	private EClass resourceEntryEClass = null;
48
49
	/**
50
	 * <!-- begin-user-doc -->
51
	 * <!-- end-user-doc -->
52
	 * @generated
53
	 */
54
	private EClass parentEntryEClass = null;
55
56
	/**
57
	 * <!-- begin-user-doc -->
58
	 * <!-- end-user-doc -->
59
	 * @generated
60
	 */
61
	private EClass childEntryEClass = null;
62
63
	/**
64
	 * Creates an instance of the model <b>Package</b>, registered with
65
	 * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package
66
	 * package URI value.
67
	 * <p>Note: the correct way to create the package is via the static
68
	 * factory method {@link #init init()}, which also performs
69
	 * initialization of the package, or returns the registered package,
70
	 * if one already exists.
71
	 * <!-- begin-user-doc -->
72
	 * <!-- end-user-doc -->
73
	 * @see org.eclipse.emf.ecore.EPackage.Registry
74
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage#eNS_URI
75
	 * @see #init()
76
	 * @generated
77
	 */
78
	private ResourceMapPackageImpl() {
79
		super(eNS_URI, ResourceMapFactory.eINSTANCE);
80
	}
81
82
	/**
83
	 * <!-- begin-user-doc -->
84
	 * <!-- end-user-doc -->
85
	 * @generated
86
	 */
87
	private static boolean isInited = false;
88
89
	/**
90
	 * Creates, registers, and initializes the <b>Package</b> for this
91
	 * model, and for any others upon which it depends.  Simple
92
	 * dependencies are satisfied by calling this method on all
93
	 * dependent packages before doing anything else.  This method drives
94
	 * initialization for interdependent packages directly, in parallel
95
	 * with this package, itself.
96
	 * <p>Of this package and its interdependencies, all packages which
97
	 * have not yet been registered by their URI values are first created
98
	 * and registered.  The packages are then initialized in two steps:
99
	 * meta-model objects for all of the packages are created before any
100
	 * are initialized, since one package's meta-model objects may refer to
101
	 * those of another.
102
	 * <p>Invocation of this method will not affect any packages that have
103
	 * already been initialized.
104
	 * <!-- begin-user-doc -->
105
	 * <!-- end-user-doc -->
106
	 * @see #eNS_URI
107
	 * @see #createPackageContents()
108
	 * @see #initializePackageContents()
109
	 * @generated
110
	 */
111
	public static ResourceMapPackage init() {
112
		if (isInited) return (ResourceMapPackage)EPackage.Registry.INSTANCE.getEPackage(ResourceMapPackage.eNS_URI);
113
114
		// Obtain or create and register package
115
		ResourceMapPackageImpl theResourceMapPackage = (ResourceMapPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(eNS_URI) instanceof ResourceMapPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(eNS_URI) : new ResourceMapPackageImpl());
116
117
		isInited = true;
118
119
		// Create package meta-data objects
120
		theResourceMapPackage.createPackageContents();
121
122
		// Initialize created meta-data
123
		theResourceMapPackage.initializePackageContents();
124
125
		// Mark meta-data to indicate it can't be changed
126
		theResourceMapPackage.freeze();
127
128
		return theResourceMapPackage;
129
	}
130
131
	/**
132
	 * <!-- begin-user-doc -->
133
	 * <!-- end-user-doc -->
134
	 * @generated
135
	 */
136
	public EClass getResourceMap() {
137
		return resourceMapEClass;
138
	}
139
140
	/**
141
	 * <!-- begin-user-doc -->
142
	 * <!-- end-user-doc -->
143
	 * @generated
144
	 */
145
	public EReference getResourceMap_RootMap() {
146
		return (EReference)resourceMapEClass.getEStructuralFeatures().get(0);
147
	}
148
149
	/**
150
	 * <!-- begin-user-doc -->
151
	 * <!-- end-user-doc -->
152
	 * @generated
153
	 */
154
	public EReference getResourceMap_ParentEntries() {
155
		return (EReference)resourceMapEClass.getEStructuralFeatures().get(1);
156
	}
157
158
	/**
159
	 * <!-- begin-user-doc -->
160
	 * <!-- end-user-doc -->
161
	 * @generated
162
	 */
163
	public EReference getResourceMap_ChildEntries() {
164
		return (EReference)resourceMapEClass.getEStructuralFeatures().get(2);
165
	}
166
167
	/**
168
	 * <!-- begin-user-doc -->
169
	 * <!-- end-user-doc -->
170
	 * @generated
171
	 */
172
	public EClass getResourceEntry() {
173
		return resourceEntryEClass;
174
	}
175
176
	/**
177
	 * <!-- begin-user-doc -->
178
	 * <!-- end-user-doc -->
179
	 * @generated
180
	 */
181
	public EAttribute getResourceEntry_Resource() {
182
		return (EAttribute)resourceEntryEClass.getEStructuralFeatures().get(0);
183
	}
184
185
	/**
186
	 * <!-- begin-user-doc -->
187
	 * <!-- end-user-doc -->
188
	 * @generated
189
	 */
190
	public EAttribute getResourceEntry_ChildPosition() {
191
		return (EAttribute)resourceEntryEClass.getEStructuralFeatures().get(1);
192
	}
193
194
	/**
195
	 * <!-- begin-user-doc -->
196
	 * <!-- end-user-doc -->
197
	 * @generated
198
	 */
199
	public EReference getResourceEntry_ChildObject() {
200
		return (EReference)resourceEntryEClass.getEStructuralFeatures().get(2);
201
	}
202
203
	/**
204
	 * <!-- begin-user-doc -->
205
	 * <!-- end-user-doc -->
206
	 * @generated
207
	 */
208
	public EReference getResourceEntry_ParentEntry() {
209
		return (EReference)resourceEntryEClass.getEStructuralFeatures().get(3);
210
	}
211
212
	/**
213
	 * <!-- begin-user-doc -->
214
	 * <!-- end-user-doc -->
215
	 * @generated
216
	 */
217
	public EClass getParentEntry() {
218
		return parentEntryEClass;
219
	}
220
221
	/**
222
	 * <!-- begin-user-doc -->
223
	 * <!-- end-user-doc -->
224
	 * @generated
225
	 */
226
	public EReference getParentEntry_ParentObject() {
227
		return (EReference)parentEntryEClass.getEStructuralFeatures().get(0);
228
	}
229
230
	/**
231
	 * <!-- begin-user-doc -->
232
	 * <!-- end-user-doc -->
233
	 * @generated
234
	 */
235
	public EReference getParentEntry_ChildSlot() {
236
		return (EReference)parentEntryEClass.getEStructuralFeatures().get(1);
237
	}
238
239
	/**
240
	 * <!-- begin-user-doc -->
241
	 * <!-- end-user-doc -->
242
	 * @generated
243
	 */
244
	public EReference getParentEntry_ResourceEntries() {
245
		return (EReference)parentEntryEClass.getEStructuralFeatures().get(2);
246
	}
247
248
	/**
249
	 * <!-- begin-user-doc -->
250
	 * <!-- end-user-doc -->
251
	 * @generated
252
	 */
253
	public EReference getParentEntry_ResourceMap() {
254
		return (EReference)parentEntryEClass.getEStructuralFeatures().get(3);
255
	}
256
257
	/**
258
	 * <!-- begin-user-doc -->
259
	 * <!-- end-user-doc -->
260
	 * @generated
261
	 */
262
	public EClass getChildEntry() {
263
		return childEntryEClass;
264
	}
265
266
	/**
267
	 * <!-- begin-user-doc -->
268
	 * <!-- end-user-doc -->
269
	 * @generated
270
	 */
271
	public EReference getChildEntry_ChildObject() {
272
		return (EReference)childEntryEClass.getEStructuralFeatures().get(0);
273
	}
274
275
	/**
276
	 * <!-- begin-user-doc -->
277
	 * <!-- end-user-doc -->
278
	 * @generated
279
	 */
280
	public EReference getChildEntry_ParentMap() {
281
		return (EReference)childEntryEClass.getEStructuralFeatures().get(1);
282
	}
283
284
	/**
285
	 * <!-- begin-user-doc -->
286
	 * <!-- end-user-doc -->
287
	 * @generated
288
	 */
289
	public ResourceMapFactory getResourceMapFactory() {
290
		return (ResourceMapFactory)getEFactoryInstance();
291
	}
292
293
	/**
294
	 * <!-- begin-user-doc -->
295
	 * <!-- end-user-doc -->
296
	 * @generated
297
	 */
298
	private boolean isCreated = false;
299
300
	/**
301
	 * Creates the meta-model objects for the package.  This method is
302
	 * guarded to have no affect on any invocation but its first.
303
	 * <!-- begin-user-doc -->
304
	 * <!-- end-user-doc -->
305
	 * @generated
306
	 */
307
	public void createPackageContents() {
308
		if (isCreated) return;
309
		isCreated = true;
310
311
		// Create classes and their features
312
		resourceMapEClass = createEClass(RESOURCE_MAP);
313
		createEReference(resourceMapEClass, RESOURCE_MAP__ROOT_MAP);
314
		createEReference(resourceMapEClass, RESOURCE_MAP__PARENT_ENTRIES);
315
		createEReference(resourceMapEClass, RESOURCE_MAP__CHILD_ENTRIES);
316
317
		resourceEntryEClass = createEClass(RESOURCE_ENTRY);
318
		createEAttribute(resourceEntryEClass, RESOURCE_ENTRY__RESOURCE);
319
		createEAttribute(resourceEntryEClass, RESOURCE_ENTRY__CHILD_POSITION);
320
		createEReference(resourceEntryEClass, RESOURCE_ENTRY__CHILD_OBJECT);
321
		createEReference(resourceEntryEClass, RESOURCE_ENTRY__PARENT_ENTRY);
322
323
		parentEntryEClass = createEClass(PARENT_ENTRY);
324
		createEReference(parentEntryEClass, PARENT_ENTRY__PARENT_OBJECT);
325
		createEReference(parentEntryEClass, PARENT_ENTRY__CHILD_SLOT);
326
		createEReference(parentEntryEClass, PARENT_ENTRY__RESOURCE_ENTRIES);
327
		createEReference(parentEntryEClass, PARENT_ENTRY__RESOURCE_MAP);
328
329
		childEntryEClass = createEClass(CHILD_ENTRY);
330
		createEReference(childEntryEClass, CHILD_ENTRY__CHILD_OBJECT);
331
		createEReference(childEntryEClass, CHILD_ENTRY__PARENT_MAP);
332
	}
333
334
	/**
335
	 * <!-- begin-user-doc -->
336
	 * <!-- end-user-doc -->
337
	 * @generated
338
	 */
339
	private boolean isInitialized = false;
340
341
	/**
342
	 * Complete the initialization of the package and its meta-model.  This
343
	 * method is guarded to have no affect on any invocation but its first.
344
	 * <!-- begin-user-doc -->
345
	 * <!-- end-user-doc -->
346
	 * @generated
347
	 */
348
	public void initializePackageContents() {
349
		if (isInitialized) return;
350
		isInitialized = true;
351
352
		// Initialize package
353
		setName(eNAME);
354
		setNsPrefix(eNS_PREFIX);
355
		setNsURI(eNS_URI);
356
357
		// Add supertypes to classes
358
359
		// Initialize classes and features; add operations and parameters
360
		initEClass(resourceMapEClass, ResourceMap.class, "ResourceMap", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$
361
		initEReference(getResourceMap_RootMap(), this.getResourceMap(), null, "rootMap", null, 0, 1, ResourceMap.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
362
		initEReference(getResourceMap_ParentEntries(), this.getParentEntry(), null, "parentEntries", null, 0, -1, ResourceMap.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, !IS_ORDERED); //$NON-NLS-1$
363
		initEReference(getResourceMap_ChildEntries(), this.getChildEntry(), null, "childEntries", null, 0, -1, ResourceMap.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, !IS_ORDERED); //$NON-NLS-1$
364
365
		EOperation op = addEOperation(resourceMapEClass, this.getParentEntry(), "getParentEntry"); //$NON-NLS-1$
366
		addEParameter(op, ecorePackage.getEObject(), "parent"); //$NON-NLS-1$
367
		addEParameter(op, ecorePackage.getEReference(), "slot"); //$NON-NLS-1$
368
369
		op = addEOperation(resourceMapEClass, this.getResourceEntry(), "getResourceEntry"); //$NON-NLS-1$
370
		addEParameter(op, ecorePackage.getEObject(), "child"); //$NON-NLS-1$
371
372
		op = addEOperation(resourceMapEClass, this.getResourceMap(), "getParentMap"); //$NON-NLS-1$
373
		addEParameter(op, ecorePackage.getEObject(), "child"); //$NON-NLS-1$
374
375
		initEClass(resourceEntryEClass, ResourceEntry.class, "ResourceEntry", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$
376
		initEAttribute(getResourceEntry_Resource(), ecorePackage.getEResource(), "resource", null, 0, 1, ResourceEntry.class, IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
377
		initEAttribute(getResourceEntry_ChildPosition(), ecorePackage.getEInt(), "childPosition", "-1", 0, 1, ResourceEntry.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$ //$NON-NLS-2$
378
		initEReference(getResourceEntry_ChildObject(), ecorePackage.getEObject(), null, "childObject", null, 1, 1, ResourceEntry.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
379
		initEReference(getResourceEntry_ParentEntry(), this.getParentEntry(), null, "parentEntry", null, 0, 1, ResourceEntry.class, IS_TRANSIENT, IS_VOLATILE, !IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
380
381
		initEClass(parentEntryEClass, ParentEntry.class, "ParentEntry", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$
382
		initEReference(getParentEntry_ParentObject(), ecorePackage.getEObject(), null, "parentObject", null, 0, 1, ParentEntry.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
383
		initEReference(getParentEntry_ChildSlot(), ecorePackage.getEReference(), null, "childSlot", null, 0, 1, ParentEntry.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
384
		initEReference(getParentEntry_ResourceEntries(), this.getResourceEntry(), null, "resourceEntries", null, 1, -1, ParentEntry.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
385
		initEReference(getParentEntry_ResourceMap(), this.getResourceMap(), null, "resourceMap", null, 0, 1, ParentEntry.class, IS_TRANSIENT, IS_VOLATILE, !IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
386
387
		op = addEOperation(parentEntryEClass, this.getResourceEntry(), "getResourceEntry"); //$NON-NLS-1$
388
		addEParameter(op, ecorePackage.getEObject(), "child"); //$NON-NLS-1$
389
390
		initEClass(childEntryEClass, ChildEntry.class, "ChildEntry", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$
391
		initEReference(getChildEntry_ChildObject(), ecorePackage.getEObject(), null, "childObject", null, 1, 1, ChildEntry.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
392
		initEReference(getChildEntry_ParentMap(), this.getResourceMap(), null, "parentMap", null, 1, 1, ChildEntry.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
393
394
		// Create resource
395
		createResource(eNS_URI);
396
	}
397
398
} //ResourceMapPackageImpl
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resourcemap/impl/ResourceMapFactoryImpl.java (-117 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
package org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl;
13
14
import org.eclipse.emf.ecore.EClass;
15
import org.eclipse.emf.ecore.EObject;
16
import org.eclipse.emf.ecore.impl.EFactoryImpl;
17
18
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ChildEntry;
19
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry;
20
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry;
21
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap;
22
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapFactory;
23
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage;
24
25
/**
26
 * <!-- begin-user-doc -->
27
 * An implementation of the model <b>Factory</b>.
28
 * <!-- end-user-doc -->
29
 * @generated
30
 */
31
public class ResourceMapFactoryImpl extends EFactoryImpl implements ResourceMapFactory {
32
	/**
33
	 * Creates an instance of the factory.
34
	 * <!-- begin-user-doc -->
35
	 * <!-- end-user-doc -->
36
	 * @generated
37
	 */
38
	public ResourceMapFactoryImpl() {
39
		super();
40
	}
41
42
	/**
43
	 * <!-- begin-user-doc -->
44
	 * <!-- end-user-doc -->
45
	 * @generated
46
	 */
47
	public EObject create(EClass eClass) {
48
		switch (eClass.getClassifierID()) {
49
			case ResourceMapPackage.RESOURCE_MAP: return createResourceMap();
50
			case ResourceMapPackage.RESOURCE_ENTRY: return createResourceEntry();
51
			case ResourceMapPackage.PARENT_ENTRY: return createParentEntry();
52
			case ResourceMapPackage.CHILD_ENTRY: return createChildEntry();
53
			default:
54
				throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier"); //$NON-NLS-1$ //$NON-NLS-2$
55
		}
56
	}
57
58
	/**
59
	 * <!-- begin-user-doc -->
60
	 * <!-- end-user-doc -->
61
	 * @generated
62
	 */
63
	public ResourceMap createResourceMap() {
64
		ResourceMapImpl resourceMap = new ResourceMapImpl();
65
		return resourceMap;
66
	}
67
68
	/**
69
	 * <!-- begin-user-doc -->
70
	 * <!-- end-user-doc -->
71
	 * @generated
72
	 */
73
	public ResourceEntry createResourceEntry() {
74
		ResourceEntryImpl resourceEntry = new ResourceEntryImpl();
75
		return resourceEntry;
76
	}
77
78
	/**
79
	 * <!-- begin-user-doc -->
80
	 * <!-- end-user-doc -->
81
	 * @generated
82
	 */
83
	public ParentEntry createParentEntry() {
84
		ParentEntryImpl parentEntry = new ParentEntryImpl();
85
		return parentEntry;
86
	}
87
88
	/**
89
	 * <!-- begin-user-doc -->
90
	 * <!-- end-user-doc -->
91
	 * @generated
92
	 */
93
	public ChildEntry createChildEntry() {
94
		ChildEntryImpl childEntry = new ChildEntryImpl();
95
		return childEntry;
96
	}
97
98
	/**
99
	 * <!-- begin-user-doc -->
100
	 * <!-- end-user-doc -->
101
	 * @generated
102
	 */
103
	public ResourceMapPackage getResourceMapPackage() {
104
		return (ResourceMapPackage)getEPackage();
105
	}
106
107
	/**
108
	 * <!-- begin-user-doc -->
109
	 * <!-- end-user-doc -->
110
	 * @deprecated
111
	 * @generated
112
	 */
113
	public static ResourceMapPackage getPackage() {
114
		return ResourceMapPackage.eINSTANCE;
115
	}
116
117
} //ResourceMapFactoryImpl
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resourcemap/impl/ResourceMapImpl.java (-338 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
package org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl;
13
14
import java.util.Collection;
15
import java.util.Iterator;
16
17
import org.eclipse.emf.common.notify.Notification;
18
import org.eclipse.emf.common.notify.NotificationChain;
19
import org.eclipse.emf.common.util.EList;
20
import org.eclipse.emf.ecore.EClass;
21
import org.eclipse.emf.ecore.EObject;
22
import org.eclipse.emf.ecore.EReference;
23
import org.eclipse.emf.ecore.EStructuralFeature;
24
import org.eclipse.emf.ecore.InternalEObject;
25
import org.eclipse.emf.ecore.impl.ENotificationImpl;
26
import org.eclipse.emf.ecore.impl.EObjectImpl;
27
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
28
import org.eclipse.emf.ecore.util.InternalEList;
29
30
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ChildEntry;
31
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry;
32
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry;
33
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap;
34
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage;
35
36
/**
37
 * <!-- begin-user-doc -->
38
 * An implementation of the model object '<em><b>Resource Map</b></em>'.
39
 * <!-- end-user-doc -->
40
 * <p>
41
 * The following features are implemented:
42
 * <ul>
43
 *   <li>{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl.ResourceMapImpl#getRootMap <em>Root Map</em>}</li>
44
 *   <li>{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl.ResourceMapImpl#getParentEntries <em>Parent Entries</em>}</li>
45
 *   <li>{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl.ResourceMapImpl#getChildEntries <em>Child Entries</em>}</li>
46
 * </ul>
47
 * </p>
48
 *
49
 * @generated
50
 */
51
public class ResourceMapImpl extends EObjectImpl implements ResourceMap {
52
	/**
53
	 * The cached value of the '{@link #getRootMap() <em>Root Map</em>}' reference.
54
	 * <!-- begin-user-doc -->
55
	 * <!-- end-user-doc -->
56
	 * @see #getRootMap()
57
	 * @generated
58
	 * @ordered
59
	 */
60
	protected ResourceMap rootMap = null;
61
62
	/**
63
	 * The cached value of the '{@link #getParentEntries() <em>Parent Entries</em>}' containment reference list.
64
	 * <!-- begin-user-doc -->
65
	 * <!-- end-user-doc -->
66
	 * @see #getParentEntries()
67
	 * @generated
68
	 * @ordered
69
	 */
70
	protected EList parentEntries = null;
71
72
	/**
73
	 * The cached value of the '{@link #getChildEntries() <em>Child Entries</em>}' containment reference list.
74
	 * <!-- begin-user-doc -->
75
	 * <!-- end-user-doc -->
76
	 * @see #getChildEntries()
77
	 * @generated
78
	 * @ordered
79
	 */
80
	protected EList childEntries = null;
81
82
	/**
83
	 * <!-- begin-user-doc -->
84
	 * <!-- end-user-doc -->
85
	 * @generated
86
	 */
87
	protected ResourceMapImpl() {
88
		super();
89
	}
90
91
	/**
92
	 * <!-- begin-user-doc -->
93
	 * <!-- end-user-doc -->
94
	 * @generated
95
	 */
96
	protected EClass eStaticClass() {
97
		return ResourceMapPackage.eINSTANCE.getResourceMap();
98
	}
99
100
	/**
101
	 * <!-- begin-user-doc -->
102
	 * <!-- end-user-doc -->
103
	 * @generated
104
	 */
105
	public ResourceMap getRootMap() {
106
		if (rootMap != null && rootMap.eIsProxy()) {
107
			ResourceMap oldRootMap = rootMap;
108
			rootMap = (ResourceMap)eResolveProxy((InternalEObject)rootMap);
109
			if (rootMap != oldRootMap) {
110
				if (eNotificationRequired())
111
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, ResourceMapPackage.RESOURCE_MAP__ROOT_MAP, oldRootMap, rootMap));
112
			}
113
		}
114
		return rootMap;
115
	}
116
117
	/**
118
	 * <!-- begin-user-doc -->
119
	 * <!-- end-user-doc -->
120
	 * @generated
121
	 */
122
	public ResourceMap basicGetRootMap() {
123
		return rootMap;
124
	}
125
126
	/**
127
	 * <!-- begin-user-doc -->
128
	 * <!-- end-user-doc -->
129
	 * @generated
130
	 */
131
	public void setRootMap(ResourceMap newRootMap) {
132
		ResourceMap oldRootMap = rootMap;
133
		rootMap = newRootMap;
134
		if (eNotificationRequired())
135
			eNotify(new ENotificationImpl(this, Notification.SET, ResourceMapPackage.RESOURCE_MAP__ROOT_MAP, oldRootMap, rootMap));
136
	}
137
138
	/**
139
	 * <!-- begin-user-doc -->
140
	 * <!-- end-user-doc -->
141
	 * @generated
142
	 */
143
	public EList getParentEntries() {
144
		if (parentEntries == null) {
145
			parentEntries = new EObjectContainmentEList(ParentEntry.class, this, ResourceMapPackage.RESOURCE_MAP__PARENT_ENTRIES);
146
		}
147
		return parentEntries;
148
	}
149
150
	/**
151
	 * <!-- begin-user-doc -->
152
	 * <!-- end-user-doc -->
153
	 * @generated
154
	 */
155
	public EList getChildEntries() {
156
		if (childEntries == null) {
157
			childEntries = new EObjectContainmentEList(ChildEntry.class, this, ResourceMapPackage.RESOURCE_MAP__CHILD_ENTRIES);
158
		}
159
		return childEntries;
160
	}
161
162
	/**
163
	 * <!-- begin-user-doc -->
164
	 * <!-- end-user-doc -->
165
	 * @generated NOT
166
	 */
167
	public ParentEntry getParentEntry(EObject parent, EReference slot) {
168
		ParentEntry result = null;
169
		
170
		for (Iterator iter = getParentEntries().iterator();
171
				(result == null) && iter.hasNext();) {
172
			
173
			ParentEntry next = (ParentEntry) iter.next();
174
			
175
			if ((next.getParentObject() == parent) && (next.getChildSlot() == slot)) {
176
				result = next;
177
			}
178
		}
179
		
180
		return result;
181
	}
182
183
	/**
184
	 * <!-- begin-user-doc -->
185
	 * <!-- end-user-doc -->
186
	 * @generated NOT
187
	 */
188
	public ResourceEntry getResourceEntry(EObject child) {
189
		ResourceEntry result = null;
190
		
191
		// do not attempt to find the correct parent entry by the child's
192
		//   eContainer and eContainmentFeature, as it may not have either
193
		//   of these at this moment, or they may be different than expected
194
		for (Iterator iter = getParentEntries().iterator();
195
				(result == null) && iter.hasNext();) {
196
			
197
			ParentEntry parentEntry = (ParentEntry) iter.next();
198
			
199
			result = parentEntry.getResourceEntry(child);
200
		}
201
		
202
		return result;
203
	}
204
205
	/**
206
	 * <!-- begin-user-doc -->
207
	 * <!-- end-user-doc -->
208
	 * @generated NOT
209
	 */
210
	public ResourceMap getParentMap(EObject child) {
211
		ResourceMap result = null;
212
		ChildEntry childEntry = getChildEntry(child);
213
		
214
		if (childEntry != null) {
215
			result = childEntry.getParentMap();
216
		}
217
		
218
		return result;
219
	}
220
221
	/**
222
	 * <!-- begin-user-doc -->
223
	 * <!-- end-user-doc -->
224
	 * @generated NOT
225
	 */
226
	public ChildEntry getChildEntry(EObject child) {
227
		ChildEntry result = null;
228
		
229
		for (Iterator iter = getChildEntries().iterator();
230
				(result == null) && iter.hasNext();) {
231
			
232
			ChildEntry next = (ChildEntry) iter.next();
233
			
234
			if (next.getChildObject() == child) {
235
				result = next;
236
			}
237
		}
238
		
239
		return result;
240
	}
241
242
	/**
243
	 * <!-- begin-user-doc -->
244
	 * <!-- end-user-doc -->
245
	 * @generated
246
	 */
247
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, Class baseClass, NotificationChain msgs) {
248
		if (featureID >= 0) {
249
			switch (eDerivedStructuralFeatureID(featureID, baseClass)) {
250
				case ResourceMapPackage.RESOURCE_MAP__PARENT_ENTRIES:
251
					return ((InternalEList)getParentEntries()).basicRemove(otherEnd, msgs);
252
				case ResourceMapPackage.RESOURCE_MAP__CHILD_ENTRIES:
253
					return ((InternalEList)getChildEntries()).basicRemove(otherEnd, msgs);
254
				default:
255
					return eDynamicInverseRemove(otherEnd, featureID, baseClass, msgs);
256
			}
257
		}
258
		return eBasicSetContainer(null, featureID, msgs);
259
	}
260
261
	/**
262
	 * <!-- begin-user-doc -->
263
	 * <!-- end-user-doc -->
264
	 * @generated
265
	 */
266
	public Object eGet(EStructuralFeature eFeature, boolean resolve) {
267
		switch (eDerivedStructuralFeatureID(eFeature)) {
268
			case ResourceMapPackage.RESOURCE_MAP__ROOT_MAP:
269
				if (resolve) return getRootMap();
270
				return basicGetRootMap();
271
			case ResourceMapPackage.RESOURCE_MAP__PARENT_ENTRIES:
272
				return getParentEntries();
273
			case ResourceMapPackage.RESOURCE_MAP__CHILD_ENTRIES:
274
				return getChildEntries();
275
		}
276
		return eDynamicGet(eFeature, resolve);
277
	}
278
279
	/**
280
	 * <!-- begin-user-doc -->
281
	 * <!-- end-user-doc -->
282
	 * @generated
283
	 */
284
	public void eSet(EStructuralFeature eFeature, Object newValue) {
285
		switch (eDerivedStructuralFeatureID(eFeature)) {
286
			case ResourceMapPackage.RESOURCE_MAP__ROOT_MAP:
287
				setRootMap((ResourceMap)newValue);
288
				return;
289
			case ResourceMapPackage.RESOURCE_MAP__PARENT_ENTRIES:
290
				getParentEntries().clear();
291
				getParentEntries().addAll((Collection)newValue);
292
				return;
293
			case ResourceMapPackage.RESOURCE_MAP__CHILD_ENTRIES:
294
				getChildEntries().clear();
295
				getChildEntries().addAll((Collection)newValue);
296
				return;
297
		}
298
		eDynamicSet(eFeature, newValue);
299
	}
300
301
	/**
302
	 * <!-- begin-user-doc -->
303
	 * <!-- end-user-doc -->
304
	 * @generated
305
	 */
306
	public void eUnset(EStructuralFeature eFeature) {
307
		switch (eDerivedStructuralFeatureID(eFeature)) {
308
			case ResourceMapPackage.RESOURCE_MAP__ROOT_MAP:
309
				setRootMap((ResourceMap)null);
310
				return;
311
			case ResourceMapPackage.RESOURCE_MAP__PARENT_ENTRIES:
312
				getParentEntries().clear();
313
				return;
314
			case ResourceMapPackage.RESOURCE_MAP__CHILD_ENTRIES:
315
				getChildEntries().clear();
316
				return;
317
		}
318
		eDynamicUnset(eFeature);
319
	}
320
321
	/**
322
	 * <!-- begin-user-doc -->
323
	 * <!-- end-user-doc -->
324
	 * @generated
325
	 */
326
	public boolean eIsSet(EStructuralFeature eFeature) {
327
		switch (eDerivedStructuralFeatureID(eFeature)) {
328
			case ResourceMapPackage.RESOURCE_MAP__ROOT_MAP:
329
				return rootMap != null;
330
			case ResourceMapPackage.RESOURCE_MAP__PARENT_ENTRIES:
331
				return parentEntries != null && !parentEntries.isEmpty();
332
			case ResourceMapPackage.RESOURCE_MAP__CHILD_ENTRIES:
333
				return childEntries != null && !childEntries.isEmpty();
334
		}
335
		return eDynamicIsSet(eFeature);
336
	}
337
338
} //ResourceMapImpl
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resourcemap/impl/ResourceEntryImpl.java (-312 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
package org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl;
13
14
import org.eclipse.emf.common.notify.Notification;
15
import org.eclipse.emf.ecore.EClass;
16
import org.eclipse.emf.ecore.EObject;
17
import org.eclipse.emf.ecore.EStructuralFeature;
18
import org.eclipse.emf.ecore.InternalEObject;
19
import org.eclipse.emf.ecore.impl.ENotificationImpl;
20
import org.eclipse.emf.ecore.impl.EObjectImpl;
21
import org.eclipse.emf.ecore.resource.Resource;
22
23
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry;
24
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry;
25
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage;
26
27
/**
28
 * <!-- begin-user-doc -->
29
 * An implementation of the model object '<em><b>Resource Entry</b></em>'.
30
 * <!-- end-user-doc -->
31
 * <p>
32
 * The following features are implemented:
33
 * <ul>
34
 *   <li>{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl.ResourceEntryImpl#getResource <em>Resource</em>}</li>
35
 *   <li>{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl.ResourceEntryImpl#getChildPosition <em>Child Position</em>}</li>
36
 *   <li>{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl.ResourceEntryImpl#getChildObject <em>Child Object</em>}</li>
37
 *   <li>{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl.ResourceEntryImpl#getParentEntry <em>Parent Entry</em>}</li>
38
 * </ul>
39
 * </p>
40
 *
41
 * @generated
42
 */
43
public class ResourceEntryImpl extends EObjectImpl implements ResourceEntry {
44
	/**
45
	 * The default value of the '{@link #getResource() <em>Resource</em>}' attribute.
46
	 * <!-- begin-user-doc -->
47
	 * <!-- end-user-doc -->
48
	 * @see #getResource()
49
	 * @generated
50
	 * @ordered
51
	 */
52
	protected static final Resource RESOURCE_EDEFAULT = null;
53
54
	/**
55
	 * The cached value of the '{@link #getResource() <em>Resource</em>}' attribute.
56
	 * <!-- begin-user-doc -->
57
	 * <!-- end-user-doc -->
58
	 * @see #getResource()
59
	 * @generated
60
	 * @ordered
61
	 */
62
	protected Resource resource = RESOURCE_EDEFAULT;
63
64
	/**
65
	 * The default value of the '{@link #getChildPosition() <em>Child Position</em>}' attribute.
66
	 * <!-- begin-user-doc -->
67
	 * <!-- end-user-doc -->
68
	 * @see #getChildPosition()
69
	 * @generated
70
	 * @ordered
71
	 */
72
	protected static final int CHILD_POSITION_EDEFAULT = -1;
73
74
	/**
75
	 * The cached value of the '{@link #getChildPosition() <em>Child Position</em>}' attribute.
76
	 * <!-- begin-user-doc -->
77
	 * <!-- end-user-doc -->
78
	 * @see #getChildPosition()
79
	 * @generated
80
	 * @ordered
81
	 */
82
	protected int childPosition = CHILD_POSITION_EDEFAULT;
83
84
	/**
85
	 * The cached value of the '{@link #getChildObject() <em>Child Object</em>}' reference.
86
	 * <!-- begin-user-doc -->
87
	 * <!-- end-user-doc -->
88
	 * @see #getChildObject()
89
	 * @generated
90
	 * @ordered
91
	 */
92
	protected EObject childObject = null;
93
94
	/**
95
	 * <!-- begin-user-doc -->
96
	 * <!-- end-user-doc -->
97
	 * @generated
98
	 */
99
	protected ResourceEntryImpl() {
100
		super();
101
	}
102
103
	/**
104
	 * <!-- begin-user-doc -->
105
	 * <!-- end-user-doc -->
106
	 * @generated
107
	 */
108
	protected EClass eStaticClass() {
109
		return ResourceMapPackage.eINSTANCE.getResourceEntry();
110
	}
111
112
	/**
113
	 * <!-- begin-user-doc -->
114
	 * <!-- end-user-doc -->
115
	 * @generated
116
	 */
117
	public Resource getResource() {
118
		return resource;
119
	}
120
121
	/**
122
	 * <!-- begin-user-doc -->
123
	 * <!-- end-user-doc -->
124
	 * @generated
125
	 */
126
	public void setResource(Resource newResource) {
127
		Resource oldResource = resource;
128
		resource = newResource;
129
		if (eNotificationRequired())
130
			eNotify(new ENotificationImpl(this, Notification.SET, ResourceMapPackage.RESOURCE_ENTRY__RESOURCE, oldResource, resource));
131
	}
132
133
	/**
134
	 * <!-- begin-user-doc -->
135
	 * <!-- end-user-doc -->
136
	 * @generated
137
	 */
138
	public int getChildPosition() {
139
		return childPosition;
140
	}
141
142
	/**
143
	 * <!-- begin-user-doc -->
144
	 * <!-- end-user-doc -->
145
	 * @generated
146
	 */
147
	public void setChildPosition(int newChildPosition) {
148
		int oldChildPosition = childPosition;
149
		childPosition = newChildPosition;
150
		if (eNotificationRequired())
151
			eNotify(new ENotificationImpl(this, Notification.SET, ResourceMapPackage.RESOURCE_ENTRY__CHILD_POSITION, oldChildPosition, childPosition));
152
	}
153
154
	/**
155
	 * <!-- begin-user-doc -->
156
	 * <!-- end-user-doc -->
157
	 * @generated
158
	 */
159
	public EObject getChildObject() {
160
		if (childObject != null && childObject.eIsProxy()) {
161
			EObject oldChildObject = childObject;
162
			childObject = eResolveProxy((InternalEObject)childObject);
163
			if (childObject != oldChildObject) {
164
				if (eNotificationRequired())
165
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, ResourceMapPackage.RESOURCE_ENTRY__CHILD_OBJECT, oldChildObject, childObject));
166
			}
167
		}
168
		return childObject;
169
	}
170
171
	/**
172
	 * <!-- begin-user-doc -->
173
	 * <!-- end-user-doc -->
174
	 * @generated
175
	 */
176
	public EObject basicGetChildObject() {
177
		return childObject;
178
	}
179
180
	/**
181
	 * <!-- begin-user-doc -->
182
	 * <!-- end-user-doc -->
183
	 * @generated
184
	 */
185
	public void setChildObject(EObject newChildObject) {
186
		EObject oldChildObject = childObject;
187
		childObject = newChildObject;
188
		if (eNotificationRequired())
189
			eNotify(new ENotificationImpl(this, Notification.SET, ResourceMapPackage.RESOURCE_ENTRY__CHILD_OBJECT, oldChildObject, childObject));
190
	}
191
192
	/**
193
	 * <!-- begin-user-doc -->
194
	 * <!-- end-user-doc -->
195
	 * @generated
196
	 */
197
	public ParentEntry getParentEntry() {
198
		ParentEntry parentEntry = basicGetParentEntry();
199
		return parentEntry == null ? null : (ParentEntry)eResolveProxy((InternalEObject)parentEntry);
200
	}
201
202
	/**
203
	 * <!-- begin-user-doc -->
204
	 * <!-- end-user-doc -->
205
	 * @generated NOT
206
	 */
207
	public ParentEntry basicGetParentEntry() {
208
		if (eContainer() instanceof ParentEntry) {
209
			return (ParentEntry) eContainer();
210
		}
211
		
212
		return null;
213
	}
214
215
	/**
216
	 * <!-- begin-user-doc -->
217
	 * <!-- end-user-doc -->
218
	 * @generated
219
	 */
220
	public Object eGet(EStructuralFeature eFeature, boolean resolve) {
221
		switch (eDerivedStructuralFeatureID(eFeature)) {
222
			case ResourceMapPackage.RESOURCE_ENTRY__RESOURCE:
223
				return getResource();
224
			case ResourceMapPackage.RESOURCE_ENTRY__CHILD_POSITION:
225
				return new Integer(getChildPosition());
226
			case ResourceMapPackage.RESOURCE_ENTRY__CHILD_OBJECT:
227
				if (resolve) return getChildObject();
228
				return basicGetChildObject();
229
			case ResourceMapPackage.RESOURCE_ENTRY__PARENT_ENTRY:
230
				if (resolve) return getParentEntry();
231
				return basicGetParentEntry();
232
		}
233
		return eDynamicGet(eFeature, resolve);
234
	}
235
236
	/**
237
	 * <!-- begin-user-doc -->
238
	 * <!-- end-user-doc -->
239
	 * @generated
240
	 */
241
	public void eSet(EStructuralFeature eFeature, Object newValue) {
242
		switch (eDerivedStructuralFeatureID(eFeature)) {
243
			case ResourceMapPackage.RESOURCE_ENTRY__RESOURCE:
244
				setResource((Resource)newValue);
245
				return;
246
			case ResourceMapPackage.RESOURCE_ENTRY__CHILD_POSITION:
247
				setChildPosition(((Integer)newValue).intValue());
248
				return;
249
			case ResourceMapPackage.RESOURCE_ENTRY__CHILD_OBJECT:
250
				setChildObject((EObject)newValue);
251
				return;
252
		}
253
		eDynamicSet(eFeature, newValue);
254
	}
255
256
	/**
257
	 * <!-- begin-user-doc -->
258
	 * <!-- end-user-doc -->
259
	 * @generated
260
	 */
261
	public void eUnset(EStructuralFeature eFeature) {
262
		switch (eDerivedStructuralFeatureID(eFeature)) {
263
			case ResourceMapPackage.RESOURCE_ENTRY__RESOURCE:
264
				setResource(RESOURCE_EDEFAULT);
265
				return;
266
			case ResourceMapPackage.RESOURCE_ENTRY__CHILD_POSITION:
267
				setChildPosition(CHILD_POSITION_EDEFAULT);
268
				return;
269
			case ResourceMapPackage.RESOURCE_ENTRY__CHILD_OBJECT:
270
				setChildObject((EObject)null);
271
				return;
272
		}
273
		eDynamicUnset(eFeature);
274
	}
275
276
	/**
277
	 * <!-- begin-user-doc -->
278
	 * <!-- end-user-doc -->
279
	 * @generated
280
	 */
281
	public boolean eIsSet(EStructuralFeature eFeature) {
282
		switch (eDerivedStructuralFeatureID(eFeature)) {
283
			case ResourceMapPackage.RESOURCE_ENTRY__RESOURCE:
284
				return RESOURCE_EDEFAULT == null ? resource != null : !RESOURCE_EDEFAULT.equals(resource);
285
			case ResourceMapPackage.RESOURCE_ENTRY__CHILD_POSITION:
286
				return childPosition != CHILD_POSITION_EDEFAULT;
287
			case ResourceMapPackage.RESOURCE_ENTRY__CHILD_OBJECT:
288
				return childObject != null;
289
			case ResourceMapPackage.RESOURCE_ENTRY__PARENT_ENTRY:
290
				return basicGetParentEntry() != null;
291
		}
292
		return eDynamicIsSet(eFeature);
293
	}
294
295
	/**
296
	 * <!-- begin-user-doc -->
297
	 * <!-- end-user-doc -->
298
	 * @generated
299
	 */
300
	public String toString() {
301
		if (eIsProxy()) return super.toString();
302
303
		StringBuffer result = new StringBuffer(super.toString());
304
		result.append(" (resource: "); //$NON-NLS-1$
305
		result.append(resource);
306
		result.append(", childPosition: "); //$NON-NLS-1$
307
		result.append(childPosition);
308
		result.append(')');
309
		return result.toString();
310
	}
311
312
} //ResourceEntryImpl
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resourcemap/impl/package.html (-16 lines)
Removed Link Here
1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
2
<html>
3
<head>
4
<!--
5
6
/******************************************************************************
7
 * Copyright (c) 2004,2005 IBM Corporation and others.
8
 * All rights reserved. This program and the accompanying materials
9
 * are made available under the terms of the Eclipse Public License v1.0
10
 * which accompanies this distribution, and is available at
11
 * http://www.eclipse.org/legal/epl-v10.html
12
 *
13
 * Contributors:
14
 *    IBM Corporation - initial API and implementation 
15
 ****************************************************************************/
16
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resourcemap/impl/ParentEntryImpl.java (-331 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
package org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl;
13
14
import java.util.Collection;
15
import java.util.Iterator;
16
17
import org.eclipse.emf.common.notify.Notification;
18
import org.eclipse.emf.common.notify.NotificationChain;
19
import org.eclipse.emf.common.util.EList;
20
import org.eclipse.emf.ecore.EClass;
21
import org.eclipse.emf.ecore.EObject;
22
import org.eclipse.emf.ecore.EReference;
23
import org.eclipse.emf.ecore.EStructuralFeature;
24
import org.eclipse.emf.ecore.InternalEObject;
25
import org.eclipse.emf.ecore.impl.ENotificationImpl;
26
import org.eclipse.emf.ecore.impl.EObjectImpl;
27
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
28
import org.eclipse.emf.ecore.util.InternalEList;
29
30
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry;
31
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry;
32
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap;
33
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage;
34
35
/**
36
 * <!-- begin-user-doc -->
37
 * An implementation of the model object '<em><b>Parent Entry</b></em>'.
38
 * <!-- end-user-doc -->
39
 * <p>
40
 * The following features are implemented:
41
 * <ul>
42
 *   <li>{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl.ParentEntryImpl#getParentObject <em>Parent Object</em>}</li>
43
 *   <li>{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl.ParentEntryImpl#getChildSlot <em>Child Slot</em>}</li>
44
 *   <li>{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl.ParentEntryImpl#getResourceEntries <em>Resource Entries</em>}</li>
45
 *   <li>{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl.ParentEntryImpl#getResourceMap <em>Resource Map</em>}</li>
46
 * </ul>
47
 * </p>
48
 *
49
 * @generated
50
 */
51
public class ParentEntryImpl extends EObjectImpl implements ParentEntry {
52
	/**
53
	 * The cached value of the '{@link #getParentObject() <em>Parent Object</em>}' reference.
54
	 * <!-- begin-user-doc -->
55
	 * <!-- end-user-doc -->
56
	 * @see #getParentObject()
57
	 * @generated
58
	 * @ordered
59
	 */
60
	protected EObject parentObject = null;
61
62
	/**
63
	 * The cached value of the '{@link #getChildSlot() <em>Child Slot</em>}' reference.
64
	 * <!-- begin-user-doc -->
65
	 * <!-- end-user-doc -->
66
	 * @see #getChildSlot()
67
	 * @generated
68
	 * @ordered
69
	 */
70
	protected EReference childSlot = null;
71
72
	/**
73
	 * The cached value of the '{@link #getResourceEntries() <em>Resource Entries</em>}' containment reference list.
74
	 * <!-- begin-user-doc -->
75
	 * <!-- end-user-doc -->
76
	 * @see #getResourceEntries()
77
	 * @generated
78
	 * @ordered
79
	 */
80
	protected EList resourceEntries = null;
81
82
	/**
83
	 * <!-- begin-user-doc -->
84
	 * <!-- end-user-doc -->
85
	 * @generated
86
	 */
87
	protected ParentEntryImpl() {
88
		super();
89
	}
90
91
	/**
92
	 * <!-- begin-user-doc -->
93
	 * <!-- end-user-doc -->
94
	 * @generated
95
	 */
96
	protected EClass eStaticClass() {
97
		return ResourceMapPackage.eINSTANCE.getParentEntry();
98
	}
99
100
	/**
101
	 * <!-- begin-user-doc -->
102
	 * <!-- end-user-doc -->
103
	 * @generated
104
	 */
105
	public EObject getParentObject() {
106
		if (parentObject != null && parentObject.eIsProxy()) {
107
			EObject oldParentObject = parentObject;
108
			parentObject = eResolveProxy((InternalEObject)parentObject);
109
			if (parentObject != oldParentObject) {
110
				if (eNotificationRequired())
111
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, ResourceMapPackage.PARENT_ENTRY__PARENT_OBJECT, oldParentObject, parentObject));
112
			}
113
		}
114
		return parentObject;
115
	}
116
117
	/**
118
	 * <!-- begin-user-doc -->
119
	 * <!-- end-user-doc -->
120
	 * @generated
121
	 */
122
	public EObject basicGetParentObject() {
123
		return parentObject;
124
	}
125
126
	/**
127
	 * <!-- begin-user-doc -->
128
	 * <!-- end-user-doc -->
129
	 * @generated
130
	 */
131
	public void setParentObject(EObject newParentObject) {
132
		EObject oldParentObject = parentObject;
133
		parentObject = newParentObject;
134
		if (eNotificationRequired())
135
			eNotify(new ENotificationImpl(this, Notification.SET, ResourceMapPackage.PARENT_ENTRY__PARENT_OBJECT, oldParentObject, parentObject));
136
	}
137
138
	/**
139
	 * <!-- begin-user-doc -->
140
	 * <!-- end-user-doc -->
141
	 * @generated
142
	 */
143
	public EReference getChildSlot() {
144
		if (childSlot != null && childSlot.eIsProxy()) {
145
			EReference oldChildSlot = childSlot;
146
			childSlot = (EReference)eResolveProxy((InternalEObject)childSlot);
147
			if (childSlot != oldChildSlot) {
148
				if (eNotificationRequired())
149
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, ResourceMapPackage.PARENT_ENTRY__CHILD_SLOT, oldChildSlot, childSlot));
150
			}
151
		}
152
		return childSlot;
153
	}
154
155
	/**
156
	 * <!-- begin-user-doc -->
157
	 * <!-- end-user-doc -->
158
	 * @generated
159
	 */
160
	public EReference basicGetChildSlot() {
161
		return childSlot;
162
	}
163
164
	/**
165
	 * <!-- begin-user-doc -->
166
	 * <!-- end-user-doc -->
167
	 * @generated
168
	 */
169
	public void setChildSlot(EReference newChildSlot) {
170
		EReference oldChildSlot = childSlot;
171
		childSlot = newChildSlot;
172
		if (eNotificationRequired())
173
			eNotify(new ENotificationImpl(this, Notification.SET, ResourceMapPackage.PARENT_ENTRY__CHILD_SLOT, oldChildSlot, childSlot));
174
	}
175
176
	/**
177
	 * <!-- begin-user-doc -->
178
	 * <!-- end-user-doc -->
179
	 * @generated
180
	 */
181
	public EList getResourceEntries() {
182
		if (resourceEntries == null) {
183
			resourceEntries = new EObjectContainmentEList(ResourceEntry.class, this, ResourceMapPackage.PARENT_ENTRY__RESOURCE_ENTRIES);
184
		}
185
		return resourceEntries;
186
	}
187
188
	/**
189
	 * <!-- begin-user-doc -->
190
	 * <!-- end-user-doc -->
191
	 * @generated
192
	 */
193
	public ResourceMap getResourceMap() {
194
		ResourceMap resourceMap = basicGetResourceMap();
195
		return resourceMap == null ? null : (ResourceMap)eResolveProxy((InternalEObject)resourceMap);
196
	}
197
198
	/**
199
	 * <!-- begin-user-doc -->
200
	 * <!-- end-user-doc -->
201
	 * @generated NOT
202
	 */
203
	public ResourceMap basicGetResourceMap() {
204
		if (eContainer() instanceof ResourceMap) {
205
			return (ResourceMap) eContainer();
206
		}
207
		
208
		return null;
209
	}
210
211
	/**
212
	 * <!-- begin-user-doc -->
213
	 * <!-- end-user-doc -->
214
	 * @generated NOT
215
	 */
216
	public ResourceEntry getResourceEntry(EObject child) {
217
		ResourceEntry result = null;
218
		
219
		for (Iterator iter = getResourceEntries().iterator();
220
				(result == null) && iter.hasNext();) {
221
			
222
			ResourceEntryImpl next = (ResourceEntryImpl) iter.next();
223
			
224
			if (next.basicGetChildObject() == child) {
225
				result = next;
226
			}
227
		}
228
		
229
		return result;
230
	}
231
232
	/**
233
	 * <!-- begin-user-doc -->
234
	 * <!-- end-user-doc -->
235
	 * @generated
236
	 */
237
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, Class baseClass, NotificationChain msgs) {
238
		if (featureID >= 0) {
239
			switch (eDerivedStructuralFeatureID(featureID, baseClass)) {
240
				case ResourceMapPackage.PARENT_ENTRY__RESOURCE_ENTRIES:
241
					return ((InternalEList)getResourceEntries()).basicRemove(otherEnd, msgs);
242
				default:
243
					return eDynamicInverseRemove(otherEnd, featureID, baseClass, msgs);
244
			}
245
		}
246
		return eBasicSetContainer(null, featureID, msgs);
247
	}
248
249
	/**
250
	 * <!-- begin-user-doc -->
251
	 * <!-- end-user-doc -->
252
	 * @generated
253
	 */
254
	public Object eGet(EStructuralFeature eFeature, boolean resolve) {
255
		switch (eDerivedStructuralFeatureID(eFeature)) {
256
			case ResourceMapPackage.PARENT_ENTRY__PARENT_OBJECT:
257
				if (resolve) return getParentObject();
258
				return basicGetParentObject();
259
			case ResourceMapPackage.PARENT_ENTRY__CHILD_SLOT:
260
				if (resolve) return getChildSlot();
261
				return basicGetChildSlot();
262
			case ResourceMapPackage.PARENT_ENTRY__RESOURCE_ENTRIES:
263
				return getResourceEntries();
264
			case ResourceMapPackage.PARENT_ENTRY__RESOURCE_MAP:
265
				if (resolve) return getResourceMap();
266
				return basicGetResourceMap();
267
		}
268
		return eDynamicGet(eFeature, resolve);
269
	}
270
271
	/**
272
	 * <!-- begin-user-doc -->
273
	 * <!-- end-user-doc -->
274
	 * @generated
275
	 */
276
	public void eSet(EStructuralFeature eFeature, Object newValue) {
277
		switch (eDerivedStructuralFeatureID(eFeature)) {
278
			case ResourceMapPackage.PARENT_ENTRY__PARENT_OBJECT:
279
				setParentObject((EObject)newValue);
280
				return;
281
			case ResourceMapPackage.PARENT_ENTRY__CHILD_SLOT:
282
				setChildSlot((EReference)newValue);
283
				return;
284
			case ResourceMapPackage.PARENT_ENTRY__RESOURCE_ENTRIES:
285
				getResourceEntries().clear();
286
				getResourceEntries().addAll((Collection)newValue);
287
				return;
288
		}
289
		eDynamicSet(eFeature, newValue);
290
	}
291
292
	/**
293
	 * <!-- begin-user-doc -->
294
	 * <!-- end-user-doc -->
295
	 * @generated
296
	 */
297
	public void eUnset(EStructuralFeature eFeature) {
298
		switch (eDerivedStructuralFeatureID(eFeature)) {
299
			case ResourceMapPackage.PARENT_ENTRY__PARENT_OBJECT:
300
				setParentObject((EObject)null);
301
				return;
302
			case ResourceMapPackage.PARENT_ENTRY__CHILD_SLOT:
303
				setChildSlot((EReference)null);
304
				return;
305
			case ResourceMapPackage.PARENT_ENTRY__RESOURCE_ENTRIES:
306
				getResourceEntries().clear();
307
				return;
308
		}
309
		eDynamicUnset(eFeature);
310
	}
311
312
	/**
313
	 * <!-- begin-user-doc -->
314
	 * <!-- end-user-doc -->
315
	 * @generated
316
	 */
317
	public boolean eIsSet(EStructuralFeature eFeature) {
318
		switch (eDerivedStructuralFeatureID(eFeature)) {
319
			case ResourceMapPackage.PARENT_ENTRY__PARENT_OBJECT:
320
				return parentObject != null;
321
			case ResourceMapPackage.PARENT_ENTRY__CHILD_SLOT:
322
				return childSlot != null;
323
			case ResourceMapPackage.PARENT_ENTRY__RESOURCE_ENTRIES:
324
				return resourceEntries != null && !resourceEntries.isEmpty();
325
			case ResourceMapPackage.PARENT_ENTRY__RESOURCE_MAP:
326
				return basicGetResourceMap() != null;
327
		}
328
		return eDynamicIsSet(eFeature);
329
	}
330
331
} //ParentEntryImpl
(-)src/org/eclipse/gmf/runtime/emf/core/resources/AbstractLogicalResource.java (-223 / +41 lines)
Lines 16-33 Link Here
16
import java.util.Collections;
16
import java.util.Collections;
17
import java.util.Map;
17
import java.util.Map;
18
18
19
import org.eclipse.core.runtime.Platform;
19
import org.eclipse.emf.common.util.URI;
20
import org.eclipse.emf.common.util.URI;
20
import org.eclipse.emf.ecore.EObject;
21
import org.eclipse.emf.ecore.EObject;
21
import org.eclipse.emf.ecore.resource.Resource;
22
import org.eclipse.emf.ecore.resource.Resource;
22
import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
23
import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
23
import org.eclipse.gmf.runtime.emf.core.EventTypes;
24
import org.eclipse.gmf.runtime.emf.core.internal.l10n.EMFCoreMessages;
25
import org.eclipse.gmf.runtime.emf.core.internal.plugin.MSLDebugOptions;
26
import org.eclipse.gmf.runtime.emf.core.internal.resources.AbstractResourceWrapper;
27
import org.eclipse.gmf.runtime.emf.core.internal.resources.LogicalResourcePolicyManager;
28
import org.eclipse.gmf.runtime.emf.core.internal.resources.LogicalResourceUtil;
29
import org.eclipse.gmf.runtime.emf.core.internal.resources.UnmodifiableResourceView;
30
import org.eclipse.gmf.runtime.emf.core.internal.util.Trace;
31
24
32
25
33
/**
26
/**
Lines 60-80 Link Here
60
 * @see ILogicalResourcePolicy
53
 * @see ILogicalResourcePolicy
61
 * 
54
 * 
62
 * @author Christian W. Damus (cdamus)
55
 * @author Christian W. Damus (cdamus)
56
 * 
57
 * @deprecated Use the cross-resource containment support provided by EMF,
58
 *     instead, by defining containment features that are capable of storing
59
 *     proxies.
63
 */
60
 */
64
public abstract class AbstractLogicalResource
61
public abstract class AbstractLogicalResource
65
	extends XMIResourceImpl
62
	extends XMIResourceImpl
66
	implements ILogicalResource {
63
	implements ILogicalResource {
67
64
68
	private final Map resourceMap = new java.util.HashMap();
65
	private final Map resourceMap = new java.util.HashMap();
69
	private final Map unmodifiableResourceMap = new java.util.HashMap();
70
	
71
	/**
72
	 * A map remembering the resource that used to store a separate object
73
	 * after that object has been detached (in the hope that it will be
74
	 * re-attached soon).
75
	 * Maps {@link String} element ID to resource {@link URI}
76
	 */
77
	private final Map detachedIdToResourceMap = new java.util.HashMap(); 
78
	
66
	
79
	/**
67
	/**
80
	 * Initializes me.
68
	 * Initializes me.
Lines 93-189 Link Here
93
	}
81
	}
94
	
82
	
95
	/**
83
	/**
96
	 * Implements the interface method by delegation to the registered logical
84
	 * I cannot separate any elements.
97
	 * resource policies, with the additional constraint that the
98
	 * <code>eObject</code> must not already be
99
	 * {@linkplain ILogicalResource#isSeparate(EObject) separate}.
100
	 * 
85
	 * 
101
	 * @see ILogicalResource#isSeparate(EObject)
86
	 * @return <code>false</code>, always
102
	 */
87
	 */
103
	public final boolean canSeparate(EObject eObject) {
88
	public boolean canSeparate(EObject eObject) {
104
		assert eObject.eResource() == this : "eObject is not in receiver" ; //$NON-NLS-1$
89
		return false;
105
		
106
		// the logical resource roots are not considered as separate or
107
		//   as separable
108
		return !isSeparate(eObject) && customCanSeparate(eObject)
109
			&& LogicalResourcePolicyManager.getInstance().canSeparate(this, eObject);
110
	}
90
	}
111
	
91
112
	/**
92
	/**
113
	 * Applies additional criteria to the question of whether an element
93
	 * I cannot separate any elements.
114
	 * can be separated.  May be overridden by subclasses to provide custom
115
	 * behaviour.
116
	 * <p>
117
	 * This default implementation just returns <code>true</code>.
118
	 * </p>
119
	 * 
94
	 * 
120
	 * @param eObject the element that is proposed for separation
95
	 * @return <code>false</code>, always
121
	 * @return whether it meets the resource implementation's additional criteria
122
	 */
96
	 */
123
	protected boolean customCanSeparate(EObject eObject) {
97
	public boolean isSeparate(EObject eObject) {
124
		return true;
98
		return false;
99
	}
100
101
	public void separate(EObject eObject, URI uri) {
102
		throw new IllegalArgumentException("cannot separate eObject"); //$NON-NLS-1$
103
	}
104
105
	public void absorb(EObject eObject) {
106
		throw new IllegalArgumentException("eObject is not separate"); //$NON-NLS-1$
125
	}
107
	}
126
	
108
	
127
	/**
109
	public boolean isLoaded(EObject eObject) {
128
	 * Implementation of the element separation operation, which does the
110
		return true;  // no object in a non-logical-resource can be unloaded
129
	 * following:
111
	}
130
	 * <ul>
112
	
131
	 *   <li>enforces the preconditions declared by the interface</li>
113
	public void load(EObject eObject)
132
	 *   <li>consults the registered {@linkplain ILogicalResourcePolicy}
114
		throws IOException {
133
	 *       policies before and after separation</li>
134
	 *   <li>fires the {@link org.eclipse.gmf.runtime.emf.core.EventTypes#SEPARATE}
135
	 *       notification when (and if) separation succeeds</li>
136
	 *   <li>delegates the actual separation implementation to the
137
	 *       {@link #doSeparate(EObject, URI)} method implemented by the
138
	 *       subclass</li>
139
	 * </ul> 
140
	 * 
141
	 * @see #doSeparate(EObject, URI)
142
	 * @see ILogicalResourcePolicy
143
	 */
144
	public final void separate(EObject eObject, URI physUri) throws CannotSeparateException {
145
		assert eObject.eResource() == this : "eObject is not in receiver" ; //$NON-NLS-1$
146
		
147
		if (isSeparate(eObject)) {
148
			throw new IllegalArgumentException("eObject is already separate"); //$NON-NLS-1$
149
		}
150
		
151
		physUri = LogicalResourcePolicyManager.getInstance().preSeparate(this, eObject, physUri);
152
		
153
		Resource oldUnit = getPhysicalResource(eObject);
154
		
155
		if (Trace.isEnabled(MSLDebugOptions.RESOURCES)) {
156
			Trace.trace(
157
				MSLDebugOptions.RESOURCES,
158
				"Separating: " + oldUnit.getURI() + " ==> " + physUri + ": " + eObject);  //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
159
		}
160
		
161
		if (physUri == null) {
162
			// not provided by user and no policy had a suggestion
163
			CannotSeparateException e = new CannotSeparateException(
164
				EMFCoreMessages.separate_noUri_ERROR_);
165
			Trace.throwing(LogicalResourceUtil.class, "separate", e); //$NON-NLS-1$
166
			throw e;
167
		}
168
		
169
		if (physUri.equals(oldUnit.getURI())) {
170
			// not allowed to separate into current storage unit
171
			CannotSeparateException e = new CannotSeparateException(
172
				EMFCoreMessages.separate_sameUnit_ERROR_);
173
			Trace.throwing(LogicalResourceUtil.class, "separate", e); //$NON-NLS-1$
174
			throw e;
175
		}
176
		
177
		doSeparate(eObject, physUri);
178
		
179
		Resource newUnit = getPhysicalResource(eObject);
180
		
181
		LogicalResourcePolicyManager.getInstance().postSeparate(this, eObject, physUri);
182
		
183
		// notify listeners
184
		LogicalResourceUtil.fireSeparationEvent(eObject, oldUnit, newUnit);
185
		
115
		
186
		setModified(true);
116
		throw new IllegalArgumentException("eObject is not separate"); //$NON-NLS-1$
117
	}
118
119
	public Map getMappedResources() {
120
		return Collections.EMPTY_MAP;
121
	}
122
123
	public Object getAdapter(Class adapter) {
124
		return Platform.getAdapterManager().getAdapter(this, adapter);
187
	}
125
	}
188
	
126
	
189
	/**
127
	/**
Lines 199-261 Link Here
199
	protected abstract void doSeparate(EObject eObject, URI physUri) throws CannotSeparateException;
137
	protected abstract void doSeparate(EObject eObject, URI physUri) throws CannotSeparateException;
200
	
138
	
201
	/**
139
	/**
202
	 * Implementation of the element absorption operation, which does the
203
	 * following:
204
	 * <ul>
205
	 *   <li>enforces the preconditions declared by the interface</li>
206
	 *   <li>consults the registered {@linkplain ILogicalResourcePolicy}
207
	 *       policies before and after absorption</li>
208
	 *   <li>fires the {@link org.eclipse.gmf.runtime.emf.core.EventTypes#ABSORB}
209
	 *       notification when (and if) absorption succeeds</li>
210
	 *   <li>delegates the actual absorption implementation to the
211
	 *       {@link #doAbsorb(EObject)} method implemented by the subclass</li>
212
	 * </ul> 
213
	 * 
214
	 * @see #doAbsorb(EObject)
215
	 * @see ILogicalResourcePolicy
216
	 */
217
	public final void absorb(EObject eObject) throws CannotAbsorbException {
218
		assert eObject.eResource() == this : "eObject is not in receiver" ; //$NON-NLS-1$
219
		
220
		if (!isSeparate(eObject)) {
221
			throw new IllegalArgumentException("eObject is not separate"); //$NON-NLS-1$
222
		}
223
		
224
		if (!isLoaded(eObject)) {
225
			throw new IllegalArgumentException("eObject is not loaded"); //$NON-NLS-1$
226
		}
227
		
228
		Resource oldUnit = getPhysicalResource(eObject);
229
		EObject parent = eObject.eContainer();
230
		
231
		Resource newUnit;
232
		if (parent == null) {
233
			// the parent unit of a separate root must be to physical root unit
234
			newUnit = getPhysicalResource(getURI());
235
		} else {
236
			newUnit = getPhysicalResource(eObject.eContainer());
237
		}
238
		
239
		if (Trace.isEnabled(MSLDebugOptions.RESOURCES)) {
240
			Trace.trace(
241
				MSLDebugOptions.RESOURCES,
242
				"Absorbing: " + oldUnit.getURI() //$NON-NLS-1$
243
				+ " ==> " + newUnit.getURI() + ": " + eObject);  //$NON-NLS-1$//$NON-NLS-2$
244
		}
245
		
246
		LogicalResourcePolicyManager.getInstance().preAbsorb(this, eObject);
247
		
248
		doAbsorb(eObject);
249
		
250
		LogicalResourcePolicyManager.getInstance().postAbsorb(this, eObject);
251
		
252
		// notify listeners
253
		LogicalResourceUtil.fireAbsorptionEvent(eObject, oldUnit, newUnit);
254
		
255
		setModified(true);
256
	}
257
	
258
	/**
259
	 * Implemented by the subclass to perform the absorption operation.
140
	 * Implemented by the subclass to perform the absorption operation.
260
	 * 
141
	 * 
261
	 * @param eObject the element to be absorbed
142
	 * @param eObject the element to be absorbed
Lines 264-300 Link Here
264
	protected abstract void doAbsorb(EObject eObject) throws CannotAbsorbException;
145
	protected abstract void doAbsorb(EObject eObject) throws CannotAbsorbException;
265
	
146
	
266
	/**
147
	/**
267
	 * Implementation of the element load operation, which does the
268
	 * following:
269
	 * <ul>
270
	 *   <li>enforces the preconditions declared by the interface</li>
271
	 *   <li>delegates the actual load implementation to the
272
	 *       {@link #doLoad(EObject)} method implemented by the subclass, if
273
	 *       the element is not already loaded</li>
274
	 * </ul> 
275
	 * <p>
276
	 * <b>Note</b> that, because loading an object may also load other objects
277
	 * from the same sub-unit, this template method does not fire the
278
	 * {@link EventTypes#LOAD} notification, as it would not know how many
279
	 * to fire for which objects.  This is the responsibility of the subclass's
280
	 * {@link #doLoad(EObject)} implementation.
281
	 * </p>
282
	 * 
283
	 * @see #doLoad(EObject)
284
	 */
285
	public final void load(EObject eObject) throws IOException {
286
		assert eObject.eResource() == this : "eObject is not in receiver" ; //$NON-NLS-1$
287
		
288
		if (!isSeparate(eObject)) {
289
			throw new IllegalArgumentException("eObject is not separate"); //$NON-NLS-1$
290
		}
291
		
292
		if (!isLoaded(eObject)) {
293
			doLoad(eObject);
294
		}
295
	}
296
	
297
	/**
298
	 * Implemented by the subclass to perform the load operation.  This method
148
	 * Implemented by the subclass to perform the load operation.  This method
299
	 * will only be invoked if the element is not already loaded.
149
	 * will only be invoked if the element is not already loaded.
300
	 * 
150
	 * 
Lines 303-312 Link Here
303
	 */
153
	 */
304
	protected abstract void doLoad(EObject eObject) throws IOException;
154
	protected abstract void doLoad(EObject eObject) throws IOException;
305
	
155
	
306
	public final Map getMappedResources() {
307
		return Collections.unmodifiableMap(unmodifiableResourceMap);
308
	}
309
	
310
	/**
156
	/**
311
	 * Adds the specified <code>subunit</code> resource to the map.
157
	 * Adds the specified <code>subunit</code> resource to the map.
312
	 * Subclasses implementing this method must invoke <code>super</code>.
158
	 * Subclasses implementing this method must invoke <code>super</code>.
Lines 317-339 Link Here
317
	 *     was detached
163
	 *     was detached
318
	 */
164
	 */
319
	protected void addMappedResource(EObject object, Resource unit) {
165
	protected void addMappedResource(EObject object, Resource unit) {
320
		if (unit == null) {
166
		// no need to do anything any longer
321
			// look to see whether this object was previously a separate element
322
			//    that was detached from me
323
			URI unitUri = (URI) detachedIdToResourceMap.remove(getID(object));
324
			
325
			if ((unitUri != null) && !uri.equals(getURI())) {
326
				unit = getPhysicalResource(unitUri);
327
			}
328
		}
329
		
330
		if (unit != null) {
331
			// unwrap just in case
332
			resourceMap.put(object, AbstractResourceWrapper.unwrap(unit));
333
			
334
			// wrap just in case
335
			unmodifiableResourceMap.put(object, UnmodifiableResourceView.get(unit));
336
		}
337
	}
167
	}
338
	
168
	
339
	/**
169
	/**
Lines 343-359 Link Here
343
	 * @param object the (formerly) separate element
173
	 * @param object the (formerly) separate element
344
	 */
174
	 */
345
	protected void removeMappedResource(EObject object) {
175
	protected void removeMappedResource(EObject object) {
346
		// this element has been now detached.  Preserve the physical mapping
176
		// no need to do anything any longer
347
		//    in case it is re-attached later
348
		Resource unit = (Resource) getMappedResources().get(object);
349
		
350
		if (unit != null) {
351
			// the object's ID is retained by the detached object ID map
352
			detachedIdToResourceMap.put(getID(object), unit.getURI());
353
		}
354
		
355
		resourceMap.remove(object);
356
		unmodifiableResourceMap.remove(object);
357
	}
177
	}
358
	
178
	
359
	/**
179
	/**
Lines 361-369 Link Here
361
	 * Subclasses implementing this method must invoke <code>super</code>.
181
	 * Subclasses implementing this method must invoke <code>super</code>.
362
	 */
182
	 */
363
	protected void clearMappedResources() {
183
	protected void clearMappedResources() {
364
		resourceMap.clear();
184
		// no need to do anything any longer
365
		unmodifiableResourceMap.clear();
366
		detachedIdToResourceMap.clear();
367
	}
185
	}
368
	
186
	
369
	/**
187
	/**
Lines 389-395 Link Here
389
	protected final Resource getPhysicalResource(EObject eObject) {
207
	protected final Resource getPhysicalResource(EObject eObject) {
390
		assert eObject.eResource() == this : "eObject is not in receiver" ; //$NON-NLS-1$
208
		assert eObject.eResource() == this : "eObject is not in receiver" ; //$NON-NLS-1$
391
		
209
		
392
		return LogicalResourceUtil.getPhysicalResource(this, eObject);
210
		return eObject.eResource();
393
	}
211
	}
394
212
395
	/**
213
	/**
(-)src/org/eclipse/gmf/runtime/emf/core/resources/AbstractLogicalResourcePolicy.java (+4 lines)
Lines 21-26 Link Here
21
 * subclasses.
21
 * subclasses.
22
 *
22
 *
23
 * @author Christian W. Damus (cdamus)
23
 * @author Christian W. Damus (cdamus)
24
 * 
25
 * @deprecated Use the cross-resource containment support provided by EMF,
26
 *     instead, by defining containment features that are capable of storing
27
 *     proxies.
24
 */
28
 */
25
public abstract class AbstractLogicalResourcePolicy
29
public abstract class AbstractLogicalResourcePolicy
26
	implements ILogicalResourcePolicy {
30
	implements ILogicalResourcePolicy {
(-)src/org/eclipse/gmf/runtime/emf/core/resources/CannotSeparateException.java (+4 lines)
Lines 21-26 Link Here
21
 * some reason (such as being read-only).
21
 * some reason (such as being read-only).
22
 *
22
 *
23
 * @author Christian W. Damus (cdamus)
23
 * @author Christian W. Damus (cdamus)
24
 * 
25
 * @deprecated Use the cross-resource containment support provided by EMF,
26
 *     instead, by defining containment features that are capable of storing
27
 *     proxies.
24
 */
28
 */
25
public class CannotSeparateException
29
public class CannotSeparateException
26
	extends MSLCheckedException {
30
	extends MSLCheckedException {
(-)src/org/eclipse/gmf/runtime/emf/core/resources/ILogicalResourcePolicy.java (+4 lines)
Lines 36-41 Link Here
36
 * @author Christian W. Damus (cdamus)
36
 * @author Christian W. Damus (cdamus)
37
 * 
37
 * 
38
 * @see AbstractLogicalResourcePolicy
38
 * @see AbstractLogicalResourcePolicy
39
 * 
40
 * @deprecated Use the cross-resource containment support provided by EMF,
41
 *     instead, by defining containment features that are capable of storing
42
 *     proxies.
39
 */
43
 */
40
public interface ILogicalResourcePolicy {
44
public interface ILogicalResourcePolicy {
41
	
45
	
(-)src/org/eclipse/gmf/runtime/emf/core/resources/CannotAbsorbException.java (+4 lines)
Lines 20-25 Link Here
20
 * resource in a logical resource.
20
 * resource in a logical resource.
21
 *
21
 *
22
 * @author Christian W. Damus (cdamus)
22
 * @author Christian W. Damus (cdamus)
23
 * 
24
 * @deprecated Use the cross-resource containment support provided by EMF,
25
 *     instead, by defining containment features that are capable of storing
26
 *     proxies.
23
 */
27
 */
24
public class CannotAbsorbException
28
public class CannotAbsorbException
25
	extends MSLCheckedException {
29
	extends MSLCheckedException {
(-)src/org/eclipse/gmf/runtime/emf/core/resources/ILogicalResource.java (+4 lines)
Lines 50-55 Link Here
50
 * 
50
 * 
51
 * @see org.eclipse.gmf.runtime.emf.core.edit.MEditingDomain#asLogicalResource(Resource)
51
 * @see org.eclipse.gmf.runtime.emf.core.edit.MEditingDomain#asLogicalResource(Resource)
52
 * @see org.eclipse.gmf.runtime.emf.core.resources.MResourceFactory
52
 * @see org.eclipse.gmf.runtime.emf.core.resources.MResourceFactory
53
 * 
54
 * @deprecated Use the cross-resource containment support provided by EMF,
55
 *     instead, by defining containment features that are capable of storing
56
 *     proxies.
53
 */
57
 */
54
public interface ILogicalResource
58
public interface ILogicalResource
55
	extends Resource, IAdaptable {
59
	extends Resource, IAdaptable {
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resourcemap/ResourceMapFactory.java (-78 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
package org.eclipse.gmf.runtime.emf.core.internal.resourcemap;
13
14
import org.eclipse.emf.ecore.EFactory;
15
16
/**
17
 * <!-- begin-user-doc -->
18
 * The <b>Factory</b> for the logical resource physical mapping metamodel.
19
 * It provides a create method for each non-abstract class of the metamodel.
20
 * <!-- end-user-doc -->
21
 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage
22
 * @generated
23
 */
24
public interface ResourceMapFactory extends EFactory{
25
	/**
26
	 * The singleton instance of the factory.
27
	 * <!-- begin-user-doc -->
28
	 * <!-- end-user-doc -->
29
	 * @generated
30
	 */
31
	ResourceMapFactory eINSTANCE = new org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl.ResourceMapFactoryImpl();
32
33
	/**
34
	 * Returns a new object of class '<em>Resource Map</em>'.
35
	 * <!-- begin-user-doc -->
36
	 * <!-- end-user-doc -->
37
	 * @return a new object of class '<em>Resource Map</em>'.
38
	 * @generated
39
	 */
40
	ResourceMap createResourceMap();
41
42
	/**
43
	 * Returns a new object of class '<em>Resource Entry</em>'.
44
	 * <!-- begin-user-doc -->
45
	 * <!-- end-user-doc -->
46
	 * @return a new object of class '<em>Resource Entry</em>'.
47
	 * @generated
48
	 */
49
	ResourceEntry createResourceEntry();
50
51
	/**
52
	 * Returns a new object of class '<em>Parent Entry</em>'.
53
	 * <!-- begin-user-doc -->
54
	 * <!-- end-user-doc -->
55
	 * @return a new object of class '<em>Parent Entry</em>'.
56
	 * @generated
57
	 */
58
	ParentEntry createParentEntry();
59
60
	/**
61
	 * Returns a new object of class '<em>Child Entry</em>'.
62
	 * <!-- begin-user-doc -->
63
	 * <!-- end-user-doc -->
64
	 * @return a new object of class '<em>Child Entry</em>'.
65
	 * @generated
66
	 */
67
	ChildEntry createChildEntry();
68
69
	/**
70
	 * Returns the package supported by this factory.
71
	 * <!-- begin-user-doc -->
72
	 * <!-- end-user-doc -->
73
	 * @return the package supported by this factory.
74
	 * @generated
75
	 */
76
	ResourceMapPackage getResourceMapPackage();
77
78
} //ResourceMapFactory
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resourcemap/ResourceEntry.java (-142 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
package org.eclipse.gmf.runtime.emf.core.internal.resourcemap;
13
14
import org.eclipse.emf.ecore.EObject;
15
import org.eclipse.emf.ecore.resource.Resource;
16
17
/**
18
 * <!-- begin-user-doc -->
19
 * An entry in a {@link ParentEntry} in the physical resource map, that
20
 * indicates which separate child of the parent element fits into the
21
 * containment reference at what position.
22
 * <!-- end-user-doc -->
23
 *
24
 * <p>
25
 * The following features are supported:
26
 * <ul>
27
 *   <li>{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry#getResource <em>Resource</em>}</li>
28
 *   <li>{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry#getChildPosition <em>Child Position</em>}</li>
29
 *   <li>{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry#getChildObject <em>Child Object</em>}</li>
30
 *   <li>{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry#getParentEntry <em>Parent Entry</em>}</li>
31
 * </ul>
32
 * </p>
33
 *
34
 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage#getResourceEntry()
35
 * @model
36
 * @generated
37
 */
38
public interface ResourceEntry extends EObject{
39
	/**
40
	 * Returns the value of the '<em><b>Resource</b></em>' attribute.
41
	 * <!-- begin-user-doc -->
42
	 * <p>
43
	 * Obtains the transient reference to the sub-unit resource containing the
44
	 * separate child element.
45
	 * </p>
46
	 * <!-- end-user-doc -->
47
	 * @return the value of the '<em>Resource</em>' attribute.
48
	 * @see #setResource(Resource)
49
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage#getResourceEntry_Resource()
50
	 * @model transient="true"
51
	 * @generated
52
	 */
53
	Resource getResource();
54
55
	/**
56
	 * Sets the value of the '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry#getResource <em>Resource</em>}' attribute.
57
	 * <!-- begin-user-doc -->
58
	 * <p>
59
	 * Sets the transient reference to the sub-unit resource containing the
60
	 * separate child element.
61
	 * </p>
62
	 * <!-- end-user-doc -->
63
	 * @param value the new value of the '<em>Resource</em>' attribute.
64
	 * @see #getResource()
65
	 * @generated
66
	 */
67
	void setResource(Resource value);
68
69
	/**
70
	 * Returns the value of the '<em><b>Child Position</b></em>' attribute.
71
	 * The default value is <code>"-1"</code>.
72
	 * <!-- begin-user-doc -->
73
	 * <p>
74
	 * Gets the index in the containment reference at which this child resides.
75
	 * The index is <code>-1</code> (the default value) for scalar references.
76
	 * </p>
77
	 * <!-- end-user-doc -->
78
	 * @return the value of the '<em>Child Position</em>' attribute.
79
	 * @see #setChildPosition(int)
80
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage#getResourceEntry_ChildPosition()
81
	 * @model default="-1"
82
	 * @generated
83
	 */
84
	int getChildPosition();
85
86
	/**
87
	 * Sets the value of the '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry#getChildPosition <em>Child Position</em>}' attribute.
88
	 * <!-- begin-user-doc -->
89
	 * <p>
90
	 * Sets the index in the containment reference at which this child resides,
91
	 * or <code>-1</code> (the default value) for scalar references.
92
	 * </p>
93
	 * <!-- end-user-doc -->
94
	 * @param value the new value of the '<em>Child Position</em>' attribute.
95
	 * @see #getChildPosition()
96
	 * @generated
97
	 */
98
	void setChildPosition(int value);
99
100
	/**
101
	 * Returns the value of the '<em><b>Child Object</b></em>' reference.
102
	 * <!-- begin-user-doc -->
103
	 * <p>
104
	 * Obtains the separate child object.
105
	 * </p>
106
	 * <!-- end-user-doc -->
107
	 * @return the value of the '<em>Child Object</em>' reference.
108
	 * @see #setChildObject(EObject)
109
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage#getResourceEntry_ChildObject()
110
	 * @model required="true"
111
	 * @generated
112
	 */
113
	EObject getChildObject();
114
115
	/**
116
	 * Sets the value of the '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry#getChildObject <em>Child Object</em>}' reference.
117
	 * <!-- begin-user-doc -->
118
	 * <p>
119
	 * Sets the separate child object.
120
	 * </p>
121
	 * <!-- end-user-doc -->
122
	 * @param value the new value of the '<em>Child Object</em>' reference.
123
	 * @see #getChildObject()
124
	 * @generated
125
	 */
126
	void setChildObject(EObject value);
127
128
	/**
129
	 * Returns the value of the '<em><b>Parent Entry</b></em>' reference.
130
	 * <!-- begin-user-doc -->
131
	 * <p>
132
	 * Obtains the parent entry that contains me.
133
	 * </p>
134
	 * <!-- end-user-doc -->
135
	 * @return the value of the '<em>Parent Entry</em>' reference.
136
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage#getResourceEntry_ParentEntry()
137
	 * @model transient="true" changeable="false" volatile="true"
138
	 * @generated
139
	 */
140
	ParentEntry getParentEntry();
141
142
} // ResourceEntry
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resourcemap/ParentEntry.java (-148 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
package org.eclipse.gmf.runtime.emf.core.internal.resourcemap;
13
14
import org.eclipse.emf.common.util.EList;
15
import org.eclipse.emf.ecore.EObject;
16
import org.eclipse.emf.ecore.EReference;
17
18
/**
19
 * <!-- begin-user-doc -->
20
 * An entry in the physical resource map for an element in the unit that has
21
 * one or more separate children in some containment reference.
22
 * <!-- end-user-doc -->
23
 *
24
 * <p>
25
 * The following features are supported:
26
 * <ul>
27
 *   <li>{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry#getParentObject <em>Parent Object</em>}</li>
28
 *   <li>{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry#getChildSlot <em>Child Slot</em>}</li>
29
 *   <li>{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry#getResourceEntries <em>Resource Entries</em>}</li>
30
 *   <li>{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry#getResourceMap <em>Resource Map</em>}</li>
31
 * </ul>
32
 * </p>
33
 *
34
 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage#getParentEntry()
35
 * @model
36
 * @generated
37
 */
38
public interface ParentEntry extends EObject{
39
	/**
40
	 * Returns the value of the '<em><b>Parent Object</b></em>' reference.
41
	 * <!-- begin-user-doc -->
42
	 * <p>
43
	 * Obtains the model element that is the parent of some separate children.
44
	 * For the parent entry representing the logical resource, itself (whose
45
	 * roots may be separate), the parent is <code>null</code>.
46
	 * </p>
47
	 * <!-- end-user-doc -->
48
	 * @return the value of the '<em>Parent Object</em>' reference.
49
	 * @see #setParentObject(EObject)
50
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage#getParentEntry_ParentObject()
51
	 * @model
52
	 * @generated
53
	 */
54
	EObject getParentObject();
55
56
	/**
57
	 * Sets the value of the '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry#getParentObject <em>Parent Object</em>}' reference.
58
	 * <!-- begin-user-doc -->
59
	 * <p>
60
	 * Sets the model element that is the parent of some separate children.
61
	 * </p>
62
	 * <!-- end-user-doc -->
63
	 * @param value the new value of the '<em>Parent Object</em>' reference.
64
	 * @see #getParentObject()
65
	 * @generated
66
	 */
67
	void setParentObject(EObject value);
68
69
	/**
70
	 * Returns the value of the '<em><b>Child Slot</b></em>' reference.
71
	 * <!-- begin-user-doc -->
72
	 * <p>
73
	 * Obtains the containment reference of the
74
	 * {@linkplain #getParentObject() parent} element that contains one or more
75
	 * separate children.
76
	 * For the parent entry representing the logical resource, itself (whose
77
	 * roots may be separate), the child slot is <code>null</code>.
78
	 * </p>
79
	 * <!-- end-user-doc -->
80
	 * @return the value of the '<em>Child Slot</em>' reference.
81
	 * @see #setChildSlot(EReference)
82
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage#getParentEntry_ChildSlot()
83
	 * @model
84
	 * @generated
85
	 */
86
	EReference getChildSlot();
87
88
	/**
89
	 * Sets the value of the '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry#getChildSlot <em>Child Slot</em>}' reference.
90
	 * <!-- begin-user-doc -->
91
	 * <p>
92
	 * Sets the containment reference of the
93
	 * {@linkplain #getParentObject() parent} element that contains one or more
94
	 * separate children.
95
	 * </p>
96
	 * <!-- end-user-doc -->
97
	 * @param value the new value of the '<em>Child Slot</em>' reference.
98
	 * @see #getChildSlot()
99
	 * @generated
100
	 */
101
	void setChildSlot(EReference value);
102
103
	/**
104
	 * Returns the value of the '<em><b>Resource Entries</b></em>' containment reference list.
105
	 * The list contents are of type {@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry}.
106
	 * <!-- begin-user-doc -->
107
	 * <p>
108
	 * Obtains the list of entries for the separate children of the parent in
109
	 * the slot.
110
	 * </p>
111
	 * <!-- end-user-doc -->
112
	 * @return the value of the '<em>Resource Entries</em>' containment reference list.
113
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage#getParentEntry_ResourceEntries()
114
	 * @model type="org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry" containment="true" required="true"
115
	 * @generated
116
	 */
117
	EList getResourceEntries();
118
119
	/**
120
	 * Returns the value of the '<em><b>Resource Map</b></em>' reference.
121
	 * <!-- begin-user-doc -->
122
	 * <p>
123
	 * Obtains the resource map that contains me.
124
	 * </p>
125
	 * <!-- end-user-doc -->
126
	 * @return the value of the '<em>Resource Map</em>' reference.
127
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage#getParentEntry_ResourceMap()
128
	 * @model transient="true" changeable="false" volatile="true"
129
	 * @generated
130
	 */
131
	ResourceMap getResourceMap();
132
133
	/**
134
	 * <!-- begin-user-doc -->
135
	 * Obtains the resource entry within me for the specified <code>child</code>
136
	 * of my parent element.
137
	 * 
138
	 * @param child a child of my parent element
139
	 * @return the resource entry, or <code>null</code> if the
140
	 *    <code>child</code> is not containment by this parent in this slot or
141
	 *    if it is not separate
142
	 * <!-- end-user-doc -->
143
	 * @model childRequired="true"
144
	 * @generated
145
	 */
146
	ResourceEntry getResourceEntry(EObject child);
147
148
} // ParentEntry
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resourcemap/ChildEntry.java (-93 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
package org.eclipse.gmf.runtime.emf.core.internal.resourcemap;
13
14
import org.eclipse.emf.ecore.EObject;
15
16
/**
17
 * <!-- begin-user-doc -->
18
 * An entry in the physical resource map that links a separate element (as a
19
 * root of a sub-unit) to its parent unit.
20
 * <!-- end-user-doc -->
21
 *
22
 * <p>
23
 * The following features are supported:
24
 * <ul>
25
 *   <li>{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ChildEntry#getChildObject <em>Child Object</em>}</li>
26
 *   <li>{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ChildEntry#getParentMap <em>Parent Map</em>}</li>
27
 * </ul>
28
 * </p>
29
 *
30
 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage#getChildEntry()
31
 * @model
32
 * @generated
33
 */
34
public interface ChildEntry extends EObject {
35
	/**
36
	 * Returns the value of the '<em><b>Child Object</b></em>' reference.
37
	 * <!-- begin-user-doc -->
38
	 * <p>
39
	 * Obtains the child object for which I indicate the parent unit.
40
	 * </p>
41
	 * <!-- end-user-doc -->
42
	 * @return the value of the '<em>Child Object</em>' reference.
43
	 * @see #setChildObject(EObject)
44
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage#getChildEntry_ChildObject()
45
	 * @model required="true"
46
	 * @generated
47
	 */
48
	EObject getChildObject();
49
50
	/**
51
	 * Sets the value of the '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ChildEntry#getChildObject <em>Child Object</em>}' reference.
52
	 * <!-- begin-user-doc -->
53
	 * <p>
54
	 * Sets the child object for which I indicate the parent unit.
55
	 * </p>
56
	 * <!-- end-user-doc -->
57
	 * @param value the new value of the '<em>Child Object</em>' reference.
58
	 * @see #getChildObject()
59
	 * @generated
60
	 */
61
	void setChildObject(EObject value);
62
63
	/**
64
	 * Returns the value of the '<em><b>Parent Map</b></em>' reference.
65
	 * <!-- begin-user-doc -->
66
	 * <p>
67
	 * Obtains the resource map of the child's parent unit.  This serves as
68
	 * a handle on the parent unit, itself.
69
	 * </p>
70
	 * <!-- end-user-doc -->
71
	 * @return the value of the '<em>Parent Map</em>' reference.
72
	 * @see #setParentMap(ResourceMap)
73
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage#getChildEntry_ParentMap()
74
	 * @model required="true"
75
	 * @generated
76
	 */
77
	ResourceMap getParentMap();
78
79
	/**
80
	 * Sets the value of the '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ChildEntry#getParentMap <em>Parent Map</em>}' reference.
81
	 * <!-- begin-user-doc -->
82
	 * <p>
83
	 * Sets the resource map of the child's parent unit.  This serves as
84
	 * a handle on the parent unit, itself.
85
	 * </p>
86
	 * <!-- end-user-doc -->
87
	 * @param value the new value of the '<em>Parent Map</em>' reference.
88
	 * @see #getParentMap()
89
	 * @generated
90
	 */
91
	void setParentMap(ResourceMap value);
92
93
} // ChildEntry
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resourcemap/package.html (-16 lines)
Removed Link Here
1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
2
<html>
3
<head>
4
<!--
5
6
/******************************************************************************
7
 * Copyright (c) 2004,2005 IBM Corporation and others.
8
 * All rights reserved. This program and the accompanying materials
9
 * are made available under the terms of the Eclipse Public License v1.0
10
 * which accompanies this distribution, and is available at
11
 * http://www.eclipse.org/legal/epl-v10.html
12
 *
13
 * Contributors:
14
 *    IBM Corporation - initial API and implementation 
15
 ****************************************************************************/
16
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resourcemap/ResourceMapPackage.java (-454 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
package org.eclipse.gmf.runtime.emf.core.internal.resourcemap;
13
14
import org.eclipse.emf.ecore.EAttribute;
15
import org.eclipse.emf.ecore.EClass;
16
import org.eclipse.emf.ecore.EPackage;
17
import org.eclipse.emf.ecore.EReference;
18
19
/**
20
 * <!-- begin-user-doc -->
21
 * The <b>Package</b> for the logical resource physical mapping metamodel.
22
 * It contains accessors for the meta objects to represent
23
 * <ul>
24
 *   <li>each class,</li>
25
 *   <li>each feature of each class,</li>
26
 *   <li>each enum,</li>
27
 *   <li>and each data type</li>
28
 * </ul>
29
 * <!-- end-user-doc -->
30
 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapFactory
31
 * @model kind="package"
32
 * @generated
33
 */
34
public interface ResourceMapPackage extends EPackage{
35
	/**
36
	 * The package name.
37
	 * <!-- begin-user-doc -->
38
	 * <!-- end-user-doc -->
39
	 * @generated
40
	 */
41
	String eNAME = "resourcemap"; //$NON-NLS-1$
42
43
	/**
44
	 * The package namespace URI.
45
	 * <!-- begin-user-doc -->
46
	 * <!-- end-user-doc -->
47
	 * @generated
48
	 */
49
	String eNS_URI = "http://www.ibm.com/RMP-MSL/7.0.0/ResourceMap"; //$NON-NLS-1$
50
51
	/**
52
	 * The package namespace name.
53
	 * <!-- begin-user-doc -->
54
	 * <!-- end-user-doc -->
55
	 * @generated
56
	 */
57
	String eNS_PREFIX = "resmap"; //$NON-NLS-1$
58
59
	/**
60
	 * The singleton instance of the package.
61
	 * <!-- begin-user-doc -->
62
	 * <!-- end-user-doc -->
63
	 * @generated
64
	 */
65
	ResourceMapPackage eINSTANCE = org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl.ResourceMapPackageImpl.init();
66
67
	/**
68
	 * The meta object id for the '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl.ResourceMapImpl <em>Resource Map</em>}' class.
69
	 * <!-- begin-user-doc -->
70
	 * <!-- end-user-doc -->
71
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl.ResourceMapImpl
72
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl.ResourceMapPackageImpl#getResourceMap()
73
	 * @generated
74
	 */
75
	int RESOURCE_MAP = 0;
76
77
	/**
78
	 * The feature id for the '<em><b>Root Map</b></em>' reference.
79
	 * <!-- begin-user-doc -->
80
	 * <!-- end-user-doc -->
81
	 * @generated
82
	 * @ordered
83
	 */
84
	int RESOURCE_MAP__ROOT_MAP = 0;
85
86
	/**
87
	 * The feature id for the '<em><b>Parent Entries</b></em>' containment reference list.
88
	 * <!-- begin-user-doc -->
89
	 * <!-- end-user-doc -->
90
	 * @generated
91
	 * @ordered
92
	 */
93
	int RESOURCE_MAP__PARENT_ENTRIES = 1;
94
95
	/**
96
	 * The feature id for the '<em><b>Child Entries</b></em>' containment reference list.
97
	 * <!-- begin-user-doc -->
98
	 * <!-- end-user-doc -->
99
	 * @generated
100
	 * @ordered
101
	 */
102
	int RESOURCE_MAP__CHILD_ENTRIES = 2;
103
104
	/**
105
	 * The number of structural features of the the '<em>Resource Map</em>' class.
106
	 * <!-- begin-user-doc -->
107
	 * <!-- end-user-doc -->
108
	 * @generated
109
	 * @ordered
110
	 */
111
	int RESOURCE_MAP_FEATURE_COUNT = 3;
112
113
	/**
114
	 * The meta object id for the '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl.ResourceEntryImpl <em>Resource Entry</em>}' class.
115
	 * <!-- begin-user-doc -->
116
	 * <!-- end-user-doc -->
117
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl.ResourceEntryImpl
118
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl.ResourceMapPackageImpl#getResourceEntry()
119
	 * @generated
120
	 */
121
	int RESOURCE_ENTRY = 1;
122
123
	/**
124
	 * The feature id for the '<em><b>Resource</b></em>' attribute.
125
	 * <!-- begin-user-doc -->
126
	 * <!-- end-user-doc -->
127
	 * @generated
128
	 * @ordered
129
	 */
130
	int RESOURCE_ENTRY__RESOURCE = 0;
131
132
	/**
133
	 * The feature id for the '<em><b>Child Position</b></em>' attribute.
134
	 * <!-- begin-user-doc -->
135
	 * <!-- end-user-doc -->
136
	 * @generated
137
	 * @ordered
138
	 */
139
	int RESOURCE_ENTRY__CHILD_POSITION = 1;
140
141
	/**
142
	 * The feature id for the '<em><b>Child Object</b></em>' reference.
143
	 * <!-- begin-user-doc -->
144
	 * <!-- end-user-doc -->
145
	 * @generated
146
	 * @ordered
147
	 */
148
	int RESOURCE_ENTRY__CHILD_OBJECT = 2;
149
150
	/**
151
	 * The feature id for the '<em><b>Parent Entry</b></em>' reference.
152
	 * <!-- begin-user-doc -->
153
	 * <!-- end-user-doc -->
154
	 * @generated
155
	 * @ordered
156
	 */
157
	int RESOURCE_ENTRY__PARENT_ENTRY = 3;
158
159
	/**
160
	 * The number of structural features of the the '<em>Resource Entry</em>' class.
161
	 * <!-- begin-user-doc -->
162
	 * <!-- end-user-doc -->
163
	 * @generated
164
	 * @ordered
165
	 */
166
	int RESOURCE_ENTRY_FEATURE_COUNT = 4;
167
168
	/**
169
	 * The meta object id for the '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl.ParentEntryImpl <em>Parent Entry</em>}' class.
170
	 * <!-- begin-user-doc -->
171
	 * <!-- end-user-doc -->
172
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl.ParentEntryImpl
173
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl.ResourceMapPackageImpl#getParentEntry()
174
	 * @generated
175
	 */
176
	int PARENT_ENTRY = 2;
177
178
	/**
179
	 * The feature id for the '<em><b>Parent Object</b></em>' reference.
180
	 * <!-- begin-user-doc -->
181
	 * <!-- end-user-doc -->
182
	 * @generated
183
	 * @ordered
184
	 */
185
	int PARENT_ENTRY__PARENT_OBJECT = 0;
186
187
	/**
188
	 * The feature id for the '<em><b>Child Slot</b></em>' reference.
189
	 * <!-- begin-user-doc -->
190
	 * <!-- end-user-doc -->
191
	 * @generated
192
	 * @ordered
193
	 */
194
	int PARENT_ENTRY__CHILD_SLOT = 1;
195
196
	/**
197
	 * The feature id for the '<em><b>Resource Entries</b></em>' containment reference list.
198
	 * <!-- begin-user-doc -->
199
	 * <!-- end-user-doc -->
200
	 * @generated
201
	 * @ordered
202
	 */
203
	int PARENT_ENTRY__RESOURCE_ENTRIES = 2;
204
205
	/**
206
	 * The feature id for the '<em><b>Resource Map</b></em>' reference.
207
	 * <!-- begin-user-doc -->
208
	 * <!-- end-user-doc -->
209
	 * @generated
210
	 * @ordered
211
	 */
212
	int PARENT_ENTRY__RESOURCE_MAP = 3;
213
214
	/**
215
	 * The number of structural features of the the '<em>Parent Entry</em>' class.
216
	 * <!-- begin-user-doc -->
217
	 * <!-- end-user-doc -->
218
	 * @generated
219
	 * @ordered
220
	 */
221
	int PARENT_ENTRY_FEATURE_COUNT = 4;
222
223
224
	/**
225
	 * The meta object id for the '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl.ChildEntryImpl <em>Child Entry</em>}' class.
226
	 * <!-- begin-user-doc -->
227
	 * <!-- end-user-doc -->
228
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl.ChildEntryImpl
229
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.impl.ResourceMapPackageImpl#getChildEntry()
230
	 * @generated
231
	 */
232
	int CHILD_ENTRY = 3;
233
234
	/**
235
	 * The feature id for the '<em><b>Child Object</b></em>' reference.
236
	 * <!-- begin-user-doc -->
237
	 * <!-- end-user-doc -->
238
	 * @generated
239
	 * @ordered
240
	 */
241
	int CHILD_ENTRY__CHILD_OBJECT = 0;
242
243
	/**
244
	 * The feature id for the '<em><b>Parent Map</b></em>' reference.
245
	 * <!-- begin-user-doc -->
246
	 * <!-- end-user-doc -->
247
	 * @generated
248
	 * @ordered
249
	 */
250
	int CHILD_ENTRY__PARENT_MAP = 1;
251
252
	/**
253
	 * The number of structural features of the the '<em>Child Entry</em>' class.
254
	 * <!-- begin-user-doc -->
255
	 * <!-- end-user-doc -->
256
	 * @generated
257
	 * @ordered
258
	 */
259
	int CHILD_ENTRY_FEATURE_COUNT = 2;
260
261
262
	/**
263
	 * Returns the meta object for class '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap <em>Resource Map</em>}'.
264
	 * <!-- begin-user-doc -->
265
	 * <!-- end-user-doc -->
266
	 * @return the meta object for class '<em>Resource Map</em>'.
267
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap
268
	 * @generated
269
	 */
270
	EClass getResourceMap();
271
272
	/**
273
	 * Returns the meta object for the reference '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap#getRootMap <em>Root Map</em>}'.
274
	 * <!-- begin-user-doc -->
275
	 * <!-- end-user-doc -->
276
	 * @return the meta object for the reference '<em>Root Map</em>'.
277
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap#getRootMap()
278
	 * @see #getResourceMap()
279
	 * @generated
280
	 */
281
	EReference getResourceMap_RootMap();
282
283
	/**
284
	 * Returns the meta object for the containment reference list '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap#getParentEntries <em>Parent Entries</em>}'.
285
	 * <!-- begin-user-doc -->
286
	 * <!-- end-user-doc -->
287
	 * @return the meta object for the containment reference list '<em>Parent Entries</em>'.
288
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap#getParentEntries()
289
	 * @see #getResourceMap()
290
	 * @generated
291
	 */
292
	EReference getResourceMap_ParentEntries();
293
294
	/**
295
	 * Returns the meta object for the containment reference list '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap#getChildEntries <em>Child Entries</em>}'.
296
	 * <!-- begin-user-doc -->
297
	 * <!-- end-user-doc -->
298
	 * @return the meta object for the containment reference list '<em>Child Entries</em>'.
299
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap#getChildEntries()
300
	 * @see #getResourceMap()
301
	 * @generated
302
	 */
303
	EReference getResourceMap_ChildEntries();
304
305
	/**
306
	 * Returns the meta object for class '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry <em>Resource Entry</em>}'.
307
	 * <!-- begin-user-doc -->
308
	 * <!-- end-user-doc -->
309
	 * @return the meta object for class '<em>Resource Entry</em>'.
310
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry
311
	 * @generated
312
	 */
313
	EClass getResourceEntry();
314
315
	/**
316
	 * Returns the meta object for the attribute '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry#getResource <em>Resource</em>}'.
317
	 * <!-- begin-user-doc -->
318
	 * <!-- end-user-doc -->
319
	 * @return the meta object for the attribute '<em>Resource</em>'.
320
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry#getResource()
321
	 * @see #getResourceEntry()
322
	 * @generated
323
	 */
324
	EAttribute getResourceEntry_Resource();
325
326
	/**
327
	 * Returns the meta object for the attribute '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry#getChildPosition <em>Child Position</em>}'.
328
	 * <!-- begin-user-doc -->
329
	 * <!-- end-user-doc -->
330
	 * @return the meta object for the attribute '<em>Child Position</em>'.
331
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry#getChildPosition()
332
	 * @see #getResourceEntry()
333
	 * @generated
334
	 */
335
	EAttribute getResourceEntry_ChildPosition();
336
337
	/**
338
	 * Returns the meta object for the reference '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry#getChildObject <em>Child Object</em>}'.
339
	 * <!-- begin-user-doc -->
340
	 * <!-- end-user-doc -->
341
	 * @return the meta object for the reference '<em>Child Object</em>'.
342
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry#getChildObject()
343
	 * @see #getResourceEntry()
344
	 * @generated
345
	 */
346
	EReference getResourceEntry_ChildObject();
347
348
	/**
349
	 * Returns the meta object for the reference '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry#getParentEntry <em>Parent Entry</em>}'.
350
	 * <!-- begin-user-doc -->
351
	 * <!-- end-user-doc -->
352
	 * @return the meta object for the reference '<em>Parent Entry</em>'.
353
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceEntry#getParentEntry()
354
	 * @see #getResourceEntry()
355
	 * @generated
356
	 */
357
	EReference getResourceEntry_ParentEntry();
358
359
	/**
360
	 * Returns the meta object for class '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry <em>Parent Entry</em>}'.
361
	 * <!-- begin-user-doc -->
362
	 * <!-- end-user-doc -->
363
	 * @return the meta object for class '<em>Parent Entry</em>'.
364
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry
365
	 * @generated
366
	 */
367
	EClass getParentEntry();
368
369
	/**
370
	 * Returns the meta object for the reference '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry#getParentObject <em>Parent Object</em>}'.
371
	 * <!-- begin-user-doc -->
372
	 * <!-- end-user-doc -->
373
	 * @return the meta object for the reference '<em>Parent Object</em>'.
374
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry#getParentObject()
375
	 * @see #getParentEntry()
376
	 * @generated
377
	 */
378
	EReference getParentEntry_ParentObject();
379
380
	/**
381
	 * Returns the meta object for the reference '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry#getChildSlot <em>Child Slot</em>}'.
382
	 * <!-- begin-user-doc -->
383
	 * <!-- end-user-doc -->
384
	 * @return the meta object for the reference '<em>Child Slot</em>'.
385
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry#getChildSlot()
386
	 * @see #getParentEntry()
387
	 * @generated
388
	 */
389
	EReference getParentEntry_ChildSlot();
390
391
	/**
392
	 * Returns the meta object for the containment reference list '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry#getResourceEntries <em>Resource Entries</em>}'.
393
	 * <!-- begin-user-doc -->
394
	 * <!-- end-user-doc -->
395
	 * @return the meta object for the containment reference list '<em>Resource Entries</em>'.
396
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry#getResourceEntries()
397
	 * @see #getParentEntry()
398
	 * @generated
399
	 */
400
	EReference getParentEntry_ResourceEntries();
401
402
	/**
403
	 * Returns the meta object for the reference '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry#getResourceMap <em>Resource Map</em>}'.
404
	 * <!-- begin-user-doc -->
405
	 * <!-- end-user-doc -->
406
	 * @return the meta object for the reference '<em>Resource Map</em>'.
407
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry#getResourceMap()
408
	 * @see #getParentEntry()
409
	 * @generated
410
	 */
411
	EReference getParentEntry_ResourceMap();
412
413
	/**
414
	 * Returns the meta object for class '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ChildEntry <em>Child Entry</em>}'.
415
	 * <!-- begin-user-doc -->
416
	 * <!-- end-user-doc -->
417
	 * @return the meta object for class '<em>Child Entry</em>'.
418
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ChildEntry
419
	 * @generated
420
	 */
421
	EClass getChildEntry();
422
423
	/**
424
	 * Returns the meta object for the reference '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ChildEntry#getChildObject <em>Child Object</em>}'.
425
	 * <!-- begin-user-doc -->
426
	 * <!-- end-user-doc -->
427
	 * @return the meta object for the reference '<em>Child Object</em>'.
428
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ChildEntry#getChildObject()
429
	 * @see #getChildEntry()
430
	 * @generated
431
	 */
432
	EReference getChildEntry_ChildObject();
433
434
	/**
435
	 * Returns the meta object for the reference '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ChildEntry#getParentMap <em>Parent Map</em>}'.
436
	 * <!-- begin-user-doc -->
437
	 * <!-- end-user-doc -->
438
	 * @return the meta object for the reference '<em>Parent Map</em>'.
439
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ChildEntry#getParentMap()
440
	 * @see #getChildEntry()
441
	 * @generated
442
	 */
443
	EReference getChildEntry_ParentMap();
444
445
	/**
446
	 * Returns the factory that creates the instances of the model.
447
	 * <!-- begin-user-doc -->
448
	 * <!-- end-user-doc -->
449
	 * @return the factory that creates the instances of the model.
450
	 * @generated
451
	 */
452
	ResourceMapFactory getResourceMapFactory();
453
454
} //ResourceMapPackage
(-)src/org/eclipse/gmf/runtime/emf/core/internal/resourcemap/ResourceMap.java (-157 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
package org.eclipse.gmf.runtime.emf.core.internal.resourcemap;
13
14
import org.eclipse.emf.common.util.EList;
15
import org.eclipse.emf.ecore.EObject;
16
import org.eclipse.emf.ecore.EReference;
17
18
/**
19
 * <!-- begin-user-doc -->
20
 * Physical mapping of child and parent units for a unit of a logical resource.
21
 * The resource map has a list of {@link ParentEntry}s with physical-URI
22
 * references to sub-units and a list of {@link ChildEntry}s with physical-URI
23
 * references to parent units.  The resource map also has a direct reference
24
 * to the root resource in the structure, so that each unit individually knows
25
 * the logical URI of the logical resource that owns it.
26
 * <!-- end-user-doc -->
27
 *
28
 * <p>
29
 * The following features are supported:
30
 * <ul>
31
 *   <li>{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap#getRootMap <em>Root Map</em>}</li>
32
 *   <li>{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap#getParentEntries <em>Parent Entries</em>}</li>
33
 *   <li>{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap#getChildEntries <em>Child Entries</em>}</li>
34
 * </ul>
35
 * </p>
36
 *
37
 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage#getResourceMap()
38
 * @model
39
 * @generated
40
 */
41
public interface ResourceMap extends EObject{
42
	/**
43
	 * Returns the value of the '<em><b>Root Map</b></em>' reference.
44
	 * <!-- begin-user-doc -->
45
	 * <p>
46
	 * Obtains the reference to the root resource, via its resource map object.
47
	 * Only the root resource, itself, does not have this reference.
48
	 * </p>
49
	 * <!-- end-user-doc -->
50
	 * @return the value of the '<em>Root Map</em>' reference.
51
	 * @see #setRootMap(ResourceMap)
52
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage#getResourceMap_RootMap()
53
	 * @model
54
	 * @generated
55
	 */
56
	ResourceMap getRootMap();
57
58
	/**
59
	 * Sets the value of the '{@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap#getRootMap <em>Root Map</em>}' reference.
60
	 * <!-- begin-user-doc -->
61
	 * <p>
62
	 * Sets the root resource map reference.  Only the root resource should
63
	 * have a <code>null</code> value.
64
	 * </p>
65
	 * <!-- end-user-doc -->
66
	 * @param value the new value of the '<em>Root Map</em>' reference.
67
	 * @see #getRootMap()
68
	 * @generated
69
	 */
70
	void setRootMap(ResourceMap value);
71
72
	/**
73
	 * Returns the value of the '<em><b>Parent Entries</b></em>' containment reference list.
74
	 * The list contents are of type {@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry}.
75
	 * <!-- begin-user-doc -->
76
	 * <p>
77
	 * Obtains the list of parent entries indicating child units.
78
	 * </p>
79
	 * <!-- end-user-doc -->
80
	 * @return the value of the '<em>Parent Entries</em>' containment reference list.
81
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage#getResourceMap_ParentEntries()
82
	 * @model type="org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ParentEntry" containment="true" ordered="false"
83
	 * @generated
84
	 */
85
	EList getParentEntries();
86
87
	/**
88
	 * Returns the value of the '<em><b>Child Entries</b></em>' containment reference list.
89
	 * The list contents are of type {@link org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ChildEntry}.
90
	 * <!-- begin-user-doc -->
91
	 * <p>
92
	 * Obtains the list of child entries indicating parent units.
93
	 * </p>
94
	 * <!-- end-user-doc -->
95
	 * @return the value of the '<em>Child Entries</em>' containment reference list.
96
	 * @see org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage#getResourceMap_ChildEntries()
97
	 * @model type="org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ChildEntry" containment="true" ordered="false"
98
	 * @generated
99
	 */
100
	EList getChildEntries();
101
102
	/**
103
	 * <!-- begin-user-doc -->
104
	 * Obtains the parent entry for the specified <code>parent</code> element
105
	 * and containment <code>slot</code>.
106
	 * 
107
	 * @param parent a model element
108
	 * @param slot a containment reference of the <code>parent</code>'s class
109
	 * @return the matching parent entry object, or <code>null</code> if there
110
	 *     is none such
111
	 * <!-- end-user-doc -->
112
	 * @model parentRequired="true" slotRequired="true"
113
	 * @generated
114
	 */
115
	ParentEntry getParentEntry(EObject parent, EReference slot);
116
117
	/**
118
	 * <!-- begin-user-doc -->
119
	 * Obtains the resource entry for the specified <code>child</code> element
120
	 * in whatever parent element it is currently defined.
121
	 * 
122
	 * @param child a model element
123
	 * @return the matching resource entry object, or <code>null</code> if there
124
	 *     is none such
125
	 * <!-- end-user-doc -->
126
	 * @model childRequired="true"
127
	 * @generated
128
	 */
129
	ResourceEntry getResourceEntry(EObject child);
130
131
	/**
132
	 * <!-- begin-user-doc -->
133
	 * Obtains the resource map of the parent unit of the speified
134
	 * <code>child</code> element.
135
	 * 
136
	 * @param child a model element
137
	 * @return the parent unit's resource map (as a handle on the parent
138
	 *     resource), or <code>null</code> if there is none
139
	 * <!-- end-user-doc -->
140
	 * @model childRequired="true"
141
	 * @generated
142
	 */
143
	ResourceMap getParentMap(EObject child);
144
145
	/**
146
	 * <!-- begin-user-doc -->
147
	 * Obtains the child entry for the speified <code>child</code> element.
148
	 * 
149
	 * @param child a model element
150
	 * @return the child entry, or <code>null</code> if there is none
151
	 * <!-- end-user-doc -->
152
	 * @model childRequired="true"
153
	 * @generated
154
	 */
155
	ChildEntry getChildEntry(EObject child);
156
157
} // ResourceMap
(-)src/org/eclipse/gmf/runtime/emf/core/util/EObjectContainmentWithInverseLoadingEList.java (-16 / +4 lines)
Lines 12-30 Link Here
12
12
13
package org.eclipse.gmf.runtime.emf.core.util;
13
package org.eclipse.gmf.runtime.emf.core.util;
14
14
15
import org.eclipse.emf.ecore.EObject;
16
import org.eclipse.emf.ecore.InternalEObject;
15
import org.eclipse.emf.ecore.InternalEObject;
17
import org.eclipse.emf.ecore.resource.Resource;
18
import org.eclipse.emf.ecore.util.EObjectContainmentWithInverseEList;
16
import org.eclipse.emf.ecore.util.EObjectContainmentWithInverseEList;
19
17
20
import org.eclipse.gmf.runtime.emf.core.internal.resources.LogicalResourceUtil;
21
22
18
23
/**
19
/**
24
 * Specialized containment reference list (with inverse) that automatically
20
 * Specialized containment reference list (with inverse) that automatically
25
 * loads sub-unit objects when they are retrieved from the list.
21
 * loads sub-unit objects when they are retrieved from the list.
26
 *
22
 *
27
 * @author Christian W. Damus (cdamus)
23
 * @author Christian W. Damus (cdamus)
24
 * 
25
 * @deprecated Use the cross-resource containment support provided by EMF,
26
 *     instead, by defining containment features that are capable of storing
27
 *     proxies.
28
 */
28
 */
29
public class EObjectContainmentWithInverseLoadingEList
29
public class EObjectContainmentWithInverseLoadingEList
30
	extends EObjectContainmentWithInverseEList {
30
	extends EObjectContainmentWithInverseEList {
Lines 44-59 Link Here
44
			InternalEObject owner, int featureID, int inverseFeatureID) {
44
			InternalEObject owner, int featureID, int inverseFeatureID) {
45
		super(dataClass, owner, featureID, inverseFeatureID);
45
		super(dataClass, owner, featureID, inverseFeatureID);
46
	}
46
	}
47
48
	protected Object resolve(int index, Object object) {
49
		EObject eObject = (EObject) object;
50
		Resource res = getEObject().eResource();
51
		
52
		if (res != null) {
53
			LogicalResourceUtil.autoload(res, eObject);
54
		}
55
		
56
		return eObject;
57
	}
58
59
}
47
}
(-)src/org/eclipse/gmf/runtime/emf/core/util/EObjectContainmentLoadingEList.java (-15 / +4 lines)
Lines 12-30 Link Here
12
12
13
package org.eclipse.gmf.runtime.emf.core.util;
13
package org.eclipse.gmf.runtime.emf.core.util;
14
14
15
import org.eclipse.emf.ecore.EObject;
16
import org.eclipse.emf.ecore.InternalEObject;
15
import org.eclipse.emf.ecore.InternalEObject;
17
import org.eclipse.emf.ecore.resource.Resource;
18
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
16
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
19
17
20
import org.eclipse.gmf.runtime.emf.core.internal.resources.LogicalResourceUtil;
21
22
18
23
/**
19
/**
24
 * Specialized containment reference list that automatically loads sub-unit
20
 * Specialized containment reference list that automatically loads sub-unit
25
 * objects when they are retrieved from the list.
21
 * objects when they are retrieved from the list.
26
 *
22
 *
27
 * @author Christian W. Damus (cdamus)
23
 * @author Christian W. Damus (cdamus)
24
 * 
25
 * @deprecated Use the cross-resource containment support provided by EMF,
26
 *     instead, by defining containment features that are capable of storing
27
 *     proxies.
28
 */
28
 */
29
public class EObjectContainmentLoadingEList
29
public class EObjectContainmentLoadingEList
30
	extends EObjectContainmentEList {
30
	extends EObjectContainmentEList {
Lines 42-56 Link Here
42
			InternalEObject owner, int featureID) {
42
			InternalEObject owner, int featureID) {
43
		super(dataClass, owner, featureID);
43
		super(dataClass, owner, featureID);
44
	}
44
	}
45
46
	protected Object resolve(int index, Object object) {
47
		EObject eObject = (EObject) object;
48
		Resource res = getEObject().eResource();
49
		
50
		if (res != null) {
51
			LogicalResourceUtil.autoload(res, eObject);
52
		}
53
		
54
		return eObject;
55
	}
56
}
45
}
(-)src/org/eclipse/gmf/runtime/emf/core/util/ResourceUtil.java (-1 / +9 lines)
Lines 79-84 Link Here
79
	 * @return whether the <code>resource</code> is a logical resource
79
	 * @return whether the <code>resource</code> is a logical resource
80
	 * 
80
	 * 
81
	 * @see ILogicalResource
81
	 * @see ILogicalResource
82
	 * 
83
	 * @deprecated Use the cross-resource containment support provided by EMF,
84
	 *     instead, by defining containment features that are capable of storing
85
	 *     proxies.
82
	 */
86
	 */
83
	public static boolean isLogicalResource(Resource resource) {
87
	public static boolean isLogicalResource(Resource resource) {
84
		return MEditingDomain.INSTANCE.isLogicalResource(resource);
88
		return MEditingDomain.INSTANCE.isLogicalResource(resource);
Lines 93-99 Link Here
93
	 * 
97
	 * 
94
	 * @param resource a resource for which we want to obtain a logical view
98
	 * @param resource a resource for which we want to obtain a logical view
95
	 * @return the logical view of the resource
99
	 * @return the logical view of the resource
96
	 */
100
	 * 
101
	 * @deprecated Use the cross-resource containment support provided by EMF,
102
	 *     instead, by defining containment features that are capable of storing
103
	 *     proxies.
104
s	 */
97
	public static ILogicalResource asLogicalResource(Resource resource) {
105
	public static ILogicalResource asLogicalResource(Resource resource) {
98
		return MEditingDomain.INSTANCE.asLogicalResource(resource);
106
		return MEditingDomain.INSTANCE.asLogicalResource(resource);
99
	}
107
	}
(-)src/org/eclipse/gmf/runtime/emf/core/internal/commands/MSLSeparateCommand.java (-109 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
13
package org.eclipse.gmf.runtime.emf.core.internal.commands;
14
15
import org.eclipse.emf.common.util.EList;
16
import org.eclipse.emf.ecore.EObject;
17
import org.eclipse.emf.ecore.EStructuralFeature;
18
import org.eclipse.emf.ecore.resource.Resource;
19
import org.eclipse.gmf.runtime.common.core.util.Trace;
20
import org.eclipse.gmf.runtime.emf.core.exceptions.MSLRuntimeException;
21
import org.eclipse.gmf.runtime.emf.core.internal.domain.MSLEditingDomain;
22
import org.eclipse.gmf.runtime.emf.core.internal.l10n.EMFCoreMessages;
23
import org.eclipse.gmf.runtime.emf.core.internal.plugin.MSLDebugOptions;
24
import org.eclipse.gmf.runtime.emf.core.internal.plugin.MSLPlugin;
25
import org.eclipse.gmf.runtime.emf.core.resources.CannotAbsorbException;
26
import org.eclipse.gmf.runtime.emf.core.resources.CannotSeparateException;
27
import org.eclipse.gmf.runtime.emf.core.resources.ILogicalResource;
28
29
30
/**
31
 * Command that undoes/redoes separation of an element into another resource.
32
 *
33
 * @author Christian W. Damus (cdamus)
34
 */
35
public class MSLSeparateCommand
36
	extends MSLBasicCommand {
37
38
	private EObject child;
39
	private ILogicalResource res;
40
	private Resource subres;
41
	
42
	/**
43
	 * Initializes me.
44
	 * 
45
	 * @param domain the editing domain in which I occurred
46
	 * @param owner the container element that notified
47
	 * @param feature the containment feature
48
	 * @param position the index in the containment feature of the separated
49
	 *     object (or -1 if not a list feature)
50
	 * @param resource the new physical resource of the child element
51
	 */
52
	public MSLSeparateCommand(MSLEditingDomain domain, EObject owner,
53
			EStructuralFeature feature, int position, Resource resource) {
54
		super(domain, owner, feature);
55
		
56
		if (position < 0) {
57
			// must be a scalar feature
58
			this.child = (EObject) owner.eGet(feature);
59
		} else {
60
			// no need to worry about proxies in a containment feature
61
			this.child = (EObject) ((EList) owner.eGet(feature)).get(position);
62
		}
63
		
64
		this.res = (ILogicalResource) child.eResource();
65
		this.subres = resource;
66
	}
67
68
	public void dispose() {
69
		super.dispose();
70
		
71
		child = null;
72
		res = null;
73
		subres = null;
74
	}
75
	
76
	public Type getType() {
77
		return MCommand.SEPARATE;
78
	}
79
80
	public void undo() {
81
		try {
82
			res.absorb(child);
83
		} catch (CannotAbsorbException e) {
84
			RuntimeException re = new MSLRuntimeException(
85
				EMFCoreMessages.absorption_failed_EXC_,
86
					e);
87
	
88
			Trace.throwing(MSLPlugin.getDefault(),
89
				MSLDebugOptions.EXCEPTIONS_THROWING, getClass(), "undo", e); //$NON-NLS-1$
90
	
91
			throw re;
92
		}
93
	}
94
95
	public void redo() {
96
		try {
97
			res.separate(child, subres.getURI());
98
		} catch (CannotSeparateException e) {
99
			RuntimeException re = new MSLRuntimeException(
100
				EMFCoreMessages.separation_failed_EXC_,
101
					e);
102
103
			Trace.throwing(MSLPlugin.getDefault(),
104
				MSLDebugOptions.EXCEPTIONS_THROWING, getClass(), "redo", e); //$NON-NLS-1$
105
106
			throw re;
107
		}
108
	}
109
}
(-)src/org/eclipse/gmf/runtime/emf/core/internal/commands/MSLAbsorbCommand.java (-109 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
13
package org.eclipse.gmf.runtime.emf.core.internal.commands;
14
15
import org.eclipse.emf.common.util.EList;
16
import org.eclipse.emf.ecore.EObject;
17
import org.eclipse.emf.ecore.EStructuralFeature;
18
import org.eclipse.emf.ecore.resource.Resource;
19
import org.eclipse.gmf.runtime.common.core.util.Trace;
20
import org.eclipse.gmf.runtime.emf.core.exceptions.MSLRuntimeException;
21
import org.eclipse.gmf.runtime.emf.core.internal.domain.MSLEditingDomain;
22
import org.eclipse.gmf.runtime.emf.core.internal.l10n.EMFCoreMessages;
23
import org.eclipse.gmf.runtime.emf.core.internal.plugin.MSLDebugOptions;
24
import org.eclipse.gmf.runtime.emf.core.internal.plugin.MSLPlugin;
25
import org.eclipse.gmf.runtime.emf.core.resources.CannotAbsorbException;
26
import org.eclipse.gmf.runtime.emf.core.resources.CannotSeparateException;
27
import org.eclipse.gmf.runtime.emf.core.resources.ILogicalResource;
28
29
30
/**
31
 * Command that undoes/redoes absorption of an element from another resource.
32
 *
33
 * @author Christian W. Damus (cdamus)
34
 */
35
public class MSLAbsorbCommand
36
	extends MSLBasicCommand {
37
38
	private EObject child;
39
	private ILogicalResource res;
40
	private Resource subres;
41
	
42
	/**
43
	 * Initializes me.
44
	 * 
45
	 * @param domain the editing domain in which I occurred
46
	 * @param owner the container element that notified
47
	 * @param feature the containment feature
48
	 * @param position the index in the containment feature of the absorbed
49
	 *     object (or -1 if not a list feature)
50
	 * @param resource the old physical resource of the child element
51
	 */
52
	public MSLAbsorbCommand(MSLEditingDomain domain, EObject owner,
53
			EStructuralFeature feature, int position, Resource resource) {
54
		super(domain, owner, feature);
55
		
56
		if (position < 0) {
57
			// must be a scalar feature
58
			this.child = (EObject) owner.eGet(feature);
59
		} else {
60
			// no need to worry about proxies in a containment feature
61
			this.child = (EObject) ((EList) owner.eGet(feature)).get(position);
62
		}
63
		
64
		this.res = (ILogicalResource) child.eResource();
65
		this.subres = resource;
66
	}
67
68
	public void dispose() {
69
		super.dispose();
70
		
71
		child = null;
72
		res = null;
73
		subres = null;
74
	}
75
	
76
	public Type getType() {
77
		return MCommand.ABSORB;
78
	}
79
80
	public void undo() {
81
		try {
82
			res.separate(child, subres.getURI());
83
		} catch (CannotSeparateException e) {
84
			RuntimeException re = new MSLRuntimeException(
85
				EMFCoreMessages.separation_failed_EXC_,
86
					e);
87
88
			Trace.throwing(MSLPlugin.getDefault(),
89
				MSLDebugOptions.EXCEPTIONS_THROWING, getClass(), "undo", e); //$NON-NLS-1$
90
91
			throw re;
92
		}
93
	}
94
95
	public void redo() {
96
		try {
97
			res.absorb(child);
98
		} catch (CannotAbsorbException e) {
99
			RuntimeException re = new MSLRuntimeException(
100
				EMFCoreMessages.absorption_failed_EXC_,
101
					e);
102
	
103
			Trace.throwing(MSLPlugin.getDefault(),
104
				MSLDebugOptions.EXCEPTIONS_THROWING, getClass(), "redo", e); //$NON-NLS-1$
105
	
106
			throw re;
107
		}
108
	}
109
}
(-)src/org/eclipse/gmf/runtime/emf/core/internal/commands/MSLCommandGenerator.java (-14 lines)
Lines 143-162 Link Here
143
143
144
					break;
144
					break;
145
				}
145
				}
146
				
147
				case EventTypes.SEPARATE: {
148
					MSLUtil.execute(domain, new MSLSeparateCommand(domain,
149
						notifier, structuralFeature, position, (Resource) newValue));
150
					
151
					break;
152
				}
153
				
154
				case EventTypes.ABSORB: {
155
					MSLUtil.execute(domain, new MSLAbsorbCommand(domain,
156
						notifier, structuralFeature, position, (Resource) oldValue));
157
					
158
					break;
159
				}
160
			}
146
			}
161
		}
147
		}
162
	}
148
	}
(-)src/org/eclipse/gmf/runtime/emf/core/internal/domain/MSLEditingDomain.java (-8 / +2 lines)
Lines 650-663 Link Here
650
				loadOptions.put(XMLResource.OPTION_EXTENDED_META_DATA,
650
				loadOptions.put(XMLResource.OPTION_EXTENDED_META_DATA,
651
					extendedMetaData);
651
					extendedMetaData);
652
			}
652
			}
653
654
			if ((options & MResourceOption.LOAD_ALL_SUBUNITS) != 0) {
655
				loadOptions.put(ILogicalResource.OPTION_LOAD_ALL_UNITS,
656
					Boolean.TRUE);
657
			} else if ((options & MResourceOption.DONT_AUTO_LOAD_SUBUNITS) != 0) {
658
				loadOptions.put(ILogicalResource.OPTION_AUTO_LOAD_UNITS,
659
					Boolean.FALSE);
660
			}
661
			
653
			
662
			if (null == inputStream)
654
			if (null == inputStream)
663
				resource.load(loadOptions);
655
				resource.load(loadOptions);
Lines 1967-1976 Link Here
1967
		}
1959
		}
1968
	}
1960
	}
1969
1961
1962
	/** @deprecated */
1970
	public boolean isLogicalResource(Resource resource) {
1963
	public boolean isLogicalResource(Resource resource) {
1971
		return resource instanceof ILogicalResource;
1964
		return resource instanceof ILogicalResource;
1972
	}
1965
	}
1973
	
1966
	
1967
	/** @deprecated */
1974
	public ILogicalResource asLogicalResource(Resource resource) {
1968
	public ILogicalResource asLogicalResource(Resource resource) {
1975
		ILogicalResource result = null;
1969
		ILogicalResource result = null;
1976
		
1970
		
(-)schema/resourcePolicies.exsd (-6 / +11 lines)
Lines 51-56 Link Here
51
51
52
   <element name="policy">
52
   <element name="policy">
53
      <annotation>
53
      <annotation>
54
         <appInfo>
55
            <meta.element deprecated="true"/>
56
         </appInfo>
54
         <documentation>
57
         <documentation>
55
            A policy applies certain metamodel- or application-specific constraints on the management of logical resources.  The policy implements a callback interface defining hooks for these constraints and for insertion of additional behaviour.
58
            A policy applies certain metamodel- or application-specific constraints on the management of logical resources.  The policy implements a callback interface defining hooks for these constraints and for insertion of additional behaviour.
56
         </documentation>
59
         </documentation>
Lines 74-79 Link Here
74
77
75
   <element name="efactory">
78
   <element name="efactory">
76
      <annotation>
79
      <annotation>
80
         <appInfo>
81
            <meta.element deprecated="true"/>
82
         </appInfo>
77
         <documentation>
83
         <documentation>
78
            A custom &lt;code&gt;EFactory&lt;/code&gt; implementation that the logical resource may use to create model elements that will automatically load their children.  This is commonly done by defining subclasses of the metamodel&apos;s basic &quot;Impl&quot; classes that substitute special containment lists for the default implementations.  These containment lists are defined in the &lt;code&gt;org.eclipse.gmf.runtime.emf.core.util&lt;/code&gt; package.
84
            A custom &lt;code&gt;EFactory&lt;/code&gt; implementation that the logical resource may use to create model elements that will automatically load their children.  This is commonly done by defining subclasses of the metamodel&apos;s basic &quot;Impl&quot; classes that substitute special containment lists for the default implementations.  These containment lists are defined in the &lt;code&gt;org.eclipse.gmf.runtime.emf.core.util&lt;/code&gt; package.
79
         </documentation>
85
         </documentation>
Lines 185-196 Link Here
185
         <meta.section type="copyright"/>
191
         <meta.section type="copyright"/>
186
      </appInfo>
192
      </appInfo>
187
      <documentation>
193
      <documentation>
188
        Copyright (c) 2005  IBM Corporation and others.&lt;br&gt;
194
         Copyright (c) 2005  IBM Corporation and others.&lt;br&gt;
189
	All rights reserved. This program and the accompanying materials 
195
 All rights reserved. This program and the accompanying materials 
190
	are made available under the terms of the Eclipse Public License v1.0 
196
 are made available under the terms of the Eclipse Public License v1.0 
191
	which accompanies this distribution, and is available at 
197
 which accompanies this distribution, and is available at 
192
	&lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
198
 &lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
193
194
      </documentation>
199
      </documentation>
195
   </annotation>
200
   </annotation>
196
201
(-)plugin.xml (-7 lines)
Lines 127-137 Link Here
127
        </elementTypeFactory>
127
        </elementTypeFactory>
128
   </extension>
128
   </extension>
129
   
129
   
130
   <extension
131
         point="org.eclipse.emf.ecore.generated_package">
132
      <package
133
            class="org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMapPackage"
134
            uri="http://www.ibm.com/RMP-MSL/7.0.0/ResourceMap"/>
135
   </extension>
136
   
137
 </plugin>
130
 </plugin>
(-)src/org/eclipse/gmf/runtime/emf/core/internal/expressions/EObjectPropertyTester.java (-19 / +15 lines)
Lines 28-47 Link Here
28
 *   <dt>objectType</dt>
28
 *   <dt>objectType</dt>
29
 *     <dd>string-valued property denoting an <code>EObject</code>'s
29
 *     <dd>string-valued property denoting an <code>EObject</code>'s
30
 *         {@linkplain org.eclipse.gmf.runtime.emf.core.internal.MObjectType object type}</dd>
30
 *         {@linkplain org.eclipse.gmf.runtime.emf.core.internal.MObjectType object type}</dd>
31
 *   <dt>canSeparate</dt>
32
 *     <dd>boolean-valued property indicating whether an <code>EObject</code>
33
 *         can be
34
 *         {@linkplain org.eclipse.gmf.runtime.emf.core.resources.ILogicalResource#canSeparate(EObject) separated}</dd>
35
 *   <dt>isSeparate</dt>
36
 *     <dd>boolean-valued property indicating whether an <code>EObject</code> is
37
 *         {@linkplain org.eclipse.gmf.runtime.emf.core.resources.ILogicalResource#isSeparate(EObject) separate}</dd>
38
 * </dl>
31
 * </dl>
39
 *
32
 *
40
 * @author Christian W. Damus (cdamus)
33
 * @author Christian W. Damus (cdamus)
41
 */
34
 */
42
public class EObjectPropertyTester extends PropertyTester {
35
public class EObjectPropertyTester extends PropertyTester {
43
	private static final String OBJECT_TYPE_PROPERTY = "objectType"; //$NON-NLS-1$
36
	private static final String OBJECT_TYPE_PROPERTY = "objectType"; //$NON-NLS-1$
37
	
38
	/**
39
	 * 
40
	 * @deprecated Use the cross-resource containment support provided by EMF,
41
	 *     instead, by defining containment features that are capable of storing
42
	 *     proxies.
43
	 */
44
	private static final String CAN_SEPARATE_PROPERTY = "canSeparate"; //$NON-NLS-1$
44
	private static final String CAN_SEPARATE_PROPERTY = "canSeparate"; //$NON-NLS-1$
45
	/**
46
	 * 
47
	 * @deprecated Use the cross-resource containment support provided by EMF,
48
	 *     instead, by defining containment features that are capable of storing
49
	 *     proxies.
50
	 */
45
	private static final String IS_SEPARATE_PROPERTY = "isSeparate"; //$NON-NLS-1$
51
	private static final String IS_SEPARATE_PROPERTY = "isSeparate"; //$NON-NLS-1$
46
	
52
	
47
	/**
53
	/**
Lines 98-116 Link Here
98
		if (property.equals(OBJECT_TYPE_PROPERTY)) {
104
		if (property.equals(OBJECT_TYPE_PROPERTY)) {
99
			result = EObjectUtil.getType(eObject).getName().equals(expectedValue);
105
			result = EObjectUtil.getType(eObject).getName().equals(expectedValue);
100
		} else if (property.equals(CAN_SEPARATE_PROPERTY)) {
106
		} else if (property.equals(CAN_SEPARATE_PROPERTY)) {
101
			Resource res = eObject.eResource();
107
			return Boolean.FALSE;
102
			MEditingDomain domain = MEditingDomain.getEditingDomain(res);
103
			
104
			if (domain != null) {
105
				result = domain.asLogicalResource(res).canSeparate(eObject);
106
			}
107
		} else if (property.equals(IS_SEPARATE_PROPERTY)) {
108
		} else if (property.equals(IS_SEPARATE_PROPERTY)) {
108
			Resource res = eObject.eResource();
109
			return Boolean.FALSE;
109
			MEditingDomain domain = MEditingDomain.getEditingDomain(res);
110
			
111
			if (domain != null) {
112
				result = domain.asLogicalResource(res).isSeparate(eObject);
113
			}
114
		}
110
		}
115
		
111
		
116
		return Boolean.valueOf(result);
112
		return Boolean.valueOf(result);
(-)src/org/eclipse/gmf/runtime/emf/core/EventTypes.java (+12 lines)
Lines 181-186 Link Here
181
	 * {@link Notification#getNewValue()}.
181
	 * {@link Notification#getNewValue()}.
182
	 * 
182
	 * 
183
	 * @see org.eclipse.emf.common.notify.Notification#getEventType
183
	 * @see org.eclipse.emf.common.notify.Notification#getEventType
184
	 * 
185
	 * @deprecated Use the cross-resource containment support provided by EMF,
186
	 *     instead, by defining containment features that are capable of storing
187
	 *     proxies.
184
	 */
188
	 */
185
	public static final int SEPARATE = 1006;
189
	public static final int SEPARATE = 1006;
186
190
Lines 193-198 Link Here
193
	 * {@link Notification#getOldValue()}.
197
	 * {@link Notification#getOldValue()}.
194
	 * 
198
	 * 
195
	 * @see org.eclipse.emf.common.notify.Notification#getEventType
199
	 * @see org.eclipse.emf.common.notify.Notification#getEventType
200
	 * 
201
	 * @deprecated Use the cross-resource containment support provided by EMF,
202
	 *     instead, by defining containment features that are capable of storing
203
	 *     proxies.
196
	 */
204
	 */
197
	public static final int ABSORB = 1007;
205
	public static final int ABSORB = 1007;
198
206
Lines 205-210 Link Here
205
	 * {@link Notification#getNewValue()} of the notification.
213
	 * {@link Notification#getNewValue()} of the notification.
206
	 * 
214
	 * 
207
	 * @see org.eclipse.emf.common.notify.Notification#getEventType
215
	 * @see org.eclipse.emf.common.notify.Notification#getEventType
216
	 * 
217
	 * @deprecated Use the cross-resource containment support provided by EMF,
218
	 *     instead, by defining containment features that are capable of storing
219
	 *     proxies.
208
	 */
220
	 */
209
	public static final int LOAD = 1008;
221
	public static final int LOAD = 1008;
210
222
(-)src/org/eclipse/gmf/examples/runtime/emf/actions/MSLLibraryActionBarContributor.java (-256 lines)
Lines 37-58 Link Here
37
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
37
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
38
import org.eclipse.emf.examples.extlibrary.actions.EXTLibraryExtendedActionBarContributor;
38
import org.eclipse.emf.examples.extlibrary.actions.EXTLibraryExtendedActionBarContributor;
39
import org.eclipse.emf.examples.extlibrary.presentation.EXTLibraryEditorPlugin;
39
import org.eclipse.emf.examples.extlibrary.presentation.EXTLibraryEditorPlugin;
40
import org.eclipse.gmf.examples.runtime.emf.MSLExamplePlugin;
41
import org.eclipse.gmf.examples.runtime.emf.constraints.ValidationDelegateClientSelector;
40
import org.eclipse.gmf.examples.runtime.emf.constraints.ValidationDelegateClientSelector;
42
import org.eclipse.gmf.examples.runtime.emf.dialogs.ValidationErrorDialog;
41
import org.eclipse.gmf.examples.runtime.emf.dialogs.ValidationErrorDialog;
43
import org.eclipse.gmf.examples.runtime.emf.editor.MSLLibraryEditor;
42
import org.eclipse.gmf.examples.runtime.emf.editor.MSLLibraryEditor;
44
import org.eclipse.gmf.examples.runtime.emf.internal.l10n.MSLExampleMessages;
43
import org.eclipse.gmf.examples.runtime.emf.internal.l10n.MSLExampleMessages;
45
import org.eclipse.gmf.examples.runtime.emf.properties.PropertySheetDialog;
44
import org.eclipse.gmf.examples.runtime.emf.properties.PropertySheetDialog;
46
import org.eclipse.gmf.runtime.common.core.util.Log;
47
import org.eclipse.gmf.runtime.emf.core.edit.MEditingDomain;
45
import org.eclipse.gmf.runtime.emf.core.edit.MEditingDomain;
48
import org.eclipse.gmf.runtime.emf.core.edit.MFilter;
46
import org.eclipse.gmf.runtime.emf.core.edit.MFilter;
49
import org.eclipse.gmf.runtime.emf.core.edit.MListener;
47
import org.eclipse.gmf.runtime.emf.core.edit.MListener;
50
import org.eclipse.gmf.runtime.emf.core.edit.MRunnable;
48
import org.eclipse.gmf.runtime.emf.core.edit.MRunnable;
51
import org.eclipse.gmf.runtime.emf.core.edit.MUndoInterval;
49
import org.eclipse.gmf.runtime.emf.core.edit.MUndoInterval;
52
import org.eclipse.gmf.runtime.emf.core.exceptions.MSLActionAbandonedException;
50
import org.eclipse.gmf.runtime.emf.core.exceptions.MSLActionAbandonedException;
53
import org.eclipse.gmf.runtime.emf.core.resources.CannotAbsorbException;
54
import org.eclipse.gmf.runtime.emf.core.resources.CannotSeparateException;
55
import org.eclipse.gmf.runtime.emf.core.resources.ILogicalResource;
56
import org.eclipse.gmf.runtime.emf.core.util.EObjectUtil;
51
import org.eclipse.gmf.runtime.emf.core.util.EObjectUtil;
57
import org.eclipse.gmf.runtime.emf.core.util.MetaModelUtil;
52
import org.eclipse.gmf.runtime.emf.core.util.MetaModelUtil;
58
import org.eclipse.jface.action.Action;
53
import org.eclipse.jface.action.Action;
Lines 64-70 Link Here
64
import org.eclipse.jface.dialogs.Dialog;
59
import org.eclipse.jface.dialogs.Dialog;
65
import org.eclipse.jface.dialogs.IInputValidator;
60
import org.eclipse.jface.dialogs.IInputValidator;
66
import org.eclipse.jface.dialogs.InputDialog;
61
import org.eclipse.jface.dialogs.InputDialog;
67
import org.eclipse.jface.dialogs.MessageDialog;
68
import org.eclipse.jface.viewers.ISelection;
62
import org.eclipse.jface.viewers.ISelection;
69
import org.eclipse.jface.viewers.IStructuredSelection;
63
import org.eclipse.jface.viewers.IStructuredSelection;
70
import org.eclipse.jface.viewers.SelectionChangedEvent;
64
import org.eclipse.jface.viewers.SelectionChangedEvent;
Lines 248-503 Link Here
248
		}
242
		}
249
  	}
243
  	}
250
	
244
	
251
	/**
252
	 * This action delegate refactors the selected element into a seaparate
253
	 * controlled unit.
254
	 */
255
	public static class ControlUnitDelegate
256
		implements IEditorActionDelegate, IActionDelegate2 {
257
258
		/**
259
		 * Error message to display when an exception occured
260
		 */
261
		protected static final String MESSAGE_EXCEPTION = MSLExampleMessages.message_exception;
262
263
		/**
264
		 * The shell this action is hosted in
265
		 */
266
		protected Shell shell = null;
267
268
		/**
269
		 * The active editor
270
		 */
271
		protected MSLLibraryEditor editor = null;
272
273
		/**
274
		 * Selected EObjects
275
		 */
276
		protected List selectedEObjects = null;
277
278
		/**
279
		 * The title for the action.
280
		 */
281
		private String title = MSLExampleMessages.ControlUnitAction_label;
282
		
283
		/** Action bar contributor of the MSL Library example editor. */
284
		private MSLLibraryActionBarContributor actionBarContrib;
285
		
286
		public void selectionChanged(IAction action, final ISelection selection) {
287
			this.selectedEObjects = null;
288
			try {
289
				if (selection instanceof IStructuredSelection) {
290
					IStructuredSelection structuredSelection = (IStructuredSelection) selection;
291
					this.selectedEObjects = structuredSelection.toList();
292
				}
293
			} catch (Exception e) {
294
				// Exceptions are not expected
295
				MessageDialog.openInformation(shell, title, MESSAGE_EXCEPTION);
296
				throw new RuntimeException(e);
297
			} finally {
298
				if ((null != selectedEObjects) && (selectedEObjects.size() == 1)
299
						&& (selectedEObjects.get(0) instanceof EObject)) {
300
					EObject selected = (EObject) selectedEObjects.get(0);
301
					final MEditingDomain domain = MEditingDomain.getEditingDomain(
302
						selected.eResource());
303
					ILogicalResource res = domain.asLogicalResource(
304
						selected.eResource());
305
					
306
					action.setEnabled(res.canSeparate(selected));
307
				} else {
308
					action.setEnabled(false);
309
				}
310
			}
311
		}
312
313
		public void dispose() {
314
			//No-op
315
		}
316
317
		public void setActiveEditor(IAction action, IEditorPart targetEditor) {
318
			this.editor = (MSLLibraryEditor) targetEditor;
319
			if ( targetEditor != null ) {
320
				this.shell = targetEditor.getSite().getShell();
321
				actionBarContrib = (MSLLibraryActionBarContributor)((MSLLibraryEditor)targetEditor).getActionBarContributor();
322
			} else {
323
				actionBarContrib = null;
324
			}
325
		}
326
327
		public void init(IAction action) {
328
			// No-op
329
		}
330
331
		public void runWithEvent(IAction action, Event event) {
332
			run(action);
333
		}
334
335
		public void run(final IAction action) {
336
			final EObject selected = (EObject) selectedEObjects.get(0);
337
			final MEditingDomain domain = MEditingDomain.getEditingDomain(
338
				selected.eResource());
339
			final ILogicalResource res = domain.asLogicalResource(
340
				selected.eResource());
341
			
342
			final Exception[] caught = new Exception[1];
343
			
344
			MUndoInterval undo = domain.runInUndoInterval(title, new Runnable() {
345
				public void run() {
346
					try {
347
						domain.runAsWrite(new MRunnable() {
348
							
349
							public Object run() {
350
								try {
351
									res.separate(selected, null);
352
									action.setEnabled(false);
353
								} catch (CannotSeparateException e) {
354
									caught[0] = e;
355
									MessageDialog.openError(
356
										shell,
357
										title,
358
										e.getLocalizedMessage());
359
								}
360
								return null;
361
							}});
362
					} catch (MSLActionAbandonedException e) {
363
						caught[0] = e;
364
						Log.log(MSLExamplePlugin.getDefault(), e.getStatus());
365
					}
366
				}});
367
			
368
			if (caught[0] != null) {
369
				undo.undo();
370
			} else {
371
				actionBarContrib.addUndoInterval(undo);
372
			}
373
		}
374
	}
375
	
376
	/**
377
	 * This action delegate refactors the selected element into a seaparate
378
	 * controlled unit.
379
	 */
380
	public static class UncontrolUnitDelegate
381
		implements IEditorActionDelegate, IActionDelegate2 {
382
383
		/**
384
		 * Error message to display when an exception occured
385
		 */
386
		protected static final String MESSAGE_EXCEPTION = MSLExampleMessages.message_exception;
387
388
		/**
389
		 * The shell this action is hosted in
390
		 */
391
		protected Shell shell = null;
392
393
		/**
394
		 * The active editor
395
		 */
396
		protected MSLLibraryEditor editor = null;
397
398
		/**
399
		 * Selected EObjects
400
		 */
401
		protected List selectedEObjects = null;
402
403
		/**
404
		 * The title for the action.
405
		 */
406
		private String title = MSLExampleMessages.UncontrolUnitAction_label;
407
		
408
		/** Action bar contributor of the MSL Library example editor. */
409
		private MSLLibraryActionBarContributor actionBarContrib;
410
		
411
		public void selectionChanged(IAction action, final ISelection selection) {
412
			this.selectedEObjects = null;
413
			try {
414
				if (selection instanceof IStructuredSelection) {
415
					IStructuredSelection structuredSelection = (IStructuredSelection) selection;
416
					this.selectedEObjects = structuredSelection.toList();
417
				}
418
			} catch (Exception e) {
419
				// Exceptions are not expected
420
				MessageDialog.openInformation(shell, title, MESSAGE_EXCEPTION);
421
				throw new RuntimeException(e);
422
			} finally {
423
				if ((null != selectedEObjects) && (selectedEObjects.size() == 1)
424
						&& (selectedEObjects.get(0) instanceof EObject)) {
425
					EObject selected = (EObject) selectedEObjects.get(0);
426
					final MEditingDomain domain = MEditingDomain.getEditingDomain(
427
						selected.eResource());
428
					ILogicalResource res = domain.asLogicalResource(
429
						selected.eResource());
430
					
431
					action.setEnabled(res.isSeparate(selected));
432
				} else {
433
					action.setEnabled(false);
434
				}
435
			}
436
		}
437
438
		public void dispose() {
439
			//No-op
440
		}
441
442
		public void setActiveEditor(IAction action, IEditorPart targetEditor) {
443
			this.editor = (MSLLibraryEditor) targetEditor;
444
			if ( targetEditor != null ) {
445
				this.shell = targetEditor.getSite().getShell();
446
				actionBarContrib = (MSLLibraryActionBarContributor)((MSLLibraryEditor)targetEditor).getActionBarContributor();
447
			} else {
448
				actionBarContrib = null;
449
			}
450
		}
451
452
		public void init(IAction action) {
453
			// No-op
454
		}
455
456
		public void runWithEvent(IAction action, Event event) {
457
			run(action);
458
		}
459
460
		public void run(final IAction action) {
461
			final EObject selected = (EObject) selectedEObjects.get(0);
462
			final MEditingDomain domain = MEditingDomain.getEditingDomain(
463
				selected.eResource());
464
			final ILogicalResource res = domain.asLogicalResource(
465
				selected.eResource());
466
			
467
			final Exception[] caught = new Exception[1];
468
			
469
			MUndoInterval undo = domain.runInUndoInterval(title, new Runnable() {
470
				public void run() {
471
					try {
472
						domain.runAsWrite(new MRunnable() {
473
							
474
							public Object run() {
475
								try {
476
									res.absorb(selected);
477
									action.setEnabled(false);
478
								} catch (CannotAbsorbException e) {
479
									caught[0] = e;
480
									MessageDialog.openError(
481
										shell,
482
										title,
483
										e.getLocalizedMessage());
484
								}
485
								return null;
486
							}});
487
					} catch (MSLActionAbandonedException e) {
488
						caught[0] = e;
489
						Log.log(MSLExamplePlugin.getDefault(), e.getStatus());
490
					}
491
				}});
492
			
493
			if (caught[0] != null) {
494
				undo.undo();
495
			} else {
496
				actionBarContrib.addUndoInterval(undo);
497
			}
498
		}
499
	}
500
	
501
	private class MSLDeleteAction extends DeleteAction {
245
	private class MSLDeleteAction extends DeleteAction {
502
		private Collection objects;
246
		private Collection objects;
503
		
247
		
(-)src/org/eclipse/gmf/examples/runtime/emf/actions/UnloadResourceDelegate.java (-2 / +1 lines)
Lines 17-23 Link Here
17
import org.eclipse.emf.ecore.resource.Resource;
17
import org.eclipse.emf.ecore.resource.Resource;
18
import org.eclipse.gmf.examples.runtime.emf.editor.MSLLibraryEditor;
18
import org.eclipse.gmf.examples.runtime.emf.editor.MSLLibraryEditor;
19
import org.eclipse.gmf.examples.runtime.emf.internal.l10n.MSLExampleMessages;
19
import org.eclipse.gmf.examples.runtime.emf.internal.l10n.MSLExampleMessages;
20
import org.eclipse.gmf.runtime.emf.core.edit.MEditingDomain;
21
import org.eclipse.jface.action.IAction;
20
import org.eclipse.jface.action.IAction;
22
import org.eclipse.jface.dialogs.MessageDialog;
21
import org.eclipse.jface.dialogs.MessageDialog;
23
import org.eclipse.jface.viewers.ISelection;
22
import org.eclipse.jface.viewers.ISelection;
Lines 130-136 Link Here
130
			for (Iterator i = selectedResources.iterator(); i.hasNext();) {
129
			for (Iterator i = selectedResources.iterator(); i.hasNext();) {
131
				Resource res = (Resource)i.next();
130
				Resource res = (Resource)i.next();
132
				
131
				
133
				((MEditingDomain)editor.getEditingDomain()).unloadResource(res);
132
				res.unload();
134
			}
133
			}
135
		}
134
		}
136
	}
135
	}
(-)src/org/eclipse/gmf/examples/runtime/emf/resources/LoadingLibraryImpl.java (-43 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
13
package org.eclipse.gmf.examples.runtime.emf.resources;
14
15
import org.eclipse.emf.examples.extlibrary.EXTLibraryPackage;
16
import org.eclipse.emf.examples.extlibrary.Library;
17
import org.eclipse.emf.examples.extlibrary.impl.LibraryImpl;
18
import org.eclipse.gmf.runtime.emf.core.util.EObjectContainmentWithInverseLoadingEList;
19
20
21
/**
22
 * Example of a custom implementation for an {@link org.eclipse.emf.ecore.EClass}
23
 * that needs to support auto-loading of sub-unit resource in one or more of
24
 * its containment features.
25
 */
26
class LoadingLibraryImpl
27
	extends LibraryImpl {
28
29
	/**
30
	 * Initializes me.
31
	 */
32
	public LoadingLibraryImpl() {
33
		super();
34
		
35
		// use the custom containment-with-inverse list to perform automatic
36
		//   loading of contained elements in this feature.  This pre-empts
37
		//   the superclass's lazy initialization of this list
38
		branches = new EObjectContainmentWithInverseLoadingEList(
39
			Library.class, this, EXTLibraryPackage.LIBRARY__BRANCHES,
40
			EXTLibraryPackage.LIBRARY__PARENT_BRANCH);
41
	}
42
43
}
(-)src/org/eclipse/gmf/examples/runtime/emf/resources/LoadingEXTLibraryFactoryImpl.java (-53 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
13
package org.eclipse.gmf.examples.runtime.emf.resources;
14
15
import org.eclipse.emf.ecore.EPackage;
16
17
import org.eclipse.emf.examples.extlibrary.EXTLibraryPackage;
18
import org.eclipse.emf.examples.extlibrary.Library;
19
import org.eclipse.emf.examples.extlibrary.impl.EXTLibraryFactoryImpl;
20
21
22
/**
23
 * Example of a custom {@link org.eclipse.emf.ecore.EFactory} implementation
24
 * for auto-loading the sub-units of a logical resource, for the EXT Library
25
 * example metamodel.
26
 */
27
public class LoadingEXTLibraryFactoryImpl
28
	extends EXTLibraryFactoryImpl {
29
30
	/**
31
	 * Initializes me.
32
	 */
33
	public LoadingEXTLibraryFactoryImpl() {
34
		super();
35
	}
36
37
	/**
38
	 * Creates {@link Library} implementations that automatically load their
39
	 * contained {@link Library#getBranches() branches}.
40
	 */
41
	public Library createLibrary() {
42
		return new LoadingLibraryImpl();
43
	}
44
	
45
	public EPackage getEPackage() {
46
		// must appear to belong to the EXT Library Package.  Note that we
47
		//   cannot assign our EPackage using the setEPackage(...) method
48
		//   because that would inverse-add us to the EPackage, which is
49
		//   not good
50
		return EXTLibraryPackage.eINSTANCE;
51
	}
52
53
}
(-)src/org/eclipse/gmf/examples/runtime/emf/resources/LibraryResourcePolicy.java (-89 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
13
package org.eclipse.gmf.examples.runtime.emf.resources;
14
15
import org.eclipse.emf.common.util.URI;
16
import org.eclipse.emf.ecore.EObject;
17
import org.eclipse.emf.ecore.resource.Resource;
18
import org.eclipse.emf.ecore.xmi.XMIResource;
19
20
import org.eclipse.emf.examples.extlibrary.Library;
21
import org.eclipse.gmf.runtime.emf.core.resources.AbstractLogicalResourcePolicy;
22
import org.eclipse.gmf.runtime.emf.core.resources.CannotSeparateException;
23
import org.eclipse.gmf.runtime.emf.core.resources.ILogicalResource;
24
25
26
/**
27
 * Logical resource management policy implementation for the example library
28
 * metamodel.
29
 */
30
public class LibraryResourcePolicy
31
	extends AbstractLogicalResourcePolicy {
32
33
	/**
34
	 * Initializes me.
35
	 */
36
	public LibraryResourcePolicy() {
37
		super();
38
	}
39
40
	/**
41
	 * Only libraries may be stored in separate physical units.
42
	 */
43
	public boolean canSeparate(ILogicalResource resource, EObject eObject) {
44
		return eObject instanceof Library;
45
	}
46
	
47
	/**
48
	 * Suggests a URI for the new library sub-resource.
49
	 * <p>
50
	 * <b>Note</b> that this URI convention is not intended as a common design
51
	 * practice.  It is just a sample.
52
	 * </p>
53
	 */
54
	public URI preSeparate(ILogicalResource resource, EObject eObject, URI uri)
55
		throws CannotSeparateException {
56
		// construct a sensibly unique URI for the new
57
		//    controlled unit by constructing a path based on library names
58
		//    or, where not available, IDs
59
		URI result = resource.getURI().trimFileExtension();
60
		
61
		result = appendSegments(result, resource, (Library) eObject);
62
		
63
		result = result.appendFileExtension(resource.getURI().fileExtension());
64
		
65
		return result;
66
	}
67
	
68
	/**
69
	 * Appends segments to a URI corresponding to the nesting of libraries.
70
	 * 
71
	 * @param uri a uri to append segments to
72
	 * @param resource the resource containing the <code>library</code>
73
	 * @param library a library whose "name path" is to be appended to the URI
74
	 * @return the appended URI
75
	 */
76
	private URI appendSegments(URI uri, Resource resource, Library library) {
77
		Library parent = library.getParentBranch();
78
		if (parent != null) {
79
			uri = appendSegments(uri, resource, parent);
80
		}
81
		
82
		String segment = library.getName();
83
		if ((segment == null) || (segment.length() == 0)) {
84
			segment = ((XMIResource) resource).getID(library);
85
		}
86
		
87
		return uri.appendSegment(segment);
88
	}
89
}
(-)plugin.xml (-22 lines)
Lines 170-185 Link Here
170
              label="%EditEObject"
170
              label="%EditEObject"
171
              menubarPath="org.eclipse.gmf.examples.runtime.emf.mslMenu/edit"/>
171
              menubarPath="org.eclipse.gmf.examples.runtime.emf.mslMenu/edit"/>
172
        <action
172
        <action
173
              class="org.eclipse.gmf.examples.runtime.emf.actions.MSLLibraryActionBarContributor$UncontrolUnitDelegate"
174
              id="org.eclipse.gmf.examples.runtime.emf.uncontrol"
175
              label="%UncontrolUnitAction.label"
176
              menubarPath="org.eclipse.gmf.examples.runtime.emf.mslMenu/units"/>
177
        <action
178
              class="org.eclipse.gmf.examples.runtime.emf.actions.MSLLibraryActionBarContributor$ControlUnitDelegate"
179
              id="org.eclipse.gmf.examples.runtime.emf.control"
180
              label="%ControlUnitAction.label"
181
              menubarPath="org.eclipse.gmf.examples.runtime.emf.mslMenu/units"/>
182
        <action
183
              class="org.eclipse.gmf.examples.runtime.emf.actions.FindReferencers"
173
              class="org.eclipse.gmf.examples.runtime.emf.actions.FindReferencers"
184
              id="org.eclipse.gmf.examples.runtime.emf.referencers"
174
              id="org.eclipse.gmf.examples.runtime.emf.referencers"
185
              label="%FindReferencersAction.label"
175
              label="%FindReferencersAction.label"
Lines 200-216 Link Here
200
           nsURI="http:///org/eclipse/emf/examples/library/extlibrary.ecore/1.0.0"
190
           nsURI="http:///org/eclipse/emf/examples/library/extlibrary.ecore/1.0.0"
201
           priority="highest"/>
191
           priority="highest"/>
202
  </extension>
192
  </extension>
203
  <extension
204
        point="org.eclipse.gmf.runtime.emf.core.resourcePolicies">
205
     <policy
206
           class="org.eclipse.gmf.examples.runtime.emf.resources.LibraryResourcePolicy">
207
        <epackage 
208
              nsURI="http:///org/eclipse/emf/examples/library/extlibrary.ecore/1.0.0"/>
209
      </policy>
210
      
211
      <efactory
212
            class="org.eclipse.gmf.examples.runtime.emf.resources.LoadingEXTLibraryFactoryImpl"
213
            nsURI="http:///org/eclipse/emf/examples/library/extlibrary.ecore/1.0.0"/>
214
  </extension>
215
   
193
   
216
</plugin>
194
</plugin>
(-)src/org/eclipse/gmf/examples/runtime/emf/editor/MSLLibraryEditor.java (-2 / +4 lines)
Lines 604-610 Link Here
604
		try {
604
		try {
605
			// Load the resource through the editing domain.
605
			// Load the resource through the editing domain.
606
			//
606
			//
607
			editingDomain.loadResource(modelFile.getFile().getLocation().toOSString());
607
			Resource res = editingDomain.createResource(
608
					modelFile.getFile().getLocation().toOSString());
609
			editingDomain.loadResource(res);
608
		} catch (Exception exception) {
610
		} catch (Exception exception) {
609
			EXTLibraryEditorPlugin.INSTANCE.log(exception);
611
			EXTLibraryEditorPlugin.INSTANCE.log(exception);
610
		}
612
		}
Lines 1075-1081 Link Here
1075
				while (iter.hasNext()) {
1077
				while (iter.hasNext()) {
1076
					Resource res = (Resource) iter.next();
1078
					Resource res = (Resource) iter.next();
1077
					if (res != null && res.isLoaded() && res.isModified()
1079
					if (res != null && res.isLoaded() && res.isModified()
1078
							&& ResourceUtil.isModifiable(res)) { //$NON-NLS-1$
1080
							&& ResourceUtil.isModifiable(res)) {
1079
						dirtyResources.add(res);
1081
						dirtyResources.add(res);
1080
					}
1082
					}
1081
				}
1083
				}
(-)src/org/eclipse/gmf/tests/runtime/emf/core/internal/resources/LogicalResourceTest.java (-1237 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
13
package org.eclipse.gmf.tests.runtime.emf.core.internal.resources;
14
15
import java.io.IOException;
16
import java.util.List;
17
import java.util.Map;
18
19
import junit.framework.Test;
20
import junit.framework.TestSuite;
21
22
import org.eclipse.core.resources.IFile;
23
import org.eclipse.core.resources.IFileState;
24
import org.eclipse.core.runtime.CoreException;
25
import org.eclipse.core.runtime.Path;
26
import org.eclipse.emf.common.notify.Notification;
27
import org.eclipse.emf.common.notify.impl.AdapterImpl;
28
import org.eclipse.emf.common.util.URI;
29
import org.eclipse.emf.ecore.EObject;
30
import org.eclipse.emf.ecore.resource.Resource;
31
import org.eclipse.emf.ecore.resource.ResourceSet;
32
import org.eclipse.emf.ecore.util.EcoreUtil;
33
34
import org.eclipse.emf.examples.extlibrary.Book;
35
import org.eclipse.emf.examples.extlibrary.EXTLibraryFactory;
36
import org.eclipse.emf.examples.extlibrary.EXTLibraryPackage;
37
import org.eclipse.emf.examples.extlibrary.Library;
38
import org.eclipse.emf.examples.extlibrary.Writer;
39
import org.eclipse.gmf.runtime.emf.core.EventTypes;
40
import org.eclipse.gmf.runtime.emf.core.edit.DemuxedMListener;
41
import org.eclipse.gmf.runtime.emf.core.edit.MEditingDomain;
42
import org.eclipse.gmf.runtime.emf.core.edit.MFilter;
43
import org.eclipse.gmf.runtime.emf.core.edit.MResourceOption;
44
import org.eclipse.gmf.runtime.emf.core.edit.MRunnable;
45
import org.eclipse.gmf.runtime.emf.core.edit.MUndoInterval;
46
import org.eclipse.gmf.runtime.emf.core.exceptions.MSLActionAbandonedException;
47
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap;
48
import org.eclipse.gmf.runtime.emf.core.resources.CannotAbsorbException;
49
import org.eclipse.gmf.runtime.emf.core.resources.CannotSeparateException;
50
import org.eclipse.gmf.runtime.emf.core.resources.ILogicalResource;
51
52
53
/**
54
 * Tests the {@link org.eclipse.gmf.runtime.emf.core.internal.resources.LogicalResource}
55
 * class and its load/save/handler/helper/util cohorts.
56
 *
57
 * @author Christian W. Damus (cdamus)
58
 */
59
public class LogicalResourceTest
60
	extends BaseLogicalResourceTest {
61
	
62
	public LogicalResourceTest(String name) {
63
		super(name);
64
	}
65
	
66
	public static Test suite() {
67
		return new TestSuite(LogicalResourceTest.class, "Basic Tests"); //$NON-NLS-1$
68
	}
69
	
70
	DemuxedMListener aListener;
71
72
	/**
73
	 * Tests the getMappedResources() method.
74
	 */
75
	public void test_getMappedResources() {
76
		Map resources = logres.getMappedResources();
77
		assertEquals(1, resources.size());
78
		
79
		Resource nested = (Resource) resources.get(root);
80
		assertNotNull(nested);
81
		assertEquals(logres.getURI(), nested.getURI());
82
		
83
		nested = (ILogicalResource) resources.get(subunit1);
84
		assertNull(nested);
85
		
86
		try {
87
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
88
		} catch (CannotSeparateException e) {
89
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
90
		}
91
		nested = (Resource) resources.get(subunit1);
92
		assertNotNull(nested);
93
		
94
		try {
95
			logres.absorb(subunit1);
96
		} catch (CannotAbsorbException e) {
97
			fail("Should not fail to absorb: " + e); //$NON-NLS-1$
98
		}
99
		nested = (Resource) resources.get(subunit1);
100
		assertNull(nested);
101
		
102
		assertEquals(1, resources.size());
103
	}
104
105
	/**
106
	 * Specifically tests the representation of the logical resource's roots
107
	 * in the getMappedResources() map.
108
	 */
109
	public void test_getMappedResources_logicalRoots() {
110
		Map resources = logres.getMappedResources();
111
		assertEquals(1, resources.size());
112
		
113
		Resource unit = (Resource) resources.get(root);
114
		assertNotNull(unit);
115
		assertEquals(logres.getURI(), unit.getURI());
116
		
117
		// test adding another root
118
		Library otherRoot = EXTLibraryFactory.eINSTANCE.createLibrary();
119
		logres.getContents().add(otherRoot);
120
		
121
		assertEquals(2, resources.size());
122
		unit = (Resource) resources.get(otherRoot);
123
		assertNotNull(unit);
124
		assertEquals(logres.getURI(), unit.getURI());
125
		
126
		// test replacing a root using the set() method
127
		Library yetAnotherRoot = EXTLibraryFactory.eINSTANCE.createLibrary();
128
		logres.getContents().set(1, yetAnotherRoot);
129
		
130
		assertEquals(2, resources.size());
131
		unit = (Resource) resources.get(otherRoot);
132
		assertNull(unit);  // the old root is no longer mapped to a unit
133
		unit = (Resource) resources.get(yetAnotherRoot);
134
		assertNotNull(unit);  // the new one is
135
		assertEquals(logres.getURI(), unit.getURI());
136
		
137
		// test removing a root
138
		logres.getContents().remove(yetAnotherRoot);
139
		
140
		assertEquals(1, resources.size());
141
		unit = (Resource) resources.get(yetAnotherRoot);
142
		assertNull(unit);  // the old root is no longer mapped to a unit
143
	}
144
	
145
	/**
146
	 * Tests the URIs of sub-units and objects in the logical resource.
147
	 */
148
	public void test_uris() {
149
		String subunitFrag = logres.getURIFragment(subunit1);
150
		URI subunitUri = EcoreUtil.getURI(subunit1);
151
		
152
		URI nestedUri = URI.createPlatformResourceURI(SUBUNIT_NAME1);
153
		
154
		try {
155
			logres.separate(subunit1, nestedUri);
156
		} catch (CannotSeparateException e) {
157
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
158
		}
159
		
160
		Resource nested = (Resource) logres.getMappedResources().get(
161
			subunit1);
162
		assertNotNull(nested);
163
		assertEquals(nestedUri, nested.getURI());
164
		
165
		assertEquals(subunitFrag, logres.getURIFragment(subunit1));
166
		assertEquals(subunitUri, EcoreUtil.getURI(subunit1));
167
	}
168
	
169
	/**
170
	 * Tests a monolithic resource (no sub-units).
171
	 */
172
	public void test_saveLoad_monolith() {
173
		String rootFrag = logres.getURIFragment(root);
174
		String subunitFrag = logres.getURIFragment(subunit1);
175
		
176
		saveLogicalResource();
177
		
178
		assertFalse(logres.isModified());
179
		
180
		// discard and re-load the resource
181
		createLogicalResource(RESOURCE_NAME);
182
		
183
		loadLogicalResource();
184
		
185
		assertFalse(logres.isModified());
186
		
187
		Map resources = logres.getMappedResources();
188
		assertEquals(1, resources.size());
189
		
190
		assertEquals(1, logres.getContents().size());
191
		assertFalse(logres.getContents().get(0) instanceof ResourceMap);
192
		
193
		root = lookupLibrary(rootFrag);
194
		assertNotNull(root);
195
		
196
		// in monolithic case, there should be no resource map.  Should look
197
		//    just like any old XMI resource
198
		assertFalse(
199
			((Resource) resources.get(root)).getContents().get(0) instanceof ResourceMap);
200
		
201
		subunit1 = lookupLibrary(subunitFrag);
202
		assertNotNull(subunit1);
203
		assertTrue(EcoreUtil.isAncestor(root, subunit1));
204
	}
205
	
206
	/**
207
	 * Tests single-level subunit nesting.
208
	 */
209
	public void test_saveLoad_singleNesting() {
210
		String rootFrag = logres.getURIFragment(root);
211
		String subunitFrag = logres.getURIFragment(subunit1);
212
		
213
		try {
214
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
215
		} catch (CannotSeparateException e) {
216
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
217
		}
218
		
219
		assertTrue(logres.isModified());
220
		
221
		saveLogicalResource();
222
		
223
		assertFalse(logres.isModified());
224
		
225
		IFile subunitFile = project.getParent().getFile(new Path(SUBUNIT_NAME1));
226
		assertNotNull(subunitFile);
227
		assertTrue(subunitFile.exists());
228
		
229
		// discard and re-load the resource
230
		createLogicalResource(RESOURCE_NAME);
231
		
232
		loadLogicalResource();
233
		
234
		assertFalse(logres.isModified());
235
		
236
		Map resources = logres.getMappedResources();
237
		assertEquals(2, resources.size());
238
		
239
		assertEquals(1, logres.getContents().size());
240
		assertFalse(logres.getContents().get(0) instanceof ResourceMap);
241
		
242
		root = lookupLibrary(rootFrag);
243
		assertNotNull(root);
244
		
245
		subunit1 = lookupLibrary(subunitFrag);
246
		assertNotNull(subunit1);
247
		assertTrue(EcoreUtil.isAncestor(root, subunit1));
248
	}
249
	
250
	/**
251
	 * Tests multi-level subunit nesting.
252
	 */
253
	public void test_saveLoad_multiNesting() {
254
		String rootFrag = logres.getURIFragment(root);
255
		String subunit1Frag = logres.getURIFragment(subunit1);
256
		String subunit2Frag = logres.getURIFragment(subunit2);
257
		
258
		try {
259
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
260
			logres.separate(subunit2, URI.createPlatformResourceURI(SUBUNIT_NAME2));
261
		} catch (CannotSeparateException e) {
262
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
263
		}
264
		
265
		assertTrue(logres.isModified());
266
		
267
		saveLogicalResource();
268
		
269
		assertFalse(logres.isModified());
270
		
271
		IFile subunitFile = project.getParent().getFile(new Path(SUBUNIT_NAME1));
272
		assertNotNull(subunitFile);
273
		assertTrue(subunitFile.exists());
274
		
275
		subunitFile = project.getParent().getFile(new Path(SUBUNIT_NAME2));
276
		assertNotNull(subunitFile);
277
		assertTrue(subunitFile.exists());
278
		
279
		// discard and re-load the resource
280
		createLogicalResource(RESOURCE_NAME);
281
		
282
		loadLogicalResource();
283
		
284
		assertFalse(logres.isModified());
285
		
286
		Map resources = logres.getMappedResources();
287
		assertEquals(3, resources.size());
288
		
289
		assertEquals(1, logres.getContents().size());
290
		assertFalse(logres.getContents().get(0) instanceof ResourceMap);
291
		
292
		root = lookupLibrary(rootFrag);
293
		assertNotNull(root);
294
		
295
		subunit1 = lookupLibrary(subunit1Frag);
296
		assertNotNull(subunit1);
297
		subunit2 = lookupLibrary(subunit2Frag);
298
		assertNotNull(subunit2);
299
		assertTrue(EcoreUtil.isAncestor(root, subunit2));
300
		assertTrue(EcoreUtil.isAncestor(subunit1, subunit2));
301
	}
302
	
303
	/**
304
	 * Tests multi-level subunit nesting in which two different sub-units
305
	 * are stored in the same physical resource.
306
	 */
307
	public void test_saveLoad_multiNestingSameUnit() {
308
		String rootFrag = logres.getURIFragment(root);
309
		String subunit1Frag = logres.getURIFragment(subunit1);
310
		String subunit2Frag = logres.getURIFragment(subunit2);
311
		String subunit3Frag = logres.getURIFragment(subunit3);
312
		
313
		try {
314
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
315
			logres.separate(subunit2, URI.createPlatformResourceURI(SUBUNIT_NAME2));
316
			logres.separate(subunit3, URI.createPlatformResourceURI(SUBUNIT_NAME2)); // same file
317
		} catch (CannotSeparateException e) {
318
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
319
		}
320
		
321
		assertTrue(logres.isModified());
322
		
323
		saveLogicalResource();
324
		
325
		assertFalse(logres.isModified());
326
		
327
		IFile subunitFile = project.getParent().getFile(new Path(SUBUNIT_NAME1));
328
		assertNotNull(subunitFile);
329
		assertTrue(subunitFile.exists());
330
		
331
		subunitFile = project.getParent().getFile(new Path(SUBUNIT_NAME2));
332
		assertNotNull(subunitFile);
333
		assertTrue(subunitFile.exists());
334
		
335
		try {
336
			// the sub-unit file should only have been written to once, to write
337
			//   both roots
338
			IFileState[] history = subunitFile.getHistory(null);
339
			assertNotNull(history);
340
			assertEquals(0, history.length);  // file was only written once
341
		} catch (CoreException e) {
342
			fail("Failed to get file history: " + e.getLocalizedMessage()); //$NON-NLS-1$
343
		}
344
		
345
		// discard and re-load the resource
346
		createLogicalResource(RESOURCE_NAME);
347
		
348
		loadLogicalResource();
349
		
350
		Map resources = logres.getMappedResources();
351
		assertEquals(4, resources.size());
352
		
353
		assertEquals(1, logres.getContents().size());
354
		assertFalse(logres.getContents().get(0) instanceof ResourceMap);
355
		
356
		root = lookupLibrary(rootFrag);
357
		assertNotNull(root);
358
		
359
		subunit1 = lookupLibrary(subunit1Frag);
360
		assertNotNull(subunit1);
361
		subunit2 = lookupLibrary(subunit2Frag);
362
		assertNotNull(subunit2);
363
		subunit3 = lookupLibrary(subunit3Frag);
364
		assertNotNull(subunit3);
365
		assertTrue(EcoreUtil.isAncestor(subunit1, subunit2));
366
		assertTrue(EcoreUtil.isAncestor(root, subunit3));
367
	}
368
	
369
	/**
370
	 * Tests logical roots as sub-units.
371
	 */
372
	public void test_saveLoad_separateLogicalRoot() {
373
		String rootFrag = logres.getURIFragment(root);
374
		
375
		try {
376
			logres.separate(root, URI.createPlatformResourceURI(SUBUNIT_NAME1));
377
		} catch (CannotSeparateException e) {
378
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
379
		}
380
		
381
		assertTrue(logres.isModified());
382
		
383
		saveLogicalResource();
384
		
385
		assertFalse(logres.isModified());
386
		
387
		IFile subunitFile = project.getParent().getFile(new Path(SUBUNIT_NAME1));
388
		assertNotNull(subunitFile);
389
		assertTrue(subunitFile.exists());
390
		
391
		// discard and re-load the resource
392
		createLogicalResource(RESOURCE_NAME);
393
		
394
		loadLogicalResource();
395
		
396
		assertFalse(logres.isModified());
397
		
398
		Map resources = logres.getMappedResources();
399
		assertEquals(1, resources.size());  // nothing maps to the physical root resource
400
		
401
		assertEquals(1, logres.getContents().size());
402
		assertFalse(logres.getContents().get(0) instanceof ResourceMap);
403
		
404
		root = lookupLibrary(rootFrag);
405
		assertNotNull(root);
406
		assertTrue(logres.isSeparate(root));
407
		assertNull(root.eContainer());
408
		assertTrue(logres.getContents().contains(root));
409
		
410
		// absorb the root again
411
		try {
412
			logres.absorb(root);
413
		} catch (CannotAbsorbException e) {
414
			fail("Should not fail to absorb: " + e); //$NON-NLS-1$
415
		}
416
		
417
		saveLogicalResource();
418
		
419
		// discard and re-load the resource
420
		createLogicalResource(RESOURCE_NAME);
421
		loadLogicalResource();
422
		
423
		root = lookupLibrary(rootFrag);
424
		assertNotNull(root);
425
		assertFalse(logres.isSeparate(root));
426
		assertNull(root.eContainer());
427
		assertTrue(logres.getContents().contains(root));
428
	}
429
	
430
	/**
431
	 * Tests multiple sub-units under the same parent, to verify that they are
432
	 * loaded again in the correct order.  This method uses the
433
	 * <tt>subunit<i>n</i></tt> fields to store different elements than the
434
	 * other tests.
435
	 */
436
	public void test_multipleSubunitsOfSameParent() {
437
		// create a third child of the root element
438
		subunit3 = EXTLibraryFactory.eINSTANCE.createLibrary();
439
		root.getBranches().add(subunit3);
440
		subunit3.setName("level1-2"); //$NON-NLS-1$
441
		
442
		subunit1 = (Library) root.getBranches().get(0);
443
		subunit2 = (Library) root.getBranches().get(1);
444
		subunit3 = (Library) root.getBranches().get(2);
445
		
446
		String rootFrag = logres.getURIFragment(root);
447
		String subunit1Frag = logres.getURIFragment(subunit1);
448
		String subunit2Frag = logres.getURIFragment(subunit2);
449
		String subunit3Frag = logres.getURIFragment(subunit3);
450
		
451
		try {
452
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
453
			logres.separate(subunit2, URI.createPlatformResourceURI(SUBUNIT_NAME2));
454
			logres.separate(subunit3, URI.createPlatformResourceURI(SUBUNIT_NAME2));
455
		} catch (CannotSeparateException e) {
456
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
457
		}
458
		
459
		assertTrue(logres.isModified());
460
		
461
		saveLogicalResource();
462
		
463
		assertFalse(logres.isModified());
464
		
465
		// discard and re-load the resource
466
		createLogicalResource(RESOURCE_NAME);
467
		
468
		loadLogicalResource();
469
		
470
		root = lookupLibrary(rootFrag);
471
		assertNotNull(root);
472
		
473
		subunit1 = lookupLibrary(subunit1Frag);
474
		assertNotNull(subunit1);
475
		subunit2 = lookupLibrary(subunit2Frag);
476
		assertNotNull(subunit2);
477
		subunit3 = lookupLibrary(subunit3Frag);
478
		assertNotNull(subunit3);
479
		
480
		// verify the ordering of the sub-units
481
		assertEquals(0, root.getBranches().indexOf(subunit1));
482
		assertEquals(1, root.getBranches().indexOf(subunit2));
483
		assertEquals(2, root.getBranches().indexOf(subunit3));
484
	}
485
	
486
	/**
487
	 * Tests absorption of an internal (middle) unit in multi-level subunit
488
	 * nesting.
489
	 */
490
	public void test_absorb_internal_multiNesting() {
491
		String rootFrag = logres.getURIFragment(root);
492
		String subunit1Frag = logres.getURIFragment(subunit1);
493
		String subunit2Frag = logres.getURIFragment(subunit2);
494
		
495
		try {
496
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
497
			logres.separate(subunit2, URI.createPlatformResourceURI(SUBUNIT_NAME2));
498
		} catch (CannotSeparateException e) {
499
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
500
		}
501
		
502
		saveLogicalResource();
503
		
504
		// get the file modification stamps for later comparison
505
		IFile file = project.getParent().getFile(new Path(RESOURCE_NAME));
506
		assertNotNull(file);
507
		long rootStamp = file.getModificationStamp();
508
		file = project.getParent().getFile(new Path(SUBUNIT_NAME1));
509
		assertNotNull(file);
510
		long subunit1Stamp = file.getModificationStamp();
511
		file = project.getParent().getFile(new Path(SUBUNIT_NAME2));
512
		assertNotNull(file);
513
		long subunit2Stamp = file.getModificationStamp();
514
		
515
		// discard and re-load the resource
516
		createLogicalResource(RESOURCE_NAME);
517
		
518
		loadLogicalResource();
519
		
520
		Map resources = logres.getMappedResources();
521
		assertEquals(3, resources.size());
522
		
523
		root = lookupLibrary(rootFrag);
524
		assertNotNull(root);
525
		
526
		subunit1 = lookupLibrary(subunit1Frag);
527
		assertNotNull(subunit1);
528
		subunit2 = lookupLibrary(subunit2Frag);
529
		assertNotNull(subunit2);
530
		assertTrue(EcoreUtil.isAncestor(root, subunit2));
531
		assertTrue(EcoreUtil.isAncestor(subunit1, subunit2));
532
		
533
		assertTrue(logres.isSeparate(subunit1));
534
		
535
		try {
536
			logres.absorb(subunit1);
537
		} catch (CannotAbsorbException e) {
538
			fail("Should not fail to absorb: " + e); //$NON-NLS-1$
539
		}
540
		
541
		assertFalse(logres.isSeparate(subunit1));
542
		assertEquals(2, resources.size());
543
		
544
		saveLogicalResource();
545
		
546
		// all files needed to be rewritten by the save, because the subunit2
547
		//   was updated to reference the root unit as its parent when subunit1
548
		//   was absorbed
549
		file = project.getParent().getFile(new Path(RESOURCE_NAME));
550
		assertNotNull(file);
551
		assertFalse(rootStamp == file.getModificationStamp());
552
		file = project.getParent().getFile(new Path(SUBUNIT_NAME1));
553
		assertNotNull(file);
554
		assertFalse(subunit1Stamp == file.getModificationStamp());
555
		file = project.getParent().getFile(new Path(SUBUNIT_NAME2));
556
		assertNotNull(file);
557
		assertFalse(subunit2Stamp == file.getModificationStamp());
558
	}
559
	
560
	/**
561
	 * Tests absorption of a leaf unit in multi-level subunit nesting.
562
	 */
563
	public void test_absorb_leaf_multiNesting() {
564
		String rootFrag = logres.getURIFragment(root);
565
		String subunit1Frag = logres.getURIFragment(subunit1);
566
		String subunit2Frag = logres.getURIFragment(subunit2);
567
		
568
		try {
569
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
570
			logres.separate(subunit2, URI.createPlatformResourceURI(SUBUNIT_NAME2));
571
		} catch (CannotSeparateException e) {
572
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
573
		}
574
		
575
		saveLogicalResource();
576
		
577
		// get the file modification stamps for later comparison
578
		IFile file = project.getParent().getFile(new Path(RESOURCE_NAME));
579
		assertNotNull(file);
580
		long rootStamp = file.getModificationStamp();
581
		file = project.getParent().getFile(new Path(SUBUNIT_NAME1));
582
		assertNotNull(file);
583
		long subunit1Stamp = file.getModificationStamp();
584
		file = project.getParent().getFile(new Path(SUBUNIT_NAME2));
585
		assertNotNull(file);
586
		long subunit2Stamp = file.getModificationStamp();
587
		
588
		// discard and re-load the resource
589
		createLogicalResource(RESOURCE_NAME);
590
		
591
		loadLogicalResource();
592
		
593
		Map resources = logres.getMappedResources();
594
		assertEquals(3, resources.size());
595
		
596
		root = lookupLibrary(rootFrag);
597
		assertNotNull(root);
598
		
599
		subunit1 = lookupLibrary(subunit1Frag);
600
		assertNotNull(subunit1);
601
		subunit2 = lookupLibrary(subunit2Frag);
602
		assertNotNull(subunit2);
603
		assertTrue(EcoreUtil.isAncestor(root, subunit2));
604
		assertTrue(EcoreUtil.isAncestor(subunit1, subunit2));
605
		
606
		assertTrue(logres.isSeparate(subunit2));
607
		
608
		try {
609
			logres.absorb(subunit2);
610
		} catch (CannotAbsorbException e) {
611
			fail("Should not fail to absorb: " + e); //$NON-NLS-1$
612
		}
613
		
614
		assertFalse(logres.isSeparate(subunit2));
615
		assertEquals(2, resources.size());
616
		
617
		saveLogicalResource();
618
		
619
		// the subunit1 and subunit2 files should have been written by the
620
		//   second save, but not the root file
621
		file = project.getParent().getFile(new Path(RESOURCE_NAME));
622
		assertNotNull(file);
623
		assertEquals(rootStamp, file.getModificationStamp());
624
		file = project.getParent().getFile(new Path(SUBUNIT_NAME1));
625
		assertNotNull(file);
626
		assertFalse(subunit1Stamp == file.getModificationStamp());
627
		file = project.getParent().getFile(new Path(SUBUNIT_NAME2));
628
		assertNotNull(file);
629
		assertFalse(subunit2Stamp == file.getModificationStamp());
630
	}
631
	
632
	/**
633
	 * Test saving a logical resource with sub-units under a new URI.
634
	 */
635
	public void test_saveAs() {
636
		String rootFrag = logres.getURIFragment(root);
637
		String subunit1Frag = logres.getURIFragment(subunit1);
638
		String subunit2Frag = logres.getURIFragment(subunit2);
639
		
640
		try {
641
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
642
			logres.separate(subunit2, URI.createPlatformResourceURI(SUBUNIT_NAME2));
643
		} catch (CannotSeparateException e) {
644
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
645
		}
646
		
647
		assertTrue(logres.isModified());
648
		
649
		saveLogicalResource();
650
		
651
		assertFalse(logres.isModified());
652
		
653
		// record the modification stamps of the various units for later
654
		//   comparison
655
		IFile file = project.getParent().getFile(new Path(RESOURCE_NAME));
656
		assertNotNull(file);
657
		long rootStamp = file.getModificationStamp();
658
		
659
		file = project.getParent().getFile(new Path(SUBUNIT_NAME1));
660
		assertNotNull(file);
661
		long subunit1Stamp = file.getModificationStamp();
662
		
663
		file = project.getParent().getFile(new Path(SUBUNIT_NAME2));
664
		assertNotNull(file);
665
		long subunit2Stamp = file.getModificationStamp();
666
		
667
		Map resources = logres.getMappedResources();
668
		assertEquals(3, resources.size());
669
		
670
		String newName = "/" + PROJECT_NAME + "/newuri.extlibrary"; //$NON-NLS-1$ //$NON-NLS-2$
671
		logres.setURI(URI.createPlatformResourceURI(newName));
672
		
673
		// reduced to a single physical resource
674
		assertEquals(1, resources.size());
675
		
676
		saveLogicalResource();
677
		
678
		// discard and re-load the resource
679
		createLogicalResource(newName);
680
		
681
		loadLogicalResource();
682
		resources = logres.getMappedResources();
683
		assertEquals(1, resources.size());
684
		
685
		// verify the structure of the file (that nothing is missing)
686
		root = lookupLibrary(rootFrag);
687
		assertNotNull(root);
688
		
689
		subunit1 = lookupLibrary(subunit1Frag);
690
		assertNotNull(subunit1);
691
		subunit2 = lookupLibrary(subunit2Frag);
692
		assertNotNull(subunit2);
693
		assertTrue(EcoreUtil.isAncestor(root, subunit2));
694
		assertTrue(EcoreUtil.isAncestor(subunit1, subunit2));
695
		
696
		// load the former URI again
697
		createLogicalResource(RESOURCE_NAME);
698
		
699
		loadLogicalResource();
700
		
701
		// the old one still has three units
702
		resources = logres.getMappedResources();
703
		assertEquals(3, resources.size());
704
		
705
		// verify the structure of the file (that nothing is missing)
706
		root = lookupLibrary(rootFrag);
707
		assertNotNull(root);
708
		
709
		subunit1 = lookupLibrary(subunit1Frag);
710
		assertNotNull(subunit1);
711
		subunit2 = lookupLibrary(subunit2Frag);
712
		assertNotNull(subunit2);
713
		assertTrue(EcoreUtil.isAncestor(root, subunit2));
714
		assertTrue(EcoreUtil.isAncestor(subunit1, subunit2));
715
		
716
		// check the modification stamps to verify that the old units are
717
		//   not changed
718
		file = project.getParent().getFile(new Path(RESOURCE_NAME));
719
		assertNotNull(file);
720
		assertEquals(rootStamp, file.getModificationStamp());
721
		
722
		file = project.getParent().getFile(new Path(SUBUNIT_NAME1));
723
		assertNotNull(file);
724
		assertEquals(subunit1Stamp, file.getModificationStamp());
725
		
726
		file = project.getParent().getFile(new Path(SUBUNIT_NAME2));
727
		assertNotNull(file);
728
		assertEquals(subunit2Stamp, file.getModificationStamp());
729
	}
730
	
731
	/** Tests undo/redo of unit separation and absorption. */
732
	public void test_undoRedo() {
733
		Map resources = logres.getMappedResources();
734
		assertEquals(1, resources.size());
735
		
736
		Resource nested = (Resource) resources.get(root);
737
		assertNotNull(nested);
738
		assertEquals(logres.getURI(), nested.getURI());
739
		
740
		nested = (Resource) resources.get(subunit1);
741
		assertNull(nested);
742
		
743
		stopWriting();
744
		startWriting();
745
		
746
		try {
747
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
748
		} catch (CannotSeparateException e) {
749
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
750
		}
751
		
752
		nested = (Resource) resources.get(subunit1);
753
		assertNotNull(nested);
754
		
755
		MUndoInterval undo = stopWriting();
756
		
757
		// test undo of separation
758
		undo.undo();
759
		
760
		startReading();
761
		
762
		nested = (Resource) resources.get(subunit1);
763
		assertNull(nested);
764
		assertFalse(logres.isSeparate(subunit1));
765
		
766
		stopReading();
767
		
768
		// test redo of separation
769
		undo.redo();
770
		
771
		startReading();
772
		
773
		nested = (Resource) resources.get(subunit1);
774
		assertNotNull(nested);
775
		assertTrue(logres.isSeparate(subunit1));
776
		
777
		stopReading();
778
		
779
		startWriting();
780
		
781
		try {
782
			logres.absorb(subunit1);
783
		} catch (CannotAbsorbException e) {
784
			fail("Should not fail to absorb: " + e); //$NON-NLS-1$
785
		}
786
		nested = (Resource) resources.get(subunit1);
787
		assertNull(nested);
788
		
789
		undo = stopWriting();
790
		
791
		// test undo of absorption
792
		undo.undo();
793
		
794
		startReading();
795
		
796
		nested = (Resource) resources.get(subunit1);
797
		assertNotNull(nested);
798
		assertTrue(logres.isSeparate(subunit1));
799
		
800
		stopReading();
801
		
802
		// test undo of absorption
803
		undo.redo();
804
		
805
		startReading();
806
		
807
		nested = (Resource) resources.get(subunit1);
808
		assertNull(nested);
809
		assertFalse(logres.isSeparate(subunit1));
810
		
811
		stopReading();
812
	}
813
	
814
	/**
815
	 * Tests that the dirty states of units are correctly updated when
816
	 * separating an element.
817
	 */
818
	public void test_dirtyState_separate() {
819
		saveLogicalResource();
820
		
821
		Resource rootRes = (Resource) logres.getMappedResources().get(root);
822
		
823
		assertFalse(logres.isModified());
824
		assertFalse(rootRes.isModified());
825
		
826
		try {
827
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
828
		} catch (CannotSeparateException e) {
829
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
830
		}
831
		
832
		Resource sub1Res = (Resource) logres.getMappedResources().get(subunit1);
833
		
834
		assertTrue(logres.isModified());
835
		assertTrue(rootRes.isModified());
836
		assertTrue(sub1Res.isModified());
837
		
838
		saveLogicalResource();
839
		
840
		assertFalse(logres.isModified());
841
		assertFalse(rootRes.isModified());
842
		assertFalse(sub1Res.isModified());
843
	}
844
	
845
	/**
846
	 * Tests that the dirty states of units are correctly updated when
847
	 * absorbing an element.
848
	 */
849
	public void test_dirtyState_absorb() {
850
		try {
851
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
852
		} catch (CannotSeparateException e) {
853
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
854
		}
855
		
856
		saveLogicalResource();
857
		
858
		Resource rootRes = (Resource) logres.getMappedResources().get(root);
859
		Resource sub1Res = (Resource) logres.getMappedResources().get(subunit1);
860
		
861
		assertFalse(logres.isModified());
862
		assertFalse(rootRes.isModified());
863
		assertFalse(sub1Res.isModified());
864
		
865
		try {
866
			logres.absorb(subunit1);
867
		} catch (CannotAbsorbException e) {
868
			fail("Should not fail to absorb: " + e); //$NON-NLS-1$
869
		}
870
		
871
		assertTrue(logres.isModified());
872
		assertTrue(rootRes.isModified());
873
		assertTrue(sub1Res.isModified());
874
		
875
		saveLogicalResource();
876
		
877
		assertFalse(logres.isModified());
878
		assertFalse(rootRes.isModified());
879
		assertFalse(sub1Res.isModified());
880
	}
881
	
882
	/**
883
	 * Tests that the dirty states of units are correctly updated when
884
	 * modifying an element.
885
	 */
886
	public void test_dirtyState_modify() {
887
		try {
888
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
889
		} catch (CannotSeparateException e) {
890
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
891
		}
892
		
893
		saveLogicalResource();
894
		
895
		Resource rootRes = (Resource) logres.getMappedResources().get(root);
896
		Resource sub1Res = (Resource) logres.getMappedResources().get(subunit1);
897
		
898
		assertFalse(logres.isModified());
899
		assertFalse(rootRes.isModified());
900
		assertFalse(sub1Res.isModified());
901
		
902
		subunit1.setAddress("500 Pennsylvania Ave."); //$NON-NLS-1$
903
		
904
		assertTrue(logres.isModified());
905
		assertFalse(rootRes.isModified());  // didn't update the root unit
906
		assertTrue(sub1Res.isModified());
907
		
908
		saveLogicalResource();
909
		
910
		assertFalse(logres.isModified());
911
		assertFalse(rootRes.isModified());
912
		assertFalse(sub1Res.isModified());
913
		
914
		root.setAddress("10 Downing St."); //$NON-NLS-1$
915
		
916
		assertTrue(logres.isModified());
917
		assertTrue(rootRes.isModified());
918
		assertFalse(sub1Res.isModified());  // didn't update the sub-unit
919
	}
920
	
921
	/** Tests the EMF-style listening for notifications from adapters. */
922
	public void test_basicEventing() {
923
		class TestAdapter extends AdapterImpl {
924
			List notifications = new java.util.ArrayList();
925
			
926
			public void notifyChanged(Notification msg) {
927
				if (!(msg.getNotifier() instanceof Resource) ||
928
						(msg.getFeatureID(Resource.class) == Resource.RESOURCE__CONTENTS)) {
929
					// don't want the touch events for resource isModified
930
					notifications.add(msg);
931
				}
932
			}
933
		}
934
		
935
		TestAdapter adapter = new TestAdapter();
936
		
937
		URI logicalUri = logres.getURI();
938
		URI subunitUri = URI.createPlatformResourceURI(SUBUNIT_NAME1);
939
		
940
		// listen for notifications of separation/absorption on the parent
941
		EObject parent = subunit1.eContainer();
942
		parent.eAdapters().add(adapter);
943
		
944
		try {
945
			logres.separate(subunit1, subunitUri);
946
		} catch (CannotSeparateException e) {
947
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
948
		}
949
		
950
		assertEquals(1, adapter.notifications.size());
951
		Notification event = (Notification) adapter.notifications.get(0);
952
		adapter.notifications.clear();
953
		
954
		assertSame(parent, event.getNotifier());
955
		assertEquals(EventTypes.SEPARATE, event.getEventType());
956
		assertSame(EXTLibraryPackage.eINSTANCE.getLibrary_Branches(), event.getFeature());
957
		assertEquals(logicalUri, ((Resource) event.getOldValue()).getURI());
958
		assertEquals(subunitUri, ((Resource) event.getNewValue()).getURI());
959
		
960
		try {
961
			logres.absorb(subunit1);
962
		} catch (CannotAbsorbException e) {
963
			fail("Should not fail to absorb: " + e); //$NON-NLS-1$
964
		}
965
		
966
		assertEquals(1, adapter.notifications.size());
967
		event = (Notification) adapter.notifications.get(0);
968
		adapter.notifications.clear();
969
		
970
		assertSame(parent, event.getNotifier());
971
		assertEquals(EventTypes.ABSORB, event.getEventType());
972
		assertSame(EXTLibraryPackage.eINSTANCE.getLibrary_Branches(), event.getFeature());
973
		assertEquals(subunitUri, ((Resource) event.getOldValue()).getURI());
974
		assertEquals(logicalUri, ((Resource) event.getNewValue()).getURI());
975
		
976
		logres.eAdapters().add(adapter);
977
		
978
		try {
979
			logres.separate(root, subunitUri); // logical root
980
		} catch (CannotSeparateException e) {
981
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
982
		}
983
		
984
		assertEquals(1, adapter.notifications.size());
985
		event = (Notification) adapter.notifications.get(0);
986
		adapter.notifications.clear();
987
		
988
		assertSame(logres, event.getNotifier());
989
		assertEquals(EventTypes.SEPARATE, event.getEventType());
990
		assertSame(null, event.getFeature());
991
		assertEquals(Resource.RESOURCE__CONTENTS, event.getFeatureID(Resource.class));
992
		assertEquals(logicalUri, ((Resource) event.getOldValue()).getURI());
993
		assertEquals(subunitUri, ((Resource) event.getNewValue()).getURI());
994
		
995
		try {
996
			logres.absorb(root);  // logical root
997
		} catch (CannotAbsorbException e) {
998
			fail("Should not fail to absorb: " + e); //$NON-NLS-1$
999
		}
1000
		
1001
		assertEquals(1, adapter.notifications.size());
1002
		event = (Notification) adapter.notifications.get(0);
1003
		adapter.notifications.clear();
1004
		
1005
		assertSame(logres, event.getNotifier());
1006
		assertEquals(EventTypes.ABSORB, event.getEventType());
1007
		assertSame(null, event.getFeature());
1008
		assertEquals(Resource.RESOURCE__CONTENTS, event.getFeatureID(Resource.class));
1009
		assertEquals(subunitUri, ((Resource) event.getOldValue()).getURI());
1010
		assertEquals(logicalUri, ((Resource) event.getNewValue()).getURI());
1011
	}
1012
	
1013
	/** Tests the MSL-style listening for notifications from MListeners. */
1014
	public void test_mslEventing() {
1015
		class TestListener extends DemuxedMListener {
1016
			Notification event;
1017
			ILogicalResource res;
1018
			EObject element;
1019
			Resource subunit;
1020
			
1021
			TestListener() {
1022
				super(domain);
1023
			}
1024
			
1025
			public MFilter getFilter() {
1026
				return MFilter.SEPARATED_ABSORBED_FILTER;
1027
			}
1028
			
1029
			public void handleElementSeparatedEvent(
1030
					Notification notification, ILogicalResource resource,
1031
					EObject eObject, Resource newResource) {
1032
				event = notification;
1033
				res = resource;
1034
				element = eObject;
1035
				subunit = newResource;
1036
			}
1037
			
1038
			public void handleElementAbsorbedEvent(
1039
					Notification notification, ILogicalResource resource,
1040
					EObject eObject, Resource oldResource) {
1041
				event = notification;
1042
				res = resource;
1043
				element = eObject;
1044
				subunit = oldResource;
1045
			}
1046
		}
1047
		
1048
		TestListener listener = new TestListener();
1049
		listener.startListening();
1050
		
1051
		URI subunitUri = URI.createPlatformResourceURI(SUBUNIT_NAME1);
1052
		
1053
		try {
1054
			logres.separate(subunit1, subunitUri);
1055
		} catch (CannotSeparateException e) {
1056
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
1057
		}
1058
		
1059
		// must complete the write action in order for events to fire
1060
		stopWriting();
1061
		
1062
		assertSame(subunit1, listener.element);
1063
		assertEquals(EventTypes.SEPARATE, listener.event.getEventType());
1064
		assertSame(logres, listener.res);
1065
		assertEquals(subunitUri, listener.subunit.getURI());
1066
		
1067
		startWriting();
1068
		
1069
		try {
1070
			logres.absorb(subunit1);
1071
		} catch (CannotAbsorbException e) {
1072
			fail("Should not fail to absorb: " + e); //$NON-NLS-1$
1073
		}
1074
		
1075
		// must complete the write action in order for events to fire
1076
		stopWriting();
1077
		
1078
		assertSame(subunit1, listener.element);
1079
		assertEquals(EventTypes.ABSORB, listener.event.getEventType());
1080
		assertSame(logres, listener.res);
1081
		assertEquals(subunitUri, listener.subunit.getURI());
1082
		
1083
		try {
1084
			logres.separate(root, subunitUri);  // logical root
1085
		} catch (CannotSeparateException e) {
1086
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
1087
		}
1088
		
1089
		// must complete the write action in order for events to fire
1090
		stopWriting();
1091
		
1092
		assertSame(root, listener.element);
1093
		assertEquals(EventTypes.SEPARATE, listener.event.getEventType());
1094
		assertSame(logres, listener.res);
1095
		assertEquals(subunitUri, listener.subunit.getURI());
1096
		
1097
		startWriting();
1098
		
1099
		try {
1100
			logres.absorb(root);  // logical root
1101
		} catch (CannotAbsorbException e) {
1102
			fail("Should not fail to absorb: " + e); //$NON-NLS-1$
1103
		}
1104
		
1105
		// must complete the write action in order for events to fire
1106
		stopWriting();
1107
		
1108
		assertSame(root, listener.element);
1109
		assertEquals(EventTypes.ABSORB, listener.event.getEventType());
1110
		assertSame(logres, listener.res);
1111
		assertEquals(subunitUri, listener.subunit.getURI());
1112
	}
1113
	
1114
	/**
1115
	 * Tests that we can correctly load models from the 6.x physical structure.
1116
	 */
1117
	public void test_compatibility_6_0() {
1118
		URI uri = URI.createURI(MslCoreTestsBundle.getEntry(
1119
				"/test_models/test_6_0_format.extlibrary").toString()); //$NON-NLS-1$
1120
		logres = createNewLogicalResource(uri);
1121
		loadLogicalResource();
1122
		
1123
		assertTrue(logres.isLoaded());
1124
		assertEquals(1, ((ResourceSet) logres.getAdapter(ResourceSet.class)).getResources().size());
1125
		
1126
		assertEquals(1, logres.getContents().size());
1127
		Library library = (Library) logres.getContents().get(0);
1128
		
1129
		assertEquals("Library of Congress", library.getName()); //$NON-NLS-1$
1130
		
1131
		assertEquals(1, library.getWriters().size());
1132
		Writer writer = (Writer) library.getWriters().get(0);
1133
		assertEquals("Master Librarian", writer.getName()); //$NON-NLS-1$
1134
		
1135
		assertEquals(1, library.getBooks().size());
1136
		Book book = (Book) library.getBooks().get(0);
1137
		assertEquals("All Books In Existence", book.getTitle()); //$NON-NLS-1$
1138
		
1139
		assertSame(writer, book.getAuthor());
1140
		assertEquals(1, writer.getBooks().size());
1141
		assertSame(book, writer.getBooks().get(0));
1142
	}
1143
	
1144
	/**
1145
	 * Tests that we properly propagate errors from the unit to the logical
1146
	 *  resource.
1147
	 */
1148
	public void test_load_errors_RATLC00537775() {
1149
		URI uri = URI.createURI(MslCoreTestsBundle.getEntry(
1150
				"/test_models/test_corrupted_model.extlibrary").toString()); //$NON-NLS-1$
1151
		logres = createNewLogicalResource(uri);
1152
1153
		Map options = new java.util.HashMap();
1154
		
1155
		options.put(ILogicalResource.OPTION_LOAD_ALL_UNITS,
1156
			Boolean.TRUE);
1157
		options.put(ILogicalResource.OPTION_AUTO_LOAD_UNITS,
1158
			Boolean.TRUE);
1159
		
1160
		try {
1161
			logres.load(options);
1162
		} catch (IOException e) {
1163
			// Check to ensure that the resource is loaded but it has
1164
			//  errors.
1165
			assertTrue(logres.isLoaded());
1166
			assertTrue(!logres.getErrors().isEmpty());
1167
			return;
1168
		}
1169
		
1170
		fail("Logical resource load should have failed because of corrupted XML."); //$NON-NLS-1$
1171
	}
1172
	
1173
	/**
1174
	 * Tests that the DemuxingMListener will not report a model unloaded when
1175
	 *  the errors list of a resource is emptied.
1176
	 */
1177
	public void test_load_errors_RATLC00537693() {
1178
		final MEditingDomain editingDomain = MEditingDomain.createNewDomain();
1179
		URI uri = URI.createURI(MslCoreTestsBundle.getEntry(
1180
				"/test_models/test_corrupted_model.extlibrary").toString()); //$NON-NLS-1$
1181
		
1182
		final Resource[] r = new Resource[1];
1183
		
1184
		try {
1185
			r[0] = editingDomain.createResource(uri.toString(),MResourceOption.URI);
1186
			r[0].unload();
1187
		} catch (Exception e) {
1188
			// Do nothing, just proceed.
1189
		}
1190
		
1191
		Map options = new java.util.HashMap();
1192
		
1193
		options.put(ILogicalResource.OPTION_LOAD_ALL_UNITS,
1194
			Boolean.TRUE);
1195
		options.put(ILogicalResource.OPTION_AUTO_LOAD_UNITS,
1196
			Boolean.TRUE);
1197
		
1198
		try {
1199
			r[0].load(options);
1200
			// We shouldn't get this far.
1201
			fail();
1202
		} catch (IOException e) {
1203
			// Do nothing.
1204
		}
1205
		
1206
		// Make sure that there are errors to be cleared from the resource.
1207
		assertTrue(r[0].getErrors().size() > 0);
1208
		
1209
		final int[] listenerCalled = new int[1];
1210
		listenerCalled[0] = 0;
1211
		
1212
		aListener = new DemuxedMListener(editingDomain) {
1213
			public void handleResourceUnloadedEvent(Notification notification, Resource resource, EObject modelRoot) {
1214
				listenerCalled[0]++;
1215
			}
1216
		};
1217
		aListener.startListening();
1218
		
1219
		// Clear all of the errors from the resource in a proper write action.
1220
		editingDomain.runInUndoInterval(new Runnable() {
1221
			public void run() {
1222
				try {
1223
					editingDomain.runAsWrite(new MRunnable() {
1224
						public Object run() {
1225
							r[0].getErrors().clear();
1226
							return null;
1227
						}
1228
					});
1229
				} catch (MSLActionAbandonedException e) {
1230
					fail();
1231
				}
1232
			}
1233
		});
1234
		
1235
		assertEquals(0,listenerCalled[0]);
1236
	}
1237
}
(-)src/org/eclipse/gmf/tests/runtime/emf/core/internal/resources/BaseLogicalResourceTest.java (-626 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
13
package org.eclipse.gmf.tests.runtime.emf.core.internal.resources;
14
15
import java.io.IOException;
16
import java.util.Collections;
17
import java.util.Iterator;
18
import java.util.List;
19
import java.util.Map;
20
import java.util.Set;
21
22
import junit.framework.Test;
23
import junit.framework.TestCase;
24
import junit.framework.TestSuite;
25
26
import org.eclipse.core.resources.IFile;
27
import org.eclipse.core.resources.IProject;
28
import org.eclipse.core.resources.IWorkspaceRoot;
29
import org.eclipse.core.resources.ResourcesPlugin;
30
import org.eclipse.core.runtime.IPath;
31
import org.eclipse.core.runtime.Path;
32
import org.eclipse.core.runtime.Platform;
33
import org.eclipse.emf.common.util.URI;
34
import org.eclipse.emf.ecore.EObject;
35
import org.eclipse.emf.ecore.resource.Resource;
36
import org.eclipse.emf.examples.extlibrary.AudioVisualItem;
37
import org.eclipse.emf.examples.extlibrary.Book;
38
import org.eclipse.emf.examples.extlibrary.Library;
39
import org.eclipse.emf.examples.extlibrary.Periodical;
40
import org.eclipse.emf.examples.extlibrary.Person;
41
import org.eclipse.emf.examples.extlibrary.Writer;
42
import org.eclipse.emf.examples.extlibrary.util.EXTLibrarySwitch;
43
import org.eclipse.gmf.runtime.emf.core.edit.MEditingDomain;
44
import org.eclipse.gmf.runtime.emf.core.edit.MResourceOption;
45
import org.eclipse.gmf.runtime.emf.core.edit.MUndoInterval;
46
import org.eclipse.gmf.runtime.emf.core.internal.commands.MSLUndoStack;
47
import org.eclipse.gmf.runtime.emf.core.internal.commands.MSLUndoStack.ActionLockMode;
48
import org.eclipse.gmf.runtime.emf.core.internal.domain.MSLEditingDomain;
49
import org.eclipse.gmf.runtime.emf.core.internal.resources.AbstractResourceWrapper;
50
import org.eclipse.gmf.runtime.emf.core.internal.resources.LogicalResourceWrapper;
51
import org.eclipse.gmf.runtime.emf.core.resources.ILogicalResource;
52
import org.osgi.framework.Bundle;
53
54
55
/**
56
 * Mini-framework class for logical resource test cases.
57
 *
58
 * @author Christian W. Damus (cdamus)
59
 */
60
public abstract class BaseLogicalResourceTest extends TestCase {
61
	static final Bundle MslCoreTestsBundle =
62
		Platform.getBundle("org.eclipse.gmf.tests.runtime.emf.core"); //$NON-NLS-1$
63
	
64
	protected static final String PROJECT_NAME = "logrestest"; //$NON-NLS-1$
65
	protected static final String RESOURCE_NAME = "/" + PROJECT_NAME + "/logres.extlibrary";  //$NON-NLS-1$//$NON-NLS-2$
66
	protected static final String RESOURCE_NAME2 = "/" + PROJECT_NAME + "/logres2.extlibrary";  //$NON-NLS-1$//$NON-NLS-2$
67
	protected static final String SUBUNIT_NAME1 = "/" + PROJECT_NAME + "/logres.1.extlibrary";  //$NON-NLS-1$//$NON-NLS-2$
68
	protected static final String SUBUNIT_NAME2 = "/" + PROJECT_NAME + "/logres.2.extlibrary";  //$NON-NLS-1$//$NON-NLS-2$
69
	protected static final String SUBUNIT_NAME3 = "/" + PROJECT_NAME + "/logres.3.extlibrary";  //$NON-NLS-1$//$NON-NLS-2$
70
	
71
	protected MEditingDomain domain;
72
	private boolean isReading;
73
	
74
	protected IProject project;
75
	protected ILogicalResource logres;
76
	
77
	//
78
	// Model structure created by setUp():
79
	//
80
	// root
81
	//  +- level1
82
	//  |    +- level2-subunit  (== subunit1)
83
	//  |          +- level3
84
	//  |               +- level4-subunit   (== subunit2)
85
	//  +- level1-1
86
	//       +- level2-1-subunit   (== subunit3)
87
	//
88
	// In each library at each level, there is a book and a writer, named
89
	// according to the library name (nesting level).
90
	// 
91
	
92
	protected Library root;
93
	protected Library subunit1;
94
	protected Library subunit2;
95
	protected Library subunit3;
96
97
	/**
98
	 * Initializes me with my name.
99
	 * 
100
	 * @param name my name
101
	 */
102
	protected BaseLogicalResourceTest(String name) {
103
		super(name);
104
	}
105
106
	/**
107
	 * Test suite encompassing all of the logical resource tests.
108
	 * 
109
	 * @return the suite of logical resource tests
110
	 */
111
	public static Test suite() {
112
		TestSuite suite = new TestSuite("MSL Logical Resource Tests"); //$NON-NLS-1$
113
114
		suite.addTest(LogicalResourceTest.suite());
115
		suite.addTest(CrossReferenceTest.suite());
116
		suite.addTest(IncrementalLoadingTest.suite());
117
		suite.addTest(RefactoringTest.suite());
118
		suite.addTest(LogicalResourcePolicyManagerTest.suite());
119
		suite.addTest(LogicalResourceWrapperTest.suite());
120
		suite.addTest(UnmodifiableResourceViewTest.suite());
121
		suite.addTest(ErrorConditionsTest.suite());
122
		suite.addTest(RegressionTest.suite());
123
		suite.addTest(GarbageCollectionTest.suite());
124
125
		return suite;
126
	}
127
128
	//
129
	// Test configuration methods
130
	//
131
	
132
	protected void setUp()
133
		throws Exception {
134
		
135
		project = ResourcesPlugin.getWorkspace().getRoot().getProject(PROJECT_NAME);
136
		if (!project.exists()) {
137
			project.create(null);
138
		}
139
		
140
		project.open(null);
141
	
142
		domain = MEditingDomain.INSTANCE;
143
		
144
		startWriting();
145
		
146
		createLogicalResource(RESOURCE_NAME);
147
		
148
		initializeTestModel();
149
	}
150
151
	protected void tearDown()
152
		throws Exception {
153
		
154
		stopWriting();  // in case a write action is left open
155
		stopReading();  // in case a read action is left open
156
		
157
		unloadLogicalResource();
158
		
159
		// clean up any others that a unit test may have created
160
		for (Iterator iter = new java.util.HashSet(domain.getResourceSet().getResources()).iterator(); iter.hasNext();) {
161
			unloadResource((Resource) iter.next());
162
		}
163
		
164
		subunit1 = null;
165
		root = null;
166
		
167
		if ((project != null) && project.exists()) {
168
			project.delete(true, true, null);
169
		}
170
		
171
		project = null;
172
		
173
		domain = null;
174
	}
175
176
	//
177
	// Other framework methods
178
	//
179
	
180
	/**
181
	 * Initializes the test model by loading it and stores certain key
182
	 * elements in the <tt>root</tt> and <tt>subunit<i>n</i></tt>
183
	 * variables.
184
	 */
185
	protected void initializeTestModel() {
186
		loadFromTestModel(logres);
187
		
188
		root = (Library) find("root"); //$NON-NLS-1$
189
		subunit1 = (Library) find(root, "level1/level2-subunit"); //$NON-NLS-1$
190
		subunit2 = (Library) find(subunit1, "level3/level4-subunit"); //$NON-NLS-1$
191
		subunit3 = (Library) find(root, "level1-1/level2-1-subunit"); //$NON-NLS-1$
192
	}
193
	
194
	/**
195
	 * Populates the specified resource with data from the test model file.
196
	 * 
197
	 * @param res the resource to load
198
	 */
199
	protected void loadFromTestModel(ILogicalResource res) {
200
		URI original = res.getURI();
201
		
202
		try {
203
			res.setURI(URI.createURI(MslCoreTestsBundle.getEntry(
204
				"/test_models/test_model.extlibrary").toString())); //$NON-NLS-1$
205
		
206
			// no special options needed to load the monolithic test model
207
			res.load(Collections.EMPTY_MAP);
208
		} catch (IOException e) {
209
			fail("Failed to load test model: " + e.getLocalizedMessage()); //$NON-NLS-1$
210
		} finally {
211
			res.setURI(original);
212
		}
213
	}
214
	
215
	/**
216
	 * Unloads the test resource.
217
	 */
218
	protected void unloadLogicalResource() {
219
		unloadLogicalResource(logres);
220
		
221
		logres = null;
222
	}
223
224
	/**
225
	 * Unloads the specified resource.
226
	 * 
227
	 * @param res the resource to unload
228
	 */
229
	protected void unloadResource(Resource res) {
230
		if (res != null) {
231
			if (res.isLoaded()) {
232
				res.unload();
233
			}
234
			
235
			if (res.getResourceSet() != null) {
236
				res.getResourceSet().getResources().remove(res);
237
			}
238
		}
239
	}
240
241
	/**
242
	 * Unloads the specified resource.
243
	 * 
244
	 * @param res the resource to unload
245
	 */
246
	protected void unloadLogicalResource(ILogicalResource res) {
247
		unloadResource(AbstractResourceWrapper.unwrap(res));
248
	}
249
250
	/**
251
	 * Creates a new logical resource on the specified path and assigns it
252
	 * to the <tt>logres</tt> test resource variable.
253
	 * 
254
	 * @param path a path relative to the workspace root
255
	 */
256
	protected void createLogicalResource(String path) {
257
		logres = createNewLogicalResource(
258
			URI.createPlatformResourceURI(path));
259
	}
260
261
	/**
262
	 * Creates a new logical resource on the specified URI.
263
	 * 
264
	 * @param uri the new resource's URI
265
	 * @return the new resource (not assigned to <tt>logres</tt>)
266
	 */
267
	protected ILogicalResource createNewLogicalResource(URI uri) {
268
		unloadResource(
269
			MEditingDomain.INSTANCE.getResourceSet().getResource(uri, false));
270
		
271
		return domain.asLogicalResource(
272
			domain.createResource(
273
				uri.toString(),
274
				MResourceOption.URI));
275
	}
276
277
	/**
278
	 * Saves the test resource.  This method stops writing and
279
	 * resumes again after saving.
280
	 */
281
	protected void saveLogicalResource() {
282
		saveLogicalResource(logres);
283
	}
284
285
	/**
286
	 * Saves the specified logical resource.  This method stops writing and
287
	 * resumes again after saving.
288
	 * 
289
	 * @param res the resource to save
290
	 */
291
	protected void saveLogicalResource(ILogicalResource res) {
292
		try {
293
			stopWriting();
294
			
295
			res.save(Collections.EMPTY_MAP);
296
			
297
			startWriting();
298
		} catch (IOException e) {
299
			fail("Exception in saving: " + e.getLocalizedMessage()); //$NON-NLS-1$
300
		}
301
	}
302
303
	/**
304
	 * Loads the test resource from its workspace location, initially loading
305
	 * all units.
306
	 */
307
	protected void loadLogicalResource() {
308
		loadLogicalResource(true);
309
	}
310
311
	/**
312
	 * Loads the test resource.
313
	 * 
314
	 * @param loadAllUnits whether to initially load all units.  If
315
	 *    <code>false</code>, units are not auto-loaded
316
	 */
317
	protected void loadLogicalResource(boolean loadAllUnits) {
318
		loadLogicalResource(logres, loadAllUnits, false);
319
	}
320
321
	/**
322
	 * Loads the test resource.
323
	 * 
324
	 * @param loadAllUnits whether to initially load all units
325
	 * @param autoLoadUnits if <code>loadAllUnits</code> is <code>false</code>,
326
	 *     whether to auto-load the units
327
	 */
328
	protected void loadLogicalResource(boolean loadAllUnits, boolean autoLoadUnits) {
329
		loadLogicalResource(logres, loadAllUnits, autoLoadUnits);
330
	}
331
332
	/**
333
	 * Loads the specified resource from its workspace location, initially loading
334
	 * all units.
335
	 * 
336
	 * @param res the resource to load
337
	 */
338
	protected void loadLogicalResource(ILogicalResource res) {
339
		loadLogicalResource(res, true, false);
340
	}
341
342
	/**
343
	 * Loads the specified resource.
344
	 * 
345
	 * @param res the resource to load
346
	 * @param loadAllUnits whether to initially load all units
347
	 * @param autoLoadUnits if <code>loadAllUnits</code> is <code>false</code>,
348
	 *     whether to auto-load the units
349
	 */
350
	protected void loadLogicalResource(ILogicalResource res, boolean loadAllUnits, boolean autoLoadUnits) {
351
		Map options = new java.util.HashMap();
352
		
353
		options.put(ILogicalResource.OPTION_LOAD_ALL_UNITS,
354
			Boolean.valueOf(loadAllUnits));
355
		options.put(ILogicalResource.OPTION_AUTO_LOAD_UNITS,
356
			Boolean.valueOf(autoLoadUnits));
357
		
358
		loadLogicalResource(res, options);
359
	}
360
361
	/**
362
	 * Loads the test resource with options.
363
	 * 
364
	 * @param res the resource to load
365
	 * @param options the load options to apply
366
	 */
367
	protected void loadLogicalResource(ILogicalResource res, Map options) {
368
		try {
369
			res.load(options);
370
			
371
			// verify that none of the physical resources was accidentally
372
			//    loaded by the resource set containing the logical resource,
373
			//    if the resource is not a wrapper
374
			if (!(res instanceof LogicalResourceWrapper)) {
375
				Set resources = new java.util.HashSet();
376
				resources.addAll(res.getMappedResources().values());
377
				assertFalse(resources.removeAll(res.getResourceSet().getResources()));
378
			}
379
		} catch (IOException e) {
380
			fail("Exception in loading: " + e.getLocalizedMessage()); //$NON-NLS-1$
381
		}
382
	}
383
384
	/**
385
	 * Finds the object in the test model having the specified qualified name.
386
	 * 
387
	 * @param qname a slash-delimited qualified name
388
	 * @return the matching object, or <code>null</code> if not found
389
	 */
390
	protected EObject find(String qname) {
391
		return find(logres, qname);
392
	}
393
	
394
	/**
395
	 * Finds the object in the test model having the specified qualified name,
396
	 * starting from some object.
397
	 * 
398
	 * @param object the starting object (resource or element)
399
	 * @param qname a slash-delimited qualified name, relative to the
400
	 *     provided <code>object</code>
401
	 * @return the matching object, or <code>null</code> if not found
402
	 */
403
	protected EObject find(Object start, String qname) {
404
		EObject result = null;
405
		Object current = start;
406
		
407
		String[] names = tokenize(qname);
408
		
409
		for (int i = 0; (current != null) && (i < names.length); i++) {
410
			String name = names[i];
411
			result = null;
412
			
413
			for (Iterator iter = getContents(current).iterator(); iter.hasNext();) {
414
				EObject child = (EObject) iter.next();
415
				
416
				if (name.equals(getName(child))) {
417
					result = child;
418
					break;
419
				}
420
			}
421
			
422
			current = result;
423
		}
424
		
425
		return result;
426
	}
427
428
	/**
429
	 * Gets the contents of an object.
430
	 * 
431
	 * @param object an object, which may be a resource or an element
432
	 * @return its immediate contents (children)
433
	 */
434
	private List getContents(Object object) {
435
		if (object instanceof EObject) {
436
			return ((EObject) object).eContents();
437
		} else if (object instanceof Resource) {
438
			return ((Resource) object).getContents();
439
		} else {
440
			return Collections.EMPTY_LIST;
441
		}
442
	}
443
	
444
	/**
445
	 * Tokenizes a qualified name on the slashes.
446
	 * 
447
	 * @param qname a qualified name
448
	 * @return the parts between the slashes
449
	 */
450
	private String[] tokenize(String qname) {
451
		return qname.split("/"); //$NON-NLS-1$
452
	}
453
	
454
	/** Looks up a library by its URI fragment. */
455
	protected Library lookupLibrary(String fragment) {
456
		return lookupLibrary(logres, fragment);
457
	}
458
459
	/** Looks up a library by its URI fragment. */
460
	protected Library lookupLibrary(ILogicalResource res, String fragment) {
461
		return (Library) res.getEObject(fragment);
462
	}
463
464
	/** Looks up a writer by its URI fragment. */
465
	protected Writer lookupWriter(String fragment) {
466
		return lookupWriter(logres, fragment);
467
	}
468
469
	/** Looks up a writer by its URI fragment. */
470
	protected Writer lookupWriter(ILogicalResource res, String fragment) {
471
		return (Writer) res.getEObject(fragment);
472
	}
473
474
	/** Looks up a book by its URI fragment. */
475
	protected Book lookupBook(String fragment) {
476
		return lookupBook(logres, fragment);
477
	}
478
479
	/** Looks up a book by its URI fragment. */
480
	protected Book lookupBook(ILogicalResource res, String fragment) {
481
		return (Book) res.getEObject(fragment);
482
	}
483
484
	/**
485
	 * Opens a write action (if necessary) in an undo interval (if necessary).
486
	 */
487
	protected void startWriting() {
488
		MSLUndoStack stack = ((MSLEditingDomain) domain).getUndoStack();
489
		
490
		if (!stack.isUndoIntervalOpen()) {
491
			stack.openUndoInterval("Test", "Logical Resource Test");  //$NON-NLS-1$//$NON-NLS-2$
492
		}
493
		
494
		if (!stack.isWriteActionInProgress()) {
495
			stack.startAction(ActionLockMode.WRITE);
496
		}
497
	}
498
499
	/**
500
	 * Stops writing, if we were writing.
501
	 * 
502
	 * @return the closed undo interval, if any needed to be closed; otherwise
503
	 *    <code>null</code>
504
	 */
505
	protected MUndoInterval stopWriting() {
506
		MSLUndoStack stack = ((MSLEditingDomain) domain).getUndoStack();
507
		MUndoInterval result = null;
508
		
509
		if (stack.isWriteActionInProgress()) {
510
			stack.completeAction();
511
		}
512
		
513
		if (stack.isUndoIntervalOpen()) {
514
			result = stack.closeUndoInterval();
515
		}
516
		
517
		return result;
518
	}
519
520
	/**
521
	 * Opens a read action (if necessary).
522
	 */
523
	protected void startReading() {
524
		MSLUndoStack stack = ((MSLEditingDomain) domain).getUndoStack();
525
		stack.startAction(ActionLockMode.READ);
526
		isReading = true;
527
	}
528
529
	/**
530
	 * Closes a read action, if one was open.
531
	 */
532
	protected void stopReading() {
533
		MSLUndoStack stack = ((MSLEditingDomain) domain).getUndoStack();
534
		if (isReading) {
535
			isReading = false;
536
			stack.completeAction();
537
		}
538
	}
539
	
540
	/**
541
	 * Gets the file corresponding to the specified workspace path.
542
	 * 
543
	 * @param path a path relative to the workspace root
544
	 * @return the corresponding file
545
	 */
546
	protected IFile getFile(String path) {
547
		return getFile(new Path(path));
548
	}
549
	
550
	/**
551
	 * Gets the file corresponding to the specified workspace path.
552
	 * 
553
	 * @param path a path relative to the workspace root
554
	 * @return the corresponding file
555
	 */
556
	protected IFile getFile(IPath path) {
557
		IWorkspaceRoot wsRoot = (IWorkspaceRoot) project.getParent();
558
		return wsRoot.getFile(path);
559
	}
560
	
561
	/**
562
	 * Gets the name of a library object.
563
	 * 
564
	 * @param object the object
565
	 * @return its name
566
	 */
567
	private String getName(EObject object) {
568
		return (String) GetName.INSTANCE.doSwitch(object);
569
	}
570
	
571
	/**
572
	 * Switch to compute the names of library objects.
573
	 *
574
	 * @author Christian W. Damus (cdamus)
575
	 */
576
	private static final class GetName extends EXTLibrarySwitch {
577
		static final GetName INSTANCE = new GetName();
578
		
579
		private GetName() {
580
			super();
581
		}
582
		
583
		public Object caseAudoVisualItem(AudioVisualItem object) {
584
			return object.getTitle();
585
		}
586
587
		public Object caseBook(Book object) {
588
			return object.getTitle();
589
		}
590
591
		public Object caseLibrary(Library object) {
592
			return object.getName();
593
		}
594
595
		public Object casePeriodical(Periodical object) {
596
			return object.getTitle();
597
		}
598
		
599
		public Object caseWriter(Writer object) {
600
			return object.getName();
601
		}
602
603
		public Object casePerson(Person object) {
604
			if (object.getFirstName() == null) {
605
				if (object.getLastName() == null) {
606
					return ""; //$NON-NLS-1$
607
				} else {
608
					return object.getLastName();
609
				}
610
			} else if (object.getLastName() == null) {
611
				return object.getFirstName();
612
			} else {
613
				StringBuffer result = new StringBuffer();
614
615
				result.append(object.getFirstName()).append(' ').append(
616
					object.getLastName());
617
618
				return result.toString();
619
			}
620
		}
621
622
		public Object defaultCase(EObject object) {
623
			return ""; //$NON-NLS-1$
624
		}
625
	}
626
}
(-)src/org/eclipse/gmf/tests/runtime/emf/core/internal/resources/LogicalResourcePolicyManagerTest.java (-313 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
13
package org.eclipse.gmf.tests.runtime.emf.core.internal.resources;
14
15
import org.eclipse.emf.common.util.EList;
16
import org.eclipse.emf.common.util.URI;
17
import org.eclipse.emf.ecore.EAttribute;
18
import org.eclipse.emf.ecore.EClass;
19
import org.eclipse.emf.ecore.EFactory;
20
import org.eclipse.emf.ecore.EObject;
21
import org.eclipse.emf.ecore.EPackage;
22
import org.eclipse.emf.ecore.EcoreFactory;
23
import org.eclipse.emf.ecore.EcorePackage;
24
25
import org.eclipse.gmf.runtime.emf.core.edit.MEditingDomain;
26
import org.eclipse.gmf.runtime.emf.core.internal.resources.LogicalResourcePolicyManager;
27
import org.eclipse.gmf.runtime.emf.core.resources.CannotAbsorbException;
28
import org.eclipse.gmf.runtime.emf.core.resources.CannotSeparateException;
29
import org.eclipse.gmf.runtime.emf.core.resources.ILogicalResource;
30
import org.eclipse.gmf.runtime.emf.core.resources.ILogicalResourcePolicy;
31
import org.eclipse.gmf.runtime.emf.core.resources.MResourceFactory;
32
33
import junit.framework.Test;
34
import junit.framework.TestCase;
35
import junit.framework.TestSuite;
36
37
/**
38
 * Tests the {@link LogicalResourcePolicyManager} class.
39
 *
40
 * @author Christian W. Damus (cdamus)
41
 */
42
public class LogicalResourcePolicyManagerTest
43
	extends TestCase {
44
	
45
	private EPackage dynamicPackage;
46
	private EClass dynamicClass;
47
	static EAttribute dynamicPoliciesAttribute;
48
	private EObject dynamicObject;
49
	private ILogicalResource res;
50
	
51
	public static Test suite() {
52
		return new TestSuite(LogicalResourcePolicyManagerTest.class, "Policy Manager Tests"); //$NON-NLS-1$
53
	}
54
	
55
	public void test_canSeparate() {
56
		assertTrue(LogicalResourcePolicyManager.getInstance().canSeparate(
57
			res, dynamicObject));
58
		checkTokens();
59
		
60
		TestPolicy.shouldBalk = true;
61
		
62
		assertFalse(LogicalResourcePolicyManager.getInstance().canSeparate(
63
			res, dynamicObject));
64
		checkTokens();
65
	}
66
	
67
	public void test_preSeparate() {
68
		URI uri = null;
69
		try {
70
			uri = LogicalResourcePolicyManager.getInstance().preSeparate(
71
				res, dynamicObject, null);
72
		} catch (CannotSeparateException e) {
73
			fail("Should not have thrown: " + e); //$NON-NLS-1$
74
		}
75
		checkTokens();
76
		assertNotNull(uri);
77
		// check that the first suggestion was accepted
78
		assertEquals(URI.createFileURI("/tmp/Foo.xmi"), uri); //$NON-NLS-1$
79
		
80
		try {
81
			uri = LogicalResourcePolicyManager.getInstance().preSeparate(
82
				res, dynamicObject, URI.createFileURI("/tmp/User.xmi")); //$NON-NLS-1$
83
		} catch (CannotSeparateException e) {
84
			fail("Should not have thrown: " + e); //$NON-NLS-1$
85
		}
86
		checkTokens();
87
		assertNotNull(uri);
88
		// check that the no suggestion was accepted
89
		assertEquals(URI.createFileURI("/tmp/User.xmi"), uri); //$NON-NLS-1$
90
		
91
		TestPolicy.shouldBalk = true;
92
		
93
		try {
94
			uri = LogicalResourcePolicyManager.getInstance().preSeparate(
95
				res, dynamicObject, null);
96
			fail("Should have thrown exception."); //$NON-NLS-1$
97
		} catch (CannotSeparateException e) {
98
			checkTokens();
99
		}
100
	}
101
	
102
	public void test_postSeparate() {
103
		LogicalResourcePolicyManager.getInstance().postSeparate(
104
			res, dynamicObject, URI.createFileURI("/tmp/User.xmi")); //$NON-NLS-1$
105
		checkTokens();
106
	}
107
	
108
	public void test_preAbsorb() {
109
		try {
110
			LogicalResourcePolicyManager.getInstance().preAbsorb(
111
				res, dynamicObject);
112
		} catch (CannotAbsorbException e) {
113
			fail("Should not have thrown: " + e); //$NON-NLS-1$
114
		}
115
		checkTokens();
116
		
117
		TestPolicy.shouldBalk = true;
118
		
119
		try {
120
			LogicalResourcePolicyManager.getInstance().preAbsorb(
121
				res, dynamicObject);
122
			fail("Should have thrown exception."); //$NON-NLS-1$
123
		} catch (CannotAbsorbException e) {
124
			checkTokens();
125
		}
126
	}
127
	
128
	public void test_postAbsorb() {
129
		LogicalResourcePolicyManager.getInstance().postAbsorb(
130
			res, dynamicObject);
131
		checkTokens();
132
	}
133
	
134
	/**
135
	 * Tests the robustness of the policy manager against run-time exceptions
136
	 * in the policies.
137
	 */
138
	public void test_robustness() {
139
		TestPolicy.shouldThrow = true;
140
		
141
		LogicalResourcePolicyManager.getInstance().canSeparate(res, dynamicObject);
142
		checkTokens();
143
		
144
		try {
145
			LogicalResourcePolicyManager.getInstance().preSeparate(res, dynamicObject, null);
146
			checkTokens();
147
		} catch (CannotSeparateException e) {
148
			fail("Should not have thrown: " + e); //$NON-NLS-1$
149
		}
150
		
151
		LogicalResourcePolicyManager.getInstance().postSeparate(res, dynamicObject, null);
152
		checkTokens();
153
		
154
		try {
155
			LogicalResourcePolicyManager.getInstance().preAbsorb(res, dynamicObject);
156
			checkTokens();
157
		} catch (CannotAbsorbException e) {
158
			fail("Should not have thrown: " + e); //$NON-NLS-1$
159
		}
160
		
161
		LogicalResourcePolicyManager.getInstance().postAbsorb(res, dynamicObject);
162
		checkTokens();
163
	}
164
	
165
	//
166
	// Fixtures
167
	//
168
	
169
	protected void setUp()
170
		throws Exception {
171
		
172
		super.setUp();
173
		
174
		// create the dynamic metamodel and an object
175
		dynamicPackage = EcoreFactory.eINSTANCE.createEPackage();
176
		dynamicPackage.setName("logrestest"); //$NON-NLS-1$
177
		dynamicPackage.setNsPrefix("logrestest"); //$NON-NLS-1$
178
		dynamicPackage.setNsURI("http:///com/ibm/xtools/emf/msl/core/tests/logrestest.ecore"); //$NON-NLS-1$
179
		
180
		EFactory factory = EcoreFactory.eINSTANCE.createEFactory();
181
		factory.setEPackage(dynamicPackage);
182
		dynamicPackage.setEFactoryInstance(factory);
183
184
		dynamicClass = EcoreFactory.eINSTANCE.createEClass();
185
		dynamicPackage.getEClassifiers().add(dynamicClass);
186
		dynamicClass.setName("TestClass"); //$NON-NLS-1$
187
		
188
		dynamicPoliciesAttribute = EcoreFactory.eINSTANCE.createEAttribute();
189
		dynamicClass.getEStructuralFeatures().add(dynamicPoliciesAttribute);
190
		dynamicPoliciesAttribute.setName("policies"); //$NON-NLS-1$
191
		dynamicPoliciesAttribute.setUpperBound(EAttribute.UNBOUNDED_MULTIPLICITY);
192
		dynamicPoliciesAttribute.setEType(EcorePackage.eINSTANCE.getEJavaObject());
193
		
194
		dynamicObject = factory.create(dynamicClass);
195
		
196
		res = (ILogicalResource) new MResourceFactory().createResource(
197
			URI.createFileURI("/tmp/logrespolmgrtest.xmi")); //$NON-NLS-1$
198
		MEditingDomain.INSTANCE.getResourceSet().getResources().add(res);
199
	}
200
	
201
	protected void tearDown()
202
		throws Exception {
203
		
204
		res.unload();
205
		MEditingDomain.INSTANCE.getResourceSet().getResources().remove(res);
206
		
207
		TestPolicy.shouldThrow = false;
208
		TestPolicy.shouldBalk = false;
209
		
210
		dynamicObject = null;
211
		dynamicPoliciesAttribute = null;
212
		dynamicClass = null;
213
		dynamicPackage = null;
214
		
215
		super.tearDown();
216
	}
217
218
	/**
219
	 * Checks that both tokens were added to the dynamic eObject by the test,
220
	 * then clears them.
221
	 */
222
	private void checkTokens() {
223
		EList value = (EList) dynamicObject.eGet(dynamicPoliciesAttribute);
224
		
225
		// check that both tokens were added
226
		assertEquals(2, value.size());
227
		
228
		if (TestPolicy.shouldThrow) {
229
			assertTrue(value.get(0) instanceof RuntimeException);
230
			assertTrue(value.get(1) instanceof RuntimeException);
231
		} else {
232
			assertTrue(value.get(0) instanceof TestPolicy);
233
			assertTrue(value.get(1) instanceof TestPolicy);
234
		}
235
		
236
		value.clear();
237
	}
238
	
239
	/**
240
	 * Test policy implementation.  Two instances are created, 0 and 1.
241
	 * If the 1 instance is invoked when the <code>shouldBalk</code> flag is
242
	 * set, then it either returns false or throws an exception, as appropriate
243
	 * to the method being called.  The 0 instance always behaves nicely.
244
	 *
245
	 * @author Christian W. Damus (cdamus)
246
	 */
247
	public static class TestPolicy implements ILogicalResourcePolicy {
248
		static boolean shouldBalk = false;
249
		static boolean shouldThrow = false;
250
		
251
		private static int nextSerialNum = 0;
252
		
253
		private final int serialNum;
254
		
255
		public TestPolicy() {
256
			serialNum = nextSerialNum++;
257
		}
258
		
259
		public boolean canSeparate(ILogicalResource resource, EObject eObject) {
260
			recordToken(eObject);
261
			
262
			return serialNum == 0 || !shouldBalk;
263
		}
264
265
		public URI preSeparate(ILogicalResource resource, EObject eObject, URI uri)
266
			throws CannotSeparateException {
267
			
268
			recordToken(eObject);
269
			
270
			if (serialNum == 0) {
271
				return URI.createFileURI("/tmp/Foo.xmi"); //$NON-NLS-1$
272
			} else {
273
				if (shouldBalk) {
274
					throw new CannotSeparateException("I should balk."); //$NON-NLS-1$
275
				}
276
				
277
				return URI.createFileURI("/tmp/Bar.xmi"); //$NON-NLS-1$;
278
			}
279
		}
280
281
		public void postSeparate(ILogicalResource resource, EObject eObject, URI uri) {
282
			recordToken(eObject);
283
		}
284
285
		public void preAbsorb(ILogicalResource resource, EObject eObject)
286
			throws CannotAbsorbException {
287
			
288
			recordToken(eObject);
289
			
290
			if (serialNum == 1 && shouldBalk) {
291
				throw new CannotAbsorbException("I should balk."); //$NON-NLS-1$
292
			}
293
		}
294
295
		public void postAbsorb(ILogicalResource resource, EObject eObject) {
296
			recordToken(eObject);
297
		}
298
		
299
		private void recordToken(EObject eObject) {
300
			EList value = (EList) eObject.eGet(dynamicPoliciesAttribute);
301
			
302
			if (shouldThrow) {
303
				RuntimeException e = new RuntimeException(
304
					"I am supposed to throw."); //$NON-NLS-1$
305
				
306
				value.add(e);
307
				throw e; 
308
			} else {
309
				value.add(this);
310
			}
311
		}
312
	}
313
}
(-)src/org/eclipse/gmf/tests/runtime/emf/core/internal/resources/CrossReferenceTest.java (-578 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
13
package org.eclipse.gmf.tests.runtime.emf.core.internal.resources;
14
15
import java.util.Collections;
16
import java.util.Iterator;
17
import java.util.Map;
18
import java.util.Set;
19
20
import junit.framework.Test;
21
import junit.framework.TestSuite;
22
23
import org.eclipse.emf.common.util.URI;
24
import org.eclipse.emf.ecore.EObject;
25
import org.eclipse.emf.ecore.resource.ResourceSet;
26
import org.eclipse.emf.ecore.util.EcoreUtil;
27
import org.eclipse.emf.ecore.util.InternalEList;
28
29
import org.eclipse.emf.examples.extlibrary.Book;
30
import org.eclipse.emf.examples.extlibrary.EXTLibraryFactory;
31
import org.eclipse.emf.examples.extlibrary.EXTLibraryPackage;
32
import org.eclipse.emf.examples.extlibrary.Library;
33
import org.eclipse.emf.examples.extlibrary.Writer;
34
import org.eclipse.gmf.runtime.emf.core.resources.CannotSeparateException;
35
import org.eclipse.gmf.runtime.emf.core.resources.ILogicalResource;
36
37
38
/**
39
 * Tests the the management of cross-references (between units and logical
40
 * resources) in a logical resource, as well as the loading of (non-root)
41
 * sub-units in logical and physical mode.
42
 *
43
 * @author Christian W. Damus (cdamus)
44
 */
45
public class CrossReferenceTest
46
	extends BaseLogicalResourceTest {
47
	
48
	public CrossReferenceTest(String name) {
49
		super(name);
50
	}
51
	
52
	public static Test suite() {
53
		return new TestSuite(CrossReferenceTest.class, "Cross-Reference Tests"); //$NON-NLS-1$
54
	}
55
56
	/**
57
	 * Tests resolution of cross-unit references on loading.  This case has
58
	 * a bidirectional reference between unrelated units.
59
	 */
60
	public void test_crossUnitReferences_unrelated() {
61
		try {
62
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
63
			logres.separate(subunit3, URI.createPlatformResourceURI(SUBUNIT_NAME2));
64
		} catch (CannotSeparateException e) {
65
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
66
		}
67
		
68
		Book book = (Book) find(subunit1, "Level2 Book"); //$NON-NLS-1$
69
		String bookFrag = logres.getURIFragment(book);
70
		
71
		Writer writer = (Writer) find(subunit3, "Level2-1 Writer"); //$NON-NLS-1$
72
		writer.getBooks().add(book);  // cross-unit reference
73
		String writerFrag = logres.getURIFragment(writer);
74
		
75
		saveLogicalResource();
76
		
77
		// discard and re-load the resource
78
		createLogicalResource(RESOURCE_NAME);
79
		
80
		loadLogicalResource();
81
		
82
		book = lookupBook(bookFrag);
83
		assertNotNull(book);
84
		
85
		writer = lookupWriter(writerFrag);
86
		assertNotNull(writer);
87
		
88
		assertTrue(writer.getBooks().contains(book));
89
		assertSame(writer, book.getAuthor());
90
	}
91
	
92
	/**
93
	 * Tests resolution of cross-unit references on loading.  This case has
94
	 * a bidirectional reference between parent and child units.
95
	 */
96
	public void test_crossUnitReferences_parentChild() {
97
		try {
98
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
99
			logres.separate(subunit2, URI.createPlatformResourceURI(SUBUNIT_NAME2));
100
		} catch (CannotSeparateException e) {
101
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
102
		}
103
		
104
		Book book = (Book) find(subunit1, "Level2 Book"); //$NON-NLS-1$
105
		String bookFrag = logres.getURIFragment(book);
106
		
107
		Writer writer = (Writer) find(subunit2, "Level4 Writer"); //$NON-NLS-1$
108
		writer.getBooks().add(book);  // cross-unit reference
109
		String writerFrag = logres.getURIFragment(writer);
110
		
111
		saveLogicalResource();
112
		
113
		// discard and re-load the resource
114
		createLogicalResource(RESOURCE_NAME);
115
		
116
		loadLogicalResource();
117
		
118
		book = lookupBook(bookFrag);
119
		assertNotNull(book);
120
		
121
		writer = lookupWriter(writerFrag);
122
		assertNotNull(writer);
123
		
124
		assertTrue(writer.getBooks().contains(book));
125
		assertSame(writer, book.getAuthor());
126
	}
127
	
128
	/**
129
	 * Tests resolution of cross-unit references on loading.  This case has
130
	 * a bidirectional reference between the root unit and a child unit.
131
	 */
132
	public void test_crossUnitReferences_rootChild() {
133
		try {
134
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
135
		} catch (CannotSeparateException e) {
136
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
137
		}
138
		
139
		Book book = (Book) find("root/Root Book"); //$NON-NLS-1$
140
		String bookFrag = logres.getURIFragment(book);
141
		
142
		Writer writer = (Writer) find(subunit1, "Level2 Writer"); //$NON-NLS-1$
143
		writer.getBooks().add(book);  // cross-unit reference
144
		String writerFrag = logres.getURIFragment(writer);
145
		
146
		saveLogicalResource();
147
		
148
		// discard and re-load the resource
149
		createLogicalResource(RESOURCE_NAME);
150
		
151
		loadLogicalResource();
152
		
153
		book = lookupBook(bookFrag);
154
		assertNotNull(book);
155
		
156
		writer = lookupWriter(writerFrag);
157
		assertNotNull(writer);
158
		
159
		assertTrue(writer.getBooks().contains(book));
160
		assertSame(writer, book.getAuthor());
161
	}
162
	
163
	/**
164
	 * Tests the on-the-fly replacement of the logical resource by its proper
165
	 * root when loading a non-root unit, loading the units required to trace
166
	 * containment to the root unit.
167
	 */
168
	public void test_loadNonRootUnit() {
169
		try {
170
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
171
			logres.separate(subunit2, URI.createPlatformResourceURI(SUBUNIT_NAME2));
172
			logres.separate(subunit3, URI.createPlatformResourceURI(SUBUNIT_NAME3));
173
		} catch (CannotSeparateException e) {
174
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
175
		}
176
		
177
		Book bookRoot = (Book) find(root, "Root Book"); //$NON-NLS-1$
178
		String bookRootFrag = logres.getURIFragment(bookRoot);
179
		Book book1 = (Book) find(subunit1, "Level2 Book"); //$NON-NLS-1$
180
		String book1Frag = logres.getURIFragment(book1);
181
		Book book2 = (Book) find(subunit2, "Level4 Book"); //$NON-NLS-1$
182
		String book2Frag = logres.getURIFragment(book2);
183
		Book book3 = (Book) find(subunit3, "Level2-1 Book"); //$NON-NLS-1$
184
		String book3Frag = logres.getURIFragment(book3);
185
		
186
		saveLogicalResource();
187
		
188
		URI logicalUri = logres.getURI();
189
		URI subunitUri = URI.createPlatformResourceURI(SUBUNIT_NAME2);
190
		
191
		// discard the logical resource and load the subunit
192
		unloadLogicalResource();
193
		createLogicalResource(SUBUNIT_NAME2);
194
		
195
		// so, we're trying to load the second-level unit.  We want to
196
		//   actually load the second-, first-, and root-level units, but not
197
		//   the other unit that contains book3 (subunit3)
198
		loadLogicalResource(false);
199
		
200
		// the logical resource has assumed the logical URI, despite its having
201
		//    been created with a subunit's URI
202
		assertEquals(logicalUri, logres.getURI());
203
		
204
		// make sure we didn't get an extra logical resource by this means
205
		assertNull(domain.getResourceSet().getResource(subunitUri, false));
206
		
207
		// make sure that we didn't get too many physical resources, either
208
		ResourceSet rset = (ResourceSet) logres.getAdapter(ResourceSet.class);
209
		assertEquals(4, rset.getResources().size());
210
		
211
		// make sure that we find the books we expect and not the ones we don't.
212
		bookRoot = lookupBook(bookRootFrag);
213
		assertNotNull(bookRoot);
214
		book1 = lookupBook(book1Frag);
215
		assertNotNull(book1);
216
		book2 = lookupBook(book2Frag);
217
		assertNotNull(book2);
218
		book3 = lookupBook(book3Frag);
219
		assertNull(book3);  // didn't load this unit
220
		
221
		// Repeat by walking the tree instead of looking by fragment, to check
222
		// that the content tree is correctly connected
223
		Set notFound = new java.util.HashSet();
224
		notFound.add(bookRootFrag);
225
		notFound.add(book1Frag);
226
		notFound.add(book2Frag);
227
		notFound.add(book3Frag);
228
		
229
		for (Iterator iter = logres.getAllContents(); iter.hasNext();) {
230
			notFound.remove(logres.getURIFragment((EObject) iter.next()));
231
		}
232
		
233
		assertEquals(Collections.singleton(book3Frag), notFound);  // didn't load this unit
234
	}
235
	
236
	/**
237
	 * Tests the on-the-fly replacement of the logical resource by its proper
238
	 * root when loading a non-root unit storing a logical root.
239
	 */
240
	public void test_loadNonRootUnit_logicalRoot() {
241
		logres.getContents().add(subunit3);  // create another root
242
		
243
		try {
244
			// separating a root element
245
			logres.separate(subunit3, URI.createPlatformResourceURI(SUBUNIT_NAME3));
246
			
247
			// just for fun, separate another root's descendent into same unit
248
			logres.separate(subunit2, URI.createPlatformResourceURI(SUBUNIT_NAME3));
249
		} catch (CannotSeparateException e) {
250
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
251
		}
252
		
253
		Book bookRoot = (Book) find(root, "Root Book"); //$NON-NLS-1$
254
		String bookRootFrag = logres.getURIFragment(bookRoot);
255
		Book book1 = (Book) find(subunit1, "Level2 Book"); //$NON-NLS-1$
256
		String book1Frag = logres.getURIFragment(book1);
257
		Book book2 = (Book) find(subunit2, "Level4 Book"); //$NON-NLS-1$
258
		String book2Frag = logres.getURIFragment(book2);
259
		Book book3 = (Book) find(subunit3, "Level2-1 Book"); //$NON-NLS-1$
260
		String book3Frag = logres.getURIFragment(book3);
261
		
262
		saveLogicalResource();
263
		
264
		URI logicalUri = logres.getURI();
265
		URI subunitUri = URI.createPlatformResourceURI(SUBUNIT_NAME3);
266
		
267
		// discard the logical resource and load the subunit
268
		unloadLogicalResource();
269
		createLogicalResource(SUBUNIT_NAME3);
270
		
271
		// so, we're trying to load the second-level unit with the logical root
272
		loadLogicalResource();
273
		
274
		// the logical resource has assumed the logical URI, despite its having
275
		//    been created with a subunit's URI
276
		assertEquals(logicalUri, logres.getURI());
277
		
278
		// make sure we didn't get an extra logical resource by this means
279
		assertNull(domain.getResourceSet().getResource(subunitUri, false));
280
		
281
		// make sure that we didn't get too many physical resources, either
282
		ResourceSet rset = (ResourceSet) logres.getAdapter(ResourceSet.class);
283
		assertEquals(2, rset.getResources().size());
284
		assertEquals(3, logres.getMappedResources().size());
285
		
286
		// make sure that we find the books we expect
287
		bookRoot = lookupBook(bookRootFrag);
288
		assertNotNull(bookRoot);
289
		book1 = lookupBook(book1Frag);
290
		assertNotNull(book1);
291
		book2 = lookupBook(book2Frag);
292
		assertNotNull(book2);
293
		book3 = lookupBook(book3Frag);
294
		assertNotNull(book3);
295
		
296
		// Repeat by walking the tree instead of looking by fragment, to check
297
		// that the content tree is correctly connected
298
		Set notFound = new java.util.HashSet();
299
		notFound.add(bookRootFrag);
300
		notFound.add(book1Frag);
301
		notFound.add(book2Frag);
302
		notFound.add(book3Frag);
303
		
304
		for (Iterator iter = logres.getAllContents(); iter.hasNext();) {
305
			notFound.remove(logres.getURIFragment((EObject) iter.next()));
306
		}
307
		
308
		assertEquals(Collections.EMPTY_SET, notFound);
309
	}
310
	
311
	/**
312
	 * Tests the case where the sub-unit that we are trying to load has
313
	 * multiple parent units.  Both parents must be loaded, recursively.
314
	 */
315
	public void test_loadNonRootUnit_multiParents() {
316
		Library subunit4 = EXTLibraryFactory.eINSTANCE.createLibrary();
317
		subunit3.getBranches().add(subunit4);
318
		subunit4.setName("level 3-1-Subunit"); //$NON-NLS-1$
319
		Book book4 = EXTLibraryFactory.eINSTANCE.createBook();
320
		subunit4.getBooks().add(book4);
321
		book4.setTitle("Level3-1 Book"); //$NON-NLS-1$
322
		
323
		try {
324
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
325
			logres.separate(subunit2, URI.createPlatformResourceURI(SUBUNIT_NAME2));
326
			logres.separate(subunit3, URI.createPlatformResourceURI(SUBUNIT_NAME3));
327
			
328
			// another 2nd-level sub-unit into the same file as subunit2, with
329
			// a different parent unit
330
			logres.separate(subunit4, URI.createPlatformResourceURI(SUBUNIT_NAME2));
331
		} catch (CannotSeparateException e) {
332
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
333
		}
334
		
335
		Book bookRoot = (Book) find(root, "Root Book"); //$NON-NLS-1$
336
		String bookRootFrag = logres.getURIFragment(bookRoot);
337
		Book book1 = (Book) find(subunit1, "Level2 Book"); //$NON-NLS-1$
338
		String book1Frag = logres.getURIFragment(book1);
339
		Book book2 = (Book) find(subunit2, "Level4 Book"); //$NON-NLS-1$
340
		String book2Frag = logres.getURIFragment(book2);
341
		Book book3 = (Book) find(subunit3, "Level2-1 Book"); //$NON-NLS-1$
342
		String book3Frag = logres.getURIFragment(book3);
343
		String book4Frag = logres.getURIFragment(book4);
344
		
345
		saveLogicalResource();
346
		
347
		URI logicalUri = logres.getURI();
348
		URI subunitUri = URI.createPlatformResourceURI(SUBUNIT_NAME2);
349
		
350
		// discard the logical resource and load the subunit
351
		unloadLogicalResource();
352
		createLogicalResource(SUBUNIT_NAME2);
353
		
354
		// so, we're trying to load the second-level unit.  We want to
355
		//   actually load the second-, first-, and root-level units, and this
356
		//   time also the other unit that contains book3 (subunit3)
357
		loadLogicalResource(false);
358
		
359
		// the logical resource has assumed the logical URI, despite its having
360
		//    been created with a subunit's URI
361
		assertEquals(logicalUri, logres.getURI());
362
		
363
		// make sure we didn't get an extra logical resource by this means
364
		assertNull(domain.getResourceSet().getResource(subunitUri, false));
365
		
366
		// make sure that we didn't get too many physical resources, either
367
		ResourceSet rset = (ResourceSet) logres.getAdapter(ResourceSet.class);
368
		assertEquals(4, rset.getResources().size());
369
		
370
		// make sure that we find the books we expect
371
		bookRoot = lookupBook(bookRootFrag);
372
		assertNotNull(bookRoot);
373
		book1 = lookupBook(book1Frag);
374
		assertNotNull(book1);
375
		book2 = lookupBook(book2Frag);
376
		assertNotNull(book2);
377
		book3 = lookupBook(book3Frag);
378
		assertNotNull(book3);  // did load this unit this time
379
		book4 = lookupBook(book4Frag);
380
		assertNotNull(book4);
381
		
382
		// Repeat by walking the tree instead of looking by fragment, to check
383
		// that the content tree is correctly connected
384
		Set notFound = new java.util.HashSet();
385
		notFound.add(bookRoot);
386
		notFound.add(book1);
387
		notFound.add(book2);
388
		notFound.add(book3);
389
		notFound.add(book4);
390
		
391
		for (Iterator iter = logres.getAllContents(); iter.hasNext();) {
392
			notFound.remove(iter.next());
393
		}
394
		
395
		assertEquals(Collections.EMPTY_SET, notFound);  // did load book3 this time
396
	}
397
	
398
	/**
399
	 * Tests the support for loading only a single physical resource.
400
	 */
401
	public void test_loadAsPhysical() {
402
		try {
403
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
404
			logres.separate(subunit2, URI.createPlatformResourceURI(SUBUNIT_NAME2));
405
		} catch (CannotSeparateException e) {
406
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
407
		}
408
		
409
		Book bookRoot = (Book) find(root, "Root Book"); //$NON-NLS-1$
410
		String bookRootFrag = logres.getURIFragment(bookRoot);
411
		Book book1 = (Book) find(subunit1, "Level2 Book"); //$NON-NLS-1$
412
		String book1Frag = logres.getURIFragment(book1);
413
		Book book2 = (Book) find(subunit2, "Level4 Book"); //$NON-NLS-1$
414
		String book2Frag = logres.getURIFragment(book2);
415
		
416
		saveLogicalResource();
417
		
418
		URI logicalUri = logres.getURI();
419
		URI subunitUri = URI.createPlatformResourceURI(SUBUNIT_NAME1);
420
		
421
		// discard the logical resource and load the subunit
422
		unloadLogicalResource();
423
		createLogicalResource(SUBUNIT_NAME1);
424
		
425
		// we're trying to load the middle-level unit, and only it
426
		Map options = new java.util.HashMap();
427
		options.put(ILogicalResource.OPTION_LOAD_AS_LOGICAL, Boolean.FALSE);
428
		loadLogicalResource(logres, options);
429
		
430
		// the logical resource has not assumed the logical URI, despite its having
431
		//    been created with a subunit's URI
432
		assertEquals(subunitUri, logres.getURI());
433
		
434
		// make sure we didn't get an extra logical resource by this means
435
		assertNull(domain.getResourceSet().getResource(logicalUri, false));
436
		
437
		// make sure that we didn't get too many physical resources, either
438
		ResourceSet rset = (ResourceSet) logres.getAdapter(ResourceSet.class);
439
		assertEquals(2, rset.getResources().size());  // the resource and its sub-unit
440
		
441
		// make sure that we find the books we expect, and not the ones we don't
442
		bookRoot = lookupBook(bookRootFrag);
443
		assertNull(bookRoot);
444
		book1 = lookupBook(book1Frag);
445
		assertNotNull(book1);
446
		book2 = lookupBook(book2Frag);
447
		assertNull(book2);
448
		
449
		// check that the resource has the expected contents list
450
		assertEquals(
451
			Collections.singletonList(book1.eContainer()),
452
			logres.getContents());
453
	}
454
	
455
	/**
456
	 * Tests the support for saving a resource loaded as a single physical
457
	 * resource.
458
	 */
459
	public void test_savePhysical() {
460
		try {
461
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
462
			logres.separate(subunit2, URI.createPlatformResourceURI(SUBUNIT_NAME2));
463
		} catch (CannotSeparateException e) {
464
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
465
		}
466
		
467
		Book bookRoot = (Book) find(root, "Root Book"); //$NON-NLS-1$
468
		String bookRootFrag = logres.getURIFragment(bookRoot);
469
		Book book1 = (Book) find(subunit1, "Level2 Book"); //$NON-NLS-1$
470
		String book1Frag = logres.getURIFragment(book1);
471
		Book book2 = (Book) find(subunit2, "Level4 Book"); //$NON-NLS-1$
472
		String book2Frag = logres.getURIFragment(book2);
473
		
474
		saveLogicalResource();
475
		
476
		// discard the logical resource and load the subunit
477
		unloadLogicalResource();
478
		createLogicalResource(SUBUNIT_NAME1);
479
		
480
		// we're trying to load the middle-level unit, and only it
481
		Map options = new java.util.HashMap();
482
		options.put(ILogicalResource.OPTION_LOAD_AS_LOGICAL, Boolean.FALSE);
483
		loadLogicalResource(logres, options);
484
		
485
		// get the book and change its title
486
		book1 = lookupBook(book1Frag);
487
		assertNotNull(book1);
488
		String newTitle = "New Title"; //$NON-NLS-1$
489
		book1.setTitle(newTitle);
490
		
491
		saveLogicalResource();
492
		
493
		// discard the logical resource and load the whole logical resource
494
		unloadLogicalResource();
495
		createLogicalResource(RESOURCE_NAME);
496
		loadLogicalResource();
497
		
498
		// make sure that we find the books we expect with the right containment
499
		bookRoot = lookupBook(bookRootFrag);
500
		assertNotNull(bookRoot);
501
		book1 = lookupBook(book1Frag);
502
		assertNotNull(book1);
503
		book2 = lookupBook(book2Frag);
504
		assertNotNull(book2);
505
		
506
		assertTrue(EcoreUtil.isAncestor(logres.getContents(), book1));
507
508
		// check the title
509
		assertEquals(newTitle, book1.getTitle());
510
	}
511
	
512
	/**
513
	 * Tests that we can correctly resolve references between logical models.
514
	 */
515
	public void test_interLogicalModelReference() {
516
		try {
517
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
518
		} catch (CannotSeparateException e) {
519
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
520
		}
521
		
522
		ILogicalResource logres2 = createNewLogicalResource(
523
			URI.createPlatformResourceURI(RESOURCE_NAME2));
524
		Library library2 = EXTLibraryFactory.eINSTANCE.createLibrary();
525
		logres2.getContents().add(library2);
526
		library2.setName("Library 2"); //$NON-NLS-1$
527
		
528
		subunit3 = EXTLibraryFactory.eINSTANCE.createLibrary();
529
		library2.getBranches().add(subunit3);
530
		subunit3.setName("Library 2 Subunit"); //$NON-NLS-1$
531
		
532
		String library2SubunitName = "/" + PROJECT_NAME + "/logres2.1.extlibrary"; //$NON-NLS-1$//$NON-NLS-2$
533
		try {
534
			logres2.separate(subunit3, URI.createPlatformResourceURI(library2SubunitName));
535
		} catch (CannotSeparateException e) {
536
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
537
		}
538
			
539
		Book book = (Book) find(subunit1, "Level2 Book"); //$NON-NLS-1$
540
		String bookFrag = logres.getURIFragment(book);
541
		
542
		Writer writer = EXTLibraryFactory.eINSTANCE.createWriter();
543
		subunit3.getWriters().add(writer);
544
		writer.setName("Level2 Writer"); //$NON-NLS-1$
545
		writer.getBooks().add(book);  // cross-resource reference
546
		String writerFrag = logres2.getURIFragment(writer);
547
		
548
		saveLogicalResource();
549
		saveLogicalResource(logres2);
550
		
551
		// discard and re-load the resources
552
		createLogicalResource(RESOURCE_NAME);
553
		logres2 = createNewLogicalResource(
554
			URI.createPlatformResourceURI(RESOURCE_NAME2));
555
		
556
		loadLogicalResource();
557
		loadLogicalResource(logres2);
558
		
559
		book = lookupBook(bookFrag);
560
		assertNotNull(book);
561
		
562
		writer = lookupWriter(logres2, writerFrag);
563
		assertNotNull(writer);
564
		
565
		// first, test the proxies without resolving them
566
		EObject proxy = (EObject) ((InternalEList) writer.getBooks()).basicGet(0);
567
		assertTrue(proxy.eIsProxy());
568
		assertEquals(logres.getURI(), EcoreUtil.getURI(proxy).trimFragment());
569
		
570
		proxy = (EObject) book.eGet(EXTLibraryPackage.eINSTANCE.getBook_Author(), false);
571
		// cannot assertTrue(proxy.eIsProxy()) because MSL's indexer resolves it
572
		assertEquals(logres2.getURI(), EcoreUtil.getURI(proxy).trimFragment());
573
		
574
		// these method invocations will cause proxy resolution
575
		assertTrue(writer.getBooks().contains(book));
576
		assertSame(writer, book.getAuthor());
577
	}
578
}
(-)src/org/eclipse/gmf/tests/runtime/emf/core/internal/resources/IncrementalLoadingTest.java (-833 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
13
package org.eclipse.gmf.tests.runtime.emf.core.internal.resources;
14
15
import java.io.IOException;
16
import java.util.List;
17
import java.util.Map;
18
19
import junit.framework.Test;
20
import junit.framework.TestSuite;
21
22
import org.eclipse.core.resources.IFile;
23
import org.eclipse.core.runtime.Path;
24
import org.eclipse.emf.common.notify.Notification;
25
import org.eclipse.emf.common.notify.impl.AdapterImpl;
26
import org.eclipse.emf.common.util.URI;
27
import org.eclipse.emf.ecore.EObject;
28
import org.eclipse.emf.ecore.util.EcoreUtil;
29
import org.eclipse.emf.ecore.util.InternalEList;
30
31
import org.eclipse.emf.examples.extlibrary.Book;
32
import org.eclipse.emf.examples.extlibrary.EXTLibraryFactory;
33
import org.eclipse.emf.examples.extlibrary.EXTLibraryPackage;
34
import org.eclipse.emf.examples.extlibrary.Library;
35
import org.eclipse.emf.examples.extlibrary.Writer;
36
import org.eclipse.gmf.runtime.emf.core.EventTypes;
37
import org.eclipse.gmf.runtime.emf.core.edit.DemuxedMListener;
38
import org.eclipse.gmf.runtime.emf.core.edit.MFilter;
39
import org.eclipse.gmf.runtime.emf.core.internal.exceptions.MSLActionProtocolException;
40
import org.eclipse.gmf.runtime.emf.core.internal.resources.LogicalResourceUtil;
41
import org.eclipse.gmf.runtime.emf.core.resources.CannotSeparateException;
42
import org.eclipse.gmf.runtime.emf.core.resources.ILogicalResource;
43
44
45
/**
46
 * Tests the incremental loading support in the logical resource implementation
47
 * (both automatic and not).
48
 *
49
 * @author Christian W. Damus (cdamus)
50
 */
51
public class IncrementalLoadingTest
52
	extends BaseLogicalResourceTest {
53
	
54
	public IncrementalLoadingTest(String name) {
55
		super(name);
56
	}
57
	
58
	public static Test suite() {
59
		return new TestSuite(IncrementalLoadingTest.class, "Incremental Loading Tests"); //$NON-NLS-1$
60
	}
61
	
62
	/**
63
	 * Tests incremental loading of a logical resource, where there are
64
	 * references between the sub-units.
65
	 */
66
	public void test_incrementalLoading() {
67
		try {
68
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
69
			logres.separate(subunit3, URI.createPlatformResourceURI(SUBUNIT_NAME2));
70
		} catch (CannotSeparateException e) {
71
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
72
		}
73
		
74
		String subunit1Frag = logres.getURIFragment(subunit1);
75
		String subunit3Frag = logres.getURIFragment(subunit3);
76
		
77
		Book book = EXTLibraryFactory.eINSTANCE.createBook();
78
		subunit1.getBooks().add(book);
79
		book.setTitle("Book"); //$NON-NLS-1$
80
		String bookFrag = logres.getURIFragment(book);
81
		
82
		Writer writer = EXTLibraryFactory.eINSTANCE.createWriter();
83
		subunit3.getWriters().add(writer);
84
		writer.setName("Sherlock Holmes"); //$NON-NLS-1$
85
		writer.getBooks().add(book);  // cross-unit reference
86
		String writerFrag = logres.getURIFragment(writer);
87
		
88
		saveLogicalResource();
89
		
90
		// discard and re-load the resource
91
		createLogicalResource(RESOURCE_NAME);
92
		
93
		loadLogicalResource(false); // don't load sub-units, yet
94
		
95
		// check that the subunits are unloaded
96
		subunit1 = lookupLibrary(subunit1Frag);
97
		assertNotNull(subunit1);
98
		assertFalse(subunit1.eIsProxy());
99
		assertFalse(logres.isLoaded(subunit1));
100
		
101
		subunit3 = lookupLibrary(subunit3Frag);
102
		assertNotNull(subunit3);
103
		assertFalse(subunit3.eIsProxy());
104
		assertFalse(logres.isLoaded(subunit3));
105
		
106
		// check that the book and writer don't exist
107
		book = lookupBook(bookFrag);
108
		assertNull(book);
109
		
110
		writer = lookupWriter(writerFrag);
111
		assertNull(writer);
112
		
113
		// check that we can load subunit1 and its contents (incl. the book)
114
		try {
115
			logres.load(subunit1);
116
		} catch (IOException e) {
117
			fail("Should not fail to load sub-unit: " + e.getLocalizedMessage()); //$NON-NLS-1$
118
		}
119
		assertTrue(logres.isLoaded(subunit1));
120
		book = lookupBook(bookFrag);
121
		assertNotNull(book);
122
		
123
		// the author reference (intra-logical-resource) must not have been
124
		//   discarded on loading, and must be unresolved
125
		assertNotNull(book.getAuthor());
126
		assertTrue(book.getAuthor().eIsProxy());
127
		
128
		// check that we can load subunit3 and its contents (incl. the writer)
129
		try {
130
			logres.load(subunit3);
131
		} catch (IOException e) {
132
			fail("Should not fail to load sub-unit: " + e.getLocalizedMessage()); //$NON-NLS-1$
133
		}
134
		assertTrue(logres.isLoaded(subunit3));
135
		writer = lookupWriter(writerFrag);
136
		assertNotNull(writer);
137
		
138
		// now the references resolve
139
		assertTrue(writer.getBooks().contains(book));
140
		assertSame(writer, book.getAuthor());
141
	}
142
	
143
	/**
144
	 * Tests that we can incrementally load logical resources where other
145
	 * logical resources have references to the as-yet-unloaded units.
146
	 */
147
	public void test_incrementalLoadingWithCrossModelRefs() {
148
		try {
149
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
150
		} catch (CannotSeparateException e) {
151
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
152
		}
153
		
154
		String library2Name = "/" + PROJECT_NAME + "/logres2.extlibrary"; //$NON-NLS-1$//$NON-NLS-2$
155
		ILogicalResource logres2 = createNewLogicalResource(
156
			URI.createPlatformResourceURI(library2Name));
157
		Library library2 = EXTLibraryFactory.eINSTANCE.createLibrary();
158
		logres2.getContents().add(library2);
159
		library2.setName("Library 2"); //$NON-NLS-1$
160
		
161
		subunit3 = EXTLibraryFactory.eINSTANCE.createLibrary();
162
		library2.getBranches().add(subunit3);
163
		subunit3.setName("Library 2 Subunit"); //$NON-NLS-1$
164
		
165
		String library2SubunitName = "/" + PROJECT_NAME + "/logres2.1.extlibrary"; //$NON-NLS-1$//$NON-NLS-2$
166
		try {
167
			logres2.separate(subunit3, URI.createPlatformResourceURI(library2SubunitName));
168
		} catch (CannotSeparateException e) {
169
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
170
		}
171
			
172
		Book book = EXTLibraryFactory.eINSTANCE.createBook();
173
		subunit1.getBooks().add(book);
174
		book.setTitle("Book"); //$NON-NLS-1$
175
		String bookFrag = logres.getURIFragment(book);
176
		
177
		Writer writer = EXTLibraryFactory.eINSTANCE.createWriter();
178
		subunit3.getWriters().add(writer);
179
		writer.setName("Sherlock Holmes"); //$NON-NLS-1$
180
		writer.getBooks().add(book);  // cross-unit reference
181
		String writerFrag = logres.getURIFragment(writer);
182
		
183
		saveLogicalResource();
184
		saveLogicalResource(logres2);
185
		
186
		String subunit1Frag = logres.getURIFragment(subunit1);
187
		String subunit3Frag = logres.getURIFragment(subunit3);
188
		
189
		// discard and re-load the resources
190
		createLogicalResource(RESOURCE_NAME);
191
		logres2 = createNewLogicalResource(
192
			URI.createPlatformResourceURI(library2Name));
193
		
194
		loadLogicalResource(false);
195
		loadLogicalResource(logres2, false, false);
196
				
197
		// check that the subunits are unloaded
198
		subunit1 = lookupLibrary(subunit1Frag);
199
		assertNotNull(subunit1);
200
		assertFalse(subunit1.eIsProxy());
201
		assertFalse(logres.isLoaded(subunit1));
202
		
203
		subunit3 = lookupLibrary(logres2, subunit3Frag);
204
		assertNotNull(subunit3);
205
		assertFalse(subunit3.eIsProxy());
206
		assertFalse(logres2.isLoaded(subunit3));
207
		
208
		// check that the book and writer don't exist
209
		book = lookupBook(bookFrag);
210
		assertNull(book);
211
		
212
		writer = lookupWriter(logres2, writerFrag);
213
		assertNull(writer);
214
		
215
		// check that we can load subunit1 and its contents (incl. the book)
216
		try {
217
			logres.load(subunit1);
218
		} catch (IOException e) {
219
			fail("Should not fail to load sub-unit: " + e.getLocalizedMessage()); //$NON-NLS-1$
220
		}
221
		assertTrue(logres.isLoaded(subunit1));
222
		book = lookupBook(bookFrag);
223
		assertNotNull(book);
224
		
225
		// the author reference (intra-logical-resource) must not have been
226
		//   discarded on loading, and must be unresolved
227
		assertNotNull(book.getAuthor());
228
		assertTrue(book.getAuthor().eIsProxy());
229
		
230
		// check that we can load subunit3 and its contents (incl. the writer)
231
		try {
232
			logres2.load(subunit3);
233
		} catch (IOException e) {
234
			fail("Should not fail to load sub-unit: " + e.getLocalizedMessage()); //$NON-NLS-1$
235
		}
236
		assertTrue(logres2.isLoaded(subunit3));
237
		writer = lookupWriter(logres2, writerFrag);
238
		assertNotNull(writer);
239
		
240
		// now the references resolve
241
		assertTrue(writer.getBooks().contains(book));
242
		assertSame(writer, book.getAuthor());
243
	}
244
	
245
	/**
246
	 * Tests the notification of incremental load events, EMF style.
247
	 */
248
	public void test_incrementalLoading_basicEventing() {
249
		class TestAdapter extends AdapterImpl {
250
			List notifications = new java.util.ArrayList();
251
			
252
			public void notifyChanged(Notification msg) {
253
				notifications.add(msg);
254
			}
255
		}
256
		
257
		TestAdapter adapter = new TestAdapter();
258
		
259
		try {
260
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
261
			logres.separate(subunit3, URI.createPlatformResourceURI(SUBUNIT_NAME2));
262
		} catch (CannotSeparateException e) {
263
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
264
		}
265
		
266
		String subunit1Frag = logres.getURIFragment(subunit1);
267
		String subunit3Frag = logres.getURIFragment(subunit3);
268
		
269
		saveLogicalResource();
270
		
271
		// discard and re-load the resource
272
		createLogicalResource(RESOURCE_NAME);
273
		
274
		loadLogicalResource(false); // don't load sub-units, yet
275
		
276
		root = (Library) logres.getContents().get(0);
277
		
278
		subunit1 = lookupLibrary(subunit1Frag);
279
		assertNotNull(subunit1);
280
		subunit3 = lookupLibrary(subunit3Frag);
281
		assertNotNull(subunit3);
282
		
283
		// listen for notifications of loading on the parent element
284
		Library parent = subunit1.getParentBranch();
285
		assertNotNull(parent);
286
		parent.eAdapters().add(adapter);
287
288
		try {
289
			logres.load(subunit1);
290
		} catch (IOException e) {
291
			fail("Should not fail to load unit: " + e.getLocalizedMessage()); //$NON-NLS-1$
292
		}
293
		
294
		assertEquals(1, adapter.notifications.size());
295
		Notification event = (Notification) adapter.notifications.get(0);
296
		adapter.notifications.clear();
297
		
298
		assertSame(parent, event.getNotifier());
299
		assertEquals(EventTypes.LOAD, event.getEventType());
300
		assertSame(EXTLibraryPackage.eINSTANCE.getLibrary_Branches(), event.getFeature());
301
		assertSame(subunit1, parent.getBranches().get(event.getPosition()));
302
		
303
		// listen for notifications of loading on the parent element
304
		parent = subunit3.getParentBranch();
305
		assertNotNull(parent);
306
		parent.eAdapters().add(adapter);
307
308
		try {
309
			logres.load(subunit3);
310
		} catch (IOException e) {
311
			fail("Should not fail to load unit: " + e.getLocalizedMessage()); //$NON-NLS-1$
312
		}
313
		
314
		assertEquals(1, adapter.notifications.size());
315
		event = (Notification) adapter.notifications.get(0);
316
		adapter.notifications.clear();
317
		
318
		assertSame(parent, event.getNotifier());
319
		assertEquals(EventTypes.LOAD, event.getEventType());
320
		assertSame(EXTLibraryPackage.eINSTANCE.getLibrary_Branches(), event.getFeature());
321
		assertSame(subunit3, parent.getBranches().get(event.getPosition()));
322
	}
323
	
324
	/**
325
	 * Tests the notification of incremental load events, MSL style.
326
	 */
327
	public void test_incrementalLoading_mslEventing() {
328
		class TestListener extends DemuxedMListener {
329
			Notification event;
330
			ILogicalResource res;
331
			EObject element;
332
			
333
			TestListener() {
334
				super(domain);
335
			}
336
			
337
			public MFilter getFilter() {
338
				return MFilter.ELEMENT_LOADED_FILTER;
339
			}
340
			
341
			public void handleElementLoadedEvent(
342
					Notification notification, ILogicalResource resource,
343
					EObject eObject) {
344
				event = notification;
345
				res = resource;
346
				element = eObject;
347
			}
348
		}
349
		
350
		TestListener listener = new TestListener();
351
		listener.startListening();
352
		
353
		try {
354
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
355
			logres.separate(subunit3, URI.createPlatformResourceURI(SUBUNIT_NAME2));
356
		} catch (CannotSeparateException e) {
357
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
358
		}
359
		
360
		String subunit1Frag = logres.getURIFragment(subunit1);
361
		String subunit3Frag = logres.getURIFragment(subunit3);
362
		
363
		saveLogicalResource();
364
		
365
		// discard and re-load the resource
366
		createLogicalResource(RESOURCE_NAME);
367
		
368
		loadLogicalResource(false); // don't load sub-units, yet
369
		
370
		root = (Library) logres.getContents().get(0);
371
		
372
		subunit1 = lookupLibrary(subunit1Frag);
373
		assertNotNull(subunit1);
374
		subunit3 = lookupLibrary(subunit3Frag);
375
		assertNotNull(subunit3);
376
377
		try {
378
			logres.load(subunit1);
379
		} catch (IOException e) {
380
			fail("Should not fail to load unit: " + e.getLocalizedMessage()); //$NON-NLS-1$
381
		}
382
		
383
		// must complete the write action in order for events to fire
384
		stopWriting();
385
		
386
		assertSame(subunit1, listener.element);
387
		assertEquals(EventTypes.LOAD, listener.event.getEventType());
388
		assertSame(logres, listener.res);
389
		
390
		startWriting();
391
		
392
		try {
393
			logres.load(subunit3);
394
		} catch (IOException e) {
395
			fail("Should not fail to load unit: " + e.getLocalizedMessage()); //$NON-NLS-1$
396
		}
397
		
398
		// must complete the write action in order for events to fire
399
		stopWriting();
400
		
401
		assertSame(subunit3, listener.element);
402
		assertEquals(EventTypes.LOAD, listener.event.getEventType());
403
		assertSame(logres, listener.res);
404
	}
405
	
406
	/**
407
	 * Tests that we do not need a write operation to incrementally load a
408
	 * model that we are reading; a read operation is OK.
409
	 */
410
	public void test_incrementalLoading_readAction() {
411
		try {
412
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
413
			logres.separate(subunit3, URI.createPlatformResourceURI(SUBUNIT_NAME2));
414
		} catch (CannotSeparateException e) {
415
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
416
		}
417
		
418
		String subunit1Frag = logres.getURIFragment(subunit1);
419
		String subunit3Frag = logres.getURIFragment(subunit3);
420
		
421
		Book book = EXTLibraryFactory.eINSTANCE.createBook();
422
		subunit1.getBooks().add(book);
423
		book.setTitle("Book"); //$NON-NLS-1$
424
		String bookFrag = logres.getURIFragment(book);
425
		
426
		Writer writer = EXTLibraryFactory.eINSTANCE.createWriter();
427
		subunit3.getWriters().add(writer);
428
		writer.setName("Sherlock Holmes"); //$NON-NLS-1$
429
		writer.getBooks().add(book);  // cross-unit reference
430
		String writerFrag = logres.getURIFragment(writer);
431
		
432
		saveLogicalResource();
433
		
434
		// discard and re-load the resource
435
		createLogicalResource(RESOURCE_NAME);
436
		
437
		loadLogicalResource(false);
438
		
439
		// go into read-only mode
440
		stopWriting();
441
		startReading();
442
		
443
		// get the sub-units again
444
		subunit1 = lookupLibrary(subunit1Frag);
445
		assertNotNull(subunit1);
446
		subunit3 = lookupLibrary(subunit3Frag);
447
		assertNotNull(subunit3);
448
		
449
		// check that the book and writer don't exist
450
		book = lookupBook(bookFrag);
451
		assertNull(book);
452
		
453
		writer = lookupWriter(writerFrag);
454
		assertNull(writer);
455
		
456
		// check that we can load subunit1 and its contents (incl. the book)
457
		try {
458
			logres.load(subunit1);
459
		} catch (IOException e) {
460
			fail("Should not fail to load sub-unit: " + e.getLocalizedMessage()); //$NON-NLS-1$
461
		} catch (MSLActionProtocolException e) {
462
			fail("Should have been able to load in a read action: " + e); //$NON-NLS-1$
463
		}
464
		assertTrue(logres.isLoaded(subunit1));
465
		book = lookupBook(bookFrag);
466
		assertNotNull(book);
467
		
468
		// check that we can load subunit3 and its contents (incl. the writer)
469
		try {
470
			logres.load(subunit3);
471
		} catch (IOException e) {
472
			fail("Should not fail to load sub-unit: " + e.getLocalizedMessage()); //$NON-NLS-1$
473
		} catch (MSLActionProtocolException e) {
474
			fail("Should have been able to load in a read action: " + e); //$NON-NLS-1$
475
		}
476
		assertTrue(logres.isLoaded(subunit3));
477
		writer = lookupWriter(writerFrag);
478
		assertNotNull(writer);
479
		
480
		// now the references resolve
481
		assertTrue(writer.getBooks().contains(book));
482
		assertSame(writer, book.getAuthor());
483
	}
484
	
485
	/**
486
	 * Tests the utility method that loads all unloaded units of a resource.
487
	 */
488
	public void test_loadAllUnloadedUnits() {
489
		String rootFrag = logres.getURIFragment(root);
490
		String subunit1Frag = logres.getURIFragment(subunit1);
491
		String subunit2Frag = logres.getURIFragment(subunit2);
492
		
493
		try {
494
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
495
			logres.separate(subunit2, URI.createPlatformResourceURI(SUBUNIT_NAME2));
496
		} catch (CannotSeparateException e) {
497
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
498
		}
499
		
500
		assertTrue(logres.isModified());
501
		
502
		saveLogicalResource();
503
		
504
		assertFalse(logres.isModified());
505
		
506
		// discard and re-load the resource
507
		createLogicalResource(RESOURCE_NAME);
508
		
509
		loadLogicalResource(false);  // don't load any sub-units
510
		
511
		assertFalse(logres.isModified());
512
		
513
		// only the root is loaded
514
		Map resources = logres.getMappedResources();
515
		assertEquals(2, resources.size());
516
		subunit1 = lookupLibrary(subunit1Frag);
517
		assertNotNull(subunit1);
518
		assertFalse(logres.isLoaded(subunit1));
519
		subunit2 = lookupLibrary(subunit2Frag);
520
		assertNull(subunit2);
521
		
522
		try {
523
			LogicalResourceUtil.loadAllUnloadedUnits(logres);
524
		} catch (IOException e) {
525
			fail("Should not fail to load all unloaded units: " + e); //$NON-NLS-1$
526
		}
527
		
528
		// all units are now loaded
529
		assertEquals(3, resources.size());
530
		subunit1 = lookupLibrary(subunit1Frag);
531
		assertNotNull(subunit1);
532
		assertTrue(logres.isLoaded(subunit1));
533
		subunit2 = lookupLibrary(subunit2Frag);
534
		assertNotNull(subunit2);
535
		assertTrue(logres.isLoaded(subunit2));
536
537
		// verify the model structure just to be sure
538
		root = lookupLibrary(rootFrag);
539
		assertNotNull(root);
540
		assertTrue(EcoreUtil.isAncestor(root, subunit2));
541
		assertTrue(EcoreUtil.isAncestor(subunit1, subunit2));
542
	}
543
	
544
	/**
545
	 * Tests automatic loading by walking the containment tree.
546
	 */
547
	public void test_autoLoading() {
548
		String rootFrag = logres.getURIFragment(root);
549
		String subunit1ParentFrag = logres.getURIFragment(subunit1.eContainer());
550
		String subunit2ParentFrag = logres.getURIFragment(subunit2.eContainer());
551
		
552
		try {
553
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
554
			logres.separate(subunit2, URI.createPlatformResourceURI(SUBUNIT_NAME2));
555
		} catch (CannotSeparateException e) {
556
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
557
		}
558
		
559
		assertTrue(logres.isModified());
560
		
561
		saveLogicalResource();
562
		
563
		assertFalse(logres.isModified());
564
		
565
		IFile subunitFile = project.getParent().getFile(new Path(SUBUNIT_NAME1));
566
		assertNotNull(subunitFile);
567
		assertTrue(subunitFile.exists());
568
		
569
		subunitFile = project.getParent().getFile(new Path(SUBUNIT_NAME2));
570
		assertNotNull(subunitFile);
571
		assertTrue(subunitFile.exists());
572
		
573
		// discard and re-load the resource
574
		createLogicalResource(RESOURCE_NAME);
575
		
576
		// do not load all sub-units, but load them automatically as needed
577
		loadLogicalResource(false, true);
578
		
579
		assertFalse(logres.isModified());
580
		
581
		root = lookupLibrary(rootFrag);
582
		assertNotNull(root);
583
		
584
		Library subunit1Parent = lookupLibrary(subunit1ParentFrag);
585
		assertNotNull(subunit1Parent); // this one should exist
586
		Library subunit2Parent = lookupLibrary(subunit2ParentFrag);
587
		assertNull(subunit2Parent);  // shouldn't exist, yet
588
		
589
		// use internal list capabilities for non-resolving/non-loading access
590
		InternalEList branches = (InternalEList) subunit1Parent.getBranches();
591
		assertEquals(1, branches.size());
592
		subunit1 = (Library) branches.basicGet(0);
593
		assertNotNull(subunit1);
594
		assertFalse(logres.isLoaded(subunit1));
595
		
596
		// loading access (branches.get(0) would work just as well)
597
		subunit1 = (Library) branches.iterator().next();
598
		assertNotNull(subunit1);
599
		assertTrue(logres.isLoaded(subunit1));
600
		
601
		subunit2Parent = lookupLibrary(subunit2ParentFrag);
602
		assertNotNull(subunit2Parent);  // now it should exist
603
		
604
		// use internal list capabilities for non-resolving/non-loading access
605
		branches = (InternalEList) subunit2Parent.getBranches();
606
		assertEquals(1, branches.size());
607
		subunit2 = (Library) branches.basicGet(0);
608
		assertNotNull(subunit2);
609
		assertFalse(logres.isLoaded(subunit2));
610
		
611
		// loading access (branches.iterator().next() would work just as well)
612
		subunit2 = (Library) branches.get(0);
613
		assertNotNull(subunit2);
614
		assertTrue(logres.isLoaded(subunit2));
615
	}
616
	
617
	/**
618
	 * Tests that loading a resource to load one of its roots also loads
619
	 * other unloaded elements from its other roots.
620
	 */
621
	public void test_loadingMultiRootedUnit() {
622
		String rootFrag = logres.getURIFragment(root);
623
		String subunit1Frag = logres.getURIFragment(subunit1);
624
		String subunit3Frag = logres.getURIFragment(subunit3);
625
		
626
		try {
627
			// separate these two elements into the same resource
628
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
629
			logres.separate(subunit3, URI.createPlatformResourceURI(SUBUNIT_NAME1));
630
		} catch (CannotSeparateException e) {
631
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
632
		}
633
		
634
		saveLogicalResource();
635
		
636
		// discard and re-load the resource
637
		createLogicalResource(RESOURCE_NAME);
638
		
639
		// do not load all sub-units
640
		loadLogicalResource(false);
641
		
642
		assertFalse(logres.isModified());
643
		
644
		root = lookupLibrary(rootFrag);
645
		assertNotNull(root);
646
		subunit1 = lookupLibrary(subunit1Frag);
647
		assertNotNull(subunit1);
648
		subunit3 = lookupLibrary(subunit3Frag);
649
		assertNotNull(subunit3);
650
651
		// not loaded, yet
652
		assertFalse(logres.isLoaded(subunit1));
653
		assertFalse(logres.isLoaded(subunit3));
654
		
655
		// load one of them
656
		try {
657
			logres.load(subunit3);
658
		} catch (IOException e) {
659
			fail("Should not fail to load unit: " + e.getLocalizedMessage()); //$NON-NLS-1$
660
		}
661
		assertTrue(logres.isLoaded(subunit3));
662
		
663
		// check that subunit1 was also loaded
664
		assertTrue(logres.isLoaded(subunit1));
665
		
666
		// check some contents
667
		assertTrue(!subunit1.eContents().isEmpty());
668
	}
669
	
670
	/**
671
	 * Tests that loading a resource to auto-load one of its roots also loads
672
	 * other unloaded elements from its other roots.
673
	 */
674
	public void test_autoLoadingMultiRootedUnit() {
675
		String rootFrag = logres.getURIFragment(root);
676
		String subunit1Frag = logres.getURIFragment(subunit1);
677
		String subunit3Frag = logres.getURIFragment(subunit3);
678
		
679
		try {
680
			// separate these two elements into the same resource
681
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
682
			logres.separate(subunit3, URI.createPlatformResourceURI(SUBUNIT_NAME1));
683
		} catch (CannotSeparateException e) {
684
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
685
		}
686
		
687
		saveLogicalResource();
688
		
689
		// discard and re-load the resource
690
		createLogicalResource(RESOURCE_NAME);
691
		
692
		// do not load all sub-units, but let them load automatically
693
		loadLogicalResource(false, true);
694
		
695
		assertFalse(logres.isModified());
696
		
697
		root = lookupLibrary(rootFrag);
698
		assertNotNull(root);
699
		subunit1 = lookupLibrary(subunit1Frag);
700
		assertNotNull(subunit1);
701
		subunit3 = lookupLibrary(subunit3Frag);
702
		assertNotNull(subunit3);
703
704
		// not loaded, yet
705
		assertFalse(logres.isLoaded(subunit1));
706
		assertFalse(logres.isLoaded(subunit3));
707
		
708
		// load one of them automatically
709
		assertSame(subunit3, ((Library) root.getBranches().get(1)).getBranches().get(0));
710
		assertTrue(logres.isLoaded(subunit3));
711
		
712
		// check that subunit1 was also loaded
713
		assertTrue(logres.isLoaded(subunit1));
714
		
715
		// check some contents
716
		assertTrue(!subunit1.eContents().isEmpty());
717
	}
718
	
719
	/**
720
	 * Tests that separating an element into a sub-unit that already exists but
721
	 * is not yet loaded, will first load and resolve its roots.
722
	 */
723
	public void test_separatingIntoUnloadedUnit() {
724
		String rootFrag = logres.getURIFragment(root);
725
		String subunit1Frag = logres.getURIFragment(subunit1);
726
		String subunit3Frag = logres.getURIFragment(subunit3);
727
		
728
		try {
729
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
730
		} catch (CannotSeparateException e) {
731
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
732
		}
733
		
734
		saveLogicalResource();
735
		
736
		// discard and re-load the resource
737
		createLogicalResource(RESOURCE_NAME);
738
		
739
		// do not load all sub-units
740
		loadLogicalResource(false);
741
		
742
		assertFalse(logres.isModified());
743
		
744
		root = lookupLibrary(rootFrag);
745
		assertNotNull(root);
746
		subunit1 = lookupLibrary(subunit1Frag);
747
		assertNotNull(subunit1);
748
		subunit3 = lookupLibrary(subunit3Frag);
749
		assertNotNull(subunit3);
750
751
		assertFalse(logres.isLoaded(subunit1));
752
		assertTrue(logres.isLoaded(subunit3));
753
		
754
		try {
755
			// separate into the same resource (not previously loaded)
756
			logres.separate(subunit3, URI.createPlatformResourceURI(SUBUNIT_NAME1));
757
		} catch (CannotSeparateException e) {
758
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
759
		}
760
		
761
		// now subunit1 is loaded
762
		assertTrue(logres.isLoaded(subunit1));
763
		assertTrue(logres.isLoaded(subunit3)); // still loaded
764
		
765
		// check some contents
766
		assertTrue(!subunit1.eContents().isEmpty());
767
	}
768
	
769
	/**
770
	 * Tests that incremental loading does not apply to the logical roots;
771
	 * they are always loaded.
772
	 */
773
	public void test_logicalRoots() {
774
		// create another couple of roots
775
		logres.getContents().add(subunit1);
776
		logres.getContents().add(subunit3);
777
		
778
		try {
779
			logres.separate(root, URI.createPlatformResourceURI(SUBUNIT_NAME2));
780
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
781
			logres.separate(subunit3, URI.createPlatformResourceURI(SUBUNIT_NAME3));
782
		} catch (CannotSeparateException e) {
783
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
784
		}
785
		
786
		String rootFrag = logres.getURIFragment(root);
787
		String subunit1Frag = logres.getURIFragment(subunit1);
788
		String subunit3Frag = logres.getURIFragment(subunit3);
789
		
790
		Book book = EXTLibraryFactory.eINSTANCE.createBook();
791
		subunit1.getBooks().add(book);
792
		book.setTitle("Book"); //$NON-NLS-1$
793
		String bookFrag = logres.getURIFragment(book);
794
		
795
		Writer writer = EXTLibraryFactory.eINSTANCE.createWriter();
796
		subunit3.getWriters().add(writer);
797
		writer.setName("Sherlock Holmes"); //$NON-NLS-1$
798
		writer.getBooks().add(book);  // cross-unit reference
799
		String writerFrag = logres.getURIFragment(writer);
800
		
801
		saveLogicalResource();
802
		
803
		// discard and re-load the resource
804
		createLogicalResource(RESOURCE_NAME);
805
		
806
		// don't load sub-units, yet (except, we have to load the roots)
807
		loadLogicalResource(false);
808
		
809
		// check that the subunits are loaded
810
		root = lookupLibrary(rootFrag);
811
		assertNotNull(root);
812
		assertFalse(root.eIsProxy());
813
		assertTrue(logres.isLoaded(root));
814
		
815
		subunit1 = lookupLibrary(subunit1Frag);
816
		assertNotNull(subunit1);
817
		assertFalse(subunit1.eIsProxy());
818
		assertTrue(logres.isLoaded(subunit1));
819
		
820
		subunit3 = lookupLibrary(subunit3Frag);
821
		assertNotNull(subunit3);
822
		assertFalse(subunit3.eIsProxy());
823
		assertTrue(logres.isLoaded(subunit3));
824
		
825
		// check books and cross-refs
826
		
827
		book = lookupBook(bookFrag);
828
		assertNotNull(book);
829
		writer = lookupWriter(writerFrag);
830
		assertNotNull(book);
831
		assertSame(writer, book.getAuthor());
832
	}
833
}
(-)src/org/eclipse/gmf/tests/runtime/emf/core/internal/resources/RefactoringTest.java (-673 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
13
package org.eclipse.gmf.tests.runtime.emf.core.internal.resources;
14
15
import junit.framework.Test;
16
import junit.framework.TestSuite;
17
18
import org.eclipse.emf.common.util.EList;
19
import org.eclipse.emf.common.util.URI;
20
import org.eclipse.emf.ecore.EAttribute;
21
import org.eclipse.emf.ecore.EClass;
22
import org.eclipse.emf.ecore.EFactory;
23
import org.eclipse.emf.ecore.EObject;
24
import org.eclipse.emf.ecore.EPackage;
25
import org.eclipse.emf.ecore.EReference;
26
import org.eclipse.emf.ecore.EcoreFactory;
27
import org.eclipse.emf.ecore.resource.impl.ResourceImpl;
28
29
import org.eclipse.emf.examples.extlibrary.EXTLibraryFactory;
30
import org.eclipse.emf.examples.extlibrary.Library;
31
import org.eclipse.gmf.runtime.emf.core.resources.CannotSeparateException;
32
import org.eclipse.gmf.runtime.emf.core.resources.ILogicalResource;
33
34
35
/**
36
 * Tests a variety of refactoring scenarios in logical resources, involving
37
 * the relocation in the content tree of separate elements, to check that the
38
 * resource map is correctly updated on saving.
39
 *
40
 * @author Christian W. Damus (cdamus)
41
 */
42
public class RefactoringTest
43
	extends BaseLogicalResourceTest {
44
	
45
	public RefactoringTest(String name) {
46
		super(name);
47
	}
48
	
49
	public static Test suite() {
50
		return new TestSuite(RefactoringTest.class, "Refactoring Tests"); //$NON-NLS-1$
51
	}
52
53
	/**
54
	 * Tests correct save and re-load when moving a separate element to a
55
	 * different position in its containment reference.
56
	 */
57
	public void test_moveWithinContainmentList() {
58
		String subunit1Frag = logres.getURIFragment(subunit1);
59
		
60
		Library parent = subunit1.getParentBranch();
61
		EList branches = parent.getBranches();
62
		
63
		Library newLibrary = EXTLibraryFactory.eINSTANCE.createLibrary();
64
		branches.add(newLibrary);
65
		newLibrary.setName("New Library"); //$NON-NLS-1$
66
		String newFrag = logres.getURIFragment(newLibrary);
67
		
68
		try {
69
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
70
		} catch (CannotSeparateException e) {
71
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
72
		}
73
		
74
		saveLogicalResource();
75
		
76
		// discard the resource and re-load from disk
77
		createLogicalResource(RESOURCE_NAME);
78
		loadLogicalResource();
79
		
80
		subunit1 = lookupLibrary(subunit1Frag);
81
		newLibrary = lookupLibrary(newFrag);
82
		
83
		parent = subunit1.getParentBranch();
84
		assertNotNull(parent);
85
		
86
		branches = parent.getBranches();
87
		
88
		assertEquals(0, branches.indexOf(subunit1));
89
		assertEquals(1, branches.indexOf(newLibrary));
90
		
91
		// reposition the sub-unit
92
		branches.move(1, subunit1);
93
		
94
		saveLogicalResource();
95
		
96
		// discard the resource and re-load from disk
97
		createLogicalResource(RESOURCE_NAME);
98
		loadLogicalResource();
99
		
100
		subunit1 = lookupLibrary(subunit1Frag);
101
		newLibrary = lookupLibrary(newFrag);
102
		
103
		parent = subunit1.getParentBranch();
104
		assertNotNull(parent);
105
		
106
		branches = parent.getBranches();
107
		
108
		// correctly restored the reverse order
109
		assertEquals(1, branches.indexOf(subunit1));
110
		assertEquals(0, branches.indexOf(newLibrary));
111
	}
112
113
	/**
114
	 * Tests correct save and re-load when moving a separate element to a
115
	 * different containment reference in its parent.
116
	 */
117
	public void test_moveWithinParentElement() {
118
		// create a test metamodel that has two features of the same kind
119
		EPackage dynamicPackage;
120
		EClass dynamicClass;
121
		EReference dynamicRef1;
122
		EReference dynamicRef2;
123
		
124
		dynamicPackage = EcoreFactory.eINSTANCE.createEPackage();
125
		dynamicPackage.setName("logresrefactor"); //$NON-NLS-1$
126
		dynamicPackage.setNsPrefix("lrr"); //$NON-NLS-1$
127
		dynamicPackage.setNsURI("http:///com/ibm/xtools/emf/msl/core/tests/logresrefactor.ecore"); //$NON-NLS-1$
128
		// make sure that we can serialize references to the package's contents
129
		new ResourceImpl(URI.createURI(dynamicPackage.getNsURI())).getContents().add(
130
			dynamicPackage);
131
		EPackage.Registry.INSTANCE.put(dynamicPackage.getNsURI(), dynamicPackage);
132
		
133
		EFactory factory = EcoreFactory.eINSTANCE.createEFactory();
134
		factory.setEPackage(dynamicPackage);
135
		dynamicPackage.setEFactoryInstance(factory);
136
137
		dynamicClass = EcoreFactory.eINSTANCE.createEClass();
138
		dynamicPackage.getEClassifiers().add(dynamicClass);
139
		dynamicClass.setName("TestClass"); //$NON-NLS-1$
140
		
141
		dynamicRef1 = EcoreFactory.eINSTANCE.createEReference();
142
		dynamicClass.getEStructuralFeatures().add(dynamicRef1);
143
		dynamicRef1.setName("ref1"); //$NON-NLS-1$
144
		dynamicRef1.setChangeable(true);
145
		dynamicRef1.setContainment(true);
146
		dynamicRef1.setUpperBound(EAttribute.UNBOUNDED_MULTIPLICITY);
147
		dynamicRef1.setEType(dynamicClass);
148
		
149
		dynamicRef2 = EcoreFactory.eINSTANCE.createEReference();
150
		dynamicClass.getEStructuralFeatures().add(dynamicRef2);
151
		dynamicRef2.setName("ref2"); //$NON-NLS-1$
152
		dynamicRef2.setChangeable(true);
153
		dynamicRef2.setContainment(true);
154
		dynamicRef2.setUpperBound(EAttribute.UNBOUNDED_MULTIPLICITY);
155
		dynamicRef2.setEType(dynamicClass);
156
		
157
		try {
158
			EObject dynamicContainer = factory.create(dynamicClass);
159
			EObject dynamicSubunit = factory.create(dynamicClass);
160
161
			logres.getContents().add(dynamicContainer);
162
			((EList) dynamicContainer.eGet(dynamicRef1)).add(dynamicSubunit);
163
			
164
			String containerFrag = logres.getURIFragment(dynamicContainer);
165
			String subunitFrag = logres.getURIFragment(dynamicSubunit);
166
			
167
			try {
168
				logres.separate(dynamicSubunit, URI.createPlatformResourceURI(SUBUNIT_NAME1));
169
			} catch (CannotSeparateException e) {
170
				fail("Should not fail to separate: " + e); //$NON-NLS-1$
171
			}
172
			
173
			saveLogicalResource();
174
			
175
			// discard the resource and re-load from disk
176
			createLogicalResource(RESOURCE_NAME);
177
			loadLogicalResource();
178
			
179
			dynamicContainer = logres.getEObject(containerFrag);
180
			dynamicSubunit = logres.getEObject(subunitFrag);
181
			assertNotNull(dynamicContainer);
182
			assertNotNull(dynamicSubunit);
183
			
184
			assertSame(dynamicContainer, dynamicSubunit.eContainer());
185
			assertSame(dynamicRef1, dynamicSubunit.eContainmentFeature());
186
			
187
			// move the sub-unit to another containment reference of the same parent
188
			((EList) dynamicContainer.eGet(dynamicRef2)).add(dynamicSubunit);
189
			
190
			saveLogicalResource();
191
			
192
			// discard the resource and re-load from disk
193
			createLogicalResource(RESOURCE_NAME);
194
			loadLogicalResource();
195
			
196
			dynamicContainer = logres.getEObject(containerFrag);
197
			dynamicSubunit = logres.getEObject(subunitFrag);
198
			assertNotNull(dynamicContainer);
199
			assertNotNull(dynamicSubunit);
200
			
201
			// correctly restored the containment reference
202
			assertSame(dynamicContainer, dynamicSubunit.eContainer());
203
			assertSame(dynamicRef2, dynamicSubunit.eContainmentFeature());
204
		} finally {			
205
			// must unload before we remove the dynamic package
206
			unloadLogicalResource();
207
			EPackage.Registry.INSTANCE.remove(dynamicPackage.getNsURI());
208
		}
209
	}
210
211
	/**
212
	 * Tests correct save and re-load when moving a separate element to a
213
	 * different parent element in the same (parent) unit.
214
	 */
215
	public void test_moveWithinParentUnit() {
216
		String subunit1Frag = logres.getURIFragment(subunit1);
217
		String subunit3Frag = logres.getURIFragment(subunit3);
218
		
219
		try {
220
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
221
		} catch (CannotSeparateException e) {
222
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
223
		}
224
		
225
		saveLogicalResource();
226
		
227
		// discard the resource and re-load from disk
228
		createLogicalResource(RESOURCE_NAME);
229
		loadLogicalResource();
230
		
231
		subunit1 = lookupLibrary(subunit1Frag);
232
		assertNotNull(subunit1);
233
		subunit3 = lookupLibrary(subunit3Frag);
234
		assertNotNull(subunit3);
235
		
236
		subunit3.getBranches().add(subunit1);
237
		
238
		saveLogicalResource();
239
		
240
		// discard the resource and re-load from disk
241
		createLogicalResource(RESOURCE_NAME);
242
		loadLogicalResource();
243
		
244
		subunit1 = lookupLibrary(subunit1Frag);
245
		assertNotNull(subunit1);
246
		subunit3 = lookupLibrary(subunit3Frag);
247
		assertNotNull(subunit3);
248
		
249
		// correctly restored the parent relationship
250
		assertSame(subunit3, subunit1.getParentBranch());
251
	}
252
253
	/**
254
	 * Tests correct save and re-load when moving a separate element to a
255
	 * different parent element in a different (parent) unit.
256
	 */
257
	public void test_moveToNewParentUnit() {
258
		String subunit1Frag = logres.getURIFragment(subunit1);
259
		String subunit3Frag = logres.getURIFragment(subunit3);
260
		
261
		try {
262
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
263
			logres.separate(subunit3, URI.createPlatformResourceURI(SUBUNIT_NAME3));
264
		} catch (CannotSeparateException e) {
265
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
266
		}
267
		
268
		saveLogicalResource();
269
		
270
		// discard the resource and re-load from disk
271
		createLogicalResource(RESOURCE_NAME);
272
		loadLogicalResource();
273
		
274
		subunit1 = lookupLibrary(subunit1Frag);
275
		assertNotNull(subunit1);
276
		subunit3 = lookupLibrary(subunit3Frag);
277
		assertNotNull(subunit3);
278
		
279
		subunit3.getBranches().add(subunit1);
280
		
281
		saveLogicalResource();
282
		
283
		// discard the resource and re-load from disk
284
		createLogicalResource(RESOURCE_NAME);
285
		loadLogicalResource();
286
		
287
		subunit1 = lookupLibrary(subunit1Frag);
288
		assertNotNull(subunit1);
289
		subunit3 = lookupLibrary(subunit3Frag);
290
		assertNotNull(subunit3);
291
		
292
		// correctly restored the parent relationship
293
		assertSame(subunit3, subunit1.getParentBranch());
294
	}
295
	
296
	/**
297
	 * Tests correct save and re-load when deleting a separate element from
298
	 * the logical model.
299
	 */
300
	public void test_deleteSeparateElement() {
301
		String subunit2Frag = logres.getURIFragment(subunit2);
302
		
303
		try {
304
			logres.separate(subunit2, URI.createPlatformResourceURI(SUBUNIT_NAME2));
305
		} catch (CannotSeparateException e) {
306
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
307
		}
308
		
309
		saveLogicalResource();
310
		
311
		// discard the resource and re-load from disk
312
		createLogicalResource(RESOURCE_NAME);
313
		loadLogicalResource();
314
		
315
		subunit2 = lookupLibrary(subunit2Frag);
316
		assertNotNull(subunit2);
317
		
318
		assertEquals(2, logres.getMappedResources().size());
319
		
320
		// disconnect from the logical contents tree
321
		subunit2.getParentBranch().getBranches().remove(subunit2);
322
		
323
		assertEquals(1, logres.getMappedResources().size());
324
		
325
		saveLogicalResource();
326
		
327
		// discard the resource and re-load from disk
328
		createLogicalResource(RESOURCE_NAME);
329
		loadLogicalResource();
330
331
		// check that it doesn't exist any more, even as an unloaded "proxy"
332
		subunit2 = lookupLibrary(subunit2Frag);
333
		assertNull(subunit2);
334
	}
335
336
	/**
337
	 * Tests correct save and re-load when moving a separate element from one
338
	 * logical resource to another.
339
	 */
340
	public void test_moveToNewLogicalResource() {
341
		String subunit1Frag = logres.getURIFragment(subunit1);
342
		String subunit3Frag = logres.getURIFragment(subunit3);
343
		
344
		ILogicalResource logres2 = createNewLogicalResource(
345
			URI.createPlatformResourceURI(RESOURCE_NAME2));
346
		Library library2 = EXTLibraryFactory.eINSTANCE.createLibrary();
347
		logres2.getContents().add(library2);
348
		library2.setName("Library 2"); //$NON-NLS-1$
349
		
350
		String root2Frag = logres2.getURIFragment(library2);
351
		
352
		try {
353
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
354
			logres.separate(subunit3, URI.createPlatformResourceURI(SUBUNIT_NAME3));
355
		} catch (CannotSeparateException e) {
356
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
357
		}
358
		
359
		saveLogicalResource();
360
		saveLogicalResource(logres2);
361
		
362
		// discard the resources and re-load from disk
363
		createLogicalResource(RESOURCE_NAME);
364
		loadLogicalResource();
365
		logres2 = createNewLogicalResource(
366
			URI.createPlatformResourceURI(RESOURCE_NAME2));
367
		loadLogicalResource(logres2);
368
		
369
		subunit1 = lookupLibrary(subunit1Frag);
370
		assertNotNull(subunit1);
371
		subunit3 = lookupLibrary(subunit3Frag);
372
		assertNotNull(subunit3);
373
		library2 = lookupLibrary(logres2, root2Frag);
374
		assertNotNull(library2);
375
		
376
		assertEquals(3, logres.getMappedResources().size());
377
		assertEquals(1, logres2.getMappedResources().size());
378
		
379
		library2.getBranches().add(subunit1); // inter-resource move
380
		subunit1Frag = logres2.getURIFragment(subunit1);  // in case of re-guid
381
		
382
		assertEquals(2, logres.getMappedResources().size());
383
		assertEquals(1, logres2.getMappedResources().size()); // not a sub-unit here
384
		
385
		saveLogicalResource();
386
		saveLogicalResource(logres2);
387
		
388
		// discard the resources and re-load from disk
389
		createLogicalResource(RESOURCE_NAME);
390
		loadLogicalResource();
391
		logres2 = createNewLogicalResource(
392
			URI.createPlatformResourceURI(RESOURCE_NAME2));
393
		loadLogicalResource(logres2);
394
		
395
		subunit1 = lookupLibrary(subunit1Frag);
396
		assertNull(subunit1);
397
		subunit1 = lookupLibrary(logres2, subunit1Frag);
398
		assertNotNull(subunit1);  // found it in the other resource this time
399
		subunit3 = lookupLibrary(subunit3Frag);
400
		assertNotNull(subunit3);
401
		library2 = lookupLibrary(logres2, root2Frag);
402
		assertNotNull(library2);
403
		
404
		// correctly restored the parent relationship
405
		assertSame(library2, subunit1.getParentBranch());
406
	}
407
408
	/**
409
	 * Tests correct save and re-load when moving a separate root to a
410
	 * different position in its containment reference.
411
	 */
412
	public void test_moveRootWithinContentsList() {
413
		String rootFrag = logres.getURIFragment(root);
414
		
415
		Library newLibrary = EXTLibraryFactory.eINSTANCE.createLibrary();
416
		EList contents = logres.getContents();
417
		contents.add(newLibrary);
418
		newLibrary.setName("New Library"); //$NON-NLS-1$
419
		String newFrag = logres.getURIFragment(newLibrary);
420
		
421
		try {
422
			logres.separate(root, URI.createPlatformResourceURI(SUBUNIT_NAME1));
423
		} catch (CannotSeparateException e) {
424
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
425
		}
426
		
427
		saveLogicalResource();
428
		
429
		// discard the resource and re-load from disk
430
		createLogicalResource(RESOURCE_NAME);
431
		loadLogicalResource();
432
		
433
		root = lookupLibrary(rootFrag);
434
		newLibrary = lookupLibrary(newFrag);
435
		
436
		contents = logres.getContents();
437
		
438
		assertEquals(0, contents.indexOf(root));
439
		assertEquals(1, contents.indexOf(newLibrary));
440
		
441
		// reposition the sub-unit
442
		contents.move(1, root);
443
		
444
		saveLogicalResource();
445
		
446
		// discard the resource and re-load from disk
447
		createLogicalResource(RESOURCE_NAME);
448
		loadLogicalResource();
449
		
450
		root = lookupLibrary(rootFrag);
451
		newLibrary = lookupLibrary(newFrag);
452
		
453
		contents = logres.getContents();
454
		
455
		// correctly restored the reverse order
456
		assertEquals(1, contents.indexOf(root));
457
		assertEquals(0, contents.indexOf(newLibrary));
458
	}
459
460
	/**
461
	 * Tests correct save and re-load when moving a separate root to a
462
	 * different parent element in the same (root) unit.
463
	 */
464
	public void test_moveRootWithinParentUnit() {
465
		String rootFrag = logres.getURIFragment(root);
466
		String subunit3Frag = logres.getURIFragment(subunit3);
467
		
468
		EList contents = logres.getContents();
469
		contents.add(subunit3);  // second root in the root resource
470
		
471
		try {
472
			logres.separate(root, URI.createPlatformResourceURI(SUBUNIT_NAME1));
473
		} catch (CannotSeparateException e) {
474
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
475
		}
476
		
477
		saveLogicalResource();
478
		
479
		// discard the resource and re-load from disk
480
		createLogicalResource(RESOURCE_NAME);
481
		loadLogicalResource();
482
		
483
		root = lookupLibrary(rootFrag);
484
		assertNotNull(root);
485
		subunit3 = lookupLibrary(subunit3Frag);
486
		assertNotNull(subunit3);
487
		
488
		subunit3.getBranches().add(root);
489
		
490
		saveLogicalResource();
491
		
492
		// discard the resource and re-load from disk
493
		createLogicalResource(RESOURCE_NAME);
494
		loadLogicalResource();
495
		
496
		root = lookupLibrary(rootFrag);
497
		assertNotNull(root);
498
		subunit3 = lookupLibrary(subunit3Frag);
499
		assertNotNull(subunit3);
500
		
501
		// correctly restored the parent relationship
502
		assertSame(subunit3, root.getParentBranch());
503
	}
504
505
	/**
506
	 * Tests correct save and re-load when moving a separate root to a
507
	 * different parent element in a different (parent) unit.
508
	 */
509
	public void test_moveRootToNewParentUnit() {
510
		String rootFrag = logres.getURIFragment(root);
511
		String subunit3Frag = logres.getURIFragment(subunit3);
512
		
513
		logres.getContents().add(subunit3);  // make it another root
514
		
515
		try {
516
			logres.separate(root, URI.createPlatformResourceURI(SUBUNIT_NAME1));
517
			logres.separate(subunit3, URI.createPlatformResourceURI(SUBUNIT_NAME3));
518
		} catch (CannotSeparateException e) {
519
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
520
		}
521
		
522
		saveLogicalResource();
523
		
524
		// discard the resource and re-load from disk
525
		createLogicalResource(RESOURCE_NAME);
526
		loadLogicalResource();
527
		
528
		root = lookupLibrary(rootFrag);
529
		assertNotNull(root);
530
		subunit3 = lookupLibrary(subunit3Frag);
531
		assertNotNull(subunit3);
532
		
533
		subunit3.getBranches().add(root);
534
		
535
		saveLogicalResource();
536
		
537
		// discard the resource and re-load from disk
538
		createLogicalResource(RESOURCE_NAME);
539
		loadLogicalResource();
540
		
541
		root = lookupLibrary(rootFrag);
542
		assertNotNull(root);
543
		subunit3 = lookupLibrary(subunit3Frag);
544
		assertNotNull(subunit3);
545
		
546
		// correctly restored the parent relationship
547
		assertSame(subunit3, root.getParentBranch());
548
	}
549
	
550
	/**
551
	 * Tests correct save and re-load when deleting a separate root from
552
	 * the logical model.
553
	 */
554
	public void test_deleteSeparateRootElement() {
555
		String rootFrag = logres.getURIFragment(root);
556
		String subunit2Frag = logres.getURIFragment(subunit2);
557
		
558
		logres.getContents().add(subunit2);
559
		
560
		try {
561
			logres.separate(root, URI.createPlatformResourceURI(SUBUNIT_NAME1));
562
			logres.separate(subunit2, URI.createPlatformResourceURI(SUBUNIT_NAME2));
563
		} catch (CannotSeparateException e) {
564
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
565
		}
566
		
567
		saveLogicalResource();
568
		
569
		// discard the resource and re-load from disk
570
		createLogicalResource(RESOURCE_NAME);
571
		loadLogicalResource();
572
		
573
		root = lookupLibrary(rootFrag);
574
		assertNotNull(root);
575
		subunit2 = lookupLibrary(subunit2Frag);
576
		assertNotNull(subunit2);
577
		
578
		assertEquals(2, logres.getMappedResources().size());
579
		
580
		// disconnect from the logical contents tree
581
		logres.getContents().remove(root);
582
		
583
		assertEquals(1, logres.getMappedResources().size());
584
		
585
		saveLogicalResource();
586
		
587
		// discard the resource and re-load from disk
588
		createLogicalResource(RESOURCE_NAME);
589
		loadLogicalResource();
590
591
		subunit2 = lookupLibrary(subunit2Frag);
592
		assertNotNull(subunit2);
593
		
594
		// check that it doesn't exist any more, even as an unloaded "proxy"
595
		root = lookupLibrary(rootFrag);
596
		assertNull(root);
597
	}
598
599
	/**
600
	 * Tests correct save and re-load when moving a separate root from one
601
	 * logical resource to another.  This is an extra special case, because
602
	 * not only is a logical root moved, but it brings with it content from
603
	 * another sub-unit also.
604
	 */
605
	public void test_moveRootToNewLogicalResource() {
606
		String rootFrag = logres.getURIFragment(root);
607
		String subunit3Frag = logres.getURIFragment(subunit3);
608
		
609
		ILogicalResource logres2 = createNewLogicalResource(
610
			URI.createPlatformResourceURI(RESOURCE_NAME2));
611
		Library library2 = EXTLibraryFactory.eINSTANCE.createLibrary();
612
		logres2.getContents().add(library2);
613
		library2.setName("Library 2"); //$NON-NLS-1$
614
		
615
		String root2Frag = logres2.getURIFragment(library2);
616
		
617
		try {
618
			logres.separate(root, URI.createPlatformResourceURI(SUBUNIT_NAME1));
619
			logres.separate(subunit3, URI.createPlatformResourceURI(SUBUNIT_NAME3));
620
		} catch (CannotSeparateException e) {
621
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
622
		}
623
		
624
		saveLogicalResource();
625
		saveLogicalResource(logres2);
626
		
627
		// discard the resources and re-load from disk
628
		createLogicalResource(RESOURCE_NAME);
629
		loadLogicalResource();
630
		logres2 = createNewLogicalResource(
631
			URI.createPlatformResourceURI(RESOURCE_NAME2));
632
		loadLogicalResource(logres2);
633
		
634
		root = lookupLibrary(rootFrag);
635
		assertNotNull(root);
636
		subunit3 = lookupLibrary(subunit3Frag);
637
		assertNotNull(subunit3);
638
		library2 = lookupLibrary(logres2, root2Frag);
639
		assertNotNull(library2);
640
		
641
		assertEquals(2, logres.getMappedResources().size());
642
		assertEquals(1, logres2.getMappedResources().size());
643
		
644
		library2.getBranches().add(root); // inter-resource move
645
		rootFrag = logres2.getURIFragment(root);  // in case of re-guid
646
		subunit3Frag = logres2.getURIFragment(subunit3);  // in case of re-guid
647
		
648
		assertEquals(1, logres.getMappedResources().size());
649
		assertEquals(1, logres2.getMappedResources().size()); // not a sub-unit here
650
		
651
		saveLogicalResource();
652
		saveLogicalResource(logres2);
653
		
654
		// discard the resources and re-load from disk
655
		createLogicalResource(RESOURCE_NAME);
656
		loadLogicalResource();
657
		logres2 = createNewLogicalResource(
658
			URI.createPlatformResourceURI(RESOURCE_NAME2));
659
		loadLogicalResource(logres2);
660
		
661
		root = lookupLibrary(rootFrag);
662
		assertNull(root);
663
		root = lookupLibrary(logres2, rootFrag);
664
		assertNotNull(root);  // found it in the other resource this time
665
		subunit3 = lookupLibrary(logres2, subunit3Frag);
666
		assertNotNull(subunit3);  // this sub-unit content followed the root!
667
		library2 = lookupLibrary(logres2, root2Frag);
668
		assertNotNull(library2);
669
		
670
		// correctly restored the parent relationship
671
		assertSame(library2, root.getParentBranch());
672
	}
673
}
(-)src/org/eclipse/gmf/tests/runtime/emf/core/internal/resources/LogicalResourceWrapperTest.java (-256 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
13
package org.eclipse.gmf.tests.runtime.emf.core.internal.resources;
14
15
import java.io.IOException;
16
import java.util.Map;
17
18
import junit.framework.Test;
19
import junit.framework.TestSuite;
20
21
import org.eclipse.emf.common.notify.Notification;
22
import org.eclipse.emf.common.notify.impl.AdapterImpl;
23
import org.eclipse.emf.common.util.URI;
24
import org.eclipse.emf.ecore.resource.Resource;
25
26
import org.eclipse.emf.examples.extlibrary.EXTLibraryFactory;
27
import org.eclipse.emf.examples.extlibrary.Library;
28
import org.eclipse.gmf.runtime.emf.core.internal.resources.AbstractResourceWrapper;
29
import org.eclipse.gmf.runtime.emf.core.resources.CannotAbsorbException;
30
import org.eclipse.gmf.runtime.emf.core.resources.CannotSeparateException;
31
import org.eclipse.gmf.runtime.emf.core.resources.ILogicalResource;
32
33
34
/**
35
 * Tests the {@link LogicalResourceWrapper} class.
36
 *
37
 * @author Christian W. Damus (cdamus)
38
 */
39
public class LogicalResourceWrapperTest
40
	extends BaseLogicalResourceTest {
41
	
42
	public LogicalResourceWrapperTest(String name) {
43
		super(name);
44
	}
45
	
46
	public static Test suite() {
47
		return new TestSuite(LogicalResourceWrapperTest.class, "Wrapper Tests"); //$NON-NLS-1$
48
	}
49
50
	/**
51
	 * Tests that nothing can be separated in a non-logical resource.
52
	 */
53
	public void test_canSeparate() {
54
		assertFalse(logres.canSeparate(root)); // wouldn't be separable, anyway
55
		assertFalse(logres.canSeparate(subunit1)); // would be separable in MSL resource
56
	}
57
58
	/**
59
	 * Tests that nothing appears to be separate in a non-logical resource.
60
	 */
61
	public void test_isSeparate() {
62
		assertFalse(logres.isSeparate(root)); // wouldn't be separate, anyway
63
		assertFalse(logres.isSeparate(subunit1)); // same here, actually
64
	}
65
66
	/**
67
	 * Tests that everything appears to be loaded in a non-logical resource.
68
	 */
69
	public void test_isLoaded() {
70
		saveLogicalResource();
71
		logres.unload();
72
		
73
		Map options = new java.util.HashMap();
74
		options.put(ILogicalResource.OPTION_LOAD_ALL_UNITS, Boolean.FALSE);
75
		options.put(ILogicalResource.OPTION_AUTO_LOAD_UNITS, Boolean.FALSE);
76
		
77
		// try loading without loading sub-units and without auto-loading
78
		loadLogicalResource(false, false);
79
		
80
		assertTrue(logres.isLoaded(root)); // wouldn't be unloaded, anyway
81
		assertTrue(logres.isLoaded(subunit1)); // same here, actually
82
	}
83
	
84
	/**
85
	 * Tests that attempting to load an element always fails.
86
	 */
87
	public void test_load() {
88
		try {
89
			logres.load(root);  // would fail, anyway
90
			fail("Should have failed to load"); //$NON-NLS-1$
91
		} catch (IllegalArgumentException e) {
92
			// passed the test
93
		} catch (IOException e) {
94
			fail("Wrong exception thrown: " + e.getLocalizedMessage()); //$NON-NLS-1$
95
		}
96
		
97
		try {
98
			logres.load(subunit1);  // would also fail in MSL resource because it's not separate
99
			fail("Should have failed to load"); //$NON-NLS-1$
100
		} catch (IllegalArgumentException e) {
101
			// passed the test
102
		} catch (IOException e) {
103
			fail("Wrong exception thrown: " + e.getLocalizedMessage()); //$NON-NLS-1$
104
		}
105
	}
106
	
107
	/**
108
	 * Tests that attempting to separate always fails.
109
	 */
110
	public void test_separate() {
111
		URI subunitUri = URI.createPlatformResourceURI(SUBUNIT_NAME1);
112
		
113
		try {
114
			logres.separate(root, subunitUri);  // would fail, anyway
115
			fail("Should have failed to separate"); //$NON-NLS-1$
116
		} catch (IllegalArgumentException e) {
117
			// passed the test
118
		} catch (CannotSeparateException e) {
119
			fail("Wrong exception thrown: " + e.getLocalizedMessage()); //$NON-NLS-1$
120
		}
121
		
122
		try {
123
			logres.separate(subunit1, subunitUri);  // would not fail in MSL resource
124
			fail("Should have failed to separate"); //$NON-NLS-1$
125
		} catch (IllegalArgumentException e) {
126
			// passed the test
127
		} catch (CannotSeparateException e) {
128
			fail("Wrong exception thrown: " + e.getLocalizedMessage()); //$NON-NLS-1$
129
		}
130
	}
131
	
132
	/**
133
	 * Tests that attempting to absorb always fails.
134
	 */
135
	public void test_absorb() {
136
		try {
137
			logres.absorb(root);  // would fail, anyway
138
			fail("Should have failed to absorb"); //$NON-NLS-1$
139
		} catch (IllegalArgumentException e) {
140
			// passed the test
141
		} catch (CannotAbsorbException e) {
142
			fail("Wrong exception thrown: " + e.getLocalizedMessage()); //$NON-NLS-1$
143
		}
144
		
145
		try {
146
			logres.absorb(subunit1);  // would actually fail in MSL resource, too
147
			fail("Should have failed to absorb"); //$NON-NLS-1$
148
		} catch (IllegalArgumentException e) {
149
			// passed the test
150
		} catch (CannotAbsorbException e) {
151
			fail("Wrong exception thrown: " + e.getLocalizedMessage()); //$NON-NLS-1$
152
		}
153
	}
154
	
155
	/**
156
	 * Tests that we do get a correct mapped-resources map.
157
	 */
158
	public void test_getMappedResources() {
159
		Map resources = logres.getMappedResources();
160
		
161
		assertEquals(1, resources.size());
162
		assertSame(
163
			AbstractResourceWrapper.unwrap(logres),
164
			AbstractResourceWrapper.unwrap((Resource) resources.get(root)));
165
		
166
		Library second = EXTLibraryFactory.eINSTANCE.createLibrary();
167
		logres.getContents().add(second);  // test adding a root
168
		
169
		// check that the resource map is dynamically updated
170
		assertEquals(2, resources.size());
171
		assertSame(
172
			AbstractResourceWrapper.unwrap(logres),
173
			AbstractResourceWrapper.unwrap((Resource) resources.get(root)));
174
		assertSame(
175
			AbstractResourceWrapper.unwrap(logres),
176
			AbstractResourceWrapper.unwrap((Resource) resources.get(second)));
177
		
178
		Library third = EXTLibraryFactory.eINSTANCE.createLibrary();
179
		logres.getContents().set(1, third);  // test setting a root
180
		assertEquals(2, resources.size());
181
		assertSame(
182
			AbstractResourceWrapper.unwrap(logres),
183
			AbstractResourceWrapper.unwrap((Resource) resources.get(third)));
184
		
185
		logres.getContents().remove(0);  // test removing a root
186
		assertEquals(1, resources.size());
187
		assertSame(
188
			AbstractResourceWrapper.unwrap(logres),
189
			AbstractResourceWrapper.unwrap((Resource) resources.get(third)));
190
	}
191
	
192
	/** Test that notifications appear correctly to come from the wrapper. */
193
	public void test_notifications() {
194
		class TestAdapter extends AdapterImpl {
195
			Notification notification;
196
			
197
			public void notifyChanged(Notification msg) {
198
				notification = msg;
199
			}
200
		}
201
		
202
		TestAdapter adapter = new TestAdapter();
203
		
204
		logres.eAdapters().add(adapter);
205
		
206
		logres.setModified(true);
207
		
208
		Notification notification = adapter.notification;
209
		assertNotNull(notification);
210
		assertSame(logres, notification.getNotifier());  // not the wrapped XMI
211
		assertEquals(Resource.RESOURCE__IS_MODIFIED, notification.getFeatureID(null));
212
		assertFalse(notification.getOldBooleanValue());
213
		assertTrue(notification.getNewBooleanValue());
214
	}
215
	
216
	public void test_unwrap() {
217
		Resource unwrapped = AbstractResourceWrapper.unwrap(logres);
218
		
219
		assertNotNull(unwrapped);
220
		assertNotSame(logres, unwrapped);
221
		assertSame(
222
			logres.getResourceSet().getResource(getXmiUri(), false),
223
			unwrapped);
224
	}
225
	
226
	//
227
	// Framework methods
228
	//
229
	
230
	/**
231
	 * Replaces the *.extlibrary extension with *.xmi so that the editing domain
232
	 * will not create logical resources, but instead default XMI resources.
233
	 */
234
	protected ILogicalResource createNewLogicalResource(URI uri) {
235
		return super.createNewLogicalResource(getXmiUri(uri));
236
	}
237
	
238
	/**
239
	 * Converts a URI to *.xmi.
240
	 * 
241
	 * @param uri a URI
242
	 * @return the same URI, except with a *.xmi extension
243
	 */
244
	private URI getXmiUri(URI uri) {
245
		return uri.trimFileExtension().appendFileExtension("xmi"); //$NON-NLS-1$
246
	}
247
	
248
	/**
249
	 * Gets the default test resource URI as an XMI URI.
250
	 * 
251
	 * @return the *.xmi variant of our default test resource URI
252
	 */
253
	private URI getXmiUri() {
254
		return getXmiUri(URI.createPlatformResourceURI(RESOURCE_NAME));
255
	}
256
}
(-)src/org/eclipse/gmf/tests/runtime/emf/core/internal/resources/UnmodifiableResourceViewTest.java (-329 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
13
package org.eclipse.gmf.tests.runtime.emf.core.internal.resources;
14
15
import java.io.IOException;
16
import java.util.Iterator;
17
import java.util.List;
18
import java.util.Map;
19
20
import junit.framework.Test;
21
import junit.framework.TestSuite;
22
23
import org.eclipse.emf.common.notify.Notification;
24
import org.eclipse.emf.common.notify.impl.AdapterImpl;
25
import org.eclipse.emf.common.util.URI;
26
import org.eclipse.emf.ecore.resource.Resource;
27
28
import org.eclipse.gmf.runtime.emf.core.resources.CannotSeparateException;
29
30
31
/**
32
 * Tests the unmodifiable resource views that are made available to clients
33
 * by the {@link ILogicalResource#getMappedResources()} method and the
34
 * logical-resource-related notifications.
35
 *
36
 * @author Christian W. Damus (cdamus)
37
 */
38
public class UnmodifiableResourceViewTest
39
	extends BaseLogicalResourceTest {
40
	
41
	public UnmodifiableResourceViewTest(String name) {
42
		super(name);
43
	}
44
	
45
	public static Test suite() {
46
		return new TestSuite(UnmodifiableResourceViewTest.class, "Unmodifiable Resource View Tests"); //$NON-NLS-1$
47
	}
48
49
	/**
50
	 * Tests that the APIs clients need to access are available.
51
	 */
52
	public void test_getURI() {
53
		// get the map first, to test that its view of the resource set changes
54
		//    in synch with reality
55
		Map resources = logres.getMappedResources();
56
		
57
		URI subunitUri = URI.createPlatformResourceURI(SUBUNIT_NAME1);
58
		
59
		try {
60
			logres.separate(subunit1, subunitUri);
61
		} catch (CannotSeparateException e) {
62
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
63
		}
64
		
65
		Resource unit = (Resource) resources.get(subunit1);
66
		assertNotNull(unit);
67
		
68
		try {
69
			assertEquals(subunitUri, unit.getURI());
70
		} catch (UnsupportedOperationException e) {
71
			fail("Operation should be supported: " + e.getLocalizedMessage()); //$NON-NLS-1$
72
		}
73
	}
74
75
	/**
76
	 * Tests that the APIs clients need to access are available.
77
	 */
78
	public void test_isModified() {
79
		// get the map first, to test that its view of the resource set changes
80
		//    in synch with reality
81
		Map resources = logres.getMappedResources();
82
		
83
		try {
84
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
85
		} catch (CannotSeparateException e) {
86
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
87
		}
88
		
89
		Resource unit = (Resource) resources.get(subunit1);
90
		assertNotNull(unit);
91
		
92
		try {
93
			assertTrue(unit.isModified());
94
		} catch (UnsupportedOperationException e) {
95
			fail("Operation should be supported: " + e.getLocalizedMessage()); //$NON-NLS-1$
96
		}
97
		
98
		saveLogicalResource();
99
		
100
		try {
101
			assertFalse(unit.isModified());
102
		} catch (UnsupportedOperationException e) {
103
			fail("Operation should be supported: " + e.getLocalizedMessage()); //$NON-NLS-1$
104
		}
105
	}
106
107
	/**
108
	 * Tests that the APIs clients need to access are available.
109
	 */
110
	public void test_isLoaded() {
111
		// get the map first, to test that its view of the resource set changes
112
		//    in synch with reality
113
		Map resources = logres.getMappedResources();
114
		
115
		String subunit1Frag = logres.getURIFragment(subunit1);
116
		try {
117
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
118
		} catch (CannotSeparateException e) {
119
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
120
		}
121
		
122
		Resource unit = (Resource) resources.get(subunit1);
123
		assertNotNull(unit);
124
		
125
		try {
126
			assertTrue(unit.isLoaded());
127
		} catch (UnsupportedOperationException e) {
128
			fail("Operation should be supported: " + e.getLocalizedMessage()); //$NON-NLS-1$
129
		}
130
		
131
		saveLogicalResource();
132
		logres.unload();
133
		
134
		loadLogicalResource(false, false);  // load without sub-units
135
		
136
		subunit1 = lookupLibrary(subunit1Frag);
137
		assertNotNull(subunit1);
138
		
139
		unit = (Resource) resources.get(subunit1);
140
		assertNotNull(unit);
141
		
142
		try {
143
			assertFalse(unit.isLoaded());
144
		} catch (UnsupportedOperationException e) {
145
			fail("Operation should be supported: " + e.getLocalizedMessage()); //$NON-NLS-1$
146
		}
147
	}
148
149
	/**
150
	 * Tests that the APIs clients need to access are available.
151
	 */
152
	public void test_eAdapters() {
153
		// get the map first, to test that its view of the resource set changes
154
		//    in synch with reality
155
		Map resources = logres.getMappedResources();
156
		
157
		String subunit1Frag = logres.getURIFragment(subunit1);
158
		try {
159
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
160
		} catch (CannotSeparateException e) {
161
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
162
		}
163
		
164
		Resource unit = (Resource) resources.get(subunit1);
165
		assertNotNull(unit);
166
		
167
		try {
168
			assertTrue(unit.isLoaded());
169
		} catch (UnsupportedOperationException e) {
170
			fail("Operation should be supported: " + e.getLocalizedMessage()); //$NON-NLS-1$
171
		}
172
		
173
		saveLogicalResource();
174
		logres.unload();
175
		
176
		loadLogicalResource(false, false);  // load without sub-units
177
		
178
		subunit1 = lookupLibrary(subunit1Frag);
179
		assertNotNull(subunit1);
180
		
181
		unit = (Resource) resources.get(subunit1);
182
		assertNotNull(unit);
183
		
184
		class TestAdapter extends AdapterImpl {
185
			Notification notification;
186
			
187
			public void notifyChanged(Notification msg) {
188
				// capture the change in isLoaded feature
189
				if (msg.getFeatureID(Resource.class) == Resource.RESOURCE__IS_LOADED) {
190
					notification = msg;
191
				}
192
			}
193
		}
194
		
195
		TestAdapter adapter = new TestAdapter();
196
		
197
		try {
198
			unit.eAdapters().add(adapter);
199
		} catch (UnsupportedOperationException e) {
200
			fail("Operation should be supported: " + e.getLocalizedMessage()); //$NON-NLS-1$
201
		}
202
		
203
		try {
204
			logres.load(subunit1);
205
		} catch (IOException e) {
206
			fail("Should not have failed to load: " + e.getLocalizedMessage()); //$NON-NLS-1$
207
		}
208
		
209
		Notification notification = adapter.notification;
210
		assertNotNull(notification);
211
		assertSame(unit, notification.getNotifier()); // view is the notifier
212
		assertEquals(
213
			Resource.RESOURCE__IS_LOADED,
214
			notification.getFeatureID(Resource.class));
215
		assertFalse(notification.getOldBooleanValue());
216
		assertTrue(notification.getNewBooleanValue());
217
	}
218
219
	/**
220
	 * Tests that the APIs clients need to access are available.
221
	 */
222
	public void test_getContents() {
223
		// get the map first, to test that its view of the resource set changes
224
		//    in synch with reality
225
		Map resources = logres.getMappedResources();
226
		
227
		try {
228
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
229
		} catch (CannotSeparateException e) {
230
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
231
		}
232
		
233
		Resource unit = (Resource) resources.get(subunit1);
234
		assertNotNull(unit);
235
		
236
		try {
237
			List contents = unit.getContents();
238
			assertNotNull(contents);
239
			assertFalse(contents.isEmpty());
240
			assertSame(subunit1, contents.get(0));
241
		} catch (UnsupportedOperationException e) {
242
			fail("Operation should be supported: " + e.getLocalizedMessage()); //$NON-NLS-1$
243
		}
244
	}
245
246
	/**
247
	 * Tests that the APIs clients need to access are available.
248
	 */
249
	public void test_getAllContents() {
250
		// get the map first, to test that its view of the resource set changes
251
		//    in synch with reality
252
		Map resources = logres.getMappedResources();
253
		
254
		try {
255
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
256
		} catch (CannotSeparateException e) {
257
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
258
		}
259
		
260
		Resource unit = (Resource) resources.get(subunit1);
261
		assertNotNull(unit);
262
		
263
		try {
264
			Iterator allContents = unit.getAllContents();
265
			assertNotNull(allContents);
266
			
267
			boolean foundSubunit2 = false;
268
			while (allContents.hasNext() && !foundSubunit2) {
269
				foundSubunit2 = allContents.next() == subunit2;
270
			}
271
			
272
			assertTrue(foundSubunit2);
273
		} catch (UnsupportedOperationException e) {
274
			fail("Operation should be supported: " + e.getLocalizedMessage()); //$NON-NLS-1$
275
		}
276
	}
277
278
	/**
279
	 * Tests that the APIs clients need to access are available.
280
	 */
281
	public void test_getEObject() {
282
		// get the map first, to test that its view of the resource set changes
283
		//    in synch with reality
284
		Map resources = logres.getMappedResources();
285
		
286
		String subunit2Frag = logres.getURIFragment(subunit2);
287
		
288
		try {
289
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
290
		} catch (CannotSeparateException e) {
291
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
292
		}
293
		
294
		Resource unit = (Resource) resources.get(subunit1);
295
		assertNotNull(unit);
296
		
297
		try {
298
			assertSame(subunit2, unit.getEObject(subunit2Frag));
299
		} catch (UnsupportedOperationException e) {
300
			fail("Operation should be supported: " + e.getLocalizedMessage()); //$NON-NLS-1$
301
		}
302
	}
303
304
	/**
305
	 * Tests that the APIs clients need to access are available.
306
	 */
307
	public void test_getURIFragment() {
308
		// get the map first, to test that its view of the resource set changes
309
		//    in synch with reality
310
		Map resources = logres.getMappedResources();
311
		
312
		String subunit2Frag = logres.getURIFragment(subunit2);
313
		
314
		try {
315
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
316
		} catch (CannotSeparateException e) {
317
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
318
		}
319
		
320
		Resource unit = (Resource) resources.get(subunit1);
321
		assertNotNull(unit);
322
		
323
		try {
324
			assertEquals(subunit2Frag, unit.getURIFragment(subunit2));
325
		} catch (UnsupportedOperationException e) {
326
			fail("Operation should be supported: " + e.getLocalizedMessage()); //$NON-NLS-1$
327
		}
328
	}
329
}
(-)src/org/eclipse/gmf/tests/runtime/emf/core/internal/resources/GarbageCollectionTest.java (-128 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
13
package org.eclipse.gmf.tests.runtime.emf.core.internal.resources;
14
15
import java.lang.ref.Reference;
16
import java.lang.ref.ReferenceQueue;
17
import java.lang.ref.WeakReference;
18
19
import junit.framework.Test;
20
import junit.framework.TestSuite;
21
22
import org.eclipse.emf.common.util.URI;
23
import org.eclipse.emf.ecore.resource.Resource;
24
import org.eclipse.emf.ecore.resource.impl.ResourceImpl;
25
26
import org.eclipse.gmf.runtime.emf.core.internal.domain.MSLEditingDomain;
27
import org.eclipse.gmf.runtime.emf.core.resources.CannotSeparateException;
28
import org.eclipse.gmf.runtime.emf.core.resources.ILogicalResource;
29
30
31
/**
32
 * Tests that we do not introduce uncollected or uncollectable garbage in the
33
 * logical resources API.
34
 *
35
 * @author Christian W. Damus (cdamus)
36
 */
37
public class GarbageCollectionTest
38
	extends BaseLogicalResourceTest {
39
	
40
	public GarbageCollectionTest(String name) {
41
		super(name);
42
	}
43
	
44
	public static Test suite() {
45
		return new TestSuite(GarbageCollectionTest.class, "Garbage Collection Tests"); //$NON-NLS-1$
46
	}
47
48
	/**
49
	 * Tests that sub-unit resources and their unmodifiable views are properly
50
	 * collectable.
51
	 */
52
	public void test_collectSubunitResources() {
53
		try {
54
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
55
		} catch (CannotSeparateException e) {
56
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
57
		}
58
		
59
		ReferenceQueue q = new ReferenceQueue();
60
		WeakReference ref = new WeakReference(
61
			logres.getMappedResources().get(subunit1), q);
62
		
63
		unloadLogicalResource();
64
		
65
		// just in case, clear all fields that can reference this resource
66
		root = null;
67
		subunit1 = null;
68
		subunit2 = null;
69
		subunit3 = null;
70
		
71
		// stop writing and clear the MSL undo stack
72
		stopWriting();
73
		((MSLEditingDomain) domain).getUndoStack().flushAll();
74
		
75
		try {
76
			Thread.sleep(1000);
77
		} catch (InterruptedException e) {
78
			// won't happen
79
		}
80
		
81
		Runtime.getRuntime().gc();
82
		
83
		try {
84
			Thread.sleep(1000);
85
		} catch (InterruptedException e) {
86
			// won't happen
87
		}
88
		
89
		Reference enqueued = q.poll();
90
		assertSame(ref, enqueued);
91
	}
92
93
	/**
94
	 * Tests that resources and their logical views are properly
95
	 * collectable.
96
	 */
97
	public void test_collectLogicalResourceWrappers() {
98
		Resource res = new ResourceImpl();
99
		ILogicalResource logical = domain.asLogicalResource(res);
100
		
101
		ReferenceQueue q = new ReferenceQueue();
102
		WeakReference ref = new WeakReference(logical, q);
103
		
104
		logical = null;
105
		res = null;
106
		
107
		// stop writing and clear the MSL undo stack
108
		stopWriting();
109
		((MSLEditingDomain) domain).getUndoStack().flushAll();
110
		
111
		try {
112
			Thread.sleep(1000);
113
		} catch (InterruptedException e) {
114
			// won't happen
115
		}
116
		
117
		Runtime.getRuntime().gc();
118
		
119
		try {
120
			Thread.sleep(1000);
121
		} catch (InterruptedException e) {
122
			// won't happen
123
		}
124
		
125
		Reference enqueued = q.poll();
126
		assertSame(ref, enqueued);
127
	}
128
}
(-)src/org/eclipse/gmf/tests/runtime/emf/core/internal/resources/ErrorConditionsTest.java (-329 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
13
package org.eclipse.gmf.tests.runtime.emf.core.internal.resources;
14
15
import java.io.IOException;
16
import java.util.Collections;
17
import java.util.Map;
18
19
import junit.framework.Test;
20
import junit.framework.TestSuite;
21
22
import org.eclipse.core.resources.IFile;
23
import org.eclipse.core.resources.ResourceAttributes;
24
import org.eclipse.core.runtime.CoreException;
25
import org.eclipse.emf.common.util.URI;
26
27
import org.eclipse.emf.examples.extlibrary.Library;
28
import org.eclipse.gmf.runtime.emf.core.resources.CannotAbsorbException;
29
import org.eclipse.gmf.runtime.emf.core.resources.CannotSeparateException;
30
import org.eclipse.gmf.runtime.emf.core.resources.ILogicalResource;
31
32
33
/**
34
 * Tests a variety of error conditions in loading and saving, to see that the
35
 * appropriate response is relayed to the client.
36
 *
37
 * @author Christian W. Damus (cdamus)
38
 */
39
public class ErrorConditionsTest
40
	extends BaseLogicalResourceTest {
41
	
42
	public ErrorConditionsTest(String name) {
43
		super(name);
44
	}
45
	
46
	public static Test suite() {
47
		return new TestSuite(ErrorConditionsTest.class, "Error Condition Tests"); //$NON-NLS-1$
48
	}
49
50
	/**
51
	 * Tests failure to load a monolithic resource that does not exist.
52
	 */
53
	public void test_loadNonExistentFile_monolith() {
54
		saveLogicalResource();
55
		
56
		delete(RESOURCE_NAME);
57
		
58
		// discard the resource and re-load from disk
59
		createLogicalResource(RESOURCE_NAME);
60
		
61
		try {
62
			logres.load(Collections.EMPTY_MAP);
63
			fail("Should have thrown IOException on non-existent file."); //$NON-NLS-1$
64
		} catch (IOException e) {
65
			// success
66
		}
67
	}
68
69
	/**
70
	 * Tests failure to load a sub-unit resource that does not exist.
71
	 */
72
	public void test_loadNonExistentFile_subunit() {
73
		try {
74
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
75
		} catch (CannotSeparateException e) {
76
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
77
		}
78
		
79
		saveLogicalResource();
80
		
81
		delete(SUBUNIT_NAME1);
82
		
83
		// discard the resource and re-load from disk
84
		createLogicalResource(RESOURCE_NAME);
85
		
86
		try {
87
			Map options = new java.util.HashMap();
88
			options.put(ILogicalResource.OPTION_LOAD_ALL_UNITS, Boolean.TRUE);
89
			
90
			logres.load(options);
91
		} catch (IOException e) {
92
			// non-existent sub-units just cause proxies to be unresolved
93
			//   and separate elements to be unresolved
94
			fail("Should not have thrown IOException on non-existent file."); //$NON-NLS-1$
95
		}
96
		
97
		subunit1 = (Library) find("root/level1/level2-subunit"); //$NON-NLS-1$
98
		assertNotNull(subunit1);
99
		assertFalse(logres.isLoaded(subunit1));
100
		
101
		try {
102
			// now we should get an exception, when explicitly trying to
103
			//    load the non-existent sub-unit
104
			logres.load(subunit1);
105
			fail("Should have thrown IOException on non-existent file."); //$NON-NLS-1$
106
		} catch (IOException e) {
107
			// success
108
		}
109
	}
110
111
	/**
112
	 * Tests failure to save a monolithic resource that is read-only.
113
	 */
114
	public void test_saveReadOnlyFile_monolith() {
115
		saveLogicalResource();
116
		
117
		setReadOnly(RESOURCE_NAME);
118
		
119
		// modify the resource
120
		root.setName("Library of Congress"); //$NON-NLS-1$
121
		
122
		try {
123
			logres.save(Collections.EMPTY_MAP);
124
			fail("Should have thrown IOException on read-only file."); //$NON-NLS-1$
125
		} catch (IOException e) {
126
			// success
127
		}
128
	}
129
130
	/**
131
	 * Tests failure to save a sub-unit resource that is read-only.
132
	 */
133
	public void test_saveReadOnlyFile_subunit() {
134
		try {
135
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
136
		} catch (CannotSeparateException e) {
137
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
138
		}
139
		
140
		saveLogicalResource();
141
		
142
		setReadOnly(SUBUNIT_NAME1);
143
		
144
		// modify the resource (subunit2 isin the subunit1 file)
145
		subunit2.setName("Library of Congress"); //$NON-NLS-1$
146
		
147
		try {
148
			logres.save(Collections.EMPTY_MAP);
149
			fail("Should have thrown IOException on read-only file."); //$NON-NLS-1$
150
		} catch (IOException e) {
151
			// success
152
		}
153
	}
154
155
	/**
156
	 * Tests the exception to the don't-save-what-isn't-dirty rule for the
157
	 * case of a monolithic resource, which behaviour should be compatible with
158
	 * the basic XMI resource behaviour.
159
	 */
160
	public void test_saveNonDirtyReadOnlyFile_monolith() {
161
		saveLogicalResource();
162
		
163
		setReadOnly(RESOURCE_NAME);
164
		
165
		// do not modify the resource, so that it is not dirty when we save
166
		//    again
167
		
168
		try {
169
			logres.save(Collections.EMPTY_MAP);
170
			fail("Should have thrown IOException on read-only file."); //$NON-NLS-1$
171
		} catch (IOException e) {
172
			// success
173
		}
174
	}
175
176
	/**
177
	 * Tests that when we have multiple units in our resource, we only save
178
	 * what's dirty, if we save anything at all.
179
	 */
180
	public void test_saveNonDirtyReadOnlyFile_subunit() {
181
		try {
182
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
183
		} catch (CannotSeparateException e) {
184
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
185
		}
186
		
187
		saveLogicalResource();
188
		
189
		setReadOnly(RESOURCE_NAME);
190
		setReadOnly(SUBUNIT_NAME1);
191
		
192
		// do not modify the resource, so that it is not dirty when we save
193
		//    again
194
		
195
		try {
196
			logres.save(Collections.EMPTY_MAP);
197
		} catch (IOException e) {
198
			fail("Should not have thrown IOException on read-only file."); //$NON-NLS-1$
199
		}
200
	}
201
202
	/**
203
	 * Tests that when we have multiple units in our resource, we only save
204
	 * what's dirty.
205
	 */
206
	public void test_saveOnlyDirtyFile_subunit() {
207
		try {
208
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
209
		} catch (CannotSeparateException e) {
210
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
211
		}
212
		
213
		saveLogicalResource();
214
		
215
		setReadOnly(RESOURCE_NAME);
216
		
217
		// modify only the sub-unit, which is not read-only
218
		subunit2.setName("Library of Congress"); //$NON-NLS-1$
219
		
220
		try {
221
			logres.save(Collections.EMPTY_MAP);
222
		} catch (IOException e) {
223
			fail("Should not have thrown IOException on read-only file."); //$NON-NLS-1$
224
		}
225
	}
226
	
227
	/**
228
	 * Tests that absorption of an unloaded element is not allowed.
229
	 */
230
	public void test_absorbUnloadedElement() {
231
		try {
232
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
233
		} catch (CannotSeparateException e) {
234
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
235
		}
236
		
237
		saveLogicalResource();
238
		
239
		delete(SUBUNIT_NAME1);
240
		
241
		// discard the resource and re-load from disk
242
		createLogicalResource(RESOURCE_NAME);
243
		
244
		try {
245
			Map options = new java.util.HashMap();
246
			options.put(ILogicalResource.OPTION_LOAD_ALL_UNITS, Boolean.TRUE);
247
			
248
			logres.load(options);
249
		} catch (IOException e) {
250
			// non-existent sub-units just cause proxies to be unresolved
251
			//   and separate elements to be unresolved
252
			fail("Should not have thrown IOException on non-existent file."); //$NON-NLS-1$
253
		}
254
		
255
		subunit1 = (Library) find("root/level1/level2-subunit"); //$NON-NLS-1$
256
		assertNotNull(subunit1);
257
		assertFalse(logres.isLoaded(subunit1));
258
		
259
		try {
260
			logres.absorb(subunit1);
261
			fail("Should have thrown IllegalArgumentException"); //$NON-NLS-1$
262
		} catch (CannotAbsorbException e) {
263
			fail("Should not thrown CannotAbsorbException: " + e.getLocalizedMessage()); //$NON-NLS-1$
264
		} catch (IllegalArgumentException e) {
265
			// success
266
		}
267
	}
268
	
269
	/**
270
	 * Tests that seaparation of an element into its current storage unit is
271
	 * not allowed.
272
	 */
273
	public void test_separateIntoSameUnit() {
274
		URI subunitUri = URI.createPlatformResourceURI(SUBUNIT_NAME1);
275
		
276
		try {
277
			logres.separate(subunit1, subunitUri);
278
		} catch (CannotSeparateException e) {
279
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
280
		}
281
		
282
		try {
283
			logres.separate(subunit2, subunitUri);
284
			fail("Should have thrown IllegalArgumentException"); //$NON-NLS-1$
285
		} catch (CannotSeparateException e) {
286
			// success
287
		} catch (IllegalArgumentException e) {
288
			fail("Should not thrown IllegalArgumentException: " + e.getLocalizedMessage()); //$NON-NLS-1$
289
		}
290
	}
291
	
292
	//
293
	// Framework methods
294
	//
295
	
296
	/**
297
	 * Deletes the file specified by a workspace-relative path.
298
	 * 
299
	 * @param filePath the workspace-relative path
300
	 */
301
	private void delete(String filePath) {
302
		IFile file = getFile(filePath);
303
		assertNotNull(file);
304
		
305
		try {
306
			file.delete(true, null);
307
		} catch (CoreException e) {
308
			fail("Should not fail to delete file: " + e.getLocalizedMessage()); //$NON-NLS-1$
309
		}
310
	}
311
	
312
	/**
313
	 * Sets the file specified by a workspace-relative path as read-only.
314
	 * 
315
	 * @param filePath the workspace-relative path
316
	 */
317
	private void setReadOnly(String filePath) {
318
		IFile file = getFile(filePath);
319
		assertNotNull(file);
320
		
321
		try {
322
			ResourceAttributes attrs = new ResourceAttributes();
323
			attrs.setReadOnly(true);
324
			file.setResourceAttributes(attrs);
325
		} catch (CoreException e) {
326
			fail("Should not fail to set read-only: " + e.getLocalizedMessage()); //$NON-NLS-1$
327
		}
328
	}
329
}
(-)src/org/eclipse/gmf/tests/runtime/emf/core/internal/resources/RegressionTest.java (-204 lines)
Removed Link Here
1
/******************************************************************************
2
 * Copyright (c) 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - initial API and implementation 
10
 ****************************************************************************/
11
12
13
package org.eclipse.gmf.tests.runtime.emf.core.internal.resources;
14
15
import java.util.Collections;
16
17
import junit.framework.Test;
18
import junit.framework.TestSuite;
19
20
import org.eclipse.emf.common.util.URI;
21
import org.eclipse.emf.ecore.EObject;
22
import org.eclipse.emf.ecore.resource.Resource;
23
import org.eclipse.emf.examples.extlibrary.EXTLibraryFactory;
24
import org.eclipse.emf.examples.extlibrary.EXTLibraryPackage;
25
import org.eclipse.emf.examples.extlibrary.Library;
26
import org.eclipse.gmf.runtime.emf.core.internal.resourcemap.ResourceMap;
27
import org.eclipse.gmf.runtime.emf.core.internal.resources.AbstractResourceWrapper;
28
import org.eclipse.gmf.runtime.emf.core.resources.CannotAbsorbException;
29
import org.eclipse.gmf.runtime.emf.core.resources.CannotSeparateException;
30
import org.eclipse.gmf.runtime.emf.core.util.EObjectUtil;
31
32
33
/**
34
 * Tests for regressions in RATLC defects.
35
 *
36
 * @author Christian W. Damus (cdamus)
37
 */
38
public class RegressionTest
39
	extends BaseLogicalResourceTest {
40
	
41
	public RegressionTest(String name) {
42
		super(name);
43
	}
44
	
45
	public static Test suite() {
46
		return new TestSuite(RegressionTest.class, "Regression Tests"); //$NON-NLS-1$
47
	}
48
49
	/**
50
	 * Tests that moving a logical root into another container does not get
51
	 * it moved back into the resource contents.
52
	 */
53
	public void test_reparentLogicalRoot_RATLC00537428() {
54
		Library other = EXTLibraryFactory.eINSTANCE.createLibrary();
55
		logres.getContents().add(other);
56
		
57
		root.getBranches().add(other);
58
		
59
		assertSame(root, other.eContainer());
60
		assertSame(
61
			EXTLibraryPackage.eINSTANCE.getLibrary_Branches(),
62
			other.eContainmentFeature());
63
		assertEquals(Collections.singletonList(root), logres.getContents());
64
	}
65
	
66
	/**
67
	 * Tests that units correctly transfer ownership of their sub-units to
68
	 * other units when intervening elements in the containment tree are
69
	 * separated.
70
	 */
71
	public void test_unitsTransferSubunitOwnership_separate_RATLC00538037() {
72
		try {
73
			logres.separate(subunit2, URI.createPlatformResourceURI(SUBUNIT_NAME2));
74
			
75
			// now, separating parent is supposed to cause it to get subunit2
76
			//    as a child instead of the root unit owning it
77
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
78
		} catch (CannotSeparateException e) {
79
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
80
		}
81
		
82
		Resource unit = (Resource) logres.getMappedResources().get(root);
83
		
84
		// unwrap so that we don't get a view that hides the resource map
85
		unit = AbstractResourceWrapper.unwrap(unit);
86
		ResourceMap resmap = (ResourceMap) unit.getContents().get(0);
87
		
88
		assertEquals(
89
			"Root resource has wrong number of child units", //$NON-NLS-1$
90
			1,
91
			resmap.getParentEntries().size());
92
		
93
		// this unit must also have a single child unit
94
		unit = (Resource) logres.getMappedResources().get(subunit1);
95
		unit = AbstractResourceWrapper.unwrap(unit);
96
		ResourceMap resmap2 = (ResourceMap) unit.getContents().get(0);
97
		
98
		assertEquals(
99
			"Root resource has wrong number of child units", //$NON-NLS-1$
100
			1,
101
			resmap2.getParentEntries().size());
102
		
103
		// the leaf unit must have middle unit as its parent
104
		unit = (Resource) logres.getMappedResources().get(subunit2);
105
		unit = AbstractResourceWrapper.unwrap(unit);
106
		ResourceMap resmap3 = (ResourceMap) unit.getContents().get(0);
107
		
108
		assertSame(
109
			"Subunit has wrong parent", //$NON-NLS-1$
110
			resmap2,
111
			resmap3.getChildEntry(subunit2).getParentMap());
112
	}
113
	
114
	/**
115
	 * Tests that units correctly transfer ownership of their sub-units to
116
	 * other units when intervening elements in the containment tree are
117
	 * absorbed.
118
	 */
119
	public void test_unitsTransferSubunitOwnership_absorb_RATLC00538037() {
120
		try {
121
			logres.separate(subunit1, URI.createPlatformResourceURI(SUBUNIT_NAME1));
122
			logres.separate(subunit2, URI.createPlatformResourceURI(SUBUNIT_NAME2));
123
			
124
			// take out the middle unit.  subunit2's parent should now be the
125
			//    root
126
			logres.absorb(subunit1);
127
		} catch (CannotSeparateException e) {
128
			fail("Should not fail to separate: " + e); //$NON-NLS-1$
129
		} catch (CannotAbsorbException e) {
130
			fail("Should not fail to absorb: " + e); //$NON-NLS-1$
131
		}
132
		
133
		Resource unit = (Resource) logres.getMappedResources().get(root);
134
		
135
		// unwrap so that we don't get a view that hides the resource map
136
		unit = AbstractResourceWrapper.unwrap(unit);
137
		ResourceMap resmap = (ResourceMap) unit.getContents().get(0);
138
		
139
		assertEquals(
140
			"Root resource has wrong number of child units", //$NON-NLS-1$
141
			1,
142
			resmap.getParentEntries().size());
143
		
144
		// the remaining sub-unit must reference the root unit as parent
145
		unit = (Resource) logres.getMappedResources().get(subunit2);
146
		unit = AbstractResourceWrapper.unwrap(unit);
147
		ResourceMap resmap2 = (ResourceMap) unit.getContents().get(0);
148
		
149
		assertSame(
150
			"Subunit has wrong parent", //$NON-NLS-1$
151
			resmap,
152
			resmap2.getChildEntry(subunit2).getParentMap());
153
	}
154
155
	/**
156
	 * Tests that after moving a logical root into another container and then
157
	 * back to being a logical root, the logical root is properly saved.
158
	 */
159
	public void test_rerootLogicalRoot_RATLC00538194() {
160
		Library library = EXTLibraryFactory.eINSTANCE.createLibrary();
161
162
		// add the library to the logical resource
163
		logres.getContents().add(library);
164
		
165
		// logical resource should contain library
166
		assertEquals(2, logres.getContents().size());
167
		assertSame(logres.getContents().get(1), library);
168
		
169
		// remove the library from the logical resource
170
		logres.getContents().remove(library);
171
172
		assertFalse(logres.getMappedResources().containsKey(library));
173
174
		// move the library into the branches containment list of another library
175
		root.getBranches().add(library);
176
		
177
		// library should not be part of the resource map because it was added
178
		// to the list of branches in the root
179
		assertFalse(logres.getMappedResources().containsKey(library));
180
		
181
		// move the library back to being a root
182
		logres.getContents().add(library);
183
		
184
		// logical resource should contain library
185
		assertEquals(2, logres.getContents().size());
186
		assertSame(logres.getContents().get(1), library);
187
188
		// store the library ID for comparison later
189
		String libraryID = EObjectUtil.getID(library);
190
191
		saveLogicalResource();
192
		
193
		assertFalse(logres.isModified());
194
		
195
		// discard and re-load the resource
196
		createLogicalResource(RESOURCE_NAME);
197
		
198
		loadLogicalResource();
199
		
200
		// logical resource unit should contain library after reloading
201
		assertEquals(2, logres.getContents().size());
202
		assertEquals(libraryID, EObjectUtil.getID((EObject)logres.getContents().get(1)));
203
	}
204
}
(-)META-INF/MANIFEST.MF (-1 lines)
Lines 8-14 Link Here
8
Export-Package: org.eclipse.gmf.tests.runtime.emf.core.internal.commands,
8
Export-Package: org.eclipse.gmf.tests.runtime.emf.core.internal.commands,
9
 org.eclipse.gmf.tests.runtime.emf.core.internal.expressions,
9
 org.eclipse.gmf.tests.runtime.emf.core.internal.expressions,
10
 org.eclipse.gmf.tests.runtime.emf.core.internal.multithread.testcases,
10
 org.eclipse.gmf.tests.runtime.emf.core.internal.multithread.testcases,
11
 org.eclipse.gmf.tests.runtime.emf.core.internal.resources,
12
 org.eclipse.gmf.tests.runtime.emf.core.internal,
11
 org.eclipse.gmf.tests.runtime.emf.core.internal,
13
 org.eclipse.gmf.tests.runtime.emf.core
12
 org.eclipse.gmf.tests.runtime.emf.core
14
Require-Bundle: org.junit,
13
Require-Bundle: org.junit,
(-)src/org/eclipse/gmf/tests/runtime/emf/core/AllTests.java (-1 lines)
Lines 33-39 Link Here
33
import org.eclipse.gmf.tests.runtime.emf.core.internal.multithread.testcases.ReadOperationTest;
33
import org.eclipse.gmf.tests.runtime.emf.core.internal.multithread.testcases.ReadOperationTest;
34
import org.eclipse.gmf.tests.runtime.emf.core.internal.multithread.testcases.ReadWriteOperationTest;
34
import org.eclipse.gmf.tests.runtime.emf.core.internal.multithread.testcases.ReadWriteOperationTest;
35
import org.eclipse.gmf.tests.runtime.emf.core.internal.multithread.testcases.WriteOperationTest;
35
import org.eclipse.gmf.tests.runtime.emf.core.internal.multithread.testcases.WriteOperationTest;
36
import org.eclipse.gmf.tests.runtime.emf.core.internal.resources.BaseLogicalResourceTest;
37
import org.osgi.service.prefs.BackingStoreException;
36
import org.osgi.service.prefs.BackingStoreException;
38
import org.osgi.service.prefs.Preferences;
37
import org.osgi.service.prefs.Preferences;
39
38

Return to bug 113863