You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@sis.apache.org by "Martin Desruisseaux (Jira)" <ji...@apache.org> on 2022/04/12 10:58:00 UTC

[jira] [Updated] (SIS-401) Use of GML 3.2 implies the use of ISO 19139:2007 metadata

     [ https://issues.apache.org/jira/browse/SIS-401?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Martin Desruisseaux updated SIS-401:
------------------------------------
    Fix Version/s: 1.3
                       (was: 1.2)

> 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, 1.1
>            Reporter: Martin Desruisseaux
>            Priority: Major
>             Fix For: 1.3
>
>
> 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
(v8.20.1#820001)