Author: pkluegl
Date: Thu Aug 25 07:01:42 2016
New Revision: 1757611

URL: http://svn.apache.org/viewvc?rev=1757611&view=rev
Log:
no jira -  avoid npe for empty annotation variables in match condition

Modified:
    
uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/RutaEnvironment.java

Modified: 
uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/RutaEnvironment.java
URL: 
http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/RutaEnvironment.java?rev=1757611&r1=1757610&r2=1757611&view=diff
==============================================================================
--- 
uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/RutaEnvironment.java
 (original)
+++ 
uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/RutaEnvironment.java
 Thu Aug 25 07:01:42 2016
@@ -82,979 +82,980 @@ import org.springframework.core.io.Resou
 
 public class RutaEnvironment {
 
-  private static final String DOCUMENT = "Document";
+       private static final String DOCUMENT = "Document";
 
-  private final Object annotationTypeDummy = new Object();
+       private final Object annotationTypeDummy = new Object();
 
-  private Map<String, Type> types;
+       private Map<String, Type> types;
 
-  private Map<String, RutaWordList> wordLists;
+       private Map<String, RutaWordList> wordLists;
 
-  private Map<String, RutaTable> tables;
-
-  private RutaBlock owner;
-
-  /**
-   * Mapping from short type name (e.g. {@code W}) to their disambiguated long 
type names (e.g.
-   * {@code org.apache.uima.ruta.type.W}).
-   */
-  private Map<String, String> namespaces;
-
-  /**
-   * Mapping from ambiguous short type names to all their possible long type 
names.
-   */
-  private Map<String, Set<String>> ambiguousTypeAlias;
-
-  /**
-   * Set of imported typesystems.
-   */
-  private Set<String> typesystems;
-
-  /**
-   * Set of imported scripts.
-   */
-  private Set<String> scripts;
-
-  /**
-   * An alias from a long to a short name.
-   */
-  private static class Alias {
-    final String longName;
-
-    final String shortName;
-
-    Alias(String longName, String shortName) {
-      this.longName = longName;
-      this.shortName = shortName;
-    }
-  }
-
-  /**
-   * Types that are imported in the environment. Keys are type system 
descriptors and values are
-   * aliased types.
-   */
-  private Map<String, List<Alias>> typeImports;
-
-  /**
-   * Packages that are imported in the environment without a typesystem 
specification.
-   *
-   * Keys are package names and values are aliases. An empty string as alias 
means that all types
-   * from the package should be imported in the default namespace.
-   */
-  private Map<String, List<String>> packageImports;
-
-  /**
-   * Set of types that are declared in the script.
-   */
-  private Set<String> declaredAnnotationTypes;
-
-  private Map<String, Object> variableValues;
-
-  private Map<String, Class<?>> variableTypes;
-
-  private Map<String, Class<?>> availableTypes;
-
-  private Map<String, Class<?>> variableGenericTypes;
-
-  private Map<String, Class<?>> availableListTypes;
-
-  private Map<String, Triple<Map<String, String>, List<AbstractRutaCondition>, 
Set<String>>> macroConditions;
-
-  private Map<String, Triple<Map<String, String>, List<AbstractRutaAction>, 
Set<String>>> macroActions;
-
-  private String[] resourcePaths = null;
-
-  private CAS cas;
-
-  private Map<String, Object> initializedVariables;
-
-  private ResourceManager resourceManager;
-
-  private Map<String, String> variableAliases;
-
-  private RutaVerbalizer verbalizer = new RutaVerbalizer();
-
-  public RutaEnvironment(RutaBlock owner) {
-    super();
-    this.owner = owner;
-
-    types = new HashMap<String, Type>();
-    namespaces = new HashMap<String, String>();
-    ambiguousTypeAlias = new HashMap<String, Set<String>>();
-    typesystems = new HashSet<String>();
-    scripts = new HashSet<String>();
-    typeImports = new HashMap<String, List<Alias>>();
-    packageImports = new HashMap<String, List<String>>();
-    declaredAnnotationTypes = new HashSet<String>();
-    wordLists = new HashMap<String, RutaWordList>();
-    tables = new HashMap<String, RutaTable>();
-    variableValues = new HashMap<String, Object>();
-    variableTypes = new HashMap<String, Class<?>>();
-    variableGenericTypes = new HashMap<String, Class<?>>();
-    macroConditions = new HashMap<>();
-    macroActions = new HashMap<>();
-    availableTypes = new HashMap<String, Class<?>>();
-    availableTypes.put(RutaConstants.RUTA_VARIABLE_ANNOTATION, 
AnnotationFS.class);
-    availableTypes.put("INT", Integer.class);
-    availableTypes.put("STRING", String.class);
-    availableTypes.put("DOUBLE", Double.class);
-    availableTypes.put("FLOAT", Float.class);
-    availableTypes.put("BOOLEAN", Boolean.class);
-    availableTypes.put("TYPE", Type.class);
-    availableTypes.put("CONDITION", AbstractRutaCondition.class);
-    availableTypes.put("ACTION", AbstractRutaAction.class);
-    availableTypes.put("WORDLIST", RutaWordList.class);
-    availableTypes.put("WORDTABLE", RutaTable.class);
-    availableTypes.put("ANNOTATIONLIST", List.class);
-    availableTypes.put("BOOLEANLIST", List.class);
-    availableTypes.put("INTLIST", List.class);
-    availableTypes.put("DOUBLELIST", List.class);
-    availableTypes.put("FLOATLIST", List.class);
-    availableTypes.put("STRINGLIST", List.class);
-    availableTypes.put("TYPELIST", List.class);
-    availableListTypes = new HashMap<String, Class<?>>();
-    availableListTypes.put("ANNOTATIONLIST", AnnotationFS.class);
-    availableListTypes.put("BOOLEANLIST", Boolean.class);
-    availableListTypes.put("INTLIST", Integer.class);
-    availableListTypes.put("DOUBLELIST", Double.class);
-    availableListTypes.put("FLOATLIST", Float.class);
-    availableListTypes.put("STRINGLIST", String.class);
-    availableListTypes.put("TYPELIST", Type.class);
-    resourcePaths = getResourcePaths();
-    initializedVariables = new HashMap<String, Object>();
-    variableAliases = new HashMap<>();
-
-    // Always import BasicTypeSystem
-    addTypeSystem("org.apache.uima.ruta.engine.BasicTypeSystem");
-  }
-
-  /**
-   * Import short type names.
-   *
-   * @param cas
-   *          Cas to initialize the types for.
-   * @param strictImport
-   *          Specify whether all types should be imported (false) or only 
types
-   */
-  public void initializeTypes(CAS cas, boolean strictImport) {
-    this.cas = cas;
-    try {
-      if (strictImport) {
-        importDeclaredTypes(cas.getTypeSystem());
-        importDeclaredTypesystems(cas.getTypeSystem());
-        importTypeAliases(cas.getTypeSystem());
-        importPackageAliases(cas.getTypeSystem());
-        importDeclaredScripts(cas.getTypeSystem());
-      } else {
-        // import all types known to the cas
-        importAllTypes(cas.getTypeSystem());
-        importTypeAliases(cas.getTypeSystem());
-        importPackageAliases(cas.getTypeSystem());
-      }
-
-      // "Document" can be resolved to "uima.tcas.DocumentAnnotation" or
-      // "org.apache.uima.ruta.type.Document",
-      // we force it to the former
-      ambiguousTypeAlias.remove(DOCUMENT);
-      namespaces.remove(DOCUMENT);
-      Type documentType = 
cas.getTypeSystem().getType(UIMAConstants.TYPE_DOCUMENT);
-      addType(DOCUMENT, documentType);
-      addType(documentType.getShortName(), documentType);
-      
-      Type annotationType = 
cas.getJCas().getCasType(org.apache.uima.jcas.tcas.Annotation.type);
-      addType("Annotation", annotationType);
-    } catch (CASException e) {
-      UIMAFramework.getLogger(getClass()).log(SEVERE, "Cannot initialize 
types.", e);
-    } catch (InvalidXMLException e) {
-      UIMAFramework.getLogger(getClass()).log(SEVERE, "Cannot initialize 
types.", e);
-    }
-
-  }
-
-  /**
-   * Imports all types that are known to a type system.
-   *
-   * @param ts
-   *          Type system to import.
-   * @throws CASException
-   */
-  private void importAllTypes(TypeSystem ts) throws CASException {
-    Type topType = ts.getTopType();
-    if (topType != null) {
-      List<Type> list = ts.getProperlySubsumedTypes(topType);
-      for (Type type : list) {
-        addType(type);
-      }
-    }
-  }
-
-  /**
-   * Import all types that are declared by the script.
-   *
-   * @param casTS
-   *          Type system containing all known types.
-   * @throws InvalidXMLException
-   *           When import cannot be resolved.
-   */
-  private void importDeclaredTypes(TypeSystem casTS) throws 
InvalidXMLException {
-    for (String name : declaredAnnotationTypes) {
-      Type type = casTS.getType(name);
-      if (type != null) {
-        addType(type);
-      } else {
-        throw new RuntimeException("Type '" + name + "' not found");
-      }
-    }
-  }
-
-  /**
-   * Import all typesystems that are imported in the script.
-   *
-   * @param casTS
-   *          Type system containing all known types.
-   * @throws InvalidXMLException
-   *           When import cannot be resolved.
-   */
-  private void importDeclaredTypesystems(TypeSystem casTS) throws 
InvalidXMLException {
-    String[] descriptors = typesystems.toArray(new String[typesystems.size()]);
-    TypeSystemDescription ts = 
TypeSystemDescriptionFactory.createTypeSystemDescription(descriptors);
-    ts.resolveImports(resourceManager);
-    for (TypeDescription td : ts.getTypes()) {
-      Type type = casTS.getType(td.getName());
-      if (type != null) {
-        addType(type);
-      } else {
-        throw new RuntimeException("Type '" + td.getName() + "' not found");
-      }
-    }
-  }
-
-  /**
-   * Import all already initialized types of imported scripts.
-   *
-   * @param casTS
-   *          Type system containing all known types.
-   * @throws InvalidXMLException
-   *           When import cannot be resolved.
-   */
-  private void importDeclaredScripts(TypeSystem casTS) throws 
InvalidXMLException {
-
-    RutaModule script = owner.getScript();
-    for (String eachImportedScript : scripts) {
-      RutaModule importedModule = script.getScript(eachImportedScript);
-      RutaEnvironment importedEnvironment = 
importedModule.getRootBlock().getEnvironment();
-      Map<String, Type> importedTypeMap = importedEnvironment.getTypes();
-      Map<String, String> importedNamespaces = 
importedEnvironment.getNamespaces();
-      Set<Entry<String, String>> entrySet = importedNamespaces.entrySet();
-      for (Entry<String, String> entry : entrySet) {
-        if (!ownsType(entry.getValue()) && !StringUtils.equals(entry.getKey(), 
DOCUMENT)) {
-          Type type = importedTypeMap.get(entry.getValue());
-          addType(entry.getKey(), type);
-        }
-      }
-      // TODO import also wordlists and variables?
-    }
-  }
-
-  /**
-   * Imports all type aliases.
-   *
-   * @param casTS
-   *          Cas type system.
-   */
-  private void importTypeAliases(TypeSystem casTS) {
-    for (List<Alias> aliases : typeImports.values()) {
-      for (Alias alias : aliases) {
-        Type type = casTS.getType(alias.longName);
-        if (type == null) {
-          throw new RuntimeException("Type '" + alias.longName + "' not 
found");
-        }
-        addType(alias.shortName, casTS.getType(alias.longName));
-      }
-    }
-  }
-
-  /**
-   * Import all packages that are imported by the script.
-   *
-   * @param casTS
-   *          Type system containing all known types.
-   */
-  private void importPackageAliases(TypeSystem casTS) {
-    Iterator<Type> iter = casTS.getTypeIterator();
-    while (iter.hasNext()) {
-      Type type = iter.next();
-      String name = type.getName();
-      String pkg = name.substring(0, Math.max(name.lastIndexOf('.'), 0));
-      List<String> aliases = packageImports.get(pkg);
-      if (aliases != null) {
-        for (String alias : aliases) {
-          if (alias.isEmpty()) {
-            addType(type);
-          } else {
-            addType(alias + "." + type.getShortName(), type);
-          }
-        }
-      }
-    }
-  }
-
-  public String[] getResourcePaths() {
-    if (resourcePaths == null) {
-      RutaBlock parent = owner.getParent();
-      if (parent != null) {
-        return parent.getEnvironment().getResourcePaths();
-      }
-    }
-    return resourcePaths;
-  }
-
-  public void setResourcePaths(String[] resourcePaths) {
-    this.resourcePaths = resourcePaths;
-  }
-
-  public boolean ownsType(String match) {
-    match = expand(match);
-    return types.keySet().contains(match);
-  }
-
-  private String expand(String string) {
-    String complete = namespaces.get(string);
-    if (complete == null) {
-      if (!string.contains(".")) {
-        complete = namespaces.get(string);
-        if (complete == null) {
-          complete = string;
-        }
-      } else {
-        complete = string;
-      }
-    }
-    return complete;
-  }
-
-  /**
-   * Resolves an annotation type.
-   *
-   * @param match
-   *          Annotation type to resolve.
-   * @return Resolved annotation type or null if match is unknown.
-   * @throws IllegalArgumentException
-   *           When {@code match} is ambiguous.
-   */
-  public Type getType(String match) {
-    // make sure that match is not ambiguous
-    Set<String> ambiguousTargets = ambiguousTypeAlias.get(match);
-    if (ambiguousTargets != null) {
-      StringBuilder message = new StringBuilder(match);
-      message.append(" is ambiguous, use one of the following instead : ");
-      for (String target : ambiguousTargets) {
-        message.append(target).append(' ');
-      }
-      throw new IllegalArgumentException(message.toString());
-    }
-
-    // try to resolve match
-    String expanded = expand(match);
-    Type type = types.get(expanded);
-    if (type == null) {
-      RutaBlock parent = owner.getParent();
-      if (parent != null) {
-        type = parent.getEnvironment().getType(match);
-      }
-    }
-    return type;
-  }
-
-  public void addType(String string, Type type) {
-    importType(type.getName(), string);
-    types.put(type.getName(), type);
-  }
-
-  public void addType(Type type) {
-    addType(type.getShortName(), type);
-  }
-
-  public void declareType(String name) {
-    declaredAnnotationTypes.add(name);
-  }
-
-  /**
-   * Add a typesystem to the script.
-   *
-   * @param descriptor
-   *          Type system's descriptor path.
-   */
-  public void addTypeSystem(String descriptor) {
-    typesystems.add(descriptor);
-  }
-
-  /**
-   * Add a script to the script.
-   *
-   * @param script
-   *          the script's full name.
-   */
-  public void addScript(String script) {
-    scripts.add(script);
-  }
-
-  /**
-   * Import a type in the current namespace.
-   *
-   * @param longName
-   *          Complete type name.
-   * @param shortName
-   *          Short type name (without namespace).
-   */
-  private void importType(String longName, String shortName) {
-    Set<String> targets = ambiguousTypeAlias.get(shortName);
-    if (targets != null) {
-      // shortName is already ambiguous, add longName to its list of possible 
targets
-      targets.add(longName);
-    } else {
-      String existing = namespaces.put(shortName, longName);
-
-      if (existing != null && !existing.equals(longName)) {
-        // shortName can now be resolved to "existing" or "longName"
-        targets = new HashSet<String>(2);
-        targets.add(existing);
-        targets.add(longName);
-
-        // add existing mapping and longName to its list of possible targets
-        ambiguousTypeAlias.put(shortName, targets);
-
-        // remove shortName from the namespace because it is ambiguous
-        namespaces.remove(shortName);
-      }
-    }
-  }
-
-  /**
-   * Import a type from a type system.
-   *
-   * @param typesystem
-   *          Typesystem from which to import the type or null.
-   * @param longName
-   *          Type to import.
-   * @param shortName
-   *          Short name to use for this type.
-   */
-  public void importTypeFromTypeSystem(String typesystem, String longName, 
String shortName) {
-    String key = typesystem != null ? typesystem : "";
-    List<Alias> aliases = typeImports.get(key);
-
-    if (aliases == null) {
-      aliases = new ArrayList<Alias>();
-      typeImports.put(key, aliases);
-    }
-
-    aliases.add(new Alias(longName, shortName));
-  }
-
-  /**
-   * Import a type from a type system.
-   *
-   * The type is aliased by its unqualified name.
-   *
-   * @param typesystem
-   *          Typesystem from which to import the type or null.
-   * @param longName
-   *          Type to import.
-   */
-  public void importTypeFromTypeSystem(String typesystem, String longName) {
-    importTypeFromTypeSystem(typesystem, longName,
-            longName.substring(longName.lastIndexOf('.') + 1));
-  }
-
-  /**
-   * Import all the types from a package.
-   *
-   * @param typesystem
-   *          Type system describing the package to load.
-   * @param packageName
-   *          Package to load or null to load all packages.
-   * @param alias
-   *          Alias of the package. Null or empty string to use no alias.
-   */
-  public void importPackageFromTypeSystem(String typesystem, String 
packageName, String alias) {
-    TypeSystemDescription tsd = TypeSystemDescriptionFactory
-            .createTypeSystemDescription(typesystem);
-    try {
-      tsd.resolveImports(getResourceManager());
-    } catch (InvalidXMLException e) {
-      throw new RuntimeException("Cannot resolve imports in " + typesystem, e);
-    }
-
-    for (TypeDescription td : tsd.getTypes()) {
-      String qname = td.getName();
-      if (packageName == null || (qname.startsWith(packageName)
-              && qname.indexOf('.', packageName.length() + 1) == -1)) {
-        // td is in packageName
-        if (alias != null) {
-          String shortName = alias + "." + 
qname.substring(qname.lastIndexOf('.') + 1);
-          importTypeFromTypeSystem(typesystem, qname, shortName);
-        } else {
-          importTypeFromTypeSystem(typesystem, qname);
-        }
-      }
-    }
-  }
-
-  /**
-   * Imports all the packages from the specified type system.
-   *
-   * @param typesystem
-   *          Typesystem to load.
-   * @param alias
-   *          Alias for all the packages.
-   */
-  public void importAllPackagesFromTypeSystem(String typesystem, String alias) 
{
-    importPackageFromTypeSystem(typesystem, null, alias);
-  }
-
-  /**
-   * Import all the types from a package that are available at runtime.
-   *
-   * @param packageName
-   *          Package to load.
-   * @param alias
-   *          Alias of the package. Null or empty string to use no alias.
-   */
-  public void importPackage(String packageName, String alias) {
-    List<String> aliases = packageImports.get(packageName);
-    if (aliases == null) {
-      aliases = new ArrayList<String>(1);
-      packageImports.put(packageName, aliases);
-    }
-
-    aliases.add(alias == null ? "" : alias);
-  }
-
-  public RutaWordList getWordList(String list) {
-    RutaWordList result = wordLists.get(list);
-    UimaContext context = owner.getContext();
-    Boolean dictRemoveWS = false;
-    if (context != null) {
-      dictRemoveWS = (Boolean) 
context.getConfigParameterValue(RutaEngine.PARAM_DICT_REMOVE_WS);
-      if (dictRemoveWS == null) {
-        dictRemoveWS = false;
-      }
-    }
-    if (result == null) {
-      if (list.endsWith("txt") || list.endsWith("twl") || 
list.endsWith("mtwl")) {
-        ResourceLoader resourceLoader = new 
RutaResourceLoader(getResourcePaths());
-        Resource resource = resourceLoader.getResource(list);
-        if (resource.exists()) {
-          try {
-            if (list.endsWith("mtwl")) {
-              wordLists.put(list, new MultiTreeWordList(resource));
-            } else {
-              wordLists.put(list, new TreeWordList(resource, dictRemoveWS));
-            }
-          } catch (IOException e) {
-            Logger.getLogger(this.getClass().getName()).log(Level.SEVERE,
-                    "Error reading word list" + list, e);
-          }
-        } else {
-          Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "Can't 
find " + list + "!");
-        }
-      } else {
-        try {
-          RutaWordList rutaTable = (RutaWordList) 
context.getResourceObject(list);
-          wordLists.put(list, rutaTable);
-        } catch (ResourceAccessException e) {
-          Logger.getLogger(this.getClass().getName()).log(Level.SEVERE,
-                  "Can't find external resource table" + list, e);
-        }
-      }
-    }
-
-    return wordLists.get(list);
-  }
-
-  public RutaTable getWordTable(String table) {
-    RutaTable result = tables.get(table);
-    if (result == null) {
-      if (table.endsWith("csv")) {
-        ResourceLoader resourceLoader = new 
RutaResourceLoader(getResourcePaths());
-        Resource resource = resourceLoader.getResource(table);
-        if (resource.exists()) {
-          try {
-            tables.put(table, new CSVTable(resource));
-          } catch (IOException e) {
-            Logger.getLogger(this.getClass().getName()).log(Level.SEVERE,
-                    "Error reading csv table " + table, e);
-          }
-        } else {
-          Logger.getLogger(this.getClass().getName()).log(Level.SEVERE,
-                  "Can't find " + table + "!");
-        }
-      } else {
-        try {
-          RutaTable rutaTable = (RutaTable) 
owner.getContext().getResourceObject(table);
-          tables.put(table, rutaTable);
-        } catch (ResourceAccessException e) {
-          Logger.getLogger(this.getClass().getName()).log(Level.SEVERE,
-                  "Can't find external resource table" + table, e);
-        }
-      }
-    }
-
-    return tables.get(table);
-  }
-
-  private void addVariable(String name, Class<?> type, Class<?> generic) {
-    variableTypes.put(name, type);
-    if (generic != null) {
-      variableGenericTypes.put(name, generic);
-    }
-    variableValues.put(name, getInitialValue(name, type));
-  }
-
-  @SuppressWarnings("unchecked")
-  private Object getInitialValue(String name, Class<?> type) {
-    Object init = initializedVariables.get(name);
-    if (init != null) {
-      if (init instanceof List) {
-        ArrayList<Object> list = new ArrayList<Object>();
-        list.addAll((Collection<? extends Object>) init);
-        return list;
-      }
-      return init;
-    }
-    if (Integer.class.equals(type)) {
-      return 0;
-    } else if (Double.class.equals(type)) {
-      return 0d;
-    } else if (Float.class.equals(type)) {
-      return 0f;
-    } else if (String.class.equals(type)) {
-      return "";
-    } else if (Boolean.class.equals(type)) {
-      return false;
-    } else if (Type.class.equals(type)) {
-      if (cas == null) {
-        return annotationTypeDummy;
-      } else {
-        return cas.getAnnotationType();
-      }
-    } else if (List.class.equals(type)) {
-      return new ArrayList<Object>();
-    }
-    return null;
-  }
-
-  public void addVariable(String name, String type) {
-    addVariable(name, availableTypes.get(type), availableListTypes.get(type));
-  }
-
-  public void removeVariable(String name) {
-    variableTypes.remove(name);
-    variableGenericTypes.remove(name);
-    variableValues.remove(name);
-  }
-
-  public boolean ownsVariable(String name) {
-    return variableTypes.containsKey(name);
-  }
-
-  public boolean ownsVariableOfType(String name, String type) {
-    if (variableAliases.containsKey(name)) {
-      name = variableAliases.get(name);
-    }
-    Class<?> varclass = variableTypes.get(name);
-    Class<?> aclass = availableTypes.get(type);
-    boolean list = true;
-    if (aclass.equals(List.class)) {
-      Class<?> vt = variableGenericTypes.get(name);
-      Class<?> at = availableListTypes.get(type);
-      list = vt != null && vt.equals(at);
-    }
-    return list && varclass != null && varclass.equals(aclass);
-  }
-
-  public boolean isVariable(String name) {
-    if (variableAliases.containsKey(name)) {
-      name = variableAliases.get(name);
-    }
-    if (ownsVariable(name)) {
-      return true;
-    }
-    if (owner != null && owner.getParent() != null) {
-      return owner.getParent().getEnvironment().isVariable(name);
-    }
-    return false;
-  }
-
-  public boolean isVariableOfType(String name, String type) {
-    return ownsVariableOfType(name, type) || (owner.getParent() != null
-            && owner.getParent().getEnvironment().isVariableOfType(name, 
type));
-  }
-
-  public Class<?> getVariableType(String name) {
-    if (variableAliases.containsKey(name)) {
-      name = variableAliases.get(name);
-    }
-    Class<?> result = variableTypes.get(name);
-    if (result != null) {
-      return result;
-    } else if (owner.getParent() != null) {
-      return owner.getParent().getEnvironment().getVariableType(name);
-    }
-    return null;
-  }
-
-  public Class<?> getVariableGenericType(String name) {
-    Class<?> result = variableGenericTypes.get(name);
-    if (result != null) {
-      return result;
-    } else if (owner.getParent() != null) {
-      return owner.getParent().getEnvironment().getVariableGenericType(name);
-    }
-    return null;
-  }
-
-  public <T> T getVariableValue(String name, Class<T> type) {
-    if (variableAliases.containsKey(name)) {
-      name = variableAliases.get(name);
-    }
-    boolean containsKey = variableValues.containsKey(name);
-    Object result = variableValues.get(name);
-
-    if (result instanceof String && type.equals(Type.class)) {
-      // "cast" string to type, because initial values were set when there was 
no cas/type system
-      // yet
-      String stringValue = (String) result;
-      result = types.get(stringValue);
-      if(result == null) {
-        // try to resolve short names
-        result = getType(stringValue);
-      }
-    }
-
-    if (containsKey && result == null) {
-      // TODO find the problem with the null values!
-      // this might now work for word lists in another env.
-      Object initialValue = getInitialValue(name, type);
-      if(initialValue instanceof Type) {
-        return type.cast(initialValue);
-      } else {
-        throw new IllegalArgumentException("Variable "+name+" of type" +type 
+" is nto correctly initialized! It is not a Type!");
-      }
-    }
-    if (result == annotationTypeDummy) {
-      return type.cast(cas.getAnnotationType());
-    }
-    if (result != null) {
-      MatchContext context = new MatchContext(owner);
-      if (RutaWordList.class.isAssignableFrom(type) && result instanceof 
WordListExpression) {
-        WordListExpression wle = (WordListExpression) result;
-        RutaWordList list = wle.getList(context);
-        return type.cast(list);
-      } else if (RutaTable.class.isAssignableFrom(type) && result instanceof 
WordTableExpression) {
-        WordTableExpression wte = (WordTableExpression) result;
-        RutaTable table = wte.getTable(context);
-        return type.cast(table);
-      } else {
-        return type.cast(result);
-      }
-    } else if (owner.getParent() != null) {
-      return owner.getParent().getEnvironment().getVariableValue(name, type);
-    }
-    return null;
-  }
-
-  public Object getVariableValue(String name) {
-    return getVariableValue(name, Object.class);
-  }
-
-  @SuppressWarnings("rawtypes")
-  public Object getLiteralValue(String var, Object value) {
-    if (ownsVariable(var)) {
-      MatchContext context = new MatchContext(owner);
-      Class<?> clazz = variableTypes.get(var);
-      if (value instanceof INumberExpression) {
-        INumberExpression ne = (INumberExpression) value;
-        if (clazz.equals(Integer.class)) {
-          return ne.getIntegerValue(context, null);
-        } else if (clazz.equals(Double.class)) {
-          return ne.getDoubleValue(context, null);
-        } else if (clazz.equals(Float.class)) {
-          return ne.getFloatValue(context, null);
-        } else if (clazz.equals(String.class)) {
-          return ne.getStringValue(context, null);
-        }
-      } else if (clazz.equals(String.class) && value instanceof 
IStringExpression) {
-        IStringExpression se = (IStringExpression) value;
-        return se.getStringValue(context, null);
-      } else if (clazz.equals(Boolean.class) && value instanceof 
IBooleanExpression) {
-        IBooleanExpression be = (IBooleanExpression) value;
-        return be.getBooleanValue(context, null);
-      }
-      if (clazz.equals(RutaWordList.class) && value instanceof 
LiteralWordListExpression) {
-        return value;
-      } else if (clazz.equals(RutaWordList.class) && value instanceof String) {
-        return value;
-      } else if (clazz.equals(RutaTable.class) && value instanceof 
LiteralWordTableExpression) {
-        return value;
-      } else if (clazz.equals(RutaTable.class) && value instanceof String) {
-        return value;
-      } else if (clazz.equals(List.class) && value instanceof ListExpression) {
-        List list = getList((ListExpression) value);
-        return list;
-      } else if (clazz.equals(Type.class) && value instanceof CommonToken) {
-        String typeName = ((CommonToken) value).getText();
-        return typeName;
-      } else if (clazz.equals(Type.class) && value instanceof 
SimpleTypeExpression) {
-        String typeName = ((SimpleTypeExpression) value).getTypeString();
-        return typeName;
-      }
-
-      return null;
-    } else {
-      return owner.getParent().getEnvironment().getLiteralValue(var, value);
-    }
-  }
-
-  @SuppressWarnings("unchecked")
-  public void setInitialVariableValue(String var, Object value) {
-    if (ownsVariable(var)) {
-      if (value instanceof List) {
-        List<Object> initValue = new ArrayList<Object>();
-        initValue.addAll((Collection<? extends Object>) value);
-        initializedVariables.put(var, initValue);
-      } else {
-        initializedVariables.put(var, value);
-      }
-      setVariableValue(var, value);
-    } else if (owner.getParent() != null) {
-      owner.getParent().getEnvironment().setInitialVariableValue(var, value);
-    }
-  }
-
-  public void setVariableValue(String name, Object value) {
-    if (variableAliases.containsKey(name)) {
-      name = variableAliases.get(name);
-    }
-    if (ownsVariable(name)) {
-      Class<?> clazz = variableTypes.get(name);
-      if (value == null) {
-        value = getInitialValue(name, clazz);
-      }
-      variableValues.put(name, value);
-    } else if (owner.getParent() != null) {
-      owner.getParent().getEnvironment().setVariableValue(name, value);
-    }
-  }
-
-  @SuppressWarnings("rawtypes")
-  private List getList(ListExpression value) {
-    if (value instanceof SimpleBooleanListExpression) {
-      SimpleBooleanListExpression e = (SimpleBooleanListExpression) value;
-      return e.getList();
-    } else if (value instanceof SimpleNumberListExpression) {
-      SimpleNumberListExpression e = (SimpleNumberListExpression) value;
-      return e.getList();
-    } else if (value instanceof SimpleStringListExpression) {
-      SimpleStringListExpression e = (SimpleStringListExpression) value;
-      return e.getList();
-    } else if (value instanceof SimpleTypeListExpression) {
-      SimpleTypeListExpression e = (SimpleTypeListExpression) value;
-      return e.getList();
-    }
-    return null;
-  }
-
-  public void reset(CAS cas) {
-    this.cas = cas;
-    Set<Entry<String, Object>> entrySet = variableValues.entrySet();
-    for (Entry<String, Object> entry : entrySet) {
-      String key = entry.getKey();
-      Object initialValue = getInitialValue(key, variableTypes.get(key));
-      if (initialValue != null) {
-        // not for word lists
-        entry.setValue(initialValue);
-      }
-    }
-  }
-
-  public ResourceManager getResourceManager() {
-    if (resourceManager != null) {
-      return resourceManager;
-    } else {
-      RutaBlock parent = owner.getParent();
-      if (parent != null) {
-        return parent.getEnvironment().getResourceManager();
-      }
-    }
-    // at least return default resource manager
-    return UIMAFramework.newDefaultResourceManager();
-  }
-
-  public void setResourceManager(ResourceManager resourceManager) {
-    this.resourceManager = resourceManager;
-  }
-
-  public void addMacroAction(String name, Map<String, String> def, Set<String> 
vars,
-          List<AbstractRutaAction> actions) {
-    macroActions.put(name,
-            new ImmutableTriple<Map<String, String>, List<AbstractRutaAction>, 
Set<String>>(def,
-                    actions, vars));
-  }
-
-  public void addMacroCondition(String name, Map<String, String> def, 
Set<String> vars,
-          List<AbstractRutaCondition> conditions) {
-    macroConditions.put(name,
-            new ImmutableTriple<Map<String, String>, 
List<AbstractRutaCondition>, Set<String>>(def,
-                    conditions, vars));
-  }
-
-  public boolean isMacroAction(String name) {
-    return macroActions.keySet().contains(name);
-  }
-
-  public boolean isMacroCondition(String name) {
-    return macroConditions.keySet().contains(name);
-  }
-
-  public Triple<Map<String, String>, List<AbstractRutaAction>, Set<String>> 
getMacroAction(
-          String name) {
-    return macroActions.get(name);
-  }
-
-  public Triple<Map<String, String>, List<AbstractRutaCondition>, Set<String>> 
getMacroCondition(
-          String name) {
-    return macroConditions.get(name);
-  }
-
-  public void addAliasVariable(String name, String var) {
-    variableAliases.put(name, var);
-  }
-
-  public void removeAliasVariable(String name) {
-    variableAliases.remove(name);
-  }
-
-  public String getVariableNameOfExpression(IRutaExpression expression) {
-    String verbalize = verbalizer.verbalize(expression);
-    return verbalize;
-  }
-
-  public Map<String, Type> getTypes() {
-    return types;
-  }
-
-  public Set<String> getDeclaredAnnotationTypes() {
-    return declaredAnnotationTypes;
-  }
-
-  public Set<String> getTypesystems() {
-    return typesystems;
-  }
-
-  public Map<String, String> getNamespaces() {
-    return namespaces;
-  }
+       private Map<String, RutaTable> tables;
+
+       private RutaBlock owner;
+
+       /**
+        * Mapping from short type name (e.g. {@code W}) to their disambiguated 
long
+        * type names (e.g. {@code org.apache.uima.ruta.type.W}).
+        */
+       private Map<String, String> namespaces;
+
+       /**
+        * Mapping from ambiguous short type names to all their possible long 
type
+        * names.
+        */
+       private Map<String, Set<String>> ambiguousTypeAlias;
+
+       /**
+        * Set of imported typesystems.
+        */
+       private Set<String> typesystems;
+
+       /**
+        * Set of imported scripts.
+        */
+       private Set<String> scripts;
+
+       /**
+        * An alias from a long to a short name.
+        */
+       private static class Alias {
+               final String longName;
+
+               final String shortName;
+
+               Alias(String longName, String shortName) {
+                       this.longName = longName;
+                       this.shortName = shortName;
+               }
+       }
+
+       /**
+        * Types that are imported in the environment. Keys are type system
+        * descriptors and values are aliased types.
+        */
+       private Map<String, List<Alias>> typeImports;
+
+       /**
+        * Packages that are imported in the environment without a typesystem
+        * specification.
+        *
+        * Keys are package names and values are aliases. An empty string as 
alias
+        * means that all types from the package should be imported in the 
default
+        * namespace.
+        */
+       private Map<String, List<String>> packageImports;
+
+       /**
+        * Set of types that are declared in the script.
+        */
+       private Set<String> declaredAnnotationTypes;
+
+       private Map<String, Object> variableValues;
+
+       private Map<String, Class<?>> variableTypes;
+
+       private Map<String, Class<?>> availableTypes;
+
+       private Map<String, Class<?>> variableGenericTypes;
+
+       private Map<String, Class<?>> availableListTypes;
+
+       private Map<String, Triple<Map<String, String>, 
List<AbstractRutaCondition>, Set<String>>> macroConditions;
+
+       private Map<String, Triple<Map<String, String>, 
List<AbstractRutaAction>, Set<String>>> macroActions;
+
+       private String[] resourcePaths = null;
+
+       private CAS cas;
+
+       private Map<String, Object> initializedVariables;
+
+       private ResourceManager resourceManager;
+
+       private Map<String, String> variableAliases;
+
+       private RutaVerbalizer verbalizer = new RutaVerbalizer();
+
+       public RutaEnvironment(RutaBlock owner) {
+               super();
+               this.owner = owner;
+
+               types = new HashMap<String, Type>();
+               namespaces = new HashMap<String, String>();
+               ambiguousTypeAlias = new HashMap<String, Set<String>>();
+               typesystems = new HashSet<String>();
+               scripts = new HashSet<String>();
+               typeImports = new HashMap<String, List<Alias>>();
+               packageImports = new HashMap<String, List<String>>();
+               declaredAnnotationTypes = new HashSet<String>();
+               wordLists = new HashMap<String, RutaWordList>();
+               tables = new HashMap<String, RutaTable>();
+               variableValues = new HashMap<String, Object>();
+               variableTypes = new HashMap<String, Class<?>>();
+               variableGenericTypes = new HashMap<String, Class<?>>();
+               macroConditions = new HashMap<>();
+               macroActions = new HashMap<>();
+               availableTypes = new HashMap<String, Class<?>>();
+               availableTypes.put(RutaConstants.RUTA_VARIABLE_ANNOTATION, 
AnnotationFS.class);
+               availableTypes.put("INT", Integer.class);
+               availableTypes.put("STRING", String.class);
+               availableTypes.put("DOUBLE", Double.class);
+               availableTypes.put("FLOAT", Float.class);
+               availableTypes.put("BOOLEAN", Boolean.class);
+               availableTypes.put("TYPE", Type.class);
+               availableTypes.put("CONDITION", AbstractRutaCondition.class);
+               availableTypes.put("ACTION", AbstractRutaAction.class);
+               availableTypes.put("WORDLIST", RutaWordList.class);
+               availableTypes.put("WORDTABLE", RutaTable.class);
+               availableTypes.put("ANNOTATIONLIST", List.class);
+               availableTypes.put("BOOLEANLIST", List.class);
+               availableTypes.put("INTLIST", List.class);
+               availableTypes.put("DOUBLELIST", List.class);
+               availableTypes.put("FLOATLIST", List.class);
+               availableTypes.put("STRINGLIST", List.class);
+               availableTypes.put("TYPELIST", List.class);
+               availableListTypes = new HashMap<String, Class<?>>();
+               availableListTypes.put("ANNOTATIONLIST", AnnotationFS.class);
+               availableListTypes.put("BOOLEANLIST", Boolean.class);
+               availableListTypes.put("INTLIST", Integer.class);
+               availableListTypes.put("DOUBLELIST", Double.class);
+               availableListTypes.put("FLOATLIST", Float.class);
+               availableListTypes.put("STRINGLIST", String.class);
+               availableListTypes.put("TYPELIST", Type.class);
+               resourcePaths = getResourcePaths();
+               initializedVariables = new HashMap<String, Object>();
+               variableAliases = new HashMap<>();
+
+               // Always import BasicTypeSystem
+               addTypeSystem("org.apache.uima.ruta.engine.BasicTypeSystem");
+       }
+
+       /**
+        * Import short type names.
+        *
+        * @param cas
+        *            Cas to initialize the types for.
+        * @param strictImport
+        *            Specify whether all types should be imported (false) or 
only
+        *            types
+        */
+       public void initializeTypes(CAS cas, boolean strictImport) {
+               this.cas = cas;
+               try {
+                       if (strictImport) {
+                               importDeclaredTypes(cas.getTypeSystem());
+                               importDeclaredTypesystems(cas.getTypeSystem());
+                               importTypeAliases(cas.getTypeSystem());
+                               importPackageAliases(cas.getTypeSystem());
+                               importDeclaredScripts(cas.getTypeSystem());
+                       } else {
+                               // import all types known to the cas
+                               importAllTypes(cas.getTypeSystem());
+                               importTypeAliases(cas.getTypeSystem());
+                               importPackageAliases(cas.getTypeSystem());
+                       }
+
+                       // "Document" can be resolved to 
"uima.tcas.DocumentAnnotation" or
+                       // "org.apache.uima.ruta.type.Document",
+                       // we force it to the former
+                       ambiguousTypeAlias.remove(DOCUMENT);
+                       namespaces.remove(DOCUMENT);
+                       Type documentType = 
cas.getTypeSystem().getType(UIMAConstants.TYPE_DOCUMENT);
+                       addType(DOCUMENT, documentType);
+                       addType(documentType.getShortName(), documentType);
+
+                       Type annotationType = 
cas.getJCas().getCasType(org.apache.uima.jcas.tcas.Annotation.type);
+                       addType("Annotation", annotationType);
+               } catch (CASException e) {
+                       UIMAFramework.getLogger(getClass()).log(SEVERE, "Cannot 
initialize types.", e);
+               } catch (InvalidXMLException e) {
+                       UIMAFramework.getLogger(getClass()).log(SEVERE, "Cannot 
initialize types.", e);
+               }
+
+       }
+
+       /**
+        * Imports all types that are known to a type system.
+        *
+        * @param ts
+        *            Type system to import.
+        * @throws CASException
+        */
+       private void importAllTypes(TypeSystem ts) throws CASException {
+               Type topType = ts.getTopType();
+               if (topType != null) {
+                       List<Type> list = ts.getProperlySubsumedTypes(topType);
+                       for (Type type : list) {
+                               addType(type);
+                       }
+               }
+       }
+
+       /**
+        * Import all types that are declared by the script.
+        *
+        * @param casTS
+        *            Type system containing all known types.
+        * @throws InvalidXMLException
+        *             When import cannot be resolved.
+        */
+       private void importDeclaredTypes(TypeSystem casTS) throws 
InvalidXMLException {
+               for (String name : declaredAnnotationTypes) {
+                       Type type = casTS.getType(name);
+                       if (type != null) {
+                               addType(type);
+                       } else {
+                               throw new RuntimeException("Type '" + name + "' 
not found");
+                       }
+               }
+       }
+
+       /**
+        * Import all typesystems that are imported in the script.
+        *
+        * @param casTS
+        *            Type system containing all known types.
+        * @throws InvalidXMLException
+        *             When import cannot be resolved.
+        */
+       private void importDeclaredTypesystems(TypeSystem casTS) throws 
InvalidXMLException {
+               String[] descriptors = typesystems.toArray(new 
String[typesystems.size()]);
+               TypeSystemDescription ts = 
TypeSystemDescriptionFactory.createTypeSystemDescription(descriptors);
+               ts.resolveImports(resourceManager);
+               for (TypeDescription td : ts.getTypes()) {
+                       Type type = casTS.getType(td.getName());
+                       if (type != null) {
+                               addType(type);
+                       } else {
+                               throw new RuntimeException("Type '" + 
td.getName() + "' not found");
+                       }
+               }
+       }
+
+       /**
+        * Import all already initialized types of imported scripts.
+        *
+        * @param casTS
+        *            Type system containing all known types.
+        * @throws InvalidXMLException
+        *             When import cannot be resolved.
+        */
+       private void importDeclaredScripts(TypeSystem casTS) throws 
InvalidXMLException {
+
+               RutaModule script = owner.getScript();
+               for (String eachImportedScript : scripts) {
+                       RutaModule importedModule = 
script.getScript(eachImportedScript);
+                       RutaEnvironment importedEnvironment = 
importedModule.getRootBlock().getEnvironment();
+                       Map<String, Type> importedTypeMap = 
importedEnvironment.getTypes();
+                       Map<String, String> importedNamespaces = 
importedEnvironment.getNamespaces();
+                       Set<Entry<String, String>> entrySet = 
importedNamespaces.entrySet();
+                       for (Entry<String, String> entry : entrySet) {
+                               if (!ownsType(entry.getValue()) && 
!StringUtils.equals(entry.getKey(), DOCUMENT)) {
+                                       Type type = 
importedTypeMap.get(entry.getValue());
+                                       addType(entry.getKey(), type);
+                               }
+                       }
+                       // TODO import also wordlists and variables?
+               }
+       }
+
+       /**
+        * Imports all type aliases.
+        *
+        * @param casTS
+        *            Cas type system.
+        */
+       private void importTypeAliases(TypeSystem casTS) {
+               for (List<Alias> aliases : typeImports.values()) {
+                       for (Alias alias : aliases) {
+                               Type type = casTS.getType(alias.longName);
+                               if (type == null) {
+                                       throw new RuntimeException("Type '" + 
alias.longName + "' not found");
+                               }
+                               addType(alias.shortName, 
casTS.getType(alias.longName));
+                       }
+               }
+       }
+
+       /**
+        * Import all packages that are imported by the script.
+        *
+        * @param casTS
+        *            Type system containing all known types.
+        */
+       private void importPackageAliases(TypeSystem casTS) {
+               Iterator<Type> iter = casTS.getTypeIterator();
+               while (iter.hasNext()) {
+                       Type type = iter.next();
+                       String name = type.getName();
+                       String pkg = name.substring(0, 
Math.max(name.lastIndexOf('.'), 0));
+                       List<String> aliases = packageImports.get(pkg);
+                       if (aliases != null) {
+                               for (String alias : aliases) {
+                                       if (alias.isEmpty()) {
+                                               addType(type);
+                                       } else {
+                                               addType(alias + "." + 
type.getShortName(), type);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       public String[] getResourcePaths() {
+               if (resourcePaths == null) {
+                       RutaBlock parent = owner.getParent();
+                       if (parent != null) {
+                               return 
parent.getEnvironment().getResourcePaths();
+                       }
+               }
+               return resourcePaths;
+       }
+
+       public void setResourcePaths(String[] resourcePaths) {
+               this.resourcePaths = resourcePaths;
+       }
+
+       public boolean ownsType(String match) {
+               match = expand(match);
+               return types.keySet().contains(match);
+       }
+
+       private String expand(String string) {
+               String complete = namespaces.get(string);
+               if (complete == null) {
+                       if (!string.contains(".")) {
+                               complete = namespaces.get(string);
+                               if (complete == null) {
+                                       complete = string;
+                               }
+                       } else {
+                               complete = string;
+                       }
+               }
+               return complete;
+       }
+
+       /**
+        * Resolves an annotation type.
+        *
+        * @param match
+        *            Annotation type to resolve.
+        * @return Resolved annotation type or null if match is unknown.
+        * @throws IllegalArgumentException
+        *             When {@code match} is ambiguous.
+        */
+       public Type getType(String match) {
+               // make sure that match is not ambiguous
+               Set<String> ambiguousTargets = ambiguousTypeAlias.get(match);
+               if (ambiguousTargets != null) {
+                       StringBuilder message = new StringBuilder(match);
+                       message.append(" is ambiguous, use one of the following 
instead : ");
+                       for (String target : ambiguousTargets) {
+                               message.append(target).append(' ');
+                       }
+                       throw new IllegalArgumentException(message.toString());
+               }
+
+               // try to resolve match
+               String expanded = expand(match);
+               Type type = types.get(expanded);
+               if (type == null) {
+                       RutaBlock parent = owner.getParent();
+                       if (parent != null) {
+                               type = parent.getEnvironment().getType(match);
+                       }
+               }
+               return type;
+       }
+
+       public void addType(String string, Type type) {
+               importType(type.getName(), string);
+               types.put(type.getName(), type);
+       }
+
+       public void addType(Type type) {
+               addType(type.getShortName(), type);
+       }
+
+       public void declareType(String name) {
+               declaredAnnotationTypes.add(name);
+       }
+
+       /**
+        * Add a typesystem to the script.
+        *
+        * @param descriptor
+        *            Type system's descriptor path.
+        */
+       public void addTypeSystem(String descriptor) {
+               typesystems.add(descriptor);
+       }
+
+       /**
+        * Add a script to the script.
+        *
+        * @param script
+        *            the script's full name.
+        */
+       public void addScript(String script) {
+               scripts.add(script);
+       }
+
+       /**
+        * Import a type in the current namespace.
+        *
+        * @param longName
+        *            Complete type name.
+        * @param shortName
+        *            Short type name (without namespace).
+        */
+       private void importType(String longName, String shortName) {
+               Set<String> targets = ambiguousTypeAlias.get(shortName);
+               if (targets != null) {
+                       // shortName is already ambiguous, add longName to its 
list of
+                       // possible targets
+                       targets.add(longName);
+               } else {
+                       String existing = namespaces.put(shortName, longName);
+
+                       if (existing != null && !existing.equals(longName)) {
+                               // shortName can now be resolved to "existing" 
or "longName"
+                               targets = new HashSet<String>(2);
+                               targets.add(existing);
+                               targets.add(longName);
+
+                               // add existing mapping and longName to its 
list of possible
+                               // targets
+                               ambiguousTypeAlias.put(shortName, targets);
+
+                               // remove shortName from the namespace because 
it is ambiguous
+                               namespaces.remove(shortName);
+                       }
+               }
+       }
+
+       /**
+        * Import a type from a type system.
+        *
+        * @param typesystem
+        *            Typesystem from which to import the type or null.
+        * @param longName
+        *            Type to import.
+        * @param shortName
+        *            Short name to use for this type.
+        */
+       public void importTypeFromTypeSystem(String typesystem, String 
longName, String shortName) {
+               String key = typesystem != null ? typesystem : "";
+               List<Alias> aliases = typeImports.get(key);
+
+               if (aliases == null) {
+                       aliases = new ArrayList<Alias>();
+                       typeImports.put(key, aliases);
+               }
+
+               aliases.add(new Alias(longName, shortName));
+       }
+
+       /**
+        * Import a type from a type system.
+        *
+        * The type is aliased by its unqualified name.
+        *
+        * @param typesystem
+        *            Typesystem from which to import the type or null.
+        * @param longName
+        *            Type to import.
+        */
+       public void importTypeFromTypeSystem(String typesystem, String 
longName) {
+               importTypeFromTypeSystem(typesystem, longName, 
longName.substring(longName.lastIndexOf('.') + 1));
+       }
+
+       /**
+        * Import all the types from a package.
+        *
+        * @param typesystem
+        *            Type system describing the package to load.
+        * @param packageName
+        *            Package to load or null to load all packages.
+        * @param alias
+        *            Alias of the package. Null or empty string to use no 
alias.
+        */
+       public void importPackageFromTypeSystem(String typesystem, String 
packageName, String alias) {
+               TypeSystemDescription tsd = 
TypeSystemDescriptionFactory.createTypeSystemDescription(typesystem);
+               try {
+                       tsd.resolveImports(getResourceManager());
+               } catch (InvalidXMLException e) {
+                       throw new RuntimeException("Cannot resolve imports in " 
+ typesystem, e);
+               }
+
+               for (TypeDescription td : tsd.getTypes()) {
+                       String qname = td.getName();
+                       if (packageName == null
+                                       || (qname.startsWith(packageName) && 
qname.indexOf('.', packageName.length() + 1) == -1)) {
+                               // td is in packageName
+                               if (alias != null) {
+                                       String shortName = alias + "." + 
qname.substring(qname.lastIndexOf('.') + 1);
+                                       importTypeFromTypeSystem(typesystem, 
qname, shortName);
+                               } else {
+                                       importTypeFromTypeSystem(typesystem, 
qname);
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Imports all the packages from the specified type system.
+        *
+        * @param typesystem
+        *            Typesystem to load.
+        * @param alias
+        *            Alias for all the packages.
+        */
+       public void importAllPackagesFromTypeSystem(String typesystem, String 
alias) {
+               importPackageFromTypeSystem(typesystem, null, alias);
+       }
+
+       /**
+        * Import all the types from a package that are available at runtime.
+        *
+        * @param packageName
+        *            Package to load.
+        * @param alias
+        *            Alias of the package. Null or empty string to use no 
alias.
+        */
+       public void importPackage(String packageName, String alias) {
+               List<String> aliases = packageImports.get(packageName);
+               if (aliases == null) {
+                       aliases = new ArrayList<String>(1);
+                       packageImports.put(packageName, aliases);
+               }
+
+               aliases.add(alias == null ? "" : alias);
+       }
+
+       public RutaWordList getWordList(String list) {
+               RutaWordList result = wordLists.get(list);
+               UimaContext context = owner.getContext();
+               Boolean dictRemoveWS = false;
+               if (context != null) {
+                       dictRemoveWS = (Boolean) 
context.getConfigParameterValue(RutaEngine.PARAM_DICT_REMOVE_WS);
+                       if (dictRemoveWS == null) {
+                               dictRemoveWS = false;
+                       }
+               }
+               if (result == null) {
+                       if (list.endsWith("txt") || list.endsWith("twl") || 
list.endsWith("mtwl")) {
+                               ResourceLoader resourceLoader = new 
RutaResourceLoader(getResourcePaths());
+                               Resource resource = 
resourceLoader.getResource(list);
+                               if (resource.exists()) {
+                                       try {
+                                               if (list.endsWith("mtwl")) {
+                                                       wordLists.put(list, new 
MultiTreeWordList(resource));
+                                               } else {
+                                                       wordLists.put(list, new 
TreeWordList(resource, dictRemoveWS));
+                                               }
+                                       } catch (IOException e) {
+                                               
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "Error reading 
word list" + list,
+                                                               e);
+                                       }
+                               } else {
+                                       
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "Can't find " + 
list + "!");
+                               }
+                       } else {
+                               try {
+                                       RutaWordList rutaTable = (RutaWordList) 
context.getResourceObject(list);
+                                       wordLists.put(list, rutaTable);
+                               } catch (ResourceAccessException e) {
+                                       
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE,
+                                                       "Can't find external 
resource table" + list, e);
+                               }
+                       }
+               }
+
+               return wordLists.get(list);
+       }
+
+       public RutaTable getWordTable(String table) {
+               RutaTable result = tables.get(table);
+               if (result == null) {
+                       if (table.endsWith("csv")) {
+                               ResourceLoader resourceLoader = new 
RutaResourceLoader(getResourcePaths());
+                               Resource resource = 
resourceLoader.getResource(table);
+                               if (resource.exists()) {
+                                       try {
+                                               tables.put(table, new 
CSVTable(resource));
+                                       } catch (IOException e) {
+                                               
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE,
+                                                               "Error reading 
csv table " + table, e);
+                                       }
+                               } else {
+                                       
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "Can't find " + 
table + "!");
+                               }
+                       } else {
+                               try {
+                                       RutaTable rutaTable = (RutaTable) 
owner.getContext().getResourceObject(table);
+                                       tables.put(table, rutaTable);
+                               } catch (ResourceAccessException e) {
+                                       
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE,
+                                                       "Can't find external 
resource table" + table, e);
+                               }
+                       }
+               }
+
+               return tables.get(table);
+       }
+
+       private void addVariable(String name, Class<?> type, Class<?> generic) {
+               variableTypes.put(name, type);
+               if (generic != null) {
+                       variableGenericTypes.put(name, generic);
+               }
+               variableValues.put(name, getInitialValue(name, type));
+       }
+
+       @SuppressWarnings("unchecked")
+       private Object getInitialValue(String name, Class<?> type) {
+               Object init = initializedVariables.get(name);
+               if (init != null) {
+                       if (init instanceof List) {
+                               ArrayList<Object> list = new 
ArrayList<Object>();
+                               list.addAll((Collection<? extends Object>) 
init);
+                               return list;
+                       }
+                       return init;
+               }
+               if (Integer.class.equals(type)) {
+                       return 0;
+               } else if (Double.class.equals(type)) {
+                       return 0d;
+               } else if (Float.class.equals(type)) {
+                       return 0f;
+               } else if (String.class.equals(type)) {
+                       return "";
+               } else if (Boolean.class.equals(type)) {
+                       return false;
+               } else if (Type.class.equals(type)) {
+                       if (cas == null) {
+                               return annotationTypeDummy;
+                       } else {
+                               return cas.getAnnotationType();
+                       }
+               } else if (List.class.equals(type)) {
+                       return new ArrayList<Object>();
+               }
+               return null;
+       }
+
+       public void addVariable(String name, String type) {
+               addVariable(name, availableTypes.get(type), 
availableListTypes.get(type));
+       }
+
+       public void removeVariable(String name) {
+               variableTypes.remove(name);
+               variableGenericTypes.remove(name);
+               variableValues.remove(name);
+       }
+
+       public boolean ownsVariable(String name) {
+               return variableTypes.containsKey(name);
+       }
+
+       public boolean ownsVariableOfType(String name, String type) {
+               if (variableAliases.containsKey(name)) {
+                       name = variableAliases.get(name);
+               }
+               Class<?> varclass = variableTypes.get(name);
+               Class<?> aclass = availableTypes.get(type);
+               boolean list = true;
+               if (aclass.equals(List.class)) {
+                       Class<?> vt = variableGenericTypes.get(name);
+                       Class<?> at = availableListTypes.get(type);
+                       list = vt != null && vt.equals(at);
+               }
+               return list && varclass != null && varclass.equals(aclass);
+       }
+
+       public boolean isVariable(String name) {
+               if (variableAliases.containsKey(name)) {
+                       name = variableAliases.get(name);
+               }
+               if (ownsVariable(name)) {
+                       return true;
+               }
+               if (owner != null && owner.getParent() != null) {
+                       return 
owner.getParent().getEnvironment().isVariable(name);
+               }
+               return false;
+       }
+
+       public boolean isVariableOfType(String name, String type) {
+               return ownsVariableOfType(name, type)
+                               || (owner.getParent() != null && 
owner.getParent().getEnvironment().isVariableOfType(name, type));
+       }
+
+       public Class<?> getVariableType(String name) {
+               if (variableAliases.containsKey(name)) {
+                       name = variableAliases.get(name);
+               }
+               Class<?> result = variableTypes.get(name);
+               if (result != null) {
+                       return result;
+               } else if (owner.getParent() != null) {
+                       return 
owner.getParent().getEnvironment().getVariableType(name);
+               }
+               return null;
+       }
+
+       public Class<?> getVariableGenericType(String name) {
+               Class<?> result = variableGenericTypes.get(name);
+               if (result != null) {
+                       return result;
+               } else if (owner.getParent() != null) {
+                       return 
owner.getParent().getEnvironment().getVariableGenericType(name);
+               }
+               return null;
+       }
+
+       public <T> T getVariableValue(String name, Class<T> type) {
+               if (variableAliases.containsKey(name)) {
+                       name = variableAliases.get(name);
+               }
+               boolean containsKey = variableValues.containsKey(name);
+               Object result = variableValues.get(name);
+
+               if (result instanceof String && type.equals(Type.class)) {
+                       // "cast" string to type, because initial values were 
set when there
+                       // was no cas/type system
+                       // yet
+                       String stringValue = (String) result;
+                       result = types.get(stringValue);
+                       if (result == null) {
+                               // try to resolve short names
+                               result = getType(stringValue);
+                       }
+               }
+
+               if (containsKey && result == null) {
+                       // TODO find the problem with the null values!
+                       // this might now work for word lists in another env.
+                       Object initialValue = getInitialValue(name, type);
+                       if (initialValue instanceof Type) {
+                               return type.cast(initialValue);
+                       } else if (initialValue != null){
+                               throw new IllegalArgumentException("Variable " 
+ name + " of type " + type
+                                               + " is not correctly 
initialized! It is not a Type, but " + initialValue);
+                       }
+               }
+               if (result == annotationTypeDummy) {
+                       return type.cast(cas.getAnnotationType());
+               }
+               if (result != null) {
+                       MatchContext context = new MatchContext(owner);
+                       if (RutaWordList.class.isAssignableFrom(type) && result 
instanceof WordListExpression) {
+                               WordListExpression wle = (WordListExpression) 
result;
+                               RutaWordList list = wle.getList(context);
+                               return type.cast(list);
+                       } else if (RutaTable.class.isAssignableFrom(type) && 
result instanceof WordTableExpression) {
+                               WordTableExpression wte = (WordTableExpression) 
result;
+                               RutaTable table = wte.getTable(context);
+                               return type.cast(table);
+                       } else {
+                               return type.cast(result);
+                       }
+               } else if (owner.getParent() != null) {
+                       return 
owner.getParent().getEnvironment().getVariableValue(name, type);
+               }
+               return null;
+       }
+
+       public Object getVariableValue(String name) {
+               return getVariableValue(name, Object.class);
+       }
+
+       @SuppressWarnings("rawtypes")
+       public Object getLiteralValue(String var, Object value) {
+               if (ownsVariable(var)) {
+                       MatchContext context = new MatchContext(owner);
+                       Class<?> clazz = variableTypes.get(var);
+                       if (value instanceof INumberExpression) {
+                               INumberExpression ne = (INumberExpression) 
value;
+                               if (clazz.equals(Integer.class)) {
+                                       return ne.getIntegerValue(context, 
null);
+                               } else if (clazz.equals(Double.class)) {
+                                       return ne.getDoubleValue(context, null);
+                               } else if (clazz.equals(Float.class)) {
+                                       return ne.getFloatValue(context, null);
+                               } else if (clazz.equals(String.class)) {
+                                       return ne.getStringValue(context, null);
+                               }
+                       } else if (clazz.equals(String.class) && value 
instanceof IStringExpression) {
+                               IStringExpression se = (IStringExpression) 
value;
+                               return se.getStringValue(context, null);
+                       } else if (clazz.equals(Boolean.class) && value 
instanceof IBooleanExpression) {
+                               IBooleanExpression be = (IBooleanExpression) 
value;
+                               return be.getBooleanValue(context, null);
+                       }
+                       if (clazz.equals(RutaWordList.class) && value 
instanceof LiteralWordListExpression) {
+                               return value;
+                       } else if (clazz.equals(RutaWordList.class) && value 
instanceof String) {
+                               return value;
+                       } else if (clazz.equals(RutaTable.class) && value 
instanceof LiteralWordTableExpression) {
+                               return value;
+                       } else if (clazz.equals(RutaTable.class) && value 
instanceof String) {
+                               return value;
+                       } else if (clazz.equals(List.class) && value instanceof 
ListExpression) {
+                               List list = getList((ListExpression) value);
+                               return list;
+                       } else if (clazz.equals(Type.class) && value instanceof 
CommonToken) {
+                               String typeName = ((CommonToken) 
value).getText();
+                               return typeName;
+                       } else if (clazz.equals(Type.class) && value instanceof 
SimpleTypeExpression) {
+                               String typeName = ((SimpleTypeExpression) 
value).getTypeString();
+                               return typeName;
+                       }
+
+                       return null;
+               } else {
+                       return 
owner.getParent().getEnvironment().getLiteralValue(var, value);
+               }
+       }
+
+       @SuppressWarnings("unchecked")
+       public void setInitialVariableValue(String var, Object value) {
+               if (ownsVariable(var)) {
+                       if (value instanceof List) {
+                               List<Object> initValue = new 
ArrayList<Object>();
+                               initValue.addAll((Collection<? extends Object>) 
value);
+                               initializedVariables.put(var, initValue);
+                       } else {
+                               initializedVariables.put(var, value);
+                       }
+                       setVariableValue(var, value);
+               } else if (owner.getParent() != null) {
+                       
owner.getParent().getEnvironment().setInitialVariableValue(var, value);
+               }
+       }
+
+       public void setVariableValue(String name, Object value) {
+               if (variableAliases.containsKey(name)) {
+                       name = variableAliases.get(name);
+               }
+               if (ownsVariable(name)) {
+                       Class<?> clazz = variableTypes.get(name);
+                       if (value == null) {
+                               value = getInitialValue(name, clazz);
+                       }
+                       variableValues.put(name, value);
+               } else if (owner.getParent() != null) {
+                       
owner.getParent().getEnvironment().setVariableValue(name, value);
+               }
+       }
+
+       @SuppressWarnings("rawtypes")
+       private List getList(ListExpression value) {
+               if (value instanceof SimpleBooleanListExpression) {
+                       SimpleBooleanListExpression e = 
(SimpleBooleanListExpression) value;
+                       return e.getList();
+               } else if (value instanceof SimpleNumberListExpression) {
+                       SimpleNumberListExpression e = 
(SimpleNumberListExpression) value;
+                       return e.getList();
+               } else if (value instanceof SimpleStringListExpression) {
+                       SimpleStringListExpression e = 
(SimpleStringListExpression) value;
+                       return e.getList();
+               } else if (value instanceof SimpleTypeListExpression) {
+                       SimpleTypeListExpression e = (SimpleTypeListExpression) 
value;
+                       return e.getList();
+               }
+               return null;
+       }
+
+       public void reset(CAS cas) {
+               this.cas = cas;
+               Set<Entry<String, Object>> entrySet = variableValues.entrySet();
+               for (Entry<String, Object> entry : entrySet) {
+                       String key = entry.getKey();
+                       Object initialValue = getInitialValue(key, 
variableTypes.get(key));
+                       if (initialValue != null) {
+                               // not for word lists
+                               entry.setValue(initialValue);
+                       }
+               }
+       }
+
+       public ResourceManager getResourceManager() {
+               if (resourceManager != null) {
+                       return resourceManager;
+               } else {
+                       RutaBlock parent = owner.getParent();
+                       if (parent != null) {
+                               return 
parent.getEnvironment().getResourceManager();
+                       }
+               }
+               // at least return default resource manager
+               return UIMAFramework.newDefaultResourceManager();
+       }
+
+       public void setResourceManager(ResourceManager resourceManager) {
+               this.resourceManager = resourceManager;
+       }
+
+       public void addMacroAction(String name, Map<String, String> def, 
Set<String> vars,
+                       List<AbstractRutaAction> actions) {
+               macroActions.put(name,
+                               new ImmutableTriple<Map<String, String>, 
List<AbstractRutaAction>, Set<String>>(def, actions, vars));
+       }
+
+       public void addMacroCondition(String name, Map<String, String> def, 
Set<String> vars,
+                       List<AbstractRutaCondition> conditions) {
+               macroConditions.put(name, new ImmutableTriple<Map<String, 
String>, List<AbstractRutaCondition>, Set<String>>(
+                               def, conditions, vars));
+       }
+
+       public boolean isMacroAction(String name) {
+               return macroActions.keySet().contains(name);
+       }
+
+       public boolean isMacroCondition(String name) {
+               return macroConditions.keySet().contains(name);
+       }
+
+       public Triple<Map<String, String>, List<AbstractRutaAction>, 
Set<String>> getMacroAction(String name) {
+               return macroActions.get(name);
+       }
+
+       public Triple<Map<String, String>, List<AbstractRutaCondition>, 
Set<String>> getMacroCondition(String name) {
+               return macroConditions.get(name);
+       }
+
+       public void addAliasVariable(String name, String var) {
+               variableAliases.put(name, var);
+       }
+
+       public void removeAliasVariable(String name) {
+               variableAliases.remove(name);
+       }
+
+       public String getVariableNameOfExpression(IRutaExpression expression) {
+               String verbalize = verbalizer.verbalize(expression);
+               return verbalize;
+       }
+
+       public Map<String, Type> getTypes() {
+               return types;
+       }
+
+       public Set<String> getDeclaredAnnotationTypes() {
+               return declaredAnnotationTypes;
+       }
+
+       public Set<String> getTypesystems() {
+               return typesystems;
+       }
+
+       public Map<String, String> getNamespaces() {
+               return namespaces;
+       }
 
 }


Reply via email to