diff options
Diffstat (limited to 'bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository')
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 |