KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > emf > ecore > resource > impl > ResourceSetImpl


1 /**
2  * <copyright>
3  *
4  * Copyright (c) 2002-2004 IBM Corporation and others.
5  * All rights reserved. This program and the accompanying materials
6  * are made available under the terms of the Eclipse Public License v1.0
7  * which accompanies this distribution, and is available at
8  * http://www.eclipse.org/legal/epl-v10.html
9  *
10  * Contributors:
11  * IBM - Initial API and implementation
12  *
13  * </copyright>
14  *
15  * $Id: ResourceSetImpl.java,v 1.7 2005/06/08 06:20:10 nickb Exp $
16  */

17 package org.eclipse.emf.ecore.resource.impl;
18
19
20 import java.io.IOException JavaDoc;
21 import java.util.Collections JavaDoc;
22 import java.util.HashMap JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.ListIterator JavaDoc;
26 import java.util.Map JavaDoc;
27
28 import org.eclipse.emf.common.notify.AdapterFactory;
29 import org.eclipse.emf.common.notify.NotificationChain;
30 import org.eclipse.emf.common.notify.impl.NotifierImpl;
31 import org.eclipse.emf.common.notify.impl.NotifyingListImpl;
32 import org.eclipse.emf.common.util.BasicEList;
33 import org.eclipse.emf.common.util.EList;
34 import org.eclipse.emf.common.util.TreeIterator;
35 import org.eclipse.emf.common.util.URI;
36 import org.eclipse.emf.common.util.WrappedException;
37 import org.eclipse.emf.ecore.EObject;
38 import org.eclipse.emf.ecore.EPackage;
39 import org.eclipse.emf.ecore.impl.EPackageRegistryImpl;
40 import org.eclipse.emf.ecore.resource.Resource;
41 import org.eclipse.emf.ecore.resource.ResourceSet;
42 import org.eclipse.emf.ecore.resource.URIConverter;
43 import org.eclipse.emf.ecore.util.EcoreUtil;
44 import org.eclipse.emf.ecore.util.InternalEList;
45
46
47 /**
48  * An extensible resource set implementation.
49  * <p>
50  * The following configuration and control mechanisms are provided:
51  * <ul>
52  * <li><b>Resolve</b></li>
53  * <ul>
54  * <li>{@link #delegatedGetResource(URI, boolean)}</li>
55  * <li>{@link #getEObject(URI, boolean)}</li>
56  * </ul>
57  * <li><b>Demand</b></li>
58  * <ul>
59  * <li>{@link #demandCreateResource(URI)}</li>
60  * <li>{@link #demandLoad(Resource)}</li>
61  * <li>{@link #demandLoadHelper(Resource)}</li>
62  * </ul>
63  * </ul>
64  * </p>
65  */

66 public class ResourceSetImpl extends NotifierImpl implements ResourceSet
67 {
68   /**
69    * The contained resources.
70    * @see #getResources
71    */

72   protected EList resources;
73
74   /**
75    * The registered adapter factories.
76    * @see #getAdapterFactories
77    */

78   protected EList adapterFactories;
79
80   /**
81    * The load options.
82    * @see #getLoadOptions
83    */

84   protected Map JavaDoc loadOptions;
85
86   /**
87    * The local resource factory registry.
88    * @see #getResourceFactoryRegistry
89    */

90   protected Resource.Factory.Registry resourceFactoryRegistry;
91
92   /**
93    * The URI converter.
94    * @see #getURIConverter
95    */

96   protected URIConverter uriConverter;
97
98   /**
99    * The local package registry.
100    * @see #getPackageRegistry
101    */

102   protected EPackage.Registry packageRegistry;
103   
104   /**
105    * A map to cache the resource associated with a specific URI.
106    * @see #setURIResourceMap(Map)
107    */

108   protected Map JavaDoc uriResourceMap;
109
110   /**
111    * Creates an empty instance.
112    */

113   public ResourceSetImpl()
114   {
115   }
116   
117   /**
118    * Returns the map used to cache the resource {@link #getResource(URI, boolean) associated} with a specific URI.
119    * @return the map used to cache the resource associated with a specific URI.
120    * @see #setURIResourceMap
121    */

122   public Map JavaDoc getURIResourceMap()
123   {
124     return uriResourceMap;
125   }
126
127   /**
128    * Sets the map used to cache the resource associated with a specific URI.
129    * This cache is only activated if the map is not <code>null</code>.
130    * The map will be lazily loaded by the {@link #getResource(URI, boolean) getResource} method.
131    * It is up to the client to clear the cache when it becomes invalid,
132    * e.g., when the URI of a previously mapped resource is changed.
133    * @param uriResourceMap the new map or <code>null</code>.
134    * @see #getURIResourceMap
135    */

136   public void setURIResourceMap(Map JavaDoc uriResourceMap)
137   {
138     this.uriResourceMap = uriResourceMap;
139   }
140   
141   /*
142    * Javadoc copied from interface.
143    */

144   public EList getResources()
145   {
146     if (resources == null)
147     {
148       resources = new ResourcesEList();
149     }
150     return resources;
151   }
152
153   /*
154    * Javadoc copied from interface.
155    */

156   public TreeIterator getAllContents()
157   {
158     TreeIterator result = EcoreUtil.getAllContents(Collections.singleton(this));
159     result.next();
160     return result;
161   }
162
163   /*
164    * Javadoc copied from interface.
165    */

166   public EList getAdapterFactories()
167   {
168     if (adapterFactories == null)
169     {
170       adapterFactories =
171         new BasicEList()
172         {
173           protected boolean useEquals()
174           {
175             return false;
176           }
177
178           protected boolean isUnique()
179           {
180             return true;
181           }
182
183           protected Object JavaDoc [] newData(int capacity)
184           {
185             return new AdapterFactory [capacity];
186           }
187         };
188     }
189     return adapterFactories;
190   }
191
192   /*
193    * Javadoc copied from interface.
194    */

195   public Map JavaDoc getLoadOptions()
196   {
197     if (loadOptions == null)
198     {
199       loadOptions = new HashMap JavaDoc();
200     }
201
202     return loadOptions;
203   }
204
205   /*
206    * Javadoc copied from interface.
207    */

208   public EObject getEObject(URI uri, boolean loadOnDemand)
209   {
210     Resource resource = getResource(uri.trimFragment(), loadOnDemand);
211     if (resource != null)
212     {
213       return resource.getEObject(uri.fragment());
214     }
215     else
216     {
217       return null;
218     }
219   }
220
221   /**
222    * Creates a new resource appropriate for the URI.
223    * It is called by {@link #getResource(URI, boolean) getResource(URI, boolean)}
224    * when a URI that doesn't exist as a resource is demand loaded.
225    * This implementation simply calls {@link #createResource(URI) createResource(URI)}.
226    * Clients may extend this as appropriate.
227    * @param uri the URI of the resource to create.
228    * @return a new resource.
229    * @see #getResource(URI, boolean)
230    */

231   protected Resource demandCreateResource(URI uri)
232   {
233     return createResource(uri);
234   }
235
236   /**
237    * Loads the given resource.
238    * It is called by {@link #demandLoadHelper(Resource) demandLoadHelper(Resource)}
239    * to perform a demand load.
240    * This implementation simply calls <code>resource.</code>{@link Resource#load(Map) load}({@link #getLoadOptions() getLoadOptions}()).
241    * Clients may extend this as appropriate.
242    * @param resource a resource that isn't loaded.
243    * @exception IOException if there are serious problems loading the resource.
244    * @see #getResource(URI, boolean)
245    * @see #demandLoadHelper(Resource)
246    */

247   protected void demandLoad(Resource resource) throws IOException JavaDoc
248   {
249     resource.load(getLoadOptions());
250   }
251   
252   /**
253    * Demand loads the given resource using {@link #demandLoad(Resource)}
254    * and {@link WrappedException wraps} any {@link IOException} as a runtime exception.
255    * It is called by {@link #getResource(URI, boolean) getResource(URI, boolean)}
256    * to perform a demand load.
257    * @param resource a resource that isn't loaded.
258    * @see #demandLoad(Resource)
259    */

260   protected void demandLoadHelper(Resource resource)
261   {
262     try
263     {
264       demandLoad(resource);
265     }
266     catch (Resource.IOWrappedException exception)
267     {
268       throw new WrappedException(exception.getWrappedException());
269     }
270     catch (IOException JavaDoc exception)
271     {
272       throw new WrappedException(exception);
273     }
274   }
275
276   /**
277    * Returns a resolved resource available outside of the resource set.
278    * It is called by {@link #getResource(URI, boolean) getResource(URI, boolean)}
279    * after it has determined that the URI cannot be resolved
280    * based on the existing contents of the resource set.
281    * This implementation looks up the URI in the {#getPackageRegistry() local} package registry.
282    * Clients may extend this as appropriate.
283    * @param uri the URI
284    * @param loadOnDemand whether demand loading is required.
285    */

286   protected Resource delegatedGetResource(URI uri, boolean loadOnDemand)
287   {
288     EPackage ePackage = getPackageRegistry().getEPackage(uri.toString());
289     return ePackage == null ? null : ePackage.eResource();
290   }
291
292   /*
293    * Javadoc copied from interface.
294    */

295   public Resource getResource(URI uri, boolean loadOnDemand)
296   {
297     Map JavaDoc map = getURIResourceMap();
298     if (map != null)
299     {
300       Resource resource = (Resource)map.get(uri);
301       if (resource != null)
302       {
303         if (loadOnDemand && !resource.isLoaded())
304         {
305           demandLoadHelper(resource);
306         }
307         return resource;
308       }
309     }
310     
311     URIConverter theURIConverter = getURIConverter();
312     URI normalizedURI = theURIConverter.normalize(uri);
313     for (Iterator JavaDoc i = getResources().iterator(); i.hasNext(); )
314     {
315       Resource resource = (Resource)i.next();
316       if (theURIConverter.normalize(resource.getURI()).equals(normalizedURI))
317       {
318         if (loadOnDemand && !resource.isLoaded())
319         {
320           demandLoadHelper(resource);
321         }
322         
323         if (map != null)
324         {
325           map.put(uri, resource);
326         }
327         return resource;
328       }
329     }
330     
331     Resource delegatedResource = delegatedGetResource(uri, loadOnDemand);
332     if (delegatedResource != null)
333     {
334       if (map != null)
335       {
336         map.put(uri, delegatedResource);
337       }
338       return delegatedResource;
339     }
340
341     if (loadOnDemand)
342     {
343       Resource resource = demandCreateResource(uri);
344       if (resource == null)
345       {
346         throw new RuntimeException JavaDoc("Cannot create a resource for '" + uri + "'; a registered resource factory is needed");
347       }
348
349       demandLoadHelper(resource);
350
351       if (map != null)
352       {
353         map.put(uri, resource);
354       }
355       return resource;
356     }
357
358     return null;
359   }
360
361   /*
362    * Javadoc copied from interface.
363    */

364   public Resource createResource(URI uri)
365   {
366     Resource.Factory resourceFactory = getResourceFactoryRegistry().getFactory(uri);
367     if (resourceFactory != null)
368     {
369       Resource result = resourceFactory.createResource(uri);
370       getResources().add(result);
371       return result;
372     }
373     else
374     {
375       return null;
376     }
377   }
378
379   /*
380    * Javadoc copied from interface.
381    */

382   public Resource.Factory.Registry getResourceFactoryRegistry()
383   {
384     if (resourceFactoryRegistry == null)
385     {
386       resourceFactoryRegistry =
387         new ResourceFactoryRegistryImpl()
388         {
389           public Resource.Factory delegatedGetFactory(URI uri)
390           {
391             return Resource.Factory.Registry.INSTANCE.getFactory(uri);
392           }
393         };
394     }
395     return resourceFactoryRegistry;
396   }
397
398   /*
399    * Javadoc copied from interface.
400    */

401   public void setResourceFactoryRegistry(Resource.Factory.Registry resourceFactoryRegistry)
402   {
403     this.resourceFactoryRegistry = resourceFactoryRegistry;
404   }
405
406   /*
407    * Javadoc copied from interface.
408    */

409   public URIConverter getURIConverter()
410   {
411     if (uriConverter == null)
412     {
413       uriConverter = new URIConverterImpl();
414     }
415     return uriConverter;
416   }
417
418   /*
419    * Javadoc copied from interface.
420    */

421   public void setURIConverter(URIConverter uriConverter)
422   {
423     this.uriConverter = uriConverter;
424   }
425
426   /*
427    * Javadoc copied from interface.
428    */

429   public EPackage.Registry getPackageRegistry()
430   {
431     if (packageRegistry == null)
432     {
433       packageRegistry = new EPackageRegistryImpl(EPackage.Registry.INSTANCE);
434     }
435     return packageRegistry;
436   }
437
438   /*
439    * Javadoc copied from interface.
440    */

441   public void setPackageRegistry(EPackage.Registry packageRegistry)
442   {
443     this.packageRegistry = packageRegistry;
444   }
445
446
447   /**
448    * A notifying list implementation for supporting {@link ResourceSet#getResources}.
449    */

450   protected class ResourcesEList extends NotifyingListImpl implements InternalEList
451   {
452     protected boolean isNotificationRequired()
453     {
454       return ResourceSetImpl.this.eNotificationRequired();
455     }
456
457     protected Object JavaDoc [] newData(int capacity)
458     {
459       return new Resource [capacity];
460     }
461
462     public Object JavaDoc getNotifier()
463     {
464       return ResourceSetImpl.this;
465     }
466
467     public int getFeatureID()
468     {
469       return RESOURCE_SET__RESOURCES;
470     }
471
472     protected boolean useEquals()
473     {
474       return false;
475     }
476
477     protected boolean hasInverse()
478     {
479       return true;
480     }
481
482     protected boolean isUnique()
483     {
484       return true;
485     }
486
487     protected NotificationChain inverseAdd(Object JavaDoc object, NotificationChain notifications)
488     {
489       Resource.Internal resource = (Resource.Internal)object;
490       return resource.basicSetResourceSet(ResourceSetImpl.this, notifications);
491     }
492
493     protected NotificationChain inverseRemove(Object JavaDoc object, NotificationChain notifications)
494     {
495       Resource.Internal resource = (Resource.Internal)object;
496       Map JavaDoc map = getURIResourceMap();
497       if (map != null)
498       {
499         for (Iterator JavaDoc i = map.values().iterator(); i.hasNext();)
500         {
501           if (resource == i.next())
502           {
503             i.remove();
504           }
505         }
506       }
507       return resource.basicSetResourceSet(null, notifications);
508     }
509
510     public Iterator JavaDoc basicIterator()
511     {
512       return super.basicIterator();
513     }
514
515     public ListIterator JavaDoc basicListIterator()
516     {
517       return super.basicListIterator();
518     }
519   
520     public ListIterator JavaDoc basicListIterator(int index)
521     {
522       return super.basicListIterator(index);
523     }
524
525     public List JavaDoc basicList()
526     {
527       return super.basicList();
528     }
529   }
530
531   /**
532    * Returns a standard label with the list of resources.
533    * @return the string form.
534    */

535   public String JavaDoc toString()
536   {
537     return
538       getClass().getName() + '@' + Integer.toHexString(hashCode()) +
539         " resources=" + (resources == null ? "[]" : resources.toString());
540   }
541 }
542
Popular Tags