AbstractSemanticAnnotationHelper.java
- /*
- * AbstractSemanticAnnotationHelper.java
- *
- * Copyright (c) 2007-2011, The University of Sheffield.
- *
- * This file is part of GATE MÃmir (see http://gate.ac.uk/family/mimir.html),
- * and is free software, licenced under the GNU Lesser General Public License,
- * Version 3, June 2007 (also included with this distribution as file
- * LICENCE-LGPL3.html).
- *
- * Valentin Tablan, 5 Aug 2009
- *
- * $Id: AbstractSemanticAnnotationHelper.java 17261 2014-01-30 14:05:14Z valyt $
- */
- package gate.mimir;
- import gate.Document;
- import gate.mimir.index.AtomicAnnotationIndex;
- import gate.mimir.index.Mention;
- import gate.mimir.search.QueryEngine;
- import gate.mimir.util.DefaultMentionDescriber;
- import java.io.Serializable;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.List;
- import java.util.Map;
- import java.util.Map.Entry;
- /**
- * Simple abstract class that provides:
- * <ul>
- * <li>an empty implementation for {@link #documentStart(Document)}</li>
- * <li>an empty implementation for {@link #documentEnd()}</li>
- * <li>an implementation for {@link #getMentions(String, Map, QueryEngine)},
- * which simply calls {@link #getMentions(String, List, QueryEngine)} after
- * creating the appropriate constraints.</li>
- * </ul>
- *
- * Subclasses are required to provide a no-argument constructor. When
- * implementing the {@link #init(Indexer)} and {@link #init(QueryEngine)}
- * methods, they must first call super.init(...).
- *
- * <p>If a particular helper does not support certain feature types it should
- * use the {@link #concatenateArrays} method to combine those features with
- * another kind that it can support, during the init(Indexer) call. For example,
- * helpers that do not have access to a full semantic repository may choose to
- * treat URI features as if they were simply text features with no semantics.</p>
- */
- public abstract class AbstractSemanticAnnotationHelper implements
- SemanticAnnotationHelper {
-
- /**
- * Interface for supporting classes used by
- * {@link AbstractSemanticAnnotationHelper} and its sub-classes to provide a
- * pluggable implementation for
- * {@link SemanticAnnotationHelper#describeMention(String)}.
- */
- public static interface MentionDescriber extends Serializable {
- public String describeMention(AbstractSemanticAnnotationHelper helper,
- String mentionUri, String[] descriptiveFeatureNames,
- String[] descriptiveFeatureValues);
- }
-
- private static final long serialVersionUID = -5432862771431426914L;
- private transient boolean isInited = false;
-
-
- protected final boolean isInited() {
- return isInited;
- }
- /**
- * The list of names for the nominal features.
- */
- protected String[] nominalFeatureNames;
- /**
- * The list of names for the numeric features.
- */
- protected String[] integerFeatureNames;
- /**
- * The list of names for the numeric features.
- */
- protected String[] floatFeatureNames;
-
- /**
- * The list of names for the text features.
- */
- protected String[] textFeatureNames;
-
- /**
- * The list of names for the URI features.
- */
- protected String[] uriFeatureNames;
-
- /**
- * The type of the annotations handled by this helper.
- */
- protected String annotationType;
-
- /**
- * The list of names for all the features that should be used when describing
- * an annotation mention (see {@link #describeMention(String)}).
- */
- protected String[] descriptiveFeatures;
-
- protected MentionDescriber mentionDescriber;
-
-
- /**
- * The working mode for this helper (defaults to {@link Mode#ANNOTATION}).
- */
- protected Mode mode = Mode.ANNOTATION;
-
- public Mode getMode() {
- return mode;
- }
- public void setMode(Mode mode) {
- this.mode = mode;
- }
- public String getAnnotationType() {
- return annotationType;
- }
- public void setAnnotationType(String annotationType) {
- this.annotationType = annotationType;
- }
-
- public void setAnnType(String annotationType) {
- setAnnotationType(annotationType);
- }
- public String[] getNominalFeatures() {
- return nominalFeatureNames;
- }
- public void setNominalFeatures(String[] nominalFeatureNames) {
- this.nominalFeatureNames = nominalFeatureNames;
- }
- public String[] getIntegerFeatures() {
- return integerFeatureNames;
- }
- public void setIntegerFeatures(String[] integerFeatureNames) {
- this.integerFeatureNames = integerFeatureNames;
- }
-
- public String[] getFloatFeatures() {
- return floatFeatureNames;
- }
- public void setFloatFeatures(String[] floatFeatureNames) {
- this.floatFeatureNames = floatFeatureNames;
- }
-
- public String[] getTextFeatures() {
- return textFeatureNames;
- }
- public void setTextFeatures(String[] textFeatureNames) {
- this.textFeatureNames = textFeatureNames;
- }
-
- /**
- * @return the uriFeatureNames
- */
- public String[] getUriFeatures() {
- return uriFeatureNames;
- }
- public void setUriFeatures(String[] uriFeatureNames) {
- this.uriFeatureNames = uriFeatureNames;
- }
-
- /**
- * Gets the names of features that should be used when describing an
- * annotation mention.
- *
- * @return the descriptiveFeatures
- */
- protected String[] getDescriptiveFeatures() {
- return descriptiveFeatures;
- }
- /**
- * Sets the names of features that should be used when describing an
- * annotation mention. This should be called <strong>before</strong> the
- * helper is initialised (i.e. before calling {@link #init(QueryEngine)}).
- *
- * If no custom value has been set before {@link #init(QueryEngine)} is
- * called, then all features are used as descriptive features.
- *
- * @param descriptiveFeatures the descriptiveFeatures to set
- */
- public void setDescriptiveFeatures(String[] descriptiveFeatures) {
- this.descriptiveFeatures = descriptiveFeatures;
- }
-
-
- /**
- * @return the mentionDescriber
- */
- public MentionDescriber getMentionDescriber() {
- return mentionDescriber;
- }
- /**
- * Sets the {@link MentionDescriber} to be used as the implementation of
- * {@link SemanticAnnotationHelper#describeMention(String)}.
- * If set to <code>null</code>, then an instance of
- * {@link DefaultMentionDescriber} is automatically created and used.
- *
- * @param mentionDescriber the custom mentionDescriber to use
- */
- public void setMentionDescriber(MentionDescriber mentionDescriber) {
- this.mentionDescriber = mentionDescriber;
- }
- /* (non-Javadoc)
- * @see gate.mimir.SemanticAnnotationHelper#documentEnd()
- */
- public void documentEnd() {}
- public void documentStart(Document document) { }
- /* (non-Javadoc)
- * @see gate.mimir.SemanticAnnotationHelper#getMentions(java.lang.String, java.util.Map, gate.mimir.search.QueryEngine)
- */
- public List<Mention> getMentions(String annotationType,
- Map<String, String> constraints, QueryEngine engine) {
- //convert the simple constraints to actual implementations.
- List<Constraint> predicates = new ArrayList<Constraint>(constraints.size());
- for(Entry<String, String> entry : constraints.entrySet()){
- predicates.add(new Constraint(ConstraintType.EQ, entry.getKey(), entry.getValue()));
- }
- return getMentions(annotationType, predicates, engine);
- }
-
-
- /* (non-Javadoc)
- * @see gate.mimir.SemanticAnnotationHelper#describeMention(java.lang.String)
- */
- @Override
- public String describeMention(String mentionUri) {
- if(mentionDescriber == null) {
- mentionDescriber = new DefaultMentionDescriber();
- }
- return mentionDescriber.describeMention(this, mentionUri,
- getDescriptiveFeatures(), getDescriptiveFeatureValues(mentionUri));
- }
-
- /**
- * Calculates the textual representations for the values of features that are
- * part of the description of an annotation mention. The list of features for
- * which the values should be returned is {@link #descriptiveFeatures}.
- *
- * This implementation always returns <code>null</code> as the abstract class
- * has no way of accessing the actual feature values. Subclasses should
- * provide an actual implementation to support proper mention descriptions.
- *
- * @param mentionUri the URI for the mention that needs to be described.
- *
- * @return an array of strings parallel with {@link #descriptiveFeatures}, or
- * null if the feature values are not known.
- */
- protected String[] getDescriptiveFeatureValues(String mentionUri) {
- return null;
- }
-
- /**
- * Helper method to concatenate a number of arrays into one, for helpers
- * that don't support all the feature types and want to combine some of
- * them together.
- * @return null if all the supplied arrays are either null or empty,
- * otherwise a single array containing the concatenation of
- * all the supplied arrays in order.
- */
- protected static String[] concatenateArrays(String[]... arrays) {
- int totalLength = 0;
- for(String[] arr : arrays) {
- if(arr != null) totalLength += arr.length;
- }
- if(totalLength == 0) return null;
- String[] concat = new String[totalLength];
- int start = 0;
- for(String[] arr : arrays) {
- if(arr != null) {
- System.arraycopy(arr, 0, concat, start, arr.length);
- start += arr.length;
- }
- }
- return concat;
- }
- private void checkInit() {
- if(isInited) throw new IllegalStateException(
- "This helper has already been initialised!");
-
- isInited = true;
- }
-
- @Override
- public void init(AtomicAnnotationIndex index) {
- checkInit();
- // calculate the list of descriptive features if needed
- if(descriptiveFeatures == null) {
- List<String> featNames = new ArrayList<String>();
- if(nominalFeatureNames != null){
- Collections.addAll(featNames, nominalFeatureNames);
- }
- if(integerFeatureNames != null) {
- Collections.addAll(featNames, integerFeatureNames);
- }
- if(floatFeatureNames != null) {
- Collections.addAll(featNames, floatFeatureNames);
- }
- if(textFeatureNames != null) {
- Collections.addAll(featNames, textFeatureNames);
- }
- if(uriFeatureNames != null) {
- Collections.addAll(featNames, uriFeatureNames);
- }
- descriptiveFeatures = featNames.toArray(new String[featNames.size()]);
- }
- }
- }