/*******************************************************************************
* Copyright (c) 2009, 2010 Fraunhofer IWU 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:
* Fraunhofer IWU - initial API and implementation
*******************************************************************************/
package net.enilink.komma.model;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import net.enilink.komma.core.URI;
import net.enilink.komma.model.base.IURIMapRuleSet;
import net.enilink.komma.model.base.URIHandler;
import org.xml.sax.ContentHandler;
/**
* A converter to normalize a URI or to produce an input or output stream for a
* URI.
* <p>
* A model set provides {@link ResourceSet#getURIConverter one} of these for use
* by it's {@link IModelSet#getModels models} when they are
* {@link IModel#save(java.util.Map) serialized} and
* {@link IModel#load(java.util.Map) deserialized}. A model set also uses this
* directly when it {@link IModelSet#getModel looks up} a model: a model is
* considered a match if {@link IModel#getURI it's URI}, and the URI being
* looked up, {@link #normalize normalize} to {@link URI#equals(Object) equal}
* URIs. Clients must extend the default implementation}, since methods can and
* will be added to this API.
* </p>
*
* @see IModelSet#getURIConverter()
* @see URIHandler
* @see ContentHandler
*/
public interface IURIConverter {
/**
* An option used to pass the calling URIConverter to the {@link URIHandler}
* s.
*/
String OPTION_URI_CONVERTER = "URI_CONVERTER";
/**
* An option to pass a {@link Map Map<Object, Object>} to any of the URI
* converter's methods in order to yield results in addition to the returned
* value of the method.
*/
String OPTION_RESPONSE = "RESPONSE";
/**
* A property of the {@link #OPTION_RESPONSE response option} used to yield
* the {@link #ATTRIBUTE_TIME_STAMP time stamp} associated with the creation
* of an {@link #createInputStream(URI, Map) input} or an
* {@link #createOutputStream(URI, Map) output} stream. This is typically
* used by resource {@link IModel#load(Map) load} and
* {@link IModel#save(Map) save} in order to set the
* {@link IModel#getTimeStamp()}.
*/
String RESPONSE_TIME_STAMP_PROPERTY = "TIME_STAMP";
/**
* A property of the {@link #OPTION_RESPONSE response option} used to yield
* the {@link #ATTRIBUTE_MIME_TYPE MIME-type} associated with the creation
* of an {@link #createInputStream(URI, Map) input} or an
* {@link #createOutputStream(URI, Map) output} stream.
*/
String RESPONSE_MIME_TYPE_PROPERTY = "MIME_TYPE";
/**
* Returns the normalized form of the URI.
* <p>
* This may, in theory, do absolutely anything. Default behaviour includes
* applying URI {@link IURIConverter#getURIMap mapping}, assuming
* <code>"file:"</code> protocol for a {@link URI#isRelative relative} URI
* with a {@link URI#hasRelativePath relative path}:
*
* <pre>
* ./WhateverDirectory/Whatever.file
* ->
* file:./WhateverDirectory/Whatever.file
* </pre>
*
* and assuming <code>"platform:/resource"</code> protocol for a relative
* URI with an {@link URI#hasAbsolutePath absolute path}:
*
* <pre>
* /WhateverRelocatableProject/Whatever.file
* ->
* platform:/resource/WhateverRelocatableProject/Whatever.file
* </pre>
*
* </p>
* <p>
* It is important to emphasize that normalization can result it loss of
* information. The normalized URI should generally be used only for
* comparison and for access to input or output streams.
* </p>
*
* @param uri
* the URI to normalize.
* @return the normalized form.
* @see org.eclipse.emf.ecore.plugin.EcorePlugin#getPlatformResourceMap
*/
URI normalize(URI uri);
/**
* Returns the map used for remapping a logical URI to a physical URI when
* {@link #normalize normalizing}.
* <p>
* An implementation will typically also delegate to the
* {@link IURIConverter#URI_MAP global} map, so registrations made in this
* map are <em>local</em> to this URI converter, i.e., they augment or
* override those of the global map.
* </p>
* <p>
* The map generally specifies instance to instance mapping, except for the
* case that both the key URI and the value URI end with "/", which
* specifies a folder to folder mapping. A folder mapping will remap any URI
* that has the key as its {@link URI#replacePrefix prefix}, e.g., if the
* map contains:
*
* <pre>
* http://www.example.com/ -> platform:/resource/example/
* </pre>
*
* then the URI
*
* <pre>
* http://www.example.com/a/b/c.d
* </pre>
*
* will map to
*
* <pre>
* platform:/resource/example/a/b/c.d
* </pre>
*
* A matching instance mapping is considered first. If there isn't one, the
* folder mappings are considered starting with the
* {@link URI#segmentCount() longest} prefix.
* </p>
*
* @see #normalize(URI)
* @see #URI_MAP
* @return the map used for remapping a logical URI to a physical URI.
*/
IURIMapRuleSet getURIMapRules();
void setURIMapRules(IURIMapRuleSet uriMapRules);
/**
* Returns the list of {@link IURIHandler}s.
*
* @return the list of {@link IURIHandler}s.
*/
Collection<IURIHandler> getURIHandlers();
/**
* Returns the first URI handler in the {@link #getURIHandler(URI) list} of
* URI handlers which {@link IURIHandler#canHandle(URI) can handle} the
* given URI.
*
* @param uri
* the URI for which to find a handler.
* @return the first URI handler in the list of URI handlers which can
* handle the given URI.
* @throws RuntimeException
* if no matching handler is found.
*/
IURIHandler getURIHandler(URI uri);
/**
* Returns the list of {@link IContentHandler}s.
*
* @return the list of {@link IContentHandler}s.
*/
Collection<IContentHandler> getContentHandlers();
/**
* Creates an input stream for the URI and returns it; it has the same
* effect as calling {@link #createInputStream(URI, Map)
* createInputStream(uri, null)}.
*
* @param uri
* the URI for which to create the input stream.
* @return an open input stream.
* @exception IOException
* if there is a problem obtaining an open input stream.
* @see #createInputStream(URI, Map)
*/
InputStream createInputStream(URI uri) throws IOException;
/**
* Creates an input stream for the URI and returns it.
* <p>
* It {@link #normalize normalizes} the URI and uses that as the basis for
* further processing. Special requirements, such as an Eclipse file
* refresh, are handled by the
* {@link net.enilink.komma.test.model.base.ExtensibleURIConverter.ecore.resource.impl.ExtensibleURIConverterImpl
* default implementation}.
* </p>
*
* @param uri
* the URI for which to create the input stream.
* @param options
* a map of options to influence the kind of stream that is
* returned; unrecognized options are ignored and
* <code>null</code> is permitted.
* @return an open input stream.
* @exception IOException
* if there is a problem obtaining an open input stream.
*/
InputStream createInputStream(URI uri, Map<?, ?> options)
throws IOException;
/**
* Creates an output stream for the URI and returns it; it has the same
* effect as calling {@link #createOutputStream(URI, Map)
* createOutputStream(uri, null)}.
*
* @return an open output stream.
* @exception IOException
* if there is a problem obtaining an open output stream.
* @see #createOutputStream(URI, Map)
*/
OutputStream createOutputStream(URI uri) throws IOException;
/**
* Creates an output stream for the URI and returns it.
* <p>
* It {@link #normalize normalizes} the URI and uses that as the basis for
* further processing. Special requirements, such as an Eclipse file
* refresh, are handled by the
* {@link net.enilink.komma.test.model.base.ExtensibleURIConverter.ecore.resource.impl.ExtensibleURIConverterImpl
* default implementation}.
* </p>
*
* @param uri
* the URI for which to create the output stream.
* @param options
* a map of options to influence the kind of stream that is
* returned; unrecognized options are ignored and
* <code>null</code> is permitted.
* @return an open output stream.
* @exception IOException
* if there is a problem obtaining an open output stream.
*/
OutputStream createOutputStream(URI uri, Map<?, ?> options)
throws IOException;
/**
* Deletes the contents of the given URI.
*
* @param uri
* the URI to consider.
* @param options
* options to influence how the contents are deleted, or
* <code>null</code> if there are no options.
* @throws IOException
* if there is a problem deleting the contents.
*/
void delete(URI uri, Map<?, ?> options) throws IOException;
/**
* Returns a map from String properties to their corresponding values
* representing a description the given URI's contents. See the
* {@link ContentHandler#contentDescription(URI, InputStream, Map, Map)
* content handler} for more details.
*
* @param uri
* the URI to consider.
* @param options
* options to influence how the content description is
* determined, or <code>null</code> if there are no options.
* @return a map from String properties to their corresponding values
* representing a description the given URI's contents.
* @throws IOException
* if there is a problem accessing the contents.
* @see ContentHandler#contentDescription(URI, InputStream, Map, Map)
*/
Map<String, ?> contentDescription(URI uri, Map<?, ?> options)
throws IOException;
/**
* Returns whether the given URI has contents. If the URI
* {@link #exists(URI, Map) exists} it will be possible to
* {@link #createOutputStream(URI, Map) create} an input stream.
*
* @param uri
* the URI to consider.
* @param options
* options to influence how the existence determined, or
* <code>null</code> if there are no options.
* @return whether the given URI has contents.
*/
boolean exists(URI uri, Map<?, ?> options);
/**
* The MIME-type {@link #getAttributes(URI, Map) attribute} of the contents
* of a URI as String value.
*/
String ATTRIBUTE_MIME_TYPE = "mimeType";
/**
* The time stamp {@link #getAttributes(URI, Map) attribute} representing
* the last time the contents of a URI were modified. The value is
* represented as Long that encodes the number of milliseconds since the
* epoch 00:00:00 GMT, January 1, 1970.
*/
String ATTRIBUTE_TIME_STAMP = "timeStamp";
/**
* A {@link #ATTRIBUTE_TIME_STAMP} value that indicates no time stamp is
* available.
*/
long NULL_TIME_STAMP = -1;
/**
* The length {@link #getAttributes(URI, Map) attribute} representing the
* number of bytes in the contents of a URI. It is represented as a Long
* value.
*/
String ATTRIBUTE_LENGTH = "length";
/**
* The read only {@link #getAttributes(URI, Map) attribute} representing
* whether the contents of a URI can be modified. It is represented as a
* Boolean value. If the URI's contents {@link #exists(URI, Map) exist} and
* it is read only, it will not be possible to
* {@link #createOutputStream(URI, Map) create} an output stream.
*/
String ATTRIBUTE_READ_ONLY = "readOnly";
/**
* The execute {@link #getAttributes(URI, Map) attribute} representing
* whether the contents of a URI can be executed. It is represented as a
* Boolean value.
*/
String ATTRIBUTE_EXECUTABLE = "executable";
/**
* The archive {@link #getAttributes(URI, Map) attribute} representing
* whether the contents of a URI are archived. It is represented as a
* Boolean value.
*/
String ATTRIBUTE_ARCHIVE = "archive";
/**
* The hidden {@link #getAttributes(URI, Map) attribute} representing
* whether the URI is visible. It is represented as a Boolean value.
*/
String ATTRIBUTE_HIDDEN = "hidden";
/**
* The directory {@link #getAttributes(URI, Map) attribute} representing
* whether the URI represents a directory rather than a file. It is
* represented as a Boolean value.
*/
String ATTRIBUTE_DIRECTORY = "directory";
/**
* An option passed as a {@link Set Set<String>} to
* {@link #getAttributes(URI, Map)} to indicate the specific attributes to
* be fetched.
*/
String OPTION_REQUESTED_ATTRIBUTES = "requestedAttributes";
/**
* Returns a map from String attributes to their corresponding values
* representing information about various aspects of the URI's state. The
* {@link #OPTION_REQUESTED_ATTRIBUTES requested attributes option} can be
* used to specify which properties to fetch; without that option, all
* supported attributes will be fetched. If the URI doesn't not support any
* particular attribute, an entry for that attribute will not be appear in
* the result.
*
* @param uri
* the URI to consider.
* @param options
* options to influence how the attributes are determined, or
* <code>null</code> if there are no options.
* @return a map from String attributes to their corresponding values
* representing information about various aspects of the URI's
* state.
*/
Map<String, ?> getAttributes(URI uri, Map<?, ?> options);
/**
* Updates the map from String attributes to their corresponding values
* representing information about various aspects of the URI's state.
* Unsupported or unchangeable attributes are ignored.
*
* @param uri
* the URI to consider.
* @param attributes
* the new values for the attributes.
* @param options
* options to influence how the attributes are updated, or
* <code>null</code> if there are no options.
* @throws IOException
* if there is a problem updating the attributes.
*/
void setAttributes(URI uri, Map<String, ?> attributes, Map<?, ?> options)
throws IOException;
}