## org.biojava.bio
Interface AnnotationType

All Known Implementing Classes:
  AnnotationType.Abstract, AnnotationType.Impl

    public interface AnnotationType

A set of constraints on the data contained in an `Annotation`. `AnnotationType` instances can be used to validate an `Annotation` to check that it has the appropriate properties and that they are of the right type.

## Common Usage

     // annType is going to define ID as being a single String and
     // AC as being a list of Strings and accept any other properties at all
     AnnotationType annType = new AnnotationType.Impl();
     annType.setDefaultConstraints(PropertyConstraint.ANY, Cardinality.ANY)
     annType.setConstraints("ID",
                            new PropertyConstraint.ByClass(String.class),
                            CardinalityConstraint.ONE );
     annType.setConstraint("AC",
                           new PropertyConstraint.ByClass(String.class),
                           CardinalityConstraint.ANY );

     Annotation ann = ...;

     if(annType.accepts(ann)) {
       // we have proved that ann contains one ID property that is a String
       System.out.println("ID: " + (String) ann.getProperty("ID"));
       // we know that the AC property is potentialy more than one String -
       // let's use getProperty on AnnotationType to make sure that the
       // values get unpacked cleanly
       System.out.println("AC:");
       for(Iterator i = annType.getProperty(ann, "AC"); i.hasNext(); ) {
         System.out.println("\t" + (String) i.next());
       }
     } else {
       throw new IllegalArgumentException(
         "Expecting an annotation conforming to: "
         annType + " but got: " + ann
       );
     }

## Description

AnnotationType is a constraint-based language for describing sets of Annotation bundles. It works by assuming that any given Annotation may have any set of properties defined. If it matches a particular AnnotationType instance, then each defined property must be of a value that is acceptable to the type, and each undefined property must be allowed to be absend in the type.

`AnnotationType` imposes a data model on `Annotations` where the value of each `slot' is considered as a `Collection`. Values which aren't actually `Collection` instances are treated as singleton sets. Undefined properties are treated as `Collection.EMPTY_SET`. The logic to validate a complete slot in an `Annotation` is encapsulated by a `CollectionConstraint` object. In the common case, slots are validated by `CollectionConstraint.AllValuesIn` which ensures that all members of the collection match a specified `PropertyConstraint`, and that the size of the collection matches a cardinality constraint. This is the most important type of constraint when defining datatypes. However, when using `AnnotationTypes` to specify a query over a set of Annotations, it may be more useful to ask whether a slot contains a given value: For example

     // Test that gene_name contains the value "BRCA2", ignoring other values (synonyms)
     // which might be present in that slot.
     AnnotationType at = new AnnotationType.Impl();
     at.setConstraint(
          "gene_name",
          new CollectionConstraint.Contains(
              new PropertyConstraint.ExactValue("BRCA2"),
              CardinalityConstraint.ONE
          )
     );

It is usually left up to the AnnotationType instance to work out how multiple values should be packed into a single property slot in an Annotation instance. Commonly, things that are allowed a cardinality of 1 will store one value directly in the slot. Things that allow multiple values (and optionaly things with one value) will usualy store them within a Collection in the slot. This complexity is hidden from you if you use the accessor methods built into AnnotationType, setProperty(), addProperty(), removeProperty() and getProperty().

Using AnnotationType instances that you have been provided with e.g. from UnigeneTools.LIBRARY_ANNOTATION `AnnotationType` instances can be used as queries to select from a set of Annotations based on the value of one or more properties. Commonly, this is used in conjunction with `FeatureFilter.ByAnnotationType`. Make AnnotationType instances that describe what should and should not appear in an Annotation bundle Constrain FeatureFilter schemas by Annotation associated with the features Provide meta-data to the tag-value parser for automatically generating object representations of flat-files Implementing your own AnnotationType implementations to reflect frame, schema or ontology definitions. For example, dynamically reflect an RDMBS schema or DAML/Oil deffinition as an AnnotationType.

Since:
  1.3
Author:
  Matthew Pocock, Keith James (docs), Thomas Down

Nested Class Summary
`static class` `AnnotationType.Abstract` An abstract base class useful for implementing AnnotationType instances.
`static class` `AnnotationType.Impl` An implementation of `AnnotationType`.

Field Summary
`static AnnotationType` `ANY` The type that accepts all annotations and is the supertype of all other annotations.
`static AnnotationType` `NONE` The type that accepts no annotations at all and is the subtype of all other annotations.

Method Summary
`void` `addProperty(Annotation ann, Object property, Object value)` Add a value to the specified property slot.
`String` `getComment()` Get the comment for the whole AnnotationType.
`String` `getComment(Object property)` Get the comment for a particular property.
`CollectionConstraint` `getConstraint(Object key)` Retrieve the constraint that will be applied to all properties with a given key.
`CollectionConstraint` `getDefaultConstraint()` Get the CollectionConstraint that will be applied to all properties without an explicit binding.
`Set` `getProperties()` Retrieve the set of properties for which constraints have been explicity specified.
`Collection` `getProperty(Annotation ann, Object property)` Get the Collection of values associated with an Annotation bundle according to the type we believe it to be.
`boolean` `instanceOf(Annotation ann)` Validate an Annotation against this AnnotationType.
`void` `removeProperty(Annotation ann, Object property, Object value)` Remove a value from the specified property slot.
`void` `setComment(Object property, String comment)` Set the comment for a particular property.
`void` `setComment(String comment)` Set the comment for the whole AnnotationType.
`void` `setConstraint(Object key, CollectionConstraint con)` Specifies the constraint to apply to the specified property.
`void` `setConstraints(Object key, PropertyConstraint con, Location card)` Set the constraints associated with a property.
`void` `setDefaultConstraint(CollectionConstraint cc)` Specifies the default constraint to apply to properties where no other constraint is specified.
`void` `setDefaultConstraints(PropertyConstraint pc, Location cc)` Set the constraints that will apply to all properties without an explicitly defined set of constraints.
`void` `setProperty(Annotation ann, Object property, Object value)` Set the property in an annotation bundle according to the type we believe it should be.
`boolean` `subTypeOf(AnnotationType subType)` See if an AnnotationType is a specialisation of this type.

Field Detail

### ANY

    static final AnnotationType ANY

  The type that accepts all annotations and is the supertype of all other annotations. Only an empty annotation is an exact instance of this type. Use this whenever an AnnotationType is needed by an API and you don't want to constrain anything

### NONE

    static final AnnotationType NONE

  The type that accepts no annotations at all and is the subtype of all other annotations. Use this whenever an AnnotationType is needed by an API and you want to make sure that all Annotation objects get rejected

Method Detail

### instanceOf

    boolean instanceOf(Annotation ann)

  Validate an Annotation against this AnnotationType. Any time you wish to see if an Annotation bundle conforms to a type

  Parameters:
    `ann` - the Annotation to validate.
  Returns:
    true if ann conforms to this type and false if it doesn't.

### subTypeOf

    boolean subTypeOf(AnnotationType subType)

  See if an AnnotationType is a specialisation of this type.

  An AnnotationType is a sub-type if it restricts each of the properties of the super-type to a type that can be cast to the type in the super-type. Note that this is not always a cast in the pure Java sense; it may include checks on the number and type of members in collections or other criteria.

  Parameters:
    `subType` - an AnnotationType to check.
  Returns:
    true if subType is a sub-type of this type.

### getConstraint

    CollectionConstraint getConstraint(Object key)

  Retrieve the constraint that will be applied to all properties with a given key.

  For an `Annotation` to be accepted, each key in getProperties() must be present in the annotation and each of the values associated with those properties must match the constraint.

  If you want to find out exactly what constraints will be applied to a particular propery key

  Parameters:
    `key` - the property to be validated.
  Returns:
    PropertyConstraint the constraint by which the values must be accepted.

### setConstraints

    void setConstraints(Object key,
                        PropertyConstraint con,
                        Location card)

  Set the constraints associated with a property. This method constrains the value of the specified property such that all members must match `con`, and the number of members must match `card`. It implicitly constructs a `CollectionConstraint.AllValuesIn` instance.

  When you are building your own AnnotationType

  Parameters:
    `key` - the name of the property to constrain
    `con` - the PropertyConstraint to enforce
    `card` - the CardinalityConstraint to enforce

### setConstraint

    void setConstraint(Object key,
                       CollectionConstraint con)

  Specifies the constraint to apply to the specified property.

  Parameters:
    `key` - the name of the property to constrain
    `con` - the constraint to apply to this slot.

### setDefaultConstraints

    void setDefaultConstraints(PropertyConstraint pc,
                               Location cc)

  Set the constraints that will apply to all properties without an explicitly defined set of constraints. This method constrains the value of the specified property such that all members must match `con`, and the number of members must match `card`. It implicitly constructs a `CollectionConstraint.AllValuesIn` instance.

  Parameters:
    `pc` - the default PropertyConstraint
    `cc` - the default CardinalityConstraint

### setDefaultConstraint

    void setDefaultConstraint(CollectionConstraint cc)

  Specifies the default constraint to apply to properties where no other constraint is specified.

  Parameters:
    `cc` - The default constraint.

### getDefaultConstraint

    CollectionConstraint getDefaultConstraint()

  Get the CollectionConstraint that will be applied to all properties without an explicit binding. This defaults to CollectionConstraint.ALL.

  If you want to find out exactly what constraint will be applied to properties with no explicitly defined constraints

  Returns:
    the default CollectionConstraint

### getProperties

    Set getProperties()

  Retrieve the set of properties for which constraints have been explicity specified. Discover which properties have explicit constraints

  Returns:
    the Set of properties to validate.

### setProperty

    void setProperty(Annotation ann,
                     Object property,
                     Object value)
                     throws ChangeVetoException

  Set the property in an annotation bundle according to the type we believe it should be. This will take care of any neccisary packing or unpacking to Collections.

  Parameters:
    `ann` - the Annotation to modify
    `property` - the property key Object
    `value` - the property value Object
  Throws:
    `ChangeVetoException` - if the value could not be accepted by this annotation type for that property key, or if the Annotation could not be modified

### addProperty

    void addProperty(Annotation ann,
                     Object property,
                     Object value)
                     throws ChangeVetoException

  Add a value to the specified property slot.

  Parameters:
    `ann` - the Annotation to modify
    `property` - the property key Object
    `value` - the property value Object
  Throws:
    `ChangeVetoException` - if the value could not be accepted by this annotation type for that property key, or if the Annotation could not be modified

### getProperty

    Collection getProperty(Annotation ann,
                           Object property)
                           throws ChangeVetoException

  Get the Collection of values associated with an Annotation bundle according to the type we believe it to be. This will take care of any neccisary packing or unpacking to Collections. Properties with no values will return empty Collections.

  Parameters:
    `ann` - the Annotation to access
    `property` - the property key Object
  Returns:
    a Collection of values
  Throws:
    `ChangeVetoException` - if the value could not be removed

### removeProperty

    void removeProperty(Annotation ann,
                        Object property,
                        Object value)
                        throws ChangeVetoException

  Remove a value from the specified property slot.

  Parameters:
    `ann` - the Annotation to modify
    `property` - the property key Object
    `value` - the property value Object
  Throws:
    `ChangeVetoException` - if the Annotation could not be modified

### setComment

    void setComment(String comment)

  Set the comment for the whole AnnotationType. This is human-readable text.

  Parameters:
    `comment` - the new comment

### getComment

    String getComment()

  Get the comment for the whole AnnotationType. This is human-readable text.

  Returns:
    the comment

### setComment

    void setComment(Object property,
                    String comment)

  Set the comment for a particular property. This is a human-readable description of the property.

  Parameters:
    `property` - the property to comment on
    `comment` - the comment

### getComment

    String getComment(Object property)

  Get the comment for a particular property. This is a human-readable description of the property.

  Parameters:
    `property` - the property to get a comment for
  Returns:
    the comment