blob: 7e9e090095d206377db5196da682b48523a1b437 [file] [log] [blame]
<?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="../../../content/book/book.css"/>
</head>
<body>
<!--
Content below this point is copied in "(…)/content/book/en/developer-guide.html" file
by the 'org.apache.sis.internal.book.Assembler' class in 'sis-build-helper' module.
-->
<section>
<header>
<h3 id="XML-ISO-19115">Representing metadata according to <abbr>ISO</abbr> 19115-3</h3>
</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.
However, when writing an <abbr>XML</abbr> document, elements of the first group must be temporarily recreated.
The corresponding classes are defined in internal <abbr>SIS</abbr> packages.
These classes may be ignored, unless the developer wishes to implement his or her own classes whose instances must be written in <abbr>JAXB</abbr>.
</p>
<aside id="XML-SIS">
<h3>Implementation strategy in Apache <abbr>SIS</abbr></h3>
<p>
<code>org.apache.sis.internal.jaxb.*</code> packages (non-public) define <abbr>JAXB</abbr> adaptors for all types of <abbr>ISO</abbr> objects.
These adaptors are required anyway to allow <abbr>JAXB</abbr> to get <abbr>SIS</abbr> classes while implementing GeoAPI interfaces.
Conveniently, <abbr>SIS</abbr> made both <abbr>JAXB</abbr> adaptors and objects wrapping the “real” object to be read or written.
This double usage avoids having to double the number of classes (already quite high) present in the internal packages.
</p>
<h4>Naming conventions in <abbr>XSD</abbr> schemas</h4>
<p>
For each element of the first group listed above, the <abbr>XSD</abbr> schemas of the <abbr>OGC</abbr>
define a type whose name ends with “<code class="OGC">_PropertyType</code>”.
For the second group, each element has a type whose name ends with “<code class="OGC">_Type</code>”.
The “<code class="OGC">_PropertyType</code>” elements may have a group of attributes
(such as <code>gco:uuidref</code> and <code>xlink:href</code>)
which the <abbr>XSD</abbr> schemas collectively name <code>gco:ObjectIdentification</code>.
These attributes do not have dedicated Java methods, but are accessible indirectly via the
<code class="SIS">IdentifiedObject</code> interface described in the following subsection.
</p>
</aside>
<h4 id="gco-id">Identification of already-defined instances</h4>
<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>
<h4 id="nilReason">Representing missing values</h4>
<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>