Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository')
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/ICompositeRepository.java44
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/IRepository.java190
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/IRepositoryManager.java217
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/ArtifactDescriptorQuery.java101
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/ArtifactKeyQuery.java81
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IArtifactDescriptor.java109
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IArtifactRepository.java142
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IArtifactRepositoryManager.java150
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IArtifactRequest.java44
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IFileArtifactRepository.java35
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IProcessingStepDescriptor.java45
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/spi/AbstractArtifactRepository.java89
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/spi/ArtifactDescriptor.java145
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/spi/ArtifactRepositoryFactory.java99
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/spi/ProcessingStepDescriptor.java103
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/metadata/IMetadataRepository.java78
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/metadata/IMetadataRepositoryManager.java157
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/metadata/spi/AbstractMetadataRepository.java74
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/metadata/spi/MetadataRepositoryFactory.java119
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/spi/AbstractRepository.java136
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/spi/RepositoryReference.java58
21 files changed, 2216 insertions, 0 deletions
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/ICompositeRepository.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/ICompositeRepository.java
new file mode 100644
index 000000000..1bfada5b9
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/ICompositeRepository.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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 Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.repository;
+
+import java.net.URI;
+import java.util.List;
+
+/**
+ * @since 2.0
+ */
+public interface ICompositeRepository<T> extends IRepository<T> {
+ /**
+ *
+ * @return a list of URIs containing the locations of the children repositories
+ */
+ public abstract List<URI> getChildren();
+
+ /**
+ * Removes all child repositories
+ */
+ public abstract void removeAllChildren();
+
+ /**
+ * Removes specified URI from list of child repositories.
+ * Does nothing if specified URI is not a child repository
+ * @param child
+ */
+ public abstract void removeChild(URI child);
+
+ /**
+ * Adds a specified URI to list of child repositories.
+ * Does nothing if URI is a duplicate of an existing child repository.
+ * @param child
+ */
+ public abstract void addChild(URI child);
+}
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/IRepository.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/IRepository.java
new file mode 100644
index 000000000..c8d949853
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/IRepository.java
@@ -0,0 +1,190 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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 Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.repository;
+
+import java.net.URI;
+import java.util.Map;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.equinox.p2.query.IQueryable;
+
+/**
+ * Base interface that defines common properties that may be provided by
+ * various kinds of repositories.
+ *
+ * @noimplement This interface is not intended to be implemented by clients.
+ * @since 2.0
+ */
+public interface IRepository<T> extends IAdaptable, IQueryable<T> {
+ /**
+ * The key for a boolean property indicating that the repository
+ * is a system repository. System repositories are implementation details
+ * that are not subject to general access, hidden from the typical user, etc.
+ */
+ public static final String PROP_SYSTEM = "p2.system"; //$NON-NLS-1$
+
+ /**
+ * The key for a boolean property indicating that repository metadata is
+ * stored in compressed form. A compressed repository will have lower
+ * bandwidth cost to read when remote, but higher processing cost to
+ * uncompress when reading.
+ */
+ public static final String PROP_COMPRESSED = "p2.compressed"; //$NON-NLS-1$
+
+ /**
+ * The key for a string property providing a human-readable name for the repository.
+ */
+ public static final String PROP_NAME = "name"; //$NON-NLS-1$
+
+ /**
+ * The key for a string property providing a user-defined name for the repository.
+ * This property is never stored in the repository itself, but is instead tracked and managed
+ * by an {@link IRepositoryManager}.
+ */
+ public static final String PROP_NICKNAME = "p2.nickname"; //$NON-NLS-1$
+
+ /**
+ * The key for a string property providing a human-readable description for the repository.
+ */
+ public static final String PROP_DESCRIPTION = "description"; //$NON-NLS-1$
+
+ /**
+ * The key for a string property providing the common base URL that should
+ * be replaced with the mirror URL.
+ */
+ public static final String PROP_MIRRORS_BASE_URL = "p2.mirrorsBaseURL"; //$NON-NLS-1$
+
+ /**
+ * The key for a string property providing a URL that can return mirrors of this
+ * repository.
+ */
+ public static final String PROP_MIRRORS_URL = "p2.mirrorsURL"; //$NON-NLS-1$
+
+ /**
+ * The key for a string property containing the time when the repository was last modified.
+ */
+ public static final String PROP_TIMESTAMP = "p2.timestamp"; //$NON-NLS-1$
+
+ /**
+ * The key for a string property providing the user name to an authenticated
+ * URL. This key is used in the secure preference store for repository data.
+ * @see #PREFERENCE_NODE
+ */
+ public static final String PROP_USERNAME = "username"; //$NON-NLS-1$
+
+ /**
+ * The key for a string property providing the password to an authenticated
+ * URL. This key is used in the secure preference store for repository data.
+ * @see #PREFERENCE_NODE
+ */
+ public static final String PROP_PASSWORD = "password"; //$NON-NLS-1$
+
+ /**
+ * The node identifier for repository secure preference store.
+ */
+ public static final String PREFERENCE_NODE = "org.eclipse.equinox.p2.repository"; //$NON-NLS-1$
+
+ /**
+ * A repository type constant (value 0) representing a metadata repository.
+ */
+ public static final int TYPE_METADATA = 0;
+
+ /**
+ * A repository type constant (value 1) representing an artifact repository.
+ */
+ public static final int TYPE_ARTIFACT = 1;
+
+ /**
+ * General purpose zero-valued bit mask constant. Useful whenever you need to
+ * supply a bit mask with no bits set.
+ */
+ public static final int NONE = 0;
+
+ /**
+ * An option flag constant (value 1) indicating an enabled repository.
+ */
+ public static final int ENABLED = 1;
+
+ /**
+ * Returns the URL of the repository.
+ * TODO: Should we use URL or URI? URL requires a protocol handler
+ * to be installed in Java. Can the URL have any protocol?
+ * @return the URL of the repository.
+ */
+ public URI getLocation();
+
+ /**
+ * Returns the name of the repository.
+ * @return the name of the repository.
+ */
+ public String getName();
+
+ /**
+ * Returns a string representing the type of the repository.
+ * @return the type of the repository.
+ */
+ public String getType();
+
+ /**
+ * Returns a string representing the version for the repository type.
+ * @return the version of the type of the repository.
+ */
+ public String getVersion();
+
+ /**
+ * Returns a brief description of the repository.
+ * @return the description of the repository.
+ */
+ public String getDescription();
+
+ /**
+ * Returns the name of the provider of the repository.
+ * @return the provider of this repository.
+ */
+ public String getProvider();
+
+ /**
+ * Returns a read-only collection of the properties of the repository.
+ * @return the properties of this repository.
+ */
+ public Map<String, String> getProperties();
+
+ /**
+ * Returns <code>true</code> if this repository can be modified.
+ * @return whether or not this repository can be modified
+ */
+ public boolean isModifiable();
+
+ /**
+ * Set the name of the repository.
+ */
+ public void setName(String name);
+
+ /**
+ * Sets the description of the repository.
+ */
+ public void setDescription(String description);
+
+ /**
+ * Sets the value of the property with the given key. Returns the old property
+ * associated with that key, if any. Setting a value of <code>null</code> will
+ * remove the corresponding key from the properties of this repository.
+ *
+ * @param key The property key
+ * @param value The new property value, or <code>null</code> to remove the key
+ * @return The old property value, or <code>null</code> if there was no old value
+ */
+ public String setProperty(String key, String value);
+
+ /**
+ * Sets the name of the provider of the repository.
+ */
+ public void setProvider(String provider);
+}
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/IRepositoryManager.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/IRepositoryManager.java
new file mode 100644
index 000000000..6c0800393
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/IRepositoryManager.java
@@ -0,0 +1,217 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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 Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.repository;
+
+import org.eclipse.equinox.p2.query.IQueryable;
+
+import java.net.URI;
+import org.eclipse.equinox.internal.provisional.p2.repository.RepositoryEvent;
+
+/**
+ * The common base class for metadata and artifact repository managers.
+ * <p>
+ * A repository manager keeps track of a set of known repositories, and provides
+ * caching of these known repositories to avoid unnecessary loading of repositories
+ * from the disk or network. The manager fires {@link RepositoryEvent}s when the
+ * set of known repositories changes.
+ * </p>
+ * <p>
+ * All {@link URI} instances provided to a repository manager must be absolute.
+ * </p>
+ *
+ * @noimplement This interface is not intended to be implemented by clients.
+ * @since 2.0
+ */
+public interface IRepositoryManager<T> extends IQueryable<T> {
+ /**
+ * Constant used to indicate that all enabled repositories are of interest.
+ */
+ public static final int REPOSITORIES_ALL = 0;
+
+ /**
+ * Constant used to indicate that disabled repositories are of interest.
+ * @see #getKnownRepositories(int)
+ */
+ public static final int REPOSITORIES_DISABLED = 1 << 3;
+
+ /**
+ * Constant used to indicate that local repositories are of interest.
+ * @see #getKnownRepositories(int)
+ */
+ public static final int REPOSITORIES_LOCAL = 1 << 2;
+
+ /**
+ * Constant used to indicate that non-system repositories are of interest.
+ * @see IRepository#PROP_SYSTEM
+ * @see #getKnownRepositories(int)
+ */
+ public static final int REPOSITORIES_NON_SYSTEM = 1 << 1;
+
+ /**
+ * Constant used to indicate that system repositories are of interest.
+ * @see IRepository#PROP_SYSTEM
+ * @see #getKnownRepositories(int)
+ */
+ public static final int REPOSITORIES_SYSTEM = 1 << 0;
+
+ /**
+ * Constant used to indicate that a repository manager should only load the
+ * repository if the repository is modifiable.
+ * @see IRepository#isModifiable()
+ */
+ public static final int REPOSITORY_HINT_MODIFIABLE = 1 << 0;
+
+ /**
+ * Adds the repository at the given location to the list of repositories tracked by
+ * this repository manager. This method does not attempt to contact or load
+ * the repository, and makes no attempt to determine whether there is a valid
+ * repository at the provided location.
+ * <p>
+ * If there is a known disabled repository at the given location, it will become
+ * enabled as a result of this method. Thus the caller can be guaranteed that
+ * there is a known, enabled repository at the given location when this method returns.
+ *
+ * @param location The absolute location of the repository to add
+ * @see #isEnabled(URI)
+ */
+ public void addRepository(URI location);
+
+ /**
+ * Returns whether a repository at the given location is in the list of repositories
+ * tracked by this repository manager.
+ *
+ * @param location The absolute location of the repository to look for
+ * @return <code>true</code> if the repository is known to this manager,
+ * and <code>false</code> otherwise
+ */
+ public boolean contains(URI location);
+
+ /**
+ * Returns the artifact repository locations known to the repository manager.
+ * <p>
+ * Note that the repository manager does not guarantee that a valid repository
+ * exists at any of the returned locations at any particular moment in time.
+ * A subsequent attempt to load a repository at any of the given locations may
+ * or may not succeed.
+ *
+ * @param flags an integer bit-mask indicating which repositories should be
+ * returned. <code>REPOSITORIES_ALL</code> can be used as the mask when
+ * all enabled repositories should be returned.
+ * @return the locations of the repositories managed by this repository manager.
+ *
+ * @see #REPOSITORIES_ALL
+ * @see #REPOSITORIES_SYSTEM
+ * @see #REPOSITORIES_NON_SYSTEM
+ * @see #REPOSITORIES_LOCAL
+ * @see #REPOSITORIES_DISABLED
+ */
+ public URI[] getKnownRepositories(int flags);
+
+ /**
+ * Returns the property associated with the repository at the given URI,
+ * without loading the repository.
+ * <p>
+ * Note that some properties for a repository can only be
+ * determined when that repository is loaded. This method will return <code>null</code>
+ * for such properties. Only values for the properties that are already
+ * known by a repository manager will be returned.
+ * <p>
+ * If a client wishes to retrieve a property value from a repository
+ * regardless of the cost of retrieving it, the client should load the
+ * repository and then retrieve the property from the repository itself.
+ *
+ * @param location the absolute URI of the repository in question
+ * @param key the String key of the property desired
+ * @return the value of the property, or <code>null</code> if the repository
+ * does not exist, the value does not exist, or the property value
+ * could not be determined without loading the repository.
+ *
+ * @see IRepository#getProperties()
+ * @see #setRepositoryProperty(URI, String, String)
+ */
+ public String getRepositoryProperty(URI location, String key);
+
+ /**
+ * Sets the property associated with the repository at the given URI,
+ * without loading the repository.
+ * <p>
+ * This method stores properties in a cache in the repository manager and does
+ * not write the property to the backing repository. This is useful for making
+ * repository properties available without incurring the cost of loading the repository.
+ * When the repository is loaded, it will overwrite any conflicting properties that
+ * have been set using this method.
+ * </p>
+ * <p>
+ * To persistently set a property on a repository, clients must load
+ * the repository and call {@link IRepository#setProperty(String, String)}.
+ * </p>
+ *
+ * @param location the absolute URI of the repository in question
+ * @param key the String key of the property desired
+ * @param value the value to set the property to
+ * @see #getRepositoryProperty(URI, String)
+ * @see IRepository#setProperty(String, String)
+ */
+ public void setRepositoryProperty(URI location, String key, String value);
+
+ /**
+ * Returns the enablement value of a repository. Disabled repositories are known
+ * to the repository manager, but are never used in the context of provisioning
+ * operations. Disabled repositories are useful as a form of bookmark to indicate that a
+ * repository location is of interest, but not currently used.
+ * <p>
+ * Note that enablement is a property of the repository manager and not a property
+ * of the affected repository. The enablement of the repository is discarded when
+ * a repository is removed from the repository manager.
+ *
+ * @param location The absolute location of the repository whose enablement is requested
+ * @return <code>true</code> if the repository is enabled, and
+ * <code>false</code> if it is not enabled, or if the repository location
+ * is not known to the repository manager.
+ * @see #REPOSITORIES_DISABLED
+ * @see #setEnabled(URI, boolean)
+ */
+ public boolean isEnabled(URI location);
+
+ /**
+ * Removes the repository at the given location from the list of
+ * repositories known to this repository manager. The underlying
+ * repository is not deleted. This method has no effect if the given
+ * repository is not already known to this repository manager.
+ *
+ * @param location The absolute location of the repository to remove
+ * @return <code>true</code> if a repository was removed, and
+ * <code>false</code> otherwise.
+ */
+ public boolean removeRepository(URI location);
+
+ /**
+ * Sets the enablement of a repository. Disabled repositories are known
+ * to the repository manager, but are never used in the context of provisioning
+ * operation. Disabled repositories are useful as a form of bookmark to indicate that a
+ * repository location is of interest, but not currently used.
+ * <p>
+ * Note that enablement is a property of the repository manager and not a property
+ * of the affected repository. The enablement of the repository is discarded when
+ * a repository is removed from the repository manager.
+ * <p>
+ * This method has no effect if the given repository location is not known to the
+ * repository manager.
+ *
+ * @param location The absolute location of the repository to enable or disable
+ * @param enablement <code>true</code>to enable the repository, and
+ * <code>false</code> to disable the repository
+ * @see #REPOSITORIES_DISABLED
+ * @see #isEnabled(URI)
+ */
+ public void setEnabled(URI location, boolean enablement);
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/ArtifactDescriptorQuery.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/ArtifactDescriptorQuery.java
new file mode 100644
index 000000000..1347b8ff0
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/ArtifactDescriptorQuery.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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 Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.equinox.p2.repository.artifact;
+
+import org.eclipse.equinox.p2.metadata.VersionRange;
+
+import org.eclipse.equinox.p2.query.MatchQuery;
+import org.eclipse.equinox.p2.repository.artifact.spi.ArtifactDescriptor;
+
+/**
+ * An implementation of IArtifactQuery that matches IArtifactDescriptors
+ * @since 2.0
+ */
+public class ArtifactDescriptorQuery extends MatchQuery<IArtifactDescriptor> {
+ public static final ArtifactDescriptorQuery ALL_DESCRIPTORS = new ArtifactDescriptorQuery();
+ private VersionRange range = null;
+ private String id = null;
+ private String format = null;
+ private ArtifactDescriptor descriptor = null;
+ private IArtifactRepository repository = null;
+
+ /**
+ * The query will match descriptors with the given id, version and format
+ * If any parameter is null, that attribute will be ignored
+ * @param id - the id to match, or null
+ * @param versionRange - the version range to match or null
+ * @param format - {@link IArtifactDescriptor#FORMAT} value to match, or null
+ */
+ public ArtifactDescriptorQuery(String id, VersionRange versionRange, String format) {
+ this(id, versionRange, format, null);
+ }
+
+ /**
+ * The query will match descriptors with the given id, version range, format and repository
+ * if any parameter is null, that attribute will be ignored
+ * @param id - the id to match, or null
+ * @param versionRange - the version range to match or null
+ * @param format - {@link IArtifactDescriptor#FORMAT} value to match, or null
+ * @param repository
+ */
+ public ArtifactDescriptorQuery(String id, VersionRange versionRange, String format, IArtifactRepository repository) {
+ this.id = id;
+ this.range = versionRange;
+ this.format = format;
+ this.repository = repository;
+ }
+
+ public ArtifactDescriptorQuery() {
+ //matches everything
+ }
+
+ /**
+ * The query will match candidate descriptors where
+ * new ArtifactDescriptor(descriptor).equals(new ArtifactDescriptor(candidate))
+ * @param descriptor
+ */
+ public ArtifactDescriptorQuery(IArtifactDescriptor descriptor) {
+ this.descriptor = (descriptor.getClass() == ArtifactDescriptor.class) ? (ArtifactDescriptor) descriptor : new ArtifactDescriptor(descriptor);
+ }
+
+ public boolean isMatch(IArtifactDescriptor candidate) {
+ if (descriptor != null)
+ return matchDescriptor(candidate);
+
+ if (id != null && !id.equals(candidate.getArtifactKey().getId()))
+ return false;
+
+ if (range != null && !range.isIncluded(candidate.getArtifactKey().getVersion()))
+ return false;
+
+ if (format != null && !format.equals(candidate.getProperty(IArtifactDescriptor.FORMAT)))
+ return false;
+
+ if (repository != null && repository != candidate.getRepository())
+ return false;
+
+ return true;
+ }
+
+ protected boolean matchDescriptor(IArtifactDescriptor candidate) {
+ ArtifactDescriptor candidateDescriptor = (candidate.getClass() == ArtifactDescriptor.class) ? (ArtifactDescriptor) candidate : new ArtifactDescriptor(candidate);
+ return descriptor.equals(candidateDescriptor);
+ }
+
+ public Boolean getExcludeArtifactDescriptors() {
+ return Boolean.FALSE;
+ }
+
+ public Boolean getExcludeArtifactKeys() {
+ return Boolean.TRUE;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/ArtifactKeyQuery.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/ArtifactKeyQuery.java
new file mode 100644
index 000000000..0d48ccabf
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/ArtifactKeyQuery.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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 Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.equinox.p2.repository.artifact;
+
+import org.eclipse.equinox.p2.metadata.VersionRange;
+
+import org.eclipse.equinox.p2.metadata.IArtifactKey;
+import org.eclipse.equinox.p2.query.MatchQuery;
+
+/**
+ * An IArtifactQuery returning matching IArtifactKey objects.
+ * @since 2.0
+ */
+public class ArtifactKeyQuery extends MatchQuery<IArtifactKey> {
+ public static final ArtifactKeyQuery ALL_KEYS = new ArtifactKeyQuery();
+
+ private String id;
+ private String classifier;
+ private VersionRange range;
+ private IArtifactKey artifactKey;
+
+ /**
+ * Pass the id and/or version range to match IArtifactKeys against.
+ * Passing null results in matching any id/version
+ * @param classifier The artifact key classifier, or <code>null</code>
+ * @param id The artifact key id, or <code>null</code>
+ * @param range A version range, or <code>null</code>
+ */
+ public ArtifactKeyQuery(String classifier, String id, VersionRange range) {
+ this.id = id;
+ this.classifier = classifier;
+ this.range = range;
+ }
+
+ public ArtifactKeyQuery() {
+ //matches everything
+ }
+
+ public ArtifactKeyQuery(IArtifactKey key) {
+ this.artifactKey = key;
+ }
+
+ public boolean isMatch(IArtifactKey key) {
+ if (artifactKey != null)
+ return matchKey(key);
+
+ if (classifier != null && !key.getClassifier().equals(classifier))
+ return false;
+
+ if (id != null && !key.getId().equals(id))
+ return false;
+
+ if (range != null && !range.isIncluded(key.getVersion()))
+ return false;
+
+ return true;
+ }
+
+ protected boolean matchKey(IArtifactKey candidate) {
+ return artifactKey.equals(candidate);
+ }
+
+ // We are interested in IArtifactKey objects
+ public Boolean getExcludeArtifactKeys() {
+ return Boolean.FALSE;
+ }
+
+ // We are not interested in IArtifactDescriptor objects
+ public Boolean getExcludeArtifactDescriptors() {
+ return Boolean.TRUE;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IArtifactDescriptor.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IArtifactDescriptor.java
new file mode 100644
index 000000000..4d64628d3
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IArtifactDescriptor.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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 Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.repository.artifact;
+
+import java.util.Map;
+import org.eclipse.equinox.p2.metadata.IArtifactKey;
+
+/**
+ * An artifact descriptor describes an artifact stored in some artifact repository. The
+ * descriptor defines the artifact it contains, as well as any processing steps that
+ * must be performed when the artifact is transferred out of the repository (such
+ * as decompression, error checking, etc).
+ *
+ * @since 2.0
+ */
+public interface IArtifactDescriptor {
+
+ /**
+ * An artifact descriptor property (value "download.size") indicating the number
+ * of bytes that will be transferred when this artifact is transferred out of the repository.
+ */
+ public static final String DOWNLOAD_SIZE = "download.size"; //$NON-NLS-1$
+ /**
+ * An artifact descriptor property (value "artifact.size") indicating the size in
+ * bytes of the artifact in its native format (after processing steps have been applied).
+ */
+ public static final String ARTIFACT_SIZE = "artifact.size"; //$NON-NLS-1$
+ /**
+ * An artifact descriptor property (value "download.md5") indicating the MD5
+ * checksum of the artifact bytes that are transferred.
+ */
+ public static final String DOWNLOAD_MD5 = "download.md5"; //$NON-NLS-1$
+ /**
+ * An artifact descriptor property (value "download.contentType") indicating the
+ * content type of the artifact bytes that are transferred.
+ */
+ public static final String DOWNLOAD_CONTENTTYPE = "download.contentType"; //$NON-NLS-1$
+ /**
+ * An content type (value "application/zip") indicating the content is a zip file.
+ */
+ public static final String TYPE_ZIP = "application/zip"; //$NON-NLS-1$
+ /**
+ * An artifact descriptor property (value "artifact.md5") indicating the MD5
+ * checksum of the artifact bytes in its native format (after processing steps have
+ * been applied).
+ */
+ public static final String ARTIFACT_MD5 = "artifact.md5"; //$NON-NLS-1$
+
+ /**
+ * An artifact descriptor property (value "format") indicating the storage format
+ * of the artifact in the repository.
+ * @see #FORMAT_PACKED
+ */
+ public static final String FORMAT = "format"; //$NON-NLS-1$
+
+ /**
+ * A property value for the {@link #FORMAT} artifact descriptor property (value "packed")
+ * indicating the storage format is using pack200 compression.
+ * @see #FORMAT
+ */
+ public static final String FORMAT_PACKED = "packed"; //$NON-NLS-1$
+
+ /**
+ * Return the key for the artifact described by this descriptor.
+ * @return the key associated with this descriptor
+ */
+ public abstract IArtifactKey getArtifactKey();
+
+ /**
+ * Return the value of the given property in this descriptor <code>null</code>
+ * is returned if no such property exists
+ * @param key the property key to look for
+ * @return the value of the given property or <code>null</code>
+ */
+ public abstract String getProperty(String key);
+
+ /**
+ * Returns a read-only collection of the properties of the artifact descriptor.
+ * @return the properties of this artifact descriptor.
+ */
+ public Map<String, String> getProperties();
+
+ /**
+ * Return the list of processing steps associated with this descriptor.
+ * An empty set of steps implies that this descriptor describes a complete
+ * copy of the artifact in its native form. If one or more steps are present,
+ * they may be performed when the artifact is transferred from the repository
+ * that contains it.
+ *
+ * @return the list of processing steps for this descriptor
+ */
+ public abstract IProcessingStepDescriptor[] getProcessingSteps();
+
+ /**
+ * Return the artifact repository that holds the artifact described by this descriptor.
+ * <code>null</code> is returned if this descriptor is not held in a repository.
+ *
+ * @return the repository holding this artifact or <code>null</code> if none.
+ */
+ public abstract IArtifactRepository getRepository();
+}
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IArtifactRepository.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IArtifactRepository.java
new file mode 100644
index 000000000..fd442f9c1
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IArtifactRepository.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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 Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.repository.artifact;
+
+import java.io.OutputStream;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.equinox.p2.core.ProvisionException;
+import org.eclipse.equinox.p2.metadata.IArtifactKey;
+import org.eclipse.equinox.p2.query.IQueryable;
+import org.eclipse.equinox.p2.repository.IRepository;
+import org.eclipse.equinox.p2.repository.artifact.spi.AbstractArtifactRepository;
+
+/**
+ * A repository containing artifacts.
+ * <p>
+ * This interface is not intended to be implemented by clients. Artifact repository
+ * implementations must subclass {@link AbstractArtifactRepository} rather than
+ * implementing this interface directly.
+ * </p>
+ * @noimplement This interface is not intended to be implemented by clients.
+ * @since 2.0
+ */
+public interface IArtifactRepository extends IRepository<IArtifactKey> {
+
+ /**
+ * The return code to use when a client could/should retry a failed getArtifact() operation.
+ * For example, the repository may have additional mirrors that could be consulted.
+ */
+ public static int CODE_RETRY = 13;
+
+ /**
+ * Create an instance of IArtifactDescriptor based on the given key
+ * @param key
+ * @return a new instanceof of IArtifactDescriptor
+ */
+ public IArtifactDescriptor createArtifactDescriptor(IArtifactKey key);
+
+ /**
+ * Add the given descriptor to the set of descriptors in this repository. This is
+ * a relatively low-level operation that should be used only when the actual related
+ * content is in this repository and the given descriptor accurately describes
+ * that content.
+ * @param descriptor the descriptor to add.
+ */
+ public void addDescriptor(IArtifactDescriptor descriptor);
+
+ /**
+ * Add the given artifact descriptors to this repository
+ * @param descriptors the artifact descriptors to add
+ */
+ public void addDescriptors(IArtifactDescriptor[] descriptors);
+
+ /**
+ * Returns true if this repository contains the given descriptor.
+ * @param descriptor the descriptor to query
+ * @return true if the given descriptor is already in this repository
+ */
+ public boolean contains(IArtifactDescriptor descriptor);
+
+ /**
+ * Returns true if this repository contains the given artifact key.
+ * @param key the key to query
+ * @return true if the given key is already in this repository
+ */
+ public boolean contains(IArtifactKey key);
+
+ /**
+ * Write to the given output stream the bytes represented by the artifact descriptor processed by the processing steps of the given descriptor.
+ */
+ public IStatus getArtifact(IArtifactDescriptor descriptor, OutputStream destination, IProgressMonitor monitor);
+
+ /**
+ * Write to the given output stream the bytes represented by the artifact descriptor without processing by the steps of the given descriptor.
+ */
+ public IStatus getRawArtifact(IArtifactDescriptor descriptor, OutputStream destination, IProgressMonitor monitor);
+
+ /**
+ * Return the set of artifact descriptors describing the ways that this repository
+ * can supply the artifact associated with the given artifact key
+ * @param key the artifact key to lookup
+ * @return the descriptors associated with the given key
+ */
+ public IArtifactDescriptor[] getArtifactDescriptors(IArtifactKey key);
+
+ /**
+ * Executes the given artifact requests on this byte server.
+ * @param requests The artifact requests
+ * @param monitor
+ * @return a status object that is <code>OK</code> if requests were
+ * processed successfully. Otherwise, a status indicating information,
+ * warnings, or errors that occurred while executing the artifact requests
+ */
+ public IStatus getArtifacts(IArtifactRequest[] requests, IProgressMonitor monitor);
+
+ /**
+ * Open an output stream to which a client can write the data for the given
+ * artifact descriptor.
+ * @param descriptor the descriptor describing the artifact data to be written to the
+ * resultant stream
+ * @return the stream to which the artifact content can be written. The returned output
+ * stream may implement <code>IStateful</code>.
+ * @throws ProvisionException if the output stream could not be created. Reasons include:
+ * <ul>
+ * <li>An I/O exception occurred (@link {@link ProvisionException#REPOSITORY_FAILED_WRITE}) .</li>
+ * <li>An artifact already exists at that location ({@link ProvisionException#ARTIFACT_EXISTS}).</li>
+ * </ul>
+ */
+ public OutputStream getOutputStream(IArtifactDescriptor descriptor) throws ProvisionException;
+
+ /**
+ * Returns a queryable that can be queried for artifact descriptors contained in this repository
+ * @return The queryable of artifact descriptors
+ */
+ public IQueryable<IArtifactDescriptor> descriptorQueryable();
+
+ /**
+ * Remove the all keys, descriptors, and contents from this repository.
+ */
+ public void removeAll();
+
+ /**
+ * Remove the given descriptor and its corresponding content in this repository.
+ * @param descriptor the descriptor to remove.
+ */
+ public void removeDescriptor(IArtifactDescriptor descriptor);
+
+ /**
+ * Remove the given key and all related content and descriptors from this repository.
+ * @param key the key to remove.
+ */
+ public void removeDescriptor(IArtifactKey key);
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IArtifactRepositoryManager.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IArtifactRepositoryManager.java
new file mode 100644
index 000000000..c86defc10
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IArtifactRepositoryManager.java
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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 Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.repository.artifact;
+
+import org.eclipse.equinox.p2.core.ProvisionException;
+
+import java.net.URI;
+import java.util.Map;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.equinox.p2.metadata.IArtifactKey;
+import org.eclipse.equinox.p2.repository.IRepositoryManager;
+
+/**
+ * A metadata repository manager is used to create, access, and manipulate
+ * {@link IArtifactRepository} instances. See {@link IRepositoryManager}
+ * for a general description of the characteristics of repository managers.
+ *
+ * @noimplement This interface is not intended to be implemented by clients.
+ * @since 2.0
+ */
+public interface IArtifactRepositoryManager extends IRepositoryManager<IArtifactKey> {
+ /**
+ * The name used for obtaining a reference to the metadata repository manager service
+ */
+ public static final String SERVICE_NAME = IArtifactRepositoryManager.class.getName();
+
+ public static final IArtifactRequest[] NO_ARTIFACT_REQUEST = new IArtifactRequest[0];
+
+ /**
+ * Repository type for a simple repository based on a URL or local file system location.
+ */
+ public static final String TYPE_SIMPLE_REPOSITORY = "org.eclipse.equinox.p2.artifact.repository.simpleRepository"; //$NON-NLS-1$
+ public static final String TYPE_COMPOSITE_REPOSITORY = "org.eclipse.equinox.p2.artifact.repository.compositeRepository"; //$NON-NLS-1$
+
+ /**
+ * Return a new request to mirror the given artifact into the destination repository.
+ * @param key the artifact to mirror
+ * @param destination the destination where the artifact will be mirrored
+ * @param destinationDescriptorProperties additional properties for use in creating the repository's ArtifactDescriptor,
+ * or <code>null</code> to indicate no additional properties are needed
+ * @param destinationRepositoryProperties additional repository specific properties for use in creating the repositor's ArtifactDescriptor,
+ * , or <code>null</code> to indicate no additional properties are needed
+ * @return the newly created request object
+ */
+ public IArtifactRequest createMirrorRequest(IArtifactKey key, IArtifactRepository destination, Map<String, String> destinationDescriptorProperties, Map<String, String> destinationRepositoryProperties);
+
+ /**
+ * Creates and returns a new empty artifact repository of the given type at
+ * the given location.
+ * <p>
+ * The resulting repository is added to the list of repositories tracked by
+ * the repository manager. Clients must make a subsequent call to {@link #removeRepository(URI)}
+ * if they do not want the repository manager to remember the repository for subsequent
+ * load attempts.
+ * </p>
+ *
+ * @param location the absolute location for the new repository
+ * @param name the name of the new repository
+ * @param type the kind of repository to create
+ * @param properties the properties to set on the repository
+ * @return the newly created repository
+ * @throws ProvisionException if the repository could not be created. Reasons include:
+ * <ul>
+ * <li>The repository type is unknown.</li>
+ * <li>There was an error writing to the given repository location.</li>
+ * <li>A repository already exists at that location.</li>
+ * </ul>
+ */
+ public IArtifactRepository createRepository(URI location, String name, String type, Map<String, String> properties) throws ProvisionException;
+
+ /**
+ * Loads the repository at the given location. The location is expected to contain
+ * data that describes a valid artifact repository of a known type. If this manager
+ * already knows a repository at the given location then that repository is returned.
+ * <p>
+ * The resulting repository is added to the list of repositories tracked by
+ * the repository manager. Clients must make a subsequent call to {@link #removeRepository(URI)}
+ * if they do not want the repository manager to remember the repository for subsequent
+ * load attempts.
+ * </p>
+ *
+ * @param location the absolute location in which to look for a repository description
+ * @param monitor a progress monitor, or <code>null</code> if progress
+ * reporting is not desired
+ * @return a repository object for the given location
+ * @throws ProvisionException if the repository could not be created. Reasons include:
+ * <ul>
+ * <li>There is no existing repository at that location.</li>
+ * <li>The repository at that location could not be read.</li>
+ * </ul>
+ */
+ public IArtifactRepository loadRepository(URI location, IProgressMonitor monitor) throws ProvisionException;
+
+ /**
+ * Loads the repository at the given location. The location is expected to contain
+ * data that describes a valid artifact repository of a known type. If this manager
+ * already knows a repository at the given location then that repository is returned.
+ * <p>
+ * The resulting repository is added to the list of repositories tracked by
+ * the repository manager. Clients must make a subsequent call to {@link #removeRepository(URI)}
+ * if they do not want the repository manager to remember the repository for subsequent
+ * load attempts.
+ * </p>
+ * <p>
+ * The flags passed in should be taken as a hint for the type of repository to load. If
+ * the manager cannot load a repository that satisfies these hints, it can fail fast.
+ * </p>
+ * @param location the absolute location in which to look for a repository description
+ * @param flags - bit-wise or of flags to consider when loading the repository
+ * (currently only {@link IRepositoryManager#REPOSITORY_HINT_MODIFIABLE} is supported)
+ * @param monitor a progress monitor, or <code>null</code> if progress
+ * reporting is not desired
+ * @return a repository object for the given location
+ * @throws ProvisionException if the repository could not be created. Reasons include:
+ * <ul>
+ * <li>There is no existing repository at that location.</li>
+ * <li>The repository at that location could not be read.</li>
+ * </ul>
+ * @see IRepositoryManager#REPOSITORY_HINT_MODIFIABLE
+ */
+ public IArtifactRepository loadRepository(URI location, int flags, IProgressMonitor monitor) throws ProvisionException;
+
+ /**
+ * Refreshes the repository corresponding to the given URL. This method discards
+ * any cached state held by the repository manager and reloads the repository
+ * contents. The provided repository location must already be known to the repository
+ * manager.
+ *
+ * @param location The absolute location of the repository to refresh
+ * @param monitor a progress monitor, or <code>null</code> if progress
+ * reporting is not desired
+ * @return The refreshed metadata repository
+ * @throws ProvisionException if the repository could not be created. Reasons include:
+ * <ul>
+ * <li>The location is not known to the repository manager.</li>
+ * <li>There is no existing repository at that location.</li>
+ * <li>The repository at that location could not be read.</li>
+ * </ul>
+ */
+ public IArtifactRepository refreshRepository(URI location, IProgressMonitor monitor) throws ProvisionException;
+
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IArtifactRequest.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IArtifactRequest.java
new file mode 100644
index 000000000..bced2464c
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IArtifactRequest.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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 Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.repository.artifact;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.equinox.p2.metadata.IArtifactKey;
+
+/**
+ * Represents a request to transfer an artifact from an artifact repository. When the
+ * request is executed against a repository, it will be executed and the result
+ * of the execution will become available.
+ *
+ * @see IArtifactRepositoryManager#createMirrorRequest(IArtifactKey, IArtifactRepository, java.util.Map, java.util.Map)
+ * @see IArtifactRepository#getArtifacts(IArtifactRequest[], IProgressMonitor)
+ * @noimplement This interface is not intended to be implemented by clients.
+ * @since 2.0
+ */
+public interface IArtifactRequest {
+
+ /**
+ * Returns the key for the artifact that is being requested
+ *
+ * @return The requested artifact key
+ */
+ public IArtifactKey getArtifactKey();
+
+ /**
+ * Returns the result of the executed artifact request, or <code>null</code> if
+ * the request has never been executed. Artifact requests are executed by invoking
+ * {@link IArtifactRepository#getArtifacts(IArtifactRequest[], IProgressMonitor)}.
+ *
+ * @return The result of the previous perform call, or <code>null</code>
+ */
+ public IStatus getResult();
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IFileArtifactRepository.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IFileArtifactRepository.java
new file mode 100644
index 000000000..78a7701d3
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IFileArtifactRepository.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 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 Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.repository.artifact;
+
+import java.io.File;
+import org.eclipse.equinox.p2.metadata.IArtifactKey;
+
+/**
+ * @since 2.0
+ */
+public interface IFileArtifactRepository extends IArtifactRepository {
+ /**
+ * Return the location of the full local file corresponding to the given
+ * artifact key to the given key, or <code>null</code> if not available.
+ *
+ * @return the location of the requested artifact or<code>null</code> if not available
+ */
+ public File getArtifactFile(IArtifactKey key);
+
+ /**
+ * Return the location of the local file corresponding to the given
+ * artifact descriptor, or <code>null</code> if not available.
+ *
+ * @return the location of the requested descriptor or<code>null</code> if not available
+ */
+ public File getArtifactFile(IArtifactDescriptor descriptor);
+}
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IProcessingStepDescriptor.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IProcessingStepDescriptor.java
new file mode 100644
index 000000000..5b45e0279
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IProcessingStepDescriptor.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+* Copyright (c) 2010 EclipseSource 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:
+* EclipseSource - initial API and implementation
+******************************************************************************/
+package org.eclipse.equinox.p2.repository.artifact;
+
+/**
+ * Describes a processing step. Processing steps are pieces of code that participate
+ * in the the transfer of an artifact between artifact repositories. A step may alter
+ * the shape of the artifact from its storage format in the repository (such as performing
+ * compression), or it may perform additional checks on the transferred bytes such as
+ * checksums or signature verification.
+ *
+ * @see IArtifactDescriptor#getProcessingSteps()
+ * @since 2.0
+ */
+public interface IProcessingStepDescriptor {
+
+ /**
+ * Returns the fully qualified id of the processing step extension.
+ *
+ * @return The fully qualified processing step extension id
+ */
+ public abstract String getProcessorId();
+
+ public abstract String getData();
+
+ /**
+ * Returns whether the successful execution of this processing step is
+ * required for the transfer to be successful. If the processing step extension
+ * is not installed, or fails to execute, then the artifact transfer will fail if the
+ * step is required. Failure of optional steps will result in warnings but not prevent
+ * the transfer from succeeding.
+ *
+ * @return <code>true</code> if the transfer will fail if this step does not succeed,
+ * and <code>false</code> otherwise
+ */
+ public abstract boolean isRequired();
+
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/spi/AbstractArtifactRepository.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/spi/AbstractArtifactRepository.java
new file mode 100644
index 000000000..fd7bddb67
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/spi/AbstractArtifactRepository.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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 Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.repository.artifact.spi;
+
+import org.eclipse.equinox.p2.repository.spi.AbstractRepository;
+
+import java.io.OutputStream;
+import java.net.URI;
+import java.util.Map;
+import org.eclipse.core.runtime.*;
+import org.eclipse.equinox.p2.core.ProvisionException;
+import org.eclipse.equinox.p2.metadata.IArtifactKey;
+import org.eclipse.equinox.p2.repository.artifact.*;
+
+/**
+ * The common base class for all artifact repository implementations. Clients must
+ * subclass this class to create their own repository implementations.
+ * <p>
+ * This base class provides default implementations of all methods that modify the repository.
+ * These default methods throw an exception if {@link #isModifiable()} returns <code>false</code>.
+ * Therefore a client can implement a read-only repository by overriding only the abstract methods.
+ * @since 2.0
+ */
+public abstract class AbstractArtifactRepository extends AbstractRepository<IArtifactKey> implements IArtifactRepository {
+
+ protected AbstractArtifactRepository(String name, String type, String version, URI location, String description, String provider, Map<String, String> properties) {
+ super(name, type, version, location, description, provider, properties);
+ }
+
+ public abstract boolean contains(IArtifactDescriptor descriptor);
+
+ public abstract boolean contains(IArtifactKey key);
+
+ public abstract IStatus getArtifact(IArtifactDescriptor descriptor, OutputStream destination, IProgressMonitor monitor);
+
+ public abstract IArtifactDescriptor[] getArtifactDescriptors(IArtifactKey key);
+
+ public abstract IStatus getArtifacts(IArtifactRequest[] requests, IProgressMonitor monitor);
+
+ public abstract OutputStream getOutputStream(IArtifactDescriptor descriptor) throws ProvisionException;
+
+ public void addDescriptor(IArtifactDescriptor descriptor) {
+ assertModifiable();
+ }
+
+ public void addDescriptors(IArtifactDescriptor[] descriptors) {
+ assertModifiable();
+ }
+
+ public void removeDescriptor(IArtifactDescriptor descriptor) {
+ assertModifiable();
+ }
+
+ public void removeDescriptor(IArtifactKey key) {
+ assertModifiable();
+ }
+
+ public void removeAll() {
+ assertModifiable();
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof AbstractArtifactRepository)) {
+ return false;
+ }
+ if (URIUtil.sameURI(getLocation(), ((AbstractArtifactRepository) o).getLocation()))
+ return true;
+ return false;
+ }
+
+ public int hashCode() {
+ return (this.getLocation().toString().hashCode()) * 87;
+ }
+
+ public IArtifactDescriptor createArtifactDescriptor(IArtifactKey key) {
+ return new ArtifactDescriptor(key);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/spi/ArtifactDescriptor.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/spi/ArtifactDescriptor.java
new file mode 100644
index 000000000..8f82ba1a0
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/spi/ArtifactDescriptor.java
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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 Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.repository.artifact.spi;
+
+import java.util.Arrays;
+import java.util.Map;
+import org.eclipse.equinox.internal.p2.core.helpers.OrderedProperties;
+import org.eclipse.equinox.p2.metadata.IArtifactKey;
+import org.eclipse.equinox.p2.repository.artifact.*;
+
+/**
+ * This represents information about a given artifact stored on a particular byte server.
+ * @since 2.0
+ */
+public class ArtifactDescriptor implements IArtifactDescriptor {
+ private static final IProcessingStepDescriptor[] EMPTY_STEPS = new ProcessingStepDescriptor[0];
+
+ protected IArtifactKey key; // The key associated with this artifact
+
+ // The list of post processing steps that must be applied one the artifact once it
+ // has been downloaded (e.g, unpack, then md5 checksum, then...)
+ protected IProcessingStepDescriptor[] processingSteps = EMPTY_STEPS;
+
+ protected Map<String, String> properties = new OrderedProperties();
+ protected transient IArtifactRepository repository;
+
+ public ArtifactDescriptor(IArtifactDescriptor base) {
+ super();
+ key = base.getArtifactKey();
+ processingSteps = base.getProcessingSteps();
+ properties.putAll(base.getProperties());
+ repository = base.getRepository();
+ }
+
+ public ArtifactDescriptor(ArtifactDescriptor base) {
+ super();
+ key = base.key;
+ processingSteps = base.processingSteps;
+ properties.putAll(base.properties);
+ repository = base.repository;
+ }
+
+ public ArtifactDescriptor(IArtifactKey key) {
+ super();
+ this.key = key;
+ }
+
+ public IArtifactKey getArtifactKey() {
+ return key;
+ }
+
+ public String getProperty(String propertyKey) {
+ return properties.get(propertyKey);
+ }
+
+ public void setProperty(String key, String value) {
+ if (value == null)
+ properties.remove(key);
+ else
+ properties.put(key, value);
+ }
+
+ public void addProperties(Map<String, String> additionalProperties) {
+ properties.putAll(additionalProperties);
+ }
+
+ /**
+ * Returns a read-only collection of the properties of the artifact descriptor.
+ * @return the properties of this artifact descriptor.
+ */
+ public Map<String, String> getProperties() {
+ return OrderedProperties.unmodifiableProperties(properties);
+ }
+
+ public IProcessingStepDescriptor[] getProcessingSteps() {
+ return processingSteps;
+ }
+
+ public void setProcessingSteps(IProcessingStepDescriptor[] value) {
+ processingSteps = value == null ? EMPTY_STEPS : value;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+
+ // Other implementations of IArtifactDescriptor must not be considered equal
+ if (!(obj.getClass().equals(getClass())))
+ return false;
+
+ ArtifactDescriptor other = (ArtifactDescriptor) obj;
+ if (key == null) {
+ if (other.getArtifactKey() != null)
+ return false;
+ } else if (!key.equals(other.getArtifactKey()))
+ return false;
+
+ if (!Arrays.equals(processingSteps, other.getProcessingSteps()))
+ return false;
+
+ String format = getProperty(FORMAT);
+ String otherFormat = other.getProperty(FORMAT);
+ if (format != null ? !format.equals(otherFormat) : otherFormat != null)
+ return false;
+
+ return true;
+ }
+
+ public int hashCode() {
+ String format = getProperty(FORMAT);
+
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((key == null) ? 0 : key.hashCode());
+ result = prime * result + Arrays.asList(processingSteps).hashCode();
+ result = prime * result + (format != null ? format.hashCode() : 0);
+ return result;
+ }
+
+ public IArtifactRepository getRepository() {
+ return repository;
+ }
+
+ public void setRepository(IArtifactRepository value) {
+ repository = value;
+ }
+
+ public String toString() {
+ String format = getProperty(IArtifactDescriptor.FORMAT);
+ if (format == null)
+ return "canonical: " + key.toString(); //$NON-NLS-1$
+ return format + ": " + key.toString(); //$NON-NLS-1$
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/spi/ArtifactRepositoryFactory.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/spi/ArtifactRepositoryFactory.java
new file mode 100644
index 000000000..ead8d661c
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/spi/ArtifactRepositoryFactory.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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 Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.repository.artifact.spi;
+
+import java.net.URI;
+import java.util.Map;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.equinox.p2.core.IProvisioningAgent;
+import org.eclipse.equinox.p2.core.ProvisionException;
+import org.eclipse.equinox.p2.repository.IRepositoryManager;
+import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository;
+
+/**
+ * An artifact repository factory is responsible for creating and loading instances
+ * of a particular type of artifact repository. Factories are provided via the
+ * <tt>org.eclipse.equinox.p2.artifact.repository.artifactRepositories</tt> extension point.
+ * @since 2.0
+ */
+public abstract class ArtifactRepositoryFactory {
+
+ private IProvisioningAgent agent;
+
+ /**
+ * Creates and returns a new empty artifact repository of the given type at
+ * the given location.
+ *
+ * @param location the location for the new repository
+ * @param name the name of the new repository
+ * @param type the kind of repository to create
+ * @param properties the properties to set on the repository
+ * @return the newly created repository
+ * @throws ProvisionException if the repository could not be created. Reasons include:
+ * <ul>
+ * <li>The repository type is unknown.</li>
+ * <li>There was an error writing to the given repository location.</li>
+ * <li>A repository already exists at that location.</li>
+ * </ul>
+ */
+ public abstract IArtifactRepository create(URI location, String name, String type, Map<String, String> properties) throws ProvisionException;
+
+ /**
+ * Returns the provisioning agent associated with this factory, or <code>null</code>
+ * if this factory is not associated with an agent.
+ * @return The provisioning agent, or <code>null</code>
+ */
+ protected IProvisioningAgent getAgent() {
+ return agent;
+ }
+
+ /**
+ * Loads and returns the repository of this factory's type at the given location.
+ * <p>
+ * The error code returned in the case of failure is significant. In particular an
+ * error code of {@link ProvisionException#REPOSITORY_FAILED_READ} indicates
+ * that the location definitely identifies a repository of this type, but an error occurred
+ * while loading the repository. The repository manager will not attempt to load
+ * a repository from that location using any other factory. An error code of
+ * {@link ProvisionException#REPOSITORY_NOT_FOUND} indicates there is no
+ * repository of this type at the given location, and the repository manager is free
+ * to try again with a different repository factory.
+ * </p>
+ * <p>
+ * The flags passed in should be taken as a hint for the type of repository to load. If
+ * the factory knows it will not load a repository that satisfies these hints, it can fail
+ * fast and return null.
+ * @see IRepositoryManager#REPOSITORY_HINT_MODIFIABLE
+ * </p>
+ * @param location the location in which to look for a repository description
+ * @param flags to consider while loading the repository
+ * @param monitor a progress monitor, or <code>null</code> if progress
+ * reporting is not desired
+ * @return a repository object for the given location
+ * @throws ProvisionException if the repository could not be created. Reasons include:
+ * <ul>
+ * <li>There is no existing repository at that location.</li>
+ * <li>The repository at that location could not be read.</li>
+ * </ul>
+ */
+ public abstract IArtifactRepository load(URI location, int flags, IProgressMonitor monitor) throws ProvisionException;
+
+ /**
+ * Sets the provisioning agent associated with this repository factory. This method
+ * is called by the provisioning agent to provide access to the agent instance. This
+ * method is not intended to be called by clients.
+ *
+ * @param agent The provisioning agent
+ */
+ public void setAgent(IProvisioningAgent agent) {
+ this.agent = agent;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/spi/ProcessingStepDescriptor.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/spi/ProcessingStepDescriptor.java
new file mode 100644
index 000000000..95261f4ce
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/spi/ProcessingStepDescriptor.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+* Copyright (c) 2007, 2009 compeople AG 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:
+* compeople AG (Stefan Liebig) - initial API and implementation
+*******************************************************************************/
+package org.eclipse.equinox.p2.repository.artifact.spi;
+
+import org.eclipse.equinox.p2.repository.artifact.IProcessingStepDescriptor;
+
+/**
+ * @since 2.0
+ */
+public class ProcessingStepDescriptor implements IProcessingStepDescriptor {
+
+ private final String processorId; //the operation to be applied (e.g: unpack, md5, signature verification, etc.)
+ private final String data; //data requested for the processing (eg. expected checksum)
+ private final boolean required; //whether the step is optional or not
+
+ /**
+ * Create a processing step description.
+ *
+ * @param processorId
+ * @param data
+ * @param required
+ */
+ public ProcessingStepDescriptor(String processorId, String data, boolean required) {
+ super();
+ this.processorId = processorId;
+ this.data = data;
+ this.required = required;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.equinox.p2.repository.artifact.IProcessingStepDescriptor#getProcessorId()
+ */
+ public String getProcessorId() {
+ return processorId;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.equinox.p2.repository.artifact.IProcessingStepDescriptor#getData()
+ */
+ public String getData() {
+ return data;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.equinox.p2.repository.artifact.IProcessingStepDescriptor#isRequired()
+ */
+ public boolean isRequired() {
+ return required;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((data == null) ? 0 : data.hashCode());
+ result = prime * result + ((processorId == null) ? 0 : processorId.hashCode());
+ result = prime * result + (required ? 1231 : 1237);
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (!(obj instanceof IProcessingStepDescriptor))
+ return false;
+ final IProcessingStepDescriptor other = (IProcessingStepDescriptor) obj;
+ if (data == null) {
+ if (other.getData() != null)
+ return false;
+ } else if (!data.equals(other.getData()))
+ return false;
+ if (processorId == null) {
+ if (other.getProcessorId() != null)
+ return false;
+ } else if (!processorId.equals(other.getProcessorId()))
+ return false;
+ if (required != other.isRequired())
+ return false;
+ return true;
+ }
+
+ /**
+ * Returns a string representation of this descriptor for debugging purposes only.
+ */
+ public String toString() {
+ return "Processor: " + processorId + (required ? "(req)" : "(notReq)") + " ,data: " + data; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/metadata/IMetadataRepository.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/metadata/IMetadataRepository.java
new file mode 100644
index 000000000..88be97f9d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/metadata/IMetadataRepository.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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 Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.repository.metadata;
+
+import java.net.URI;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.equinox.p2.metadata.IInstallableUnit;
+import org.eclipse.equinox.p2.repository.IRepository;
+import org.eclipse.equinox.p2.repository.metadata.spi.AbstractMetadataRepository;
+
+/**
+ * A metadata repository stores information about a set of installable units
+ * <p>
+ * This interface is not intended to be implemented by clients. Metadata repository
+ * implementations must subclass {@link AbstractMetadataRepository} rather than
+ * implementing this interface directly.
+ * </p>
+ * @noimplement This interface is not intended to be implemented by clients.
+ * @since 2.0
+ */
+public interface IMetadataRepository extends IRepository<IInstallableUnit> {
+
+ /**
+ * Add the given installable units to this repository
+ * @param installableUnits the installable units to add
+ */
+ public void addInstallableUnits(IInstallableUnit[] installableUnits);
+
+ /**
+ * Adds a reference to another repository to this repository. When a repository
+ * is loaded by {@link IMetadataRepositoryManager}, its references
+ * are automatically added to the repository manager's set of known repositories.
+ * <p>
+ * Note that this method does not add the <b>contents</b> of the given
+ * repository to this repository, but merely adds the location of another
+ * repository to the metadata of this repository.
+ * <p>
+ * The {@link IRepository#ENABLED} option flag controls whether the
+ * referenced repository should be marked as enabled when added to the repository
+ * manager. If this flag is set, the repository will be marked as enabled when
+ * added to the repository manager. If this flag is missing, the repository will
+ * be marked as disabled.
+ *
+ * @param location the location of the repository to add
+ * @param nickname The nickname of the repository, or <code>null</code>
+ * @param type the repository type (currently either {@link IRepository#TYPE_METADATA}
+ * or {@link IRepository#TYPE_ARTIFACT}).
+ * @param options bit-wise or of option constants (currently either
+ * {@link IRepository#ENABLED} or {@link IRepository#NONE}).
+ * @see IMetadataRepositoryManager#setEnabled(URI, boolean)
+ */
+ public void addReference(URI location, String nickname, int type, int options);
+
+ /**
+ * Removes all installable units that match the given query from this repository.
+ *
+ * @param installableUnits the installable units to remove
+ * @param monitor a progress monitor, or <code>null</code> if progress
+ * reporting is not desired
+ * @return <code>true</code> if any units were actually removed, and
+ * <code>false</code> otherwise
+ */
+ public boolean removeInstallableUnits(IInstallableUnit[] installableUnits, IProgressMonitor monitor);
+
+ /**
+ * Remove all installable units from this repository.
+ */
+ public void removeAll();
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/metadata/IMetadataRepositoryManager.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/metadata/IMetadataRepositoryManager.java
new file mode 100644
index 000000000..8862e6161
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/metadata/IMetadataRepositoryManager.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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 Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.repository.metadata;
+
+import org.eclipse.equinox.p2.core.ProvisionException;
+
+import java.net.URI;
+import java.util.Map;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.equinox.p2.metadata.IInstallableUnit;
+import org.eclipse.equinox.p2.repository.IRepositoryManager;
+
+/**
+ * A metadata repository manager is used to create, access, and manipulate
+ * {@link IMetadataRepository} instances. See {@link IRepositoryManager}
+ * for a general description of the characteristics of repository managers.
+ *
+ * @noimplement This interface is not intended to be implemented by clients.
+ * @since 2.0
+ */
+public interface IMetadataRepositoryManager extends IRepositoryManager<IInstallableUnit> {
+ /**
+ * The name used for obtaining a reference to the metadata repository manager service
+ */
+ public static final String SERVICE_NAME = IMetadataRepositoryManager.class.getName();
+
+ /**
+ * Repository type for a simple repository based on a URL or local file system location.
+ */
+ public static final String TYPE_SIMPLE_REPOSITORY = "org.eclipse.equinox.p2.metadata.repository.simpleRepository"; //$NON-NLS-1$
+ public static final String TYPE_COMPOSITE_REPOSITORY = "org.eclipse.equinox.p2.metadata.repository.compositeRepository"; //$NON-NLS-1$
+
+ /**
+ * Creates and returns a new empty metadata repository of the given type at
+ * the given location.
+ * <p>
+ * The resulting repository is added to the list of repositories tracked by
+ * the repository manager. Clients must make a subsequent call to {@link #removeRepository(URI)}
+ * if they do not want the repository manager to remember the repository for subsequent
+ * load attempts.
+ * </p>
+ *
+ * @param location the absolute location for the new repository
+ * @param name the name of the new repository
+ * @param type the kind of repository to create
+ * @param properties the properties to set on the repository
+ * @return the newly created repository
+ * @throws ProvisionException if the repository could not be created. Reasons include:
+ * <ul>
+ * <li>The repository type is unknown.</li>
+ * <li>There was an error writing to the given repository location.</li>
+ * <li>A repository already exists at that location.</li>
+ * </ul>
+ */
+ public IMetadataRepository createRepository(URI location, String name, String type, Map<String, String> properties) throws ProvisionException;
+
+ /**
+ * Loads a repository corresponding to the given URL. If a repository has
+ * previously been loaded at the given location, the same cached repository
+ * may be returned.
+ * <p>
+ * The resulting repository is added to the list of repositories tracked by
+ * the repository manager. Clients must make a subsequent call to {@link #removeRepository(URI)}
+ * if they do not want the repository manager to remember the repository for subsequent
+ * load attempts.
+ * </p>
+ *
+ * @param location The absolute location of the repository to load
+ * @param monitor a progress monitor, or <code>null</code> if progress
+ * reporting is not desired
+ * @return The loaded metadata repository
+ * @throws ProvisionException if the repository could not be created. Reasons include:
+ * <ul>
+ * <li>There is no existing repository at that location.</li>
+ * <li>The repository at that location could not be read.</li>
+ * </ul>
+ */
+ public IMetadataRepository loadRepository(URI location, IProgressMonitor monitor) throws ProvisionException;
+
+ /**
+ * Loads a repository corresponding to the given URL. If a repository has
+ * previously been loaded at the given location, the same cached repository
+ * may be returned.
+ * <p>
+ * The resulting repository is added to the list of repositories tracked by
+ * the repository manager. Clients must make a subsequent call to {@link #removeRepository(URI)}
+ * if they do not want the repository manager to remember the repository for subsequent
+ * load attempts.
+ * </p>
+ * <p>
+ * The flags passed in should be taken as a hint for the type of repository to load. If
+ * the manager cannot load a repository that satisfies these hints, it can fail fast.
+ * </p>
+ * @param location The absolute location of the repository to load
+ * @param flags - bit-wise or of flags to consider when loading the repository
+ * (currently only {@link IRepositoryManager#REPOSITORY_HINT_MODIFIABLE} is supported)
+ * @param monitor a progress monitor, or <code>null</code> if progress
+ * reporting is not desired
+ * @return The loaded metadata repository
+ * @throws ProvisionException if the repository could not be created. Reasons include:
+ * <ul>
+ * <li>There is no existing repository at that location.</li>
+ * <li>The repository at that location could not be read.</li>
+ * </ul>
+ * @see IRepositoryManager#REPOSITORY_HINT_MODIFIABLE
+ */
+ public IMetadataRepository loadRepository(URI location, int flags, IProgressMonitor monitor) throws ProvisionException;
+
+ /**
+ * Refreshes the repository corresponding to the given URL. This method discards
+ * any cached state held by the repository manager and reloads the repository
+ * contents. The provided repository location must already be known to the repository
+ * manager.
+ *
+ * @param location The absolute location of the repository to refresh
+ * @param monitor a progress monitor, or <code>null</code> if progress
+ * reporting is not desired
+ * @return The refreshed metadata repository
+ * @throws ProvisionException if the repository could not be refreshed. Reasons include:
+ * <ul>
+ * <li>The location is not known to the repository manager.</li>
+ * <li>There is no existing repository at that location.</li>
+ * <li>The repository at that location could not be read.</li>
+ * </ul>
+ */
+ public IMetadataRepository refreshRepository(URI location, IProgressMonitor monitor) throws ProvisionException;
+
+ /**
+ * Validates a given URL and returns a status indicating whether a valid repository is likely
+ * to be found at the given URL. Callers must assume that the validity of a
+ * repository location cannot be completely determined until an attempt to load
+ * the repository is made.
+ *
+ * @param location The absolute location of the repository to validate
+ * @param monitor a progress monitor, or <code>null</code> if progress
+ * reporting is not desired
+ * @return A status indicating whether a valid repository is likely located at the
+ * location. A status with severity <code>OK</code> indicates that the repository is
+ * likely to be loadable, or that as much validation as could be done was successful.
+ * Reasons for a non-OK status include:
+ * <ul>
+ * <li>The specified location is not a valid repository location.</li>
+ * <li>There is no existing repository at that location.</li>
+ * <li>The repository at that location could not be read.</li>
+ * </ul>
+ */
+ public IStatus validateRepositoryLocation(URI location, IProgressMonitor monitor);
+}
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/metadata/spi/AbstractMetadataRepository.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/metadata/spi/AbstractMetadataRepository.java
new file mode 100644
index 000000000..e130ed70a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/metadata/spi/AbstractMetadataRepository.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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 Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.repository.metadata.spi;
+
+import org.eclipse.equinox.p2.metadata.Version;
+
+import org.eclipse.equinox.p2.repository.spi.RepositoryReference;
+
+import java.net.URI;
+import java.util.Map;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.equinox.p2.metadata.IInstallableUnit;
+import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
+import org.eclipse.equinox.p2.repository.spi.AbstractRepository;
+
+/**
+ * The common base class for all metadata repositories.
+ * <p>
+ * Clients may subclass this class.
+ * <p>
+ * @since 2.0
+ */
+public abstract class AbstractMetadataRepository extends AbstractRepository<IInstallableUnit> implements IMetadataRepository {
+
+ //TODO Consider removing from abstract class, this is currently an implementation detail of the simple metadata repo parser
+ public static class RepositoryState {
+ public String Name;
+ public String Type;
+ public Version Version;
+ public String Provider;
+ public String Description;
+ public URI Location;
+ public Map<String, String> Properties;
+ public IInstallableUnit[] Units;
+ public RepositoryReference[] Repositories;
+ }
+
+ public AbstractMetadataRepository() {
+ super("noName", "noType", "noVersion", null, null, null, null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ //TODO Consider removing from abstract class, this is currently an implementation detail of the simple metadata repo parser
+ public abstract void initialize(RepositoryState state);
+
+ protected AbstractMetadataRepository(String name, String type, String version, URI location, String description, String provider, Map<String, String> properties) {
+ super(name, type, version, location, description, provider, properties);
+ }
+
+ public void addInstallableUnits(IInstallableUnit[] installableUnit) {
+ assertModifiable();
+ }
+
+ public void addReference(URI repositoryLocation, String nickname, int repositoryType, int options) {
+ assertModifiable();
+ }
+
+ public void removeAll() {
+ assertModifiable();
+ }
+
+ public boolean removeInstallableUnits(IInstallableUnit[] installableUnits, IProgressMonitor monitor) {
+ assertModifiable();
+ return false;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/metadata/spi/MetadataRepositoryFactory.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/metadata/spi/MetadataRepositoryFactory.java
new file mode 100644
index 000000000..2dc550f1a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/metadata/spi/MetadataRepositoryFactory.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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 Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.repository.metadata.spi;
+
+import java.net.URI;
+import java.util.Map;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.equinox.p2.core.IProvisioningAgent;
+import org.eclipse.equinox.p2.core.ProvisionException;
+import org.eclipse.equinox.p2.repository.IRepositoryManager;
+import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
+
+/**
+ * A metadata repository factory is responsible for creating and loading instances
+ * of a particular type of metadata repository. Factories are provided via the
+ * <tt>org.eclipse.equinox.p2.metadata.repository.metadataRepositories</tt> extension point.
+ * @since 2.0
+ */
+public abstract class MetadataRepositoryFactory {
+ private IProvisioningAgent agent;
+
+ /**
+ * Creates and returns a new empty metadata repository of the given type at
+ * the given location.
+ *
+ * @param location the location for the new repository
+ * @param name the name of the new repository
+ * @param type the kind of repository to create
+ * @param properties the properties to set on the repository
+ * @return the newly created repository
+ * @throws ProvisionException if the repository could not be created. Reasons include:
+ * <ul>
+ * <li>The repository type is not supported by this factory.</li>
+ * <li>There was an error writing to the given repository location.</li>
+ * </ul>
+ */
+ public abstract IMetadataRepository create(URI location, String name, String type, Map<String, String> properties) throws ProvisionException;
+
+ /**
+ * Returns the provisioning agent associated with this factory, or <code>null</code>
+ * if this factory is not associated with an agent.
+ * @return The provisioning agent, or <code>null</code>
+ */
+ protected IProvisioningAgent getAgent() {
+ return agent;
+ }
+
+ /**
+ * Loads a repository corresponding to the given URL.
+ * <p>
+ * The error code returned in the case of failure is significant. In particular an
+ * error code of {@link ProvisionException#REPOSITORY_FAILED_READ} indicates
+ * that the location definitely identifies a repository of this type, but an error occurred
+ * while loading the repository. The repository manager will not attempt to load
+ * a repository from that location using any other factory. An error code of
+ * {@link ProvisionException#REPOSITORY_NOT_FOUND} indicates there is no
+ * repository of this type at the given location, and the repository manager is free
+ * to try again with a different repository factory.
+ * </p>
+ * <p>
+ * The flags passed in should be taken as a hint for the type of repository to load. If
+ * the factory knows it will not load a repository that satisfies these hints, it can fail
+ * fast and return null.<br>
+ * See {@link IRepositoryManager#REPOSITORY_HINT_MODIFIABLE}
+ * </p>
+ * @param location The location of the repository to load
+ * @param flags to consider while loading the repository
+ * @param monitor a progress monitor, or <code>null</code> if progress
+ * reporting is not desired
+ * @return The loaded metadata repository
+ * @throws ProvisionException if the repository could not be created. Reasons include:
+ * <ul>
+ * <li>There is no existing repository at that location.</li>
+ * <li>The repository at that location could not be read.</li>
+ * </ul>
+ */
+ public abstract IMetadataRepository load(URI location, int flags, IProgressMonitor monitor) throws ProvisionException;
+
+ /**
+ * Sets the provisioning agent associated with this repository factory.
+ * @param agent The provisioning agent
+ */
+ public void setAgent(IProvisioningAgent agent) {
+ this.agent = agent;
+ }
+
+ /**
+ * Validates a candidate repository URL and returns a status indicating the
+ * likelihood of a valid repository being located at the location. Implementors
+ * should make all attempts to validate the URL that can be made without
+ * actually loading the repository. The computation for this method must be
+ * significantly faster than loading the repository. Early detectable error
+ * conditions, such as the non-existence of the location, or an inability to read
+ * the location, should be determined in this method.
+ *
+ * @param location The location of the repository to validate
+ * @param monitor a progress monitor, or <code>null</code> if progress
+ * reporting is not desired
+ * @return A status indicating whether a valid repository is likely located at the
+ * location. A status with severity <code>OK</code> indicates that the repository is
+ * likely to be loadable, or that as much validation as could be done was successful.
+ * Reasons for a non-OK status include:
+ * <ul>
+ * <li>The specified location is not a valid repository location.</li>
+ * <li>There is no existing repository at that location.</li>
+ * <li>The repository at that location could not be read.</li>
+ * </ul>
+ */
+ public abstract IStatus validate(URI location, IProgressMonitor monitor);
+}
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/spi/AbstractRepository.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/spi/AbstractRepository.java
new file mode 100644
index 000000000..5cb14b01f
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/spi/AbstractRepository.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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 Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.repository.spi;
+
+import java.net.URI;
+import java.util.Map;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.equinox.internal.p2.core.helpers.OrderedProperties;
+import org.eclipse.equinox.p2.repository.IRepository;
+
+/**
+* AbstractRepository defines common properties that may be provided by various kinds
+* of repositories.
+* <p>
+* Clients may extend this class.
+* </p>
+* @param <T> the type of object that can be queried for in this repository
+ * @since 2.0
+*/
+public abstract class AbstractRepository<T> extends PlatformObject implements IRepository<T> {
+ protected String description;
+ protected transient URI location;
+ protected String name;
+ protected Map<String, String> properties = new OrderedProperties();
+ protected String provider;
+ protected String type;
+ protected String version;
+
+ protected AbstractRepository(String name, String type, String version, URI location, String description, String provider, Map<String, String> properties) {
+ this.name = name;
+ this.type = type;
+ this.version = version;
+ this.location = location;
+ this.description = description == null ? "" : description; //$NON-NLS-1$
+ this.provider = provider == null ? "" : provider; //$NON-NLS-1$
+ if (properties != null)
+ this.properties.putAll(properties);
+ }
+
+ /**
+ * Asserts that this repository is modifiable, throwing a runtime exception if
+ * it is not. This is suitable for use by subclasses when an attempt is made
+ * to write to a repository.
+ */
+ protected void assertModifiable() {
+ if (!isModifiable())
+ throw new UnsupportedOperationException("Repository not modifiable: " + location); //$NON-NLS-1$
+ }
+
+ /**
+ * Returns a brief description of the repository.
+ * @return the description of the repository.
+ */
+ public synchronized String getDescription() {
+ return description;
+ }
+
+ /**
+ * Returns the location of this repository.
+ * TODO: Should we use URL or URI? URL requires a protocol handler
+ * to be installed in Java. Can the URL have any protocol?
+ * @return the URL of the repository.
+ */
+ public synchronized URI getLocation() {
+ return location;
+ }
+
+ /**
+ * Returns the name of the repository.
+ * @return the name of the repository.
+ */
+ public synchronized String getName() {
+ return name;
+ }
+
+ /**
+ * Returns a read-only collection of the properties of the repository.
+ * @return the properties of this repository.
+ */
+ public synchronized Map<String, String> getProperties() {
+ return OrderedProperties.unmodifiableProperties(properties);
+ }
+
+ /**
+ * Returns the name of the provider of the repository.
+ * @return the provider of this repository.
+ */
+ public synchronized String getProvider() {
+ return provider;
+ }
+
+ /**
+ * Returns a string representing the type of the repository.
+ * @return the type of the repository.
+ */
+ public synchronized String getType() {
+ return type;
+ }
+
+ /**
+ * Returns a string representing the version for the repository type.
+ * @return the version of the type of the repository.
+ */
+ public synchronized String getVersion() {
+ return version;
+ }
+
+ public boolean isModifiable() {
+ return false;
+ }
+
+ public synchronized void setDescription(String description) {
+ this.description = description;
+ }
+
+ public synchronized void setName(String value) {
+ this.name = value;
+ }
+
+ public synchronized String setProperty(String key, String value) {
+ assertModifiable();
+ return (value == null ? properties.remove(key) : properties.put(key, value));
+ }
+
+ public synchronized void setProvider(String provider) {
+ this.provider = provider;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/spi/RepositoryReference.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/spi/RepositoryReference.java
new file mode 100644
index 000000000..b50398f41
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/spi/RepositoryReference.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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 Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.repository.spi;
+
+import java.net.URI;
+
+/**
+ * Serialization helper class for repository references.
+ * @since 2.0
+ */
+public class RepositoryReference {
+ public URI Location;
+ public int Type;
+ public int Options;
+ public String Nickname;
+
+ public RepositoryReference(URI location, String nickname, int type, int options) {
+ this.Location = location;
+ this.Type = type;
+ this.Options = options;
+ this.Nickname = nickname;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ RepositoryReference other = (RepositoryReference) obj;
+ if (Location == null) {
+ if (other.Location != null)
+ return false;
+ } else if (!Location.equals(other.Location))
+ return false;
+ if (Type != other.Type)
+ return false;
+ return true;
+ }
+
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((Location == null) ? 0 : Location.hashCode());
+ result = prime * result + Type;
+ return result;
+ }
+
+} \ No newline at end of file

Back to the top