Motivation:

Map metadata from ISO-19139 to existing classes

Contact:

Martin Desruisseaux, Cédric Briançon

Tracker:

TBD

Attachment:

jaxb-metadata.xml (example of marshalled XML)

Description

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:

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.

Why JAXB annotations

Inconvenient

Java 5 users

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.

Java 6 users

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.

Status

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:

Tasks

 

no progress

(tick)

done

(error)

impeded

(warning)

lack mandate/funds/time

(question)

volunteer needed

Cédric Briançon will be doing the following work:

  1. (tick) Add a build/maven (or build/mock, or other name to be determined) module for allowing Java 5 users to get annotation erased.
  2. (tick) Updated modules/library/metadata/pom.xml with Java 5 and Java 6 profiles.
  3. (tick) Add adapters in org.geotools.resources.jaxb or some other package invisible to users.
  4. (tick) Add annotations to the Metadata implementations.
  5. (tick) User document page for the metadata module showing how to generate an XML document.
  6. (tick) User document page for the metadata module showing how to parse an XML document

Progression state

Proposal completed; and withdrawn since the build was not stable between Java 6 and Java 5 JAXB differences.

API Change

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.

BEFORE

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;
    }
...
}

AFTER

@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;
    }
...
}