001: /*
002: *
003: * Copyright 2007 by BBN Technologies Corporation
004: *
005: */
006:
007: package org.cougaar.util.annotations;
008:
009: import java.lang.annotation.Retention;
010: import java.lang.annotation.RetentionPolicy;
011:
012: /**
013: * Use this class to define COUGAAR-specific annotations. The worker methods for
014: * each annotation type should live elsewhere (eg {@link Argument}).
015: */
016: public class Cougaar {
017: // Plugin and Component argument annotatons
018:
019: /**
020: * Can't use 'null' in annotation attributes, so use this instead
021: */
022: public static final String NULL_VALUE = "###null-value###";
023:
024: /**
025: * This is used to indicate that the field should be left as is
026: */
027: public static final String NO_VALUE = "###no-value###";
028:
029: /**
030: * This annotation should be attached to a public data member to initialize
031: * it from an argument element in the society xml.
032: */
033: @Retention(RetentionPolicy.RUNTIME)
034: public @interface Arg {
035: String name();
036:
037: boolean required() default true;
038:
039: String defaultValue() default NO_VALUE;
040:
041: String description() default "no description";
042: }
043:
044: /**
045: * This annotation should be attached to a public data member if it belongs
046: * to a collection of members that need to be set as a group.
047: */
048: @Retention(RetentionPolicy.RUNTIME)
049: public @interface ArgGroup {
050: String name();
051:
052: Argument.GroupRole role() default Argument.GroupRole.MEMBER;
053:
054: Argument.GroupIterationPolicy policy() default Argument.GroupIterationPolicy.FIRST_UP;
055: }
056:
057: /**
058: * This annotation should be attached to a public static method of any class
059: * that can create an instance given a string. This resolver method will be
060: * used by the argument initialization mechanism for data members whose type
061: * isn't one of the presupported ones (ie not an atomic type, or a boxed
062: * atomic type, or String, or URI, or an Enum).
063: */
064: @Retention(RetentionPolicy.RUNTIME)
065: public @interface Resolver {
066: }
067:
068: // Obtaining services, TBD
069: @Retention(RetentionPolicy.RUNTIME)
070: public @interface ObtainService {
071: }
072:
073: // Execution annotations
074:
075: /**
076: * Attaching this kind annotation to a public method will create an
077: * IncrementalSubscription through the blackboard service, and cause the
078: * annotated method to be invoked for each item in each of the collections
079: * of that subscription mentioned in in {@link #on} clause. These
080: * invocations will happen in the plugin's execute thread, in a
081: * blackboard transaction.
082: *
083: * By default, the method will be invoked on objects whose class matches the
084: * class of the method's single parameter (it must take only one). In other
085: * words, the class of the parameter implicitly filters the subscription to
086: * items of that type. For further filtering, a value for the
087: * {@link #when} clause can be provided. This value should be name of a
088: * predicate method, ie, a public method on the same class that returns a
089: * boolean and takes a single parameter whose class matches that of the
090: * parameter of the annotated method.
091: *
092: * For now, predicate methods can also be defined using the
093: * {@link Predicate} annotation. In this case, the {@link #when} clause
094: * should match the the {@link Predicate#when}. But Predicate annotations
095: * are deprecated and might well be dropped; their use is not
096: * recommended.
097: *
098: * The return value of methods with an Execute annotation is ignored, so a
099: * 'void' return type is almost always the right choice.
100: *
101: */
102: @Retention(RetentionPolicy.RUNTIME)
103: public @interface Execute {
104: /**
105: * @return which subscription modification types are relevant
106: */
107: Subscribe.ModType[] on();
108:
109: /**
110: * @return the name of a predicate method, or a name that matches some
111: * {@link Predicate#when} on the same class}
112: */
113: String when() default NO_VALUE;
114: }
115:
116: /**
117: * Attaching this kind of annotation to a public method causes it to be used
118: * as a filter for an {@link Execute} method with a matching {@link Execute#when}.
119: *
120: * A predicate method must be a public, must return a boolean and must take
121: * exactly one argument. Further, the type of the argument should match that
122: * of the one argument of the corresonding {@link Execute}.
123: *
124: * This annotation is deprecated. Instead of annotating a method this way,
125: * the preferred approach is simply to make the name a predicate method
126: * match the value of the {@link Execute#when} clause.
127: *
128: */
129: @Retention(RetentionPolicy.RUNTIME)
130: @Deprecated
131: public @interface Predicate {
132: String when() default NO_VALUE;
133: }
134: }
|