All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gate.util.SimpleFeatureMapImpl Maven / Gradle / Ivy

Go to download

GATE - general achitecture for text engineering - is open source software capable of solving almost any text processing problem. This artifact enables you to embed the core GATE Embedded with its essential dependencies. You will able to use the GATE Embedded API and load and store GATE XML documents. This artifact is the perfect dependency for CREOLE plugins or for applications that need to customize the GATE dependencies due to confict with their own dependencies or for lower footprint.

The newest version!
/*
 *  SimpleFeatureMapImpl.java
 *
 *  Copyright (c) 1995-2012, The University of Sheffield. See the file
 *  COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
 *
 *  This file is part of GATE (see http://gate.ac.uk/), and is free
 *  software, licenced under the GNU Library General Public License,
 *  Version 2, June 1991 (in the distribution as file licence.html,
 *  and also available at http://gate.ac.uk/gate/licence.html).
 *
 *  Hamish Cunningham, 7/Feb/2000
 *  borislav popov, 1/May/2002
 *
 *  $Id: SimpleFeatureMapImpl.java 17546 2014-03-05 20:54:08Z markagreenwood $
 */

package gate.util;

import gate.FeatureMap;
import gate.creole.ontology.OClass;
import gate.creole.ontology.OConstants;
import gate.creole.ontology.Ontology;
import gate.event.FeatureMapListener;

import java.util.Set;
import java.util.Vector;

/** Simple case of features. */
public class SimpleFeatureMapImpl
    extends SimpleMapImpl
    implements FeatureMap, java.io.Serializable, java.lang.Cloneable,
    gate.creole.ANNIEConstants
{
  /** Debug flag */
  private static final boolean DEBUG = false;


 /** Freeze the serialization UID. */
  static final long serialVersionUID = -2747241616127229116L;

  /**
   * Test if this featureMap includes all features from aFeatureMap
   *
   * However, if aFeatureMap contains a feature whose value is equal to
   * gate.creole.ANNIEConstants.LOOKUP_CLASS_FEATURE_NAME (which is normally
   * "class"), then GATE will attempt to match that feature using an ontology
   * which it will try to retreive from a feature in both the feature map
   * through which this method is called and in aFeatureMap. If these do not return
   * identical ontologies, or if
   * either feature map does not contain an ontology, then
   * matching will fail, and this method will return false. In summary,
   * this method will not work normally when aFeatureMap contains a feature
   * with the name "class".
   *
    * @param aFeatureMap object which will be included or not in
    * this FeatureMap obj.If this param is null then it will return true.
    * @return true if aFeatureMap is incuded in this obj.
    * and false if not.
    */
  @Override
  public boolean subsumes(FeatureMap aFeatureMap){
    // null is included in everything
    if (aFeatureMap == null) return true;

    if (this.size() < aFeatureMap.size()) return false;

    SimpleFeatureMapImpl sfm = (SimpleFeatureMapImpl)aFeatureMap;

    Object key;
    Object keyValueFromAFeatureMap;
    Object keyValueFromThis;

    for (int i = 0; i < sfm.count; i++) {
      key = sfm.theKeys[i];
      keyValueFromAFeatureMap = sfm.theValues[i];
      int v = super.getSubsumeKey(key);
      if (v < 0) return false;
      keyValueFromThis = theValues[v];//was: get(key);

      if  ( (keyValueFromThis == null && keyValueFromAFeatureMap != null) ||
            (keyValueFromThis != null && keyValueFromAFeatureMap == null)
          ) return false;

      /*ontology aware subsume implementation
      ontotext.bp*/
      if ((keyValueFromThis != null) && (keyValueFromAFeatureMap != null)) {
// commented out as ontology subsumes is now explicitly called if
// an ontology is provided.        
//        if ( key.equals(LOOKUP_CLASS_FEATURE_NAME) ) {
//          /* ontology aware processing */
//          Object sfmOntoObj = sfm.get(LOOKUP_ONTOLOGY_FEATURE_NAME);
//          Object thisOntoObj = this.get(LOOKUP_ONTOLOGY_FEATURE_NAME);
//          if (null!=sfmOntoObj && null!= thisOntoObj) {
//            if (sfmOntoObj.equals(thisOntoObj)) {
//              boolean doSubsume = ontologySubsume(
//                          sfmOntoObj.toString(),
//                          keyValueFromAFeatureMap.toString(),
//                          keyValueFromThis.toString());
//              if (!doSubsume ) {
//                return false;
//              }
//            } // if ontologies are with the same url
//          } //if not null objects
//          else {
//            // incomplete feature set: missing ontology feature
//            return false;
//          }
//        } else {
          /* processing without ontology awareness */
          if (!keyValueFromThis.equals(keyValueFromAFeatureMap)) return false;
//        }  // else
      } // if
    } // for

    return true;
  }//subsumes()

   /** Tests if this featureMap object includes aFeatureMap features. 
* If the feature map contains class and (optionally) ontology features:
* then the ontologyLR is used to provide ontology based subsume with respect to the subClassOf relations. * @param ontologyLR an ontology to be used for the subsume * @param aFeatureMap object which will be included or not in this * FeatureMap obj. * @return true if this includes aFeatureMap * and false if not. */ @Override public boolean subsumes(Ontology ontologyLR, FeatureMap aFeatureMap) { if (ontologyLR == null) { return this.subsumes(aFeatureMap); } if (aFeatureMap == null) return true; if (this.size() < aFeatureMap.size()) return false; SimpleFeatureMapImpl sfm = (SimpleFeatureMapImpl) aFeatureMap; Object key; Object keyValueFromAFeatureMap; Object keyValueFromThis; for (int i = 0; i < sfm.count; i++) { key = sfm.theKeys[i]; keyValueFromAFeatureMap = sfm.theValues[i]; int v = super.getSubsumeKey(key); if (v < 0) return false; keyValueFromThis = theValues[v]; //was: get(key); if ( (keyValueFromThis == null && keyValueFromAFeatureMap != null) || (keyValueFromThis != null && keyValueFromAFeatureMap == null) ) return false; /*ontology aware subsume implementation based on the ontology LR ontotext.bp*/ if ( (keyValueFromThis != null) && (keyValueFromAFeatureMap != null)) { if (key.equals(LOOKUP_CLASS_FEATURE_NAME)) { // ontology aware processing try { OClass superClass = getClassForURIOrName(ontologyLR, keyValueFromAFeatureMap.toString()); OClass subClass = getClassForURIOrName(ontologyLR, keyValueFromThis.toString()); if(superClass == null || subClass == null) return false; if (DEBUG) { Out.prln("\nClass in rule: " + keyValueFromAFeatureMap.toString()); Out.prln("\nClass in annotation: " + keyValueFromThis.toString()); Out.prln("\nisSubClassOf: " + subClass.isSubClassOf(superClass, OConstants.Closure.TRANSITIVE_CLOSURE)); } return subClass.equals(superClass) || subClass.isSubClassOf(superClass, OConstants.Closure.TRANSITIVE_CLOSURE); } catch (Exception ex) { throw new gate.util.GateRuntimeException(ex); } } else { /* processing without ontology awareness */ if (!keyValueFromThis.equals(keyValueFromAFeatureMap)) return false; } // else } // if } // for return true; } //subsumes(ontology) /** * Look up the given name in the given ontology. First we try * treating the name as a complete URI and attempt to find the * matching OClass. If this fails (either the name is not a URI * or there is no class by that URI) then we try again, treating * the name as local to the default namespace of the ontology. * @param ontologyLR the ontology * @param name the URI or local resource name to look up * @return the corresponding OClass, or null if no * suitable class could be found. */ protected OClass getClassForURIOrName(Ontology ontologyLR, String name) { OClass cls = null; try { cls = ontologyLR.getOClass(ontologyLR.createOURI(name)); } catch(Exception e) { // do nothing, but leave cls == null } if(cls == null) { try { cls = ontologyLR.getOClass(ontologyLR.createOURIForName(name)); } catch(Exception e) { // do nothing, but leave cls == null } } return cls; } /** Tests if this featureMap object includes aFeatureMap but only * for the those features present in the aFeatureNamesSet. * * However, if aFeatureMap contains a feature whose value is equal to * gate.creole.ANNIEConstants.LOOKUP_CLASS_FEATURE_NAME (which is normally * "class"), then GATE will attempt to match that feature using an ontology * which it will try to retreive from a feature in both the feature map * through which this method is called and in aFeatureMap. If these do not return * identical ontologies, or if * either feature map does not contain an ontology, then * matching will fail, and this method will return false. In summary, * this method will not work normally when aFeatureMap contains a feature * with the name "class" if that feature is also in aFeatureNamesSet. * * @param aFeatureMap which will be included or not in this * FeatureMap obj.If this param is null then it will return true. * @param aFeatureNamesSet is a set of strings representing the names of the * features that would be considered for subsumes. If aFeatureNamesSet is * null then subsumes(FeatureMap) will be called. * @return true if all features present in the aFeaturesNameSet * from aFeatureMap are included in this obj, or false * otherwise. */ @Override public boolean subsumes(FeatureMap aFeatureMap, Set aFeatureNamesSet){ // This means that all features are taken into consideration. if (aFeatureNamesSet == null) return this.subsumes(aFeatureMap); // null is included in everything if (aFeatureMap == null) return true; // This means that subsumes is supressed. if (aFeatureNamesSet.isEmpty()) return true; SimpleFeatureMapImpl sfm = (SimpleFeatureMapImpl)aFeatureMap; Object key; Object keyValueFromAFeatureMap; Object keyValueFromThis; for (int i = 0; i < sfm.count; i++) { key = sfm.theKeys[i]; if (!aFeatureNamesSet.contains(key)) continue; keyValueFromAFeatureMap = sfm.theValues[i]; keyValueFromThis = get(key); if ( (keyValueFromThis == null && keyValueFromAFeatureMap != null) || (keyValueFromThis != null && keyValueFromAFeatureMap == null) ) return false; if ((keyValueFromThis != null) && (keyValueFromAFeatureMap != null)) { // Commented out as ontology subsumes is now explicitly called when an ontology // is provided. // if ( key.equals(LOOKUP_CLASS_FEATURE_NAME) ) { // /* ontology aware processing */ // if (!aFeatureNamesSet.contains(LOOKUP_ONTOLOGY_FEATURE_NAME)) // continue; // // Object sfmOntoObj = sfm.get(LOOKUP_ONTOLOGY_FEATURE_NAME); // Object thisOntoObj = this.get(LOOKUP_ONTOLOGY_FEATURE_NAME); // if (null!=sfmOntoObj && null!= thisOntoObj) { // if (sfmOntoObj.equals(thisOntoObj)) { // if (! ontologySubsume( // sfmOntoObj.toString(), // keyValueFromAFeatureMap.toString(), // keyValueFromThis.toString())) // return false; // } // if ontologies are with the same url // } //if not null objects // else { // // incomplete feature set: missing ontology feature // return false; // } // } else { /*processing without ontology awareness*/ if (!keyValueFromThis.equals(keyValueFromAFeatureMap)) return false; // } //else } // if values not null } // for return true; }// subsumes() /** * Overriden to fire events, so that the persistent objects * can keep track of what's updated */ @Override public Object put(Object key, Object value) { Object result = super.put(key, value); this.fireMapUpdatedEvent(); return result; } // put /** * Overriden to fire events, so that the persistent objects * can keep track of what's updated */ @Override public Object remove(Object key) { Object result = super.remove(key); this.fireMapUpdatedEvent(); return result; } // remove @Override public void clear() { super.clear(); //tell the world if they're listening this.fireMapUpdatedEvent(); } // clear // Views @Override public Object clone() { return super.clone(); } //clone @Override public boolean equals(Object o) { return super.equals(o); } // equals //////////////////THE EVENT HANDLING CODE////////////// //Needed so an annotation can listen to its features// //and update correctly the database////////////////// private transient Vector mapListeners; /** * Removes a gate listener */ @Override public synchronized void removeFeatureMapListener(FeatureMapListener l) { if (mapListeners != null && mapListeners.contains(l)) { @SuppressWarnings("unchecked") Vector v = (Vector) mapListeners.clone(); v.removeElement(l); mapListeners = v; } } //removeFeatureMapListener /** * Adds a gate listener */ @Override public synchronized void addFeatureMapListener(FeatureMapListener l) { @SuppressWarnings("unchecked") Vector v = mapListeners == null ? new Vector(2) : (Vector)mapListeners.clone(); if (!v.contains(l)) { v.addElement(l); mapListeners = v; } } //addFeatureMapListener /** * */ protected void fireMapUpdatedEvent () { if (mapListeners != null) { Vector listeners = mapListeners; int count = listeners.size(); if (count == 0) return; for (int i = 0; i < count; i++) listeners.elementAt(i).featureMapUpdated(); } }//fireMapUpdatedEvent //Commented out as ontology subsumes is now explicitly called when an ontology //is provided. // /**ontology enhanced subsume // * @param ontoUrl the url of the ontology to be used // * @return true if value1 subsumes value2 in the specified ontology */ // protected boolean ontologySubsume(String ontoUrl,String value1,String value2) { // boolean result = false; // try { // URL url; // try { // url = new URL(ontoUrl); // } catch (MalformedURLException e){ // throw new RuntimeException( // "\nin SimpleFeatureMapImpl on ontologySubsume()\n" // +e.getMessage()+"\n"); // } // // /* GET ONTOLOGY BY URL : a bit tricky reference // since the behaviour behind the getOntology method is // certainly static. // : should be temporary */ // Ontology o = OntologyUtilities.getOntology(url); // OClass superClass = (OClass) o.getOResourceByName(value1); // OClass subClass = (OClass) o.getOResourceByName(value2); // if (subClass.equals(superClass)) // return true; // // if (subClass.isSubClassOf(superClass, OConstants.TRANSITIVE_CLOSURE)) // return true; // // //check for equivalency // Set equiv = superClass.getEquivalentClasses(); // result = equiv.contains(subClass); // // } catch (gate.creole.ResourceInstantiationException x) { // x.printStackTrace(Err.getPrintWriter()); // } // return result; // } // ontologySubsume } // class SimpleFeatureMapImpl




© 2015 - 2025 Weber Informatics LLC | Privacy Policy