Martin Desruisseaux created SIS-401:
---------------------------------------

             Summary: Use of GML 3.2 implies the use of ISO 19139:2007 metadata
                 Key: SIS-401
                 URL: https://issues.apache.org/jira/browse/SIS-401
             Project: Spatial Information Systems
          Issue Type: Sub-task
          Components: Metadata, Referencing
    Affects Versions: 1.0
            Reporter: Martin Desruisseaux


The use of GML 3.2 implies the use of ISO 19139:2007 metadata for describing 
the extent, positional accuracy, identifiers, _etc._ For now (in Apache SIS 
1.0), we use an {{\@UseLegacyMetadata}} annotations (internal API). When this 
annotation is found on the object to marshal, {{PooledMarshaller}} 
automatically set the metadata version to 2007. However this works only for the 
root element. If the user specifies another object which itself contains GML, 
this will not work.

If we want this automatic selection of ISO 19139:2007 metadata to work no 
matter where the GML elements appear, we need a different approach. One 
possible approach is to update the {{org.apache.sis.internal.jaxb.Context}} 
state in a way similar to what we do for {{Locale}}. This can be done by 
addition the following constructor and modifying the {{push(…)}} method like 
below (only the main elements that are modified are shown below):

{code:java}
public final class Context extends MarshalContext {
    /**
     * The locale to use for marshalling, or {@code null} if no locale were 
explicitly specified.
     */
    private final Locale locale;

    /**
     * Creates a new context identical to the given parent except for the 
locale and bitmask.
     */
    private Context(final Context parent, final int bitMasks, final Locale 
locale) {
        this.bitMasks          = bitMasks;
        this.locale            = locale;
        this.timezone          = parent.timezone;
        this.schemas           = parent.schemas;
        this.versionGML        = parent.versionGML;
        this.resolver          = parent.resolver;
        this.converter         = parent.converter;
        this.warningListener   = parent.warningListener;
        this.identifiers       = parent.identifiers;
        this.identifiedObjects = parent.identifiedObjects;
        this.previous          = parent;
    }

    @Override
    public final Locale getLocale() {
        return locale;
    }

    /**
     * Sets the locale to the given value, optionally with additional bits to 
set.
     * The old locales and bit masks are remembered and will be restored by the 
next call to {@link #pull()}.
     * This method can be invoked when marshalling object that need to marshall 
their children in a different
     * locale, like below:
     *
     * {@preformat java
     *     private void beforeMarshal(Marshaller marshaller) {
     *         Context.push(0, language);
     *     }
     *
     *     private void afterMarshal(Marshaller marshaller) {
     *         Context.pull();
     *     }
     * }
     *
     * @param  bitsToSet  new bits to set, or 0 for no change.
     * @param  locale     the locale to set, or {@code null} for keeping the 
current locale.
     */
    public static void push(final int bitsToSet, Locale locale) {
        Context current = current();
        if (current != null) {
            if (locale == null) {
                locale = current.getLocale();
            }
            current = new Context(current, current.bitMasks | bitsToSet, 
locale);
            CURRENT.set(current);
        }
    }

    /**
     * Restores the locale which was used prior the call to {@link #push(int, 
Locale)}.
     */
    public static void pull() {
        final Context current = current();
        if (current != null) {
            CURRENT.set(current.previous);
        }
    }
}
{code}

Then, in the {{org.apache.sis.referencing}} package:

{code:java}
public class AbstractIdentifiedObject implements IdentifiedObject {
    /**
     * Invoked by JAXB {@link javax.xml.bind.Marshaller} before this object is 
marshalled to XML.
     * This method sets the locale to be used for XML marshalling to the 
metadata language.
     */
    @SuppressWarnings("unused")
    private void beforeMarshal(final Marshaller marshaller) {
        Context.push(Context.LEGACY_METADATA, null);
    }

    /**
     * Invoked by JAXB {@link javax.xml.bind.Marshaller} after this object has 
been marshalled to
     * XML. This method restores the locale to be used for XML marshalling to 
its previous value.
     */
    @SuppressWarnings("unused")
    private void afterMarshal(final Marshaller marshaller) {
        Context.pull();
    }
}
{code}

This approach almost work. The problem is that changing {{Context}} state is 
not sufficient. We also need to change on-the-fly the {{TransformVersion}} used 
by {{TransformingReader}} in the {{org.apache.sis.xml}} package, and restore 
the previous state once the GML object marshalling is finished. Since the 
impact needs more investigation, this task has been deferred to a later version.




--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to