<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>

<!--
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an
  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  KIND, either express or implied.  See the License for the
  specific language governing permissions and limitations
  under the License.
-->

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
  <head>
    <title>XML-ISO-19115</title>
    <meta charset="UTF-8"/>
    <link rel="stylesheet" type="text/css" href="../book.css"/>
  </head>
  <body>
    <!--
      Content below this point is copied in "/asf-staging/book/en/developer-guide.html" file
      by the `org.apache.sis.internal.book.Assembler` class in `sis-build-helper` module.
    -->
    <section>
      <header>
        <h2 id="XML-ISO-19115"><abbr>ISO</abbr> 19115-3 metadata</h2>
      </header>
      <p>
        For each metadata class, there is an <abbr>XML</abbr> type with the same name than in the abstract specification
        (for example, <code>mdb:MD_Metadata</code> and <code>cit:CI_Citation</code>).
        All of these types may be used as the root of an <abbr>XML</abbr> document.
        It is therefore possible to write a document representing a complete <code>MD_Metadata</code> object,
        or to write a document representing only a <code>CI_Citation</code> object.
      </p>
      <p>
        <abbr>ISO</abbr> 19115-3 standard arranges the content of these objects in an unusual way:
        for each property whose value type is itself another class of <abbr>ISO</abbr> 19115,
        the value is wrapped in an element that represents its type, rather than being written directly.
        For example, in an object of the <code>CI_Citation</code> type,
        the value of the <code class="OGC">citedResponsibleParty</code> property is incorporated
        into a <code>CI_Responsibility</code> element.
        This practice doubles the depth of the hierarchy, and introduces duplication at all levels for each value,
        as in the following example:
      </p>

<pre><samp class="xml"><b>&lt;MD_Metadata&gt;</b>
  &lt;identificationInfo&gt;
    <b>&lt;MD_DataIdentification&gt;</b>
      &lt;citation&gt;
        <b>&lt;CI_Citation&gt;</b>
          &lt;citedResponsibleParty&gt;
            <b>&lt;CI_Responsibility&gt;</b>
              &lt;party&gt;
                <b>&lt;CI_Party&gt;</b>
                  &lt;contactInfo&gt;
                    <b>&lt;CI_Contact&gt;</b>
                      &lt;onlineResource&gt;
                        <b>&lt;CI_OnlineResource&gt;</b>
                          &lt;linkage&gt;
                            &lt;URL&gt;https://www.ogc.org&lt;/URL&gt;
                          &lt;/linkage&gt;
                        <b>&lt;/CI_OnlineResource&gt;</b>
                      &lt;/onlineResource&gt;
                    <b>&lt;/CI_Contact&gt;</b>
                  &lt;/contactInfo&gt;
                <b>&lt;/CI_Party&gt;</b>
              &lt;/party&gt;
            <b>&lt;/CI_Responsibility&gt;</b>
          &lt;/citedResponsibleParty&gt;
        <b>&lt;/CI_Citation&gt;</b>
      &lt;/citation&gt;
    <b>&lt;/MD_DataIdentification&gt;</b>
  &lt;/identificationInfo&gt;
<b>&lt;/MD_Metadata&gt;</b></samp></pre>

      <p>
        The preceding example, like all documents that conform to <abbr>ISO</abbr> 19115-3,
        consists of a systematic alternation of two types of <abbr>XML</abbr> elements:
      </p>
      <ol>
        <li><p>
          It begins with the name of the property, which always begins with a lower-case letter (ignoring prefixes).
          In Java <abbr>API</abbr>s, each property corresponds to a method in its enclosing class.
          In the example above, <code>mdb:identificationInfo</code>  (a property of <code>MD_Metadata</code> class)
          corresponds to the <code>Metadata.getIdentificationInfo()</code> method.
        </p></li>
        <li><p>
          The value type is included under each property, unless it has been replaced with a reference
          (the following <a href="#gco-id">sub-section</a> will elaborate on this subject).
          The value type is an <abbr>XML</abbr> element whose name always begins with an upper-case letter,
          ignoring prefixes.
          In the example above we had <code>MD_DataIdentification</code>,
          which corresponds to the <code>DataIdentification</code> Java interface.
          It is this <abbr>XML</abbr> element that contains the child properties.
        </p></li>
      </ol>

      <p>
        In order to reduce the complexity of the libraries, GeoAPI and Apache <abbr>SIS</abbr>
        only expose publicly a single unified view of these two types of elements.
        The public <abbr>API</abbr> basically corresponds to the second group.
      </p>


      <h3 id="gco-id">Links to previously-defined instances</h3>
      <p>
        The parent element may contain an <code class="OGC">id</code> or <code class="OGC">uuid</code> attribute.
        If one of these attributes is present, the parent attribute may be completely omitted;
        it will be replaced at the time of reading by the element referenced by the attribute.
        In the following example, the part on the left defines an element associated with the identifier “<code>my_id</code>,”
        while the part on the right references this element:
      </p>

      <div class="row-of-boxes">
        <div>
          <div class="caption">Defining an identifier</div>
<pre style="margin-top: 6pt"><samp class="xml">&lt;MD_MetaData&gt;
  &lt;identificationInfo&gt;
    &lt;MD_DataIdentification id="<b>my_id</b>"&gt;
      &lt;!-- insert child properties here --&gt;
    &lt;/MD_DataIdentification&gt;
  &lt;/identificationInfo&gt;
&lt;/MD_MetaData&gt;</samp></pre>
        </div>
        <div>
          <div class="caption">Using a defined identifier</div>
<pre style="margin-top: 6pt"><samp class="xml">&lt;MD_MetaData&gt;
  &lt;identificationInfo xlink:href="<b>#my_id</b>"/&gt;
&lt;/MD_MetaData&gt;</samp></pre>
        </div>
      </div>

      <p>
        The decision of which attribute to use depends on the scope of the referenced item:
      </p>
      <ul>
        <li>
          <code class="OGC">id</code> is only valid in the same <abbr>XML</abbr> document that defines the object it references.
        </li>
        <li>
          <code class="OGC">uuid</code> may be valid outside the <abbr>XML</abbr> document,
          but someone must maintain a database providing the objects for each given UUID.
        </li>
        <li>
          <code>xlink:href</code> may reference another <abbr>XML</abbr> document accessible on the Internet.
        </li>
      </ul>
      <p>
        In the <abbr>SIS</abbr> library, all objects that can be identified in an <abbr>XML</abbr> document
        implements the <code>org.apache.sis.xml.IdentifiedObject</code> interface.
        Each instance of this interface provides a view of its identifiers in the form of a <code>Map&lt;Citation,String&gt;</code>,
        in which the <code>Citation</code> key indicates the type of identifier and the value is the identifier itself.
        Some constants representing different types of identifiers are listed in <code>IdentifierSpace</code>,
        including <code class="SIS">ID</code>, <code class="SIS">UUID</code> and <code class="SIS">HREF</code>.
        Each of these keys may be associated with a different type of value (usually <code>String</code>,
        <code>UUID</code> or <code>URI</code>) depending on the key.
        For example, the following code defines a value for the <code class="OGC">uuid</code> attribute:
      </p>

<pre><code>import org.apache.sis.metadata.iso.DefaultMetadata;
import org.apache.sis.xml.IdentifierSpace;
import java.util.UUID;

public class MyClass {
    public void myMethod() {
        UUID identifier = UUID.randomUUID();
        <code class="SIS">DefaultMetadata</code> metadata = new <code class="SIS">DefaultMetadata</code>();
        metadata.<code class="SIS">getIdentifierMap().putSpecialized</code>(IdentifierSpace.UUID, identifier);
    }
}</code></pre>

      <p>
        Although this mechanism has been defined in order to better support the representation of <abbr>XML</abbr> attributes
        of the <code>gco:ObjectIdentification</code> group,
        it also conveniently allows other types of identifiers to be manipulated.
        For example, the <code class="GeoAPI">ISBN</code> and <code class="GeoAPI">ISSN</code> attributes of
        <code>Citation</code> may be manipulated in this way.
        The methods of the <code class="SIS">IdentifiedObject</code> interface therefore provides a specific location
        where all types of identifiers (not only <abbr>XML</abbr>) associated with an object may be manipulated.
      </p>



      <h3 id="nilReason">Placeholders for missing values</h3>
      <p>
        When a property is not defined, the corresponding GeoAPI method usually returns <code>null</code>.
        However, things become complicated when the missing property is a value considered mandatory by <abbr>ISO</abbr> 19115 standard.
        <abbr>ISO</abbr> 19115-3 allows for the omission of mandatory properties so long as the reason for the missing value is indicated.
        The reason may be that the property is not applicable (<code class="OGC">inapplicable</code>),
        that the value probably exists but is not known (<code class="OGC">unknown</code>),
        that the value cannot exist (<code class="OGC">missing</code>),
        or that the value cannot be revealed (<code class="OGC">withheld</code>), <i>etc.</i>
        The transmission of this information requires the use of a non-nul object, even when the value is missing.
        <abbr>SIS</abbr> will then return an object that, besides implementing the desired GeoAPI interface,
        also implements the <code>org.apache.sis.xml.NilObject</code> interface.
        This interface flags the instances where all methods return an empty collection, an empty table, <code>null</code>,
        <code>NaN</code>, <code>0</code> or <code>false</code>, in this preference order, as permitted by the return types of the methods.
        Each instance that implements <code>NilObject</code> provides a <code class="SIS">getNilReason()</code> method
        indicating why the object is nil.
      </p>
      <p>
        In the following example, the left side shows a <code>CI_Citation</code> element containing a
        <code>CI_Series</code> element, while on the right side the series is unknown.
        If the <code>CI_Series</code> element had been completely omitted,
        then the <code>Citation.getSeries()</code> method would return <code>null</code> in Java.
        But when a <code class="OGC">nilReason</code> is present, the <abbr>SIS</abbr> implementation of
        <code class="SIS">getSeries()</code> returns instead an object that implements both the
        <code>Series</code> and <code>NilReason</code> interfaces, and in which the
        <code class="SIS">getNilReason()</code> method returns the constant <code class="SIS">UNKNOWN</code>.
      </p>

      <div class="row-of-boxes">
        <div>
          <div class="caption">Information included</div>
<pre style="margin-top: 6pt"><samp class="xml">&lt;CI_Citation&gt;
  &lt;series&gt;
    &lt;CI_Series&gt;
      &lt;!-- insert child properties here --&gt;
    &lt;/CI_Series&gt;
  &lt;/series&gt;
&lt;/CI_Citation&gt;</samp></pre>
        </div>
        <div>
          <div class="caption">Missing information</div>
<pre style="margin-top: 6pt"><samp class="xml">&lt;CI_Citation&gt;
  &lt;series nilReason="unknown"/&gt;
&lt;/CI_Citation&gt;</samp></pre>
        </div>
      </div>
    </section>
  </body>
</html>
