/*
 * 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.
 */

/**
 * Root package for various metadata implementations.
 *
 * <h2>Foreword</h2>
 * Many metadata standards exist, including <cite>Dublin core</cite>, <cite>ISO 19115</cite> and the Image I/O
 * metadata defined in {@link javax.imageio.metadata}. The SIS implementation focuses on ISO 19115 (including
 * its ISO 19115-2 extension), but the classes are designed in a way that allow the usage of different standards.
 * This genericity goal should be keep in mind in the discussion below.
 *
 * <h2>How Metadata are defined</h2>
 * A metadata standard is defined by a set of Java interfaces belonging to a specific package and its sub-packages.
 * For example, the ISO 19115 standard is defined by the <a href="http://www.geoapi.org">GeoAPI</a> interfaces
 * defined in the {@link org.opengis.metadata} package and sub-packages. That standard is identified in SIS by the
 * {@link org.apache.sis.metadata.MetadataStandard#ISO_19115} constant. Other standards are defined as well,
 * for example the {@link org.apache.sis.metadata.MetadataStandard#ISO_19123} constant stands for the standards
 * defined by the interfaces in the {@code org.opengis.coverage} package and sub-packages.
 *
 * <p>For each interface, the collection of declared getter methods defines its <cite>properties</cite>
 * (or <cite>attributes</cite>). If a {@link org.opengis.annotation.UML} annotation is attached to the getter method,
 * the identifier declared in that annotation is taken as the property name. This is typically the name defined by the
 * International Standard from which the interface is derived. Otherwise (if there is no {@code UML} annotation)
 * the property name is inferred from the method name like what the <cite>Java Beans</cite> framework does.</p>
 *
 * <p>The implementation classes, if they exist, are defined in different packages than the interfaces.
 * For example, the ISO 19115 interfaces, declared in {@link org.opengis.metadata}, are implemented by
 * SIS in {@link org.apache.sis.metadata.iso}. The sub-packages hierarchy is the same, and the names
 * of implementation classes are the name of the implemented interfaces prefixed with {@code Abstract}
 * or {@code Default}.</p>
 *
 * <h3>Notes</h3>
 * <ul class="verbose">
 *   <li>The {@code Abstract} prefix means that the class is abstract in the sense of the implemented standard.
 *       It it not necessarily abstract in the sense of Java. Because incomplete metadata are common in practice,
 *       sometimes we wish to instantiate an "abstract" class despite the lack of knowledge about the exact sub-type.</li>
 *   <li>The properties are determined by the getter methods declared in the interfaces.
 *       Getter methods declared in the implementation classes are ignored.</li>
 *   <li>Setter methods, if any, can be declared in the implementation classes without the need for declarations
 *       in the interfaces. In other words, interfaces are assumed read-only unless a specific implementation provide
 *       setter methods.</li>
 *   <li>The implementation is not required to exist as source code. They can be generated on the fly with
 *       {@link java.lang.reflect.Proxy}. This is the approach taken by the {@link org.apache.sis.metadata.sql}
 *       package for generating metadata implementations backed by the content of a database.</li>
 * </ul>
 *
 * <h2>How Metadata are handled</h2>
 * Metadata objects in SIS are mostly containers: they provide getter and setter methods for manipulating the values
 * associated to properties (for example the {@code title} property of a {@code Citation} object), but provide few logic.
 * The package {@link org.apache.sis.metadata.iso} and its sub-packages are the main examples of such containers.
 *
 * <p>In addition, the metadata modules provide support methods for handling the metadata objects through Java Reflection.
 * This is an approach similar to <cite>Java Beans</cite>, in that users are encouraged to use directly the API of
 * <cite>Plain Old Java</cite> objects (actually interfaces) every time their type is known at compile time,
 * and fallback on the reflection technic when the type is known only at runtime.</p>
 *
 * <p>Using Java reflection, a metadata can be viewed in many different ways:</p>
 * <ul class="verbose">
 *   <li><b>As a {@link java.util.Map}</b><br>
 *       The {@link org.apache.sis.metadata.MetadataStandard} class provides various methods returning a view
 *       of an arbitrary metadata implementation as a {@code Map}, where the key are the property names and the
 *       values are the return values, types or descriptions of getter methods. The map is writable if the
 *       underlying metadata implementation has setter methods, otherwise attempts to set a value throw an
 *       {@code UnmodifiableMetadataException}.</li>
 *
 *   <li><b>As a {@link org.apache.sis.util.collection.TreeTable}</b><br>
 *       The metadata are organized as a tree. For example, the {@code Citation} metadata contains one or many
 *       {@code ResponsibleParty} elements, each of them containing a {@code Contact} element, which contains
 *       a {@code Telephone} element, <i>etc</i>. For each node, there is many information that can be displayed
 *       in columns:
 *       <ul>
 *         <li>A description of the element.</li>
 *         <li>The type of values ({@code String}, {@code double}, <i>etc</i>).</li>
 *         <li>The range of valid values (if the type is numeric),
 *             or an enumeration of valid values (if the type is a code list).</li>
 *         <li>The value stored in the element, or the default value.</li>
 *       </ul></li>
 *
 *   <li><b>As a table record in a database (using {@link org.apache.sis.metadata.sql})</b><br>
 *       It is possible to establish the following mapping between metadata and a SQL database:
 *       <ul>
 *         <li>Each metadata interface maps to a table of the same name in the database.</li>
 *         <li>Each property in the above interface maps to a column of the same name in the above table.</li>
 *         <li>Each instance of the above interface is a record in the above table.</li>
 *       </ul>
 *       Using Java reflection, it is possible to generate implementations of the metadata interfaces
 *       where each call to a getter method is translated into a SQL query for the above database.</li>
 * </ul>
 *
 * <h2>How Metadata are marshalled</h2>
 * The ISO 19115-3 standard defines how ISO 19115-1 metadata shall be represented in XML.
 * The SIS library supports XML marshalling and unmarshalling with JAXB annotations.
 *
 * <p>Only the implementation classes defined in the {@link org.apache.sis.metadata.iso} packages and sub-packages
 * are annotated for JAXB marshalling. If a metadata is implemented by another package (for example
 * {@link org.apache.sis.metadata.sql}), then it shall be converted to an annotated class before to be marshalled.
 * All SIS annotated classes provide a copy constructor for this purpose. A shallow copy is sufficient;
 * JAXB adapters will convert the elements on-the-fly when needed.</p>
 *
 * <p>The annotated classes can be given to a JAXB {@code Marshaller}. For best results, it shall be a marshaller
 * obtained from the {@link org.apache.sis.xml.MarshallerPool}, otherwise some XML outputs may be incomplete
 * (missing namespaces for instance). The {@link org.apache.sis.xml.XML} class provides convenience methods
 * for this purpose.</p>
 *
 * @author  Martin Desruisseaux (IRD, Geomatys)
 * @author  Adrian Custer (Geomatys)
 * @version 1.4
 * @since   0.3
 */
package org.apache.sis.metadata;
