Package org.apache.uima.analysis_engine.impl

Source Code of org.apache.uima.analysis_engine.impl.ResultSpecification_impl

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

package org.apache.uima.analysis_engine.impl;

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

import org.apache.uima.analysis_engine.ResultSpecification;
import org.apache.uima.analysis_engine.TypeOrFeature;
import org.apache.uima.cas.Feature;
import org.apache.uima.cas.Type;
import org.apache.uima.cas.TypeSystem;
import org.apache.uima.resource.metadata.Capability;
import org.apache.uima.resource.metadata.impl.MetaDataObject_impl;
import org.apache.uima.resource.metadata.impl.PropertyXmlInfo;
import org.apache.uima.resource.metadata.impl.XmlizationInfo;

/**
* Reference implementaion of {@link ResultSpecification}.
*
*
*/
public final class ResultSpecification_impl extends MetaDataObject_impl implements
        ResultSpecification {

  private static final long serialVersionUID = 8516517600467270594L;

  static final String UNSPECIFIED_LANGUAGE = "x-unspecified";

  /**
   * main language separator e.g 'en' and 'en-US'
   */
  private static final char LANGUAGE_SEPARATOR = '-';

  /**
   * Map from TypeOrFeature objects to HashSets that include the language codes (Strings) for which
   * that type or feature should be produced.
   */
  private Map mTypesAndFeatures = new HashMap();

  /**
   * Map from String type or feature names to HashSets that include the language codes (Strings) for
   * which that type or feature should be produced. This is populated by the compile() method, and
   * includes subtypes as well as the individual feature names for types that have
   * allAnnotatorFeatures=true.
   */
  private Map mCompiledNameToLanguageMap = new HashMap();

  /**
   * Default language set to use if nothing else is specified
   */
  private HashSet mDefaultLanguage = new HashSet();

  /**
   * constructor init the default languge set with the language x-unspecified
   */
  public ResultSpecification_impl() {
    mDefaultLanguage.add(UNSPECIFIED_LANGUAGE);
  }

  /**
   * @see org.apache.uima.analysis_engine.ResultSpecification#getResultTypesAndFeatures()
   */
  public TypeOrFeature[] getResultTypesAndFeatures() {
    TypeOrFeature[] arr = new TypeOrFeature[mTypesAndFeatures.size()];
    mTypesAndFeatures.keySet().toArray(arr);
    return arr;
  }

  /**
   * @see org.apache.uima.analysis_engine.ResultSpecification#getResultTypesAndFeatures(java.lang.String)
   */
  public TypeOrFeature[] getResultTypesAndFeatures(String language) {
    // get language without country if applicable
    String baseLanguage = null;
    int index = language.indexOf(LANGUAGE_SEPARATOR);
    if (index > -1) {
      baseLanguage = language.substring(0, index);
    }

    // holds the found ToFs for the specified language
    Vector vec = new Vector();

    Iterator it = mTypesAndFeatures.keySet().iterator();
    while (it.hasNext()) {
      // get current key
      TypeOrFeature tof = (TypeOrFeature) it.next();
      // get value for the current key
      Set values = (HashSet) mTypesAndFeatures.get(tof);
      if (values.contains(language) || values.contains(UNSPECIFIED_LANGUAGE)
              || values.contains(baseLanguage)) {
        // add tof to the TypeOfFeature array
        vec.add(tof);
      }
    }

    // create array for return
    TypeOrFeature[] arr = new TypeOrFeature[vec.size()];

    // convert vector to TypeOrFeature[]
    vec.toArray(arr);

    return arr;
  }

  /**
   * @see org.apache.uima.analysis_engine.ResultSpecification#setResultTypesAndFeatures(org.apache.uima.analysis_engine.TypeOrFeature[])
   */
  public void setResultTypesAndFeatures(TypeOrFeature[] aTypesAndFeatures) {
    mTypesAndFeatures.clear();
    for (int i = 0; i < aTypesAndFeatures.length; i++) {
      mTypesAndFeatures.put(aTypesAndFeatures[i], mDefaultLanguage);
    }
    // revert to uncompiled state
    mCompiledNameToLanguageMap.clear();
  }

  /**
   * @see org.apache.uima.analysis_engine.ResultSpecification#setResultTypesAndFeatures(org.apache.uima.analysis_engine.TypeOrFeature[],
   *      java.lang.String[])
   */
  public void setResultTypesAndFeatures(TypeOrFeature[] aTypesAndFeatures, String[] aLanguageIDs) {
    if (aLanguageIDs != null) {
      // create HashSet for the aLanguageIDs with the initial capacity of the aLanguageIDs size
      HashSet languagesSupported = new HashSet(aLanguageIDs.length);
      // add all supported languages to at HashSet
      for (int x = 0; x < aLanguageIDs.length; x++) {
        // add current language to the HashSet
        languagesSupported.add(aLanguageIDs[x]);
      }

      mTypesAndFeatures.clear();
      for (int i = 0; i < aTypesAndFeatures.length; i++) {
        mTypesAndFeatures.put(aTypesAndFeatures[i], languagesSupported);
      }
      // revert to uncompiled state
      mCompiledNameToLanguageMap.clear();
    } else {
      // if aLangugeIDs is null set ToFs for the default language
      setResultTypesAndFeatures(aTypesAndFeatures);
    }

  }

  /**
   * @see org.apache.uima.analysis_engine.ResultSpecification#addResultTypeOrFeature(org.apache.uima.analysis_engine.TypeOrFeature)
   */
  public void addResultTypeOrFeature(TypeOrFeature aTypeOrFeature) {
    mTypesAndFeatures.put(aTypeOrFeature, mDefaultLanguage);
    // revert to uncompiled state
    mCompiledNameToLanguageMap.clear();
  }

  /**
   * @see org.apache.uima.analysis_engine.ResultSpecification#addResultTypeOrFeature(org.apache.uima.analysis_engine.TypeOrFeature,
   *      java.lang.String[])
   */
  public void addResultTypeOrFeature(TypeOrFeature aTypeOrFeature, String[] aLanguageIDs) {
    if (aLanguageIDs != null) {
      // create HashSet for the aLanguageIDs with the initial capacity of the aLanguageIDs size
      HashSet languagesSupported = new HashSet(aLanguageIDs.length);
      // add all supported languages to at HashSet
      for (int x = 0; x < aLanguageIDs.length; x++) {
        // add current language to the HashSet
        languagesSupported.add(aLanguageIDs[x]);
      }

      mTypesAndFeatures.put(aTypeOrFeature, languagesSupported);
      // revert to uncompiled state
      mCompiledNameToLanguageMap.clear();
    } else {
      // if aLangugeIDs is null add ToF with the default language
      addResultTypeOrFeature(aTypeOrFeature);
    }
  }

  /**
   * @see org.apache.uima.analysis_engine.ResultSpecification#addResultType(java.lang.String,
   *      boolean)
   */
  public void addResultType(String aTypeName, boolean aAllAnnotatorFeatures) {
    TypeOrFeature t = new TypeOrFeature_impl();
    t.setType(true);
    t.setName(aTypeName);
    t.setAllAnnotatorFeatures(aAllAnnotatorFeatures);
    mTypesAndFeatures.put(t, mDefaultLanguage);
    // revert to uncompiled state
    mCompiledNameToLanguageMap.clear();
  }

  /**
   * @see org.apache.uima.analysis_engine.ResultSpecification#addResultType(java.lang.String,
   *      boolean, java.lang.String[])
   */
  public void addResultType(String aTypeName, boolean aAllAnnotatorFeatures, String[] aLanguageIDs) {
    if (aLanguageIDs != null) {
      // create HashSet for the aLanguageIDs with the initial capacity of the aLanguageIDs size
      HashSet languagesSupported = new HashSet(aLanguageIDs.length);
      // add all supported languages to at HashSet
      for (int x = 0; x < aLanguageIDs.length; x++) {
        // add current language to the HashSet
        languagesSupported.add(aLanguageIDs[x]);
      }

      TypeOrFeature t = new TypeOrFeature_impl();
      t.setType(true);
      t.setName(aTypeName);
      t.setAllAnnotatorFeatures(aAllAnnotatorFeatures);
      HashSet existingLanguages = (HashSet) mTypesAndFeatures.get(t);
      if (existingLanguages != null) {
        existingLanguages.addAll(languagesSupported);
      } else {
        mTypesAndFeatures.put(t, languagesSupported);
      }
      // revert to uncompiled state
      mCompiledNameToLanguageMap.clear();
    } else {
      // if aLangugeIDs is null add type with the default language
      addResultType(aTypeName, aAllAnnotatorFeatures);
    }
  }

  /**
   * @see org.apache.uima.analysis_engine.ResultSpecification#addResultFeature(java.lang.String)
   */
  public void addResultFeature(String aFullFeatureName) {
    TypeOrFeature f = new TypeOrFeature_impl();
    f.setType(false);
    f.setName(aFullFeatureName);
    mTypesAndFeatures.put(f, mDefaultLanguage);
    // revert to uncompiled state
    mCompiledNameToLanguageMap.clear();
  }

  /**
   * @see org.apache.uima.analysis_engine.ResultSpecification#addResultFeature(java.lang.String,
   *      java.lang.String[])
   */
  public void addResultFeature(String aFullFeatureName, String[] aLanguageIDs) {
    if (aLanguageIDs != null) {
      // create HashSet for the aLanguageIDs with the initial capacity of the aLanguageIDs size
      HashSet languagesSupported = new HashSet(aLanguageIDs.length);
      // add all supported languages to at HashSet
      for (int x = 0; x < aLanguageIDs.length; x++) {
        // add current language to the HashSet
        languagesSupported.add(aLanguageIDs[x]);
      }

      TypeOrFeature f = new TypeOrFeature_impl();
      f.setType(false);
      f.setName(aFullFeatureName);
      HashSet existingLanguages = (HashSet) mTypesAndFeatures.get(f);
      if (existingLanguages != null) {
        existingLanguages.addAll(languagesSupported);
      } else {
        mTypesAndFeatures.put(f, languagesSupported);
      }
      // revert to uncompiled state
      mCompiledNameToLanguageMap.clear();
    } else {
      // if aLangugeIDs is null add type with the default language
      addResultFeature(aFullFeatureName);
    }
  }

  /**
   * @see org.apache.uima.analysis_engine.ResultSpecification#compile(org.apache.uima.cas.TypeSystem)
   */
  public void compile(TypeSystem aTypeSystem) {
    mCompiledNameToLanguageMap.clear();
    Iterator it = mTypesAndFeatures.entrySet().iterator();
    while (it.hasNext()) {
      Map.Entry elem = (Map.Entry) it.next();
      TypeOrFeature tof = (TypeOrFeature) elem.getKey();
      if (tof.isType()) {
        Type t = aTypeSystem.getType(tof.getName());
        if (t != null) {
          addTypeRecursive(t, aTypeSystem, (HashSet) elem.getValue(), tof.isAllAnnotatorFeatures());
        }
      } else // feature
      {
        mCompiledNameToLanguageMap.put(tof.getName(), elem.getValue());
      }
    }
    // TODO: process the set of intersections
  }

  /**
   * @param t
   */
  private void addTypeRecursive(Type type, TypeSystem typeSystem, HashSet languages,
          boolean allFeatures) {
    mCompiledNameToLanguageMap.put(type.getName(), languages);
    if (allFeatures) {
      List features = type.getFeatures();
      Iterator featIt = features.iterator();
      while (featIt.hasNext()) {
        Feature f = (Feature) featIt.next();
        mCompiledNameToLanguageMap.put(f.getName(), languages);
      }
    }
    // recurse on subtypes
    List subtypes = typeSystem.getDirectSubtypes(type);
    Iterator typeIt = subtypes.iterator();
    while (typeIt.hasNext()) {
      Type subtype = (Type) typeIt.next();
      addTypeRecursive(subtype, typeSystem, languages, allFeatures);
    }
  }

  /**
   * @see org.apache.uima.analysis_engine.ResultSpecification#containsType(java.lang.String)
   */
  public boolean containsType(String aTypeName) {
    if (aTypeName.indexOf(TypeSystem.FEATURE_SEPARATOR) != -1)
      return false; // check against someone passing a feature name here
    // if compile() has been called can be done by a hash lookup
    if (!mCompiledNameToLanguageMap.isEmpty()) {
      return mCompiledNameToLanguageMap.containsKey(aTypeName);
    } else {
      // brute force search
      Iterator it = mTypesAndFeatures.keySet().iterator();
      while (it.hasNext()) {
        TypeOrFeature elem = (TypeOrFeature) it.next();
        if (elem.isType() && aTypeName.equals(elem.getName())) {
          return true;
        }
      }
      return false;
    }
  }

  /**
   * @see org.apache.uima.analysis_engine.ResultSpecification#containsType(java.lang.String,java.lang.String)
   */
  public boolean containsType(String aTypeName, String language) {
    if (language == null) {
      return containsType(aTypeName);
    }
    if (aTypeName.indexOf(TypeSystem.FEATURE_SEPARATOR) != -1)
      return false; // check against someone passing a feature name here

    // get language without country if applicable
    String baseLanguage = null;
    int index = language.indexOf(LANGUAGE_SEPARATOR);
    if (index > -1) {
      baseLanguage = language.substring(0, index);
    }

    boolean found = false;

    if (!mCompiledNameToLanguageMap.isEmpty()) {
      // if compile() has been called can be done by a hash lookup
      HashSet languages = (HashSet) mCompiledNameToLanguageMap.get(aTypeName);
      if (languages != null) {
        // check if tof is supported for the current language
        if (UNSPECIFIED_LANGUAGE.equals(language) || languages.contains(language)
                || languages.contains(UNSPECIFIED_LANGUAGE) || languages.contains(baseLanguage)) {
          // mark item found
          found = true;
        }
      }
    } else {
      // brute force search
      Iterator it = mTypesAndFeatures.keySet().iterator();
      while (it.hasNext()) {
        TypeOrFeature elem = (TypeOrFeature) it.next();
        if (elem.isType() && aTypeName.equals(elem.getName())) {
          HashSet languages = (HashSet) mTypesAndFeatures.get(elem);
          if (languages != null) {
            // check if tof is supported for the current language
            if (UNSPECIFIED_LANGUAGE.equals(language) || languages.contains(language)
                    || languages.contains(UNSPECIFIED_LANGUAGE) || languages.contains(baseLanguage)) {
              // mark item found
              return true;
            }
          }
        }
      }
    }

    return found;
  }

  /**
   * @see org.apache.uima.analysis_engine.ResultSpecification#containsFeature(java.lang.String)
   */
  public boolean containsFeature(String aFullFeatureName) {
    if (aFullFeatureName.indexOf(TypeSystem.FEATURE_SEPARATOR) == -1)
      return false; // check against someone passing a type name here

    // if compile() has been called can be done by a hash lookup
    if (!mCompiledNameToLanguageMap.isEmpty()) {
      return mCompiledNameToLanguageMap.containsKey(aFullFeatureName);
    } else {
      // brute force search
      // (also need to consider Types with allAnnotatorFeatures = true)
      String typeName = "";
      int typeSeparatorIndex = aFullFeatureName.indexOf(':');
      if (typeSeparatorIndex > 0) {
        typeName = aFullFeatureName.substring(0, typeSeparatorIndex);
      }

      Iterator it = mTypesAndFeatures.keySet().iterator();
      while (it.hasNext()) {
        TypeOrFeature elem = (TypeOrFeature) it.next();
        if ((!elem.isType() && aFullFeatureName.equals(elem.getName()))
                || (elem.isType() && elem.isAllAnnotatorFeatures() && typeName.equals(elem
                        .getName()))) {
          return true;
        }
      }

      return false;
    }
  }

  /**
   * @see org.apache.uima.analysis_engine.ResultSpecification#containsFeature(java.lang.String,java.lang.String)
   */
  public boolean containsFeature(String aFullFeatureName, String language) {
    if (language == null) {
      return containsFeature(aFullFeatureName);
    }
    if (aFullFeatureName.indexOf(TypeSystem.FEATURE_SEPARATOR) == -1)
      return false; // check against someone passing a type name here

    // get language without country if applicable
    String baseLanguage = null;
    int index = language.indexOf(LANGUAGE_SEPARATOR);
    if (index > -1) {
      baseLanguage = language.substring(0, index);
    }

    boolean found = false;

    // if compile() has been called can be done by a hash lookup
    if (!mCompiledNameToLanguageMap.isEmpty()) {
      HashSet languages = (HashSet) mCompiledNameToLanguageMap.get(aFullFeatureName);
      if (languages != null) {
        // check if tof is supported for the current language
        if (UNSPECIFIED_LANGUAGE.equals(language) || languages.contains(language)
                || languages.contains(UNSPECIFIED_LANGUAGE) || languages.contains(baseLanguage)) {
          // mark item found
          found = true;
        }
      }
    } else {
      // brute force search
      // (also need to consider Types with allAnnotatorFeatures = true)
      String typeName = "";
      int typeSeparatorIndex = aFullFeatureName.indexOf(':');
      if (typeSeparatorIndex > 0) {
        typeName = aFullFeatureName.substring(0, typeSeparatorIndex);
      }

      Iterator it = mTypesAndFeatures.keySet().iterator();
      while (it.hasNext()) {
        TypeOrFeature elem = (TypeOrFeature) it.next();
        if ((!elem.isType() && aFullFeatureName.equals(elem.getName()))
                || (elem.isType() && elem.isAllAnnotatorFeatures() && typeName.equals(elem
                        .getName()))) {
          HashSet languages = (HashSet) mTypesAndFeatures.get(elem);
          if (languages != null) {
            // check if tof is supported for the current language
            if (UNSPECIFIED_LANGUAGE.equals(language) || languages.contains(language)
                    || languages.contains(UNSPECIFIED_LANGUAGE) || languages.contains(baseLanguage)) {
              // mark item found
              return true;
            }
          }
        }
      }
    }

    return found;
  }

  /**
   * @see org.apache.uima.resource.impl.MetaDataObject_impl#getXmlizationInfo()
   */
  protected XmlizationInfo getXmlizationInfo() {
    return new XmlizationInfo("resultSpecification", null,
            new PropertyXmlInfo[] { new PropertyXmlInfo("resultTypesAndFeatures", null) });
  }

  /**
   * @see org.apache.uima.analysis_engine.ResultSpecification#addCapabilities(org.apache.uima.resource.metadata.Capability[])
   */
  public void addCapabilities(Capability[] capabilities) {
    addCapabilities(capabilities, true);
  }

  /**
   * @see org.apache.uima.analysis_engine.ResultSpecification#addCapabilities(org.apache.uima.resource.metadata.Capability[],
   *      boolean)
   */
  public void addCapabilities(Capability[] capabilities, boolean outputs) {
    if (capabilities != null) {
      for (int i = 0; i < capabilities.length; i++) {
        TypeOrFeature[] tofs = outputs ? capabilities[i].getOutputs() : capabilities[i].getInputs();

        // get supported languages
        String[] supportedLanguagesArr = capabilities[i].getLanguagesSupported();

        HashSet supportedLanguages = null;
        if (supportedLanguagesArr != null && supportedLanguagesArr.length > 0) {
          // create new HashSet with the initial capacity of the supportedLanguageArr
          supportedLanguages = new HashSet(supportedLanguagesArr.length);
          // add all supported languages to at HashSet
          for (int x = 0; x < supportedLanguagesArr.length; x++) {
            // add current language to the HashSet
            supportedLanguages.add(supportedLanguagesArr[x]);
          }
        } else {
          // if no languages are set, set default language
          supportedLanguages = mDefaultLanguage;
        }

        for (int y = 0; y < tofs.length; y++) {
          mTypesAndFeatures.put(tofs[y], supportedLanguages);
        }

      }
    }
    // revert to uncompiled state
    mCompiledNameToLanguageMap.clear();
  }

  /**
   * @see org.apache.uima.analysis_engine.ResultSpecification#removeTypeOrFeature(org.apache.uima.analysis_engine.TypeOrFeature)
   */
  public void removeTypeOrFeature(TypeOrFeature aTypeOrFeature) {
    // reomve Type or Feature from the
    mTypesAndFeatures.remove(aTypeOrFeature);
    // revert to uncompiled state
    mCompiledNameToLanguageMap.clear();
  }

  /**
   * returns a clone of the <code>ResultSpecification</code> object.
   *
   * @return Object copy of the current object
   */
  public Object clone() {
    // create new result specification
    // NOTE: we don't use super.clone here, since for performance reasons
    // we want to do a faster clone that what the general-purpose logic in
    // MetaDataObject_impl does. This class is marked final so that
    // this can't cause a problem if ResultSpecification_impl is subclassed.
    ResultSpecification_impl newResultSpec = new ResultSpecification_impl();

    // clone HashMaps
    newResultSpec.mTypesAndFeatures = new HashMap(this.mTypesAndFeatures);
    newResultSpec.mDefaultLanguage = new HashSet(this.mDefaultLanguage);

    return newResultSpec;
  }
}
TOP

Related Classes of org.apache.uima.analysis_engine.impl.ResultSpecification_impl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.