Index: src/java/javax/jdo/annotations/Converters.java =================================================================== --- src/java/javax/jdo/annotations/Converters.java (revision 0) +++ src/java/javax/jdo/annotations/Converters.java (revision 0) @@ -0,0 +1,18 @@ +package javax.jdo.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Container annotation to allow for multiple {@link Convert} annotations. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.PACKAGE, ElementType.TYPE }) +public @interface Converters { + /** + * The conversion specifications to be configured. + */ + Convert[] value(); +} Index: src/java/javax/jdo/annotations/Convert.java =================================================================== --- src/java/javax/jdo/annotations/Convert.java (revision 0) +++ src/java/javax/jdo/annotations/Convert.java (revision 0) @@ -0,0 +1,94 @@ +package javax.jdo.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.jdo.AttributeConverter; + +/* + * NOTE: unresolved issues are in "[TBD:" and "]" markers. + */ + +/** + * [TBD: This annotation represents an all-in-one annotation that can be used on + * packages, types, methods & fields. An alternative design would create simpler + * annotations with simpler semantics for each target element: ConvertPackage, + * ConvertType, ConvertAttribute (or ConvertProperty and ConvertField).] + * + * Specifies that a given type should be converted before or after being stored + * or retrieved from the datastore, respectively, from one persistence-capable + * [TBD: and persistence-aware?] type to another using the given + * {@link AttributeConverter}. + * + * If this annotation is placed on a package, then {@link #name()} is ignored + * and the conversion applies to all fields or properties whose types within the + * package match the entity type of the given {@link AttributeConverter}. If + * {@link #subtypes()} is true, then all subtypes of types in the annotated + * package will be subject to the specified conversion. If + * {@link #subpackages()} is true, then types in all subpackages of the + * annotated package will be subject to this conversion specification. This + * annotation is required to be placed on a package statement in + * package-info.java; the resultant behavior upon placing it on any other + * package statement or on multiple package statements is undefined. Placing + * this annotation on a package allows for centralized configuration of + * {@link AttributeConverter}s based on type and possibly field or property + * name. Any {@link Convert} annotations placed on affected types' classes or + * attributes override this annotation. + * + * If this annotation is placed on a type, then {@link #subpackages()} is + * ignored and the conversion applies to all fields or properties whose types + * within the package match the entity type of the given + * {@link AttributeConverter}. If {@link #subtypes()} is true, then all subtypes + * of the annotated type are subject to the given conversion, regardless of + * whether a subclass hides a field of a superclass. If {@link #name()} is not + * the empty string, then the conversion only holds for the field or property + * whose name matches the given name. Placing this annotation on a class allow + * for centralized configuration of class-scoped {@link AttributeConverter}s. + * Any {@link Convert} annotations placed on attributes within the annotated + * type override this annotation. + * + * If this annotation is placed on a field or property, then {@link #name()} + * [TBD: (1) is ignored OR (2) if given, must match the name of the annotated + * field or property name] and the annotated attribute's type must be + * assignment-compatible with the {@link AttributeConverter}'s entity type + * argument. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.PACKAGE, ElementType.TYPE, ElementType.METHOD, + ElementType.FIELD }) +public @interface Convert { + + /** + * The {@link AttributeConverter} to use for conversion. + */ + @SuppressWarnings("rawtypes") + Class extends AttributeConverter> value(); + + /** + * Whether this conversion is enabled. True by default. + */ + boolean enabled() default true; + + /** + * The name of the field or property to which this conversion applies. [TBD: + * (1) Ignored if this annotation is on a field or property. OR (2) If + * given, must match the field or property name.] + */ + String name() default ""; + + /** + * Whether this converter applies to classes in the annotated package and + * subpackages if this annotation is placed on a package. Ignored if this + * annotation is placed on a type, field, or property. + */ + boolean subpackages() default true; + + /** + * Whether this converter applies to subclasses of the annotated type and + * subtypes if this annotation is placed on a class. Ignored if this + * annotation is placed on a field or property. + */ + boolean subtypes() default true; +} Index: src/java/javax/jdo/AttributeConverter.java =================================================================== --- src/java/javax/jdo/AttributeConverter.java (revision 0) +++ src/java/javax/jdo/AttributeConverter.java (revision 0) @@ -0,0 +1,44 @@ +package javax.jdo; + +/** + * Converts persistent attribute values (fields or properties) to different + * values stored in the underlying datastore and vice versa. + * + * [TBD: how should the implementation instantiate or receive them? + *