krysalis-update/src/java/org/krysalis/depot/update Artifact.java,NONE,1.1 Repository.java,NONE,1.1 ArtifactUpdaterOptions.java,NONE,1.1 package.html,NONE,1.1 UpdateRuntimeException.java,NONE,1.1 ArtifactInstance.java,NONE,1.1 AntUtils.java,NONE,1.1 UpdateException.java,NONE,1.1 ArtifactUpdaterFactory.java,NONE,1.1 ArtifactUpdater.java,NONE,1.1 RepositoryManifest.java,NONE,1.1

Nick Chalko <[email protected]> Wed, 08 Dec 2004 09:06:31 +0000
Newsgroups gmane.comp.krysalis.cvs
Message-ID <[email protected]>
Update of /cvsroot/krysalis/krysalis-update/src/java/org/krysalis/depot/update
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24726/src/java/org/krysalis/depot/update

Added Files:
	Artifact.java Repository.java ArtifactUpdaterOptions.java 
	package.html UpdateRuntimeException.java ArtifactInstance.java 
	AntUtils.java UpdateException.java ArtifactUpdaterFactory.java 
	ArtifactUpdater.java RepositoryManifest.java 
Log Message:
Copied from the apache incubator.

--- NEW FILE: UpdateException.java ---
/*
 * Copyright  2004 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.krysalis.depot.update;

import org.krysalis.depot.common.util.throwable.PortableException;


public class UpdateException extends PortableException {

	/**
	 * @param message the user message
	 */
	public UpdateException(final String message) {
		super(message);
	}

	/**
	 * @param message the user message
	 * @param throwable the cause
	 */
	public UpdateException(final String message, final Throwable throwable) {
		super(message, throwable);
	}

	/**
	 * @param throwable the cause
	 */
	public UpdateException(final Throwable throwable) {
		super(throwable);
	}
}

--- NEW FILE: ArtifactUpdater.java ---
/*
 * Copyright  2004 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.krysalis.depot.update;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.krysalis.depot.common.log.Logger;
import org.krysalis.depot.update.artifact.ArtifactGroup;
import org.krysalis.depot.update.download.DownloadManager;
import org.krysalis.depot.update.impl.ArtifactUpdaterContext;
import org.krysalis.depot.update.impl.RepositorySetWrapper;
import org.krysalis.depot.update.impl.RepositoryWrapper;
import org.krysalis.depot.update.protocols.DefaultProtocolOperationsManager;
import org.krysalis.depot.update.query.ArtifactQuery;
import org.krysalis.depot.update.query.ArtifactQueryHelper;
import org.krysalis.depot.update.query.ArtifactResult;
import org.krysalis.depot.update.query.ArtifactResultHelper;
import org.krysalis.depot.update.query.QueryEngine;
import org.krysalis.depot.update.repository.RepositoryException;
import org.krysalis.depot.update.repository.RepositorySet;
import org.krysalis.depot.update.util.UpdateConstants;
import org.krysalis.depot.update.util.identity.GenericIdentifier;
import org.krysalis.depot.update.util.reference.IReferenceable;
import org.krysalis.depot.update.util.text.MessageConstants;
import org.krysalis.depot.update.util.text.Messages;

/**
 * An ArtifactUpdater is the main (low level) API into Depot.
 * 
 * @see DefaultArtifactUpdater, StandardResourceUpdater
 * 
 * @author arb_jack
 */
public class ArtifactUpdater implements IReferenceable {
	
	public static class Identifier extends GenericIdentifier {

		public static final String UPDATER_URI =
			"http://depot.apache.org/update";
		public static final String UPDATER_PREFIX = "update";

		public Identifier(final String id) {
			super(UPDATER_URI, UPDATER_PREFIX, id);
		}
	}

	// The identity...
	private ArtifactUpdater.Identifier m_identifier;
	
	// Context:
	ArtifactUpdaterContext m_context;

	// Options for configuring the Updater
	private Map m_artifactConfigOptions = new HashMap();

	// Query Engine
	private QueryEngine m_queryEngine;
	
	// Download Manager
	private DownloadManager m_downloadManager;

	// Repository pool
	private RepositorySet m_repositorySet;
	
	// Target repository
	private Repository m_targetRepository;

	/**
	 * Construct an unnamed ArtifactUpdater (the default) 
	 * @param id the public name
	 * @throws UpdateException
	 */
	public ArtifactUpdater() {
		m_identifier = new ArtifactUpdater.Identifier(UpdateConstants.DEFAULT);
		initClass();
		artifactConfigInit();
	}

	/**
	 * Construct a named ArtifactUpdater
	 * @param id the public name
	 * @throws UpdateException
	 */
	public ArtifactUpdater(String id) throws UpdateException {
		this(new ArtifactUpdater.Identifier(id));
	}

	/**
	 * Construct a named ArtifactUpdater 
	 * @param id the public name
	 * @throws UpdateException
	 */
	public ArtifactUpdater(ArtifactUpdater.Identifier id)
		throws UpdateException {
		m_identifier = id;
		initClass();
		artifactConfigInit();
	}

	private void initClass() {
		if (null == m_context)
			m_context = ArtifactUpdaterContext.getDefaultContext();

		// How to perform Queries...
		m_queryEngine = new QueryEngine();

		// Protocol operations..
		if (!getContext().hasProtocolManager() )
		getContext().setProtocolManager(
			new DefaultProtocolOperationsManager(getContext()));
		
		m_repositorySet = RepositorySet.getDefaultRepositorySet();
		
		// How to perform downloads
		m_downloadManager = new DownloadManager(getContext());
	}
	
	/**
	 * Configure the updater
	 *
	 */
	private void artifactConfigInit() {
		//TODO put the options like "BestOfAll", "ReleaseOnly"
		// and the selector / comparator for it	
	}

	/**
	 * @return
	 */
	public GenericIdentifier getIdentifier() {
		return m_identifier;
	}

	/**
	 * Access configuration options
	 * @return
	 */
	public Set getArtifactConfigOptions() {
		return m_artifactConfigOptions.keySet();
	}

	/** 
	 * Access the context (files/protocols handle) this runs within.
	 * 
	 * @return
	 */
	public ArtifactUpdaterContext getContext() {
		return m_context;
	}

	/* (non-Javadoc)
	 */
	public ArtifactInstance getInstance(Artifact artifact) throws UpdateException {
		
		// get the artifact specifier query
		ArtifactQuery artifactQuery =
				ArtifactQueryHelper.getArtifactQuery(artifact, m_repositorySet);
		
		List localInstances = get(artifactQuery);
		//This always a list of lists  (ie grouped)
		final List list = (List)localInstances.get(0);
		return (ArtifactInstance)list.get(0);
	}

	/* (non-Javadoc)
	 */
	public List getArtifacts(ArtifactGroup group)
		throws UpdateException {
	
		if (group == null) {
			String message = Messages.getString(MessageConstants.NULL_GROUP);
			Logger.getLogger().error(message);

			throw new UpdateException(message);
		}
		
		// get the artifact specifier query
		ArtifactQuery artifactQuery =
				ArtifactQueryHelper.getArtifactGroupQuery(group, m_repositorySet);
		
		return get(artifactQuery); 
	}

	/**
	 * Perform the query, download the updates (if any) to the local (target)
	 * repository, and return the instances (in that local repository).
	 * 
	 * @param artifactQuery
	 * @throws UpdateException
	 */
	public List get(ArtifactQuery artifactQuery)
		throws UpdateException {
		// Query the repositories to get the result	
		ArtifactResult artifactResult = query(artifactQuery);

		// Query the target repository to get the result
		artifactQuery.setRepositorySet(new RepositorySet(m_targetRepository));
		ArtifactResult targetResult = query(artifactQuery);

		// Sort the two result sets
		List updates =
			orderResults(artifactQuery, artifactResult, targetResult);
		
		// Copy the artifact to the local repository
		if (updates != null)
			m_downloadManager.downloadTo(updates, m_targetRepository);
		
		// Query again (once downloaded)
		return query(artifactQuery);
	}

	private ArtifactResult query(ArtifactQuery query) throws UpdateException {
		RepositorySet repositorySet = query.getRepositorySet();

		RepositorySetWrapper wrappers =
			new RepositorySetWrapper(repositorySet, m_context); 

		return m_queryEngine.queryRepositories(wrappers, query);
	}
	
	/**
	 * Sort results using the ORDER_BY clause of the query.
	 * 
	 * @param artifactQuery The query containing the order_by portion
	 * @param artifactResult The result set
	 * @param targetResult The (local|target) result set
	 * @return
	 */
	private List orderResults(
		ArtifactQuery artifactQuery,
		ArtifactResult artifactResult,
		ArtifactResult targetResult) {

		List artifacts = null;
		
		// Assuming we found something in the main search repositories...
		if (!ArtifactResultHelper.noResult(artifactResult)) {
			// Compare Results Set using the OrderBy Comparator	
			if (ArtifactResultHelper
				.compareTo(
					artifactResult,
					targetResult,
					artifactQuery.getOrderBy())
				> 0) {

				artifacts =
					ArtifactResultHelper.getArtifactList(artifactResult);

				// Got something
				Logger.getLogger().verbose(
					Messages.getString(
						MessageConstants.UPDATE_FOUND,
						artifacts));
			}
			else
				// Nothing to update
				Logger.getLogger().verbose(
					Messages.getString(
						MessageConstants.NO_UPDATE_FOUND,
						artifactQuery));
		}
		else
			// Nothing found
			Logger.getLogger().verbose(
				Messages.getString(
					MessageConstants.NO_RESOURCES_FOUND,
					artifactQuery));

		return artifacts;
	}

	public void cleanTarget(ArtifactGroup group) throws UpdateException {
		cleanRepository(m_targetRepository, group);
	}

	public void cleanRepository(Repository repository, ArtifactGroup group)
		throws UpdateException {

		// Query & sort by version
		//		get the artifact specifier query
		ArtifactQuery artifactQuery =
			ArtifactQueryHelper.getArtifactGroupQuery(group);

		// Where to look
		artifactQuery.setRepositorySet(new RepositorySet(repository));

		// Query the repositories to get the result	
		ArtifactResult artifactResult = query(artifactQuery);
		List olderArtifacts =
			ArtifactResultHelper.getRemainderArtifacts(artifactResult);

		//DebugUtils.dump("Older Artifacts", olderArtifacts);

		// Delete all but 'best'
		delete(repository, olderArtifacts);
	}
	
	private void delete(Repository repository, List artifacts)
		throws UpdateException {

		RepositoryWrapper repo =
			new RepositoryWrapper(repository, m_context);

		for (Iterator i = artifacts.iterator(); i.hasNext();) {
			ArtifactInstance artifact = (ArtifactInstance) i.next();
			try {
				repo.deleteArtifact(artifact);
			}
			catch (Exception e) {
				//
				// (1) log (2) stash in result set error table
				//
				throw new RepositoryException(
					repository,
					"Failed to delete artifact: " + artifact,
					e);
			}
		}
	}


	/**
	 * @param repository
	 */
	public void setTargetRepository(Repository repository) {
		m_targetRepository = repository;
	}
	/**
	 * @return
	 */
	public Repository getTargetRepository() {
		return m_targetRepository;
	}

	/**
	 * @return Returns the repositorySet.
	 */
	public RepositorySet getRepositorySet() {
		return m_repositorySet;
	}
	/**
	 * @param repositorySet The repositorySet to set.
	 */
	public void setRepositorySet(RepositorySet repositorySet) {
		m_repositorySet = repositorySet;
	}
}

--- NEW FILE: Repository.java ---
/*
 * Copyright  2004 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.krysalis.depot.update;

import java.util.List;
import java.util.Map;

import org.krysalis.depot.update.artifact.ArtifactGroup;
import org.krysalis.depot.update.impl.ArtifactUpdaterContext;
import org.krysalis.depot.update.repository.RepositoryCapability;
import org.krysalis.depot.update.repository.RepositoryCapabilitySet;
import org.krysalis.depot.update.util.identity.GenericIdentifier;
import org.krysalis.depot.update.util.net.VirtualResourceLocator;
import org.krysalis.depot.update.util.reference.IReferenceable;
import org.krysalis.depot.update.util.select.ISelector;

/**
 * The main interface for the implementation of a Repository
 * 
 */
public interface Repository extends IReferenceable {
	public static class Identifier extends GenericIdentifier {

		public final static String REPO_URI =
			"http://apache.org/repository/";
		public final static String REPO_PREFIX = "repo";

		public Identifier(String id) {
			super(REPO_URI, REPO_PREFIX, id);
		}
	}
	/**
	* Determines if this set has a particular capability.
	*
	* @param capability The capability to check for.
	*/
	boolean hasCapability(RepositoryCapability capability);

	/**
	* Determines if this set has a particular set of capability.
	*
	* @param capability The capabilities to check for.
	*/
	boolean hasCapabilities(RepositoryCapabilitySet capabilities);

	/**
	* Return a map of capabilities.
	*
	* @param capability The capabilities to check for.
	*/
	Map getAttributes();

	/**
	 * Initialize oneself (within this context)
	 * 
	 * @param context
	 */
	void initialize(ArtifactUpdaterContext context) throws Exception;

	/**
	 * Return the root for this repository 
	 * @return
	 */
	VirtualResourceLocator getRepositoryRoot();

	/**
	 * Return a list of ResourceGroups, using selector
	 * 
	 * @param selector
	 * @return
	 */
	List listGroups(ArtifactUpdaterContext context, ISelector selector)
		throws Exception;

	/**
	 * Return a list of Artifacts. (filtered using selector)
	 * 
	 * @param selector
	 * @return
	 */
	List listArtifacts(
		ArtifactUpdaterContext context,
		ArtifactGroup group,
		ISelector selector)
		throws Exception;

	/**
	 * Return a 'manifest' of what is in this group
	 * 
	 * @return
	 */
	RepositoryManifest getManifest(
		ArtifactUpdaterContext context,
		ArtifactGroup group,
		ISelector selector)
		throws Exception;

	/**
	 * Return a list of contents, using selector
	 * 
	 * @param selector
	 * @return
	 */
	List listInstances(
		ArtifactUpdaterContext context,
		ArtifactGroup group,
		ISelector selector)
		throws Exception;

	/**
	 * Delete a resource from the Repository
	 * 
	 * @param selector
	 * @return
	*/
	void deleteArtifact(ArtifactUpdaterContext context, ArtifactInstance resource)
		throws Exception;

	/**
	 * Publish a resource to the repository
	 * 
	 * @param selector
	 * @return
	*/
	ArtifactInstance publishArtifact(ArtifactUpdaterContext context, ArtifactInstance resource)
		throws Exception;

}
--- NEW FILE: ArtifactInstance.java ---
/*
 * Copyright  2004 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.krysalis.depot.update;

import java.io.PrintWriter;

import org.krysalis.depot.common.util.debug.Dumpable;
import org.krysalis.depot.update.artifact.ArtifactAttributeMap;
import org.krysalis.depot.update.artifact.ArtifactLocator;
import org.krysalis.depot.update.util.flag.Flag;
import org.krysalis.depot.update.util.identity.GenericIdentifier;
import org.krysalis.depot.update.util.reference.IReferenceable;
import org.krysalis.depot.update.util.select.ISelectable;
import org.krysalis.version.util.DebugUtils;




/**
 * This defines a 'real world' file, e.g. junit-3.8.1.jar and has all the
 * information about it, and where it is.
 *  
 * @author <a href="http://incubator.apache.org/depot">The Apache Incubator Depot Project</a>
 */
public class ArtifactInstance implements ISelectable, IReferenceable, Dumpable {

	// What and Where
	private Artifact m_artifact = null;
	private ArtifactLocator m_locator = null;

	// Annotated attributes
	private ArtifactAttributeMap m_attributes = null;

	/**
	 * Constructor
	 * Creates a new ArtifactInstance with the given parameters
	 * 
	 * @param artifact an Artifact
	 * @param locator the location of the artifact
	 */
	public ArtifactInstance(Artifact artifact, ArtifactLocator locator) {

		m_artifact = artifact;
		m_locator = locator;
	}

	/**
	 * Returns the Identifier of the concrete artifactInstance
	 * 
	 * @return identifier of the concrete artifact
	 */
	public GenericIdentifier getIdentifier() {
		return m_artifact.getIdentifier();
	}

	public Object getSelectionObject() {
		return m_artifact.getIdentifier();
	}

	/**
	 * Returns the artifact of this instance
	 * 
	 * @return the artifact
	 */
	public Artifact getArtifact() {
		return m_artifact;
	}

	/**
	 * Returns the Location of this Artifact(Instance)
	 * 
	 * @return the location of the concrete artifact
	 */
	public ArtifactLocator getLocator() {
		return m_locator;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	public boolean equals(Object other) {
		boolean equal = true;

		if (other instanceof ArtifactInstance) {
			ArtifactInstance otherResource = (ArtifactInstance) other;

			equal = otherResource.m_artifact.equals(m_artifact);
			equal &= otherResource.m_locator.equals(m_locator);
		} else
			throw new IllegalArgumentException("Not a Resource: "
					+ other.getClass().getName());

		return equal;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#hashCode()
	 */
	public int hashCode() {
		int hash = 0;

		hash += m_artifact.hashCode();
		hash += m_locator.hashCode();
		return hash;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		StringBuffer buffer = new StringBuffer();

		buffer.append(m_artifact);
		buffer.append("~");

		buffer.append(m_locator.toString());

		return buffer.toString();
	}

	/**
	 * Returns true if, and only if this artifactInstance contains the given attribute
	 * 
	 * @param attributeName the attributeName to check
	 * 
	 * @return has this artifactInstance an attribute with the given name?
	 */
	public boolean hasAttribute(Flag attributeName) {
		return (null == m_attributes)
				? false
				: m_attributes.containsKey(attributeName);
	}

	/**
	 * Gets the attribute with the specified name, if this name does not exists, or no
	 * attributes are defined, return null
	 * 
	 * @param attributeName The attribute to get
	 * 
	 * @return the value of the given attribute
	 */
	public Object getAttribute(Flag attributeName) {
		Object value = null;
		if (null != m_attributes)
			value = m_attributes.get(attributeName);
		return value;
	}

	/**
	 * Puts an Attribute into the attributeMap
	 * 
	 * @param attributeName Name of the attribute
	 * @param value Value of the attribute
	 */
	public void setAttribute(Flag attributeName, Object value)
	{
		if (null == m_attributes)
			m_attributes = new ArtifactAttributeMap();
			
		m_attributes.put(attributeName, value);
	}
	
	/**
	 * dumps this object to the specified PrintWriter using the DebugUtils
	 * 
	 * @param out PrintWriter to write the dump to
	 * @param depth the indentation depth to use
	 * @param verbose is the output verbose?
	 * 
	 * @see org.krysalis.depot.common.util.debug.DebutUtils
	 */
	public void dump(PrintWriter out, int depth, boolean verbose) {
		String indent = DebugUtils.getIndent(depth);

		out.print(indent);
		out.println("Resource Artifact: " + m_artifact);

		if (verbose)
			m_artifact.dump(out, depth+1, verbose);
		
		out.print(indent);
		out.println("Resource Locator: " + m_locator);

		if (verbose && (null != m_attributes))
			org.krysalis.depot.common.util.debug.DebugUtils.dump(out, depth, verbose, m_attributes);
	}

	/**
	 * Provides a clone of this object
	 * 
	 * Right now this is pretty much a shallow clone. Shouldn't we also clone the attributes?
	 */
	public Object clone() {
		ArtifactInstance aInstance = new ArtifactInstance((Artifact)this.m_artifact.clone(), 
					(ArtifactLocator)this.m_locator.clone());
		return aInstance;
	}
}
--- NEW FILE: package.html ---
<body>
<p>The public Depot Update API.</p>
</body>

--- NEW FILE: ArtifactUpdaterOptions.java ---
/*
 * Copyright  2004 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.krysalis.depot.update;

/**
 * @author arb_jack
 */
public class ArtifactUpdaterOptions {

// :TODO:
// Low Bandwidth
// Latest/Greatest...

}

--- NEW FILE: UpdateRuntimeException.java ---
/*
 * Copyright  2004 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.krysalis.depot.update;

import org.krysalis.depot.common.util.throwable.PortableRuntimeException;



/**
 * @author $Author: chalko $
 * @version $Revision: 1.1 $
 */
public class UpdateRuntimeException extends PortableRuntimeException {


    /**
     * @param message the user message
     */
    public UpdateRuntimeException(final String message) {
        super(message);
    }

    /**
     * @param message the user messsage
     * @param throwable the cause
     */
	public UpdateRuntimeException(
		final String message,
		final Throwable throwable) {
        super(message, throwable);
    }

    /**
     * @param throwable the cause
     */
    public UpdateRuntimeException(final Throwable throwable) {
        super(throwable);
    }
}

--- NEW FILE: AntUtils.java ---
/*
 * ========================================================================
 * Copyright 2004 The Apache Software Foundation
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 * ========================================================================
 */
package org.krysalis.depot.update;
import java.io.File;

import org.apache.tools.ant.BuildException; 
import org.apache.tools.ant.Project;
/**
 * A static collection of AntUtils
 */
public class AntUtils {
	/**
	 * Private constructor for static class
	 *  
	 */
	private AntUtils() {
	}
	/**
	 * validate and create a dir if needed. Ignore if dir is null
	 * 
	 * @param dir
	 * @param name
	 * @param failOnError
	 * @throws BuildException
	 *             if dir is not a Directory or can not be created
	 */
	public static void createAndValidateDir(Project p, File dir,
			final String name, boolean failOnError) throws BuildException {
		if (dir != null) {
			if (!dir.exists()) {
				if (!dir.mkdirs()) {
					final String message = "Could not create dir for " + name
							+ " at " + dir.getAbsolutePath();
					if (failOnError) {
						throw new BuildException(message);
					} else {
						p.log(message, Project.MSG_WARN);
					}
				}
			} else if (!dir.isDirectory()) {
				throw new BuildException(name + " at " + dir.getAbsolutePath()
						+ " is not a directroy");
			}
		}
	}
	/**
	 * create/validate the user.home.
	 * 
	 * @param project
	 * @return File a valid user home dir or null
	 */
	public static File getUserHome(Project project) {
		return findAndCreateDirFromProperty(project, "user.home");
	}
	/**
	 * @return
	 */
	public static File getDepotHome(Project p) {
		File depotHome = findAndCreateDirFromProperty(p, "depot.home");
		if (depotHome == null) {
			File userHome = getUserHome(p);
			depotHome = new File(userHome, ".apache.depot");
			createAndValidateDir(p, depotHome, "${user.home}/.apache.depot",
					true);
		}
		if (depotHome == null) {
			throw new BuildException("The property depot.home must be set");
		}
		return depotHome;
	}
	/**
	 * find a property and then create and validate it
	 * 
	 * @param p
	 *            the ant Project
	 * @param dirProperty
	 *            the property that has the dir path
	 * @return the dir, created if possille, null if not
	 */
	public static File findAndCreateDirFromProperty(Project p,
			String dirProperty) {
		String antletsDirName = p.getProperty(dirProperty);
		File antletsDir = null;
		if (null == antletsDirName) {
			p.log(dirProperty + " not defined.", Project.MSG_DEBUG);
		} else {
			antletsDir = new File(antletsDirName);
			if (!antletsDir.exists()) {
				p.log("Unable to create dir " + antletsDir.getAbsolutePath(),
						Project.MSG_WARN);
				antletsDir = null;
			} else if (!antletsDir.isDirectory()) {
				throw new BuildException("Property ${" + dirProperty + "} -> ["
						+ antletsDir.getAbsolutePath()
						+ "] not a workable directory.");
			} else {
				p.log(dirProperty + " =" + antletsDir, Project.MSG_DEBUG);
			}
		}
		return antletsDir;
	}
}
--- NEW FILE: RepositoryManifest.java ---
/*
 * Copyright  2004 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.krysalis.depot.update;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.krysalis.depot.common.util.debug.DebugUtils;
import org.krysalis.depot.common.util.debug.Dumpable;
import org.krysalis.depot.update.artifact.ArtifactType;
import org.krysalis.depot.update.util.identity.GenericIdentifier;
import org.krysalis.version.Version;


/**
 * 
 */
public class RepositoryManifest implements Dumpable {
	private List m_types = null;

	private List m_ids = null;

	private List m_versions = null;

	private List m_instances = null;

	/**
	 * Constructor Builds an empty RepositoryManifest
	 */
	public RepositoryManifest() {
		classInit();
	}

	/**
	 * Constructor Extract manifest from a list of instances of Artifacts
	 * 
	 * @param instances
	 */
	public RepositoryManifest(List instances) {
		classInit();

		importInformation(instances);
	}

	/**
	 * Constructor Builds a RepositoryManifest based on the input parameters
	 * 
	 * @param types
	 * @param ids
	 * @param versions
	 * @param instances
	 *            of Artifacts
	 */
	public RepositoryManifest(List types, List ids, List versions,
			List instances) {
		classInit();

		m_types = types;
		m_ids = ids;
		m_versions = versions;
		m_instances = instances;
	}

	/**
	 * Constructor Building a clone of the other class
	 * 
	 * @param other
	 *            another RepositoryManifest which is cloned
	 */
	public RepositoryManifest(RepositoryManifest other) {
		classInit();

		m_types = other.m_types;
		m_ids = other.m_ids;
		m_instances = other.m_instances;
	}

	/**
	 * Initialize this class
	 */
	private void classInit() {
		m_types = new ArrayList();
		m_ids = new ArrayList();
		m_versions = new ArrayList();
		m_instances = new ArrayList();
	}

	/**
	 * Import information from a list of instances
	 * 
	 * @param instances
	 */
	public void importInformation(List instances) {

		for (Iterator i = instances.iterator(); i.hasNext();) {
			ArtifactInstance instance = (ArtifactInstance) i.next();

			// Extract all the types, and store
			ArtifactType type = instance.getArtifact().getType();
			if (!m_types.contains(type))
				m_types.add(type);

			// Extract all the ids, and store
			GenericIdentifier id = instance.getIdentifier();
			if (!m_ids.contains(id))
				m_ids.add(id);

			// Extract all the ids, and store
			Version version = instance.getArtifact().getVersion();
			if (!m_versions.contains(version))
				m_versions.add(version);

			// Might as well keep it...
			m_instances.add(instance);
		}
	}

	/**
	 * @return
	 */
	public List getIds() {
		return m_ids;
	}

	/**
	 * @return
	 */
	public List getInstances() {
		return m_instances;
	}

	/**
	 * @return
	 */
	public List getTypes() {
		return m_types;
	}

	/**
	 * @param list
	 */
	public void setIds(List list) {
		m_ids = list;
	}

	/**
	 * @param list
	 */
	public void setInstances(List list) {
		m_instances = list;
	}

	/**
	 * @param list
	 */
	public void setTypes(List list) {
		m_types = list;
	}

	public void dump(PrintWriter out, int depth, boolean verbose) {
		org.krysalis.depot.common.util.debug.DebugUtils.dump(out, depth + 1, "Types", verbose, m_types);
		DebugUtils.dump(out, depth + 1, "IDs", verbose, m_ids);
		DebugUtils.dump(out, depth + 1, "Versions", verbose, m_versions);
		if (verbose)
			DebugUtils.dump(out, depth + 1, "Instances", verbose, m_instances);
	}

}

--- NEW FILE: Artifact.java ---
/*
 * Copyright  2004 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.krysalis.depot.update;

import java.io.PrintWriter;

import org.krysalis.depot.common.util.debug.Dumpable;
import org.krysalis.depot.update.artifact.ArtifactGroup;
import org.krysalis.depot.update.artifact.ArtifactType;
import org.krysalis.depot.update.util.identity.GenericIdentifier;
import org.krysalis.version.Version;
import org.krysalis.version.util.DebugUtils;


/**
 * An entity in a repository (e.g. junit-3.8.1.jar). An Artifact has (at least
 * in the apache.org environment) also a version. Also an Artifact has a
 * security mechanism, which is nowadays mostly a file with an .asc or (better)
 * .md5-Extension. The basic attributes of an artifact are the group, this
 * artifact belongs to (in the above example the group would be junit). The type
 * of the artifact provides the type (e.g. jar or tar.gz) of the artifact. The
 * identifier is a unique identifier of the artifact (the unique name). Also the
 * artifact can provide some version information (3.8.1 in the above example).
 * 
 * @author <a href="http://incubator.apache.org/depot">The Apache Incubator
 *         Depot Project </a>
 */
public class Artifact implements Dumpable {

	public static class Identifier extends GenericIdentifier {

		public final static String ARTIFACT_URI = "http://apache.org/artifact";
		public final static String ARTIFACT_PREFIX = "artifact";

		public Identifier(String id) {
			super(ARTIFACT_URI, ARTIFACT_PREFIX, id);
		}
	}

	private ArtifactGroup m_group = null;
	private Artifact.Identifier m_identifier = null;
	private ArtifactType m_type = null;
	private Version m_version = null;

	/**
	 * Constructor Creates an artifact with the given name as the group of the
	 * artifact, as well as the identifier of the artifact. The type is set to
	 * java-binary. The version is set to null.
	 * 
	 * @param name
	 *            Name of the artifact and the group
	 */
	public Artifact(String name) {
		m_group = new ArtifactGroup(name);
		m_identifier = new Artifact.Identifier(name);
		m_type = ArtifactType.JAVA_BINARY;
		m_version = null;
	}

	/**
	 * Constructor Basically creates an artifact with the attributes of another
	 * artifact (pretty much an clone)
	 * 
	 * :TODO: should be deleted, see the clone method of this class
	 * 
	 * @param other
	 *            another artifact
	 * @deprecated
	 */
	public Artifact(Artifact other) {
		m_group = other.m_group;
		m_identifier = other.m_identifier;
		m_type = other.m_type;
		m_version = other.m_version;
	}

	/**
	 * 
	 * 
	 * @param group
	 * @param identifier
	 * @param type
	 * @param version
	 */
	public Artifact(String group, String identifier, String type,
			Version version) {
		this(new ArtifactGroup(group), new Artifact.Identifier(identifier),
				ArtifactType.getFromString(type), version);
	}

	/**
	 * 
	 * 
	 * @param group
	 * @param identifier
	 * @param type
	 * @param version
	 */
	public Artifact(String group, String identifier, ArtifactType type,
			Version version) {
		this(new ArtifactGroup(group), new Artifact.Identifier(identifier),
				type, version);
	}

	/**
	 * 
	 * 
	 * @param group
	 * @param identifier
	 * @param type
	 * @param version
	 */
	public Artifact(ArtifactGroup group, Artifact.Identifier identifier,
			ArtifactType type, Version version) {
		m_group = group;
		m_identifier = identifier;
		m_type = type;
		m_version = version;
	}

	/**
	 * 
	 * 
	 * @param group
	 * @param identifier
	 * @param type
	 * @param version
	 */
	public Artifact(ArtifactGroup group, String identifier, ArtifactType type,
			Version version) {
		m_group = group;
		m_identifier = new Artifact.Identifier(identifier);
		m_type = type;
		m_version = version;
	}

	/**
	 * @return
	 */
	public Artifact.Identifier getIdentifier() {
		return m_identifier;
	}

	/**
	 * @return
	 */
	public ArtifactType getType() {
		return m_type;
	}

	/**
	 * @param identifier
	 */
	public void setIdentifier(Artifact.Identifier identifier) {
		m_identifier = identifier;
	}

	/**
	 * @param type
	 */
	public void setType(ArtifactType type) {
		m_type = type;
	}

	/**
	 * @return
	 */
	public Version getVersion() {
		return m_version;
	}

	/**
	 * @return
	 */
	public ArtifactGroup getGroup() {
		return m_group;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	public boolean equals(Object other) {
		boolean equal = true;

		if (other instanceof Artifact) {
			Artifact otherArtifact = (Artifact) other;

			equal = otherArtifact.m_identifier.equals(m_identifier);
			equal &= otherArtifact.m_group.equals(m_group);
			equal &= otherArtifact.m_type.equals(m_type);
			if (null != m_version)
				equal &= otherArtifact.m_version.equals(m_version);
			else
				equal &= (null == otherArtifact.m_version);
		} else
			throw new IllegalArgumentException("Not an Artifact: "
					+ other.getClass().getName());

		return equal;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#hashCode()
	 */
	public int hashCode() {
		int hash = 0;

		hash += m_identifier.hashCode();
		hash += m_group.hashCode();
		hash += m_type.hashCode();

		if (null != m_version)
			hash += m_version.hashCode();

		return hash;
	}

	public String toString() {
		StringBuffer buffer = new StringBuffer();

		if (!m_group.getName().equals(m_identifier.getId())) {
			buffer.append("{");
			buffer.append(m_group.toString());
			buffer.append("}: ");
		}

		buffer.append(m_identifier.getId());
		buffer.append(" (");
		buffer.append(m_type.getPrefix());
		buffer.append(") ");

		if (null != m_version) {
			buffer.append(m_version.toString());
		}

		return buffer.toString();
	}

	public void dump(PrintWriter out, int depth, boolean verbose) {
		String indent = DebugUtils.getIndent(depth);

		out.print(indent);
		out.println("Resource Identifier: " + m_identifier);

		out.print(indent);
		out.println("Resource Type: " + m_type);

		out.print(indent);
		out.println("Resource Group: " + m_group);

		if (null != m_version) {
			out.print(indent);
			out.println("Resource Version: " + m_version);

			if (verbose)
				if (m_version instanceof Dumpable)
					org.krysalis.depot.common.util.debug.DebugUtils.dump(out, depth + 1, (Dumpable) m_version,
							verbose);
		}
	}

	public Object clone() {
		Artifact anotherArtifact = new Artifact(this.m_group,
				this.m_identifier, this.m_type, this.m_version);
		return anotherArtifact;
	}
}
--- NEW FILE: ArtifactUpdaterFactory.java ---
/*
 * Copyright  2004 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.krysalis.depot.update;

import org.krysalis.depot.update.impl.ReferenceManager;
import org.krysalis.depot.update.updater.ConfiguredArtifactUpdater;
import org.krysalis.depot.update.updater.DefaultArtifactUpdater;
import org.krysalis.depot.update.util.UpdateConstants;


/**
 * An ArtifactUpdater is the main (low level) API into Depot.
 * 
 * @see DefaultArtifactUpdater, StandardResourceUpdater
 * 
 * @author anou_mana
 */
public class ArtifactUpdaterFactory {

	public static ArtifactUpdater getDefaultUpdater() throws UpdateException {
		return new DefaultArtifactUpdater(UpdateConstants.DEFAULT);
	}

	public static ArtifactUpdater getConfiguredUpdater(String filename)
			throws UpdateException {
		return new ConfiguredArtifactUpdater(filename, filename);
	}
	
	public static ArtifactUpdater getUpdater(String updater)
	throws UpdateException {
		return ArtifactUpdaterFactory.getUpdater(
					new ArtifactUpdater.Identifier(updater), true);
	}
	
	public static ArtifactUpdater getUpdater(
		ArtifactUpdater.Identifier identifier,
		boolean createIfRequired)
		throws UpdateException {

		ArtifactUpdater updater = null;

		if (ReferenceManager.hasReference(identifier)) {
			updater =
				(ArtifactUpdater) ReferenceManager.getReference(
					identifier);
		}
		else {
			if (!createIfRequired)
				throw new UpdateException(
					"Failed to access ResourceUpdaterContext ["
						+ identifier
						+ "]");

			if ( identifier.getId().equals(UpdateConstants.DEFAULT))
				updater = getDefaultUpdater();
			else
				updater = new ArtifactUpdater(identifier);

			// Store for re-use
			ReferenceManager.createReference(updater);
		}

		return updater;
	}
}


-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now. 
http://productguide.itmanagersjournal.com/