krysalis-update/src/java/org/krysalis/depot/update/files ExtensionTable.java,NONE,1.1 IArtifactGroupFilenameAnalyzer.java,NONE,1.1 DefaultArtifactGroupFilenameAnalyzer.java,NONE,1.1 DefaultArtifactFilenameAnalyzer.java,NONE,1.1 IArtifactFilenameAnalyzer.java,NONE,1.1 TypeTable.java,NONE,1.1

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

Added Files:
	ExtensionTable.java IArtifactGroupFilenameAnalyzer.java 
	DefaultArtifactGroupFilenameAnalyzer.java 
	DefaultArtifactFilenameAnalyzer.java 
	IArtifactFilenameAnalyzer.java TypeTable.java 
Log Message:
Copied from the apache incubator.

--- NEW FILE: IArtifactGroupFilenameAnalyzer.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.files;

import java.util.List;

import org.krysalis.depot.update.UpdateException;
import org.krysalis.depot.update.artifact.ArtifactGroup;

/**
 * @author arb_jack
 */
public interface IArtifactGroupFilenameAnalyzer {

	List determineGroups(List entityList) throws UpdateException;
	ArtifactGroup determineGroup(Object entity) throws UpdateException;
}

--- NEW FILE: TypeTable.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.files;

import java.util.HashMap;
import java.util.Map;

/**
 * @author arb_jack
 */
public class TypeTable {
	private Map m_typeMap = new HashMap();

	class TypeEntry {
		String m_type;
		String m_description;

		TypeEntry(String type, String description) {
			m_type = type;
			m_description = description;
		}

	}

	public static TypeTable TYPE_TABLE = null;

	static {
		TYPE_TABLE = new TypeTable();

		TYPE_TABLE.register("-src", "Source Code");
		TYPE_TABLE.register("-bin", "Distribution");
		TYPE_TABLE.register("-docs", "Documentation");
	}

	private void register(String type, String desc) {
		registerEntry(new TypeTable.TypeEntry(type, desc));
	}

	private void registerEntry(TypeEntry entry) {
		m_typeMap.put(entry.m_type, entry);
	}
	

	public boolean hasType(String extension) {
		return m_typeMap.containsKey(extension);
	}

	public TypeEntry getEntryByType(String type) {
		return (TypeEntry) m_typeMap.get(type);
	}
}

--- NEW FILE: DefaultArtifactGroupFilenameAnalyzer.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.files;

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

import org.krysalis.depot.common.log.Logger;
import org.krysalis.depot.update.UpdateException;
import org.krysalis.depot.update.artifact.ArtifactGroup;
import org.krysalis.depot.update.monitor.FileEvent;
import org.krysalis.depot.update.monitor.Monitor;
import org.krysalis.depot.update.util.io.ResolvedFile;
import org.krysalis.depot.update.util.net.VirtualResourceLocator;
import org.krysalis.depot.update.util.text.MessageConstants;
import org.krysalis.depot.update.util.text.Messages;

/**
 * @author arb_jack
 */
public class DefaultArtifactGroupFilenameAnalyzer
	implements IArtifactGroupFilenameAnalyzer {
	private VirtualResourceLocator m_base = null;

	public DefaultArtifactGroupFilenameAnalyzer(VirtualResourceLocator base) {
		m_base = base;
	}

	public List determineGroups(List entityList) throws UpdateException {
		List store = new ArrayList();

		for (Iterator i = entityList.iterator(); i.hasNext();) {

			Object entity = i.next();

			try {

				//
				// Understood objects
				//
				if (entity instanceof String)
					processString(
						(String) entity,
						new VirtualResourceLocator(m_base, (String) entity),
						store);
				else if (entity instanceof VirtualResourceLocator)
					processVRL((VirtualResourceLocator) entity, store);
				else if (entity instanceof File)
					processFile((ResolvedFile) entity, store);
				//
				// Hmm VFS? How utilize yet be separate? Maybe String...
				//
				else {
					Logger.getLogger().error(
						Messages.getString(
							MessageConstants.WRONG_TYPE,
							entity));
				}
			}
			catch (UpdateException re) {
				//:TODO: log/context/listeners...
			}
		}

		return store;
	}

	public ArtifactGroup determineGroup(Object entity) throws UpdateException {
		List store = new ArrayList();

		try {

			//
			// Understood objects
			//
			if (entity instanceof String)
				processString(
					(String) entity,
					new VirtualResourceLocator(m_base, (String) entity),
					store);
			else if (entity instanceof VirtualResourceLocator)
				processVRL((VirtualResourceLocator) entity, store);
			else if (entity instanceof File)
				processFile((ResolvedFile) entity, store);
			//
			// Hmm VFS? How utilize yet be separate? Maybe String...
			//
			else {
				Logger.getLogger().error(
					Messages.getString(MessageConstants.WRONG_TYPE, entity));
			}
		}
		catch (UpdateException re) {
			Logger.getLogger().error(
				Messages.getString(
					MessageConstants.GENERAL_EXCEPTION2,
					new Object[] { entity, re.getLocalizedMessage()}),
				re);
		}

		// Check for empty and through ???

		return (ArtifactGroup) store.get(0);
	}

	void processVRL(VirtualResourceLocator groupVRL, List store)
		throws UpdateException {
		String baseName = groupVRL.getBasename();

		//
		// :TODO: How do we skip non-directories
		// 1) Efficiently
		// 2) Since VFS doesn't deam any URL a 'directory'
		//
		processString(baseName, groupVRL, store);
	}

	void processFile(ResolvedFile group, List store) throws UpdateException {
		String name = group.getName().toString();
		int sepPosn = name.lastIndexOf(File.pathSeparator);
		String baseName = (-1 == sepPosn) ? name : name.substring(sepPosn + 1);

		//
		// Skip non-directories.
		//
		if (!group.isDirectory())
			return;

		processString(baseName, new VirtualResourceLocator(group), store);
	}

	//
	//		HACK HACK HACK -- to get us started. Will evolve into a
	//		whole configurable parsing sub-system
	//
	void processString(
		String groupName,
		VirtualResourceLocator location,
		List store)
		throws UpdateException {

		Logger.getLogger().debug(
			Messages.getString(
				MessageConstants.PROCESS,
				new Object[] { groupName, location }));

		//
		// Ignore files starting with a .
		//
		boolean ignore =
			(null == groupName)
				|| (0 == groupName.length())
				|| (groupName.startsWith(".") || (groupName.equals(("CVS"))));

		if (!ignore) {
			ArtifactGroup group = new ArtifactGroup(groupName);

			// Store it...
			store.add(group);
		}
		else {

			Logger.getLogger().debug(
				Messages.getString(MessageConstants.IGNORED, groupName));
				// :TODO: BOGUS!!!! Need groupEvent
			Monitor.getMonitor().notify(new FileEvent(FileEvent.IGNORED, groupName));
		}
	}

}

--- NEW FILE: IArtifactFilenameAnalyzer.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.files;

import java.util.List;

import org.krysalis.depot.update.ArtifactInstance;
import org.krysalis.depot.update.UpdateException;


/**
 * @author arb_jack
 */
public interface IArtifactFilenameAnalyzer {
	List determineArtifacts(List entityList) throws UpdateException;
	ArtifactInstance determineArtifact(Object entity) throws UpdateException;
}

--- NEW FILE: DefaultArtifactFilenameAnalyzer.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.files;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.krysalis.depot.common.log.Logger;
import org.krysalis.depot.update.Artifact;
import org.krysalis.depot.update.ArtifactInstance;
import org.krysalis.depot.update.UpdateException;
import org.krysalis.depot.update.UpdateRuntimeException;
import org.krysalis.depot.update.artifact.ArtifactAttribute;
import org.krysalis.depot.update.artifact.ArtifactGroup;
import org.krysalis.depot.update.artifact.ArtifactLocator;
import org.krysalis.depot.update.artifact.ArtifactType;
import org.krysalis.depot.update.monitor.FileEvent;
import org.krysalis.depot.update.monitor.Monitor;
import org.krysalis.depot.update.util.UpdateConstants;
import org.krysalis.depot.update.util.io.ResolvedFile;
import org.krysalis.depot.update.util.net.VirtualResourceLocator;
import org.krysalis.depot.update.util.text.MessageConstants;
import org.krysalis.depot.update.util.text.Messages;
import org.krysalis.version.VersionException;
import org.krysalis.version.impl.apache.ApacheVersion;
import org.krysalis.version.impl.data.ReleaseLevel;

/**
 * @author arb_jack
 */
public class DefaultArtifactFilenameAnalyzer
	implements IArtifactFilenameAnalyzer {
	private VirtualResourceLocator m_base = null;
	private ExtensionTable m_extensionTable = null;

	public DefaultArtifactFilenameAnalyzer(VirtualResourceLocator base) {
		m_base = base;
		m_extensionTable = ExtensionTable.DEFAULT_EXTENSION_TABLE;
	}

	public DefaultArtifactFilenameAnalyzer(
		VirtualResourceLocator base,
		ExtensionTable extns) {
		m_base = base;
		m_extensionTable = extns;
	}

	//
	// Working Area. Since we aren't sure what order the resources
	// come in, and we might combine multiple inputs to make up the
	// attributes of a single resource (e.g. attach the MD5 location
	// to the owning resource)...
	//
	class ArtifactWorkingStore {
		private List m_list = new ArrayList();
		private Map m_map = new HashMap();

		// MD5 locations for resources...
		private Map m_md5map = new HashMap();
		private Map m_ascmap = new HashMap();

		boolean contains(ArtifactInstance artifact) {
			return m_map.containsKey(artifact);
		}

		void addArtifact(ArtifactInstance instance) {
			String id = instance.getIdentifier().getId();

			//
			// Keep .MD5s|.ASCs separate
			// :TODO: .pgp
			// 
			String extension = instance.getLocator().getExtension();

			if ((null != extension)
				&& (extension.endsWith(UpdateConstants.MD5_EXTN))
				&& (extension.length() > UpdateConstants.MD5_EXTN.length())) {

				ArtifactInstance orig = (ArtifactInstance)instance.clone();

				String newExtn =
					extension.substring(
						0,
						extension.length() - UpdateConstants.MD5_EXTN.length());
				orig.getLocator().setExtension(newExtn);

				m_md5map.put(orig, instance.getLocator().getLocation());
			}
			else if (
				(null != extension)
					&& (extension.endsWith(UpdateConstants.ASC_EXTN))
					&& (extension.length() > UpdateConstants.ASC_EXTN.length())) {

				ArtifactInstance orig = (ArtifactInstance)instance.clone();

				String newExtn =
					extension.substring(
						0,
						extension.length() - UpdateConstants.ASC_EXTN.length());
				orig.getLocator().setExtension(newExtn);

				m_ascmap.put(orig, instance.getLocator().getLocation());
			}
			else {
				// Meant to look first...
				if (m_map.containsKey(instance))
					throw new UpdateRuntimeException(
						"Duplicate Artifact in working store: " + id);

				// Store it...
				m_map.put(instance, instance);
				m_list.add(instance);
			}
		}

		ArtifactInstance getArtifact(ArtifactInstance artifact) {
			return (ArtifactInstance) m_map.get(artifact);
		}

		List getCompletedList() {
			for (Iterator i = m_list.iterator(); i.hasNext();) {
				ArtifactInstance instance = (ArtifactInstance) i.next();

				if (m_md5map.containsKey(instance)) {
					// Store the MD5 location for this instance
					VirtualResourceLocator md5location =
						(VirtualResourceLocator) m_md5map.get(instance);

					// Set this as an attribute on the instance,
					// future code could process this (to check)
					instance.setAttribute(
						ArtifactAttribute.MD5_LOCATION,
						md5location);
				}
				else if (m_ascmap.containsKey(instance)) {
					// Store the ASC location for this instance
					VirtualResourceLocator asclocation =
						(VirtualResourceLocator) m_ascmap.get(instance);

					// Set this as an attribute on the instance,
					// future code could process this (to check)
					instance.setAttribute(
						ArtifactAttribute.ASC_LOCATION,
						asclocation);
				}
			}
			return m_list;
		}
	}

	public List determineArtifacts(List entityList) throws UpdateException {
		ArtifactWorkingStore store =
			new DefaultArtifactFilenameAnalyzer.ArtifactWorkingStore();

		for (Iterator i = entityList.iterator(); i.hasNext();) {

			Object entity = i.next();

			try {

				//
				// Understood objects
				//
				if (entity instanceof String)
					processString(
						(String) entity,
						new VirtualResourceLocator(m_base, (String) entity),
						store);
				else if (entity instanceof VirtualResourceLocator)
					processVRL((VirtualResourceLocator) entity, store);
				else if (entity instanceof File)
					processFile((ResolvedFile) entity, store);
				//
				// Hmm VFS? How utilize yet be separate? Maybe String...
				//
				else {
					Logger.getLogger().error(
						Messages.getString(
							MessageConstants.WRONG_TYPE,
							entity));
				}
			}
			catch (UpdateException re) {
				//:TODO: log/context/listeners...
			}
		}

		return store.getCompletedList();
	}

	public ArtifactInstance determineArtifact(Object entity) throws UpdateException {
		ArtifactWorkingStore store =
			new DefaultArtifactFilenameAnalyzer.ArtifactWorkingStore();

		try {

			//
			// Understood objects
			//
			if (entity instanceof String)
				processString(
					(String) entity,
					new VirtualResourceLocator(m_base, (String) entity),
					store);
			else if (entity instanceof VirtualResourceLocator)
				processVRL((VirtualResourceLocator) entity, store);
			else if (entity instanceof ResolvedFile)
				processFile((ResolvedFile) entity, store);
			else if (entity instanceof File)
				// :TODO: Do we have resolver context?
				processFile(ResolvedFile.resolve(entity), store);
			//
			// Hmm VFS? How utilize yet be separate? Maybe String...
			//
			else {
				Logger.getLogger().error(
					Messages.getString(MessageConstants.WRONG_TYPE, entity));
			}
		}
		catch (UpdateException re) {
			Logger.getLogger().error(
				Messages.getString(
					MessageConstants.GENERAL_EXCEPTION2,
					new Object[] { entity, re.getLocalizedMessage()}),
				re);
		}

		return (ArtifactInstance) store.getCompletedList().get(0);
	}

	void processVRL(
		VirtualResourceLocator instanceVRL,
		ArtifactWorkingStore store)
		throws UpdateException {

		//			:TODO: Hacky
		String group = null;
		VirtualResourceLocator parentVRL = instanceVRL.getParent();
		if (null != parentVRL) {
			VirtualResourceLocator grandparentVRL = parentVRL.getParent();
			if (null != grandparentVRL) {
				group = grandparentVRL.getBasename();
			}
		}

		processString(instanceVRL.getBasename(), group, instanceVRL, store);
	}

	void processFile(ResolvedFile instance, ArtifactWorkingStore store)
		throws UpdateException {

		// Get file basename
		String name = instance.getName().toString();
		int sepPosn = name.lastIndexOf(File.pathSeparator);
		String baseName = (-1 == sepPosn) ? name : name.substring(sepPosn + 1);

		// :TODO: Hacky
		String group = null;
		File parent = instance.getParentFile();
		if (null != parent) {
			File grandparent = parent.getParentFile();
			if (null != grandparent) {

				String gname = grandparent.getName().toString();
				int gsepPosn = name.lastIndexOf(File.pathSeparator);
				String gbaseName =
					(-1 == sepPosn) ? name : name.substring(sepPosn + 1);

				group = gbaseName;
			}
		}

		processString(
			baseName,
			group,
			new VirtualResourceLocator(instance),
			store);
	}

	//
	//
	//
	void processString(
		String artifactName,
		VirtualResourceLocator location,
		ArtifactWorkingStore store)
		throws UpdateException {
		processString(artifactName, null, location, store);
	}

	//
	//		HACK HACK HACK -- to get us started. Could evolve into a
	//		configurable parsing sub-system
	//
	void processString(
		String artifactName,
		String groupStr,
		VirtualResourceLocator location,
		ArtifactWorkingStore store)
		throws UpdateException {

		Logger.getLogger().debug(
			Messages.getString(
				MessageConstants.PROCESS,
				new Object[] { artifactName, location }));

		// Parts...
		String extension = null;
		String type = null;
		String version = null;
		String name = null;

		// Determine the extension
		extension = extractExtension(artifactName);

		// Remainder is name-version-type
		String remainder =
			artifactName.substring(
				0,
				(artifactName.length() - (extension.length() + 1)));

		//
		// Type is anything after the last - or _ so long as
		//	it doesn't start with a digit (i.e. is the version)
		// .. and/or release level
		//
		// Hmm, but what of filenames w/ no version, where the
		// name contains one of these. Let's check that what we
		// get is a 'known' type, e.g. src/docs/etc. Not pretty,
		// but...
		//
		int typePosn = findLastSeparator(remainder);
		if (-1 != typePosn) {
			if (!Character.isDigit(remainder.charAt(typePosn + 1))) {
				type = remainder.substring(typePosn + 1);

				if (!ReleaseLevel
					.UNSET
					.equals(ReleaseLevel.getFromStringFailSafe(type))) {
					type = null; // ArtifactType.JAVA_BINARY;
				}
				else if (
					ArtifactType.UNKNOWN.equals(
						ArtifactType.getFromString(type))) {
					type = null;
				}
				else {

					//
					// What is left is name/version
					//
					remainder = remainder.substring(0, typePosn);
				}
			}
		}

		// Take a stab...
		if (null == type) {
			type = m_extensionTable.getTypeFromExtension(extension).toString();
		}

		//
		// Version is anything after the first - or _ followed
		// by a Digit
		//
		int versionPosn = findSeparatorBeforeVersionNumbers(remainder);
		if (-1 != versionPosn) {
			version = remainder.substring(versionPosn + 1, remainder.length());
			name = remainder.substring(0, versionPosn);
		}
		else
			name = remainder;

		Logger.getLogger().debug(
			Messages.getString(
				MessageConstants.EXTRACTED,
				new Object[] { groupStr, name, version, type, extension }));

		//
		// Ignore files starting with a .
		//
		boolean ignore =
			(null == name)
				|| (0 == name.length())
				|| name.startsWith(".")
				|| (name.equals("CVS"));

		if (!ignore)
			try {
				ArtifactGroup group =
					new ArtifactGroup((null == groupStr) ? name : groupStr);

				ArtifactType artifactType = ArtifactType.getFromString(type);
				
				ArtifactInstance temp =
					new ArtifactInstance(
						new Artifact(group,
						name,
						artifactType,
						(null == version ? null : new ApacheVersion(version))),
						new ArtifactLocator(
						artifactName,
						extension,
						location));
						

				//:TODO: Could be written better
				if (!store.contains(temp)) {

					Monitor.getMonitor().notify(
						new FileEvent(FileEvent.PARSED, artifactName));

					store.addArtifact(temp);
				}
				else {
					//:TODO: Fix
					Logger.getLogger().debug(
						Messages.getString(
							MessageConstants.MERGE,
							new Object[] { artifactName, location, temp }));
				}
			}
			catch (VersionException ve) {

				Logger.getLogger().error(
					Messages.getString(
						MessageConstants.GENERAL_EXCEPTION3,
						new Object[] {
							artifactName,
							location,
							ve.getLocalizedMessage()}),
					ve);

				Monitor.getMonitor().notify(
					new FileEvent(FileEvent.FAILED, artifactName));
			}
		else
			Monitor.getMonitor().notify(
				new FileEvent(FileEvent.IGNORED, artifactName));

	}

	int findLastSeparator(String input) {
		return findLastSeparator(input, input.length());
	}

	int findLastSeparator(String input, int start) {
		int dashPosn = input.lastIndexOf('-', start);
		int underscorePosn = input.lastIndexOf('_', start);
		return (dashPosn >= underscorePosn) ? dashPosn : underscorePosn;
	}

	int findSeparator(String input) {
		return findSeparator(input, 0);
	}

	int findSeparator(String input, int start) {
		int dashPosn = input.indexOf('-', start);
		int underscorePosn = input.indexOf('_', start);
		return (dashPosn >= underscorePosn) ? dashPosn : underscorePosn;
	}

	int findSeparatorBeforeVersionNumbers(String input) {
		//
		// Search for xxx-[0-9] (where xxx may have -[A-Za-z...etc.]
		// If not found, can't continue...
		//
		int separatorPosn = -1;

		int currentPosn = 0;
		do {
			int posn = findSeparator(input, currentPosn);

			// Found and not last character
			if ((-1 != posn) && (posn < input.length())) {
				int numPosn = posn + 1;
				if (Character.isDigit(input.charAt(numPosn))) {
					separatorPosn = posn;
				}
				else
					currentPosn = numPosn;
			}
			else {
				//
				// Can't process
				//
				break;
			}
		}
		while (-1 == separatorPosn);

		return separatorPosn;
	}

	String extractExtension(String artifactName) throws UpdateException {
		//	Extract extensions
		List probableExtns = extractProbableExtensions(artifactName);

		// Attempt to match extensions, if not accept it is unknown 
		// and take "biggest"
		String extension = null;
		for (Iterator i = probableExtns.iterator();
			i.hasNext() && (null == extension);
			) {
			String extn = (String) i.next();

			if (m_extensionTable.hasExtension(extn))
				extension = extn;
		}

		// If not found, pick "largest" = first.
		if (null == extension)
			if (0 == probableExtns.size())
				throw new UpdateException(
					"Unable to extract extension from [" + artifactName + "]");

		//
		// Drop case
		//
		extension = ((String) probableExtns.get(0)).toLowerCase();

		return extension;
	}

	//
	// Return a list (sorted by largest number of periods)
	//
	List extractProbableExtensions(String name) {
		// Get period separated tokens in reverse order
		List tokenList = new ArrayList();
		StringTokenizer tokens = new StringTokenizer(name, ".");
		for (; tokens.hasMoreTokens();) {
			tokenList.add(tokens.nextToken());
		}
		Collections.reverse(tokenList);

		// Build Results
		List extensionChoices = new ArrayList();
		String extension = null;
		for (Iterator i = tokenList.iterator(); i.hasNext();) {
			String token = (String) i.next();
			if (null == extension)
				extension = token;
			else
				extension = token + "." + extension;
			// If not starts with a number
			// and not the whole thing ...
			if (!Character.isDigit(token.charAt(0)) && i.hasNext()) {
				extensionChoices.add(extension);
			}
		}
		Collections.reverse(extensionChoices);

		return extensionChoices;
	}
	/**
	 * @return
	 */
	public VirtualResourceLocator getBase() {
		return m_base;
	}

	/**
	 * @param locator
	 */
	public void setBase(VirtualResourceLocator locator) {
		m_base = locator;
	}
}

--- NEW FILE: ExtensionTable.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.files;

import java.util.HashMap;
import java.util.Map;

import org.krysalis.depot.update.artifact.ArtifactType;

/**
 * @author arb_jack
 */
public class ExtensionTable {
	private Map m_extnMap = new HashMap();
	private Map m_mimeMap = new HashMap();

	class ExtensionEntry {
		String m_extn;
		String m_description;
		String m_mime;
		ArtifactType m_type;

		ExtensionEntry(
			String extn,
			String description,
			String mime,
			ArtifactType type) {
			m_extn = extn;
			m_description = description;
			m_mime = mime;
			m_type = type;
		}
	}

	public boolean hasExtension(String extension) {
		return m_extnMap.containsKey(extension);
	}

	public static ExtensionTable DEFAULT_EXTENSION_TABLE = null;

	static {
		DEFAULT_EXTENSION_TABLE = new ExtensionTable();

		DEFAULT_EXTENSION_TABLE.register(
			"jar",
			"Java Archive",
			"TODO",
			ArtifactType.JAVA_BINARY);
		DEFAULT_EXTENSION_TABLE.register("tar", "Tape Archive", "TODO", null);
		DEFAULT_EXTENSION_TABLE.register("zip", "ZIP Archive", "TODO", null);
		DEFAULT_EXTENSION_TABLE.register(
			"tar.Z",
			"Compressed Tape Archive",
			"TODO",
			null);
	}

	public void register(
		String extn,
		String desc,
		String mime,
		ArtifactType type) {
		registerEntry(
			new ExtensionTable.ExtensionEntry(extn, desc, mime, type));
	}

	public ArtifactType getTypeFromExtension(String extn) {
		ArtifactType type = ArtifactType.UNKNOWN;

		ExtensionEntry entry = getEntryByExtension(extn);

		if ((null != entry) && (null != entry.m_type))
			type = entry.m_type;

		return type;
	}
	
	public void registerEntry(ExtensionEntry entry) {
		m_extnMap.put(entry.m_extn, entry);
		m_mimeMap.put(entry.m_mime, entry);
	}

	private ExtensionEntry getEntryByExtension(String extn) {
		return (ExtensionEntry) m_extnMap.get(extn);
	}

	public ExtensionEntry getEntryByMime(String mime) {
		return (ExtensionEntry) m_mimeMap.get(mime);
	}

}



-------------------------------------------------------
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/