content/fr/developer-guide/annexes/geoapi/DefinitionProcess.html (353 lines of code) (raw):
<?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="fr">
<head>
<title>GeoAPI</title>
<meta charset="UTF-8"/>
<link rel="stylesheet" type="text/css" href="../../book.css"/>
</head>
<body>
<!--
Content below this point is copied in "/static/book/fr/developer-guide.html"
by the 'org.apache.sis.internal.book.Assembler' class in 'sis-build-helper' module.
-->
<section>
<header>
<h2 id="SpecificationToInterfaces">Des spécifications de l’<abbr>OGC</abbr> aux interfaces Java</h2>
</header>
<p>
Les interfaces Java du projet GeoAPI sont parfois générées à partir d’autres fichiers fournis par l’<abbr>OGC</abbr>,
tels que les fichiers <abbr>XSD</abbr>. Mais il y a toujours une révision manuelle, et très souvent des modifications
par rapport aux fichiers générés par des processus automatiques.
Il aurait été possible de générer automatiquement des interfaces Java à partir des standards de l’<abbr>OGC</abbr> à l’aide d’outils existants.
Par exemple une des approches les plus utilisées est de transformer les <a href="http://schemas.opengis.net/gml/3.3/">schémas <abbr>XSD</abbr></a>
en interfaces Java à l’aide de l’utilitaire en ligne de commande <code>xjc</code>.
Cet utilitaire étant fournit avec la plupart des distributions du Java (il fait partie des outils de <a href="http://jaxb.java.net"><abbr>JAXB</abbr></a>),
cette approche est choisie par plusieurs projets que l’on trouve sur internet.
D’autres approches utilisent des outils intégrés à l’environnement de développement Eclipse,
ou prennent comme point de départ les schémas <abbr>UML</abbr> plutôt que <abbr>XSD</abbr>.
Une approche similaire avait été tentée dans les débuts du projet GeoAPI, mais a été rapidement abandonnée.
Nous avons privilégié une approche manuelle pour les raisons suivantes:
</p>
<ul>
<li>
<p>
Certains schémas <abbr>XSD</abbr> sont beaucoup plus verbeux que les schémas <abbr>UML</abbr> d’origines.
Une conversion à partir des schémas <abbr>XSD</abbr> introduit, au moins dans le cas des méta-données,
près du double du nombre d’interfaces réellement définies par le standard, sans que cela n’apporte de nouvelles fonctionnalités.
Les schémas <abbr>XSD</abbr> définissent aussi des attributs propres aux documents <abbr>XML</abbr>
(<code class="OGC">id</code>, <code class="OGC">uuid</code>, <code>xlink:href</code>, <i>etc.</i>),
qui n’existent pas dans les diagrammes <abbr>UML</abbr> originaux et que l’on ne souhaite pas forcément exposer dans un <abbr>API</abbr> Java.
Une conversion à partir des schémas <abbr>UML</abbr> évite ce problème, mais les outils capable d’effectuer cette opération sont plus rares.
</p>
<div class="example"><p><b>Exemple:</b>
Les schémas <abbr>XSD</abbr> des méta-données insèrent
un élément <code><cit:CI_Citation></code> à l’intérieur de <code><cit:citation></code>,
un élément <code><cit:CI_OnlineResource></code> à l’intérieur de <code><cit:onlineResource></code>,
et ainsi de suite pour la centaine de classes définies dans le standard <abbr>ISO</abbr> 19115.
Cette redondance n’est absolument pas nécessaire à un programme Java.
</p></div>
</li>
<li>
<p>
Les standards de l’<abbr>OGC</abbr> utilisent des conventions de nommage qui sont différentes de celles du Java.
En particulier les noms de presque toutes les classes de l’<abbr>OGC</abbr> commencent par un préfixe de deux lettres,
comme dans <code>MD_Identifier</code>. Ces préfixes jouent le même rôle que les noms de paquets en Java.
GeoAPI adapte cette pratique en utilisant des noms d’interfaces sans préfixes,
et en plaçant ces interfaces dans des paquets correspondants aux préfixes mais avec des noms plus descriptifs.
Occasionnellement nous changeons aussi les noms, par exemple pour éviter des acronymes
ou pour se conformer à une convention établie telle que <i>Java beans</i>.
</p>
<div class="example"><p><b>Exemple:</b>
la classe <code>MD_Identifier</code> de l’<abbr>OGC</abbr> devient
l’interface <code>Identifier</code> dans le paquet <code>org.opengis.metadata</code>.
La classe <code>SC_CRS</code> de l’<abbr>OGC</abbr> devient l’interface <code>CoordinateReferenceSystem</code>,
et l’association <code class="OGC">usesDatum</code> devient une méthode <code class="GeoAPI">getDatum()</code> — et non pas
« <code>getUsesDatum()</code> » comme aurait fait un outil de conversion automatique.
Nous ne laissons pas des programmes appliquer aveuglement des règles qui ignorent les conventions de la communauté dont on traduit les schémas.
</p></div>
</li>
<li>
<p>
Les standards contiennent parfois des structures qui n’ont pas d’équivalent direct en Java,
notamment les unions telles qu’on peut trouver en C/C++.
La stratégie employée pour obtenir une fonctionnalité équivalente en Java dépend du contexte:
multi-héritage des interfaces, modification de la hiérarchie ou simplement omettre l’union.
Les décisions se font au cas-par-cas en fonction de l’analyse des besoins.
</p>
<div class="example"><p><b>Exemple:</b>
Le standard <abbr>ISO</abbr> 19111 définit différents types de systèmes de coordonnées, tels que sphérique, cylindrique, polaire ou cartésien.
Puis, il définit différents <em>sous-ensembles</em> de ces types de systèmes de coordonnées.
Ces sous-ensembles, représentés par des unions, servent à spécifier qu’une classe peut être associée à seulement tel ou tel type de système de coordonnées.
Par exemple l’union des types pouvant être associés à une image, nommée <code>CS_ImageCS</code>,
ne contient que <code>CS_CartesianCS</code> et <code>CS_AffineCS</code>.
Dans ce cas particulier, nous obtenons en Java l’effet souhaité par une modification de la hiérarchie des classes:
nous définissons l’interface <code>CartesianCS</code> comme une spécialisation de <code>AffineCS</code>, ce qui est sémantiquement correct.
Mais il n’est pas possible d’appliquer une stratégie similaire pour les autres unions sans violer la sémantique.
</p></div>
</li>
<li>
<p>
Plusieurs spécifications se chevauchent. GeoAPI effectue un travail d’intégration en remplaçant certaines
structures qui font doublons par des références vers les structures équivalentes du standard qui les définies le mieux.
</p>
<div class="example"><p><b>Exemple:</b>
Le standard <abbr>ISO</abbr> 19115, qui définit des structures de méta-données, s’aventure aussi à décrire quelques
structures représentant les systèmes de références des coordonnées (<abbr title="Coordinate Reference System">CRS</abbr>).
Or ces derniers sont le sujet à part entière d’un autre standard: <abbr>ISO</abbr> 19111.
D’ailleurs le standard <abbr>ISO</abbr> 19111:2007 stipule, dans sa section 3, qu’il réutilise tous les éléments
de <abbr>ISO</abbr> 19115 à l’exclusion de <code>MD_CRS</code> et de ses composantes.
Les interfaces de GeoAPI réduisent la redondance en appliquant à l’ensemble du projet l’exclusion recommandée par <abbr>ISO</abbr> 19111.
</p></div>
</li>
<li>
<p>
Certains standards ont vu leur complexité s’accroître pour des raisons historiques plutôt que techniques,
liées au processus de standardisation. GeoAPI réduit la dette technique en concevant les interfaces comme
si chaque élément avait pu être intégré à sa place, sans les contraintes liées à l’ordre chronologique
dans lequel les standards ont été publiés.
</p>
<div class="example"><p><b>Exemple:</b>
Le standard <abbr>ISO</abbr> 19115-2 est une extension du standard <abbr>ISO</abbr> 19115-1 ajoutant des structures de méta-données d’images.
Ces méta-données ont été définies dans un standard séparé parce qu’elles n’ont pas été prêtes à temps pour la publication de la première partie du standard.
Comme il n’était pas possible, pour des raisons administratives, d’ajouter des attributs dans les classes déjà publiées,
les nouveaux attributs ont été ajoutées dans une sous-classe portant quasiment le même nom.
Ainsi, le standard <abbr>ISO</abbr> 19115-2 définit une classe <code>MI_Band</code> qui étend la
classe <code>MD_Band</code> du standard <abbr>ISO</abbr> 19115-1 en y ajoutant les attributs qui
auraient dû apparaître directement dans la classe parente s’ils avaient été prêts à temps.
Dans GeoAPI, nous avons choisis de « réparer » ces anomalies en fusionnant ces deux classes en une seule interface.
</p></div>
</li>
</ul>
<p>
Les écarts par rapport aux normes sont documentés dans chaque classe et chaque méthode concernées.
Chaque mention d’un écart est aussi recopiée dans <a href="http://www.geoapi.org/3.0/javadoc/departures.html">une page unique</a>,
pour donner une vue d’ensemble.
Étant donné que ces écarts brouillent les liens qui existent entre les standards et certaines interfaces Java,
la correspondance entre ces langages est explicitée par des annotations <code>@UML</code>
et des fichiers de propriétés, décrits dans la section suivante.
</p>
<h3 id="UML-annotation">Correspondances explicites entre GeoAPI et les spécifications abstraites</h3>
<p>
Pour chaque classe, méthode et constante définie à partir d’un standard <abbr>OGC</abbr> ou <abbr>ISO</abbr>,
GeoAPI indique sa provenance à l’aide d’annotations définies dans le paquet <code>org.opengis.annotation</code>.
En particulier l’annotation <code>@UML</code> indique le standard,
le nom de l’élément dans ce standard ainsi que son niveau d’obligation.
Par exemple dans l’extrait de code suivant, la première annotation <code>@UML</code> indique
que l’interface Java qui la suit (<code>ProjectedCRS</code>) est définie à partir du type
<code>SC_ProjectedCRS</code> du standard <abbr>ISO</abbr> 19111.
La seconde annotation <code>@UML</code>, appliquée cette fois à la méthode
<code class="GeoAPI">getCoordinateSystem()</code>, indique que la méthode est définie
à partir de l’association <code class="OGC">coordinateSystem</code> du standard <abbr>ISO</abbr> 19111,
et que cette association est obligatoire — ce qui, traduit en Java, signifie que la méthode n’est
pas autorisée à retourner la valeur <code>null</code>.
</p>
<pre><code>package <code class="GeoAPI">org.opengis.referencing.crs</code>;
/**
* A 2D coordinate reference system used to approximate the shape of the earth on a planar surface.
*/
@UML(specification=ISO_19111, identifier="<code class="OGC">SC_ProjectedCRS</code>")
public interface ProjectedCRS extends GeneralDerivedCRS {
/**
* Returns the coordinate system, which must be Cartesian.
*/
@UML(obligation=MANDATORY, specification=ISO_19111, identifier="<code class="OGC">coordinateSystem</code>")
CartesianCS <code class="GeoAPI">getCoordinateSystem()</code>;
}</code></pre>
<p>
Les méthodes d’introspections du Java permettent d’accéder à ces informations pendant l’exécution d’une application.
C’est utile pour obtenir les noms à afficher à des utilisateurs familiers avec les normes de l’<abbr>OGC</abbr>,
ou pour écrire des éléments dans un document <abbr>XML</abbr>.
La classe <code>org.apache.sis.util.iso.Types</code> fournit des méthodes de commodité
telles que <code class="SIS">getStandardName(Class)</code> pour effectuer cette opération.
Par exemple le code suivant affichera
« Le nom standard du type <code>org.opengis.referencing.crs.ProjectedCRS</code> est <code>SC_ProjectedCRS</code> »:
</p>
<pre><code>Class<?> type = ProjectedCRS.class;
System.out.println("Le nom standard du type " + type.getName() + " est " + Types.getStandardName(type));</code></pre>
<p>
La méthode de commodité <code class="SIS">Types.forStandardName(String)</code> effectue l’opération inverse.
Les applications qui souhaiteraient effectuer ces opérations sans utiliser les méthodes de commodités de Apache SIS
trouveront des indications dans un <a href="#UML-annotation-geoapi">chapitre séparé</a>.
</p>
<h3 id="MappingToJDK">Correspondances implicites avec le <abbr>JDK</abbr> standard</h3>
<p>
Certaines classes et méthodes n’ont ni annotation <code>@UML</code>,
ni entrée dans le fichier <code class="GeoAPI">class-index.properties</code>.
Il s’agit soit d’extensions de GeoAPI, ou soit de types définis dans d’autres bibliothèques,
notamment le <abbr title="Java Development Kit">JDK</abbr> standard.
Pour ce dernier cas, la correspondance avec les standards <abbr>ISO</abbr> est implicite.
Le tableau suivant décrit cette correspondance pour les types de la norme <abbr>ISO</abbr> 19103.
Les types primitifs du Java standard sont préférés lorsqu’ils sont applicables,
mais parfois leurs équivalents sous forme d’objets sont employés lorsqu’il est nécessaire d’autoriser des valeurs nulles.
</p>
<table>
<caption>Correspondances entre <abbr>ISO</abbr> 19103 et <abbr>JDK</abbr></caption>
<tr>
<th>Type <abbr>ISO</abbr></th>
<th>Type <abbr>JDK</abbr></th>
<th>Remarques</th>
</tr>
<tr>
<td class="separator" colspan="2">Nombres</td>
<td class="leftBorder"></td>
</tr>
<tr>
<td><code class="OGC">Integer</code></td>
<td><code>int</code></td>
<td class="leftBorder">Parfois <code>java.lang.Integer</code> pour les attributs optionnels.</td>
</tr>
<tr>
<td><code class="OGC">Integer</code> (certains cas)</td>
<td><code>long</code></td>
<td class="leftBorder">Parfois <code>java.lang.Long</code> pour les attributs optionnels.</td>
</tr>
<tr>
<td><code class="OGC">Real</code></td>
<td><code>double</code></td>
<td class="leftBorder">Parfois <code>java.lang.Double</code> pour les attributs optionnels.</td>
</tr>
<tr>
<td><code class="OGC">Decimal</code></td>
<td><code>java.math.BigDecimal</code></td>
<td class="leftBorder"></td>
</tr>
<tr>
<td><code class="OGC">Number</code></td>
<td><code>java.lang.Number</code></td>
<td class="leftBorder"></td>
</tr>
<tr>
<td class="separator" colspan="2">Textes</td>
<td class="leftBorder"></td>
</tr>
<tr>
<td><code class="OGC">FreeText</code></td>
<td>(pas d’équivalent)</td>
<td class="leftBorder">Voir <code class="GeoAPI">org.opengis.util.InternationalString</code> ci-dessous.</td>
</tr>
<tr>
<td><code class="OGC">CharacterString</code></td>
<td><code>java.lang.String</code></td>
<td class="leftBorder">Souvent <code class="GeoAPI">org.opengis.util.InternationalString</code> (voir ci-dessous).</td>
</tr>
<tr>
<td><code class="OGC">LocalisedCharacterString</code></td>
<td><code>java.lang.String</code></td>
<td class="leftBorder"></td>
</tr>
<tr>
<td><code class="OGC">Sequence<Character></code></td>
<td><code>java.lang.CharSequence</code></td>
<td class="leftBorder"></td>
</tr>
<tr>
<td><code class="OGC">Character</code></td>
<td><code>char</code></td>
<td class="leftBorder"></td>
</tr>
<tr>
<td class="separator" colspan="2">Dates et heures</td>
<td class="leftBorder"></td>
</tr>
<tr>
<td><code class="OGC">Date</code></td>
<td><code>java.util.Date</code></td>
<td class="leftBorder"></td>
</tr>
<tr>
<td><code class="OGC">Time</code></td>
<td><code>java.util.Date</code></td>
<td class="leftBorder"></td>
</tr>
<tr>
<td><code class="OGC">DateTime</code></td>
<td><code>java.util.Date</code></td>
<td class="leftBorder"></td>
</tr>
<tr>
<td class="separator" colspan="2">Collections</td>
<td class="leftBorder"></td>
</tr>
<tr>
<td><code class="OGC">Collection</code></td>
<td><code>java.util.Collection</code></td>
<td class="leftBorder"></td>
</tr>
<tr>
<td><code class="OGC">Bag</code></td>
<td><code>java.util.Collection</code></td>
<td class="leftBorder">Un <code class="OGC">Bag</code> est similaire à un
<code class="OGC">Set</code> sans la restriction d’unicité.</td>
</tr>
<tr>
<td><code class="OGC">Set</code></td>
<td><code>java.util.Set</code></td>
<td class="leftBorder"></td>
</tr>
<tr>
<td><code class="OGC">Sequence</code></td>
<td><code>java.util.List</code></td>
<td class="leftBorder"></td>
</tr>
<tr>
<td><code class="OGC">Dictionary</code></td>
<td><code>java.util.Map</code></td>
<td class="leftBorder"></td>
</tr>
<tr>
<td><code class="OGC">KeyValuePair</code></td>
<td><code>java.util.Map.Entry</code></td>
<td class="leftBorder"></td>
</tr>
<tr>
<td class="separator" colspan="2">Énumérations</td>
<td class="leftBorder"></td>
</tr>
<tr>
<td><code class="OGC">Enumeration</code></td>
<td><code>java.lang.Enum</code></td>
<td class="leftBorder"></td>
</tr>
<tr>
<td><code class="OGC">CodeList</code></td>
<td>(pas d’équivalent)</td>
<td class="leftBorder">Voir <code>org.opengis.util.CodeList</code> ci-dessous.</td>
</tr>
<tr>
<td class="separator" colspan="2">Divers</td>
<td class="leftBorder"></td>
</tr>
<tr>
<td><code class="OGC">Boolean</code></td>
<td><code>boolean</code></td>
<td class="leftBorder">Parfois <code>java.lang.Boolean</code> pour les attributs optionnels.</td>
</tr>
<tr>
<td><code class="OGC">Any</code></td>
<td><code>java.lang.Object</code></td>
<td class="leftBorder"></td>
</tr>
</table>
<p>
L’équivalent le plus direct de <code>CharacterString</code> est la classe <code>String</code>,
mais GeoAPI emploie souvent l’interface <code>InternationalString</code> pour permettre au client de choisir la langue.
C’est utile par exemple sur un serveur fournissant simultanément des pages dans plusieurs langues.
En reportant les traductions à l’utilisation des objets plutôt qu’au moment de leur création, on permet à la bibliothèque
<abbr>SIS</abbr> de fournir les mêmes instances de <code>Metadata</code>
ou <code>Coverage</code> (par exemple) pour les mêmes données peu importe la langue du client.
Les traductions peuvent être faites à la volée à l’aide d’un <code>ResourceBundle</code> de l’application,
ou être fournies directement avec les données (cas des <code>Metadata</code> notamment).
</p>
<p>
Les <code>Enumeration</code> correspondent aux <code>Enum</code> du Java.
Ils ont en commun de définir toutes les valeurs autorisées, sans permettre à l’utilisateur d’en ajouter.
Les <code class="OGC">CodeList</code> sont similaires à ces énumérations, excepté que les utilisateurs peuvent y ajouter leurs propres éléments.
Le <abbr>JDK</abbr> standard n’offrant pas cette possibilité,
GeoAPI définit une classe abstraite <code class="GeoAPI">CodeList</code> reproduisant certaines fonctionnalités de <code>Enum</code> tout en étant extensible.
Les extensions s’obtiennent par les méthodes statiques <code class="GeoAPI">valueOf(String)</code> qui,
contrairement à celle de <code>Enum</code>, créeront de nouvelles instances si le nom donné ne correspond pas au nom d’une instance existante.
</p>
<pre><code>MediumName cdRom = MediumName.<code class="GeoAPI">CD_ROM;</code>
MediumName usbKey = MediumName.<code class="GeoAPI">valueOf</code>("<code class="GeoAPI">USB_KEY</code>"); // Aucune constante n’existe pour cette valeur.
assert MediumName.<code class="GeoAPI">valueOf</code>("<code class="GeoAPI">CD_ROM</code>") == cdRom : "valueOf doit retourner les constantes existantes.";
assert MediumName.<code class="GeoAPI">valueOf</code>("<code class="GeoAPI">USB_KEY</code>") == usbKey : "valueOf doit cacher les valeurs précédemment demandées.";</code></pre>
</section>
</body>
</html>