You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by re...@apache.org on 2013/05/10 17:59:25 UTC

svn commit: r1481068 - in /uima/sandbox/uimafit/trunk: uimafit-legacy-support/src/main/java/org/apache/uima/fit/legacy/converter/ uimafit-legacy-support/src/test/java/org/apache/uima/fit/factory/ uimafit-maven-plugin/src/it/default/reference/ uimafit-m...

Author: rec
Date: Fri May 10 15:59:23 2013
New Revision: 1481068

URL: http://svn.apache.org/r1481068
Log:
[UIMA-2748] Fill description of external resources in component from JavaDoc 
- Added "description" to ExternalResource annotation
- Refactoring of ExternalResourceFactory and ExternalResourceInitializer to better distribute the code
- Extended "enhance" mojo to take external resources into account

Modified:
    uima/sandbox/uimafit/trunk/uimafit-legacy-support/src/main/java/org/apache/uima/fit/legacy/converter/ExternalResourceConverter.java
    uima/sandbox/uimafit/trunk/uimafit-legacy-support/src/test/java/org/apache/uima/fit/factory/ExternalResourceConfiguratorTest.java
    uima/sandbox/uimafit/trunk/uimafit-maven-plugin/src/it/default/reference/TestAnnotator.xml
    uima/sandbox/uimafit/trunk/uimafit-maven-plugin/src/it/default/src/main/java/TestAnnotator.java
    uima/sandbox/uimafit/trunk/uimafit-maven-plugin/src/main/java/org/apache/uima/fit/maven/EnhanceMojo.java
    uima/sandbox/uimafit/trunk/uimafit-maven-plugin/src/test/resources/TestComponent.java
    uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/component/initialize/ExternalResourceInitializer.java
    uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/descriptor/ExternalResource.java
    uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/factory/AnalysisEngineFactory.java
    uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/factory/CollectionReaderFactory.java
    uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/factory/ExternalResourceFactory.java
    uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/factory/FlowControllerFactory.java
    uima/sandbox/uimafit/trunk/uimafit/src/test/java/org/apache/uima/fit/factory/ExternalResourceConfiguratorTest.java

Modified: uima/sandbox/uimafit/trunk/uimafit-legacy-support/src/main/java/org/apache/uima/fit/legacy/converter/ExternalResourceConverter.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uimafit/trunk/uimafit-legacy-support/src/main/java/org/apache/uima/fit/legacy/converter/ExternalResourceConverter.java?rev=1481068&r1=1481067&r2=1481068&view=diff
==============================================================================
--- uima/sandbox/uimafit/trunk/uimafit-legacy-support/src/main/java/org/apache/uima/fit/legacy/converter/ExternalResourceConverter.java (original)
+++ uima/sandbox/uimafit/trunk/uimafit-legacy-support/src/main/java/org/apache/uima/fit/legacy/converter/ExternalResourceConverter.java Fri May 10 15:59:23 2013
@@ -84,5 +84,9 @@ public class ExternalResourceConverter
     public boolean mandatory() {
       return legacyAnnotation.mandatory();
     }
+
+    public String description() {
+      return null;
+    }
   }
 }

Modified: uima/sandbox/uimafit/trunk/uimafit-legacy-support/src/test/java/org/apache/uima/fit/factory/ExternalResourceConfiguratorTest.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uimafit/trunk/uimafit-legacy-support/src/test/java/org/apache/uima/fit/factory/ExternalResourceConfiguratorTest.java?rev=1481068&r1=1481067&r2=1481068&view=diff
==============================================================================
--- uima/sandbox/uimafit/trunk/uimafit-legacy-support/src/test/java/org/apache/uima/fit/factory/ExternalResourceConfiguratorTest.java (original)
+++ uima/sandbox/uimafit/trunk/uimafit-legacy-support/src/test/java/org/apache/uima/fit/factory/ExternalResourceConfiguratorTest.java Fri May 10 15:59:23 2013
@@ -19,8 +19,8 @@
 
 package org.apache.uima.fit.factory;
 
-import static org.apache.uima.fit.component.initialize.ExternalResourceInitializer.getResourceDeclarations;
 import static org.apache.uima.fit.factory.AnalysisEngineFactory.createPrimitiveDescription;
+import static org.apache.uima.fit.factory.ExternalResourceFactory.createExternalResourceDependencies;
 import static org.junit.Assert.assertEquals;
 
 import java.util.HashMap;
@@ -40,7 +40,7 @@ import org.junit.Test;
 public class ExternalResourceConfiguratorTest extends ComponentTestBase {
   @Test
   public void testAnalyze() throws Exception {
-    Map<String, ExternalResourceDependency> deps = getResourceDeclarations(ParameterizedAE2.class);
+    ExternalResourceDependency[] deps = createExternalResourceDependencies(ParameterizedAE2.class);
 
     verify(deps);
   }
@@ -49,16 +49,15 @@ public class ExternalResourceConfigurato
   public void testDescriptor() throws Exception {
     AnalysisEngineDescription desc = createPrimitiveDescription(ParameterizedAE2.class,
             typeSystemDescription);
+    verify(desc.getExternalResourceDependencies());
+  }
 
+  private void verify(ExternalResourceDependency[] depList) {
     Map<String, ExternalResourceDependency> deps = new HashMap<String, ExternalResourceDependency>();
-    for (ExternalResourceDependency dep : desc.getExternalResourceDependencies()) {
+    for (ExternalResourceDependency dep : depList) {
       deps.put(dep.getKey(), dep);
     }
-
-    verify(deps);
-  }
-
-  private void verify(Map<String, ExternalResourceDependency> deps) {
+    
     assertEquals(3, deps.size());
 
     String key = ParameterizedAE2.DummyResource.class.getName();

Modified: uima/sandbox/uimafit/trunk/uimafit-maven-plugin/src/it/default/reference/TestAnnotator.xml
URL: http://svn.apache.org/viewvc/uima/sandbox/uimafit/trunk/uimafit-maven-plugin/src/it/default/reference/TestAnnotator.xml?rev=1481068&r1=1481067&r2=1481068&view=diff
==============================================================================
--- uima/sandbox/uimafit/trunk/uimafit-maven-plugin/src/it/default/reference/TestAnnotator.xml (original)
+++ uima/sandbox/uimafit/trunk/uimafit-maven-plugin/src/it/default/reference/TestAnnotator.xml Fri May 10 15:59:23 2013
@@ -34,4 +34,12 @@
             <outputsNewCASes>false</outputsNewCASes>
         </operationalProperties>
     </analysisEngineMetaData>
+    <externalResourceDependencies>
+        <externalResourceDependency>
+            <key>res</key>
+            <description>Documentation for resource</description>
+            <interfaceName>org.apache.uima.resource.Resource</interfaceName>
+            <optional>false</optional>
+        </externalResourceDependency>
+    </externalResourceDependencies>
 </analysisEngineDescription>

Modified: uima/sandbox/uimafit/trunk/uimafit-maven-plugin/src/it/default/src/main/java/TestAnnotator.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uimafit/trunk/uimafit-maven-plugin/src/it/default/src/main/java/TestAnnotator.java?rev=1481068&r1=1481067&r2=1481068&view=diff
==============================================================================
--- uima/sandbox/uimafit/trunk/uimafit-maven-plugin/src/it/default/src/main/java/TestAnnotator.java (original)
+++ uima/sandbox/uimafit/trunk/uimafit-maven-plugin/src/it/default/src/main/java/TestAnnotator.java Fri May 10 15:59:23 2013
@@ -19,7 +19,9 @@
 import org.apache.uima.analysis_component.JCasAnnotator_ImplBase;
 import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
 import org.apache.uima.fit.descriptor.ConfigurationParameter;
+import org.apache.uima.fit.descriptor.ExternalResource;
 import org.apache.uima.jcas.JCas;
+import org.apache.uima.resource.Resource;
 
 public class TestAnnotator extends AbstractAnnotator {
 
@@ -29,7 +31,14 @@ public class TestAnnotator extends Abstr
   public static final String PARAM_VALUE_1 = "value1";
   @ConfigurationParameter(name = PARAM_VALUE_1, mandatory=true)
   private String value1;
-  
+
+  /**
+   * Documentation for resource
+   */
+  public static final String RES_KEY = "res";
+  @ExternalResource(key = RES_KEY)
+  private Resource res;
+
   @Override
   public void process(JCas aJCas) throws AnalysisEngineProcessException {
     // Nothing to do

Modified: uima/sandbox/uimafit/trunk/uimafit-maven-plugin/src/main/java/org/apache/uima/fit/maven/EnhanceMojo.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uimafit/trunk/uimafit-maven-plugin/src/main/java/org/apache/uima/fit/maven/EnhanceMojo.java?rev=1481068&r1=1481067&r2=1481068&view=diff
==============================================================================
--- uima/sandbox/uimafit/trunk/uimafit-maven-plugin/src/main/java/org/apache/uima/fit/maven/EnhanceMojo.java (original)
+++ uima/sandbox/uimafit/trunk/uimafit-maven-plugin/src/main/java/org/apache/uima/fit/maven/EnhanceMojo.java Fri May 10 15:59:23 2013
@@ -60,10 +60,10 @@ import org.apache.maven.plugins.annotati
 import org.apache.maven.project.MavenProject;
 import org.apache.uima.fit.descriptor.ResourceMetaData;
 import org.apache.uima.fit.factory.ConfigurationParameterFactory;
+import org.apache.uima.fit.factory.ExternalResourceFactory;
 import org.apache.uima.fit.factory.ResourceMetaDataFactory;
 import org.apache.uima.fit.internal.EnhancedClassFile;
 import org.apache.uima.fit.maven.util.Util;
-import org.apache.uima.resource.metadata.ConfigurationParameter;
 import org.codehaus.plexus.util.FileUtils;
 import org.sonatype.plexus.build.incremental.BuildContext;
 
@@ -139,19 +139,31 @@ public class EnhanceMojo extends Abstrac
   private String encoding;
 
   /**
-   * Generate a report of missing meta data in {@code 
-   * ${project.build.directory}/uimafit-missing-meta-data-report.txt}
+   * Generate a report of missing meta data in {@code $ project.build.directory}
+   * /uimafit-missing-meta-data-report.txt}
    */
   @Parameter(defaultValue = "true", required = true)
   private boolean generateMissingMetaDataReport;
-  
+
   /**
    * Fail on missing meta data. This setting has no effect unless
    * {@code generateMissingMetaDataReport} is enabled.
    */
   @Parameter(defaultValue = "false", required = true)
   private boolean failOnMissingMetaData;
-  
+
+  /**
+   * Constant name prefixes used for parameters and external resources, e.g. "PARAM_".
+   */
+  @Parameter(required = false)
+  private String[] parameterNameConstantPrefixes = { "PARAM_" };
+
+  /**
+   * Constant name prefixes used for parameters and external resources, e.g. "KEY_", and "RES_".
+   */
+  @Parameter(required = false)
+  private String[] externalResourceNameConstantPrefixes = { "KEY_", "RES_" };
+
   /**
    * Start of a line containing a class name in the missing meta data report file
    */
@@ -175,11 +187,11 @@ public class EnhanceMojo extends Abstrac
 
     // Set up map to keep a report per class.
     Multimap<String, String> reportData = LinkedHashMultimap.create();
-    
+
     // Determine where to write the missing meta data report file
     File reportFile = new File(project.getBuild().getDirectory(),
             "uimafit-missing-meta-data-report.txt");
-    
+
     // Read existing report
     if (generateMissingMetaDataReport) {
       readMissingMetaDataReport(reportFile, reportData);
@@ -187,7 +199,7 @@ public class EnhanceMojo extends Abstrac
 
     // Remember the names of all examined components, whether processed or not.
     List<String> examinedComponents = new ArrayList<String>();
-    
+
     for (String file : files) {
       String clazzName = Util.getClassName(project, file);
 
@@ -215,7 +227,7 @@ public class EnhanceMojo extends Abstrac
 
       // Remember that class was examined
       examinedComponents.add(clazzName);
-      
+
       // Forget any previous missing meta data report we have on the class
       reportData.removeAll(clazzName);
 
@@ -268,20 +280,20 @@ public class EnhanceMojo extends Abstrac
                 + ExceptionUtils.getRootCauseMessage(e), e);
       }
     }
-    
+
     if (generateMissingMetaDataReport) {
       // Remove any classes from the report that are no longer part of the build
       List<String> deletedClasses = new ArrayList<String>(reportData.keySet());
       deletedClasses.removeAll(examinedComponents);
       reportData.removeAll(deletedClasses);
-      
+
       // Write updated report
       writeMissingMetaDataReport(reportFile, reportData);
-      
+
       if (failOnMissingMetaData && !reportData.isEmpty()) {
         throw new MojoFailureException("Component meta data missing. A report of the missing "
                 + "meta data can be found in " + reportFile);
-      }    
+      }
     }
   }
 
@@ -406,29 +418,46 @@ public class EnhanceMojo extends Abstrac
   /**
    * Enhance descriptions in configuration parameters.
    */
-  private void enhanceConfigurationParameter(JavaSource aAST, Class<?> aClazz, CtClass aCtClazz, 
-          Multimap<String, String> aReportData)
-          throws MojoExecutionException {
+  private void enhanceConfigurationParameter(JavaSource aAST, Class<?> aClazz, CtClass aCtClazz,
+          Multimap<String, String> aReportData) throws MojoExecutionException {
     // Get the parameter name constants
-    Map<String, String> nameFields = getParameterConstants(aClazz);
+    Map<String, String> parameterNameFields = getParameterConstants(aClazz,
+            parameterNameConstantPrefixes);
+    Map<String, String> resourceNameFields = getParameterConstants(aClazz,
+            externalResourceNameConstantPrefixes);
 
     // Fetch configuration parameters from the @ConfigurationParameter annotations in the
     // compiled class. We only need the fields in the class itself. Superclasses should be
     // enhanced by themselves.
     for (Field field : aClazz.getDeclaredFields()) {
+      final String pname;
+      final String type;
+      final String pdesc;
+
       // Is this a configuration parameter?
-      if (!ConfigurationParameterFactory.isConfigurationParameterField(field)) {
+      if (ConfigurationParameterFactory.isConfigurationParameterField(field)) {
+        type = "parameter";
+        // Extract configuration parameter information from the uimaFIT annotation
+        pname = ConfigurationParameterFactory.createPrimitiveParameter(field).getName();
+        // Extract JavaDoc for this resource from the source file
+        pdesc = Util.getParameterDocumentation(aAST, field.getName(),
+                parameterNameFields.get(pname));
+      }
+
+      // Is this an external resource?
+      else if (ExternalResourceFactory.isExternalResourceField(field)) {
+        type = "external resource";
+        // Extract resource key from the uimaFIT annotation
+        pname = ExternalResourceFactory.createExternalResourceDependency(field).getKey();
+        // Extract JavaDoc for this resource from the source file
+        pdesc = Util.getParameterDocumentation(aAST, field.getName(), 
+                resourceNameFields.get(pname));
+      } else {
         continue;
       }
 
-      // Extract configuration parameter information from the uimaFIT annotation
-      ConfigurationParameter p = ConfigurationParameterFactory.createPrimitiveParameter(field);
-
-      // Extract JavaDoc for this parameter from the source file
-      String pdesc = Util.getParameterDocumentation(aAST, field.getName(),
-              nameFields.get(p.getName()));
       if (pdesc == null) {
-        String msg = "No description found for parameter [" + p.getName() + "]";
+        String msg = "No description found for " + type + " [" + pname + "]";
         getLog().info(msg);
         aReportData.put(aClazz.getName(), msg);
         continue;
@@ -448,17 +477,20 @@ public class EnhanceMojo extends Abstrac
           for (Annotation a : annotations) {
             if (a.getTypeName().equals(
                     org.apache.uima.fit.descriptor.ConfigurationParameter.class.getName())
-                    || a.getTypeName().equals("org.uimafit.descriptor.ConfigurationParameter")) {
+                    || a.getTypeName().equals(
+                            org.apache.uima.fit.descriptor.ExternalResource.class.getName())
+                    || a.getTypeName().equals("org.uimafit.descriptor.ConfigurationParameter")
+                    || a.getTypeName().equals("org.uimafit.descriptor.ExternalResource")) {
               if (a.getMemberValue("description") == null) {
                 a.addMemberValue("description", new StringMemberValue(pdesc, aCtClazz
                         .getClassFile().getConstPool()));
-                getLog().info("Enhanced description of parameter [" + p.getName() + "]");
+                getLog().info("Enhanced description of " + type + " [" + pname + "]");
                 // Replace updated annotation
                 annoAttr.addAnnotation(a);
               } else {
                 // Extract configuration parameter information from the uimaFIT annotation
                 // We only want to override if the description is not set yet.
-                getLog().info("Not overwriting description of parameter [" + p.getName() + "] ");
+                getLog().info("Not overwriting description of " + type + " [" + pname + "] ");
               }
             }
           }
@@ -477,18 +509,30 @@ public class EnhanceMojo extends Abstrac
    * Get a map of parameter name to parameter name constant field, e.g. ("value",
    * Field("PARAM_VALUE")).
    */
-  private Map<String, String> getParameterConstants(Class<?> aClazz) {
+  private Map<String, String> getParameterConstants(Class<?> aClazz, String[] aPrefixes) {
     Map<String, String> result = new HashMap<String, String>();
     for (Field f : aClazz.getFields()) {
-      if (!f.getName().startsWith("PARAM_")) {
+      boolean hasPrefix = false;
+      // Check if any of the registered prefixes matches
+      for (String prefix : aPrefixes) {
+        if (f.getName().startsWith(prefix)) {
+          hasPrefix = true;
+          break;
+        }
+      }
+
+      // If none matched, continue
+      if (!hasPrefix) {
         continue;
       }
+
+      // If one matched, record the field
       try {
         String parameterName = (String) f.get(null);
         result.put(parameterName, f.getName());
       } catch (IllegalAccessException e) {
         getLog().warn(
-                "Unable to access parameter name constant field [" + f.getName() + "]: "
+                "Unable to access name constant field [" + f.getName() + "]: "
                         + ExceptionUtils.getRootCauseMessage(e), e);
       }
     }
@@ -521,7 +565,7 @@ public class EnhanceMojo extends Abstrac
     }
     return null;
   }
-  
+
   /**
    * Write a report on any meta data missing from components.
    */
@@ -548,8 +592,7 @@ public class EnhanceMojo extends Abstrac
           }
           out.printf("%n");
         }
-      }
-      else {
+      } else {
         out.printf("%s%n", MARK_NO_MISSING_META_DATA);
       }
     } catch (IOException e) {
@@ -559,17 +602,17 @@ public class EnhanceMojo extends Abstrac
       IOUtils.closeQuietly(out);
     }
   }
-  
+
   /**
    * Read the missing meta data report from a previous run.
    */
   private void readMissingMetaDataReport(File aReportFile, Multimap<String, String> aReportData)
-          throws MojoExecutionException  {
+          throws MojoExecutionException {
     if (!aReportFile.exists()) {
       // Ignore if the file is missing
       return;
     }
-    
+
     LineIterator i = null;
     try {
       String clazz = null;
@@ -583,11 +626,9 @@ public class EnhanceMojo extends Abstrac
         // Line containing class name
         if (line.startsWith(MARK_CLASS)) {
           clazz = line.substring(MARK_CLASS.length()).trim();
-        }
-        else if (StringUtils.isBlank(line)) {
+        } else if (StringUtils.isBlank(line)) {
           // Empty line, ignore
-        }
-        else {
+        } else {
           // Line containing a missing meta data instance
           if (clazz == null) {
             throw new MojoExecutionException("Missing meta data report has invalid format.");
@@ -595,12 +636,10 @@ public class EnhanceMojo extends Abstrac
           aReportData.put(clazz, line.trim());
         }
       }
-    }
-    catch (IOException e) {
+    } catch (IOException e) {
       throw new MojoExecutionException("Unable to read missing meta data report: "
               + ExceptionUtils.getRootCauseMessage(e), e);
-    }
-    finally {
+    } finally {
       LineIterator.closeQuietly(i);
     }
   }

Modified: uima/sandbox/uimafit/trunk/uimafit-maven-plugin/src/test/resources/TestComponent.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uimafit/trunk/uimafit-maven-plugin/src/test/resources/TestComponent.java?rev=1481068&r1=1481067&r2=1481068&view=diff
==============================================================================
--- uima/sandbox/uimafit/trunk/uimafit-maven-plugin/src/test/resources/TestComponent.java (original)
+++ uima/sandbox/uimafit/trunk/uimafit-maven-plugin/src/test/resources/TestComponent.java Fri May 10 15:59:23 2013
@@ -19,7 +19,10 @@
 package some.test.mypackage;
 
 import org.apache.uima.fit.descriptor.ConfigurationParameter;
+import org.apache.uima.fit.descriptor.ExternalResource;
+import org.apache.uima.fit.factory.ExternalResourceFactoryTest.DummyResource;
 import org.apache.uima.fit.maven.javadoc.JavadocTextExtractor;
+import org.apache.uima.resource.Resource;
 
 /**
  * A test component used to test {@link JavadocTextExtractor}.
@@ -57,6 +60,13 @@ public class TestComponent {
   public static final String PARAM_VALUE_5 = PARAM_DEFAULT_NAME_5;
   @ConfigurationParameter(name = PARAM_VALUE_5)
   private String value5;
+  
+  /**
+   * Documentation for resource
+   */
+  public static final String RES_KEY = "res";
+  @ExternalResource(key = RES_KEY)
+  private Resource res;
 
   public TestComponent() {
   }

Modified: uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/component/initialize/ExternalResourceInitializer.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/component/initialize/ExternalResourceInitializer.java?rev=1481068&r1=1481067&r2=1481068&view=diff
==============================================================================
--- uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/component/initialize/ExternalResourceInitializer.java (original)
+++ uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/component/initialize/ExternalResourceInitializer.java Fri May 10 15:59:23 2013
@@ -19,13 +19,10 @@
 package org.apache.uima.fit.component.initialize;
 
 import static org.apache.uima.fit.factory.ExternalResourceFactory.PREFIX_SEPARATOR;
-import static org.apache.uima.fit.factory.ExternalResourceFactory.createExternalResourceDependency;
-
 import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.WeakHashMap;
@@ -36,12 +33,9 @@ import org.apache.uima.fit.component.Ext
 import org.apache.uima.fit.descriptor.ExternalResource;
 import org.apache.uima.fit.descriptor.ExternalResourceLocator;
 import org.apache.uima.fit.internal.ReflectionUtil;
-import org.apache.uima.resource.ExternalResourceDependency;
-import org.apache.uima.resource.Resource;
 import org.apache.uima.resource.ResourceAccessException;
 import org.apache.uima.resource.ResourceInitializationException;
 import org.apache.uima.resource.ResourceManager;
-import org.apache.uima.resource.SharedResourceObject;
 import org.apache.uima.resource.impl.ResourceManager_impl;
 
 /**
@@ -72,8 +66,7 @@ public final class ExternalResourceIniti
    */
   public static <T> void initialize(UimaContext context, T object)
           throws ResourceInitializationException {
-    configure(context, object.getClass(), object.getClass(), object,
-            getResourceDeclarations(object.getClass()));
+    configure(context, object.getClass(), object.getClass(), object);
   }
 
   /**
@@ -89,16 +82,13 @@ public final class ExternalResourceIniti
    *          the class currently being configured.
    * @param object
    *          the object being configured.
-   * @param dependencies
-   *          the dependencies.
    * @throws ResourceInitializationException
    *           if required resources could not be bound.
    */
-  private static <T> void configure(UimaContext context, Class<?> baseCls, Class<?> cls, T object,
-          Map<String, ExternalResourceDependency> dependencies)
+  private static <T> void configure(UimaContext context, Class<?> baseCls, Class<?> cls, T object)
           throws ResourceInitializationException {
     if (cls.getSuperclass() != null) {
-      configure(context, baseCls, cls.getSuperclass(), object, dependencies);
+      configure(context, baseCls, cls.getSuperclass(), object);
     } else {
       // Try to initialize the external resources only once, not for each step of the
       // class hierarchy of a component.
@@ -109,9 +99,14 @@ public final class ExternalResourceIniti
       if (!ReflectionUtil.isAnnotationPresent(field, ExternalResource.class)) {
         continue;
       }
+      
+      ExternalResource era = ReflectionUtil.getAnnotation(field, ExternalResource.class);
 
       // Get the resource key. If it is a nested resource, also get the prefix.
-      String key = getKey(field);
+      String key = era.key();
+      if (key.length() == 0) {
+        key = field.getName();
+      }
       if (object instanceof ExternalResourceAware) {
         String prefix = ((ExternalResourceAware) object).getResourceName();
         if (prefix != null) {
@@ -131,7 +126,7 @@ public final class ExternalResourceIniti
       }
 
       // Sanity checks
-      if (value == null && isMandatory(field)) {
+      if (value == null && era.mandatory()) {
         throw new ResourceInitializationException(new IllegalStateException("Mandatory resource ["
                 + key + "] is not set on [" + baseCls + "]"));
       }
@@ -223,89 +218,4 @@ public final class ExternalResourceIniti
       }
     }
   }
-
-  public static <T> Map<String, ExternalResourceDependency> getResourceDeclarations(Class<?> cls)
-          throws ResourceInitializationException {
-    Map<String, ExternalResourceDependency> deps = new HashMap<String, ExternalResourceDependency>();
-    getResourceDeclarations(cls, cls, deps);
-    return deps;
-  }
-
-  private static <T> void getResourceDeclarations(Class<?> baseCls, Class<?> cls,
-          Map<String, ExternalResourceDependency> dependencies)
-          throws ResourceInitializationException {
-    if (cls.getSuperclass() != null) {
-      getResourceDeclarations(baseCls, cls.getSuperclass(), dependencies);
-    }
-
-    for (Field field : cls.getDeclaredFields()) {
-      if (!ReflectionUtil.isAnnotationPresent(field, ExternalResource.class)) {
-        continue;
-      }
-
-      if (dependencies.containsKey(getKey(field))) {
-        throw new ResourceInitializationException(new IllegalStateException("Key [" + getKey(field)
-                + "] may only be used on a single field."));
-      }
-
-      dependencies.put(getKey(field),
-              createExternalResourceDependency(getKey(field), getApi(field), !isMandatory(field)));
-    }
-  }
-
-  /**
-   * Determine if the field is mandatory.
-   * 
-   * @param field
-   *          the field to bind.
-   * @return whether the field is mandatory.
-   */
-  private static boolean isMandatory(Field field) {
-    return ReflectionUtil.getAnnotation(field, ExternalResource.class).mandatory();
-  }
-
-  /**
-   * Get the binding key for the specified field. If no key is set, use the field name as key.
-   * 
-   * @param field
-   *          the field to bind.
-   * @return the binding key.
-   */
-  private static String getKey(Field field) {
-    ExternalResource cpa = ReflectionUtil.getAnnotation(field, ExternalResource.class);
-    String key = cpa.key();
-    if (key.length() == 0) {
-      key = field.getName();
-    }
-    return key;
-  }
-
-  /**
-   * Get the type of class/interface a resource has to implement to bind to the annotated field. If
-   * no API is set, get it from the annotated field type.
-   * 
-   * @param field
-   *          the field to bind.
-   * @return the API type.
-   */
-  @SuppressWarnings({ "unchecked", "rawtypes" })
-  private static Class<? extends Resource> getApi(Field field) {
-    ExternalResource cpa = ReflectionUtil.getAnnotation(field, ExternalResource.class);
-    Class<? extends Resource> api = cpa.api();
-    // If no api is specified, look at the annotated field
-    if (api == Resource.class) {
-      if (Resource.class.isAssignableFrom(field.getType())
-              || SharedResourceObject.class.isAssignableFrom(field.getType())) {
-        // If no API is set, check if the field type is already a resource type
-        api = (Class<? extends Resource>) field.getType();
-      } else {
-        // If the field does not have a resource type, assume whatever. This allows to use
-        // a resource locator without having to specify the api parameter. It also allows
-        // to directly inject Java objects - yes, I know that Object does not extend
-        // Resource - REC, 2011-03-25
-        api = (Class) Object.class;
-      }
-    }
-    return api;
-  }
 }

Modified: uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/descriptor/ExternalResource.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/descriptor/ExternalResource.java?rev=1481068&r1=1481067&r2=1481068&view=diff
==============================================================================
--- uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/descriptor/ExternalResource.java (original)
+++ uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/descriptor/ExternalResource.java Fri May 10 15:59:23 2013
@@ -51,6 +51,11 @@ public @interface ExternalResource {
   Class<? extends Resource> api() default Resource.class;
 
   /**
+   * A description for the external resource.
+   */
+  String description() default "";
+
+  /**
    * Determines if this external resource is mandatory.
    */
   boolean mandatory() default true;

Modified: uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/factory/AnalysisEngineFactory.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/factory/AnalysisEngineFactory.java?rev=1481068&r1=1481067&r2=1481068&view=diff
==============================================================================
--- uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/factory/AnalysisEngineFactory.java (original)
+++ uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/factory/AnalysisEngineFactory.java Fri May 10 15:59:23 2013
@@ -26,12 +26,12 @@ import static org.apache.uima.fit.factor
 import static org.apache.uima.fit.factory.ConfigurationParameterFactory.ensureParametersComeInPairs;
 import static org.apache.uima.fit.factory.ConfigurationParameterFactory.setParameters;
 import static org.apache.uima.fit.factory.ExternalResourceFactory.bindExternalResource;
+import static org.apache.uima.fit.factory.ExternalResourceFactory.createExternalResourceDependencies;
 import static org.apache.uima.fit.factory.TypeSystemDescriptionFactory.createTypeSystemDescription;
 
 import java.io.IOException;
 import java.net.URL;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -50,13 +50,9 @@ import org.apache.uima.analysis_engine.m
 import org.apache.uima.analysis_engine.metadata.impl.FixedFlow_impl;
 import org.apache.uima.analysis_engine.metadata.impl.FlowControllerDeclaration_impl;
 import org.apache.uima.cas.CAS;
-import org.apache.uima.fit.component.initialize.ExternalResourceInitializer;
-import org.apache.uima.fit.descriptor.SofaCapability;
-import org.apache.uima.fit.descriptor.TypeCapability;
 import org.apache.uima.fit.factory.ConfigurationParameterFactory.ConfigurationData;
 import org.apache.uima.fit.internal.ReflectionUtil;
 import org.apache.uima.flow.FlowControllerDescription;
-import org.apache.uima.resource.ExternalResourceDependency;
 import org.apache.uima.resource.ExternalResourceDescription;
 import org.apache.uima.resource.ResourceInitializationException;
 import org.apache.uima.resource.ResourceSpecifier;
@@ -537,9 +533,7 @@ public final class AnalysisEngineFactory
     }
 
     // Extract external resource dependencies
-    Collection<ExternalResourceDependency> deps = ExternalResourceInitializer
-            .getResourceDeclarations(componentClass).values();
-    desc.setExternalResourceDependencies(deps.toArray(new ExternalResourceDependency[deps.size()]));
+    desc.setExternalResourceDependencies(createExternalResourceDependencies(componentClass));
 
     // Bind External Resources
     if (externalResources != null) {

Modified: uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/factory/CollectionReaderFactory.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/factory/CollectionReaderFactory.java?rev=1481068&r1=1481067&r2=1481068&view=diff
==============================================================================
--- uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/factory/CollectionReaderFactory.java (original)
+++ uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/factory/CollectionReaderFactory.java Fri May 10 15:59:23 2013
@@ -22,6 +22,7 @@ import static org.apache.uima.fit.factor
 import static org.apache.uima.fit.factory.ConfigurationParameterFactory.ensureParametersComeInPairs;
 import static org.apache.uima.fit.factory.ConfigurationParameterFactory.setParameters;
 import static org.apache.uima.fit.factory.ExternalResourceFactory.bindExternalResource;
+import static org.apache.uima.fit.factory.ExternalResourceFactory.createExternalResourceDependencies;
 import static org.apache.uima.fit.factory.FsIndexFactory.createFsIndexCollection;
 import static org.apache.uima.fit.factory.ResourceCreationSpecifierFactory.createResourceCreationSpecifier;
 import static org.apache.uima.fit.factory.TypePrioritiesFactory.createTypePriorities;
@@ -29,7 +30,6 @@ import static org.apache.uima.fit.factor
 
 import java.io.IOException;
 import java.net.URL;
-import java.util.Collection;
 import java.util.Map;
 import java.util.Map.Entry;
 
@@ -38,9 +38,7 @@ import org.apache.uima.UIMAException;
 import org.apache.uima.UIMAFramework;
 import org.apache.uima.collection.CollectionReader;
 import org.apache.uima.collection.CollectionReaderDescription;
-import org.apache.uima.fit.component.initialize.ExternalResourceInitializer;
 import org.apache.uima.fit.factory.ConfigurationParameterFactory.ConfigurationData;
-import org.apache.uima.resource.ExternalResourceDependency;
 import org.apache.uima.resource.ExternalResourceDescription;
 import org.apache.uima.resource.ResourceCreationSpecifier;
 import org.apache.uima.resource.ResourceInitializationException;
@@ -305,9 +303,7 @@ public final class CollectionReaderFacto
     }
 
     // Extract external resource dependencies
-    Collection<ExternalResourceDependency> deps = ExternalResourceInitializer
-            .getResourceDeclarations(readerClass).values();
-    desc.setExternalResourceDependencies(deps.toArray(new ExternalResourceDependency[deps.size()]));
+    desc.setExternalResourceDependencies(createExternalResourceDependencies(readerClass));
 
     // Bind External Resources
     if (externalResources != null) {

Modified: uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/factory/ExternalResourceFactory.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/factory/ExternalResourceFactory.java?rev=1481068&r1=1481067&r2=1481068&view=diff
==============================================================================
--- uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/factory/ExternalResourceFactory.java (original)
+++ uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/factory/ExternalResourceFactory.java Fri May 10 15:59:23 2013
@@ -24,9 +24,11 @@ import static org.apache.uima.fit.factor
 import static org.apache.uima.fit.factory.ConfigurationParameterFactory.createConfigurationData;
 
 import java.io.File;
+import java.lang.reflect.Field;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -40,7 +42,7 @@ import org.apache.uima.collection.Collec
 import org.apache.uima.fit.descriptor.ExternalResource;
 import org.apache.uima.fit.factory.ConfigurationParameterFactory.ConfigurationData;
 import org.apache.uima.fit.internal.ExtendedExternalResourceDescription_impl;
-import org.apache.uima.resource.ConfigurableDataResourceSpecifier;
+import org.apache.uima.fit.internal.ReflectionUtil;
 import org.apache.uima.resource.CustomResourceSpecifier;
 import org.apache.uima.resource.DataResource;
 import org.apache.uima.resource.ExternalResourceDependency;
@@ -50,7 +52,7 @@ import org.apache.uima.resource.Paramete
 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.ResourceInitializationException;
 import org.apache.uima.resource.ResourceSpecifier;
 import org.apache.uima.resource.SharedResourceObject;
 import org.apache.uima.resource.impl.ConfigurableDataResourceSpecifier_impl;
@@ -87,6 +89,15 @@ public final class ExternalResourceFacto
   }
 
   /**
+   * This method determines if the field is annotated with
+   * {@link org.apache.uima.fit.descriptor.ExternalResource}.
+   */
+  public static boolean isExternalResourceField(Field field) {
+    return ReflectionUtil.isAnnotationPresent(field,
+            org.apache.uima.fit.descriptor.ExternalResource.class);
+  }
+
+  /**
    * Create an external resource description for a custom resource. This is intended to be used
    * together with ....
    * 
@@ -308,20 +319,88 @@ public final class ExternalResourceFacto
   }
 
   /**
+   * Creates an ExternalResourceDependency for a field annotated with
+   * {@link org.apache.uima.fit.descriptor.ExternalResource}.
+   */
+  @SuppressWarnings({ "unchecked", "rawtypes" })
+  public static ExternalResourceDependency createExternalResourceDependency(Field field) {
+    ExternalResource era = ReflectionUtil.getAnnotation(field, ExternalResource.class);
+
+    // Get the binding key for the specified field. If no key is set, use the field name as key.
+    String key = era.key();
+    if (key.length() == 0) {
+      key = field.getName();
+    }
+
+    // Get the type of class/interface a resource has to implement to bind to the annotated field.
+    // If no API is set, get it from the annotated field type.
+    Class<? extends Resource> api = era.api();
+    // If no api is specified, look at the annotated field
+    if (api == Resource.class) {
+      if (Resource.class.isAssignableFrom(field.getType())
+              || SharedResourceObject.class.isAssignableFrom(field.getType())) {
+        // If no API is set, check if the field type is already a resource type
+        api = (Class<? extends Resource>) field.getType();
+      } else {
+        // If the field does not have a resource type, assume whatever. This allows to use
+        // a resource locator without having to specify the api parameter. It also allows
+        // to directly inject Java objects - yes, I know that Object does not extend
+        // Resource - REC, 2011-03-25
+        api = (Class) Object.class;
+      }
+    }
+
+    return ExternalResourceFactory.createExternalResourceDependency(key, api, !era.mandatory(),
+            era.description());
+  }
+
+  /**
    * 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) {
+          final Class<?> aInterface, final boolean aOptional, String aDescription) {
     ExternalResourceDependency dep = new ExternalResourceDependency_impl();
     dep.setInterfaceName(aInterface.getName());
     dep.setKey(aKey);
     dep.setOptional(aOptional);
+    dep.setDescription(aDescription);
     return dep;
   }
 
+  public static ExternalResourceDependency[] createExternalResourceDependencies(
+          Class<?> cls) throws ResourceInitializationException {
+    Map<String, ExternalResourceDependency> depMap = new HashMap<String, ExternalResourceDependency>();
+    ExternalResourceFactory.createExternalResourceDependencies(cls, cls, depMap);
+    Collection<ExternalResourceDependency> deps = depMap.values();
+    return deps.toArray(new ExternalResourceDependency[deps.size()]);
+  }
+
+  private static <T> void createExternalResourceDependencies(Class<?> baseCls, Class<?> cls,
+          Map<String, ExternalResourceDependency> dependencies)
+          throws ResourceInitializationException {
+    if (cls.getSuperclass() != null) {
+      createExternalResourceDependencies(baseCls, cls.getSuperclass(), dependencies);
+    }
+
+    for (Field field : cls.getDeclaredFields()) {
+      if (!ReflectionUtil.isAnnotationPresent(field, ExternalResource.class)) {
+        continue;
+      }
+
+      ExternalResourceDependency dep = createExternalResourceDependency(field);
+
+      if (dependencies.containsKey(dep.getKey())) {
+        throw new ResourceInitializationException(new IllegalStateException("Key [" + dep.getKey()
+                + "] may only be used on a single field."));
+      }
+
+      dependencies.put(dep.getKey(), 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.
@@ -648,7 +727,7 @@ public final class ExternalResourceFacto
       setExternalResourceDependencies(
               aDesc,
               (ExternalResourceDependency[]) ArrayUtils.add(deps,
-                      createExternalResourceDependency(aKey, aApi, false)));
+                      createExternalResourceDependency(aKey, aApi, false, null)));
     }
   }
 
@@ -715,7 +794,7 @@ public final class ExternalResourceFacto
         deps = new ExternalResourceDependency[] {};
       }
       aDesc.setExternalResourceDependencies((ExternalResourceDependency[]) ArrayUtils.add(deps,
-              createExternalResourceDependency(aKey, aImpl, false)));
+              createExternalResourceDependency(aKey, aImpl, false, null)));
     }
     bindResource(aDesc, aKey, aImpl, aUrl, aParams);
   }
@@ -747,7 +826,7 @@ public final class ExternalResourceFacto
       if (apiClass.equals(Object.class)) {
         continue;
       }
-      
+
       if (apiClass.isAssignableFrom(resClass)) {
         bindExternalResource(aDesc, dep.getKey(), aResDesc);
       }
@@ -987,19 +1066,18 @@ public final class ExternalResourceFacto
    * varies, depending if the resource extends {@link SharedResourceObject} or implements
    * {@link Resource}.
    * 
-   * @param aDesc the external resource description.
+   * @param aDesc
+   *          the external resource description.
    * @return the implementation name.
    */
-  protected static String getImplementationName(ExternalResourceDescription aDesc)
-  {
+  protected static String getImplementationName(ExternalResourceDescription aDesc) {
     if (aDesc.getResourceSpecifier() instanceof CustomResourceSpecifier) {
       return ((CustomResourceSpecifier) aDesc.getResourceSpecifier()).getResourceClassName();
-    }
-    else {
+    } else {
       return aDesc.getImplementationName();
     }
   }
-  
+
   /**
    * 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.

Modified: uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/factory/FlowControllerFactory.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/factory/FlowControllerFactory.java?rev=1481068&r1=1481067&r2=1481068&view=diff
==============================================================================
--- uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/factory/FlowControllerFactory.java (original)
+++ uima/sandbox/uimafit/trunk/uimafit/src/main/java/org/apache/uima/fit/factory/FlowControllerFactory.java Fri May 10 15:59:23 2013
@@ -22,18 +22,16 @@ import static org.apache.uima.fit.factor
 import static org.apache.uima.fit.factory.ConfigurationParameterFactory.ensureParametersComeInPairs;
 import static org.apache.uima.fit.factory.ConfigurationParameterFactory.setParameters;
 import static org.apache.uima.fit.factory.ExternalResourceFactory.bindExternalResource;
+import static org.apache.uima.fit.factory.ExternalResourceFactory.createExternalResourceDependencies;
 
-import java.util.Collection;
 import java.util.Map;
 import java.util.Map.Entry;
 
 import org.apache.uima.Constants;
-import org.apache.uima.fit.component.initialize.ExternalResourceInitializer;
 import org.apache.uima.fit.factory.ConfigurationParameterFactory.ConfigurationData;
 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;
@@ -99,9 +97,7 @@ public final class FlowControllerFactory
     ResourceMetaDataFactory.configureResourceMetaData(meta, flowControllerClass);
 
     // Extract external resource dependencies
-    Collection<ExternalResourceDependency> deps = ExternalResourceInitializer
-            .getResourceDeclarations(flowControllerClass).values();
-    desc.setExternalResourceDependencies(deps.toArray(new ExternalResourceDependency[deps.size()]));
+    desc.setExternalResourceDependencies(createExternalResourceDependencies(flowControllerClass));
 
     // Bind External Resources
     if (externalResources != null) {

Modified: uima/sandbox/uimafit/trunk/uimafit/src/test/java/org/apache/uima/fit/factory/ExternalResourceConfiguratorTest.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uimafit/trunk/uimafit/src/test/java/org/apache/uima/fit/factory/ExternalResourceConfiguratorTest.java?rev=1481068&r1=1481067&r2=1481068&view=diff
==============================================================================
--- uima/sandbox/uimafit/trunk/uimafit/src/test/java/org/apache/uima/fit/factory/ExternalResourceConfiguratorTest.java (original)
+++ uima/sandbox/uimafit/trunk/uimafit/src/test/java/org/apache/uima/fit/factory/ExternalResourceConfiguratorTest.java Fri May 10 15:59:23 2013
@@ -19,8 +19,8 @@
 
 package org.apache.uima.fit.factory;
 
-import static org.apache.uima.fit.component.initialize.ExternalResourceInitializer.getResourceDeclarations;
 import static org.apache.uima.fit.factory.AnalysisEngineFactory.createPrimitiveDescription;
+import static org.apache.uima.fit.factory.ExternalResourceFactory.createExternalResourceDependencies;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 
@@ -29,7 +29,6 @@ import java.util.Map;
 
 import org.apache.uima.analysis_engine.AnalysisEngineDescription;
 import org.apache.uima.fit.ComponentTestBase;
-import org.apache.uima.fit.component.initialize.ExternalResourceInitializer;
 import org.apache.uima.fit.factory.testAes.ParameterizedAE2;
 import org.apache.uima.resource.ExternalResourceDependency;
 import org.junit.Test;
@@ -41,7 +40,7 @@ import org.junit.Test;
 public class ExternalResourceConfiguratorTest extends ComponentTestBase {
   @Test
   public void testAnalyze() throws Exception {
-    Map<String, ExternalResourceDependency> deps = getResourceDeclarations(ParameterizedAE2.class);
+    ExternalResourceDependency[] deps = createExternalResourceDependencies(ParameterizedAE2.class);
 
     verify(deps);
   }
@@ -50,16 +49,14 @@ public class ExternalResourceConfigurato
   public void testDescriptor() throws Exception {
     AnalysisEngineDescription desc = createPrimitiveDescription(ParameterizedAE2.class,
             typeSystemDescription);
+    verify(desc.getExternalResourceDependencies());
+  }
 
+  private void verify(ExternalResourceDependency[] depList) {
     Map<String, ExternalResourceDependency> deps = new HashMap<String, ExternalResourceDependency>();
-    for (ExternalResourceDependency dep : desc.getExternalResourceDependencies()) {
+    for (ExternalResourceDependency dep : depList) {
       deps.put(dep.getKey(), dep);
     }
-
-    verify(deps);
-  }
-
-  private void verify(Map<String, ExternalResourceDependency> deps) {
     assertEquals(3, deps.size());
 
     String key1 = "res"; // This is the name of the field