Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

EclipseLink/Development/2.1/AnnoxSupportForJAXB/311570

< EclipseLink‎ | Development‎ | 2.1
Revision as of 14:53, 5 May 2010 by Matt.macivor.oracle.com (Talk | contribs) (Overview)

Overview

Annox is an open source project that allows a user to specify java annotation meta-data in an external document. This is useful if you're dealing with 3rd party classes that you can't directly modify, or can't include the annotations in the java class itself for some other reason. EclipseLink's JAXB implementation should be able to make use of Annox as a means for specifying annotations externally.

Annox makes use of one .xml file/class to specify the annotation data. The file needs to be in the same package as the class and uses the .ann.xml extension. For example, to add annotations to an Employee class, a file called Employee.ann.xml would be created and added into Employees package.
Sample Employee.ann.xml:

<class xmlns="http://annox.dev.java.net"
	xmlns:g="http://annox.dev.java.net/javax.xml.bind.annotation">
	<g:XmlRootElement name="employee-root" namespace="myns"/>
	<field name="id">
		<g:XmlAttribute/>
	</field>
	<field name="name">
		<g:XmlElement name="employee-name"/>
	</field>
	<field name="transientThing">
		<g:XmlTransient/>
	</field>
</class>


AnnotationHelper

By introducing the AnnotationHelper, EclipseLink can make an easy extension point available that would allow for a user to get their annotation data in any arbitrary way at runtime. AnnotationHelper is a class in the org.eclipse.persistence.javamodel.reflection package.

package org.eclipse.persistence.jaxb.javamodel.reflection;
 
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
 
/**
 * <p><b>Purpose:</b>Provide a class which is responsible for returning Annotations
 * from AnnotatedElements. This class can be extended in the case that the annotation 
 * data is being provided from an external source.
 * 
 * @author mmacivor
 *
 */
public class AnnotationHelper {
 
	/**
	 * Get an annotation of type annotationClass if it's present on the AnnotatedElement
	 * elem.
	 */
	public Annotation getAnnotation(AnnotatedElement elem, Class annotationClass) {
		return elem.getAnnotation(annotationClass);
	}
 
	/**
	 * Get all annotations that exist on the AnnotatedElement elem
	 */
	public Annotation[] getAnnotations(AnnotatedElement elem) {
		return elem.getAnnotations();
	}
 
	/**
	 * Return true if the annotation annotationClass exists on the annotatedElement elem.
	 */
	public boolean isAnnotationPresent(AnnotatedElement elem, Class annotationClass) {
		return elem.isAnnotationPresent(annotationClass);
	}
}

All calls to obtain Annotations by EclipseLink during JAXBContext creation will go through the AnnotationHelper. A user can specify that they want to use a custom AnnotationHelper by setting an instance of AnnotationHelper as a property passed into the JAXBContext creation method:

MyAnnotationHelper helper = new MyAnnotationHelper();
 
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(JAXBContextFactory.ANNOTATION_HELPER_KEY, helper);
 
JAXBContext ctx = JAXBContextFactory.createContext(new Class[] {Employee.class}, properties, Thread.currentThread().getContextClassLoader());


Using Annox

If a user wanted to make use of Annox to obtain their annotation data, they could create a custom AnnotationHelper that makes use of the Annox APIs.

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
 
import org.eclipse.persistence.jaxb.javamodel.reflection.AnnotationHelper;
import org.jvnet.annox.reflect.AnnotatedElementFactory;
 
public class AnnoxAnnotationHelper extends AnnotationHelper {
	AnnotatedElementFactory factory;
 
	public AnnoxAnnotationHelper(AnnotatedElementFactory factory) {
		this.factory = factory;
	}
 
	@Override
	public boolean isAnnotationPresent(AnnotatedElement elem, Class annotationClass) {
		try {
			return factory.getAnnotatedElement(elem).isAnnotationPresent(annotationClass);
		} catch(Exception ex) {
			throw new RuntimeException(ex);
		}
	}
 
	@Override
	public Annotation getAnnotation(AnnotatedElement elem, Class annotationClass) {
		try {
			return factory.getAnnotatedElement(elem).getAnnotation(annotationClass);
		} catch(Exception ex) {
			throw new RuntimeException(ex);
		}
	}
 
	@Override
	public Annotation[] getAnnotations(AnnotatedElement elem) {
		try {
			return factory.getAnnotatedElement(elem).getAnnotations();
		} catch(Exception ex) {
			throw new RuntimeException(ex);
		}
	}
 
}
Then by specifying an instance of this AnnotationHelper via the property as shown above, the Annotations would now be obtained from Annox and contain the information specified in the external XML files

Back to the top