/**
* Copyright (c) 2002-2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
*/
package org.eclipse.emf.ecore.resource;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.util.Callback;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.impl.ResourceFactoryRegistryImpl;
/**
* A persistent document.
* <p>
* A resource of an appropriate type is {@link Factory#createResource created} by a resource factory;
* a resource set indirectly {@link ResourceSet#createResource(URI) creates} a resource using such a factory.
* A resource is typically {@link #getResourceSet contained} by a resource set,
* along with related resources.
* It has a {@link #getURI URI} representing it's identity
* and that URI is {@link org.eclipse.emf.ecore.resource.URIConverter used}
* to determine where to {@link #save(Map) save} and {@link #load(Map) load}.
* It provides modeled {@link #getContents contents},
* in fact, it provides even the {@link #getAllContents tree} of modeled contents,
* as well as {@link Diagnostic diagnostics} for {@link #getErrors errors} and {@link #getWarnings other} problems.
* It may be {@link #unload unloaded} to discard the contents and the load state can be {@link #isLoaded queried}.
* {@link #isModified Modification} can be {@link #isTrackingModification tracked}, but it's expensive.
* The resource will be informed
* as objects are {@link Resource.Internal#attached attached} and {@link Resource.Internal#detached detached};
* if needed, it will be able to maintain a map to support {@link #getEObject getEObject}.
* Structured URI {@link #getURIFragment fragments} are used rather than IDs, since they are a more general alternative.
* Clients must extend the default {@link org.eclipse.emf.ecore.resource.impl.ResourceImpl implementation},
* or one of its derived classes,
* since methods can and will be added to this API.
* </p>
* <p>
* A resource produces notification for changes to the value of each of these features:
* <ul>
* <li>{@link #getResourceSet}</li>
* <li>{@link #getURI}</li>
* <li>{@link #getTimeStamp()}</li>
* <li>{@link #getContents}</li>
* <li>{@link #isModified}</li>
* <li>{@link #isLoaded}</li>
* <li>{@link #isTrackingModification}</li>
* <li>{@link #getErrors}</li>
* <li>{@link #getWarnings}</li>
* </ul>
* </p>
* @see org.eclipse.emf.common.notify
* @see org.eclipse.emf.ecore.resource.impl.ResourceImpl
* @see Factory
* @see ResourceSet
* @see URIConverter
*/
public interface Resource extends Notifier
{
/**
* The {@link #getResourceSet} feature {@link org.eclipse.emf.common.notify.Notification#getFeatureID ID}.
*/
int RESOURCE__RESOURCE_SET = 0;
/**
* The {@link #getURI} feature {@link org.eclipse.emf.common.notify.Notification#getFeatureID ID}.
*/
int RESOURCE__URI = 1;
/**
* The {@link #getContents} feature {@link org.eclipse.emf.common.notify.Notification#getFeatureID ID}.
*/
int RESOURCE__CONTENTS = 2;
/**
* The {@link #isModified} feature {@link org.eclipse.emf.common.notify.Notification#getFeatureID ID}.
*/
int RESOURCE__IS_MODIFIED = 3;
/**
* The {@link #isLoaded} feature {@link org.eclipse.emf.common.notify.Notification#getFeatureID ID}.
*/
int RESOURCE__IS_LOADED = 4;
/**
* The {@link #isTrackingModification} feature {@link org.eclipse.emf.common.notify.Notification#getFeatureID ID}.
*/
int RESOURCE__IS_TRACKING_MODIFICATION = 5;
/**
* The {@link #getErrors} feature {@link org.eclipse.emf.common.notify.Notification#getFeatureID ID}.
*/
int RESOURCE__ERRORS = 6;
/**
* The {@link #getWarnings} feature {@link org.eclipse.emf.common.notify.Notification#getFeatureID ID}.
*/
int RESOURCE__WARNINGS = 7;
/**
* The {@link #getTimeStamp()} feature {@link org.eclipse.emf.common.notify.Notification#getFeatureID ID}.
* @since 2.4
*/
int RESOURCE__TIME_STAMP = 8;
/**
* Specify a {@link URIConverter.Cipher} to encrypt and decrypt the resource content.
*/
String OPTION_CIPHER = "CIPHER";
/**
* Specify whether the content of the resource should be zipped during save and unzip
* during load. The default value is <tt>Boolean.FALSE</tt>
*/
String OPTION_ZIP = "ZIP";
/**
* A save option that can be used only with {@link #save(Map)}
* to specify that the resource is to be saved only if the new contents
* are different from actual contents;
* this compares the bytes in the backing store against the new bytes that would be saved.
* The value on this option can be either <code>null</code>,
* {@link #OPTION_SAVE_ONLY_IF_CHANGED_FILE_BUFFER},
* or {@link #OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER}.
* @since 2.3
*/
String OPTION_SAVE_ONLY_IF_CHANGED = "SAVE_ONLY_IF_CHANGED";
/**
* A value for {@link #OPTION_SAVE_ONLY_IF_CHANGED}
* to specify that an in-memory buffer should be used to compare the new contents with the actual contents.
* This will be faster than {@link #OPTION_SAVE_ONLY_IF_CHANGED_FILE_BUFFER} but will use up more memory.
* @since 2.3
*/
String OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER = "MEMORY_BUFFER";
/**
* A value for {@link #OPTION_SAVE_ONLY_IF_CHANGED}
* to specify that a file buffer should be used to compare the new contents with the actual contents.
* This will be slower than {@link #OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER} but will use up less memory.
* @since 2.3
*/
String OPTION_SAVE_ONLY_IF_CHANGED_FILE_BUFFER = "FILE_BUFFER";
/**
* Returns the containing resource set.
* A resource is contained by a resource set
* if it appears in the {@link ResourceSet#getResources resources}, i.e., the contents, of that resource set.
* This reference can only be modified by altering the contents of the resource set directly.
* </p>
* @return the containing resource set, or <code>null</code> if there isn't one.
* @see EObject#eContainer
* @see EObject#eResource
* @see ResourceSet#getResources
*/
ResourceSet getResourceSet();
/**
* Returns the URI of this resource.
* The URI is normally expected to be {@link URI#isRelative absolute} and {@link URI#isHierarchical hierarchical};
* document-relative references will not be serialized and will not be {@link URI#resolve(URI) resolved},
* if this is not the case.
* @return the URI of this resource, or <code>null</code> if there isn't one.
* @see #setURI(URI)
* @see URI#isRelative
* @see URI#isHierarchical
*/
URI getURI();
/**
* Sets the URI of this resource.
* @param uri the new URI.
* @see #getURI
*/
void setURI(URI uri);
/**
* Returns the cached value of the {@link URIConverter#ATTRIBUTE_TIME_STAMP time stamp}
* when this resource was last {@link #load(Map) loaded} or {@link #save(Map) saved},
* or {@link URIConverter#NULL_TIME_STAMP NULL_TIME_STAMP}
* if the resource is not {@link #isLoaded() loaded}
* and the time stamp has not been {@link #setTimeStamp(long) set}.
* The return value is represented as the number of milliseconds
* since the epoch (00:00:00 GMT, January 1, 1970).
* The returned value may not be the same as the {@link URIConverter#ATTRIBUTE_TIME_STAMP actual time stamp}
* if the resource has been modified via external means since the last load or save.
* @since 2.4
* @see #setTimeStamp(long)
*/
long getTimeStamp();
/**
* Sets the value of the {@link #getTimeStamp() time stamp}.
* The time stamp is typically set indirectly via other operations on the resource
* such as {@link #load(Map) loading} and {@link #save(Map) saving}.
* @param timeStamp the new value of the time stamp.
* @since 2.4
* @see #getTimeStamp()
* @see #RESOURCE__TIME_STAMP
*/
void setTimeStamp(long timeStamp);
/**
* Returns the list of the direct content objects;
* each is of type {@link EObject}.
* <p>
* The contents may be directly modified.
* Removing an object will have the same effect as
* {@link org.eclipse.emf.ecore.util.EcoreUtil#remove(EObject) EcoreUtil.remove(EObject)}.
* Adding an object will remove it from the previous container;
* it's {@link EObject#eContainer container} will be <code>null</code>
* and it's {@link EObject#eResource resource} will the <code>this</code>.
* </p>
* @return the direct content objects.
*/
EList<EObject> getContents();
/**
* Returns a tree iterator that iterates over all the {@link #getContents direct contents} and indirect contents of this resource.
* @return a tree iterator that iterates over all contents.
* @see EObject#eAllContents
* @see ResourceSet#getAllContents
* @see org.eclipse.emf.ecore.util.EcoreUtil#getAllContents(Resource, boolean)
*/
TreeIterator<EObject> getAllContents();
/**
* Returns the URI {@link URI#fragment fragment} that,
* when passed to {@link #getEObject getEObject} will return the given object.
* <p>
* In other words,
* the following is <code>true</code> for any object contained by a resource:
*<pre>
* Resource resource = eObject.eResource();
* eObject == resource.getEObject(resource.getURIFragment(eObject))
*</pre>
* An implementation may choose to use IDs
* or to use structured URI fragments, as supported by
* {@link org.eclipse.emf.ecore.InternalEObject#eURIFragmentSegment eURIFragmentSegment}.
* </p>
* @param eObject the object to identify.
* @return the URI {@link URI#fragment fragment} for the object.
* @see #getEObject(String)
* @see org.eclipse.emf.ecore.InternalEObject#eURIFragmentSegment(org.eclipse.emf.ecore.EStructuralFeature, EObject)
*/
String getURIFragment(EObject eObject);
/**
* Returns the resolved object for the given URI {@link URI#fragment fragment}.
* <p>
* The fragment encoding will typically be that produced by {@link #getURIFragment getURIFragment}.
* </p>
* @param uriFragment the fragment to resolve.
* @return the resolved object for the given fragment, or <code>null</code> if it can't be resolved.
* @see #getURIFragment(EObject)
* @see ResourceSet#getEObject(URI, boolean)
* @see org.eclipse.emf.ecore.util.EcoreUtil#resolve(EObject, ResourceSet)
* @see org.eclipse.emf.ecore.InternalEObject#eObjectForURIFragmentSegment(String)
* @throws org.eclipse.emf.common.util.WrappedException if a problem occurs navigating the fragment.
*/
EObject getEObject(String uriFragment);
/**
* Saves the resource using the specified options.
* <p>
* Options are handled generically as feature-to-setting entries;
* the resource will ignore options it doesn't recognize.
* The options could even include things like an Eclipse progress monitor...
* </p>
* <p>
* An implementation typically uses the {@link ResourceSet#getURIConverter URI converter}
* of the {@link #getResourceSet containing} resource set
* to {@link URIConverter#createOutputStream(URI, Map) create} an output stream,
* and then delegates to {@link #save(OutputStream, Map) save(OutputStream, Map)}.
* </p>
* @param options the save options.
* @see #save(OutputStream, Map)
*/
void save(Map<?, ?> options) throws IOException;
/**
* TODO
* @param options
* @param callback
* @throws IOException
*/
void save(Map<?, ?> options, Callback<Resource> callback) throws IOException;
/**
* Loads the resource using the specified options.
* <p>
* Options are handled generically as feature-to-setting entries;
* the resource will ignore options it doesn't recognize.
* The options could even include things like an Eclipse progress monitor...
* </p>
* <p>
* An implementation typically uses the {@link ResourceSet#getURIConverter URI converter}
* of the {@link #getResourceSet containing} resource set
* to {@link URIConverter#createInputStream(URI, Map) create} an input stream,
* and then delegates to {@link #load(InputStream, Map) load(InputStream, Map)}.
* </p>
* <p>
* When the load completes, the {@link #getErrors errors} and {@link #getWarnings warnings} can be consulted.
* An implementation will typically deserialize as much of a document as possible
* while producing diagnostics for any problems that are encountered.
* </p>
* @param options the load options.
* @see #load(InputStream, Map)
*/
void load(Map<?, ?> options) throws IOException;
/**
* TODO
* @param options
* @param callback
* @throws IOException
*/
void load(Map<?, ?> options, Callback<Resource> callback) throws IOException;
/**
* Saves the resource to the output stream using the specified options.
* <p>
* Usually, {@link #save(Map) save(Map)} is called directly and it calls this.
* </p>
* @param outputStream the stream
* @param options the save options.
* @see #save(Map)
* @see #load(InputStream, Map)
*/
void save(OutputStream outputStream, Map<?, ?> options) throws IOException;
/**
* Loads the resource from the input stream using the specified options.
* <p>
* Usually, {@link #load(Map) load(Map)} is called directly and it calls this.
* </p>
* @param inputStream the stream
* @param options the load options.
* @see #load(Map)
* @see #save(OutputStream, Map)
*/
void load(InputStream inputStream, Map<?, ?> options) throws IOException;
/**
* Returns whether modification tracking is enabled.
* <p>
* If modification tracking is enabled,
* each object of the resource must be adapted in order to listen for changes.
* This will make the processing of {@link Resource.Internal#attached attached}
* and {@link Resource.Internal#detached detached } significantly more expensive.
* as well as all model editing, in general.
* </p>
* @return whether modification tracking is enabled.
*/
boolean isTrackingModification();
/**
* Sets whether modification tracking is enabled.
* <p>
* Calling this method is expensive because it walks the content {@link #getAllContents tree} to add or remove adapters.
* </p>
* @param isTrackingModification whether modification tracking is to be enabled.
*/
void setTrackingModification(boolean isTrackingModification);
/**
* Returns whether this resource has been modified.
* <p>
* A resource is set to be unmodified after it is loaded or saved.
* {@link #isTrackingModification Automatic} modification tracking is supported, but it is expensive.
* Moreover, it is a poor fit for a model that supports undoable commands,
* since an undo looks like a change when it's really exactly the opposite.
* </p>
* @return whether this resource has been modified.
* @see #setModified(boolean)
*/
boolean isModified();
/**
* Sets whether this resource has been modified.
* <p>
* A resource is automatically set to be unmodified after it is loaded or saved.
* {@link #isTrackingModification Automatic} modification tracking typically calls this directly.
* </p>
* @param isModified whether this resource has been modified.
* @see #isModified
*/
void setModified(boolean isModified);
/**
* Returns whether the resource is loaded.
* <p>
* This will be <code>false</code> when the resource is first {@link ResourceSet#createResource(URI) created}
* and will be set to <code>false</code>, when the resource is {@link #unload unloaded}.
* It will be set to <code>true</code> when the resource is {@link #load(Map) loaded}
* and when {@link #getContents contents} are first added to a resource that isn't loaded.
* Calling {@link org.eclipse.emf.common.util.BasicEList#clear clear}
* for the {@link #getContents contents} of a resource that isn't loaded,
* will set the resource to be loaded;
* this is the simplest way to create an empty resource that's considered loaded.
* </p>
* @return whether the resource is loaded.
*/
boolean isLoaded();
/**
* Clears the {@link #getContents contents},
* {@link #getErrors errors},
* and {@link #getWarnings warnings} of the resource
* and {@link #isLoaded marks} it as unloaded.
* <p>
* It walks the content {@link #getAllContents tree},
* and {@link org.eclipse.emf.ecore.InternalEObject#eSetProxyURI sets} each content object to be a proxy.
* The resource will remain in the {@link #getResourceSet resource set},
* and can be subsequently reloaded.
* </p>
*/
void unload();
/**
* {@link URIConverter#delete(URI, Map) deletes} the resource using the specified options,
* {@link #unload() unloads} it,
* and then removes it from the {@link #getResourceSet() containing} resource set.
* <p>
* Options are handled generically as feature-to-setting entries;
* the resource will ignore options it doesn't recognize.
* The options could even include things like an Eclipse progress monitor...
* </p>
* <p>
* An implementation typically uses the {@link ResourceSet#getURIConverter URI converter}
* of the {@link #getResourceSet containing} resource set
* to {@link URIConverter#delete(URI, Map)} the resource's {@link #getURI() URI}.
* </p>
*/
void delete(Map<?, ?> options) throws IOException;
/**
* TODO
* @param options
* @param callback
* @throws IOException
*/
void delete(Map<?, ?> options, Callback<Resource> callback) throws IOException;
/**
* Returns a list of the errors in the resource;
* each error will be of type {@link org.eclipse.emf.ecore.resource.Resource.Diagnostic}.
* <p>
* These will typically be produced as the resource is {@link #load(Map) loaded}.
* </p>
* @return a list of the errors in the resource.
* @see #load(Map)
*/
EList<Diagnostic> getErrors();
/**
* Returns a list of the warnings and informational messages in the resource;
* each warning will be of type {@link org.eclipse.emf.ecore.resource.Resource.Diagnostic}.
* <p>
* These will typically be produced as the resource is {@link #load(Map) loaded}.
* </p>
* @return a list of the warnings in the resource.
* @see #load(Map)
*/
EList<Diagnostic> getWarnings();
/**
* A noteworthy issue in a document.
*/
interface Diagnostic
{
/**
* Returns a translated message describing the issue.
* @return a translated message.
*/
String getMessage();
/**
* Returns the source location of the issue.
* This will typically be just the {@link Resource#getURI URI} of the resource containing this diagnostic.
* @return the location of the issue, or <code>null</code> if it's unknown.
*/
String getLocation();
/**
* Returns the line location of the issue within the source.
* Line <code>1</code> is the first line.
* @return the line location of the issue.
*/
int getLine();
/**
* Returns the column location of the issue within the source.
* Column <code>1</code> is the first column.
* @return the column location of the issue.
*/
int getColumn();
}
/**
* A factory for creating resources.
* <p>
* A factory is implemented to {@link #createResource create} a specialized type of resource
* and is typically registered in {@link Resource.Factory.Registry registry}.
* </p>
* @see ResourceSet#createResource(URI)
*/
interface Factory
{
/**
* Creates a resource with the given URI and returns it.
* <p>
* Clients will typically not call this directly themselves;
* it's called by the resource set to {@link ResourceSet#createResource(URI) create} a resource.
* </p>
* @param uri the URI.
* @return a new resource.
* @see ResourceSet#createResource(URI)
*/
Resource createResource(URI uri);
/**
* A descriptor used by a resource factory registry to defer factory creation.
* <p>
* The creation is deferred until the factory is {@link Resource.Factory.Registry#getFactory(URI) fetched} for the first time.
* </p>
* @see Resource.Factory.Registry#getFactory(URI)
*/
interface Descriptor
{
/**
* Creates a factory and returns it.
* <p>
* An implementation may and usually does choose to create only one instance,
* which it returns for each call.
* </p>
* @return a factory.
*/
Factory createFactory();
}
/**
* A registry of resource factories.
* <p>
* A registry implementation will typically delegate to the global instance, which can be used as follows
*<pre>
* Resource.Factory.Registry.{@link Resource.Factory.Registry#INSTANCE INSTANCE}.getProtocolToFactoryMap().
* put("abc", resourceFactoryForURIWithAbcProtocol);
* Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().
* put("xyz", resourceFactoryForURIWithXyzFileExtension);
*</pre>
* A {@link Resource.Factory.Descriptor descriptor} can be used in place of an actual {@link Resource.Factory factory}
* as a value in the map.
* It is used for factories registered via
* {@link org.eclipse.emf.ecore.plugin.EcorePlugin.Implementation#startup() plugin registration}
* to ensure delayed plugin load.
* </p>
* <p>
* Clients must extend the default {@link org.eclipse.emf.ecore.resource.impl.ResourceFactoryRegistryImpl implementation},
* since methods can and will be added to this API.
* </p>
* @see ResourceSet#getResourceFactoryRegistry()
*/
interface Registry
{
/**
* Returns the resource factory appropriate for the given URI.
* <p>
* An implementation will (typically) use
* the URI's {@link URI#scheme scheme} to search the {@link #getProtocolToFactoryMap protocol} map
* the URI's {@link URI#fileExtension file extension} to search {@link #getExtensionToFactoryMap extension} map,
* and the URI's {@link URIConverter#contentDescription(URI, Map) content type identifier} to search the {@link #getContentTypeToFactoryMap() content type} map.
* It will {@link org.eclipse.emf.ecore.resource.Resource.Factory.Descriptor#createFactory convert}
* a resulting descriptor into a factory.
* It may choose to provide additional mechanisms and algorithms to determine a factory appropriate for the given URI.
* </p>
* @param uri the URI.
* @return the resource factory appropriate for the given URI, or <code>null</code> if there isn't one.
* @see ResourceSet#createResource(URI)
*/
Factory getFactory(URI uri);
/**
* Returns the resource factory appropriate for the given URI
* with the given {@link URIConverter#contentDescription(URI, Map) content type} identifier.
* <p>
* An implementation will (typically) use
* the URI's {@link URI#scheme scheme} to search the {@link #getProtocolToFactoryMap protocol} map
* the URI's {@link URI#fileExtension file extension} to search {@link #getExtensionToFactoryMap extension} map,
* and the given content type identifier to search the {@link #getContentTypeToFactoryMap() content type} map.
* It will {@link org.eclipse.emf.ecore.resource.Resource.Factory.Descriptor#createFactory convert}
* a resulting descriptor into a factory.
* It may choose to provide additional mechanisms and algorithms to determine a factory appropriate for the given URI.
* </p>
* @param uri the URI.
* @param contentType the content type of the URI or <code>null</code> if a content type should not be used during lookup.
* @return the resource factory appropriate for the given URI with the content content type, or <code>null</code> if there isn't one.
* @see ResourceSet#createResource(URI)
* @since 2.4
*/
Factory getFactory(URI uri, String contentType);
/**
* Returns a map from {@link URI#scheme protocol} to
* {@link org.eclipse.emf.ecore.resource.Resource.Factory}
* or {@link org.eclipse.emf.ecore.resource.Resource.Factory.Descriptor}.
* @return the protocol map.
*/
Map<String, Object> getProtocolToFactoryMap();
/**
* The file extension <code>"*"</code> that matches any extension.
* @see #getExtensionToFactoryMap
*/
String DEFAULT_EXTENSION = "*";
/**
* Returns a map from {@link URI#fileExtension file extension} to
* {@link org.eclipse.emf.ecore.resource.Resource.Factory}
* or {@link org.eclipse.emf.ecore.resource.Resource.Factory.Descriptor}.
* <p>
* The {@link #DEFAULT_EXTENSION default} file extension <code>"*"</code>
* can be registered as a default that matches any file extension.
* This is typically reserved for a default factory that supports XMI serialization;
* clients are strongly discouraged from using this feature in the global registry,
* particularly those that must function effectively within an Eclipse environment.
* </p>
* @return the file extension map.
* @see #DEFAULT_EXTENSION
*/
Map<String, Object> getExtensionToFactoryMap();
/**
* The content type identifier <code>"*"</code> that matches any content type identifier.
* @see #getContentTypeToFactoryMap()
*/
String DEFAULT_CONTENT_TYPE_IDENTIFIER = "*";
/**
* Returns a map from content type identifier to
* {@link org.eclipse.emf.ecore.resource.Resource.Factory}
* or {@link org.eclipse.emf.ecore.resource.Resource.Factory.Descriptor}.
* <p>
* The {@link #DEFAULT_CONTENT_TYPE_IDENTIFIER default} content type identifier <code>"*"</code>
* can be registered as a default that matches any content type identifier.
* This is typically reserved for a default factory that supports XMI serialization;
* clients are strongly discouraged from using this feature in the global registry,
* particularly those that must function effectively within an Eclipse environment.
* </p>
* @return the content type identifier map.
* @see #DEFAULT_CONTENT_TYPE_IDENTIFIER
*/
Map<String, Object> getContentTypeToFactoryMap();
/**
* The global static resource factory registry.
* Registrations made in this instance will (typically) be available
* for {@link ResourceSet#createResource(URI) use} by any resource set.
* @see ResourceSet#createResource(URI)
* @see ResourceSet#getResourceFactoryRegistry()
*/
Registry INSTANCE = new ResourceFactoryRegistryImpl();
}
}
/**
* An IO exception that wraps another exception.
* <p>
* Since save and load throw an IO Exception,
* it may be convenient for an implementation to wrap another exception
* in order to throw it as an IO exception.
* </p>
*/
class IOWrappedException extends IOException
{
static final long serialVersionUID = 1L;
/**
* Creates an instance which wraps the given exception.
* @param exception the exception to wrap.
*/
public IOWrappedException(Exception exception)
{
super(exception.getLocalizedMessage());
initCause(exception);
}
/**
* Creates an instance which wraps the given exception.
* @param throwable the exception to wrap.
* @since 2.4
*/
public IOWrappedException(Throwable throwable)
{
super(throwable.getLocalizedMessage());
initCause(throwable);
}
/**
* Returns the wrapped exception.
* @return the wrapped exception.
* @deprecated in 2.2. Use {@link #getCause()} instead.
*/
@Deprecated
public Exception getWrappedException()
{
return (Exception)getCause();
}
}
/**
* An internal interface implemented by all resources.
* <p>
* It is used to maintain the referential integrity of
* the containment relation between a resource set and a resource.
* Clients must extend the default {@link org.eclipse.emf.ecore.resource.impl.ResourceFactoryRegistryImpl implementation},
* since methods can and will be added to this API.
* </p>
* @see Resource#getResourceSet
* @see ResourceSet#getResources
* @see org.eclipse.emf.ecore.InternalEObject#eBasicSetContainer(org.eclipse.emf.ecore.InternalEObject, int, NotificationChain)
* InternalEObject.eBasicSetContainer(InternalEObject, int, NotificationChain)
*/
interface Internal extends Resource
{
/**
* Called when the object is attached to this resource,
* i.e., when it's {@link EObject#eResource eResource} changes to be this one.
* <p>
* An implementation that {@link Resource#getEObject resolves} based on IDs
* will need to walk the {@link EObject#eAllContents tree} of this object
* in order to tabulate an index.
* An implementation that needs to {@link Resource#isTrackingModification track modification}
* will also need to walk the tree
* in order to add the necessary adapter.
* In either of these cases,
* editing of containment relations will be significantly more expensive.
* </p>
* @param eObject the attached object.
* @see #detached(EObject)
*/
void attached(EObject eObject);
/**
* Called when the object is detached from this resource,
* i.e., when it's {@link EObject#eResource eResource} changes to no longer be this one.
* <p>
* An implementation that {@link Resource#getEObject resolves} based on IDs
* will need to walk the {@link EObject#eAllContents tree} of this object
* in order clean up it's index.
* An implementation that needs to {@link Resource#isTrackingModification track modification}
* will also need to walk the tree
* in order to remove the added adapter.
* In either of these cases,
* editing of containment relations will be significantly more expensive.
* </p>
* @param eObject the attached object.
* @see #attached(EObject)
*/
void detached(EObject eObject);
/**
* Sets the resource to be contained by the given resource set, and returns the notifications this produces.
* <p>
* If it was previously contained by a resource set, it will have been removed.
* </p>
* @return the notifications produced, or <code>null</code> if there aren't any.
*/
NotificationChain basicSetResourceSet(ResourceSet resourceSet, NotificationChain notifications);
/**
* Indicates whether the resource is currently being loaded.
* <p>
* This will be <code>true</code> during a call to {@link #load(InputStream, Map) load(InputStream, Map)},
* before notifications are dispatched.
* </p>
* @return whether this resource is currently being loaded.
*/
boolean isLoading();
}
}