You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by sc...@apache.org on 2012/12/12 15:58:42 UTC

svn commit: r1420723 [4/12] - in /uima/sandbox/trunk/uimaFIT: ./ src/ src/main/ src/main/assembly/ src/main/java/ src/main/java/org/ src/main/java/org/uimafit/ src/main/java/org/uimafit/component/ src/main/java/org/uimafit/component/initialize/ src/mai...

Added: uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/CpeBuilder.java
URL: http://svn.apache.org/viewvc/uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/CpeBuilder.java?rev=1420723&view=auto
==============================================================================
--- uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/CpeBuilder.java (added)
+++ uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/CpeBuilder.java Wed Dec 12 14:58:37 2012
@@ -0,0 +1,185 @@
+/*
+ Copyright 2011
+ Ubiquitous Knowledge Processing (UKP) Lab
+ Technische Universitaet Darmstadt
+ All rights reserved.
+
+ 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.uimafit.factory;
+
+import static org.apache.uima.UIMAFramework.getResourceSpecifierFactory;
+import static org.apache.uima.UIMAFramework.produceCollectionProcessingEngine;
+import static org.apache.uima.collection.impl.metadata.cpe.CpeDescriptorFactory.produceCasProcessor;
+import static org.apache.uima.collection.impl.metadata.cpe.CpeDescriptorFactory.produceCollectionReader;
+import static org.apache.uima.collection.impl.metadata.cpe.CpeDescriptorFactory.produceDescriptor;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Map;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.uima.UIMAFramework;
+import org.apache.uima.analysis_engine.AnalysisEngineDescription;
+import org.apache.uima.analysis_engine.metadata.FixedFlow;
+import org.apache.uima.collection.CollectionProcessingEngine;
+import org.apache.uima.collection.CollectionReaderDescription;
+import org.apache.uima.collection.StatusCallbackListener;
+import org.apache.uima.collection.impl.metadata.CpeDefaultValues;
+import org.apache.uima.collection.metadata.CpeCollectionReader;
+import org.apache.uima.collection.metadata.CpeComponentDescriptor;
+import org.apache.uima.collection.metadata.CpeDescription;
+import org.apache.uima.collection.metadata.CpeDescriptorException;
+import org.apache.uima.collection.metadata.CpeInclude;
+import org.apache.uima.collection.metadata.CpeIntegratedCasProcessor;
+import org.apache.uima.resource.ResourceInitializationException;
+import org.apache.uima.resource.ResourceManager;
+import org.apache.uima.resource.ResourceSpecifier;
+import org.apache.uima.util.InvalidXMLException;
+import org.xml.sax.SAXException;
+
+/**
+ * Build a Collection Processing Engine from a {@link CollectionReaderDescription} and a
+ * {@link AnalysisEngineDescription}. If an aggregate analysis engine description is used, the
+ * builder will add each child of the aggregate engine as one processor to the engine. This works
+ * only for aggregate analysis engines using a {@link FixedFlow}.
+ *
+ * @author Richard Eckart de Castilho
+ */
+public class CpeBuilder
+{
+//	private final Log log = LogFactory.getLog(getClass());
+
+	private static final String ACTION_ON_MAX_ERROR = "terminate";
+
+	/**
+	 * used for calculating the CAS pool size which needs to be adjusted to the number of parallel
+	 * pipelines
+	 */
+	private int maxProcessingUnitThreadCount = 1;
+
+	private final CpeDescription cpeDesc = produceDescriptor();
+
+	public void setMaxProcessingUnitThreadCount(int aMaxProcessingUnitThreadCount)
+	{
+		maxProcessingUnitThreadCount = aMaxProcessingUnitThreadCount;
+	}
+
+	public void setReader(CollectionReaderDescription aDesc)
+		throws IOException, SAXException, CpeDescriptorException
+	{
+		// Remove all collection readers
+		cpeDesc.setAllCollectionCollectionReaders(new CpeCollectionReader[0]);
+
+		URL descUrl = materializeDescriptor(aDesc).toURI().toURL();
+		CpeCollectionReader reader = produceCollectionReader(descUrl.toString());
+		cpeDesc.addCollectionReader(reader);
+	}
+
+	public void setAnalysisEngine(AnalysisEngineDescription aDesc)
+		throws IOException, SAXException, CpeDescriptorException, InvalidXMLException
+	{
+		// Remove all CAS processors
+		cpeDesc.setCpeCasProcessors(null);
+
+		if (aDesc.isPrimitive()) {
+			// For a primitive AE we just add it.
+			CpeIntegratedCasProcessor proc = createProcessor("", aDesc);
+			cpeDesc.addCasProcessor(proc);
+		}
+		else {
+			// For an aggregate AE we dive into the first aggregation level and add each of the
+			// contained AEs separately, thus allowing us to control their properties separately
+
+			Map<String, ResourceSpecifier> delegates = aDesc.getDelegateAnalysisEngineSpecifiers();
+			FixedFlow flow = (FixedFlow) aDesc.getAnalysisEngineMetaData().getFlowConstraints();
+			for (String key : flow.getFixedFlow()) {
+				AnalysisEngineDescription aeDesc = (AnalysisEngineDescription) delegates.get(key);
+//				boolean multi = aeDesc.getAnalysisEngineMetaData().getOperationalProperties()
+//						.isMultipleDeploymentAllowed();
+//				log.info("["+key+"] runs "+ (multi ? "multi-threaded" : "single-threaded"));
+				CpeIntegratedCasProcessor proc = createProcessor(key, aeDesc);
+				cpeDesc.addCasProcessor(proc);
+			}
+		}
+	}
+
+	public CpeDescription getCpeDescription()
+	{
+		return cpeDesc;
+	}
+	
+	public CollectionProcessingEngine createCpe(StatusCallbackListener aListener)
+		throws ResourceInitializationException, CpeDescriptorException
+	{
+		ResourceManager resMgr = UIMAFramework.newDefaultResourceManager();
+		if (maxProcessingUnitThreadCount == 0) {
+			cpeDesc.getCpeCasProcessors().setPoolSize(3);
+		}
+		else {
+			cpeDesc.getCpeCasProcessors().setPoolSize(maxProcessingUnitThreadCount + 2);
+			cpeDesc.setProcessingUnitThreadCount(maxProcessingUnitThreadCount);
+		}
+		CollectionProcessingEngine cpe = produceCollectionProcessingEngine(cpeDesc, resMgr, null);
+		cpe.addStatusCallbackListener(aListener);
+		return cpe;
+	}
+
+	/**
+	 * Writes a temporary file containing a XML descriptor of the given resource. Returns the file.
+	 *
+	 * @param resource
+	 *            A resource specifier that should we materialized.
+	 * @return The file containing the XML representation of the given resource.
+	 */
+	private static File materializeDescriptor(ResourceSpecifier resource)
+		throws IOException, SAXException
+	{
+		File tempDesc = File.createTempFile("desc", ".xml");
+		tempDesc.deleteOnExit();
+		
+		BufferedWriter out = null;
+		try {
+			out = new BufferedWriter(new FileWriter(tempDesc));
+			resource.toXML(out);
+		}
+		finally {
+			IOUtils.closeQuietly(out);
+		}
+
+		return tempDesc;
+	}
+
+	private static CpeIntegratedCasProcessor createProcessor(String key, AnalysisEngineDescription aDesc)
+		throws IOException, SAXException, CpeDescriptorException
+	{
+		URL descUrl = materializeDescriptor(aDesc).toURI().toURL();
+
+		CpeInclude cpeInclude = getResourceSpecifierFactory().createInclude();
+		cpeInclude.set(descUrl.toString());
+
+		CpeComponentDescriptor ccd = getResourceSpecifierFactory().createDescriptor();
+		ccd.setInclude(cpeInclude);
+
+		CpeIntegratedCasProcessor proc = produceCasProcessor(key);
+		proc.setCpeComponentDescriptor(ccd);
+		proc.setAttributeValue(CpeDefaultValues.PROCESSING_UNIT_THREAD_COUNT, 1);
+		proc.setActionOnMaxError(ACTION_ON_MAX_ERROR);
+		proc.setMaxErrorCount(0);
+
+		return proc;
+	}
+}

Propchange: uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/CpeBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/ExternalResourceFactory.java
URL: http://svn.apache.org/viewvc/uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/ExternalResourceFactory.java?rev=1420723&view=auto
==============================================================================
--- uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/ExternalResourceFactory.java (added)
+++ uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/ExternalResourceFactory.java Wed Dec 12 14:58:37 2012
@@ -0,0 +1,961 @@
+/*
+ Copyright 2009
+ Ubiquitous Knowledge Processing (UKP) Lab
+ Technische Universitaet Darmstadt
+ All rights reserved.
+
+ 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.uimafit.factory;
+
+import static org.apache.uima.UIMAFramework.getResourceSpecifierFactory;
+import static org.uimafit.factory.ConfigurationParameterFactory.canParameterBeSet;
+import static org.uimafit.factory.ConfigurationParameterFactory.createConfigurationData;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.uima.analysis_engine.AnalysisEngineDescription;
+import org.apache.uima.collection.CollectionReaderDescription;
+import org.apache.uima.resource.ConfigurableDataResourceSpecifier;
+import org.apache.uima.resource.CustomResourceSpecifier;
+import org.apache.uima.resource.DataResource;
+import org.apache.uima.resource.ExternalResourceDependency;
+import org.apache.uima.resource.ExternalResourceDescription;
+import org.apache.uima.resource.FileResourceSpecifier;
+import org.apache.uima.resource.Parameter;
+import org.apache.uima.resource.ParameterizedDataResource;
+import org.apache.uima.resource.Resource;
+import org.apache.uima.resource.ResourceCreationSpecifier;
+import org.apache.uima.resource.ResourceManager;
+import org.apache.uima.resource.ResourceSpecifier;
+import org.apache.uima.resource.SharedResourceObject;
+import org.apache.uima.resource.impl.ConfigurableDataResourceSpecifier_impl;
+import org.apache.uima.resource.impl.ExternalResourceDependency_impl;
+import org.apache.uima.resource.impl.ExternalResourceDescription_impl;
+import org.apache.uima.resource.impl.FileResourceSpecifier_impl;
+import org.apache.uima.resource.impl.Parameter_impl;
+import org.apache.uima.resource.metadata.ExternalResourceBinding;
+import org.apache.uima.resource.metadata.ResourceManagerConfiguration;
+import org.apache.uima.resource.metadata.impl.ExternalResourceBinding_impl;
+import org.apache.uima.resource.metadata.impl.ResourceManagerConfiguration_impl;
+import org.apache.uima.resource.metadata.impl.ResourceMetaData_impl;
+import org.apache.uima.util.InvalidXMLException;
+import org.uimafit.descriptor.ExternalResource;
+import org.uimafit.factory.ConfigurationParameterFactory.ConfigurationData;
+import org.uimafit.util.ExtendedExternalResourceDescription_impl;
+
+/**
+ * Helper methods for external resources.
+ *
+ * @author Richard Eckart de Castilho
+ */
+public final class ExternalResourceFactory {
+	public static final String PARAM_RESOURCE_NAME = "__UIMAFIT_RESOURCE_NAME__";
+	
+	/**
+	 * Used to separate resource name from key for nested resource.
+	 */
+	public static final String PREFIX_SEPARATOR = "##";
+	
+	/**
+	 * Counter used to create unique resource names.
+	 */
+	private final static AtomicLong DISAMBIGUATOR = new AtomicLong();
+
+	private ExternalResourceFactory() {
+		// This class is not meant to be instantiated
+	}
+
+	/**
+	 * Create an external resource description for a custom resource. This is intended to
+	 * be used together with ....
+	 *
+	 * @param aInterface
+	 *            the interface the resource should implement.
+	 * @param aParams
+	 *            parameters passed to the resource when it is created.
+	 * @return the description.
+	 * @see CustomResourceSpecifier
+	 */
+	public static ExternalResourceDescription createExternalResourceDescription(
+			Class<? extends Resource> aInterface, Object... aParams) {
+		return createExternalResourceDescription(uniqueResourceKey(aInterface.getName()), aInterface, aParams);
+	}
+	
+	/**
+	 * Create an external resource description for a custom resource.
+	 *
+	 * @param aName
+	 *            the name of the resource (the key).
+	 * @param aInterface
+	 *            the interface the resource should implement.
+	 * @param aParams
+	 *            parameters passed to the resource when it is created.
+	 * @return the description.
+	 * @see CustomResourceSpecifier
+	 */
+	public static ExternalResourceDescription createExternalResourceDescription(final String aName,
+			Class<? extends Resource> aInterface, Object... aParams) {
+		ConfigurationParameterFactory.ensureParametersComeInPairs(aParams);
+
+		// Extract ExternalResourceDescriptions from configurationData
+		List<ExternalResourceBinding> bindings = new ArrayList<ExternalResourceBinding>();
+		List<ExternalResourceDescription> descs = new ArrayList<ExternalResourceDescription>();
+		for (Entry<String, ExternalResourceDescription> res : extractExternalResourceParameters(
+				aParams).entrySet()) {
+			bindings.add(createExternalResourceBinding(res.getKey(), res.getValue()));
+			descs.add(res.getValue());
+		}
+		
+		List<Parameter> params = new ArrayList<Parameter>();
+		if (aParams != null) {
+			for (int i = 0; i < aParams.length / 2; i++) {
+				if (aParams[i * 2 + 1] instanceof ExternalResourceDescription) {
+					continue;
+				}
+				
+				Parameter param = new Parameter_impl();
+				param.setName((String) aParams[i * 2]);
+				param.setValue((String) aParams[i * 2 + 1]);
+				params.add(param);
+			}
+		}
+
+		CustomResourceSpecifier spec = getResourceSpecifierFactory().createCustomResourceSpecifier();
+		spec.setResourceClassName(aInterface.getName());
+		spec.setParameters(params.toArray(new Parameter[params.size()]));
+
+		ExtendedExternalResourceDescription_impl extRes = new ExtendedExternalResourceDescription_impl();
+		extRes.setName(aName);
+		extRes.setResourceSpecifier(spec);
+		extRes.setExternalResourceBindings(bindings);
+		extRes.setExternalResources(descs);
+
+		return extRes;
+	}
+	
+	/**
+	 * Create an external resource description for a {@link SharedResourceObject}.
+	 *
+	 * @param aInterface
+	 *            the interface the resource should implement.
+	 * @param aUrl
+	 *            the URL from which the resource is initialized.
+	 * @param aParams
+	 *            parameters passed to the resource when it is created.
+	 * @return the description.
+	 * @see ConfigurableDataResourceSpecifier
+	 * @see SharedResourceObject
+	 */
+	public static ExternalResourceDescription createExternalResourceDescription(
+			Class<? extends SharedResourceObject> aInterface, String aUrl, Object... aParams) {
+		return createExternalResourceDescription(uniqueResourceKey(aInterface.getName()), 
+				aInterface, aUrl, aParams);
+	}
+
+	/**
+	 * Create an external resource description for a {@link SharedResourceObject}.
+	 *
+	 * @param aInterface
+	 *            the interface the resource should implement.
+	 * @param aUrl
+	 *            the URL from which the resource is initialized.
+	 * @param aParams
+	 *            parameters passed to the resource when it is created.
+	 * @return the description.
+	 * @see ConfigurableDataResourceSpecifier
+	 * @see SharedResourceObject
+	 */
+	public static ExternalResourceDescription createExternalResourceDescription(
+			Class<? extends SharedResourceObject> aInterface, URL aUrl, Object... aParams) {
+		return createExternalResourceDescription(uniqueResourceKey(aInterface.getName()), 
+				aInterface, aUrl.toString(), aParams);
+	}
+
+	/**
+	 * Create an external resource description for a {@link SharedResourceObject}.
+	 *
+	 * @param aInterface
+	 *            the interface the resource should implement.
+	 * @param aFile
+	 *            the file from which the resource is initialized.
+	 * @param aParams
+	 *            parameters passed to the resource when it is created.
+	 * @return the description.
+	 * @see ConfigurableDataResourceSpecifier
+	 * @see SharedResourceObject
+	 */
+	public static ExternalResourceDescription createExternalResourceDescription(
+			Class<? extends SharedResourceObject> aInterface, File aFile, Object... aParams) {
+		try {
+			return createExternalResourceDescription(aInterface, aFile.toURI().toURL(), aParams);
+		}
+		catch (MalformedURLException e) {
+			// This is something that usually cannot happen, so we degrade this to an 
+			// IllegalArgumentException which is a RuntimeException that does not need to be caught.
+			throw new IllegalArgumentException("File converts to illegal URL [" + aFile + "]");
+		}
+	}
+
+	/**
+	 * Create an external resource description for a {@link SharedResourceObject}.
+	 *
+	 * @param aName
+	 *            the name of the resource (the key).
+	 * @param aInterface
+	 *            the interface the resource should implement.
+	 * @param aUrl
+	 *            the URL from which the resource is initialized.
+	 * @param aParams
+	 *            parameters passed to the resource when it is created.
+	 * @return the description.
+	 * @see ConfigurableDataResourceSpecifier
+	 * @see SharedResourceObject
+	 */
+	public static ExternalResourceDescription createExternalResourceDescription(final String aName,
+			Class<? extends SharedResourceObject> aInterface, String aUrl, Object... aParams) {
+		ConfigurationData cfg = ConfigurationParameterFactory.createConfigurationData(aParams);
+		ResourceMetaData_impl meta = new ResourceMetaData_impl();
+
+		ConfigurationData reflectedConfigurationData = createConfigurationData(aInterface);
+		ResourceCreationSpecifierFactory.setConfigurationParameters(meta,
+				reflectedConfigurationData.configurationParameters,
+				reflectedConfigurationData.configurationValues);
+		ResourceCreationSpecifierFactory.setConfigurationParameters(meta,
+				cfg.configurationParameters, cfg.configurationValues);
+
+		ConfigurableDataResourceSpecifier_impl spec = new ConfigurableDataResourceSpecifier_impl();
+		spec.setUrl(aUrl);
+		spec.setMetaData(meta);
+
+		ExtendedExternalResourceDescription_impl extRes = new ExtendedExternalResourceDescription_impl();
+		extRes.setName(aName);
+		extRes.setResourceSpecifier(spec);
+		extRes.setImplementationName(aInterface.getName());
+		
+		return extRes;
+	}
+
+	/**
+	 * Create an external resource description for a file addressable via an URL.
+	 *
+	 * @param aName
+	 *            the name of the resource (the key).
+	 * @param aUrl
+	 *            a URL.
+	 * @return the description.
+	 * @see FileResourceSpecifier
+	 */
+	public static ExternalResourceDescription createExternalResourceDescription(final String aName,
+			String aUrl) {
+		ExternalResourceDescription extRes = new ExternalResourceDescription_impl();
+		extRes.setName(aName);
+		FileResourceSpecifier frs = new FileResourceSpecifier_impl();
+		frs.setFileUrl(aUrl);
+		extRes.setResourceSpecifier(frs);
+		return extRes;
+	}
+
+	/**
+	 * Create an external resource binding.
+	 *
+	 * @param aKey
+	 *            the key to bind to.
+	 * @param aResource
+	 *            the resource to bind.
+	 * @return the description.
+	 */
+	public static ExternalResourceBinding createExternalResourceBinding(final String aKey,
+			final ExternalResourceDescription aResource) {
+		return createExternalResourceBinding(aKey, aResource.getName());
+	}
+
+	/**
+	 * Create an external resource binding.
+	 *
+	 * @param aKey
+	 *            the key to bind to.
+	 * @param aResourceKey
+	 *            the resource key to bind.
+	 * @return the description.
+	 */
+	public static ExternalResourceBinding createExternalResourceBinding(final String aKey,
+			final String aResourceKey) {
+		ExternalResourceBinding extResBind = new ExternalResourceBinding_impl();
+		extResBind.setResourceName(aResourceKey);
+		extResBind.setKey(aKey);
+		return extResBind;
+	}
+
+	/**
+	 * Creates an ExternalResourceDependency for a given key and interface
+	 *
+	 * @param aOptional
+	 *            determines whether the dependency is optional
+	 */
+	public static ExternalResourceDependency createExternalResourceDependency(final String aKey,
+			final Class<?> aInterface, final boolean aOptional) {
+		ExternalResourceDependency dep = new ExternalResourceDependency_impl();
+		dep.setInterfaceName(aInterface.getName());
+		dep.setKey(aKey);
+		dep.setOptional(aOptional);
+		return dep;
+	}
+
+	/**
+	 * Scan the given resource specifier for external resource dependencies and whenever a
+	 * dependency is encounter that has the specified key, the resource will be bound.
+	 * <p>
+	 * <b>Caveat</b>: If you use this method, you may expect that {@link DataResource#getUrl()} or
+	 * {@link DataResource#getUri()} will return the same URL that you have specified here. This may
+	 * <b>NOT</b> be the case. UIMA will internally try to resolve the URL via a
+	 * {@link ResourceManager}. If it cannot resolve a remove URL, this mechanism will think it may
+	 * be a local file and will return some local path - or it may redirect it to some location as
+	 * though fit by the {@link ResourceManager}.
+	 *
+	 * @param aDesc
+	 *            a description.
+	 * @param aKey
+	 *            the key to bind to.
+	 * @param aUrl
+	 *            a URL.
+	 * @see FileResourceSpecifier
+	 */
+	public static void bindResource(ResourceSpecifier aDesc, String aKey, URL aUrl)
+			throws InvalidXMLException {
+		bindResource(aDesc, aKey, aUrl.toString());
+	}
+
+	/**
+	 * Scan the given resource specifier for external resource dependencies and whenever a
+	 * dependency is encounter that has the specified key, the resource will be bound.
+	 * <p>
+	 * <b>Caveat</b>: If you use this method, you may expect that {@link DataResource#getUrl()} or
+	 * {@link DataResource#getUri()} will return the URL of the file that you have specified here.
+	 * This may <b>NOT</b> be the case. UIMA will internally try to resolve the URL via a
+	 * {@link ResourceManager}. If it cannot resolve a remove URL, this mechanism will think it may
+	 * be a local file and will return some local path - or it may redirect it to some location as
+	 * though fit by the {@link ResourceManager}.
+	 *
+	 * @param aDesc
+	 *            a description.
+	 * @param aKey
+	 *            the key to bind to.
+	 * @param aFile
+	 *            a file.
+	 * @see FileResourceSpecifier
+	 */
+	public static void bindResource(ResourceSpecifier aDesc, String aKey, File aFile)
+			throws InvalidXMLException {
+		try {
+			bindResource(aDesc, aKey, aFile.toURI().toURL());
+		}
+		catch (MalformedURLException e) {
+			// This is something that usually cannot happen, so we degrade this to an 
+			// IllegalArgumentException which is a RuntimeException that does not need to be caught.
+			throw new IllegalArgumentException("File converts to illegal URL [" + aFile + "]");
+		}
+	}
+
+	/**
+	 * Scan the given resource specifier for external resource dependencies and whenever a
+	 * dependency is encounter that has the specified key, the resource will be bound.
+	 * <p>
+	 * <b>Caveat</b>: If you use this method, you may expect that {@link DataResource#getUrl()} or
+	 * {@link DataResource#getUri()} will return the same URL that you have specified here. This is
+	 * may <b>NOT</b> be the case. UIMA will internally try to resolve the URL via a
+	 * {@link ResourceManager}. If it cannot resolve a remove URL, this mechanism will think it may
+	 * be a local file and will return some local path - or it may redirect it to some location as
+	 * though fit by the {@link ResourceManager}.
+	 *
+	 * @param aDesc
+	 *            a description.
+	 * @param aKey
+	 *            the key to bind to.
+	 * @param aUrl
+	 *            a URL.
+	 * @see FileResourceSpecifier
+	 */
+	public static void bindResource(ResourceSpecifier aDesc, String aKey, String aUrl)
+			throws InvalidXMLException {
+		ExternalResourceDescription extRes = createExternalResourceDescription(aKey, aUrl);
+		bindResource(aDesc, aKey, extRes);
+	}
+
+	/**
+	 * Scan the given resource specifier for external resource dependencies and whenever a
+	 * dependency is encounter that has a key equal to the resource class name, the resource will be
+	 * bound.
+	 *
+	 * @param aDesc
+	 *            a description.
+	 * @param aRes
+	 *            the resource to bind.
+	 * @param aParams
+	 *            parameters passed to the resource when it is created.
+	 * @see CustomResourceSpecifier
+	 */
+	public static void bindResource(ResourceSpecifier aDesc, Class<? extends Resource> aRes,
+			String... aParams) throws InvalidXMLException {
+		bindResource(aDesc, aRes, aRes, aParams);
+	}
+
+	/**
+	 * Scan the given resource specifier for external resource dependencies and whenever a
+	 * dependency is encounter that has a key equal to the API class name, the resource will be
+	 * bound.
+	 *
+	 * @param aDesc
+	 *            a description.
+	 * @param aApi
+	 *            the resource interface.
+	 * @param aRes
+	 *            the resource to bind.
+	 * @param aParams
+	 *            parameters passed to the resource when it is created.
+	 * @see CustomResourceSpecifier
+	 */
+	public static void bindResource(ResourceSpecifier aDesc, Class<?> aApi,
+			Class<? extends Resource> aRes, String... aParams) throws InvalidXMLException {
+		// Appending a disambiguation suffix it possible to have multiple instances of the same
+		// resource with different settings to different keys.
+		ExternalResourceDescription extRes = createExternalResourceDescription(
+				uniqueResourceKey(aRes.getName()), aRes, (Object[]) aParams);
+		bindResource(aDesc, aApi.getName(), extRes);
+	}
+
+	/**
+	 * Scan the given resource specifier for external resource dependencies and whenever a
+	 * dependency is encountered that has a key equal to the resource class name, the resource will
+	 * be bound.
+	 *
+	 * @param aDesc
+	 *            a description.
+	 * @param aRes
+	 *            the resource to bind.
+	 * @param aUrl
+	 *            the URL from which the resource is initialized.
+	 * @param aParams
+	 *            parameters passed to the resource when it is created.
+	 * @see SharedResourceObject
+	 */
+	public static void bindResource(ResourceSpecifier aDesc,
+			Class<? extends SharedResourceObject> aRes, String aUrl, Object... aParams)
+			throws InvalidXMLException {
+		bindResource(aDesc, aRes, aRes, aUrl, aParams);
+	}
+
+	/**
+	 * Scan the given resource specifier for external resource dependencies and whenever a
+	 * dependency is encountered that has a key equal to the API class name, the resource will be
+	 * bound.
+	 *
+	 * @param aDesc
+	 *            a description.
+	 * @param aApi
+	 *            the resource interface.
+	 * @param aRes
+	 *            the resource to bind.
+	 * @param aUrl
+	 *            the URL from which the resource is initialized.
+	 * @param aParams
+	 *            parameters passed to the resource when it is created.
+	 * @see SharedResourceObject
+	 */
+	public static void bindResource(ResourceSpecifier aDesc, Class<?> aApi,
+			Class<? extends SharedResourceObject> aRes, String aUrl, Object... aParams)
+			throws InvalidXMLException {
+		bindResource(aDesc, aApi.getName(), aRes, aUrl, aParams);
+	}
+
+	/**
+	 * Scan the given resource specifier for external resource dependencies and whenever a
+	 * dependency with the given key is encountered the resource will be bound.
+	 *
+	 * @param aDesc
+	 *            a description.
+	 * @param aKey
+	 *            the key to bind to.
+	 * @param aRes
+	 *            the resource to bind.
+	 * @param aUrl
+	 *            the URL from which the resource is initialized.
+	 * @param aParams
+	 *            parameters passed to the resource when it is created.
+	 * @see SharedResourceObject
+	 */
+	public static void bindResource(ResourceSpecifier aDesc, String aKey,
+			Class<? extends SharedResourceObject> aRes, String aUrl, Object... aParams)
+			throws InvalidXMLException {
+		ExternalResourceDescription extRes = createExternalResourceDescription(
+				uniqueResourceKey(aRes.getName()), aRes, aUrl, aParams);
+		bind((AnalysisEngineDescription) aDesc, aKey, extRes);
+	}
+
+	/**
+	 * Scan the given resource specifier for external resource dependencies and whenever a
+	 * dependency with the given key is encountered, the given resource is bound to it.
+	 *
+	 * @param aDesc
+	 *            a description.
+	 * @param aKey
+	 *            the key to bind to.
+	 * @param aRes
+	 *            the resource to bind.
+	 * @param aParams
+	 *            parameters passed to the resource when it is created.
+	 * @see CustomResourceSpecifier
+	 */
+	public static void bindResource(ResourceSpecifier aDesc, String aKey,
+			Class<? extends Resource> aRes, String... aParams) throws InvalidXMLException {
+		if (ParameterizedDataResource.class.isAssignableFrom(aRes)) {
+			createDependency(aDesc, aKey, DataResource.class);
+		}
+
+		// Appending a disambiguation suffix it possible to have multiple instances of the same
+		// resource with different settings to different keys.
+		ExternalResourceDescription extRes = createExternalResourceDescription(
+				uniqueResourceKey(aRes.getName()), aRes, (Object[]) aParams);
+		bindResource(aDesc, aKey, extRes);
+	}
+
+	/**
+	 * Scan the given resource specifier for external resource dependencies and whenever a
+	 * dependency with the given key is encountered, the given resource is bound to it.
+	 *
+	 * @param aDesc
+	 *            a description.
+	 * @param aKey
+	 *            the key to bind to.
+	 * @param aResDesc
+	 *            the resource description.
+	 */
+	public static void bindResource(ResourceSpecifier aDesc, String aKey,
+			ExternalResourceDescription aResDesc) throws InvalidXMLException {
+		// Dispatch
+		if (aDesc instanceof AnalysisEngineDescription) {
+			bind((AnalysisEngineDescription) aDesc, aKey, aResDesc);
+		}
+	}
+
+	/**
+	 * Create a new dependency for the specified resource and bind it. This method is helpful for
+	 * UIMA components that do not use the uimaFIT {@link ExternalResource} annotation, because no
+	 * external resource dependencies can be automatically generated by uimaFIT for such components.
+	 *
+	 * @param aDesc
+	 *            a description.
+	 * @param aKey
+	 *            the key to bind to.
+	 * @param aImpl
+	 *            the resource implementation.
+	 * @param aParams
+	 *            additional parameters supported by the resource.
+	 */
+	public static void createDependencyAndBind(ResourceSpecifier aDesc, String aKey,
+			Class<? extends Resource> aImpl, String... aParams)
+			throws InvalidXMLException {
+		Class<?> api = (ParameterizedDataResource.class.isAssignableFrom(aImpl)) ? DataResource.class
+				: aImpl;
+		createDependencyAndBind(aDesc, aKey, aImpl, api, aParams);
+	}
+
+	/**
+	 * Create a new dependency for the specified resource and bind it. This method is helpful for
+	 * UIMA components that do not use the uimaFIT {@link ExternalResource} annotation, because no
+	 * external resource dependencies can be automatically generated by uimaFIT for such components.
+	 *
+	 * @param aDesc
+	 *            a description.
+	 * @param aKey
+	 *            the key to bind to.
+	 * @param aImpl
+	 *            the resource implementation.
+	 * @param aParams
+	 *            additional parameters supported by the resource.
+	 */
+	public static void createDependencyAndBind(ResourceSpecifier aDesc, String aKey,
+			Class<? extends Resource> aImpl, Class<?> aApi, String... aParams)
+			throws InvalidXMLException {
+		createDependency(aDesc, aKey, aApi);
+		bindResource(aDesc, aKey, aImpl, aParams);
+	}
+
+
+	/**
+	 * Create a new dependency for the specified resource and bind it. This method is helpful for
+	 * UIMA components that do not use the uimaFIT {@link ExternalResource} annotation, because no
+	 * external resource dependencies can be automatically generated by uimaFIT for such components.
+	 *
+	 * @param aDesc
+	 *            a description.
+	 * @param aKey
+	 *            the key to bind to.
+	 * @param aApi
+	 *            the resource API.
+	 */
+	public static void createDependency(ResourceSpecifier aDesc, String aKey, Class<?> aApi)
+			throws InvalidXMLException {
+		ExternalResourceDependency[] deps = getExternalResourceDependencies(aDesc);
+		if (deps == null) {
+			deps = new ExternalResourceDependency[] {};
+		}
+
+		// Check if the resource dependency is already present
+		boolean found = false;
+		for (ExternalResourceDependency dep : deps) {
+			if (dep.getKey().equals(aKey)) {
+				found = true;
+				break;
+			}
+		}
+
+		// If not, create one
+		if (!found) {
+			setExternalResourceDependencies(aDesc, (ExternalResourceDependency[]) ArrayUtils.add(
+					deps, createExternalResourceDependency(aKey, aApi, false)));		}
+	}
+	
+	/**
+	 * Convenience method to set the external resource dependencies on a resource specifier. 
+	 * Unfortunately different methods need to be used for different sub-classes.
+	 * 
+	 * @throws IllegalArgumentException if the sub-class passed is not supported.
+	 */
+	private static void setExternalResourceDependencies(
+			ResourceSpecifier aDesc, ExternalResourceDependency[] aDependencies) {
+		if (aDesc instanceof CollectionReaderDescription) {
+			((CollectionReaderDescription) aDesc).setExternalResourceDependencies(aDependencies);
+		}
+		else if (aDesc instanceof AnalysisEngineDescription) {
+			((AnalysisEngineDescription) aDesc).setExternalResourceDependencies(aDependencies);
+		}
+		else {
+			throw new IllegalArgumentException("Resource specified cannot have external resource dependencies");
+		}
+	}
+
+	/**
+	 * Convenience method to get the external resource dependencies from a resource specifier. 
+	 * Unfortunately different methods need to be used for different sub-classes.
+	 * 
+	 * @throws IllegalArgumentException if the sub-class passed is not supported.
+	 */
+	private static ExternalResourceDependency[] getExternalResourceDependencies(
+			ResourceSpecifier aDesc) {
+		if (aDesc instanceof CollectionReaderDescription) {
+			return ((CollectionReaderDescription) aDesc).getExternalResourceDependencies();
+		}
+		else if (aDesc instanceof AnalysisEngineDescription) {
+			return ((AnalysisEngineDescription) aDesc).getExternalResourceDependencies();
+		}
+		else {
+			throw new IllegalArgumentException("Resource specified cannot have external resource dependencies");
+		}
+	}
+	/**
+	 * Create a new dependency for the specified resource and bind it. This method is helpful for
+	 * UIMA components that do not use the uimaFIT {@link ExternalResource} annotation, because no
+	 * external resource dependencies can be automatically generated by uimaFIT for such components.
+	 *
+	 * @param aDesc
+	 *            a description.
+	 * @param aKey
+	 *            the key to bind to.
+	 * @param aImpl
+	 *            the resource implementation.
+	 * @param aUrl
+	 *            the resource URL.
+	 * @param aParams
+	 *            additional parameters supported by the resource.
+	 */
+	public static void createDependencyAndBind(AnalysisEngineDescription aDesc, String aKey,
+			Class<? extends SharedResourceObject> aImpl, String aUrl, Object... aParams)
+			throws InvalidXMLException {
+		if (aDesc.getExternalResourceDependency(aKey) == null) {
+			ExternalResourceDependency[] deps = aDesc.getExternalResourceDependencies();
+			if (deps == null) {
+				deps = new ExternalResourceDependency[] {};
+			}
+			aDesc.setExternalResourceDependencies((ExternalResourceDependency[]) ArrayUtils.add(
+					deps, createExternalResourceDependency(aKey, aImpl, false)));
+		}
+		bindResource(aDesc, aKey, aImpl, aUrl, aParams);
+	}
+
+	/**
+	 * Scan the given resource specifier for external resource dependencies and whenever a
+	 * dependency with the given key is encountered, the given resource is bound to it.
+	 *
+	 * @param aDesc
+	 *            a description.
+	 * @param aKey
+	 *            the key to bind to.
+	 * @param aResDesc
+	 *            the resource description.
+	 */
+	private static void bind(AnalysisEngineDescription aDesc, String aKey,
+			ExternalResourceDescription aResDesc) throws InvalidXMLException {
+		// Recursively address delegates
+		if (!aDesc.isPrimitive()) {
+			for (Object delegate : aDesc.getDelegateAnalysisEngineSpecifiers().values()) {
+				bindResource((ResourceSpecifier) delegate, aKey, aResDesc);
+			}
+		}
+
+		// Bind if necessary
+		for (ExternalResourceDependency dep : aDesc.getExternalResourceDependencies()) {
+			if (aKey.equals(dep.getKey())) {
+				bindExternalResource(aDesc, aKey, aResDesc);
+			}
+		}
+	}
+
+	/**
+	 * Create a new external resource binding.
+	 *
+	 * @param aResMgrCfg
+	 *            the resource manager to create the binding in.
+	 * @param aBindTo
+	 *            what key to bind to.
+	 * @param aRes
+	 *            the resource that should be bound.
+	 */
+	public static void bindExternalResource(ResourceManagerConfiguration aResMgrCfg,
+			String aBindTo, ExternalResourceDescription aRes) {
+		// Create a map of all bindings
+		Map<String, ExternalResourceBinding> bindings = new HashMap<String, ExternalResourceBinding>();
+		for (ExternalResourceBinding b : aResMgrCfg.getExternalResourceBindings()) {
+			bindings.put(b.getKey(), b);
+		}
+		
+		// Create a map of all resources
+		Map<String, ExternalResourceDescription> resources = new HashMap<String, ExternalResourceDescription>();
+		for (ExternalResourceDescription r : aResMgrCfg.getExternalResources()) {
+			resources.put(r.getName(), r);
+		}
+		
+		// For the current resource, add resource and binding
+		ExternalResourceBinding extResBind = createExternalResourceBinding(aBindTo, aRes);
+		bindings.put(extResBind.getKey(), extResBind);
+		resources.put(aRes.getName(), aRes);
+		
+		// Handle nested resources
+		bindNestedResources(aRes, bindings, resources);
+		
+		// Commit everything to the resource manager configuration
+		aResMgrCfg.setExternalResourceBindings(bindings.values().toArray(
+				new ExternalResourceBinding[bindings.size()]));
+		aResMgrCfg.setExternalResources(resources.values().toArray(
+				new ExternalResourceDescription[resources.size()]));
+	}
+	
+	/**
+	 * Create a new external resource binding.
+	 * 
+	 * @param aRes
+	 *            the resource to bind to
+	 * @param aBindTo
+	 *            what key to bind to.
+	 * @param aNestedRes
+	 *            the resource that should be bound.
+	 */
+	public static void bindExternalResource(ExternalResourceDescription aRes, String aBindTo,
+			ExternalResourceDescription aNestedRes) {
+		if (!(aRes instanceof ExtendedExternalResourceDescription_impl)) {
+			throw new IllegalArgumentException(
+					"Nested resources are only supported on instances of [" + 
+					ExtendedExternalResourceDescription_impl.class.getName() + "] which" + 
+					"can be created with uimaFIT's createExternalResourceDescription() methods.");
+		}
+
+		ExtendedExternalResourceDescription_impl extRes = (ExtendedExternalResourceDescription_impl) aRes;
+
+		// Create a map of all bindings
+		Map<String, ExternalResourceBinding> bindings = new HashMap<String, ExternalResourceBinding>();
+		for (ExternalResourceBinding b : extRes.getExternalResourceBindings()) {
+			bindings.put(b.getKey(), b);
+		}
+		
+		// Create a map of all resources
+		Map<String, ExternalResourceDescription> resources = new HashMap<String, ExternalResourceDescription>();
+		for (ExternalResourceDescription r : extRes.getExternalResources()) {
+			resources.put(r.getName(), r);
+		}
+		
+		// For the current resource, add resource and binding
+		ExternalResourceBinding extResBind = createExternalResourceBinding(aBindTo, aNestedRes);
+		bindings.put(extResBind.getKey(), extResBind);
+		resources.put(aRes.getName(), aRes);
+		
+		// Handle nested resources
+		bindNestedResources(aRes, bindings, resources);
+		
+		// Commit everything to the resource manager configuration
+		extRes.setExternalResourceBindings(bindings.values());
+		extRes.setExternalResources(resources.values());
+		
+	}
+	
+	/**
+	 * Helper method to recursively bind resources bound to resources.
+	 * 
+	 * @param aRes resource.
+	 * @param aBindings bindings already made.
+	 * @param aResources resources already bound.
+	 */
+	private static void bindNestedResources(ExternalResourceDescription aRes,
+			Map<String, ExternalResourceBinding> aBindings,
+			Map<String, ExternalResourceDescription> aResources)	{
+		// Handle nested resources
+		if (aRes instanceof ExtendedExternalResourceDescription_impl) {
+			ExtendedExternalResourceDescription_impl extRes = (ExtendedExternalResourceDescription_impl) aRes;
+			
+			// Tell the external resource its name. This is needed in order to find the resources
+			// bound to this resource later on. Set only if the resource supports this parameter.
+			// Mind that supporting this parameter is mandatory for resource implementing 
+			// ExternalResourceAware.
+			if (canParameterBeSet(extRes.getResourceSpecifier(), PARAM_RESOURCE_NAME)) {
+				ConfigurationParameterFactory.setParameter(extRes.getResourceSpecifier(),
+						PARAM_RESOURCE_NAME, aRes.getName());
+			}
+			
+			// Create a map of all resources
+			Map<String, ExternalResourceDescription> res = new HashMap<String, ExternalResourceDescription>();
+			for (ExternalResourceDescription r : extRes.getExternalResources()) {
+				res.put(r.getName(), r);
+			}
+			
+			// Bind nested resources
+			for (ExternalResourceBinding b : extRes.getExternalResourceBindings()) {
+				// Avoid re-prefixing the resource name
+				String key = b.getKey();
+				if (!key.startsWith(aRes.getName() + PREFIX_SEPARATOR)) {
+					key = aRes.getName() + PREFIX_SEPARATOR + b.getKey();
+				}
+				// Avoid unnecessary binding and an infinite loop when a resource binds to itself
+				if (!aBindings.containsKey(key)) {
+					// Mark the current binding as processed so we do not recurse
+					aBindings.put(key, b);
+					ExternalResourceDescription nestedRes = res.get(b.getResourceName());
+					aResources.put(nestedRes.getName(), nestedRes);
+					bindNestedResources(nestedRes, aBindings, aResources);
+					// Set the proper key on the binding.
+					b.setKey(key);
+				}
+			}
+		}
+	}
+	
+	/**
+	 * Create a new external resource binding.
+	 *
+	 * @param aDesc
+	 *            the specifier to create the binding in.
+	 * @param aBindTo
+	 *            what key to bind to.
+	 * @param aRes
+	 *            the resource that should be bound.
+	 */
+	public static void bindExternalResource(ResourceCreationSpecifier aDesc,
+			String aBindTo, ExternalResourceDescription aRes) {
+		ResourceManagerConfiguration resMgrCfg = aDesc.getResourceManagerConfiguration();
+		if (resMgrCfg == null) {
+			resMgrCfg = new ResourceManagerConfiguration_impl();
+			aDesc.setResourceManagerConfiguration(resMgrCfg);
+		}
+		
+		bindExternalResource(resMgrCfg, aBindTo, aRes);
+	}
+
+	/**
+	 * Create a new external resource binding.
+	 *
+	 * @param aResMgrCfg
+	 *            the resource manager to create the binding in.
+	 * @param aBindTo
+	 *            what key to bind to.
+	 * @param aRes
+	 *            the resource that should be bound.
+	 */
+	public static void bindExternalResource(ResourceManagerConfiguration aResMgrCfg,
+			String aBindTo, String aRes) {
+		ExternalResourceBinding extResBind = createExternalResourceBinding(aBindTo, aRes);
+		aResMgrCfg.addExternalResourceBinding(extResBind);
+	}
+
+	/**
+	 * Create a new external resource binding.
+	 *
+	 * @param aDesc
+	 *            the specifier to create the binding in.
+	 * @param aBindTo
+	 *            what key to bind to.
+	 * @param aRes
+	 *            the resource that should be bound.
+	 */
+	public static void bindExternalResource(ResourceCreationSpecifier aDesc,
+			String aBindTo, String aRes) {
+		ResourceManagerConfiguration resMgrCfg = aDesc.getResourceManagerConfiguration();
+		if (resMgrCfg == null) {
+			resMgrCfg = new ResourceManagerConfiguration_impl();
+			aDesc.setResourceManagerConfiguration(resMgrCfg);
+		}
+
+		bindExternalResource(resMgrCfg, aBindTo, aRes);
+	}
+	
+	static String uniqueResourceKey(String aKey)
+	{
+		return aKey + '-' + DISAMBIGUATOR.getAndIncrement();
+	}
+	
+	/**
+	 * Extracts the external resource from the configuration parameters and nulls out these
+	 * parameters. Mind that the array passed to this method is modified by the method.
+	 * 
+	 * @param configurationData the configuration parameters.
+	 * @return extRes the external resource parameters.
+	 */
+	protected static Map<String, ExternalResourceDescription> extractExternalResourceParameters(
+			final Object[] configurationData) {
+		if (configurationData == null) {
+			return Collections.emptyMap();
+		}
+	
+		Map<String, ExternalResourceDescription> extRes = new HashMap<String, ExternalResourceDescription>();
+		for (int i = 0; i < configurationData.length - 1; i += 2) {
+			String key = (String) configurationData[i];
+			Object value = configurationData[i + 1];
+
+			// Store External Resource parameters separately
+			if (value instanceof ExternalResourceDescription) {
+				ExternalResourceDescription description = (ExternalResourceDescription) value;
+				extRes.put(key, description);
+			}
+		}
+		
+		return extRes;
+	}
+}

Propchange: uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/ExternalResourceFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/FlowControllerFactory.java
URL: http://svn.apache.org/viewvc/uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/FlowControllerFactory.java?rev=1420723&view=auto
==============================================================================
--- uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/FlowControllerFactory.java (added)
+++ uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/FlowControllerFactory.java Wed Dec 12 14:58:37 2012
@@ -0,0 +1,125 @@
+/*
+  Copyright 2010 Regents of the University of Colorado.
+ All rights reserved.
+
+ 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.uimafit.factory;
+
+import static org.uimafit.factory.ConfigurationParameterFactory.createConfigurationData;
+import static org.uimafit.factory.ConfigurationParameterFactory.ensureParametersComeInPairs;
+import static org.uimafit.factory.ExternalResourceFactory.bindExternalResource;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.uima.Constants;
+import org.apache.uima.flow.FlowController;
+import org.apache.uima.flow.FlowControllerDescription;
+import org.apache.uima.flow.impl.FlowControllerDescription_impl;
+import org.apache.uima.resource.ExternalResourceDependency;
+import org.apache.uima.resource.ExternalResourceDescription;
+import org.apache.uima.resource.ResourceInitializationException;
+import org.apache.uima.resource.metadata.ConfigurationParameter;
+import org.apache.uima.resource.metadata.ResourceMetaData;
+import org.uimafit.component.initialize.ExternalResourceInitializer;
+import org.uimafit.factory.ConfigurationParameterFactory.ConfigurationData;
+
+/**
+ * @author Fabio Mancinelli, Philip Ogren
+ */
+
+public final class FlowControllerFactory {
+	private FlowControllerFactory() {
+		// This class is not meant to be instantiated
+	}
+
+	/**
+	 * Creates a new FlowControllerDescription for a given class and configuration data
+	 * 
+	 * @param configurationData
+	 *            should be configuration parameter name / value pairs.
+	 */
+	public static FlowControllerDescription createFlowControllerDescription(
+			Class<? extends FlowController> flowControllerClass, Object... configurationData)
+			throws ResourceInitializationException {
+
+		ensureParametersComeInPairs(configurationData);
+
+		// Extract ExternalResourceDescriptions from configurationData
+		// <ParamterName, ExternalResourceDescription> will be stored in this map
+		Map<String, ExternalResourceDescription> externalResources = 
+				ExternalResourceFactory.extractExternalResourceParameters(configurationData);
+
+		// Create description normally
+		ConfigurationData cdata = createConfigurationData(configurationData);
+		return createFlowControllerDescription(flowControllerClass, cdata.configurationParameters,
+				cdata.configurationValues, externalResources);
+	}
+
+	public static FlowControllerDescription createFlowControllerDescription(
+			Class<? extends FlowController> flowControllerClass,
+			ConfigurationParameter[] configurationParameters, Object[] configurationValues)
+			throws ResourceInitializationException {
+		return createFlowControllerDescription(flowControllerClass, configurationParameters,
+				configurationValues, null);
+	}
+	
+	/**
+	 * Creates a new FlowControllerDescription for a given class and configuration parameters with
+	 * values
+	 */
+	public static FlowControllerDescription createFlowControllerDescription(
+			Class<? extends FlowController> flowControllerClass,
+			ConfigurationParameter[] configurationParameters, Object[] configurationValues,
+			Map<String, ExternalResourceDescription> externalResources)
+			throws ResourceInitializationException {
+		FlowControllerDescription desc = new FlowControllerDescription_impl();
+		desc.setFrameworkImplementation(Constants.JAVA_FRAMEWORK_NAME);
+		desc.setImplementationName(flowControllerClass.getName());
+
+		ConfigurationData reflectedConfigurationData = ConfigurationParameterFactory
+				.createConfigurationData(flowControllerClass);
+		ResourceCreationSpecifierFactory.setConfigurationParameters(desc,
+				reflectedConfigurationData.configurationParameters,
+				reflectedConfigurationData.configurationValues);
+		if (configurationParameters != null) {
+			ResourceCreationSpecifierFactory.setConfigurationParameters(desc,
+					configurationParameters, configurationValues);
+		}
+
+		ResourceMetaData meta = desc.getMetaData();
+		meta.setName(flowControllerClass.getName());
+		meta.setVendor(flowControllerClass.getPackage().toString());
+		meta.setDescription("Descriptor automatically generated by uimaFIT");
+		meta.setVersion("unknown");
+
+		// Extract external resource dependencies
+		Collection<ExternalResourceDependency> deps = ExternalResourceInitializer
+				.getResourceDeclarations(flowControllerClass).values();
+		desc.setExternalResourceDependencies(deps.toArray(new ExternalResourceDependency[deps
+				.size()]));
+
+		// Bind External Resources
+		if (externalResources != null) {
+			for (Entry<String, ExternalResourceDescription> e : externalResources.entrySet()) {
+				bindExternalResource(desc, e.getKey(), e.getValue());
+			}
+		}
+
+		return desc;
+	}
+
+}

Propchange: uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/FlowControllerFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/FsIndexFactory.java
URL: http://svn.apache.org/viewvc/uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/FsIndexFactory.java?rev=1420723&view=auto
==============================================================================
--- uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/FsIndexFactory.java (added)
+++ uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/FsIndexFactory.java Wed Dec 12 14:58:37 2012
@@ -0,0 +1,267 @@
+/*
+ Copyright 2011
+ Ubiquitous Knowledge Processing (UKP) Lab
+ Technische Universitaet Darmstadt
+ All rights reserved.
+
+ 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.uimafit.factory;
+
+import static java.util.Arrays.asList;
+import static org.apache.uima.UIMAFramework.getXMLParser;
+import static org.uimafit.util.ReflectionUtil.getInheritableAnnotation;
+import static org.uimafit.factory.TypeSystemDescriptionFactory.resolve;
+import static org.uimafit.factory.TypeSystemDescriptionFactory.scanImportsAndManifests;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.LogFactory;
+import org.apache.uima.resource.ResourceInitializationException;
+import org.apache.uima.resource.metadata.FsIndexCollection;
+import org.apache.uima.resource.metadata.FsIndexDescription;
+import org.apache.uima.resource.metadata.FsIndexKeyDescription;
+import org.apache.uima.resource.metadata.Import;
+import org.apache.uima.resource.metadata.TypeSystemDescription;
+import org.apache.uima.resource.metadata.impl.FsIndexCollection_impl;
+import org.apache.uima.resource.metadata.impl.FsIndexDescription_impl;
+import org.apache.uima.resource.metadata.impl.FsIndexKeyDescription_impl;
+import org.apache.uima.resource.metadata.impl.Import_impl;
+import org.apache.uima.util.InvalidXMLException;
+import org.apache.uima.util.XMLInputSource;
+import org.uimafit.descriptor.FsIndex;
+import org.uimafit.descriptor.FsIndexKey;
+
+/**
+ * @author Richard Eckart de Castilho
+ */
+public final class FsIndexFactory {
+	  public static final int STANDARD_COMPARE = FsIndexKeyDescription.STANDARD_COMPARE;
+
+	  public static final int REVERSE_STANDARD_COMPARE = FsIndexKeyDescription.STANDARD_COMPARE;
+
+	private FsIndexFactory() {
+		// Factory class
+	}  
+	  
+	/**
+	 * Create index configuration data for a given class definition using reflection and the
+	 * configuration parameter annotation.
+	 */
+	public static FsIndexCollection createFsIndexCollection(Class<?> componentClass) {
+		List<FsIndex> anFsIndexList = new ArrayList<FsIndex>();
+
+		// Check FsIndexCollection annotation
+		org.uimafit.descriptor.FsIndexCollection anIndexCollection =
+			getInheritableAnnotation(org.uimafit.descriptor.FsIndexCollection.class, componentClass);
+		if (anIndexCollection != null) {
+			anFsIndexList.addAll(asList(anIndexCollection.fsIndexes()));
+		}
+
+		// Check FsIndex annotation
+		org.uimafit.descriptor.FsIndex anFsIndex =
+			getInheritableAnnotation(FsIndex.class, componentClass);
+		if (anFsIndex != null) {
+			if (anIndexCollection != null) {
+				throw new IllegalStateException("Class ["+componentClass.getName()+"] must not " +
+						"declare "+org.uimafit.descriptor.FsIndexCollection.class.getSimpleName() +
+						" and "+FsIndex.class.getSimpleName()+" at the same time.");
+			}
+
+			anFsIndexList.add(anFsIndex);
+		}
+
+		FsIndexCollection_impl fsIndexCollection = new FsIndexCollection_impl();
+
+		// Process collected FsIndex annotations
+		for (FsIndex anIdx : anFsIndexList) {
+			// Collect index keys
+			List<FsIndexKeyDescription> keys = new ArrayList<FsIndexKeyDescription>();
+			for (FsIndexKey anIndexKey : anIdx.keys()) {
+				keys.add(createFsIndexKeyDescription(anIndexKey.featureName(),
+						anIndexKey.comparator()));
+			}
+
+			// type and typeName must not be set at the same time
+			if (!anIdx.typeName().equals(FsIndex.NO_NAME_TYPE_SET)
+					&& anIdx.type() != FsIndex.NoClassSet.class){
+				throw new IllegalStateException("Class ["+componentClass.getName()+"] must not " +
+						"declare an "+org.uimafit.descriptor.FsIndex.class.getSimpleName() +
+						" with type and typeName both set at the same time.");
+			}
+
+			String typeName;
+			if (!anIdx.typeName().equals(FsIndex.NO_NAME_TYPE_SET)) {
+				typeName = anIdx.typeName();
+			}
+			else if (anIdx.type() != FsIndex.NoClassSet.class) {
+				typeName = anIdx.type().getName();
+			}
+			else {
+				throw new IllegalStateException("Class ["+componentClass.getName()+"] must not " +
+						"declare an "+org.uimafit.descriptor.FsIndex.class.getSimpleName() +
+						" with neither type nor typeName set.");
+			}
+
+			fsIndexCollection.addFsIndex(createFsIndexDescription(anIdx.label(), anIdx.kind(),
+					typeName, anIdx.typePriorities(),
+					keys.toArray(new FsIndexKeyDescription[keys.size()])));
+		}
+
+		return fsIndexCollection;
+	}
+
+	public static FsIndexDescription createFsIndexDescription(String label, String kind,
+			String typeName, boolean useTypePriorities, FsIndexKeyDescription... keys)	{
+		FsIndexDescription_impl fsIndexDescription = new FsIndexDescription_impl();
+		fsIndexDescription.setLabel(label);
+		fsIndexDescription.setKind(kind);
+		fsIndexDescription.setTypeName(typeName);
+		fsIndexDescription.setKeys(keys);
+		return fsIndexDescription;
+	}
+
+	public static FsIndexCollection createFsIndexCollection(FsIndexDescription...descriptions) {
+		FsIndexCollection_impl fsIndexCollection = new FsIndexCollection_impl();
+		fsIndexCollection.setFsIndexes(descriptions);
+		return fsIndexCollection;
+	}
+
+	public static FsIndexKeyDescription createFsIndexKeyDescription(String featureName) {
+		return createFsIndexKeyDescription(featureName, STANDARD_COMPARE);
+	}
+
+	public static FsIndexKeyDescription createFsIndexKeyDescription(String featureName,
+			int comparator) {
+		FsIndexKeyDescription_impl key = new FsIndexKeyDescription_impl();
+		key.setFeatureName(featureName);
+		key.setComparator(comparator);
+		key.setTypePriority(false);
+		return key;
+	}
+
+	/**
+	 * System property indicating which locations to scan for index descriptions. A list of
+	 * locations may be given separated by ";".
+	 */
+	public static final String FS_INDEX_IMPORT_PATTERN = "org.uimafit.fsindex.import_pattern";
+
+	/**
+	 * Index manifest location.
+	 */
+	public static final String FS_INDEX_MANIFEST_PATTERN = "classpath*:META-INF/org.uimafit/fsindexes.txt";
+
+	private static String[] indexDescriptorLocations;
+
+	/**
+	 * Creates a {@link FsIndexCollection} from descriptor names.
+	 *
+	 * @param descriptorNames
+	 *            The fully qualified, Java-style, dotted descriptor names.
+	 * @return a {@link FsIndexCollection} that includes the indexes from all of the specified files.
+	 */
+	public static FsIndexCollection createFsIndexCollection(String... descriptorNames) {
+		List<Import> imports = new ArrayList<Import>();
+		for (String descriptorName : descriptorNames) {
+			Import imp = new Import_impl();
+			imp.setName(descriptorName);
+			imports.add(imp);
+		}
+		Import[] importArray = new Import[imports.size()];
+
+		FsIndexCollection fsIndexCollection = new FsIndexCollection_impl();
+		fsIndexCollection.setImports(imports.toArray(importArray));
+		return fsIndexCollection;
+	}
+
+	/**
+	 * Creates a {@link FsIndexCollection} from a descriptor file
+	 *
+	 * @param descriptorURIs
+	 *            The descriptor file paths.
+	 * @return A {@link FsIndexCollection} that includes the indexes from all of the specified files.
+	 */
+	public static FsIndexCollection createTypeSystemDescriptionFromPath(
+			String... descriptorURIs) {
+		List<Import> imports = new ArrayList<Import>();
+		for (String descriptorURI : descriptorURIs) {
+			Import imp = new Import_impl();
+			imp.setLocation(descriptorURI);
+			imports.add(imp);
+		}
+		Import[] importArray = new Import[imports.size()];
+
+		FsIndexCollection fsIndexCollection = new FsIndexCollection_impl();
+		fsIndexCollection.setImports(imports.toArray(importArray));
+		return fsIndexCollection;
+	}
+
+	/**
+	 * Creates a {@link FsIndexCollection} from all index descriptions that can be found via the
+	 * {@link #FS_INDEX_IMPORT_PATTERN} or via the {@code META-INF/org.uimafit/fsindexes.txt} files
+	 * in the classpath.
+	 *
+	 * @return the auto-scanned indexes.
+	 */
+	public static FsIndexCollection createFsIndexCollection()
+			throws ResourceInitializationException {
+		List<FsIndexDescription> fsIndexList = new ArrayList<FsIndexDescription>();
+		for (String location : scanIndexDescriptors()) {
+			try {
+				XMLInputSource xmlInput = new XMLInputSource(location);
+				FsIndexCollection fsIdxCol = getXMLParser().parseFsIndexCollection(xmlInput);
+				fsIdxCol.resolveImports();
+				fsIndexList.addAll(asList(fsIdxCol.getFsIndexes()));
+				LogFactory.getLog(FsIndexFactory.class).debug(
+						"Detected index at [" + location + "]");
+			}
+			catch (IOException e) {
+				throw new ResourceInitializationException(e);
+			}
+			catch (InvalidXMLException e) {
+				LogFactory.getLog(TypeSystemDescription.class).warn(
+						"[" + location + "] is not a index descriptor file. Ignoring.", e);
+			}
+		}
+
+		return createFsIndexCollection(fsIndexList.toArray(new FsIndexDescription[fsIndexList
+				.size()]));
+	}
+
+	/**
+	 * Get all currently accessible index descriptor locations. A scan is actually only
+	 * performed on the first call and the locations are cached. To force a re-scan use
+	 * {@link #forceIndexDescriptorsScan()}.
+	 *
+	 * @return an array of locations.
+	 * @throws ResourceInitializationException
+	 *             if the locations could not be resolved.
+	 */
+	public static String[] scanIndexDescriptors() throws ResourceInitializationException {
+		if (indexDescriptorLocations == null) {
+			indexDescriptorLocations = resolve(scanImportsAndManifests(FS_INDEX_MANIFEST_PATTERN,
+					FS_INDEX_IMPORT_PATTERN));
+		}
+		return indexDescriptorLocations;
+	}
+
+	/**
+	 * Force rescan of type descriptors. The next call to {@link #scanIndexDescriptors()} will rescan
+	 * all auto-import locations.
+	 */
+	public static void forceIndexDescriptorsScan() {
+		indexDescriptorLocations = null;
+	}
+}

Propchange: uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/FsIndexFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/JCasBuilder.java
URL: http://svn.apache.org/viewvc/uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/JCasBuilder.java?rev=1420723&view=auto
==============================================================================
--- uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/JCasBuilder.java (added)
+++ uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/JCasBuilder.java Wed Dec 12 14:58:37 2012
@@ -0,0 +1,126 @@
+/*
+ Copyright 2010
+ Ubiquitous Knowledge Processing (UKP) Lab
+ Technische Universitaet Darmstadt
+ All rights reserved.
+
+ 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.uimafit.factory;
+
+import static org.uimafit.util.JCasUtil.getType;
+
+import org.apache.uima.cas.Type;
+import org.apache.uima.cas.text.AnnotationFS;
+import org.apache.uima.jcas.JCas;
+
+/**
+ * Allows to add types and text to a CAS easily piece by piece.
+ * 
+ * @author Richard Eckart de Castilho
+ */
+public class JCasBuilder {
+	private final StringBuilder documentText = new StringBuilder();
+	private final JCas jcas;
+
+	/**
+	 * Create a new JCas builder working on the specified JCas. The JCas must not have any content
+	 * yet.
+	 * 
+	 * @param aJCas
+	 *            the working JCas.
+	 */
+	public JCasBuilder(JCas aJCas) {
+		jcas = aJCas;
+	}
+
+	/**
+	 * Append a text.
+	 * 
+	 * @param aText
+	 *            the text to append.
+	 */
+	public void add(String aText) {
+		documentText.append(aText);
+	}
+
+	/**
+	 * Append a text annotated with the specified annotation. The created annotation is returned and
+	 * further properties can be set on it. The annotation is already added to the indexes.
+	 * 
+	 * @param aText
+	 *            covered text
+	 * @param aClass
+	 *            annotation type
+	 * @param <T>
+	 *            annotation type
+	 * @return annotation instance - can be used to set features or determine offsets
+	 */
+	@SuppressWarnings("unchecked")
+	public <T> T add(String aText, Class<T> aClass) {
+		Type type = getType(jcas, aClass);
+		int begin = documentText.length();
+		add(aText);
+		int end = documentText.length();
+		AnnotationFS fs = jcas.getCas().createAnnotation(type, begin, end);
+		jcas.addFsToIndexes(fs);
+		return (T) fs;
+	}
+
+	/**
+	 * Add an annotation starting at the specified position and ending at the current end of the
+	 * text. The created annotation is returned and further properties can be set on it. The
+	 * annotation is already added to the indexes.
+	 * 
+	 * @param <T>
+	 *            annotation type
+	 * @param aBegin
+	 *            begin offset.
+	 * @param aClass
+	 *            annotation type
+	 * @return annotation instance - can be used to set features or determine offsets
+	 */
+	@SuppressWarnings("unchecked")
+	public <T> T add(int aBegin, Class<T> aClass) {
+		Type type = getType(jcas, aClass);
+		int end = documentText.length();
+		AnnotationFS fs = jcas.getCas().createAnnotation(type, aBegin, end);
+		jcas.addFsToIndexes(fs);
+		return (T) fs;
+	}
+
+	/**
+	 * Get the current "cursor" position (current text length).
+	 * 
+	 * @return current text length.
+	 */
+	public int getPosition() {
+		return documentText.length();
+	}
+
+	/**
+	 * Get the JCas.
+	 * 
+	 * @return the JCas.
+	 */
+	public JCas getJCas() {
+		return jcas;
+	}
+
+	/**
+	 * Complete the building process by writing the text into the CAS. This can only be called once.
+	 */
+	public void close() {
+		jcas.setDocumentText(documentText.toString());
+	}
+}

Propchange: uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/JCasBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/JCasFactory.java
URL: http://svn.apache.org/viewvc/uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/JCasFactory.java?rev=1420723&view=auto
==============================================================================
--- uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/JCasFactory.java (added)
+++ uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/JCasFactory.java Wed Dec 12 14:58:37 2012
@@ -0,0 +1,184 @@
+/*
+ Copyright 2009-2010	Regents of the University of Colorado.
+ All rights reserved.
+
+ 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.uimafit.factory;
+
+import static org.uimafit.factory.TypeSystemDescriptionFactory.createTypeSystemDescription;
+import static org.uimafit.factory.TypeSystemDescriptionFactory.createTypeSystemDescriptionFromPath;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.uima.UIMAException;
+import org.apache.uima.cas.CAS;
+import org.apache.uima.cas.impl.XCASDeserializer;
+import org.apache.uima.cas.impl.XmiCasDeserializer;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.resource.metadata.TypeSystemDescription;
+import org.apache.uima.util.CasCreationUtils;
+import org.xml.sax.SAXException;
+
+/**
+ * @author Steven Bethard, Philip Ogren
+ * @author Richard Eckart de Castilho
+ */
+public final class JCasFactory {
+	private JCasFactory() {
+		// This class is not meant to be instantiated
+	}
+
+	/**
+	 * Creates a new JCas for the automatically derived type system. See
+	 * {@link TypeSystemDescriptionFactory#createTypeSystemDescription()}
+	 */
+	public static JCas createJCas() throws UIMAException {
+		return CasCreationUtils.createCas(createTypeSystemDescription(), null, null).getJCas();
+
+	}
+
+	/**
+	 * Creates a new JCas from type system descriptor files found by name
+	 */
+	public static JCas createJCas(String... typeSystemDescriptorNames) throws UIMAException {
+		return CasCreationUtils.createCas(createTypeSystemDescription(typeSystemDescriptorNames),
+				null, null).getJCas();
+	}
+
+	/**
+	 * Creates a new JCas from type system descriptor files.
+	 *
+	 * @param typeSystemDescriptorPaths
+	 *            paths to type system descriptor files
+	 */
+	public static JCas createJCasFromPath(String... typeSystemDescriptorPaths) throws UIMAException {
+		return createJCas(createTypeSystemDescriptionFromPath(typeSystemDescriptorPaths));
+	}
+
+	/**
+	 * Create a new JCas with a new type system defined by the classes provided
+	 * 
+	 * @param typeSystemClasses
+	 *            should be classes generated by JCasGen
+	 *            
+	 * @deprecated This is not the method you want to use. If you declare only one type per XML type
+	 *             descriptor, you'll end up with LOTS of these. Use
+	 *             {@link TypeSystemDescriptionFactory#createTypeSystemDescription(String...)} or
+	 *             automatic type system detection with
+	 *             {@link TypeSystemDescriptionFactory#createTypeSystemDescription()}.
+	 */
+	@Deprecated
+	public static JCas createJCas(Class<?>... typeSystemClasses) throws UIMAException {
+		return createJCas(createTypeSystemDescription(typeSystemClasses));
+	}
+
+	/**
+	 * Create a new JCas for the given type system description
+	 */
+	public static JCas createJCas(TypeSystemDescription typeSystemDescription) throws UIMAException {
+		return CasCreationUtils.createCas(typeSystemDescription, null, null).getJCas();
+	}
+
+	/**
+	 * This method creates a new JCas and loads the contents of an XMI file into it.
+	 *
+	 * @param xmiFileName
+	 *            a file name for an XMI file.
+	 */
+	public static JCas createJCas(String xmiFileName, TypeSystemDescription typeSystemDescription)
+			throws UIMAException, IOException {
+		return createJCas(xmiFileName, typeSystemDescription, true);
+	}
+
+	/**
+	 * This method creates a new JCas and loads the contents of an XMI or XCAS file into it.
+	 *
+	 * @param xmlFileName
+	 *            a file name for an XML file containing XMI or XCAS content.
+	 * @param isXmi
+	 *            if true, than assume XMI format. Otherwise, assume XCAS.
+	 */
+	public static JCas createJCas(String xmlFileName, TypeSystemDescription typeSystemDescription,
+			boolean isXmi) throws UIMAException, IOException {
+		JCas jCas = createJCas(typeSystemDescription);
+		loadJCas(jCas, xmlFileName, isXmi);
+		return jCas;
+	}
+
+	/**
+	 * This method passes through to {@link #loadJCas(JCas, String, boolean)}
+	 *
+	 * @param xmiFileName
+	 *            a file name for an XMI file
+	 */
+	public static void loadJCas(JCas jCas, String xmiFileName) throws IOException {
+		loadJCas(jCas, xmiFileName, true);
+	}
+
+	/**
+	 * This method takes a JCas, resets it, and loads it with the contents of an XMI or XCAS file
+	 *
+	 * @param xmlFileName
+	 *            a file name for an XML file containing XMI or XCAS content.
+	 * @param isXmi
+	 *            if true, than assume XMI format. Otherwise, assume XCAS.
+	 */
+	public static void loadJCas(JCas jCas, String xmlFileName, boolean isXmi) throws IOException {
+		FileInputStream inputStream = new FileInputStream(xmlFileName);
+		loadJCas(jCas, inputStream, isXmi);
+	}
+
+	/**
+	 * This method passes through to {@link #loadJCas(JCas, InputStream, boolean)}
+	 */
+	public static void loadJCas(JCas jCas, InputStream xmiInputStream) throws IOException {
+		loadJCas(jCas, xmiInputStream, true);
+	}
+
+	/**
+	 * This method takes a JCas, resets it, and loads it with the contents of an XMI or XCAS input
+	 * stream
+	 *
+	 * @param xmlInputStream
+	 *            should contain the contents of a serialized CAS in the form of XMI or XCAS XML
+	 * @param isXmi
+	 *            if true, than assume XMI format. Otherwise, assume XCAS.
+	 */
+	public static void loadJCas(JCas jCas, InputStream xmlInputStream, boolean isXmi)
+			throws IOException {
+		jCas.reset();
+		try {
+			CAS cas = jCas.getCas();
+			if (isXmi) {
+				XmiCasDeserializer.deserialize(xmlInputStream, cas);
+			}
+			else {
+				XCASDeserializer.deserialize(xmlInputStream, cas);
+			}
+		}
+		catch (SAXException e) {
+			IOException ioe = new IOException(e.getMessage());
+			ioe.initCause(e);
+			throw ioe; // NOPMD
+			// If we were using Java 1.6 and add the wrapped exception to the IOException
+			// constructor, we would not get a warning here
+		}
+		finally {
+			IOUtils.closeQuietly(xmlInputStream);
+		}
+	}
+}

Propchange: uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/JCasFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/ResourceCreationSpecifierFactory.java
URL: http://svn.apache.org/viewvc/uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/ResourceCreationSpecifierFactory.java?rev=1420723&view=auto
==============================================================================
--- uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/ResourceCreationSpecifierFactory.java (added)
+++ uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/ResourceCreationSpecifierFactory.java Wed Dec 12 14:58:37 2012
@@ -0,0 +1,165 @@
+/*
+ Copyright 2009-2010	Regents of the University of Colorado.
+ All rights reserved.
+
+ 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.uimafit.factory;
+
+import java.io.IOException;
+import java.net.URL;
+
+import org.apache.uima.UIMAException;
+import org.apache.uima.UIMAFramework;
+import org.apache.uima.resource.ResourceCreationSpecifier;
+import org.apache.uima.resource.metadata.ConfigurationParameter;
+import org.apache.uima.resource.metadata.ConfigurationParameterDeclarations;
+import org.apache.uima.resource.metadata.ConfigurationParameterSettings;
+import org.apache.uima.resource.metadata.ResourceMetaData;
+import org.apache.uima.util.XMLInputSource;
+import org.apache.uima.util.XMLParser;
+
+/**
+ * @author Steven Bethard, Philip Ogren
+ */
+public final class ResourceCreationSpecifierFactory {
+	private ResourceCreationSpecifierFactory() {
+		// This class is not meant to be instantiated
+	}
+
+	/**
+	 * Parse a ResourceCreationSpecifier from the URL of an XML descriptor file, setting additional
+	 * configuration parameters as necessary.
+	 * 
+	 * @param descriptorURL
+	 *            The URL of the XML descriptor file.
+	 * @param parameters
+	 *            Any additional configuration parameters to be set. These should be supplied as
+	 *            (name, value) pairs, so there should always be an even number of parameters.
+	 * @return The ResourceCreationSpecifier for the XML descriptor with all the configuration
+	 *         parameters set.
+	 */
+	public static ResourceCreationSpecifier createResourceCreationSpecifier(URL descriptorURL,
+			Object[] parameters) throws UIMAException, IOException {
+		return createResourceCreationSpecifier(new XMLInputSource(descriptorURL), parameters);
+	}
+
+	/**
+	 * Parse a ResourceCreationSpecifier from XML descriptor file input, setting additional
+	 * configuration parameters as necessary.
+	 * 
+	 * @param xmlInput
+	 *            The descriptor file as an XMLInputSource.
+	 * @param parameters
+	 *            Any additional configuration parameters to be set. These should be supplied as
+	 *            (name, value) pairs, so there should always be an even number of parameters.
+	 * @return The ResourceCreationSpecifier for the XML descriptor with all the configuration
+	 *         parameters set.
+	 */
+	public static ResourceCreationSpecifier createResourceCreationSpecifier(
+			XMLInputSource xmlInput, Object[] parameters) throws UIMAException, IOException {
+		ConfigurationParameterFactory.ensureParametersComeInPairs(parameters);
+
+		ResourceCreationSpecifier specifier;
+		XMLParser parser = UIMAFramework.getXMLParser();
+		specifier = (ResourceCreationSpecifier) parser.parseResourceSpecifier(xmlInput);
+		setConfigurationParameters(specifier, parameters);
+
+		return specifier;
+	}
+
+	/**
+	 * Parse a ResourceCreationSpecifier from an XML descriptor file, setting additional
+	 * configuration parameters as necessary.
+	 * 
+	 * @param descriptorPath
+	 *            The path to the XML descriptor file.
+	 * @param parameters
+	 *            Any additional configuration parameters to be set. These should be supplied as
+	 *            (name, value) pairs, so there should always be an even number of parameters.
+	 * @return The ResourceCreationSpecifier for the XML descriptor with all the configuration
+	 *         parameters set.
+	 */
+	public static ResourceCreationSpecifier createResourceCreationSpecifier(String descriptorPath,
+			Object[] parameters) throws UIMAException, IOException {
+		return createResourceCreationSpecifier(new XMLInputSource(descriptorPath), parameters);
+	}
+
+	/**
+	 * Create configuration parameter declarations and settings from a list of (name, value) pairs.
+	 * 
+	 * @param specifier
+	 *            The ResourceCreationSpecifier whose parameters are to be set.
+	 * @param configurationData
+	 *            The configuration parameters to be set. These should be supplied as (name, value)
+	 *            pairs, so there should always be an even number of parameters.
+	 */
+	public static void setConfigurationParameters(ResourceCreationSpecifier specifier,
+			Object... configurationData) {
+		if (configurationData == null || configurationData.length == 0) {
+			return;
+		}
+		
+		ConfigurationParameterFactory.ensureParametersComeInPairs(configurationData);
+
+		ConfigurationParameter[] configurationParameters = new ConfigurationParameter[configurationData.length / 2];
+		Object[] configurationValues = new Object[configurationData.length / 2];
+
+		for (int i = 0; i < configurationValues.length; i++) {
+			String name = (String) configurationData[i * 2];
+			Object value = configurationData[i * 2 + 1];
+			ConfigurationParameter param = ConfigurationParameterFactory.createPrimitiveParameter(
+					name, value.getClass(), null, false);
+			configurationParameters[i] = param;
+			configurationValues[i] = ConfigurationParameterFactory.convertParameterValue(param, value);
+		}
+		setConfigurationParameters(specifier, configurationParameters, configurationValues);
+	}
+
+	/**
+	 * This method passes through to
+	 * {@link #setConfigurationParameters(ResourceMetaData, ConfigurationParameter[], Object[])}
+	 */
+	public static void setConfigurationParameters(ResourceCreationSpecifier specifier,
+			ConfigurationParameter[] configurationParameters, Object[] configurationValues) {
+		setConfigurationParameters(specifier.getMetaData(), configurationParameters,
+				configurationValues);
+	}
+
+	/**
+	 * This method sets the configuration parameters of a resource. The length of
+	 * configurationParameters and configurationValues should be equal
+	 * 
+	 * @param configurationParameters
+	 *            an array of configuration parameters
+	 * @param configurationValues
+	 *            an array of configuration parameter values
+	 */
+	public static void setConfigurationParameters(ResourceMetaData metaData,
+			ConfigurationParameter[] configurationParameters, Object[] configurationValues) {
+		ConfigurationParameterDeclarations paramDecls = metaData
+				.getConfigurationParameterDeclarations();
+		ConfigurationParameterSettings paramSettings = metaData.getConfigurationParameterSettings();
+		for (int i = 0; i < configurationParameters.length; i++) {
+			if (paramDecls != null
+					&& paramDecls.getConfigurationParameter(null,
+							configurationParameters[i].getName()) == null) {
+				paramDecls.addConfigurationParameter(configurationParameters[i]);
+			}
+			paramSettings.setParameterValue(configurationParameters[i].getName(),
+					configurationValues[i]);
+		}
+	}
+
+}

Propchange: uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/ResourceCreationSpecifierFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/SofaMappingFactory.java
URL: http://svn.apache.org/viewvc/uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/SofaMappingFactory.java?rev=1420723&view=auto
==============================================================================
--- uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/SofaMappingFactory.java (added)
+++ uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/SofaMappingFactory.java Wed Dec 12 14:58:37 2012
@@ -0,0 +1,68 @@
+/*
+ Copyright 2009-2010	Regents of the University of Colorado.
+ All rights reserved.
+
+ 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.uimafit.factory;
+
+import org.apache.uima.analysis_component.AnalysisComponent;
+import org.apache.uima.analysis_engine.metadata.SofaMapping;
+import org.apache.uima.analysis_engine.metadata.impl.SofaMapping_impl;
+
+/**
+ * @author Philip Ogren
+ */
+public final class SofaMappingFactory {
+	private SofaMappingFactory() {
+		// This class is not meant to be instantiated
+	}
+
+	/**
+	 * This method creates a sofa mapping which is useful for mapping view names in individual
+	 * components used in aggregate analysis engines to the view names used by the aggregate.
+	 * 
+	 * WARNING: in version 0.9.12 the ordering of the parameters was changed! The order used to be
+	 * aggregateSofaName, componentKey, componentSofaName. This was changed because it seemed an
+	 * unnatural ordering.
+	 * 
+	 * @param componentKey
+	 *            the key/name used by the aggregate analysis engine for the component whose view is
+	 *            being mapped.
+	 * @param componentSofaName
+	 *            the sofa name used by the the component
+	 * @param aggregateSofaName
+	 *            the view name that the component name is mapped to and used by the aggregate
+	 *            analysis engine
+	 * @return a sofa mapping with the componentSofaName mapped to the aggregateSofaName
+	 */
+	public static SofaMapping createSofaMapping(String componentKey, String componentSofaName,
+			String aggregateSofaName) {
+
+		SofaMapping sofaMapping = new SofaMapping_impl();
+		sofaMapping.setComponentKey(componentKey);
+		sofaMapping.setComponentSofaName(componentSofaName);
+		sofaMapping.setAggregateSofaName(aggregateSofaName);
+		return sofaMapping;
+	}
+
+	/**
+	 * create a sofa mapping using the component class rather than the component name
+	 */
+	public static SofaMapping createSofaMapping(Class<? extends AnalysisComponent> componentClass,
+			String componentSofaName, String aggregateSofaName) {
+
+		return createSofaMapping(componentClass.getName(), componentSofaName, aggregateSofaName);
+	}
+
+}

Propchange: uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/SofaMappingFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/TypePrioritiesFactory.java
URL: http://svn.apache.org/viewvc/uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/TypePrioritiesFactory.java?rev=1420723&view=auto
==============================================================================
--- uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/TypePrioritiesFactory.java (added)
+++ uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/TypePrioritiesFactory.java Wed Dec 12 14:58:37 2012
@@ -0,0 +1,67 @@
+/*
+ Copyright 2009-2010	Regents of the University of Colorado.
+ All rights reserved.
+
+ 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.uimafit.factory;
+
+import org.apache.uima.resource.metadata.TypePriorities;
+import org.apache.uima.resource.metadata.TypePriorityList;
+import org.apache.uima.resource.metadata.impl.TypePriorities_impl;
+import static org.uimafit.util.CasUtil.UIMA_BUILTIN_JCAS_PREFIX;
+
+/**
+ * @author Philip Ogren
+ */
+
+public final class TypePrioritiesFactory {
+	private TypePrioritiesFactory() {
+		// This class is not meant to be instantiated
+	}
+
+	/**
+	 * Create a TypePriorities given a sequence of ordered type classes
+	 *
+	 * @param prioritizedTypes
+	 *            a sequence of ordered type classes
+	 */
+	public static TypePriorities createTypePriorities(Class<?>... prioritizedTypes) {
+		String[] typeNames = new String[prioritizedTypes.length];
+		for (int i = 0; i < prioritizedTypes.length; i++) {
+			String typeName = prioritizedTypes[i].getName();
+			if (typeName.startsWith(UIMA_BUILTIN_JCAS_PREFIX)) {
+				typeName = "uima." + typeName.substring(UIMA_BUILTIN_JCAS_PREFIX.length());
+			}
+
+			typeNames[i] = typeName;
+		}
+		return createTypePriorities(typeNames);
+	}
+
+	/**
+	 * Create a TypePriorities given a sequence of ordered type names
+	 *
+	 * @param prioritizedTypeNames
+	 *            a sequence of ordered type names
+	 */
+	public static TypePriorities createTypePriorities(String... prioritizedTypeNames) {
+		TypePriorities typePriorities = new TypePriorities_impl();
+		TypePriorityList typePriorityList = typePriorities.addPriorityList();
+		for (String typeName : prioritizedTypeNames) {
+			typePriorityList.addType(typeName);
+		}
+		return typePriorities;
+	}
+}

Propchange: uima/sandbox/trunk/uimaFIT/src/main/java/org/uimafit/factory/TypePrioritiesFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native