Motivation: |
Map metadata from ISO-19139 to existing classes |
|---|---|
Contact: |
|
Tracker: |
TBD |
Attachment: |
jaxb-metadata.xml (example of marshalled XML) |
Java objects can be binded to XML using annotations. Many frameworks exist and JAXB is one of them. The traditional approach was to keep org.geotools.metadata as plain JavaBeans implementations without annotations, and let peoples generate their own annotated classes in separated modules. Those annotated classes are typically generated automatically from XSD using some processor - JAXB among others can do that. However like every automatically generated code, the result are plain containers with no intelligence in the sense of no method doing non-trivial tasks related to GIS. It is possible to modify the generated classes afterward, but adding intelligence in the generated classes duplicate the core library.
Our proposal is to annotate the existing metadata classes with JAXB, providing that:
Collection<SomeInterface> stay unchanged - the metadata module must continue to work with arbitrary interfaces. This is possible through the definition of XmlAdapter.The first point is possible since JAXB 2.0 is bundled with Java 6 (we will suggest later an approach for Java 5 users). JAXB is the result of JSR-222 with the participation of Sun Microsystems, IBM, Oracle, Novell, BEA and others, so it is as close to a standard as possible in Java world. We would not support dependencies toward external frameworks like Hibernate or XStream in core GeoTools library, but JAXB is special because of its inclusion in the JDK.
@Documented, so users who don't care will even not notice that they are there.org.geotools.metadata subclasses will have to edit and rebuild GeoTools themself, since they would need to add @XmlTransient on all super-classes.org.geotools.metadata classes offer more flexibility than generated classes. They also contains additional functionalities, like contains(point) methods. Those methods could be added to generated classes, but doing so duplicate the GeoTools core library. It still doable for metadata classes, but would be more difficult for referencing classes.We will configure the build in such a way that Java 5 users will not be affected. First, we will create a new module in the org.geotools.maven group, which will be used at compile time only. This module will contains a copy of JAXB annotations we use, except that their retention policy will be changed as below:
@Retention(RetentionPolicy.SOURCE) |
According Javadoc: "Annotations are to be discarded by the compiler". The results for Java 5 build will be as if no annotation have been declared.
The metadata module will depends on this temporary gt2-mock-jaxb module with <scope>provided</scope>, which implies that this dependency is used for compilation only and do not appears in distributed JAR. Other modules will not inherit this dependency.
Everything described in the previous section do not apply to Java 6 users. The gt2-mock-jaxb module is never declared for Java 6 users, and the metadata classes are compiled with the annotations bundled in the JDK.
This proposal was voted on; added to the 2.5.x series - and then withdrawn due to build issues with Java 5 vs Java 6.
Community support:
|
no progress |
|
done |
|
impeded |
|
lack mandate/funds/time |
|
volunteer needed |
|---|
Cédric Briançon will be doing the following work:
build/maven (or build/mock, or other name to be determined) module for allowing Java 5 users to get annotation erased.modules/library/metadata/pom.xml with Java 5 and Java 6 profiles.org.geotools.resources.jaxb or some other package invisible to users.Proposal completed; and withdrawn since the build was not stable between Java 6 and Java 5 JAXB differences.
The API change consists of the addition of annotations only; as such the functionality of the code has not changed but the information you can determine using reflection has changed. This information is used by jaxb when marshalling and unmarshalling.
Only implementations are annotated.
public class CitationImpl extends MetadataEntity implements Citation {
...
/**
* Returns the name by which the cited resource is known.
*/
public InternationalString getTitle() {
return title;
}
/**
* Set the name by which the cited resource is known.
*/
public synchronized void setTitle(final InternationalString newValue) {
checkWritePermission();
title = newValue;
}
...
}
|
@XmlType(propOrder={"title", ...})
@XmlRootElement(name = "CI_Citation")
public class CitationImpl extends MetadataEntity implements Citation {
...
/**
* Returns the name by which the cited resource is known.
*/
@XmlElement(name = "title", required = true, namespace = "http://www.isotc211.org/2005/gmd")
public InternationalString getTitle() {
return title;
}
/**
* Set the name by which the cited resource is known.
*/
public synchronized void setTitle(final InternationalString newValue) {
checkWritePermission();
title = newValue;
}
...
}
|