diff --git a/build/release.sh b/build/release.sh
new file mode 100644
index 0000000..669ac0a
--- /dev/null
+++ b/build/release.sh
@@ -0,0 +1,141 @@
+#!/bin/bash
+
+#
+# Create release of the project, which means a tag on a separate branch, with a fixed version.
+# NOTE : we expect this script to be in the following directory : ROOT_POM_DIR/build/
+#
+
+# Release version for the tag to create
+releaseVersion=
+
+# change SNAPSHOT version after release.
+newSnapshot=
+
+# A prefix for the temporary release branch
+releaseBranchPrefix="release-"
+
+# Keep original branch to come back to it after release.
+sourceBranch=
+
+# Original code from 'http://stackoverflow.com/questions/242538/unix-shell-script-find-out-which-directory-the-script-file-resides'
+# Absolute path to this script, e.g. /home/user/bin/foo.sh
+SCRIPT=$(readlink -f "$BASH_SOURCE")
+# Absolute path this script is in, thus /home/user/bin
+SCRIPT_PATH=$(dirname "$SCRIPT")
+
+###################### FUNCTIONS ############################
+
+# Print help on standard output.
+function printHelp {
+ echo "
+ Create a release tag for the current project. Release number will be something like X.x where X is major release version, and x is minor.
+ "
+ echo " WARNING : No check is done to ensure the project is well-formed (no compilation, test, syntax check, etc.)
+ "
+ echo " MANDATORY ARGUMENT : "
+ echo " -r --release-version : Version to set on new release."
+ echo " OPTIONAL ARGUMENT : "
+ echo " -s --snapshot-version : If set, and once the tag is done, the version on original branch is changed according to this argument value."
+ echo " -- help, -h : Print this help."
+}
+
+function printError() {
+ echo "
+ "
+ tput setaf 1; tput setab 7; tput bold;
+ echo "$*"
+ tput sgr0;
+ echo "
+ "
+}
+
+# Print the given parameters to standard error output, then exit the script in failure mode.
+function error() {
+ printError "$*"
+ git checkout $sourceBranch # come back on the initial branch before exit
+ exit 1
+}
+
+# do the job
+function execute {
+ # We place ourself in the script directory. It MUST BE into the git project directory.
+ cd $SCRIPT_PATH/..
+
+ # Save original branch name to go back to it at the end of the release.
+ sourceBranch="$(git symbolic-ref --short HEAD)"
+ echo "Original branch is $sourceBranch"
+ createTag
+ updateSnapshot
+}
+
+# Create the tag itself
+function createTag {
+ echo "Create temporary branch for release $releaseVersion"
+ tmpReleaseBranch="$releaseBranchPrefix$releaseVersion"
+ git branch $tmpReleaseBranch || error "Cannot create a temporary branch for release creation."
+ git checkout $tmpReleaseBranch || error "Cannot access created branch $tmpReleaseBranch"
+
+ echo "Perform version update for release $releaseVersion"
+ mvn versions:set -DnewVersion=$releaseVersion || error "Cannot update project version to $releaseVersion"
+
+ echo "Commit release versions"
+ git commit -m "Project release $releaseVersion" -a || error "Cannot commit updated poms to the temporary release branch"
+
+ echo "Create tag named $releaseVersion"
+ git tag $releaseVersion $tmpReleaseBranch || error "Cannot create the tag $releaseVersion"
+
+ echo "Remove temporary release branch"
+ git checkout $sourceBranch || error "Cannot come back to the source branch $sourceBranch"
+ git branch -D $tmpReleaseBranch || printError "WARNING : Cannot delete temporary branch $tmpReleaseBranch. You will have to do it yourself ! "
+}
+
+# Update project version on initial branch
+function updateSnapshot {
+ if [ ! -z "$releaseVersion" ]
+ then
+ echo "Update snapshot version $newSnapshot"
+ mvn versions:set -DnewVersion=$newSnapshot || error "Cannot update project version to $newSnapshot"
+
+ echo "Commit updated snapshot"
+ git commit -m "Snapshot update $newSnapshot" -a || error "Cannot commit updated poms to the source branch"
+ fi
+}
+
+########################### MAIN #############################
+
+# ARGUMENT CHECK
+while [ "$1" != "" ]; do
+ case $1 in
+ -r | --release-version ) shift
+ releaseVersion=$1
+ ;;
+ -s | --snapshot-version ) shift
+ newSnapshot=$1
+ ;;
+ # etc.
+ -h | --help ) printHelp
+ exit
+ ;;
+ * ) printHelp
+ exit 1
+ ;;
+ esac
+ shift
+done
+
+
+if [ -z "$releaseVersion" ]
+ then echo "ERROR: MINOR RELEASE VERSION IS NOT AN INTEGER. FOUND VALUE --> $releaseMinor" >&2; exit 1
+fi
+
+# We must ensure that no tag already exists with the same name.
+tagDoublon="$(git tag -l|grep $releaseVersion)"
+
+if [ ! -z "$tagDoublon" ]
+ then echo "ERROR : A tag already exists for the following version : $releaseVersion" >&2; exit 1
+fi
+
+echo "Execute for version $releaseVersion"
+
+# Make release
+execute
\ No newline at end of file
diff --git a/core/pom.xml b/core/pom.xml
new file mode 100644
index 0000000..4834088
--- /dev/null
+++ b/core/pom.xml
@@ -0,0 +1,167 @@
+
+
+ 4.0.0
+
+
+ fr.cenra.rhomeo
+ rhomeo
+ 1.2-SNAPSHOT
+
+
+ fr.cenra.rhomeo
+ core
+ jar
+ Core
+
+
+
+ javax.validation
+ validation-api
+
+
+
+ org.hibernate
+ hibernate-validator
+
+
+
+ javax.el
+ javax.el-api
+
+
+
+ org.glassfish.web
+ javax.el
+
+
+
+ org.springframework
+ spring-context
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+
+
+ commons-net
+ commons-net
+ 3.4
+
+
+ commons-codec
+ commons-codec
+
+
+
+
+ org.geotoolkit
+ geotk-feature-shapefile
+ ${geotoolkit.version}
+
+
+ org.geotoolkit
+ geotk-feature-kml
+ ${geotoolkit.version}
+
+
+ org.geotoolkit
+ geotk-feature-geojson
+ ${geotoolkit.version}
+
+
+ org.codehaus.groovy
+ groovy-all
+
+
+
+
+
+ org.geotoolkit
+ geotk-feature-store
+ ${geotoolkit.version}
+
+
+ org.codehaus.groovy
+ groovy-all
+
+
+
+
+
+ org.geotoolkit
+ geotk-feature-csv
+ ${geotoolkit.version}
+
+
+
+ org.geotoolkit
+ geotk-client-wfs
+
+
+ org.geotoolkit
+ geotk-jaxp-xsd
+
+
+
+ org.apache.derby
+ derby
+
+
+
+
+ javax.media
+ jai_core
+
+
+ javax.media
+ jai_codec
+
+
+ javax.media
+ jai_imageio
+
+
+
+
+ junit
+ junit
+ test
+
+
+
+ org.apache.sis.core
+ sis-utility
+ test-jar
+ test
+
+
+
+ org.springframework
+ spring-test
+ test
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 2.6
+
+
+
+ test-jar
+
+
+
+
+
+
+
+
diff --git a/core/src/main/java/fr/cenra/rhomeo/api/EditableIdentifiedObject.java b/core/src/main/java/fr/cenra/rhomeo/api/EditableIdentifiedObject.java
new file mode 100644
index 0000000..ed0beaf
--- /dev/null
+++ b/core/src/main/java/fr/cenra/rhomeo/api/EditableIdentifiedObject.java
@@ -0,0 +1,93 @@
+/**
+ * Copyright © CENRA (2016)
+ *
+ * remi.clement@espaces-naturels.fr
+ *
+ * This software is a multi-platform and portable application based on
+ * the scientifical toolbox to monitor wetlands. With this toolbox it’s
+ * possible to calculate indicators «RhoMéO» to monitor quality,
+ * fonctionalities and urban and agricultural pressures of wetlands.
+ * Indicators are calculated using naturalist data entered and/or imported,
+ * and geographic data downloaded from a geographic server.
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+*/
+package fr.cenra.rhomeo.api;
+
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+
+/**
+ *
+ * @author Alexis Manin (Geomatys)
+ */
+public class EditableIdentifiedObject implements IdentifiedObject {
+
+ protected final SimpleStringProperty nameProperty = new SimpleStringProperty();
+ protected final SimpleStringProperty remarksProperty = new SimpleStringProperty();
+ protected ObservableList alias;
+
+ @Override
+ public String getName() {
+ return nameProperty.get();
+ }
+
+ public void setName(final String newName) {
+ nameProperty.set(newName);
+ }
+
+ public StringProperty nameProperty() {
+ return nameProperty;
+ }
+
+ @Override
+ public ObservableList getAlias() {
+ if (alias == null) {
+ alias = FXCollections.observableArrayList();
+ }
+ return alias;
+ }
+
+ public void setAlias(final ObservableList alias) {
+ this.alias = alias;
+ }
+
+ @Override
+ public String getRemarks() {
+ return remarksProperty.get();
+ }
+
+ public void setRemarks(final String remarks) {
+ remarksProperty.set(remarks);
+ }
+
+ public StringProperty remarksProperty() {
+ return remarksProperty;
+ }
+}
diff --git a/core/src/main/java/fr/cenra/rhomeo/api/IdentifiedObject.java b/core/src/main/java/fr/cenra/rhomeo/api/IdentifiedObject.java
new file mode 100644
index 0000000..0ae14e4
--- /dev/null
+++ b/core/src/main/java/fr/cenra/rhomeo/api/IdentifiedObject.java
@@ -0,0 +1,88 @@
+/**
+ * Copyright © CENRA (2016)
+ *
+ * remi.clement@espaces-naturels.fr
+ *
+ * This software is a multi-platform and portable application based on
+ * the scientifical toolbox to monitor wetlands. With this toolbox it’s
+ * possible to calculate indicators «RhoMéO» to monitor quality,
+ * fonctionalities and urban and agricultural pressures of wetlands.
+ * Indicators are calculated using naturalist data entered and/or imported,
+ * and geographic data downloaded from a geographic server.
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+*/
+package fr.cenra.rhomeo.api;
+
+import java.util.Collection;
+import javax.validation.constraints.NotNull;
+import org.hibernate.validator.constraints.NotBlank;
+
+/**
+ * A simplified version of {@link org.opengis.referencing.IdentifiedObject} from
+ * GeoAPI. The aim is to ease manipulation by working only with Strings.
+ *
+ * Note : The {@link #getName() } is the identifier of the object.
+ * The {@link #getAlias() } is a list of alternative names to use as proper title.
+ * By default, the {@link #getTitle() } method returns the first alias available,
+ * or the name of the object if none is available.
+ *
+ * @author Alexis Manin (Geomatys)
+ */
+public interface IdentifiedObject {
+
+ /**
+ *
+ * @return Identifier of the object.
+ */
+ @NotBlank
+ String getName();
+
+ /**
+ *
+ * @return Available titles / alternative names. Can be empty, but should never be null.
+ */
+ @NotNull
+ Collection getAlias();
+
+ /**
+ *
+ * @return A short description of the object.
+ */
+ String getRemarks();
+
+ /**
+ *
+ * @return The most appropriate title from available aliases.
+ */
+ default String getTitle() {
+ if (getAlias().isEmpty()) {
+ return getName();
+ }
+ return getAlias().iterator().next();
+ }
+}
diff --git a/core/src/main/java/fr/cenra/rhomeo/api/InternationalDescription.java b/core/src/main/java/fr/cenra/rhomeo/api/InternationalDescription.java
new file mode 100644
index 0000000..66a0c75
--- /dev/null
+++ b/core/src/main/java/fr/cenra/rhomeo/api/InternationalDescription.java
@@ -0,0 +1,123 @@
+/**
+ * Copyright © CENRA (2016)
+ *
+ * remi.clement@espaces-naturels.fr
+ *
+ * This software is a multi-platform and portable application based on
+ * the scientifical toolbox to monitor wetlands. With this toolbox it’s
+ * possible to calculate indicators «RhoMéO» to monitor quality,
+ * fonctionalities and urban and agricultural pressures of wetlands.
+ * Indicators are calculated using naturalist data entered and/or imported,
+ * and geographic data downloaded from a geographic server.
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+*/
+package fr.cenra.rhomeo.api;
+
+import fr.cenra.rhomeo.core.RhomeoCore;
+import java.util.Locale;
+import java.util.ResourceBundle;
+import java.util.logging.Level;
+
+/**
+ * An object able to provide some title and description for given (or default) locales.
+ *
+ * This interface provides a default implementation based on the class {@link ResourceBundle}.
+ *
+ * According to the default implementation, the title and the description are the values
+ * of the keys {@link InternationalDescription#LABEL_KEY} and {@link InternationalDescription#DESCRIPTION_KEY} respectively.
+ *
+ * @author Samuel Andrés (Geomatys)
+ */
+public interface InternationalDescription {
+
+ /**
+ * The bundle key of the title value provided by the default implementation.
+ */
+ String LABEL_KEY = "_label";
+
+ /**
+ * The bundle key of the description value provided by the default implementation.
+ */
+ String DESCRIPTION_KEY = "_description";
+
+ /**
+ * Gets a title for the object.
+ *
+ * Default implementation returns the value of the {@link InternationalDescription#LABEL_KEY}
+ * key stored into the class {@link ResourceBundle} for the given {@link Locale}.
+ *
+ * @param locale
+ * @return
+ */
+ default String getLabel(final Locale locale) {
+ try {
+ final ResourceBundle bundle = ResourceBundle.getBundle(getClass().getName(), locale);
+ return bundle.getString(LABEL_KEY);
+ } catch (Exception e) {
+ RhomeoCore.LOGGER.log(Level.WARNING, "Cannot find any title for this object.", e);
+ return "No title available";
+ }
+ }
+
+ /**
+ * Gets a description for the object.
+ *
+ * Default implementation returns the value of the {@link InternationalDescription#DESCRIPTION_KEY}
+ * key stored into the class {@link ResourceBundle} for the given {@link Locale}.
+ *
+ * @param locale
+ * @return
+ */
+ default String getDescription(final Locale locale){
+ try {
+ final ResourceBundle bundle = ResourceBundle.getBundle(getClass().getName(), locale);
+ return bundle.getString(DESCRIPTION_KEY);
+ } catch (Exception e) {
+ RhomeoCore.LOGGER.log(Level.WARNING, "Cannot find any title for this object.", e);
+ return "No title available";
+ }
+ }
+
+ /**
+ * Shortcut method to avoid to specify locale parameter.
+ *
+ * Default implementation maps the {@link Locale#getDefault() } {@link Locale}.
+ *
+ * @return
+ */
+ default String getLabel(){return getLabel(Locale.getDefault());}
+
+ /**
+ * Shortcut method to avoid to specify locale parameter.
+ *
+ * Default implementation maps the {@link Locale#getDefault() } {@link Locale}.
+ *
+ * @return
+ */
+ default String getDescription(){return getDescription(Locale.getDefault());}
+}
diff --git a/core/src/main/java/fr/cenra/rhomeo/api/InternationalResource.java b/core/src/main/java/fr/cenra/rhomeo/api/InternationalResource.java
new file mode 100644
index 0000000..0452e7b
--- /dev/null
+++ b/core/src/main/java/fr/cenra/rhomeo/api/InternationalResource.java
@@ -0,0 +1,249 @@
+/**
+ * Copyright © CENRA (2016)
+ *
+ * remi.clement@espaces-naturels.fr
+ *
+ * This software is a multi-platform and portable application based on
+ * the scientifical toolbox to monitor wetlands. With this toolbox it’s
+ * possible to calculate indicators «RhoMéO» to monitor quality,
+ * fonctionalities and urban and agricultural pressures of wetlands.
+ * Indicators are calculated using naturalist data entered and/or imported,
+ * and geographic data downloaded from a geographic server.
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+*/
+package fr.cenra.rhomeo.api;
+
+import fr.cenra.rhomeo.core.RhomeoCore;
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.StringJoiner;
+import java.util.logging.Level;
+import org.apache.sis.util.ArgumentChecks;
+
+/**
+ * An object able to provide some resource strings for given (or default) locales.
+ *
+ * This interface provides a default implementation based on the class
+ * {@link ResourceBundle}. So, if you do not redefine its methods, make sure
+ * the {@link ResourceBundle} associated to the class exists.
+ *
+ * @author Samuel Andrés (Geomatys)
+ */
+public interface InternationalResource {
+
+ /**
+ * Default {@link InternationalResource} behaviour for a given class and a
+ * given locale, retrieving the associated {@link ResourceBundle}.
+ *
+ * The resource can be associated to a simple key or a complex one.
+ *
+ * The default implementation assumes the key parts are separated by a dot.
+ *
+ * For instance, let's assume the class my.package.MyClass implementq
+ * {@link InternationalResource} without overriding methods and is
+ * associated to the following resource bundle : /my/package/MyClass.properties
+ * which content is below :
+ *
+ * keyPart1.keyPart2=resource value
+ *
+ * The resource string "resource value" can be retrived from a my.package.MyClass
+ * instance, calling this method either specifying only one key part
+ * "keyPart1.keyPart2", or two key parts "keyPart1" and "keyPart2".
+ *
+ * @param c
+ * @param locale
+ * @param keyParts
+ * @return
+ *
+ * @throws IllegalArgumentException if the class parameter or the locale is null or no key is provided
+ * @throws MissingResourceException if no resource bundle for the specified class can be found or no object for the key can be found
+ */
+ static String getResourceString(final Class extends InternationalResource> c, final Locale locale, final String... keyParts){
+ ArgumentChecks.ensureNonNull("class", c);
+ ArgumentChecks.ensureNonNull("locale", locale);
+ ArgumentChecks.ensureNonNull("keyParts", keyParts);
+
+ final ResourceBundle bundle;
+ try{
+ bundle = ResourceBundle.getBundle(c.getName(), locale);
+ }
+ catch(MissingResourceException e){
+ // Warns about InternationalResource default behaviour is not fulfilled.
+ RhomeoCore.LOGGER.log(Level.WARNING, "No resource found for the class {0}. Default {1} behaviour use resource bundle.",
+ new Object[]{c.getCanonicalName(), InternationalResource.class.getSimpleName()});
+ // Then, re-throw the exception…
+ throw e;
+ }
+
+ final StringJoiner joiner = new StringJoiner(".");
+ for(final String keyPart : keyParts){
+ joiner.add(keyPart);
+ }
+ return bundle.getString(joiner.toString());
+ }
+
+ /**
+ *
+ * @param c
+ * @param keyParts
+ * @return
+ *
+ * @see InternationalResource#getResourceString(java.lang.Class, java.util.Locale, java.lang.String...) , with default locale.
+ *
+ * @throws IllegalArgumentException if the class parameter is null or no key is provided
+ * @throws MissingResourceException if no resource bundle for the specified class can be found or no object for the key can be found
+ */
+ static String getResourceString(final Class extends InternationalResource> c, final String... keyParts){
+ return getResourceString(c, Locale.getDefault(), keyParts);
+ }
+
+ /**
+ * Use the default behaviour to retrieve the property mapping the given key for
+ * the given class before formating the result using the given arguments.
+ *
+ * Note the key cannot be split into dot-separated key parts because of the
+ * arguments vararg parameter.
+ *
+ * @param c
+ * @param locale
+ * @param key
+ * @param arguments
+ * @return
+ *
+ * @see InternationalResource#getResourceString(java.lang.Class, java.util.Locale, java.lang.String...) , with default locale.
+ *
+ * @throws IllegalArgumentException if the class parameter or the locale are null or no key is provided
+ * @throws MissingResourceException if no resource bundle for the specified class can be found or no object for the key can be found
+ */
+ static String getFormatedResourceString(final Class extends InternationalResource> c, final Locale locale, final String key, final Object... arguments){
+ return MessageFormat.format(getResourceString(c, locale, key), arguments);
+ }
+
+ /**
+ *
+ * Same behaviour as {@link InternationalResource#getFormatedResourceString(java.lang.Class, java.util.Locale, java.lang.String, java.lang.Object...) },
+ * with default locale.
+ *
+ * @param c
+ * @param key
+ * @param arguments
+ * @return
+ *
+ * @see InternationalResource#getResourceString(java.lang.Class, java.lang.String...).
+ *
+ * @throws IllegalArgumentException if no key is provided
+ * @throws MissingResourceException if no object for the key can be found
+ */
+ static String getFormatedResourceString(final Class extends InternationalResource> c, final String key, final Object... arguments){
+ return MessageFormat.format(getResourceString(c, key), arguments);
+ }
+
+ /**
+ * Retrieves a string resource for the given locale.
+ *
+ * The resource can be associated to a simple key or a complex one.
+ *
+ * The default implementation assumes the key parts are separated by a dot.
+ *
+ * For instance, let's assume the class my.package.MyClass implementq
+ * {@link InternationalResource} without overriding methods and is
+ * associated to the following resource bundle : /my/package/MyClass.properties
+ * which content is below :
+ *
+ * keyPart1.keyPart2=resource value
+ *
+ * The resource string "resource value" can be retrived from a my.package.MyClass
+ * instance, calling this method either specifying only one key part
+ * "keyPart1.keyPart2", or two key parts "keyPart1" and "keyPart2".
+ *
+ * @param keyParts
+ * @param locale
+ * @return
+ *
+ * @throws IllegalArgumentException if the locale is null or no key is provided
+ * @throws MissingResourceException if no resource bundle can be found for the class of the current object or no object for the key can be found
+ */
+ default String getResourceString(final Locale locale, final String... keyParts) {
+ return getResourceString(getClass(), locale, keyParts);
+ }
+
+ /**
+ * Shortcut method to avoid to specify locale parameter.
+ *
+ * Default implementation maps the {@link Locale#getDefault() } {@link Locale}.
+ *
+ * @param keyParts
+ * @return
+ *
+ * @see InternationalResource#getResourceString(java.util.Locale, java.lang.String...) ...).
+ *
+ * @throws IllegalArgumentException if no key is provided
+ * @throws MissingResourceException if no resource bundle can be found for the class of the current object or no object for the key can be found
+ */
+ default String getResourceString(final String... keyParts) {
+ return getResourceString(Locale.getDefault(), keyParts);
+ }
+
+ /**
+ * Retrieves a string resource for the given locale and formats the result
+ * using the given arguments.
+ *
+ * @param locale
+ * @param key
+ * @param arguments
+ * @return
+ *
+ * @see InternationalResource#getFormatedResourceString(java.lang.Class, java.util.Locale, java.lang.String, java.lang.Object...)
+ *
+ * @throws IllegalArgumentException if the locale is null or no key is provided
+ * @throws MissingResourceException if no resource bundle for the class can be found for the class of the current object or no object for the key can be found
+ */
+ default String getFormatedResourceString(final Locale locale, final String key, final Object... arguments) {
+ return getFormatedResourceString(getClass(), locale, key, arguments);
+ }
+
+ /**
+ * Shortcut method to avoid to specify locale parameter.
+ *
+ * Default implementation maps the {@link Locale#getDefault() } {@link Locale}.
+ *
+ * @param key
+ * @param arguments
+ * @return
+ *
+ * @see InternationalResource#getFormatedResourceString(java.util.Locale, java.lang.String, java.lang.Object...) ...).
+ *
+ * @throws IllegalArgumentException if no key is provided
+ * @throws MissingResourceException if no resource bundle for the class can be found for the class of the current object or no object for the key can be found
+ */
+ default String getFormatedResourceString(final String key, final Object... arguments) {
+ return getFormatedResourceString(Locale.getDefault(), key, arguments);
+ }
+}
diff --git a/core/src/main/java/fr/cenra/rhomeo/api/Version.java b/core/src/main/java/fr/cenra/rhomeo/api/Version.java
new file mode 100644
index 0000000..d6e4886
--- /dev/null
+++ b/core/src/main/java/fr/cenra/rhomeo/api/Version.java
@@ -0,0 +1,138 @@
+/**
+ * Copyright © CENRA (2016)
+ *
+ * remi.clement@espaces-naturels.fr
+ *
+ * This software is a multi-platform and portable application based on
+ * the scientifical toolbox to monitor wetlands. With this toolbox it’s
+ * possible to calculate indicators «RhoMéO» to monitor quality,
+ * fonctionalities and urban and agricultural pressures of wetlands.
+ * Indicators are calculated using naturalist data entered and/or imported,
+ * and geographic data downloaded from a geographic server.
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+*/
+package fr.cenra.rhomeo.api;
+
+import java.util.Arrays;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.apache.sis.util.logging.Logging;
+
+/**
+ * A comparable to hold version values and allow for comparison between them.
+ * This object will try to split an input string to extract a suite of digits,
+ * which will compose the version. The weight of each digit in the suit is
+ * determined by its encounter order in the string. First encountered are priorized
+ * over the last ones.
+ *
+ * Ex : the String "1.2.3" will result in the following digit suite : 1 2 3,
+ * where 1 is the major version, 2 the minor version, and 3 the update version.
+ *
+ * @author Alexis Manin (Geomatys)
+ */
+public class Version implements Comparable {
+
+ private static final Logger LOGGER = Logging.getLogger("fr.cenra.core");
+
+ final String stringVersion;
+ final int[] version;
+
+ public Version(String inputVersion) {
+ stringVersion = inputVersion == null? "" : inputVersion;
+
+ String[] splitted = stringVersion.split("[^\\d]+");
+ if (splitted.length < 1) {
+ version = new int[0];
+ } else {
+ int[] tmpVersion = new int[splitted.length];
+ try {
+ for (int i = 0; i < splitted.length; i++) {
+ tmpVersion[i] = Integer.parseInt(splitted[i]);
+ }
+ } catch (NumberFormatException e) {
+ LOGGER.log(Level.WARNING, "Input version cannot be split as a suite of numbers : "+ inputVersion, e);
+ tmpVersion = new int[0];
+ }
+
+ version = tmpVersion;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int compareTo(Version o) {
+ if (o == null) {
+ return -1;
+ } else if (version.length < 1 || o.version.length < 1) {
+ return stringVersion.compareTo(o.stringVersion);
+ } else {
+ final int maxIndex = Math.min(version.length, o.version.length);
+ int comparison;
+ for (int i = 0 ; i < maxIndex ; i++) {
+ comparison = version[i] - o.version[i];
+ if (comparison != 0) {
+ return comparison;
+ }
+ }
+
+ // if we arrived here, common version parts are equals. The longest should be the last version.
+ return version.length - o.version.length;
+ }
+ }
+
+ /**
+ * A string representing current application version.
+ *
+ * @return current application version.
+ */
+ @Override
+ public String toString() {
+ return stringVersion;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof Version) {
+ return compareTo((Version) obj) == 0;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ if (version.length < 1) {
+ return Arrays.hashCode(version);
+ } else {
+ return stringVersion.hashCode();
+ }
+ }
+
+
+}
diff --git a/core/src/main/java/fr/cenra/rhomeo/api/annotations/RefersTo.java b/core/src/main/java/fr/cenra/rhomeo/api/annotations/RefersTo.java
new file mode 100644
index 0000000..5c9ad3c
--- /dev/null
+++ b/core/src/main/java/fr/cenra/rhomeo/api/annotations/RefersTo.java
@@ -0,0 +1,98 @@
+/**
+ * Copyright © CENRA (2016)
+ *
+ * remi.clement@espaces-naturels.fr
+ *
+ * This software is a multi-platform and portable application based on
+ * the scientifical toolbox to monitor wetlands. With this toolbox it’s
+ * possible to calculate indicators «RhoMéO» to monitor quality,
+ * fonctionalities and urban and agricultural pressures of wetlands.
+ * Indicators are calculated using naturalist data entered and/or imported,
+ * and geographic data downloaded from a geographic server.
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+*/
+package fr.cenra.rhomeo.api.annotations;
+
+import fr.cenra.rhomeo.core.validation.ReferenceValidator;
+import java.beans.Introspector;
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.function.Predicate;
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+/**
+ * Describe a link between the source (annotated) property, and another one,
+ * located in the specified class. This annotation should be positioned on a
+ * property getter.
+ *
+ * IMPORTANT : we talk about properties in java.beans term, which means a data
+ * accessible via public getter. The property name is defined by the terms used
+ * to define the getter name. For more information, see {@link Introspector}
+ * documentation.
+ *
+ * IMPORTANT : This annotation is also a validation flag, to ensure the property
+ * value is referring to an existing object. However, it tests NEITHER nullity
+ * NOR blankness.
+ *
+ * @author Alexis Manin (Geomatys)
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+@Constraint(validatedBy = ReferenceValidator.class)
+@Documented
+public @interface RefersTo {
+ String message() default "Aucune correspondance trouvée";
+
+ Class>[] groups() default {};
+
+ Class extends Payload>[] payload() default {};
+
+ /**
+ *
+ * @return The class in which is located the property we're refering to.
+ */
+ Class type();
+
+ /**
+ *
+ * @return The name of the property refered in {@link #type() }.
+ */
+ String property();
+
+ /**
+ * Provides a predicate to keep only objects which respects it.
+ * @return A class (should not be an interface nor abstract one) from which
+ * a {@link Predicate} can be created using {@link Class#newInstance() }.
+ *
+ */
+ Class extends Predicate> filterClass() default Predicate.class;
+}
diff --git a/core/src/main/java/fr/cenra/rhomeo/api/data/AbstractProtocol.java b/core/src/main/java/fr/cenra/rhomeo/api/data/AbstractProtocol.java
new file mode 100644
index 0000000..d1b5ad1
--- /dev/null
+++ b/core/src/main/java/fr/cenra/rhomeo/api/data/AbstractProtocol.java
@@ -0,0 +1,133 @@
+/**
+ * Copyright © CENRA (2016)
+ *
+ * remi.clement@espaces-naturels.fr
+ *
+ * This software is a multi-platform and portable application based on
+ * the scientifical toolbox to monitor wetlands. With this toolbox it’s
+ * possible to calculate indicators «RhoMéO» to monitor quality,
+ * fonctionalities and urban and agricultural pressures of wetlands.
+ * Indicators are calculated using naturalist data entered and/or imported,
+ * and geographic data downloaded from a geographic server.
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+*/
+package fr.cenra.rhomeo.api.data;
+
+import fr.cenra.rhomeo.api.process.Indicator;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * Abstract implementation of {@link Protocol}.
+ *
+ * @author Samuel Andrés (Geomatys)
+ */
+public abstract class AbstractProtocol implements Protocol {
+
+ private final String name;
+ private final String remarks;
+ protected final Class extends Statement> dataType;
+ protected final Set referenceTypes = new HashSet<>();
+
+ @Autowired // Need all subclasses to be Spring components.
+ protected List indicators;
+
+ public AbstractProtocol(final String name, final String remarks, final Class extends Statement> dataType, final ReferenceDescription... referenceTypes){
+ this.name = name;
+ this.remarks = remarks;
+ this.dataType = dataType;
+ if (referenceTypes != null && referenceTypes.length > 0) {
+ for (final ReferenceDescription referenceType : referenceTypes) {
+ if (referenceType != null) {
+ this.referenceTypes.add(referenceType);
+ }
+ }
+ }
+ }
+
+ @Override
+ public Class extends Statement> getDataType() {
+ return dataType;
+ }
+
+ @Override
+ public Set getReferenceTypes() {
+ return referenceTypes;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public Collection getAlias() {
+ return Collections.singleton(name);
+ }
+
+ @Override
+ public String getRemarks() {
+ return remarks;
+ }
+
+ /**
+ * Default implementation checking at least one {@link Indicator} exists
+ * referencing this {@link Protocol} instance and compatible with the given
+ * {@link Site} zone type code.
+ *
+ * @param site
+ * @return
+ */
+ @Override
+ public boolean isCompatible(Site site) {
+ if (site == null) {
+ return false;
+ }
+
+ for(final Indicator indicator : indicators){
+ if(indicator.getProtocol()==this && indicator.getZoneTypeCodes() != null
+ && indicator.getZoneTypeCodes().contains(site.getZoneType())) return true;
+ }
+ return false;
+ }
+
+ @Override
+ public int compareTo(final Protocol p){
+ return this.getName().compareTo(p.getName());
+ }
+
+ @Override
+ public String toString() {
+ return "AbstractProtocol{" + "name=" + name + ", remarks=" + remarks + '}';
+ }
+
+}
diff --git a/core/src/main/java/fr/cenra/rhomeo/api/data/DataContext.java b/core/src/main/java/fr/cenra/rhomeo/api/data/DataContext.java
new file mode 100644
index 0000000..984d52d
--- /dev/null
+++ b/core/src/main/java/fr/cenra/rhomeo/api/data/DataContext.java
@@ -0,0 +1,132 @@
+/**
+ * Copyright © CENRA (2016)
+ *
+ * remi.clement@espaces-naturels.fr
+ *
+ * This software is a multi-platform and portable application based on
+ * the scientifical toolbox to monitor wetlands. With this toolbox it’s
+ * possible to calculate indicators «RhoMéO» to monitor quality,
+ * fonctionalities and urban and agricultural pressures of wetlands.
+ * Indicators are calculated using naturalist data entered and/or imported,
+ * and geographic data downloaded from a geographic server.
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+*/
+package fr.cenra.rhomeo.api.data;
+
+import fr.cenra.rhomeo.api.Version;
+import java.time.ZonedDateTime;
+import java.util.HashMap;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableMap;
+import javax.validation.constraints.NotNull;
+import org.apache.sis.util.ArgumentChecks;
+
+/**
+ * Contains all data from the seizure context :
+ * - Target Site
+ * - Input protocol
+ * - References versions
+ * - Additional user data
+ *
+ * @author Alexis Manin (Geomatys)
+ */
+public class DataContext {
+
+ private final Site site;
+ private final Protocol protocol;
+
+ private final SimpleObjectProperty dateProperty;
+
+ private final ObservableMap, Version> references;
+
+ private final ObservableMap userData;
+
+ public DataContext(Site site, Protocol protocol) {
+ ArgumentChecks.ensureNonNull("Input site", site);
+ ArgumentChecks.ensureNonNull("Source protocol", protocol);
+ this.site = site;
+ this.protocol = protocol;
+ dateProperty = new SimpleObjectProperty<>(ZonedDateTime.now());
+ references = FXCollections.observableMap(new HashMap<>());
+ userData = FXCollections.observableMap(new HashMap<>());
+ }
+
+ /**
+ *
+ * @return Protocol currently used for seizure.
+ */
+ @NotNull
+ public Protocol getProtocol() {
+ return protocol;
+ }
+
+ /**
+ *
+ * @return Site chosen for current session.
+ */
+ @NotNull
+ public Site getSite() {
+ return site;
+ }
+
+ /**
+ *
+ * @return References used for this seizure, along with the chosen version for
+ * each of them.
+ */
+ @NotNull
+ public ObservableMap, Version> getReferences() {
+ return references;
+ }
+
+ /**
+ *
+ * @return References used for this seizure, along with the chosen version for
+ * each of them.
+ */
+ @NotNull
+ public ObservableMap getUserData() {
+ return userData;
+ }
+ /**
+ *
+ * @return Creation date of this dataset.
+ */
+ public ZonedDateTime getDate() {
+ return dateProperty.get();
+ }
+
+ /**
+ * Set given date as creation date of this dataset.
+ * @param date The date to use as new creation date.
+ */
+ public void setDate(final ZonedDateTime date) {
+ dateProperty.set(date);
+ }
+}
diff --git a/core/src/main/java/fr/cenra/rhomeo/api/data/Dataset.java b/core/src/main/java/fr/cenra/rhomeo/api/data/Dataset.java
new file mode 100644
index 0000000..c17aaf7
--- /dev/null
+++ b/core/src/main/java/fr/cenra/rhomeo/api/data/Dataset.java
@@ -0,0 +1,589 @@
+/**
+ * Copyright © CENRA (2016)
+ *
+ * remi.clement@espaces-naturels.fr
+ *
+ * This software is a multi-platform and portable application based on
+ * the scientifical toolbox to monitor wetlands. With this toolbox it’s
+ * possible to calculate indicators «RhoMéO» to monitor quality,
+ * fonctionalities and urban and agricultural pressures of wetlands.
+ * Indicators are calculated using naturalist data entered and/or imported,
+ * and geographic data downloaded from a geographic server.
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+*/
+package fr.cenra.rhomeo.api.data;
+
+import fr.cenra.rhomeo.core.RhomeoCore;
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.MethodDescriptor;
+import java.lang.reflect.Method;
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Predicate;
+import java.util.logging.Level;
+import javafx.beans.Observable;
+import javafx.beans.property.Property;
+import javafx.beans.value.ChangeListener;
+import javafx.collections.FXCollections;
+import javafx.collections.ListChangeListener;
+import javafx.collections.ObservableList;
+import javafx.collections.ObservableSet;
+import javafx.collections.SetChangeListener;
+import javafx.collections.transformation.SortedList;
+import javafx.util.Callback;
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+import org.apache.sis.util.ArgumentChecks;
+
+/**
+ * Data filled or imported in application.
+ *
+ * IMPORTANT : Avoid modifying {@link #getItems() } list outside of FX thread,
+ * because UI could use filtered / sorted lists based on it.
+ *
+ * @author Alexis Manin (Geomatys)
+ * @param Type of statements pointed by this dataset.
+ */
+public class Dataset {
+
+ private final Protocol protocol;
+
+ /**
+ * Keep a set of computed tracking points to speed up research and updates.
+ *
+ * TODO : replace with a map whose key is the tracking point, and value is the count of attached statements.
+ */
+ private ObservableSet internalPoints;
+ /**
+ * List of tracking points exposed to user.
+ */
+ private ObservableList points;
+ /**
+ * Seized statements.
+ */
+ private final ObservableList items;
+
+ /**
+ * When an item date change, this listener update available tracking point list.
+ */
+ private final ChangeListener dateListener;
+ /**
+ * When an item name change, this listener update available tracking point list.
+ */
+ private final ChangeListener nameListener;
+ /**
+ * On a change in {@link #getItems() }, this listener check added/removed
+ * objects to update tracking point list.
+ */
+ private final TrackingPointListener tPointListener;
+ private SetToListListener mirroring;
+
+ public Dataset(final Protocol target) {
+ ArgumentChecks.ensureNonNull("Target protocol", target);
+ protocol = target;
+
+ final Callback extractor = createCallback();
+ if (extractor == null) {
+ items = FXCollections.observableArrayList();
+ } else {
+ items = FXCollections.observableArrayList(extractor);
+ }
+
+ dateListener = (obs, oldDate, newDate) -> {
+ if (obs instanceof Property) {
+ Object bean = ((Property)obs).getBean();
+ if (bean instanceof Statement) {
+ final String name = ((Statement)bean).getTrackingPoint();
+ if (name != null) {
+ if (oldDate != null) {
+ final TrackingPoint p = protocol.createTrackingPoint(name, oldDate);
+ if (getSubSet(p).isEmpty()) {
+ internalPoints.remove(p);
+ }
+ }
+ if (newDate != null) {
+ internalPoints.add(protocol.createTrackingPoint(name, newDate));
+ }
+ }
+ }
+ }
+ };
+
+ nameListener = (obs, oldName, newName) -> {
+ if (obs instanceof Property) {
+ Object bean = ((Property) obs).getBean();
+ if (bean instanceof Statement) {
+ final LocalDate date = ((Statement) bean).getDate();
+ if (date != null) {
+ if (oldName != null) {
+ final TrackingPoint p = protocol.createTrackingPoint(oldName, date);
+ if (getSubSet(p).isEmpty()) {
+ internalPoints.remove(p);
+ }
+ }
+ if (newName != null) {
+ internalPoints.add(protocol.createTrackingPoint(newName, date));
+ }
+ }
+ }
+ }
+ };
+
+ tPointListener = new TrackingPointListener();
+ }
+
+ /**
+ *
+ * @return List of associated data. Can be empty, but never null.
+ */
+ @NotNull
+ @Valid
+ public synchronized ObservableList getItems() {
+ return items;
+ }
+
+ @Valid
+ public Protocol getProtocol() {
+ return protocol;
+ }
+
+ private Callback createCallback() {
+ final ArrayList extractors = new ArrayList<>();
+ try {
+ final BeanInfo info = Introspector.getBeanInfo(protocol.getDataType(), Object.class);
+ MethodDescriptor[] descs = info.getMethodDescriptors();
+ for (final MethodDescriptor desc : descs) {
+ final Method method = desc.getMethod();
+ if (method.getParameterCount() < 1 && Observable.class.isAssignableFrom(method.getReturnType())) {
+ method.setAccessible(true);
+ extractors.add(method);
+ }
+ }
+ } catch (Exception e) {
+ RhomeoCore.LOGGER.log(Level.WARNING, "Cannot analyze datatype for protocol ".concat(protocol.getName()), e);
+ }
+
+ if (extractors.isEmpty()) {
+ return null;
+ }
+
+ return input -> {
+ final ArrayList