Author: desruisseaux
Date: Fri Nov 30 08:53:47 2012
New Revision: 1415547

URL: http://svn.apache.org/viewvc?rev=1415547&view=rev
Log:
Updated the developer guide for the code commited in the last month.

Modified:
    sis/branches/JDK7/src/main/docbook/book.xsl
    sis/branches/JDK7/src/main/docbook/fr/XML.xml
    sis/branches/JDK7/src/main/docbook/fr/utility.xml
    sis/branches/JDK7/src/site/resources/book/book.css

Modified: sis/branches/JDK7/src/main/docbook/book.xsl
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK7/src/main/docbook/book.xsl?rev=1415547&r1=1415546&r2=1415547&view=diff
==============================================================================
--- sis/branches/JDK7/src/main/docbook/book.xsl (original)
+++ sis/branches/JDK7/src/main/docbook/book.xsl Fri Nov 30 08:53:47 2012
@@ -95,6 +95,9 @@
   <xsl:template match= "d:function[@role = 'OGC']"    mode="class.value"> 
<xsl:value-of select="'OGC'"   /> </xsl:template>
   <xsl:template match= "d:function[@role = 'GeoAPI']" mode="class.value"> 
<xsl:value-of select="'GeoAPI'"/> </xsl:template>
   <xsl:template match= "d:function[@role = 'SIS']"    mode="class.value"> 
<xsl:value-of select="'SIS'"   /> </xsl:template>
+  <xsl:template match= "d:constant[@role = 'OGC']"    mode="class.value"> 
<xsl:value-of select="'OGC'"   /> </xsl:template>
+  <xsl:template match= "d:constant[@role = 'GeoAPI']" mode="class.value"> 
<xsl:value-of select="'GeoAPI'"/> </xsl:template>
+  <xsl:template match= "d:constant[@role = 'SIS']"    mode="class.value"> 
<xsl:value-of select="'SIS'"   /> </xsl:template>
   <xsl:template match=  "d:literal[@role = 'OGC']"    mode="class.value"> 
<xsl:value-of select="'OGC'"   /> </xsl:template>
   <xsl:template match=  "d:literal[@role = 'GeoAPI']" mode="class.value"> 
<xsl:value-of select="'GeoAPI'"/> </xsl:template>
   <xsl:template match=  "d:literal[@role = 'SIS']"    mode="class.value"> 
<xsl:value-of select="'SIS'"   /> </xsl:template>

Modified: sis/branches/JDK7/src/main/docbook/fr/XML.xml
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK7/src/main/docbook/fr/XML.xml?rev=1415547&r1=1415546&r2=1415547&view=diff
==============================================================================
--- sis/branches/JDK7/src/main/docbook/fr/XML.xml (original)
+++ sis/branches/JDK7/src/main/docbook/fr/XML.xml Fri Nov 30 08:53:47 2012
@@ -226,5 +226,64 @@ public class MyClass {
         où peuvent être manipulés tous types d’identifiants (pas 
seulement <acronym>XML</acronym>) associés à un objet.
       </para>
     </section>
+
+    <section>
+      <title>Représentation de valeurs manquantes</title>
+      <para>
+        Lorsqu’un attribut n’est pas défini, la méthode correspondante 
de GeoAPI retourne généralement <literal>null</literal>.
+        Toutefois les choses se compliquent lorsque l’attribut manquant est 
une valeur considérée comme obligatoire par le standard 
<acronym>ISO</acronym> 19115.
+        Le standard <acronym>ISO</acronym> 19139 autorise l’omission 
d’attributs obligatoires à la condition d’indiquer pourquoi la valeur est 
manquante.
+        Les raisons peuvent être que l’attribut ne s’applique pas 
(<constant role="OGC">inapplicable</constant>),
+        que la valeur existe probablement mais n’est pas connue (<constant 
role="OGC">unknown</constant>),
+        que la valeur pourrait ne pas exister (<constant 
role="OGC">missing</constant>),
+        qu’elle ne peut pas être divulguée (<constant 
role="OGC">withheld</constant>), <foreignphrase>etc.</foreignphrase>
+        La transmission de cette information nécessite l’utilisation d’un 
objet non-nul même lorsque la valeur est manquante.
+        <acronym>SIS</acronym> procède en retournant un objet qui, en plus 
d’implémenter l’interface GeoAPI attendue,
+        implémente aussi l’interface <classname 
role="SIS">org.apache.xml.NilObject</classname>.
+        Cette interface marque les instances dont toutes les méthodes 
retournent une collection vide,
+        un tableau vide, <literal>null</literal>, <literal>NaN</literal>, 
<literal>0</literal> ou <literal>false</literal>,
+        dans cet ordre de préférence selon ce que les types de retours des 
méthodes permettent.
+        Chaque instance implémentant <classname 
role="SIS">NilObject</classname> fournit une méthode
+        <classname role="SIS">getNilReason()</classname> indiquant pourquoi 
l’objet est nul.
+      </para>
+      <para>
+        Dans l’exemple suivant, la partie gauche montre un élément 
<classname role="OGC">CI_Citation</classname>
+        contenant un élément <classname role="OGC">CI_Series</classname>, 
alors que dans la partie droite la série est inconnue.
+        Si l’élément <classname role="OGC">CI_Series</classname> avait 
été complètement omis
+        (ce qui est illégal selon les standards <acronym>ISO</acronym> mais 
toléré par <acronym>SIS</acronym>),
+        alors la méthode <function 
role="GeoAPI">Citation.getSeries()</function> retournerait 
<literal>null</literal> en Java.
+        Mais en présence d’un attribut <literal 
role="OGC">nilReason</literal>, l’implémentation <acronym>SIS</acronym>
+        de <function role="SIS">getSeries()</function> retournera plutôt un 
objet implémentant à la fois les interfaces
+        <classname role="GeoAPI">Series</classname> et <classname 
role="SIS">NilReason</classname>,
+        et dont la méthode <function role="SIS">getNilReason()</function> 
retournera la constante <constant role="SIS">UNKNOWN</constant>.
+      </para>
+      <example>
+        <title>Élément obligatoire marqué comme inconnu dans une 
méta-donnée</title>
+        <informaltable frame="none">
+          <tgroup cols="2">
+            <colspec colwidth="50%"/>
+            <colspec colwidth="50%"/>
+            <tbody>
+              <row>
+                <entry>
+                  <programlisting language="xml">&lt;gmd:CI_Citation&gt;
+  &lt;gmd:series&gt;
+    &lt;gmd:CI_Series&gt;
+      &lt;!-- Some content here --&gt;
+    &lt;/gmd:CI_Series&gt;
+  &lt;/gmd:series&gt;
+&lt;/gmd:CI_Citation&gt;</programlisting>
+                </entry>
+                <entry>
+                  <programlisting language="xml">&lt;gmd:CI_Citation&gt;
+  &lt;gmd:series nilReason="unknown"/&gt;
+&lt;/gmd:CI_Citation&gt;</programlisting>
+                </entry>
+              </row>
+            </tbody>
+          </tgroup>
+        </informaltable>
+      </example>
+    </section>
   </section>
 </chapter>

Modified: sis/branches/JDK7/src/main/docbook/fr/utility.xml
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK7/src/main/docbook/fr/utility.xml?rev=1415547&r1=1415546&r2=1415547&view=diff
==============================================================================
--- sis/branches/JDK7/src/main/docbook/fr/utility.xml (original)
+++ sis/branches/JDK7/src/main/docbook/fr/utility.xml Fri Nov 30 08:53:47 2012
@@ -13,6 +13,72 @@
   </para>
 
   <section>
+    <title>Modes de comparaisons des objets</title>
+    <para>
+      Il existe différentes opinions sur la façon d’implémenter la 
méthode <function>Object.equals(Object)</function> du Java standard.
+      Selon certains, il doit être possible de comparer différentes 
implémentations d’une même interface ou classe de base.
+      Mais cette politique nécessite que chaque interface ou classe de base 
définisse entièrement dans sa Javadoc les critères ou calculs
+      que doivent employer les méthodes <function>equals(Object)</function> 
et <function>hashCode()</function> dans toutes les implémentations.
+      Cette approche est choisie notamment par 
<classname>java.util.Collection</classname> et ses interfaces filles.
+      Elle se fait toutefois au détriment de la possibilité de prendre en 
compte des attributs supplémentaires dans les interfaces filles,
+      si cette possibilité n’a pas été spécifiée dans l’interface 
parente.
+      Cette contrainte découle des points suivants du contrat des méthodes 
<function>equals(Object)</function> et <function>hashCode()</function>:
+    </para>
+    <itemizedlist>
+      <listitem><literal>A.equals(B)</literal> implique 
<literal>B.equals(A)</literal> (symétrie);</listitem>
+      <listitem><literal>A.equals(B)</literal> et 
<literal>B.equals(C)</literal> implique <literal>A.equals(C)</literal> 
(transitivité);</listitem>
+      <listitem><literal>A.equals(B)</literal> implique <literal>A.hashCode() 
== B.hashCode()</literal>.</listitem>
+    </itemizedlist>
+    <para>
+      Par exemple ces trois contraintes sont violées si <varname>A</varname> 
(et éventuellement <varname>C</varname>)
+      peuvent contenir des attributs que <varname>B</varname> ignore.
+      Pour contourner cette difficulté, une approche alternative consiste à 
exiger que les objets comparés par la méthode
+      <function>Object.equals(Object)</function> soient exactement de la même 
classe, c’est-à-dire que <literal>A.getClass() == B.getClass()</literal>.
+      Cette approche est parfois considérée contraire aux principes de la 
programmation orientée objets.
+      Dans la pratique, pour des applications relativement complexes, ça 
dépend du contexte dans lequel les objets sont comparés:
+      si les objets sont ajoutés à un <classname>HashSet</classname> ou 
utilisés comme clés dans un <classname>HashMap</classname>,
+      alors nous avons besoin d’un strict respect du contrat de 
<function>equals(Object)</function> et <function>hashCode()</function>.
+      Mais si le développeur compare les objets lui-même, par exemple pour 
vérifier si des informations qui l’intéresse ont changées,
+      alors les contraintes de symétrie, transitivité ou de cohérence avec 
les valeurs de hachages peuvent ne pas être pertinentes pour lui.
+      Des comparaisons plus permissives peuvent être souhaitables, allant 
parfois jusqu’à tolérer de légers écarts dans les valeurs numériques.
+    </para>
+    <para>
+      Afin de donner une certaine flexibilité aux développeurs, un grand 
nombre de classes de la bibliothèque <acronym>SIS</acronym>
+      implémentent l’interface <classname 
role="SIS">org.apache.sis.util.LenientComparable</classname>, qui défini une 
méthode <function role="SIS">equals(Object, ComparisonMode)</function>.
+      Les principaux modes de comparaisons sont:
+    </para>
+    <itemizedlist>
+      <listitem><para>
+        <emphasis role="bold"><constant 
role="SIS">STRICT</constant></emphasis> — Les objets comparés doivent être 
de la même classe
+        et tous leurs attributs strictement égaux, y compris d’éventuels 
attributs publics propres à l’implémentation.
+      </para></listitem>
+      <listitem><para>
+        <emphasis role="bold"><constant 
role="SIS">BY_CONTRACT</constant></emphasis> — Les objets comparés doivent 
implémenter la même interface de GeoAPI (ou tout autre standard),
+        mais n’ont pas besoin d’être de la même classe 
d’implémentation. Seuls les attributs définis dans l’interface sont 
comparés;
+        tout autres attributs propres à l’implémentation — même 
s’ils sont publics — sont ignorés.
+      </para></listitem>
+      <listitem><para>
+        <emphasis role="bold"><constant 
role="SIS">IGNORE_METADATA</constant></emphasis> — Comme <constant 
role="SIS">BY_CONTRACT</constant>,
+        mais ne compare que les attributs qui influencent les opérations 
(calculs numériques ou autre) effectuées par l’objet.
+        Par exemple dans un référentiel géodésique, la longitude (par 
rapport à Greenwich) du méridien d’origine sera pris en compte
+        alors que le nom de ce méridien sera ignoré.
+      </para></listitem>
+      <listitem><para>
+        <emphasis role="bold"><constant 
role="SIS">APPROXIMATIVE</constant></emphasis> — Comme <constant 
role="SIS">IGNORE_METADATA</constant>,
+        mais tolère de légères différences dans les valeurs numériques.
+      </para></listitem>
+    </itemizedlist>
+    <para>
+      Le mode par défaut, utilisé par les toutes les méthodes 
<function>equals(Object)</function> de <acronym>SIS</acronym>,
+      est <constant role="SIS">STRICT</constant>. Ce mode est choisi à la 
fois pour une utilisation plus sécuritaire avec <classname>HashMap</classname>,
+      et aussi parce que définir rigoureusement le contrat des méthodes 
<function>equals(Object)</function> et <function>hashCode()</function>
+      dans les centaines d’interfaces de GeoAPI semble une entreprise peu 
réaliste, qui risque d’être assez peu suivit par les diverses 
implémentations.
+    </para>
+  </section>
+
+
+
+  <section>
     <title>Internationalisation</title>
     <para>
       Dans une architecture où un programme exécuté sur un serveur fournit 
ses données à plusieurs clients,
@@ -26,7 +92,7 @@
     </para>
 
     <section>
-      <title>Instances distinctes pour chaque conventions locales</title>
+      <title>Chaînes de caractères distinctes pour chaque conventions 
locales</title>
       <para>
         Certaines classes ne sont conçues que pour fonctionner selon une 
convention locale à la fois.
         C’est évidemment le cas des implémentations standards de 
<classname>java.text.Format</classname>,
@@ -34,7 +100,7 @@
         Mais c’est aussi le cas de d’autres classes moins évidentes comme
         
<classname>javax.imageio.ImageReader</classname>/<classname>ImageWriter</classname>
 ainsi que les exceptions.
         Lorsque une de ces classes est implémentée par 
<acronym>SIS</acronym>,
-        nous l’identifions en implémentant l’interface <classname 
role="SIS">Localized</classname>.
+        nous l’identifions en implémentant l’interface <classname 
role="SIS">org.apache.sis.util.Localized</classname>.
         La méthode <function role="SIS">getLocale()</function> de cette 
interface permet alors de déterminer
         selon quelles conventions locales l’instance produira ses messages.
       </para>
@@ -99,5 +165,95 @@
         pour des raisons d’économie de mémoire.
       </para>
     </section>
+
+    <section>
+      <title>Traitement des caractères</title>
+      <para>
+        Les chaînes de caractères en Java utilisent l’encodage UTF-16. Il 
existe une correspondance directe
+        entre les valeurs de type <classname>char</classname> et la très 
grande majorité des caractères, ce
+        qui facilite l’utilisation des chaînes lorsque ces caractères 
suffisent.
+        Mais certains caractères Unicode ne sont pas représentables par un 
seul <classname>char</classname>.
+        Ces <firstterm>caractères supplémentaires</firstterm> comprennent 
certains idéogrammes,
+        mais aussi des symboles routiers et géographiques dans la plage 1F680 
à 1F700.
+        Le support de ces caractères supplémentaires nécessite des 
itérations un peu plus complexes
+        que le cas classique où l’on supposait une correspondance directe.
+        Ainsi, au lieu de la boucle de gauche ci-dessous, les applications 
internationales devraient
+        généralement utiliser la boucle de droite:
+      </para>
+      <example>
+        <title>Boucle sur une chaîne pouvant contenir des caractères 
supplémentaires</title>
+        <informaltable frame="none">
+          <tgroup cols="2">
+            <colspec colwidth="50%"/>
+            <colspec colwidth="50%"/>
+            <tbody>
+              <row>
+                <entry>
+                  <programlisting language="java">for (int i=0; 
i&lt;string.length(); i++) {
+    char c = string.charAt(i);
+    if (Character.isWhitespace(c)) {
+        // Un espace blanc a été trouvé.
+    }
+}</programlisting>
+                </entry>
+                <entry>
+                  <programlisting language="java">for (int i=0; 
i&lt;string.length();) {
+    int c = string.codePointAt(i);
+    if (Character.isWhitespace(c)) {
+        // Un espace blanc a été trouvé.
+    }
+    i += Character.charCount(c);
+}</programlisting>
+                </entry>
+              </row>
+            </tbody>
+          </tgroup>
+        </informaltable>
+      </example>
+      <para>
+        <acronym>SIS</acronym> supporte les caractères supplémentaires en 
utilisant la boucle de droite lorsque nécessaire.
+        Mais la boucle de gauche reste occasionnellement utilisée lorsqu’il 
est connu que les caractères recherchés ne sont
+        pas des caractères supplémentaires, même si la chaîne dans 
laquelle on fait la recherche peut en contenir.
+      </para>
+
+      <section>
+      <title>Interprétation des espaces blancs</title>
+        <para>
+          Le Java standard fournit deux méthodes pour déterminer si un 
caractères est un espace blanc:
+          <function>Character.isWhitespace(…)</function> et 
<function>Character.isSpaceChar(…)</function>.
+          Ces deux méthodes diffèrent dans leurs interprétations des 
espaces insécables, des tabulations et des retours à la ligne.
+          La première méthode est conforme à l’interprétation couramment 
utilisée dans des langages telles que le Java, C/C++ et XML,
+          qui considère les tabulations et retours à la ligne comme des 
espaces blancs,
+          alors que les espaces insécables sont interprétés comme des 
caractères non-blanc.
+          La seconde méthode — strictement conforme à la définition 
Unicode — fait l’interprétation inverse.
+        </para>
+        <para>
+          <acronym>SIS</acronym> emploie ces deux méthodes dans des contextes 
différents.
+          <function>isWhitespace(…)</function> est utilisée pour 
<emphasis>séparer</emphasis>
+          les éléments d’une liste (nombres, dates, mots, 
<foreignphrase>etc.</foreignphrase>),
+          tandis que <function>isSpaceChar(…)</function> est utilisée pour 
ignorer les espaces
+          blancs <emphasis>à l’intérieur</emphasis> d’un seul élément.
+        </para>
+        <informalexample><para>
+          <emphasis role="bold">Exemple:</emphasis>
+          Supposons une liste de nombres représentés selon les conventions 
françaises.
+          Chaque nombre peut contenir des <emphasis>espace 
insécables</emphasis> comme séparateurs des milliers,
+          tandis que les différents nombres de la liste peuvent être 
séparés par des espaces ordinaires, des tabulations ou des retours à la 
ligne.
+          Pendant l’analyse d’un nombre, on veut considérer les espaces 
insécables comme faisant partie du nombre,
+          alors qu’une tabulation ou un retour à la ligne indique très 
probablement une séparation entre ce nombre et le nombre suivant.
+          On utilisera donc <function>isSpaceChar(…)</function>.
+          Inversement, lors de la séparation des nombres de la liste, on veut 
considérer les tabulations et
+          les retours à la ligne comme des séparateurs mais pas les espaces 
insécables.
+          On utilisera donc <function>isWhitespace(…)</function>.
+          Le rôle des espaces ordinaires, qui pourraient s’appliquer aux 
deux cas, doit être décidé en amont.
+        </para></informalexample>
+        <para>
+          Dans la pratique, cette distinction se traduit pas une utilisation 
de <function>isSpaceChar(…)</function>
+          dans les implémentations de <classname>java.text.Format</classname>,
+          et une utilisation de <function>isWhitespace(…)</function> dans 
pratiquement tout le reste
+          de la bibliothèque <acronym>SIS</acronym>.
+        </para>
+      </section>
+    </section>
   </section>
 </chapter>

Modified: sis/branches/JDK7/src/site/resources/book/book.css
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK7/src/site/resources/book/book.css?rev=1415547&r1=1415546&r2=1415547&view=diff
==============================================================================
--- sis/branches/JDK7/src/site/resources/book/book.css (original)
+++ sis/branches/JDK7/src/site/resources/book/book.css Fri Nov 30 08:53:47 2012
@@ -54,10 +54,18 @@ p {
  */
 pre.programlisting {
   border-style: solid;
+  border-color: gray;
   border-width: 1pt;
   padding:      9pt;
 }
 
+/* If inside a table, rely on the table border instead. */
+table pre.programlisting {
+  border-style: none;
+  margin:       0pt;
+  padding:      0pt;
+}
+
 div.sidebar {
   margin-left:      1.25cm;
   margin-right:     1.5cm;
@@ -79,11 +87,22 @@ div.informalexample {
 /*
  * Tables.
  */
+div.informaltable table tr {
+  vertical-align: top;
+}
+
+div.informaltable table tr td {
+  border-style: solid;
+  border-color: gray;
+  border-width: 1pt;
+  padding:      9pt;
+}
+
 div.table p.title {
   text-align: center;
 }
 
-table {
+div.table-contents table {
   margin-left:    auto;
   margin-right:   auto;
   border-style:   solid;
@@ -91,25 +110,25 @@ table {
   border-spacing: 0pt;
 }
 
-table tr th {
+div.table-contents table tr th {
   background-color:    #B9DCFF;
   border-bottom-style: solid;
   border-bottom-width: 1pt;
   padding:             3pt;
 }
 
-table tr td {
+div.table-contents table tr td {
   padding-left:  9pt;
   padding-right: 9pt;
 }
 
-table tr td.leftBorder {
+div.table-contents table tr td.leftBorder {
   border-left-style: solid;
   border-left-width: 1pt;
   border-left-color: lightgray;
 }
 
-table tr td.separator {
+div.table-contents table tr td.separator {
   text-align:          center;
   font-weight:         bold;
   background-color:    #EEEEFF;


Reply via email to