From 836a412a6d93debb9c980bd1d43a11c57e606fb0 Mon Sep 17 00:00:00 2001 From: lpoulin Date: Wed, 9 Oct 2024 15:06:56 +0200 Subject: [PATCH] version 1.1 --- build/release.sh | 141 ++ core/pom.xml | 167 ++ .../rhomeo/api/EditableIdentifiedObject.java | 93 + .../fr/cenra/rhomeo/api/IdentifiedObject.java | 88 + .../rhomeo/api/InternationalDescription.java | 123 + .../rhomeo/api/InternationalResource.java | 249 ++ .../java/fr/cenra/rhomeo/api/Version.java | 138 ++ .../rhomeo/api/annotations/RefersTo.java | 98 + .../rhomeo/api/data/AbstractProtocol.java | 133 ++ .../fr/cenra/rhomeo/api/data/DataContext.java | 132 + .../fr/cenra/rhomeo/api/data/Dataset.java | 589 +++++ .../cenra/rhomeo/api/data/ObjectWrapper.java | 56 + .../fr/cenra/rhomeo/api/data/Protocol.java | 104 + .../fr/cenra/rhomeo/api/data/Reference.java | 46 + .../rhomeo/api/data/ReferenceDescription.java | 54 + .../java/fr/cenra/rhomeo/api/data/Site.java | 66 + .../fr/cenra/rhomeo/api/data/Statement.java | 122 + .../cenra/rhomeo/api/data/TrackingPoint.java | 210 ++ .../rhomeo/api/data/TrackingPointFilter.java | 100 + .../fr/cenra/rhomeo/api/data/Warning.java | 51 + .../InternationalPreferenceKey.java | 106 + .../rhomeo/api/preferences/PasswordKey.java | 49 + .../api/preferences/PreferenceGroup.java | 86 + .../api/preferences/SimplePreferenceKey.java | 60 + .../UserPackagePreferenceGroup.java | 64 + .../rhomeo/api/process/AbstractIndicator.java | 128 + .../api/process/AdditionalProcessSpi.java | 69 + .../cenra/rhomeo/api/process/Indicator.java | 101 + .../fr/cenra/rhomeo/api/process/Process.java | 79 + .../rhomeo/api/process/ProcessContext.java | 214 ++ .../api/result/AbstractParametrableIndex.java | 122 + .../rhomeo/api/result/AdditionalValue.java | 48 + .../api/result/AdditionalValueMapper.java | 76 + .../api/result/DashboardResultItem.java | 124 + .../cenra/rhomeo/api/result/DefaultIndex.java | 112 + .../api/result/DefaultTrackingPointIndex.java | 107 + .../fr/cenra/rhomeo/api/result/Index.java | 71 + .../cenra/rhomeo/api/result/IndexMapper.java | 122 + .../fr/cenra/rhomeo/api/result/IndexSpi.java | 106 + .../api/result/IndicatorValuesByYearItem.java | 121 + .../rhomeo/api/result/TrackingPointIndex.java | 59 + .../rhomeo/api/ui/AdditionalResultSpi.java | 57 + .../rhomeo/api/ui/DashboardMenuItem.java | 59 + .../fr/cenra/rhomeo/api/ui/FilterTable.java | 58 + .../cenra/rhomeo/api/ui/FilterTableSpi.java | 56 + .../cenra/rhomeo/api/ui/PreferencePane.java | 70 + .../rhomeo/api/ui/ProtocolEditorSpi.java | 71 + .../cenra/rhomeo/api/ui/StatementEditor.java | 81 + .../rhomeo/api/ui/StatementEditorSpi.java | 65 + .../java/fr/cenra/rhomeo/core/BeanUtils.java | 98 + .../java/fr/cenra/rhomeo/core/CSVDecoder.java | 426 ++++ .../java/fr/cenra/rhomeo/core/CSVEncoder.java | 298 +++ .../java/fr/cenra/rhomeo/core/CSVMapper.java | 286 +++ .../cenra/rhomeo/core/CSVMappingBuilder.java | 79 + .../java/fr/cenra/rhomeo/core/RhomeoCore.java | 554 +++++ .../rhomeo/core/RhomeoRuntimeException.java | 58 + .../java/fr/cenra/rhomeo/core/Session.java | 533 +++++ .../rhomeo/core/TypedCSVMappingBuilder.java | 100 + .../fr/cenra/rhomeo/core/WorkflowStep.java | 55 + .../core/data/DashboardResultsManager.java | 560 +++++ .../rhomeo/core/data/DataContextManager.java | 178 ++ .../rhomeo/core/data/ReferenceManager.java | 508 ++++ .../rhomeo/core/data/TrackingPointValue.java | 75 + .../fr/cenra/rhomeo/core/data/UpdateInfo.java | 163 ++ .../cenra/rhomeo/core/data/county/County.java | 89 + .../core/data/county/CountyRepository.java | 255 ++ .../data/reference/FloreBassinReference.java | 140 ++ .../FloreBassinReferenceDescription.java | 72 + .../core/data/reference/GeoReferential.java | 325 +++ .../core/data/reference/GeoReferentials.java | 531 +++++ .../reference/OdonataDepartmentReference.java | 218 ++ ...OdonataDepartmentReferenceDescription.java | 75 + .../reference/OdonataHabitatReference.java | 208 ++ .../OdonataHabitatReferenceDescription.java | 75 + .../OrthopteraIndicatorReference.java | 245 ++ ...thopteraIndicatorReferenceDescription.java | 75 + .../rhomeo/core/data/reference/Taxref.java | 202 ++ .../data/reference/TaxrefDescription.java | 76 + .../data/site/DuplicatedKeyException.java | 55 + .../core/data/site/RhomeoRepository.java | 103 + .../cenra/rhomeo/core/data/site/SiteImpl.java | 229 ++ .../rhomeo/core/data/site/SiteRepository.java | 52 + .../core/data/site/SiteRepositoryImpl.java | 483 ++++ .../fr/cenra/rhomeo/core/list/CodeValue.java | 49 + .../cenra/rhomeo/core/list/HumidZoneType.java | 103 + .../rhomeo/core/list/OdonateZoneBio.java | 130 + .../rhomeo/core/list/OrthoptereZoneBio.java | 97 + .../fr/cenra/rhomeo/core/list/VonPost.java | 76 + .../core/preferences/ftp/FTPAccess.java | 206 ++ .../core/preferences/ftp/FTPPreferences.java | 75 + .../preferences/ftp/FTPPreferencesImpl.java | 188 ++ .../rhomeo/core/preferences/net/NetKey.java | 77 + .../core/preferences/net/NetPreferences.java | 172 ++ .../core/preferences/net/PassNetKey.java | 56 + .../rhomeo/core/result/ResultStorage.java | 341 +++ .../rhomeo/core/result/ResultWriter.java | 281 +++ .../core/result/SimpleLocationIndex.java | 71 + .../rhomeo/core/result/SimpleYearIndex.java | 81 + .../rhomeo/core/state/DatasetManager.java | 282 +++ .../rhomeo/core/state/ProcessManager.java | 305 +++ .../rhomeo/core/state/ResultManager.java | 270 +++ .../cenra/rhomeo/core/state/StateLoader.java | 47 + .../cenra/rhomeo/core/state/StateManager.java | 360 +++ .../rhomeo/core/state/StepStateManager.java | 82 + .../java/fr/cenra/rhomeo/core/util/AOC.java | 73 + .../rhomeo/core/util/EncryptionResult.java | 70 + .../cenra/rhomeo/core/util/ExportUtils.java | 686 ++++++ .../rhomeo/core/util/GeometryConverters.java | 99 + .../cenra/rhomeo/core/util/GeometryUtils.java | 87 + .../rhomeo/core/util/RelationResolver.java | 256 ++ .../rhomeo/core/util/RhomeoKmlWriter.java | 123 + .../rhomeo/core/util/SecretGenerator.java | 121 + .../core/util/SerializableDataContext.java | 194 ++ .../core/util/SimplePredicateChain.java | 92 + .../rhomeo/core/util/TemporalConverters.java | 319 +++ .../core/util/TrackingPointComparator.java | 69 + .../rhomeo/core/util/VersionDeserializer.java | 67 + .../rhomeo/core/util/VersionSerializer.java | 65 + .../core/util/ZonedDateTimeDeserializer.java | 73 + .../core/util/ZonedDateTimeSerializer.java | 66 + .../core/validation/ReferenceValidator.java | 154 ++ .../org.apache.sis.util.ObjectConverter | 8 + .../rhomeo/api/data/TrackingPoint.properties | 2 + .../rhomeo/core/data/county/DEPARTEMENT.dbf | Bin 0 -> 17186 bytes .../rhomeo/core/data/county/DEPARTEMENT.prj | 1 + .../rhomeo/core/data/county/DEPARTEMENT.shp | Bin 0 -> 3134040 bytes .../rhomeo/core/data/county/DEPARTEMENT.shx | Bin 0 -> 868 bytes .../rhomeo/core/data/site/SiteImpl.properties | 6 + .../core/preferences/ftp/FTPKey.properties | 8 + .../ftp/FTPPreferencesImpl.properties | 2 + .../core/preferences/net/NetKey.properties | 9 + .../preferences/net/NetPreferences.properties | 3 + .../preferences/net/PassNetKey.properties | 2 + .../rhomeo/core/preferences/net/defaultKey | 1 + .../rhomeo/core/preferences/net/defaultSR | 1 + .../fr/cenra/rhomeo/spring/spring-context.xml | 14 + .../java/fr/cenra/rhomeo/RhomeoTestCase.java | 85 + .../InternationalDescriptionTest.java | 72 + .../InternationalResourceTest.java | 103 + .../rhomeo/core/data/CSVMappingTest.java | 199 ++ .../cenra/rhomeo/core/data/DatasetTest.java | 111 + .../cenra/rhomeo/core/data/MockIndicator.java | 90 + .../cenra/rhomeo/core/data/MockProtocol.java | 81 + .../cenra/rhomeo/core/data/MockReference.java | 158 ++ .../core/data/MockReferenceDescription.java | 73 + .../cenra/rhomeo/core/data/MockStatement.java | 82 + .../core/data/ReferenceManagerTest.java | 163 ++ .../rhomeo/core/data/UpdateInfoTest.java | 81 + .../rhomeo/core/data/county/CountyTest.java | 79 + .../core/data/site/SiteRepositoryTest.java | 191 ++ .../preferences/ftp/FTPPreferencesTest.java | 128 + .../core/preferences/ftp/MockFTPClient.java | 234 ++ .../preferences/ftp/MockFTPPreferences.java | 136 ++ .../core/result/MockAnnualIndexSpi.java | 142 ++ .../core/result/MockLocationIndexSpi.java | 150 ++ .../core/state/StateManagementTest.java | 228 ++ .../rhomeo/core/util/ExportUtilsTest.java | 123 + .../rhomeo/core/util/SecretGeneratorTest.java | 60 + .../core/util/TemporalConvertersTest.java | 124 + .../validation/SimpleValidationTest.java | 89 + ...st$InternationalDescriptionImpl.properties | 6 + ...InternationalDescriptionImpl_en.properties | 6 + ...eTest$InternationalResourceImpl.properties | 13 + ...st$InternationalResourceImpl_en.properties | 13 + .../fr/cenra/rhomeo/core/data/site/sites.cpg | 1 + .../fr/cenra/rhomeo/core/data/site/sites.dbf | Bin 0 -> 2322 bytes .../fr/cenra/rhomeo/core/data/site/sites.fix | Bin 0 -> 25 bytes .../fr/cenra/rhomeo/core/data/site/sites.prj | 1 + .../fr/cenra/rhomeo/core/data/site/sites.qix | Bin 0 -> 64 bytes .../fr/cenra/rhomeo/core/data/site/sites.shp | Bin 0 -> 252 bytes .../fr/cenra/rhomeo/core/data/site/sites.shx | Bin 0 -> 108 bytes .../cenra/rhomeo/core/data/site/sitesVide.dbf | Bin 0 -> 2322 bytes .../cenra/rhomeo/core/data/site/sitesVide.prj | 1 + .../cenra/rhomeo/core/data/site/sitesVide.qpj | 1 + .../cenra/rhomeo/core/data/site/sitesVide.shp | Bin 0 -> 252 bytes .../cenra/rhomeo/core/data/site/sitesVide.shx | Bin 0 -> 108 bytes .../fr/cenra/rhomeo/core/data/update.json | 13 + core/src/test/resources/logback.xml | 16 + desktop/pom.xml | 116 + desktop/src/main/deploy/additional/CLUF | 550 +++++ .../src/main/deploy/package/linux/Rhomeo.png | Bin 0 -> 5230 bytes .../main/deploy/package/macosx/Rhomeo.icns | Bin 0 -> 24230 bytes .../main/deploy/package/windows/Rhomeo.ico | Bin 0 -> 32094 bytes .../main/java/fr/cenra/rhomeo/DocManager.java | 122 + .../main/java/fr/cenra/rhomeo/Launcher.java | 511 ++++ .../src/main/java/fr/cenra/rhomeo/Rhomeo.java | 758 ++++++ .../cenra/rhomeo/fx/FXDashboardMenuPane.java | 1282 ++++++++++ .../fr/cenra/rhomeo/fx/FXDashboardPane.java | 256 ++ .../rhomeo/fx/FXDashboardResultsTable.java | 234 ++ .../fx/FXDefaultPreferenceGroupPane.java | 186 ++ .../rhomeo/fx/FXDefaultProcessingPane.java | 674 ++++++ .../cenra/rhomeo/fx/FXDefaultResultPane.java | 520 ++++ .../cenra/rhomeo/fx/FXFinalizationPane.java | 248 ++ .../rhomeo/fx/FXFullSpecificResultPane.java | 266 +++ .../cenra/rhomeo/fx/FXInitialDialogPane.java | 127 + .../java/fr/cenra/rhomeo/fx/FXMainPane.java | 158 ++ .../rhomeo/fx/FXProtocolReferencesPane.java | 273 +++ .../rhomeo/fx/FXRhomeoPreferencePane.java | 144 ++ .../rhomeo/fx/FXRhomeoReferencePane.java | 96 + .../fr/cenra/rhomeo/fx/FXRhomeoWizard.java | 526 ++++ .../fr/cenra/rhomeo/fx/FXSplashScreen.java | 60 + .../cenra/rhomeo/fx/GraphDashboardItem.java | 139 ++ .../cenra/rhomeo/fx/IndicatorSiteColumn.java | 299 +++ .../fx/MultiIndicatorsDashboardItem.java | 208 ++ .../AbstractCustomStatementEditor.java | 396 +++ .../fx/edition/AutoCommitableTableCell.java | 53 + .../fx/edition/ByNameAndDateFilter.java | 125 + .../fx/edition/CSVConfigurationPane.java | 282 +++ .../rhomeo/fx/edition/FXDatasetPane.java | 702 ++++++ .../rhomeo/fx/edition/FXFloreEditor.java | 160 ++ .../rhomeo/fx/edition/FXOrthopteraEditor.java | 79 + .../cenra/rhomeo/fx/edition/FXP07Editor.java | 87 + .../fx/edition/FXTrackingPointTable.java | 207 ++ .../cenra/rhomeo/fx/edition/ObjectTable.java | 192 ++ .../fr/cenra/rhomeo/fx/edition/P01Editor.java | 104 + .../fr/cenra/rhomeo/fx/edition/P04Editor.java | 222 ++ .../cenra/rhomeo/fx/edition/P04EditorSpi.java | 109 + .../fr/cenra/rhomeo/fx/edition/P06Editor.java | 161 ++ .../rhomeo/fx/edition/PropertyColumn.java | 728 ++++++ .../rhomeo/fx/edition/StatementTable.java | 60 + .../rhomeo/fx/p08/FXGeoReferentialTable.java | 282 +++ .../cenra/rhomeo/fx/p08/FXP08DatasetPane.java | 220 ++ .../cenra/rhomeo/fx/p08/FXP08ProcessPane.java | 310 +++ .../rhomeo/fx/p08/P08ProtocolEditorSpi.java | 88 + .../cenra/rhomeo/fx/p09/FXP09DatasetPane.java | 125 + .../cenra/rhomeo/fx/p09/FXP09ProcessPane.java | 383 +++ .../rhomeo/fx/p09/P09ProtocolEditorSpi.java | 88 + .../ConstraintViolationListCell.java | 83 + .../fx/validation/FXValidationPane.java | 259 ++ .../preferences/FXFTPConfiguration.java | 232 ++ .../cenra/rhomeo/preferences/csv/CSVKey.java | 77 + .../preferences/csv/CSVPreferences.java | 74 + .../gui/javafx/parameter/FXDateEditor.java | 109 + .../gui/javafx/util/ProgressMonitor.java | 388 +++ .../fr/cenra/rhomeo/ProgressMonitor.css | 58 + .../cenra/rhomeo/fx/FXDashboardMenuPane.fxml | 199 ++ .../rhomeo/fx/FXDashboardMenuPane.properties | 32 + .../fr/cenra/rhomeo/fx/FXDashboardPane.fxml | 43 + .../rhomeo/fx/FXDashboardPane.properties | 5 + .../fx/FXDefaultPreferenceGroupPane.css | 5 + .../rhomeo/fx/FXDefaultProcessingPane.fxml | 73 + .../fx/FXDefaultProcessingPane.properties | 12 + .../cenra/rhomeo/fx/FXDefaultResultPane.css | 18 + .../cenra/rhomeo/fx/FXDefaultResultPane.fxml | 74 + .../rhomeo/fx/FXDefaultResultPane.properties | 8 + .../fr/cenra/rhomeo/fx/FXFinalizationPane.css | 22 + .../cenra/rhomeo/fx/FXFinalizationPane.fxml | 49 + .../rhomeo/fx/FXFinalizationPane.properties | 7 + .../cenra/rhomeo/fx/FXInitialDialogPane.fxml | 91 + .../rhomeo/fx/FXInitialDialogPane.properties | 6 + .../fr/cenra/rhomeo/fx/FXMainPane.fxml | 53 + .../fr/cenra/rhomeo/fx/FXMainPane.properties | 5 + .../rhomeo/fx/FXProtocolReferencesPane.css | 44 + .../rhomeo/fx/FXProtocolReferencesPane.fxml | 19 + .../rhomeo/fx/FXRhomeoPreferencePane.css | 5 + .../fx/FXRhomeoPreferencePane.properties | 5 + .../rhomeo/fx/FXRhomeoReferencePane.fxml | 60 + .../fx/FXRhomeoReferencePane.properties | 3 + .../fr/cenra/rhomeo/fx/FXRhomeoWizard.fxml | 91 + .../cenra/rhomeo/fx/FXRhomeoWizard.properties | 7 + .../fr/cenra/rhomeo/fx/FXSplashScreen.fxml | 57 + .../fr/cenra/rhomeo/fx/Typologie_Habitats.pdf | Bin 0 -> 429068 bytes .../fx/edition/CSVConfigurationPane.fxml | 66 + .../fx/edition/DefaultStatementEditor.fxml | 78 + .../edition/DefaultStatementEditor.properties | 9 + .../cenra/rhomeo/fx/edition/FXDatasetPane.css | 55 + .../rhomeo/fx/edition/FXDatasetPane.fxml | 82 + .../fx/edition/FXDatasetPane.properties | 23 + .../rhomeo/fx/edition/FXFloreEditor.fxml | 65 + .../fx/edition/FXFloreEditor.properties | 7 + .../rhomeo/fx/edition/FXOrthopteraEditor.fxml | 61 + .../cenra/rhomeo/fx/edition/FXP07Editor.fxml | 61 + .../fr/cenra/rhomeo/fx/edition/P01Editor.fxml | 72 + .../rhomeo/fx/edition/P01Editor.properties | 9 + .../fr/cenra/rhomeo/fx/edition/P04Editor.fxml | 43 + .../fr/cenra/rhomeo/fx/edition/P06Editor.fxml | 65 + .../rhomeo/fx/edition/P06Editor.properties | 7 + .../cenra/rhomeo/fx/p08/FXP08DatasetPane.fxml | 30 + .../cenra/rhomeo/fx/p08/FXP08ProcessPane.fxml | 40 + .../resources/fr/cenra/rhomeo/fx/p08/u74.png | Bin 0 -> 3429 bytes .../cenra/rhomeo/fx/p09/FXP09DatasetPane.fxml | 29 + .../cenra/rhomeo/fx/p09/FXP09ProcessPane.fxml | 68 + .../fx/validation/FXValidationPane.fxml | 47 + .../fx/validation/FXValidationPane.properties | 7 + .../cenra/rhomeo/fx/zones_biogeo_odonates.pdf | Bin 0 -> 2179252 bytes .../rhomeo/fx/zones_biogeo_orthopteres.pdf | Bin 0 -> 2284709 bytes .../fr/cenra/rhomeo/images/Thumbs.db | Bin 0 -> 120832 bytes .../fr/cenra/rhomeo/images/img-accueil.png | Bin 0 -> 23728 bytes .../resources/fr/cenra/rhomeo/images/logo.png | Bin 0 -> 1932 bytes .../fr/cenra/rhomeo/images/not_published.png | Bin 0 -> 977 bytes .../resources/fr/cenra/rhomeo/images/p01.png | Bin 0 -> 5560 bytes .../resources/fr/cenra/rhomeo/images/p02.png | Bin 0 -> 24717 bytes .../resources/fr/cenra/rhomeo/images/p03.png | Bin 0 -> 5560 bytes .../resources/fr/cenra/rhomeo/images/p04.png | Bin 0 -> 11558 bytes .../resources/fr/cenra/rhomeo/images/p05.png | Bin 0 -> 17628 bytes .../resources/fr/cenra/rhomeo/images/p06.png | Bin 0 -> 11332 bytes .../resources/fr/cenra/rhomeo/images/p07.png | Bin 0 -> 11332 bytes .../resources/fr/cenra/rhomeo/images/p08.png | Bin 0 -> 4509 bytes .../resources/fr/cenra/rhomeo/images/p09.png | Bin 0 -> 6414 bytes .../fr/cenra/rhomeo/images/splashscreen.png | Bin 0 -> 38684 bytes .../preferences/FXFTPConfiguration.fxml | 86 + ...nceGroup$ReferencePreferenceKey.properties | 3 + .../ReferencePreferenceGroup.properties | 3 + .../rhomeo/preferences/csv/CSVKey.properties | 9 + .../preferences/csv/CSVPreferences.properties | 3 + .../fr/cenra/rhomeo/splashscreen.css | 25 + .../main/resources/fr/cenra/rhomeo/theme.css | 318 +++ desktop/src/main/resources/logback.xml | 36 + .../gui/javafx/internal/Bundle.properties | 320 +++ .../gui/javafx/internal/Bundle_en.properties | 320 +++ .../gui/javafx/internal/Bundle_fr.properties | 320 +++ ...nceGroup$ReferencePreferenceKey.properties | 3 + ...Group$ReferencePreferenceKey_en.properties | 3 + protocol/pom.xml | 52 + .../cenra/rhomeo/protocol/TaxonOperator.java | 209 ++ .../p01/AnnualAverageSoilHumidity.java | 97 + .../p01/AnnualPointAverageSoilHumidity.java | 98 + .../AnnualPointAverageSoilHumidityIndex.java | 68 + .../fr/cenra/rhomeo/protocol/p01/I01.java | 447 ++++ .../fr/cenra/rhomeo/protocol/p01/P01.java | 58 + .../protocol/p01/PedologyStatement.java | 843 +++++++ .../rhomeo/protocol/p01/list/Abundance.java | 75 + .../protocol/p01/list/Adhesiveness.java | 75 + .../protocol/p01/list/AlterationMO.java | 75 + .../rhomeo/protocol/p01/list/Chroma.java | 86 + .../rhomeo/protocol/p01/list/Clarity.java | 77 + .../cenra/rhomeo/protocol/p01/list/Color.java | 78 + .../rhomeo/protocol/p01/list/Compacity.java | 75 + .../rhomeo/protocol/p01/list/Friability.java | 75 + .../rhomeo/protocol/p01/list/Humidity.java | 75 + .../rhomeo/protocol/p01/list/Limits.java | 75 + .../rhomeo/protocol/p01/list/Plasticity.java | 75 + .../rhomeo/protocol/p01/list/RawElements.java | 75 + .../cenra/rhomeo/protocol/p01/list/Roots.java | 75 + .../cenra/rhomeo/protocol/p01/list/Shape.java | 75 + .../cenra/rhomeo/protocol/p01/list/Size.java | 75 + .../rhomeo/protocol/p01/list/Stains.java | 74 + .../rhomeo/protocol/p01/list/Structure.java | 84 + .../rhomeo/protocol/p01/list/Texture.java | 75 + .../rhomeo/protocol/p02/FloreStatement.java | 187 ++ .../fr/cenra/rhomeo/protocol/p02/I02.java | 107 + .../rhomeo/protocol/p02/I02I06Process.java | 314 +++ .../fr/cenra/rhomeo/protocol/p02/I06.java | 107 + .../fr/cenra/rhomeo/protocol/p02/I08.java | 287 +++ .../fr/cenra/rhomeo/protocol/p02/P02.java | 69 + .../cenra/rhomeo/protocol/p02/P02Wrapper.java | 140 ++ .../cenra/rhomeo/protocol/p02/ValueType.java | 58 + .../p02/additional/AdditionalProcess.java | 165 ++ .../rhomeo/protocol/p02/additional/Value.java | 197 ++ .../protocol/p02/additional/ValueMapper.java | 93 + .../p02/additional/ValueTableSpi.java | 107 + .../p02/index/AnnualFloreEngorgement.java | 94 + .../index/AnnualFloreEngorgementPoint.java | 96 + .../AnnualFloreEngorgementPointIndex.java | 62 + .../p02/index/AnnualFloreFertile.java | 94 + .../p02/index/AnnualFloreFertilePoint.java | 95 + .../index/AnnualFloreFertilePointIndex.java | 62 + .../p02/index/AnnualFloreQuality.java | 94 + .../p02/index/AnnualFloreQualityPoint.java | 95 + .../index/AnnualFloreQualityPointIndex.java | 62 + .../protocol/p02/list/AbundanceFlore.java | 81 + .../protocol/p02/list/PhysionomyFlore.java | 87 + .../validation/DeterminedFloreSpecies.java | 116 + .../fr/cenra/rhomeo/protocol/p03/I03.java | 213 ++ .../fr/cenra/rhomeo/protocol/p03/P03.java | 112 + .../rhomeo/protocol/p03/P03Statement.java | 92 + .../cenra/rhomeo/protocol/p03/PointTable.java | 232 ++ .../rhomeo/protocol/p03/PointTableSpi.java | 70 + .../p03/index/AbstractP03IndexSpi.java | 91 + .../protocol/p03/index/FirstDecileSpi.java | 74 + .../protocol/p03/index/FirstQuartileSpi.java | 74 + .../protocol/p03/index/LastDecileSpi.java | 74 + .../rhomeo/protocol/p03/index/MaxSpi.java | 74 + .../rhomeo/protocol/p03/index/MedianeSpi.java | 74 + .../rhomeo/protocol/p03/index/MinSpi.java | 74 + .../protocol/p03/index/ThirdQuartileSpi.java | 74 + .../protocol/p03/validation/DataCoverage.java | 78 + .../p03/validation/DataCoverageValidator.java | 98 + .../protocol/p03/validation/SinglePoint.java | 64 + .../p03/validation/SinglePointValidator.java | 86 + .../protocol/p04/AbstractHabitatNbSpi.java | 78 + .../rhomeo/protocol/p04/AcidIndexSpi.java | 102 + .../rhomeo/protocol/p04/CotIndexSpi.java | 102 + .../rhomeo/protocol/p04/HumineIndexSpi.java | 103 + .../fr/cenra/rhomeo/protocol/p04/I04.java | 142 ++ .../cenra/rhomeo/protocol/p04/I04NbSpi.java | 60 + .../fr/cenra/rhomeo/protocol/p04/I07.java | 142 ++ .../cenra/rhomeo/protocol/p04/I07NbSpi.java | 60 + .../fr/cenra/rhomeo/protocol/p04/P04.java | 58 + .../rhomeo/protocol/p04/P04Statement.java | 176 ++ .../rhomeo/protocol/p04/P04Validation.java | 64 + .../rhomeo/protocol/p04/P04Validator.java | 60 + .../cenra/rhomeo/protocol/p04/PtIndexSpi.java | 102 + .../protocol/p05/AbstractP05Indicator.java | 170 ++ .../AnnualPointRateEnvironmentHumidity.java | 99 + ...nualPointRateEnvironmentHumidityIndex.java | 65 + .../AnnualPointRateSedimentaryDynamics.java | 98 + ...nualPointRateSedimentaryDynamicsIndex.java | 64 + .../p05/AnnualRateEnvironmentHumidity.java | 97 + .../p05/AnnualRateSedimentaryDynamics.java | 96 + .../fr/cenra/rhomeo/protocol/p05/I05.java | 107 + .../fr/cenra/rhomeo/protocol/p05/I09.java | 103 + .../protocol/p05/OrthopteraStatement.java | 145 ++ .../fr/cenra/rhomeo/protocol/p05/P05.java | 78 + .../cenra/rhomeo/protocol/p05/P05Wrapper.java | 132 + .../cenra/rhomeo/protocol/p05/Processor.java | 219 ++ .../p06/AnnualNbOfExpectedSpecies.java | 105 + .../p06/AnnualRatePopulationIntegrity.java | 97 + .../protocol/p06/AnnualRateRichness.java | 112 + .../cenra/rhomeo/protocol/p06/Behavior.java | 79 + .../rhomeo/protocol/p06/BehaviorSpi.java | 63 + .../fr/cenra/rhomeo/protocol/p06/Habitat.java | 115 + .../fr/cenra/rhomeo/protocol/p06/I10.java | 821 +++++++ .../rhomeo/protocol/p06/OdonataStatement.java | 227 ++ .../fr/cenra/rhomeo/protocol/p06/P06.java | 78 + .../cenra/rhomeo/protocol/p06/P06Wrapper.java | 140 ++ .../rhomeo/protocol/p06/RichnessProcess.java | 162 ++ .../p06/validation/BehaviorCoverage.java | 70 + .../validation/BehaviorCoverageValidator.java | 188 ++ .../rhomeo/protocol/p07/AbstractI11Spi.java | 87 + .../protocol/p07/AmpByCountyDescription.java | 72 + .../protocol/p07/AmpSpeciesByCounty.java | 81 + .../fr/cenra/rhomeo/protocol/p07/I11.java | 127 + .../fr/cenra/rhomeo/protocol/p07/I2PASpi.java | 66 + .../rhomeo/protocol/p07/I2paProcess.java | 222 ++ .../fr/cenra/rhomeo/protocol/p07/P07.java | 61 + .../rhomeo/protocol/p07/P07Statement.java | 123 + .../cenra/rhomeo/protocol/p07/P07Wrapper.java | 136 ++ .../fr/cenra/rhomeo/protocol/p07/SBSpi.java | 66 + .../fr/cenra/rhomeo/protocol/p07/SRSpi.java | 66 + .../fr/cenra/rhomeo/protocol/p07/Shf.java | 68 + .../rhomeo/protocol/p07/ShfDescription.java | 72 + .../rhomeo/protocol/p07/SimpsonProcess.java | 148 ++ .../cenra/rhomeo/protocol/p07/SimpsonSpi.java | 66 + .../rhomeo/protocol/p07/StenoProcess.java | 223 ++ .../fr/cenra/rhomeo/protocol/p08/I12.java | 121 + .../cenra/rhomeo/protocol/p08/I12Process.java | 356 +++ .../fr/cenra/rhomeo/protocol/p08/P08.java | 59 + .../rhomeo/protocol/p08/P08Statement.java | 60 + .../p08/index/AbstractP08IndexSpi.java | 84 + .../rhomeo/protocol/p08/index/ArtifBV.java | 81 + .../rhomeo/protocol/p08/index/ArtifSite.java | 82 + .../rhomeo/protocol/p08/index/DenseBV.java | 77 + .../rhomeo/protocol/p08/index/DenseSite.java | 76 + .../rhomeo/protocol/p08/index/PDenseBV.java | 76 + .../rhomeo/protocol/p08/index/PDenseSite.java | 76 + .../rhomeo/protocol/p08/index/TDenseBV.java | 77 + .../rhomeo/protocol/p08/index/TDenseSite.java | 77 + .../rhomeo/protocol/p08/index/UrbaBV.java | 81 + .../rhomeo/protocol/p08/index/UrbaSite.java | 81 + .../fr/cenra/rhomeo/protocol/p09/I13.java | 97 + .../cenra/rhomeo/protocol/p09/I13Process.java | 412 ++++ .../cenra/rhomeo/protocol/p09/Impacting.java | 100 + .../fr/cenra/rhomeo/protocol/p09/P09.java | 67 + .../rhomeo/protocol/p09/P09Statement.java | 60 + .../rhomeo/protocol/p09/index/AgriBV.java | 102 + .../rhomeo/protocol/p09/index/AgriSite.java | 102 + .../validation/DeterminedSpecies.java | 136 ++ .../validation/DifferenciableSpecies.java | 117 + .../protocol/validation/IndicatorTaxon.java | 167 ++ .../AnnualPointAverageSoilHumidity.properties | 6 + .../fr/cenra/rhomeo/protocol/p01/P01.pdf | Bin 0 -> 1247959 bytes .../protocol/p01/PedologyStatement.properties | 50 + .../rhomeo/protocol/p01/readme.additional | 19 + .../protocol/p02/FloreStatement.properties | 16 + .../fr/cenra/rhomeo/protocol/p02/P02.pdf | Bin 0 -> 1685241 bytes .../AnnualFloreEngorgementPoint.properties | 3 + .../index/AnnualFloreFertilePoint.properties | 3 + .../index/AnnualFloreQualityPoint.properties | 3 + .../rhomeo/protocol/p02/readme.additional | 3 + .../fr/cenra/rhomeo/protocol/p03/P03.pdf | Bin 0 -> 1684559 bytes .../protocol/p03/P03Statement.properties | 10 + .../fr/cenra/rhomeo/protocol/p04/P04.pdf | Bin 0 -> 1109168 bytes .../protocol/p04/P04Statement.properties | 12 + ...ualPointRateEnvironmentHumidity.properties | 3 + ...ualPointRateSedimentaryDynamics.properties | 4 + .../p05/OrthopteraStatement.properties | 10 + .../fr/cenra/rhomeo/protocol/p05/P05.pdf | Bin 0 -> 1057432 bytes .../p06/AnnualNbOfExpectedSpecies.properties | 4 + .../p06/AnnualRateRichness.properties | 3 + .../protocol/p06/OdonataStatement.properties | 14 + .../fr/cenra/rhomeo/protocol/p06/P06.pdf | Bin 0 -> 4294829 bytes .../rhomeo/protocol/p06/readme.additional | 3 + .../fr/cenra/rhomeo/protocol/p07/P07.pdf | Bin 0 -> 1247457 bytes .../protocol/p07/P07Statement.properties | 11 + .../rhomeo/protocol/p07/readme.additional | 4 + .../fr/cenra/rhomeo/protocol/p08/P08.pdf | Bin 0 -> 1130299 bytes .../fr/cenra/rhomeo/protocol/p09/P09.pdf | Bin 0 -> 1141085 bytes .../cenra/rhomeo/protocol/IndicatorsTest.java | 135 ++ .../fr/cenra/rhomeo/protocol/PointResult.java | 62 + .../cenra/rhomeo/protocol/ProtocolsTest.java | 132 + .../cenra/rhomeo/protocol/StatementsTest.java | 84 + .../cenra/rhomeo/protocol/TestUtilities.java | 85 + .../fr/cenra/rhomeo/protocol/YearResult.java | 72 + .../fr/cenra/rhomeo/protocol/p01/I01Test.java | 2119 +++++++++++++++++ .../protocol/p01/PedologyStatementTest.java | 134 ++ .../p05/AbstractP05IndicatorTest.java | 132 + .../fr/cenra/rhomeo/protocol/p05/I05Test.java | 278 +++ .../fr/cenra/rhomeo/protocol/p05/I09Test.java | 284 +++ .../p05/OrthopteraReferenceTestHelper.java | 55 + .../protocol/p05/OrthopteraStatementTest.java | 81 + .../rhomeo/protocol/p05/TaxrefTestHelper.java | 48 + .../fr/cenra/rhomeo/protocol/p06/I10Test.java | 2063 ++++++++++++++++ .../OdonataHabitatReferenceTestHelper.java | 85 + .../protocol/p06/OdonataStatementTest.java | 85 + .../rhomeo/protocol/p01/bidonnes_2011.csv | 33 + .../rhomeo/protocol/p01/chautagne_2012.csv | 26 + .../rhomeo/protocol/p01/pointResults.csv | 18 + .../cenra/rhomeo/protocol/p01/yearResults.csv | 3 + ...ultP05-1_AnnualRateEnvironmentHumidity.csv | 2 + ...ultP05-1_AnnualRateSedimentaryDynamics.csv | 2 + .../cenra/rhomeo/protocol/p05/testP05-1.csv | 32 + .../resultP06-7_AnnualNbOfExpectedSpecies.csv | 5 + ...ultP06-7_AnnualRatePopulationIntegrity.csv | 5 + .../p06/resultP06-7_AnnualRateRichness.csv | 5 + .../resultP06-8_AnnualNbOfExpectedSpecies.csv | 4 + ...ultP06-8_AnnualRatePopulationIntegrity.csv | 4 + .../p06/resultP06-8_AnnualRateRichness.csv | 4 + .../resultP06-9_AnnualNbOfExpectedSpecies.csv | 4 + ...ultP06-9_AnnualRatePopulationIntegrity.csv | 4 + .../p06/resultP06-9_AnnualRateRichness.csv | 4 + .../cenra/rhomeo/protocol/p06/testP06-7.csv | 67 + .../cenra/rhomeo/protocol/p06/testP06-8.csv | 182 ++ .../cenra/rhomeo/protocol/p06/testP06-9.csv | 267 +++ rhomeo-server/README | 20 + rhomeo-server/constellation/Dockerfile | 41 + rhomeo-server/constellation/setenv.sh | 3 + rhomeo-server/cstl-data/Dockerfile | 11 + rhomeo-server/db/Dockerfile | 57 + rhomeo-server/db/entrypoint-postgres.sh | 65 + rhomeo-server/docker-compose.yml | 50 + rhomeo-server/ftp/Dockerfile | 32 + rhomeo-server/ftp/supervisord.conf | 12 + rhomeo-server/ftp/userpass | 2 + rhomeo-server/ftp/vsftpd.conf | 162 ++ rhomeo-server/run-compose.sh | 10 + 536 files changed, 63922 insertions(+) create mode 100644 build/release.sh create mode 100644 core/pom.xml create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/EditableIdentifiedObject.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/IdentifiedObject.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/InternationalDescription.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/InternationalResource.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/Version.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/annotations/RefersTo.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/data/AbstractProtocol.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/data/DataContext.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/data/Dataset.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/data/ObjectWrapper.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/data/Protocol.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/data/Reference.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/data/ReferenceDescription.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/data/Site.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/data/Statement.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/data/TrackingPoint.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/data/TrackingPointFilter.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/data/Warning.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/preferences/InternationalPreferenceKey.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/preferences/PasswordKey.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/preferences/PreferenceGroup.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/preferences/SimplePreferenceKey.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/preferences/UserPackagePreferenceGroup.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/process/AbstractIndicator.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/process/AdditionalProcessSpi.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/process/Indicator.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/process/Process.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/process/ProcessContext.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/result/AbstractParametrableIndex.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/result/AdditionalValue.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/result/AdditionalValueMapper.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/result/DashboardResultItem.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/result/DefaultIndex.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/result/DefaultTrackingPointIndex.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/result/Index.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/result/IndexMapper.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/result/IndexSpi.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/result/IndicatorValuesByYearItem.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/result/TrackingPointIndex.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/ui/AdditionalResultSpi.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/ui/DashboardMenuItem.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/ui/FilterTable.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/ui/FilterTableSpi.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/ui/PreferencePane.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/ui/ProtocolEditorSpi.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/ui/StatementEditor.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/api/ui/StatementEditorSpi.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/BeanUtils.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/CSVDecoder.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/CSVEncoder.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/CSVMapper.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/CSVMappingBuilder.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/RhomeoCore.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/RhomeoRuntimeException.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/Session.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/TypedCSVMappingBuilder.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/WorkflowStep.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/data/DashboardResultsManager.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/data/DataContextManager.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/data/ReferenceManager.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/data/TrackingPointValue.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/data/UpdateInfo.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/data/county/County.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/data/county/CountyRepository.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/data/reference/FloreBassinReference.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/data/reference/FloreBassinReferenceDescription.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/data/reference/GeoReferential.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/data/reference/GeoReferentials.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/data/reference/OdonataDepartmentReference.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/data/reference/OdonataDepartmentReferenceDescription.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/data/reference/OdonataHabitatReference.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/data/reference/OdonataHabitatReferenceDescription.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/data/reference/OrthopteraIndicatorReference.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/data/reference/OrthopteraIndicatorReferenceDescription.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/data/reference/Taxref.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/data/reference/TaxrefDescription.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/data/site/DuplicatedKeyException.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/data/site/RhomeoRepository.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/data/site/SiteImpl.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/data/site/SiteRepository.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/data/site/SiteRepositoryImpl.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/list/CodeValue.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/list/HumidZoneType.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/list/OdonateZoneBio.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/list/OrthoptereZoneBio.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/list/VonPost.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/preferences/ftp/FTPAccess.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/preferences/ftp/FTPPreferences.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/preferences/ftp/FTPPreferencesImpl.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/preferences/net/NetKey.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/preferences/net/NetPreferences.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/preferences/net/PassNetKey.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/result/ResultStorage.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/result/ResultWriter.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/result/SimpleLocationIndex.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/result/SimpleYearIndex.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/state/DatasetManager.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/state/ProcessManager.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/state/ResultManager.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/state/StateLoader.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/state/StateManager.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/state/StepStateManager.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/util/AOC.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/util/EncryptionResult.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/util/ExportUtils.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/util/GeometryConverters.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/util/GeometryUtils.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/util/RelationResolver.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/util/RhomeoKmlWriter.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/util/SecretGenerator.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/util/SerializableDataContext.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/util/SimplePredicateChain.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/util/TemporalConverters.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/util/TrackingPointComparator.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/util/VersionDeserializer.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/util/VersionSerializer.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/util/ZonedDateTimeDeserializer.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/util/ZonedDateTimeSerializer.java create mode 100644 core/src/main/java/fr/cenra/rhomeo/core/validation/ReferenceValidator.java create mode 100644 core/src/main/resources/META-INF/services/org.apache.sis.util.ObjectConverter create mode 100644 core/src/main/resources/fr/cenra/rhomeo/api/data/TrackingPoint.properties create mode 100644 core/src/main/resources/fr/cenra/rhomeo/core/data/county/DEPARTEMENT.dbf create mode 100644 core/src/main/resources/fr/cenra/rhomeo/core/data/county/DEPARTEMENT.prj create mode 100644 core/src/main/resources/fr/cenra/rhomeo/core/data/county/DEPARTEMENT.shp create mode 100644 core/src/main/resources/fr/cenra/rhomeo/core/data/county/DEPARTEMENT.shx create mode 100644 core/src/main/resources/fr/cenra/rhomeo/core/data/site/SiteImpl.properties create mode 100644 core/src/main/resources/fr/cenra/rhomeo/core/preferences/ftp/FTPKey.properties create mode 100644 core/src/main/resources/fr/cenra/rhomeo/core/preferences/ftp/FTPPreferencesImpl.properties create mode 100644 core/src/main/resources/fr/cenra/rhomeo/core/preferences/net/NetKey.properties create mode 100644 core/src/main/resources/fr/cenra/rhomeo/core/preferences/net/NetPreferences.properties create mode 100644 core/src/main/resources/fr/cenra/rhomeo/core/preferences/net/PassNetKey.properties create mode 100644 core/src/main/resources/fr/cenra/rhomeo/core/preferences/net/defaultKey create mode 100644 core/src/main/resources/fr/cenra/rhomeo/core/preferences/net/defaultSR create mode 100644 core/src/main/resources/fr/cenra/rhomeo/spring/spring-context.xml create mode 100644 core/src/test/java/fr/cenra/rhomeo/RhomeoTestCase.java create mode 100644 core/src/test/java/fr/cenra/rhomeo/api/international/InternationalDescriptionTest.java create mode 100644 core/src/test/java/fr/cenra/rhomeo/api/international/InternationalResourceTest.java create mode 100644 core/src/test/java/fr/cenra/rhomeo/core/data/CSVMappingTest.java create mode 100644 core/src/test/java/fr/cenra/rhomeo/core/data/DatasetTest.java create mode 100644 core/src/test/java/fr/cenra/rhomeo/core/data/MockIndicator.java create mode 100644 core/src/test/java/fr/cenra/rhomeo/core/data/MockProtocol.java create mode 100644 core/src/test/java/fr/cenra/rhomeo/core/data/MockReference.java create mode 100644 core/src/test/java/fr/cenra/rhomeo/core/data/MockReferenceDescription.java create mode 100644 core/src/test/java/fr/cenra/rhomeo/core/data/MockStatement.java create mode 100644 core/src/test/java/fr/cenra/rhomeo/core/data/ReferenceManagerTest.java create mode 100644 core/src/test/java/fr/cenra/rhomeo/core/data/UpdateInfoTest.java create mode 100644 core/src/test/java/fr/cenra/rhomeo/core/data/county/CountyTest.java create mode 100644 core/src/test/java/fr/cenra/rhomeo/core/data/site/SiteRepositoryTest.java create mode 100644 core/src/test/java/fr/cenra/rhomeo/core/preferences/ftp/FTPPreferencesTest.java create mode 100644 core/src/test/java/fr/cenra/rhomeo/core/preferences/ftp/MockFTPClient.java create mode 100644 core/src/test/java/fr/cenra/rhomeo/core/preferences/ftp/MockFTPPreferences.java create mode 100644 core/src/test/java/fr/cenra/rhomeo/core/result/MockAnnualIndexSpi.java create mode 100644 core/src/test/java/fr/cenra/rhomeo/core/result/MockLocationIndexSpi.java create mode 100644 core/src/test/java/fr/cenra/rhomeo/core/state/StateManagementTest.java create mode 100644 core/src/test/java/fr/cenra/rhomeo/core/util/ExportUtilsTest.java create mode 100644 core/src/test/java/fr/cenra/rhomeo/core/util/SecretGeneratorTest.java create mode 100644 core/src/test/java/fr/cenra/rhomeo/core/util/TemporalConvertersTest.java create mode 100644 core/src/test/java/fr/cenra/rhomeo/validation/SimpleValidationTest.java create mode 100644 core/src/test/resources/fr/cenra/rhomeo/api/international/InternationalDescriptionTest$InternationalDescriptionImpl.properties create mode 100644 core/src/test/resources/fr/cenra/rhomeo/api/international/InternationalDescriptionTest$InternationalDescriptionImpl_en.properties create mode 100644 core/src/test/resources/fr/cenra/rhomeo/api/international/InternationalResourceTest$InternationalResourceImpl.properties create mode 100644 core/src/test/resources/fr/cenra/rhomeo/api/international/InternationalResourceTest$InternationalResourceImpl_en.properties create mode 100644 core/src/test/resources/fr/cenra/rhomeo/core/data/site/sites.cpg create mode 100644 core/src/test/resources/fr/cenra/rhomeo/core/data/site/sites.dbf create mode 100644 core/src/test/resources/fr/cenra/rhomeo/core/data/site/sites.fix create mode 100644 core/src/test/resources/fr/cenra/rhomeo/core/data/site/sites.prj create mode 100644 core/src/test/resources/fr/cenra/rhomeo/core/data/site/sites.qix create mode 100644 core/src/test/resources/fr/cenra/rhomeo/core/data/site/sites.shp create mode 100644 core/src/test/resources/fr/cenra/rhomeo/core/data/site/sites.shx create mode 100644 core/src/test/resources/fr/cenra/rhomeo/core/data/site/sitesVide.dbf create mode 100644 core/src/test/resources/fr/cenra/rhomeo/core/data/site/sitesVide.prj create mode 100644 core/src/test/resources/fr/cenra/rhomeo/core/data/site/sitesVide.qpj create mode 100644 core/src/test/resources/fr/cenra/rhomeo/core/data/site/sitesVide.shp create mode 100644 core/src/test/resources/fr/cenra/rhomeo/core/data/site/sitesVide.shx create mode 100644 core/src/test/resources/fr/cenra/rhomeo/core/data/update.json create mode 100644 core/src/test/resources/logback.xml create mode 100644 desktop/pom.xml create mode 100644 desktop/src/main/deploy/additional/CLUF create mode 100644 desktop/src/main/deploy/package/linux/Rhomeo.png create mode 100644 desktop/src/main/deploy/package/macosx/Rhomeo.icns create mode 100644 desktop/src/main/deploy/package/windows/Rhomeo.ico create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/DocManager.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/Launcher.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/Rhomeo.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/FXDashboardMenuPane.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/FXDashboardPane.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/FXDashboardResultsTable.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/FXDefaultPreferenceGroupPane.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/FXDefaultProcessingPane.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/FXDefaultResultPane.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/FXFinalizationPane.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/FXFullSpecificResultPane.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/FXInitialDialogPane.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/FXMainPane.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/FXProtocolReferencesPane.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/FXRhomeoPreferencePane.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/FXRhomeoReferencePane.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/FXRhomeoWizard.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/FXSplashScreen.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/GraphDashboardItem.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/IndicatorSiteColumn.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/MultiIndicatorsDashboardItem.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/edition/AbstractCustomStatementEditor.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/edition/AutoCommitableTableCell.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/edition/ByNameAndDateFilter.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/edition/CSVConfigurationPane.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/edition/FXDatasetPane.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/edition/FXFloreEditor.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/edition/FXOrthopteraEditor.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/edition/FXP07Editor.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/edition/FXTrackingPointTable.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/edition/ObjectTable.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/edition/P01Editor.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/edition/P04Editor.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/edition/P04EditorSpi.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/edition/P06Editor.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/edition/PropertyColumn.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/edition/StatementTable.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/p08/FXGeoReferentialTable.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/p08/FXP08DatasetPane.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/p08/FXP08ProcessPane.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/p08/P08ProtocolEditorSpi.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/p09/FXP09DatasetPane.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/p09/FXP09ProcessPane.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/p09/P09ProtocolEditorSpi.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/validation/ConstraintViolationListCell.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/fx/validation/FXValidationPane.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/preferences/FXFTPConfiguration.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/preferences/csv/CSVKey.java create mode 100644 desktop/src/main/java/fr/cenra/rhomeo/preferences/csv/CSVPreferences.java create mode 100644 desktop/src/main/java/org/geotoolkit/gui/javafx/parameter/FXDateEditor.java create mode 100644 desktop/src/main/java/org/geotoolkit/gui/javafx/util/ProgressMonitor.java create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/ProgressMonitor.css create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDashboardMenuPane.fxml create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDashboardMenuPane.properties create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDashboardPane.fxml create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDashboardPane.properties create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDefaultPreferenceGroupPane.css create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDefaultProcessingPane.fxml create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDefaultProcessingPane.properties create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDefaultResultPane.css create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDefaultResultPane.fxml create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDefaultResultPane.properties create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/FXFinalizationPane.css create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/FXFinalizationPane.fxml create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/FXFinalizationPane.properties create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/FXInitialDialogPane.fxml create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/FXInitialDialogPane.properties create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/FXMainPane.fxml create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/FXMainPane.properties create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/FXProtocolReferencesPane.css create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/FXProtocolReferencesPane.fxml create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/FXRhomeoPreferencePane.css create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/FXRhomeoPreferencePane.properties create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/FXRhomeoReferencePane.fxml create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/FXRhomeoReferencePane.properties create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/FXRhomeoWizard.fxml create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/FXRhomeoWizard.properties create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/FXSplashScreen.fxml create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/Typologie_Habitats.pdf create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/edition/CSVConfigurationPane.fxml create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/edition/DefaultStatementEditor.fxml create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/edition/DefaultStatementEditor.properties create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/edition/FXDatasetPane.css create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/edition/FXDatasetPane.fxml create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/edition/FXDatasetPane.properties create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/edition/FXFloreEditor.fxml create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/edition/FXFloreEditor.properties create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/edition/FXOrthopteraEditor.fxml create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/edition/FXP07Editor.fxml create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/edition/P01Editor.fxml create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/edition/P01Editor.properties create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/edition/P04Editor.fxml create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/edition/P06Editor.fxml create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/edition/P06Editor.properties create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/p08/FXP08DatasetPane.fxml create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/p08/FXP08ProcessPane.fxml create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/p08/u74.png create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/p09/FXP09DatasetPane.fxml create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/p09/FXP09ProcessPane.fxml create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/validation/FXValidationPane.fxml create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/validation/FXValidationPane.properties create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/zones_biogeo_odonates.pdf create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/fx/zones_biogeo_orthopteres.pdf create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/images/Thumbs.db create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/images/img-accueil.png create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/images/logo.png create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/images/not_published.png create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/images/p01.png create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/images/p02.png create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/images/p03.png create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/images/p04.png create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/images/p05.png create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/images/p06.png create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/images/p07.png create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/images/p08.png create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/images/p09.png create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/images/splashscreen.png create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/preferences/FXFTPConfiguration.fxml create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/preferences/ReferencePreferenceGroup$ReferencePreferenceKey.properties create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/preferences/ReferencePreferenceGroup.properties create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/preferences/csv/CSVKey.properties create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/preferences/csv/CSVPreferences.properties create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/splashscreen.css create mode 100644 desktop/src/main/resources/fr/cenra/rhomeo/theme.css create mode 100644 desktop/src/main/resources/logback.xml create mode 100644 desktop/src/main/resources/org/geotoolkit/gui/javafx/internal/Bundle.properties create mode 100644 desktop/src/main/resources/org/geotoolkit/gui/javafx/internal/Bundle_en.properties create mode 100644 desktop/src/main/resources/org/geotoolkit/gui/javafx/internal/Bundle_fr.properties create mode 100644 desktop/src/test/resources/fr/cenra/rhomeo/preferences/ReferencePreferenceGroup$ReferencePreferenceKey.properties create mode 100644 desktop/src/test/resources/fr/cenra/rhomeo/preferences/ReferencePreferenceGroup$ReferencePreferenceKey_en.properties create mode 100644 protocol/pom.xml create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/TaxonOperator.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p01/AnnualAverageSoilHumidity.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p01/AnnualPointAverageSoilHumidity.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p01/AnnualPointAverageSoilHumidityIndex.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p01/I01.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p01/P01.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p01/PedologyStatement.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p01/list/Abundance.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p01/list/Adhesiveness.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p01/list/AlterationMO.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p01/list/Chroma.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p01/list/Clarity.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p01/list/Color.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p01/list/Compacity.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p01/list/Friability.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p01/list/Humidity.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p01/list/Limits.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p01/list/Plasticity.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p01/list/RawElements.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p01/list/Roots.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p01/list/Shape.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p01/list/Size.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p01/list/Stains.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p01/list/Structure.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p01/list/Texture.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p02/FloreStatement.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p02/I02.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p02/I02I06Process.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p02/I06.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p02/I08.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p02/P02.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p02/P02Wrapper.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p02/ValueType.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p02/additional/AdditionalProcess.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p02/additional/Value.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p02/additional/ValueMapper.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p02/additional/ValueTableSpi.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p02/index/AnnualFloreEngorgement.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p02/index/AnnualFloreEngorgementPoint.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p02/index/AnnualFloreEngorgementPointIndex.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p02/index/AnnualFloreFertile.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p02/index/AnnualFloreFertilePoint.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p02/index/AnnualFloreFertilePointIndex.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p02/index/AnnualFloreQuality.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p02/index/AnnualFloreQualityPoint.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p02/index/AnnualFloreQualityPointIndex.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p02/list/AbundanceFlore.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p02/list/PhysionomyFlore.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p02/validation/DeterminedFloreSpecies.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p03/I03.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p03/P03.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p03/P03Statement.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p03/PointTable.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p03/PointTableSpi.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p03/index/AbstractP03IndexSpi.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p03/index/FirstDecileSpi.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p03/index/FirstQuartileSpi.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p03/index/LastDecileSpi.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p03/index/MaxSpi.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p03/index/MedianeSpi.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p03/index/MinSpi.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p03/index/ThirdQuartileSpi.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p03/validation/DataCoverage.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p03/validation/DataCoverageValidator.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p03/validation/SinglePoint.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p03/validation/SinglePointValidator.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p04/AbstractHabitatNbSpi.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p04/AcidIndexSpi.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p04/CotIndexSpi.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p04/HumineIndexSpi.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p04/I04.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p04/I04NbSpi.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p04/I07.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p04/I07NbSpi.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p04/P04.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p04/P04Statement.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p04/P04Validation.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p04/P04Validator.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p04/PtIndexSpi.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p05/AbstractP05Indicator.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p05/AnnualPointRateEnvironmentHumidity.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p05/AnnualPointRateEnvironmentHumidityIndex.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p05/AnnualPointRateSedimentaryDynamics.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p05/AnnualPointRateSedimentaryDynamicsIndex.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p05/AnnualRateEnvironmentHumidity.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p05/AnnualRateSedimentaryDynamics.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p05/I05.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p05/I09.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p05/OrthopteraStatement.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p05/P05.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p05/P05Wrapper.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p05/Processor.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p06/AnnualNbOfExpectedSpecies.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p06/AnnualRatePopulationIntegrity.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p06/AnnualRateRichness.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p06/Behavior.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p06/BehaviorSpi.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p06/Habitat.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p06/I10.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p06/OdonataStatement.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p06/P06.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p06/P06Wrapper.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p06/RichnessProcess.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p06/validation/BehaviorCoverage.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p06/validation/BehaviorCoverageValidator.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p07/AbstractI11Spi.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p07/AmpByCountyDescription.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p07/AmpSpeciesByCounty.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p07/I11.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p07/I2PASpi.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p07/I2paProcess.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p07/P07.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p07/P07Statement.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p07/P07Wrapper.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p07/SBSpi.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p07/SRSpi.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p07/Shf.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p07/ShfDescription.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p07/SimpsonProcess.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p07/SimpsonSpi.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p07/StenoProcess.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p08/I12.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p08/I12Process.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p08/P08.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p08/P08Statement.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p08/index/AbstractP08IndexSpi.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p08/index/ArtifBV.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p08/index/ArtifSite.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p08/index/DenseBV.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p08/index/DenseSite.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p08/index/PDenseBV.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p08/index/PDenseSite.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p08/index/TDenseBV.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p08/index/TDenseSite.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p08/index/UrbaBV.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p08/index/UrbaSite.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p09/I13.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p09/I13Process.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p09/Impacting.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p09/P09.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p09/P09Statement.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p09/index/AgriBV.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/p09/index/AgriSite.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/validation/DeterminedSpecies.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/validation/DifferenciableSpecies.java create mode 100644 protocol/src/main/java/fr/cenra/rhomeo/protocol/validation/IndicatorTaxon.java create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p01/AnnualPointAverageSoilHumidity.properties create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p01/P01.pdf create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p01/PedologyStatement.properties create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p01/readme.additional create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p02/FloreStatement.properties create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p02/P02.pdf create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p02/index/AnnualFloreEngorgementPoint.properties create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p02/index/AnnualFloreFertilePoint.properties create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p02/index/AnnualFloreQualityPoint.properties create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p02/readme.additional create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p03/P03.pdf create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p03/P03Statement.properties create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p04/P04.pdf create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p04/P04Statement.properties create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p05/AnnualPointRateEnvironmentHumidity.properties create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p05/AnnualPointRateSedimentaryDynamics.properties create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p05/OrthopteraStatement.properties create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p05/P05.pdf create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p06/AnnualNbOfExpectedSpecies.properties create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p06/AnnualRateRichness.properties create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p06/OdonataStatement.properties create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p06/P06.pdf create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p06/readme.additional create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p07/P07.pdf create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p07/P07Statement.properties create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p07/readme.additional create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p08/P08.pdf create mode 100644 protocol/src/main/resources/fr/cenra/rhomeo/protocol/p09/P09.pdf create mode 100644 protocol/src/test/java/fr/cenra/rhomeo/protocol/IndicatorsTest.java create mode 100644 protocol/src/test/java/fr/cenra/rhomeo/protocol/PointResult.java create mode 100644 protocol/src/test/java/fr/cenra/rhomeo/protocol/ProtocolsTest.java create mode 100644 protocol/src/test/java/fr/cenra/rhomeo/protocol/StatementsTest.java create mode 100644 protocol/src/test/java/fr/cenra/rhomeo/protocol/TestUtilities.java create mode 100644 protocol/src/test/java/fr/cenra/rhomeo/protocol/YearResult.java create mode 100644 protocol/src/test/java/fr/cenra/rhomeo/protocol/p01/I01Test.java create mode 100644 protocol/src/test/java/fr/cenra/rhomeo/protocol/p01/PedologyStatementTest.java create mode 100644 protocol/src/test/java/fr/cenra/rhomeo/protocol/p05/AbstractP05IndicatorTest.java create mode 100644 protocol/src/test/java/fr/cenra/rhomeo/protocol/p05/I05Test.java create mode 100644 protocol/src/test/java/fr/cenra/rhomeo/protocol/p05/I09Test.java create mode 100644 protocol/src/test/java/fr/cenra/rhomeo/protocol/p05/OrthopteraReferenceTestHelper.java create mode 100644 protocol/src/test/java/fr/cenra/rhomeo/protocol/p05/OrthopteraStatementTest.java create mode 100644 protocol/src/test/java/fr/cenra/rhomeo/protocol/p05/TaxrefTestHelper.java create mode 100644 protocol/src/test/java/fr/cenra/rhomeo/protocol/p06/I10Test.java create mode 100644 protocol/src/test/java/fr/cenra/rhomeo/protocol/p06/OdonataHabitatReferenceTestHelper.java create mode 100644 protocol/src/test/java/fr/cenra/rhomeo/protocol/p06/OdonataStatementTest.java create mode 100644 protocol/src/test/resources/fr/cenra/rhomeo/protocol/p01/bidonnes_2011.csv create mode 100644 protocol/src/test/resources/fr/cenra/rhomeo/protocol/p01/chautagne_2012.csv create mode 100644 protocol/src/test/resources/fr/cenra/rhomeo/protocol/p01/pointResults.csv create mode 100644 protocol/src/test/resources/fr/cenra/rhomeo/protocol/p01/yearResults.csv create mode 100644 protocol/src/test/resources/fr/cenra/rhomeo/protocol/p05/resultP05-1_AnnualRateEnvironmentHumidity.csv create mode 100644 protocol/src/test/resources/fr/cenra/rhomeo/protocol/p05/resultP05-1_AnnualRateSedimentaryDynamics.csv create mode 100644 protocol/src/test/resources/fr/cenra/rhomeo/protocol/p05/testP05-1.csv create mode 100644 protocol/src/test/resources/fr/cenra/rhomeo/protocol/p06/resultP06-7_AnnualNbOfExpectedSpecies.csv create mode 100644 protocol/src/test/resources/fr/cenra/rhomeo/protocol/p06/resultP06-7_AnnualRatePopulationIntegrity.csv create mode 100644 protocol/src/test/resources/fr/cenra/rhomeo/protocol/p06/resultP06-7_AnnualRateRichness.csv create mode 100644 protocol/src/test/resources/fr/cenra/rhomeo/protocol/p06/resultP06-8_AnnualNbOfExpectedSpecies.csv create mode 100644 protocol/src/test/resources/fr/cenra/rhomeo/protocol/p06/resultP06-8_AnnualRatePopulationIntegrity.csv create mode 100644 protocol/src/test/resources/fr/cenra/rhomeo/protocol/p06/resultP06-8_AnnualRateRichness.csv create mode 100644 protocol/src/test/resources/fr/cenra/rhomeo/protocol/p06/resultP06-9_AnnualNbOfExpectedSpecies.csv create mode 100644 protocol/src/test/resources/fr/cenra/rhomeo/protocol/p06/resultP06-9_AnnualRatePopulationIntegrity.csv create mode 100644 protocol/src/test/resources/fr/cenra/rhomeo/protocol/p06/resultP06-9_AnnualRateRichness.csv create mode 100644 protocol/src/test/resources/fr/cenra/rhomeo/protocol/p06/testP06-7.csv create mode 100644 protocol/src/test/resources/fr/cenra/rhomeo/protocol/p06/testP06-8.csv create mode 100644 protocol/src/test/resources/fr/cenra/rhomeo/protocol/p06/testP06-9.csv create mode 100644 rhomeo-server/README create mode 100644 rhomeo-server/constellation/Dockerfile create mode 100644 rhomeo-server/constellation/setenv.sh create mode 100644 rhomeo-server/cstl-data/Dockerfile create mode 100644 rhomeo-server/db/Dockerfile create mode 100644 rhomeo-server/db/entrypoint-postgres.sh create mode 100644 rhomeo-server/docker-compose.yml create mode 100644 rhomeo-server/ftp/Dockerfile create mode 100644 rhomeo-server/ftp/supervisord.conf create mode 100644 rhomeo-server/ftp/userpass create mode 100644 rhomeo-server/ftp/vsftpd.conf create mode 100644 rhomeo-server/run-compose.sh 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 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 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 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 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[] 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 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 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 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 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 result = new ArrayList<>(extractors.size()); + for (int i = 0 ; i < extractors.size() ; i++) { + try { + result.add((Observable) extractors.get(i).invoke(input)); + } catch (ReflectiveOperationException e) { + RhomeoCore.LOGGER.log(Level.WARNING, "Cannot extract a property !", e); + } + } + + return result.toArray(new Observable[result.size()]); + }; + } + + @NotNull + public synchronized ObservableList getTrackingPoints() { + if(points==null) { + final HashSet tmpSet = new HashSet<>(); + if (items != null) { + String name; + LocalDate date; + for (final Statement statement : items) { + name = statement.getTrackingPoint(); + date = statement.getDate(); + if (name != null && statement.getDate() != null) { + final TrackingPoint p = protocol.createTrackingPoint(name, date); + p.setRemarks(statement.getRemarks()); + tmpSet.add(p); + } + } + } + + internalPoints = FXCollections.synchronizedObservableSet(FXCollections.observableSet(tmpSet)); + points = FXCollections.observableArrayList(tmpSet); + removeListeners(); + addListeners(); + } + return FXCollections.unmodifiableObservableList(points); + } + + /** + * Query an unmodifiable view of the items contained in this dataset matching + * the given tracking point. All modifications in {@link #getItems() } will + * be mirrored in the returned view. + * + * If the given point is null, a list of all statements which are not bound + * to any point is returned. + * + * @param filter The tracking point to get data for. + * @return items matching a given tracking point (contained in it). + */ + @NotNull + public synchronized ObservableList getSubSet(final TrackingPoint... filter) { + return getSubSet(filter == null || (filter.length == 1 && filter[0] == null)? null : Arrays.asList(filter)); + } + + public synchronized ObservableList getSubSet(Collection filter) { + final Predicate predicate; + if (filter == null || filter.isEmpty()) { + predicate = input -> { + return input.getTrackingPoint() == null || input.getDate() == null; + }; + } else if (filter.size() == 1) { + final TrackingPoint tp = filter.iterator().next(); + final String filterName = tp.getName(); + final LocalDate filterStart = tp.getYearStart().minusDays(1); + final LocalDate filterEnd = tp.getYearEnd().plusDays(1); + predicate = input -> { + return filterName.equals(input.getTrackingPoint()) + && input.getDate() != null + && input.getDate().isAfter(filterStart) + && input.getDate().isBefore(filterEnd); + }; + } else { + // Remove doublons + if (!(filter instanceof Set)) { + filter = new HashSet(filter); + } + + // Multiple tracking point filter. For each name, we build a set of + // date range, for each tracking with the same name but different year range. + final HashMap> filters = new HashMap<>(filter.size()); + for (final TrackingPoint tp : filter) { + filters.computeIfAbsent(tp.getName(), str -> new ArrayList()) + .add(new LocalDate[]{tp.getYearStart().minusDays(1), tp.getYearEnd().plusDays(1)}); + } + + predicate = input -> { + if (input.getTrackingPoint() == null || input.getDate() == null) + return false; + + final List dates = filters.get(input.getTrackingPoint()); + if (dates == null) + return false; + + for (final LocalDate[] range : dates) { + if (input.getDate().isAfter(range[0]) && + input.getDate().isBefore(range[1])) + return true; + } + + return false; + }; + } + return getItems().filtered(predicate); + } + + public boolean deletePoints(final Collection points) { + final ArrayList defCopy = new ArrayList<>(points); + return items.removeIf(item -> { + for (final TrackingPoint tp : defCopy) { + if (tp.getName().equals(item.getTrackingPoint()) && + item.getDate() != null && + (item.getDate().isEqual(tp.getYearStart()) || item.getDate().isAfter(tp.getYearStart())) && + (item.getDate().isEqual(tp.getYearEnd()) || item.getDate().isBefore(tp.getYearEnd()))) { + return true; + } + } + return false; + }); + } + + /** + * Remove listeners in charge of updating tracking point list. + */ + private void removeListeners() { + if (mirroring != null && internalPoints != null) { + internalPoints.removeListener(mirroring); + } + + if (items != null) { + items.removeListener(tPointListener); + items.forEach(item -> { + item.dateProperty().removeListener(dateListener); + item.trackingPointProperty().removeListener(nameListener); + }); + } + } + + /** + * Add listeners on items and tracking points. The aim is to check statement + * changes to update tracking point list accordingly. + */ + private void addListeners() { + if (items != null && points != null) { + mirroring = new SetToListListener(points); + internalPoints.addListener(mirroring); + items.forEach(item -> { + item.dateProperty().addListener(dateListener); + item.trackingPointProperty().addListener(nameListener); + }); + items.addListener(tPointListener); + } + } + + /** + * Check changes on statement list, to update available tracking points + * according to dataset content. + */ + private class TrackingPointListener implements ListChangeListener { + + @Override + public void onChanged(Change c) { + final HashSet toRemove = new HashSet<>(); + final HashSet toAdd = new HashSet<>(); + + TrackingPoint point; + while (c.next()) { + if (c.wasRemoved()) { + for (Statement remitem : c.getRemoved()) { + remitem.dateProperty().removeListener(dateListener); + remitem.trackingPointProperty().removeListener(nameListener); + + point = createTrackingPoint(remitem); + if (point != null) { + toRemove.add(point); + } + } + } + + if (c.wasAdded()) { + for (Statement additem : c.getAddedSubList()) { + additem.dateProperty().addListener(dateListener); + additem.trackingPointProperty().addListener(nameListener); + + point = createTrackingPoint(additem); + if (point != null) { + toRemove.remove(point); + toAdd.add(point); + } + } + } + } + + // If there's still statements referencing removed statement tracking points, we keep them. + final Iterator it = toRemove.iterator(); + while (it.hasNext()) { + point = it.next(); + if (!getSubSet(point).isEmpty()) + it.remove(); + } + + internalPoints.removeAll(toRemove); + internalPoints.addAll(toAdd); + } + + private TrackingPoint createTrackingPoint(final Statement statement) { + final String name = statement.getTrackingPoint(); + final LocalDate date = statement.getDate(); + if (name != null && date != null) { + final TrackingPoint p = protocol.createTrackingPoint(name, date); + p.setRemarks(statement.getRemarks()); + return p; + } else { + return null; + } + } + } + + /** + * Mirrors changes happening in a set to the parameterised list. + */ + private class SetToListListener implements SetChangeListener { + + private final List destination; + + public SetToListListener(final List destination) { + this.destination = destination; + } + + @Override + public void onChanged(Change c) { + if (c.wasRemoved()) { + destination.remove(c.getElementRemoved()); + } else if (c.wasAdded()) { + destination.add(c.getElementAdded()); + } + } + } + + /** + * Search for the tracking point attached to given statement. + * @param data The statement to find parent tracking point for. + * @return A tracking point matching given parameter, or nothing. + */ + public Optional findPoint(final Statement data) { + if (data == null) + return Optional.empty(); + return findPoint(data.getTrackingPoint(), data.getDate()); + } + + /** + * Search for a tracking point whose name is equal to the given one, and validity + * period contains given date. + * @param name The name to get a tracking point for. + * @param date The date to get a tracking point for. + * @return A tracking point matching given parameters, or nothing. + */ + public Optional findPoint(String name, final LocalDate date) { + if (!items.isEmpty() && date != null && name != null && !(name = name.trim()).isEmpty()) { + final ObservableList tps = getTrackingPoints(); + if (!tps.isEmpty()) { + for (final TrackingPoint tp : tps) { + if (tp.getName().equals(name) && + (date.isAfter(tp.getYearStart()) || date.isEqual(tp.getYearStart())) && + (date.isBefore(tp.getYearEnd()) || date.isEqual(tp.getYearEnd()))) { + return Optional.of(tp); + } + } + } + } + + return Optional.empty(); + } + + public synchronized Map> groupByPoint() { + final List trackingPoints = getTrackingPoints().sorted((TrackingPoint o1, TrackingPoint o2) -> { + if (o1 == null) { + return o2 == null ? 0 : 1; + } else if (o2 == null) { + return -1; + } + + final int nameOrder = o1.getName().compareTo(o2.getName()); + if (nameOrder != 0) { + return nameOrder; + } + + return o1.getYear() - o2.getYear(); + }); + + final Map> statements = new HashMap<>(); + + final SortedList sortedSet = getItems().sorted((Comparator) ORDER_BY_POINT); + final Iterator tit = trackingPoints.iterator(); + final Iterator sit = sortedSet.iterator(); + if (tit.hasNext()) { + TrackingPoint tp = tit.next(); + Predicate predicate = new BelongsToTrackingPoint(tp); + ArrayList ptList = new ArrayList<>(); + statements.put(tp, ptList); + while (sit.hasNext()) { + final T st = sit.next(); + if (!predicate.test(st)) { + if (tit.hasNext()) { + tp = tit.next(); + predicate = new BelongsToTrackingPoint(tp); + ptList = new ArrayList<>(); + statements.put(tp, ptList); + } else { + break; + } + } + + ptList.add(st); + } + } + + return statements; + } + + /** + * Check if the given statement belongs to given tracking point. + * @param point The point to test + * @param statement The statement to test against input point. + * @return True if given statement belongs to given tracking point, false otherwise. + */ + public static boolean belongToPoint(final TrackingPoint point, final Statement statement) { + final LocalDate date = statement.getDate(); + if (date == null || statement.getTrackingPoint() == null) { + return false; + } + + return (point.getName().equals(statement.getTrackingPoint()) + && (date.isAfter(point.getYearStart()) || date.isEqual(point.getYearStart())) + && (date.isBefore(point.getYearEnd()) || date.isEqual(point.getYearEnd()))); + } + + private static class BelongsToTrackingPoint implements Predicate { + final String name; + final LocalDate filterStart; + final LocalDate filterEnd; + + private BelongsToTrackingPoint(final TrackingPoint tp) { + name = tp.getName(); + filterStart = tp.getYearStart().minusDays(1); + filterEnd = tp.getYearEnd().plusDays(1); + } + + @Override + public boolean test(Statement t) { + return name.equals(t.getTrackingPoint()) + && t.getDate() != null + && t.getDate().isAfter(filterStart) + && t.getDate().isBefore(filterEnd); + } + } + + private static Comparator ORDER_BY_POINT = (s1, s2) -> { + final String t1 = s1.getTrackingPoint(); + final String t2 = s2.getTrackingPoint(); + + int comp; + if (t1 == t2) + comp = 0; + else if (t1 != null) + comp = t1.compareTo(t2); + else + comp = 1; + + if (comp == 0) { + final LocalDate d1 = s1.getDate(); + final LocalDate d2 = s2.getDate(); + if (d1 != d2) { + if (d1 == null) + comp = 1; + else + comp = d1.compareTo(d2); + } + } + + return comp; + }; +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/data/ObjectWrapper.java b/core/src/main/java/fr/cenra/rhomeo/api/data/ObjectWrapper.java new file mode 100644 index 0000000..ca7ca2a --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/data/ObjectWrapper.java @@ -0,0 +1,56 @@ +/** + * 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 java.util.function.Function; + +/** + * A simple function designed to wrap an object of type I into another of type + * O. + * + * @author Alexis Manin (Geomatys) + * @param Type of the objects to wrap (parameter). + * @param Type of the wrapper object (returned). + */ +public interface ObjectWrapper extends Function { + + Class getInputType(); + + Class getOutputType(); +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/data/Protocol.java b/core/src/main/java/fr/cenra/rhomeo/api/data/Protocol.java new file mode 100644 index 0000000..61b3a07 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/data/Protocol.java @@ -0,0 +1,104 @@ +/** + * 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.IdentifiedObject; +import fr.cenra.rhomeo.api.process.Indicator; +import java.time.LocalDate; +import java.util.Set; +import javax.validation.constraints.NotNull; + +/** + * Defines a scientific protocol designed to hold a specific set of measures. + * + * @author Alexis Manin (Geomatys) + */ +public interface Protocol extends IdentifiedObject, Comparable { + + /** + * + * @return {@link Statement} class defining measure content. Must not be null. + */ + @NotNull + Class getDataType(); + + /** + * + * @return Set of reference types needed to complete seizure / processing of + * the protocol measures. Should never be null, but can be empty. + */ + @NotNull + Set getReferenceTypes(); + + /** + * + * @param site A site to analyze. + * @return True if we can process {@link Indicator}s associated to the current + * protocol with given site. False otherwise. + */ + boolean isCompatible(Site site); + + /** + * Create a tracking point with the provided name, whose year contains the + * given date. This method is useful when you've got a {@link Statement}, + * and want to know which stating year owns it. + * + * @param name The name of the tracking point. + * @param statementDate A date to get matching year for. + * @return A new tracking point. Never null. + */ + default TrackingPoint createTrackingPoint(final String name, final LocalDate statementDate) { + return new TrackingPoint(name, statementDate.getYear()); + } + + /** + * Create a new tracking point named as specified, on the given year. A year + * is not always a calendar year. It can go between two chosen dates. + * + * Ex : You can specify that year 2015 goes from September, 1st of 2014 to + * August, 31th of 2015 + * + * @param name The name to set on the new tracking point. + * @param year The year to affect to the tracking point. + * @return A new tracking point. Never null. + */ + default TrackingPoint createTrackingPoint(final String name, final int year) { + return new TrackingPoint(name, year); + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/data/Reference.java b/core/src/main/java/fr/cenra/rhomeo/api/data/Reference.java new file mode 100644 index 0000000..818dc55 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/data/Reference.java @@ -0,0 +1,46 @@ +/** + * 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; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public interface Reference { +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/data/ReferenceDescription.java b/core/src/main/java/fr/cenra/rhomeo/api/data/ReferenceDescription.java new file mode 100644 index 0000000..8838dd3 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/data/ReferenceDescription.java @@ -0,0 +1,54 @@ +/** + * 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.IdentifiedObject; + +/** + * Contains generic information about a specific {@link Reference} implementation. + * There should be a unique instance for each type of reference available in application. + * + * @author Alexis Manin (Geomatys) + * @param The type of reference described by this object. + */ +public interface ReferenceDescription extends IdentifiedObject { + + Class getReferenceType(); + +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/data/Site.java b/core/src/main/java/fr/cenra/rhomeo/api/data/Site.java new file mode 100644 index 0000000..b1e0ece --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/data/Site.java @@ -0,0 +1,66 @@ +/** + * 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 com.vividsolutions.jts.geom.MultiPolygon; +import fr.cenra.rhomeo.api.IdentifiedObject; + +import javax.validation.constraints.NotNull; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public interface Site extends IdentifiedObject, Comparable { + + @NotNull + MultiPolygon getGeometry(); + + String getCountyCode(); + + String getReferent(); + + String getOrganization(); + + String getZoneType(); + + String getOdonateType(); + + String getOrthoptereType(); +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/data/Statement.java b/core/src/main/java/fr/cenra/rhomeo/api/data/Statement.java new file mode 100644 index 0000000..f09c309 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/data/Statement.java @@ -0,0 +1,122 @@ +/** + * 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.InternationalDescription; +import fr.cenra.rhomeo.api.InternationalResource; +import java.time.LocalDate; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; +import javax.validation.constraints.NotNull; + +/** + * Represents an entry in a {@link Dataset}. It's an entity containing several + * physical measures. + * + * Note : we force overriding of {@link #equals(java.lang.Object) } and {@link #hashCode() + * } methods, because statements will be compared in application to remove + * potential doublons. + * + * @author Alexis Manin (Geomatys) + */ +public abstract class Statement implements InternationalResource, InternationalDescription { + + protected final SimpleStringProperty trackingPoint = new SimpleStringProperty(this, "trackingPoint"); + + protected final SimpleObjectProperty date = new SimpleObjectProperty<>(this, "date"); + + protected final StringProperty remarksProperty = new SimpleStringProperty(); + + protected Statement() {} + + protected Statement(final String trackingPoint, final LocalDate date) { + this.trackingPoint.set(trackingPoint); + this.date.set(date); + } + + protected Statement(final String trackingPoint, final LocalDate date, final String remarks) { + this(trackingPoint, date); + this.remarksProperty.set(remarks); + } + + @NotNull + public LocalDate getDate() { + return date.get(); + } + + public void setDate(final LocalDate date) { + this.date.set(date); + } + + public ObjectProperty dateProperty() { + return date; + } + + public String getTrackingPoint() { + return trackingPoint.get(); + } + + public void setTrackingPoint(final String tPoint) { + trackingPoint.set(tPoint); + } + + public StringProperty trackingPointProperty() { + return trackingPoint; + } + + public String getRemarks() { + return remarksProperty.get(); + } + + public void setRemarks(final String remarks) { + this.remarksProperty.set(remarks); + } + + public StringProperty remarksProperty() { + return remarksProperty; + } + + @Override + public abstract boolean equals(Object obj); + + @Override + public abstract int hashCode(); +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/data/TrackingPoint.java b/core/src/main/java/fr/cenra/rhomeo/api/data/TrackingPoint.java new file mode 100644 index 0000000..123e214 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/data/TrackingPoint.java @@ -0,0 +1,210 @@ +/** + * 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.IdentifiedObject; +import fr.cenra.rhomeo.api.InternationalResource; +import fr.cenra.rhomeo.core.RhomeoCore; +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.time.LocalDate; +import java.util.Collection; +import java.util.Collections; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; +import org.apache.sis.util.ArgumentChecks; + +/** + * A point on which a series of statements have been done. The point is + * identified by a name and the year on which statements have been done. + * + * It's an (almost) immutable object, because its just a reflection of + * statements name and date property, to use grouping. Moreover, introducing + * points with null year would be problematic for computing work flow. The only + * editable attribute is the remarks property, as it's not a defining data. + * + * @author Alexis Manin (Geomatys) + */ +public final class TrackingPoint implements IdentifiedObject, InternationalResource, Externalizable { + + protected static final long serialVersionUID = 1L; + + private String name; + + private int year; + + private LocalDate yearStart; + private LocalDate yearEnd; + + private final StringProperty remarks; + + public TrackingPoint() { + this("default", 2016); + } + + public TrackingPoint(final String name, final int year) { + this(name, year, null, null); + } + + public TrackingPoint(final String name, final LocalDate yearStart, final LocalDate yearEnd) { + this( + name, + // Try to find a valid year from input dates. + yearEnd != null ? yearEnd.getYear() : yearStart != null ? yearStart.getYear() : LocalDate.now().getYear(), + yearStart, + yearEnd + ); + } + + public TrackingPoint(String name, final int year, LocalDate yearStart, LocalDate yearEnd) { + if (name == null || (name = name.trim()).isEmpty()) { + throw new IllegalArgumentException("Given name is blank !"); + } + this.name = name; + this.remarks = new SimpleStringProperty(); + + if (yearStart == null) { + if (yearEnd != null) { + yearStart = yearEnd.minusYears(1).plusDays(1); + } else { + yearStart = LocalDate.of(year, 01, 01); + } + } + + if (yearEnd == null) { + yearEnd = yearStart.plusYears(1).minusDays(1); + } + + if (yearStart.isBefore(yearEnd)) { + this.yearStart = yearStart; + this.yearEnd = yearEnd; + } else { + this.yearStart = yearEnd; + this.yearEnd = yearStart; + } + + ArgumentChecks.ensureBetween("Year", this.yearStart.getYear(), this.yearEnd.getYear(), year); + this.year = year; + } + + /** + * + * @return Year associated to this point. + */ + public int getYear() { + return year; + } + + @Override + public int hashCode() { + int hash = 5; + hash = 71 * hash + this.year; + hash = 71 * hash + this.name.hashCode(); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final TrackingPoint other = (TrackingPoint) obj; + return this.year == other.year && this.name.equals(other.name); + } + + @Override + public String toString() { + return new StringBuilder("TrackingPoint{ name=").append(name).append(" year=").append(year).append(" }").toString(); + } + + public LocalDate getYearStart() { + return yearStart; + } + + public LocalDate getYearEnd() { + return yearEnd; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getRemarks() { + return remarks.get(); + } + + public void setRemarks(String remarks) { + this.remarks.set(remarks); + } + + public StringProperty remarksProperty() { + return remarks; + } + + @Override + public Collection getAlias() { + return Collections.EMPTY_SET; + } + + @Override + public void writeExternal(ObjectOutput out) throws IOException { + out.writeUTF(name); + out.writeInt(year); + RhomeoCore.writeDate(yearStart, out); + RhomeoCore.writeDate(yearEnd, out); + } + + @Override + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + name = in.readUTF(); + year = in.readInt(); + yearStart = RhomeoCore.readDate(in); + yearEnd = RhomeoCore.readDate(in); + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/data/TrackingPointFilter.java b/core/src/main/java/fr/cenra/rhomeo/api/data/TrackingPointFilter.java new file mode 100644 index 0000000..2008331 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/data/TrackingPointFilter.java @@ -0,0 +1,100 @@ +/** + * 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 java.io.Serializable; +import java.time.LocalDate; +import java.util.Objects; +import java.util.function.Predicate; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class TrackingPointFilter implements Predicate, Serializable { + + public TrackingPoint point; + + public TrackingPointFilter() {} + + public TrackingPointFilter(final TrackingPoint tp) { + point = tp; + } + + @Override + public boolean test(Statement t) { + if (t == null) + return false; + if (!Objects.equals(point == null? null : point.getName(), t.getTrackingPoint())) + return false; + return checkDateRange(t.getDate()); + } + + private boolean checkDateRange(final LocalDate toTest) { + final LocalDate yearStart = (point == null)? null : point.getYearStart(); + final LocalDate yearEnd = (point == null)? null : point.getYearEnd(); + if (toTest == yearStart || toTest == yearEnd) + return true; + if (toTest == null) + return false; + if (yearStart != null && toTest.isBefore(yearStart)) + return false; + + return !(yearEnd != null && toTest.isAfter(yearEnd)); + } + + @Override + public int hashCode() { + int hash = 5; + hash = 89 * hash + Objects.hashCode(this.point); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + final TrackingPointFilter other = (TrackingPointFilter) obj; + return Objects.equals(this.point, other.point); + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/data/Warning.java b/core/src/main/java/fr/cenra/rhomeo/api/data/Warning.java new file mode 100644 index 0000000..4bb8e11 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/data/Warning.java @@ -0,0 +1,51 @@ +/** + * 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 javax.validation.ConstraintViolation; +import javax.validation.Payload; + +/** + * A simple interface defining that the attached {@link ConstraintViolation} is + * a warning, a recoverable error. + * @author Alexis Manin (Geomatys) + */ +public interface Warning extends Payload { + +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/preferences/InternationalPreferenceKey.java b/core/src/main/java/fr/cenra/rhomeo/api/preferences/InternationalPreferenceKey.java new file mode 100644 index 0000000..bc825ff --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/preferences/InternationalPreferenceKey.java @@ -0,0 +1,106 @@ +/** + * 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.preferences; + +import fr.cenra.rhomeo.api.InternationalDescription; +import static fr.cenra.rhomeo.api.InternationalDescription.DESCRIPTION_KEY; +import fr.cenra.rhomeo.core.RhomeoCore; +import java.util.Locale; +import java.util.ResourceBundle; +import java.util.logging.Level; +import static fr.cenra.rhomeo.api.InternationalDescription.LABEL_KEY; + +/** + * An interface to be implemented by preference keys which have an international + * description. + * + * This interface provides a default implementation usefull for {@link Enum} + * based implementations, assuming the {@link InternationalPreferenceKey#name() } + * method is implemented. + * + * @author Samuel Andrés (Geomatys) + */ +public interface InternationalPreferenceKey extends InternationalDescription, SimplePreferenceKey { + + /** + * The name of the key. + * + * The purpose of this method is to provide a default implementation of + * {@link InternationalPreferenceKey#getLabel(java.util.Locale) } and + * {@link InternationalPreferenceKey#getDescription(java.util.Locale) } for + * {@link Enum} based implementations. In case the default implementation is + * overriden, the InternationalPreferenceKey#name() method implementation is + * free and even posibly useless. + * + * @see Enum#name() + * + * @return + */ + String name(); + + /** + * + * @param locale + * @return + */ + @Override + default String getDescription(final Locale locale) { + try { + return ResourceBundle.getBundle(getClass().getName(), locale).getString(name() + '.' + DESCRIPTION_KEY); + } catch (Exception e) { + RhomeoCore.LOGGER.log(Level.WARNING, "A bundle key cannot be found !", e); + return name().concat(" (No traduction available)"); + } + } + + /** + * + * @param locale + * @return + */ + @Override + default String getLabel(final Locale locale) { + try { + return ResourceBundle.getBundle(getClass().getName(), locale).getString(name() + '.' + LABEL_KEY); + } catch (Exception e) { + RhomeoCore.LOGGER.log(Level.WARNING, "A bundle key cannot be found !", e); + return name().concat(" (No traduction available)"); + } + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/preferences/PasswordKey.java b/core/src/main/java/fr/cenra/rhomeo/api/preferences/PasswordKey.java new file mode 100644 index 0000000..9dddddd --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/preferences/PasswordKey.java @@ -0,0 +1,49 @@ +/** + * 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.preferences; + +/** + * A simple interface to identify a {@link SimplePreferenceKey} as holding the + * value of a password. It's useful to adapt preference editors. + * + * @author Alexis Manin (Geomatys) + */ +public interface PasswordKey { + +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/preferences/PreferenceGroup.java b/core/src/main/java/fr/cenra/rhomeo/api/preferences/PreferenceGroup.java new file mode 100644 index 0000000..daf47b6 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/preferences/PreferenceGroup.java @@ -0,0 +1,86 @@ +/** + * 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.preferences; + +import fr.cenra.rhomeo.api.InternationalDescription; +import java.util.List; + +/** + * A group of preferences. + * + * @author Samuel Andrés (Geomatys) + * + * @param The type of preference keys. + */ +public interface PreferenceGroup extends InternationalDescription, Comparable { + + /** + * + * @param key + * @return The value of the preference associated to the given key in the preference group. + */ + String getPreference(T key); + + /** + * Sets the value of the preference associated to the given key in the preference group. + * + * @param key + * @param value + */ + void setPreference(T key, String value); + + /** + * + * @return The list of the keys of the preference group. + */ + List getKeys(); + + /** + * Priority of this group, used for comparison. + * + * @return The priority of this group. + */ + int getPriority(); + + + @Override + default int compareTo(PreferenceGroup o) { + return getPriority() - o.getPriority(); + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/preferences/SimplePreferenceKey.java b/core/src/main/java/fr/cenra/rhomeo/api/preferences/SimplePreferenceKey.java new file mode 100644 index 0000000..45151e5 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/preferences/SimplePreferenceKey.java @@ -0,0 +1,60 @@ +/** + * 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.preferences; + +/** + * A simple interface for preference keys, providing a default value. + * + * @author Samuel Andrés (Geomatys) + */ +public interface SimplePreferenceKey { + + /** + * + * @return The key used to retrive a preference value from the storage, for + * a given implementation. + */ + String getKey(); + + /** + * + * @return The default value associated to this preference key. + */ + String getDefaultValue(); +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/preferences/UserPackagePreferenceGroup.java b/core/src/main/java/fr/cenra/rhomeo/api/preferences/UserPackagePreferenceGroup.java new file mode 100644 index 0000000..0219da4 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/preferences/UserPackagePreferenceGroup.java @@ -0,0 +1,64 @@ +/** + * 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.preferences; + +import java.util.prefs.Preferences; + +/** + * Abstract {@link PreferenceGroup} using {@link Preferences#userNodeForPackage(java.lang.Class) } storage. + * + * @author Samuel Andrés (Geomatys) + * @param + */ +public abstract class UserPackagePreferenceGroup implements PreferenceGroup{ + + protected final Preferences prefs = Preferences.userNodeForPackage(getClass()); + + @Override + public String getPreference(final T key) { + return prefs.get(key.getKey(), key.getDefaultValue()); + } + + @Override + public void setPreference(final T key, String value){ + if (value == null || (value = value.trim()).isEmpty()) + prefs.remove(key.getKey()); + else prefs.put(key.getKey(), value); + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/process/AbstractIndicator.java b/core/src/main/java/fr/cenra/rhomeo/api/process/AbstractIndicator.java new file mode 100644 index 0000000..b32f0b8 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/process/AbstractIndicator.java @@ -0,0 +1,128 @@ +/** + * 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.process; + +import fr.cenra.rhomeo.api.Version; +import fr.cenra.rhomeo.api.data.DataContext; +import fr.cenra.rhomeo.api.data.Reference; +import fr.cenra.rhomeo.api.data.ReferenceDescription; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.data.ReferenceManager; +import fr.cenra.rhomeo.core.list.HumidZoneType; +import java.beans.IntrospectionException; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * + * @author Samuel Andrés (Geomatys) + */ +public abstract class AbstractIndicator implements Indicator { + + private final String name; + private final String remarks; + + public AbstractIndicator(final String name, final String remarks){ + this.name = name; + this.remarks = remarks; + } + + @Override + public String getName() { + return name; + } + + @Override + public Collection getAlias() { + return Collections.singleton(name); + } + + @Override + public String getRemarks() { + return remarks; + } + + /** + * Default implementation. If some {@link Indicator} subclass is not compatible + * with all {@link HumidZoneType}, this method MUST be overriden. + * + * @return a set containing all environment codes because this indicator is + * compatible with all of them. + */ + @Override + public Set getZoneTypeCodes() { + final Set result = new HashSet<>(); + for(final HumidZoneType type : HumidZoneType.values()){ + result.add(type.getCode()); + } + return result; + } + + @Override + public int compareTo(final Indicator i){ + return this.getName().compareTo(i.getName()); + } + + @Override + public String toString() { + return "AbstractIndicator{" + "name=" + name + ", remarks=" + remarks + '}'; + } + + + + /** + * Get the references relative to the reference description parameter. + * + * => DEPLACER VERS ReferenceManager ? + * + * @param + * @param description + * @return + * @throws IntrospectionException + */ + public static List getReferences(final ReferenceDescription description) throws IntrospectionException { + final ReferenceManager referenceManager = ReferenceManager.getOrCreate(description); + final DataContext dc = Session.getInstance().getDataContext(); + final Version versionSel = dc.getReferences().get(description.getReferenceType()); + return referenceManager.getValues(versionSel != null ? versionSel : referenceManager.getInstalledVersions().iterator().next()); + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/process/AdditionalProcessSpi.java b/core/src/main/java/fr/cenra/rhomeo/api/process/AdditionalProcessSpi.java new file mode 100644 index 0000000..35def54 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/process/AdditionalProcessSpi.java @@ -0,0 +1,69 @@ +/** + * 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.process; + +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import javafx.concurrent.Task; + +/** + * Note : this process is made for the need of "complementary values" provided + * along indicator indices. However, this is still an abstract concept for now, + * and will need to be completed later. + * + * @author Alexis Manin (Geomatys) + */ +public interface AdditionalProcessSpi { + + /** + * + * @return set of indicators for which this + */ + Set getTargets(); + + /** + * + * @param results Set of processes finished and succeeded, sorted by indicator. + * + * @return A task to compute complementary values over the given indicators, + * or nothing if we cannot extract enough data from input parameters. + */ + Optional prepareProcess(final Map> results); +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/process/Indicator.java b/core/src/main/java/fr/cenra/rhomeo/api/process/Indicator.java new file mode 100644 index 0000000..72683dc --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/process/Indicator.java @@ -0,0 +1,101 @@ +/** + * 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.process; + +import fr.cenra.rhomeo.api.IdentifiedObject; +import fr.cenra.rhomeo.api.data.Dataset; +import fr.cenra.rhomeo.api.data.Protocol; +import fr.cenra.rhomeo.api.data.Site; +import fr.cenra.rhomeo.api.result.Index; +import fr.cenra.rhomeo.core.list.HumidZoneType; +import java.util.Set; +import javax.validation.constraints.NotNull; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public interface Indicator extends IdentifiedObject, Comparable { + + /** + * + * @return Source protocol to work with. Defines input {@link Statement} type. + */ + @NotNull + Protocol getProtocol(); + + /** + * Create all processes needed to complete {@link Index} computation over + * current session {@link Dataset}. + * The statements inside the {@link Dataset} must match the type given by + * {@link Protocol#getDataType()} from this indicator {@link #getProtocol() }. + * + * Each process is designed to compute part or all of this indicator indices, + * on part or all of the input dataset. Which means developper is completely + * free to split his processes by data or by result. The only important point + * is that once all processes are over and succeeded, the union of their + * results represents all possible indices on the entire input dataset. + * + * @param ctx The context to use as input for the newly created processes. + * + * @return A set of processes ready to be run. No insurance is done on + * execution order nor on parallelisation. The processes returned here should + * be independants. + */ + @NotNull + Set createProcesses(ProcessContext ctx); + + /** + * + * @return Name of the index considered as the main result for processes of + * this indicator. + */ + String getDefaultIndex(); + + /** + * + * @return The compatible environment codes to determine if the indicator is + * applicable to potential sites. + * + * @see Site + * @see HumidZoneType + * + */ + Set getZoneTypeCodes(); +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/process/Process.java b/core/src/main/java/fr/cenra/rhomeo/api/process/Process.java new file mode 100644 index 0000000..7689924 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/process/Process.java @@ -0,0 +1,79 @@ +/** + * 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.process; + +import fr.cenra.rhomeo.api.data.TrackingPoint; +import fr.cenra.rhomeo.api.result.Index; +import java.util.Set; +import javafx.concurrent.Task; +import javax.validation.constraints.NotNull; +import org.apache.sis.util.ArgumentChecks; + +/** + * A Calculation over a {@link TrackingPoint}. This class represents a process + * created from an {@link Indicator}. + * + * Note : For process independent of any indicator, you should prefer implementing + * {@link AdditionalProcessSpi}. + * + * @author Alexis Manin (Geomatys) + */ +public abstract class Process extends Task> { + + protected final ProcessContext ctx; + + protected Process(final ProcessContext ctx) { + ArgumentChecks.ensureNonNull("Process context", ctx); + this.ctx = ctx; + } + + /** + * @return The indicator bound to this process. Should never be null. + */ + @NotNull + public abstract Indicator getIndicator(); + + /** + * @return The processing context which provide input data. Never null. + */ + @NotNull + public ProcessContext getContext() { + return ctx; + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/process/ProcessContext.java b/core/src/main/java/fr/cenra/rhomeo/api/process/ProcessContext.java new file mode 100644 index 0000000..c8ae4ba --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/process/ProcessContext.java @@ -0,0 +1,214 @@ +/** + * 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.process; + +import fr.cenra.rhomeo.api.data.DataContext; +import fr.cenra.rhomeo.api.data.Dataset; +import fr.cenra.rhomeo.api.data.Statement; +import fr.cenra.rhomeo.api.data.TrackingPoint; +import fr.cenra.rhomeo.api.result.Index; +import java.io.Externalizable; +import java.io.Serializable; +import java.util.function.Predicate; +import javafx.beans.Observable; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleObjectProperty; +import javax.validation.constraints.NotNull; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.collections.ObservableSet; +import javafx.collections.SetChangeListener; +import org.apache.sis.util.ArgumentChecks; + +/** + * Contains all source needed for {@link Index} processing. + * + * IMPORTANT : Application attempts to save restore state of this object in case + * of unexpected shutdown. For the {@link #getFilter() } property to be saved, + * it MUST be {@link Serializable} or {@link Externalizable}. + * + * @author Alexis Manin (Geomatys) + */ +public class ProcessContext { + + private final Dataset source; + private final DataContext dataCtx; + private final ObservableSet targetIndicators = FXCollections.observableSet(); + + private Dataset processData; + + /** + * A filter which allow user to specify a filter for source to take in + * account. + */ + private final ObjectProperty> filterProperty = new SimpleObjectProperty<>(this, "filter", null); + + public ProcessContext(Dataset data, DataContext dataCtx) { + ArgumentChecks.ensureNonNull("Input data", data); + ArgumentChecks.ensureNonNull("Input data context", dataCtx); + this.source = data; + this.dataCtx = dataCtx; + targetIndicators.addListener((SetChangeListener) this::indicatorsChanged); + filterProperty.addListener(this::filterChanged); + } + + /** + * Dataset to use for indicator computing. It contains imported data that + * has been selected by user for processing. + * + * Note : User selection is reflected by {@link #filterProperty}. But if it + * changes, previously returned dataset won't be updated. To get an up to + * date dataset, you must acquire a new dataset by calling this method + * again. + * + * @return A dataset built from user selected data. Every time this + * method is called, the same dataset is returned, until {@link #filterProperty()} + * change. At this time a new dataset is generated, updating contained data + * to match new filter. + */ + @NotNull + public synchronized Dataset getData() { + if (processData == null) { + if (filterProperty.get() == null) + processData = source; + else { + processData = new Dataset(source.getProtocol()); + processData.getItems().addAll(source.getItems().filtered(filterProperty.get())); + } + } + + return processData; + } + + /** + * Return data seized by user as total dataset. This dataset should not be + * used for processing, as it represents all data imported, not the + * selection made after it. + * + * WARNING : Do not use this dataset for processing indicators. Use {@link #getData() + * } + * instead. + * + * @return Dataset which has been used for building process data. + */ + @NotNull + public Dataset getSourceDataset() { + return source; + } + + /** + * + * @return Seizure context. Contains chosen site and protocol for computing. + */ + @NotNull + public DataContext getDataCtx() { + return dataCtx; + } + + /** + * + * @return a set of tracking points, never {@code null}. + */ + @NotNull + public ObservableList getTrackingPoints() { + return FXCollections.unmodifiableObservableList(getData().getTrackingPoints()); + } + + @NotNull + public ObservableSet getIndicators() { + return targetIndicators; + } + + /** + * Allow user to filter source dataset. The filter will be applied when + * calling {@link #getData() }. It serves to decimate data used by indicator + * processes. + * + * @return Currently configured filter, or null if no filter is defined. + */ + public Predicate getFilter() { + return filterProperty.get(); + } + + /** + * Allow user to specify a filter to apply on top of tracking point + * decimation. If any, previous, configured filter is completely forgotten + * after this call. To chain previously configured filter with your new one, + * you can do something like : + * {@code + * final Predicate myFilter = createFilter(); // Prepare your stuff + * final Predicate previous = processContext.getFilter(); + * processContext.setAdditionalFilter(previous.andThen(myFilter)); + * } + * + * @param filter Filter to configure for current processing context. + */ + public void setFilter(Predicate filter) { + this.filterProperty.set(filter); + } + + public ObjectProperty> filterProperty() { + return filterProperty; + } + + /** + * A listener which check added values for {@link #targetIndicators}. It + * automatically remove indicators not compatible with source site. + * + * @param c + */ + private void indicatorsChanged(final SetChangeListener.Change c) { + if (c.wasAdded() && !c.getElementAdded().getZoneTypeCodes().contains(getDataCtx().getSite().getZoneType())) { + c.getSet().remove(c.getElementAdded()); + } + } + + /** + * Trigger data refresh when filter property change. The process data will + * be regenerated on next call to {@link #getData() } + * + * @param obs + * @param oldFilter + * @param newFilter + */ + private synchronized void filterChanged(final Observable obs) { + processData = null; + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/result/AbstractParametrableIndex.java b/core/src/main/java/fr/cenra/rhomeo/api/result/AbstractParametrableIndex.java new file mode 100644 index 0000000..3b9f8e9 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/result/AbstractParametrableIndex.java @@ -0,0 +1,122 @@ +/** + * 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.result; + +import fr.cenra.rhomeo.api.data.TrackingPoint; +import java.util.Objects; + +/** + * Abstract {@link Index} implementation which contains a value for a given entity + * (for instance a {@link TrackingPoint}) and references a specific {@link IndexSpi}. + * + * @author Samuel Andrés (Geomatys) + * + * @param The type of index value. + * @param The type of the index base the index value is associated with (for instance, a {@link TrackingPoint}…). + */ +public abstract class AbstractParametrableIndex implements Index { + + protected final V value; + protected final IndexSpi indexSpi; + protected final B base; + protected final Class baseClass; + + public AbstractParametrableIndex(final V value, final IndexSpi indexSpi, final B base, final Class baseClass){ + this.value = value; + this.indexSpi = indexSpi; + this.base = base; + this.baseClass = baseClass; + } + + @Override + public V getValue() { + return value; + } + + public B getBase(){ + return base; + } + + public Class getBaseClass(){return baseClass;} + + @Override + public abstract int getYear(); + + @Override + public IndexSpi getSpi() { + return indexSpi; + } + + @Override + public int hashCode() { + int hash = 3; + hash = 83 * hash + this.getYear(); + hash = 83 * hash + Objects.hashCode(this.value); + hash = 83 * hash + Objects.hashCode(this.indexSpi); + hash = 83 * hash + Objects.hashCode(this.base); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final AbstractParametrableIndex other = (AbstractParametrableIndex) obj; + if (this.getYear() != other.getYear()) { + return false; + } + if (!Objects.equals(this.value, other.value)) { + return false; + } + if (!Objects.equals(this.indexSpi, other.indexSpi)) { + return false; + } + if (!Objects.equals(this.base, other.base)) { + return false; + } + return true; + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/result/AdditionalValue.java b/core/src/main/java/fr/cenra/rhomeo/api/result/AdditionalValue.java new file mode 100644 index 0000000..b735719 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/result/AdditionalValue.java @@ -0,0 +1,48 @@ +/** + * 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.result; + +/** + * Complementary data computed from protocol data and indicator indices. + * + * @author Alexis Manin (Geomatys) + */ +public interface AdditionalValue { + +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/result/AdditionalValueMapper.java b/core/src/main/java/fr/cenra/rhomeo/api/result/AdditionalValueMapper.java new file mode 100644 index 0000000..b246db8 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/result/AdditionalValueMapper.java @@ -0,0 +1,76 @@ +/** + * 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.result; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Set; + +/** + * A service whose aim is to serialize / deserialize {@link AdditionalValue } + * from file-system. + * + * @author Alexis Manin (Geomatys) + */ +public interface AdditionalValueMapper { + + /** + * Read additional data contained in given folder, if any. + * + * @param folder The directory containing data to read. + * @return Set of read values. Can be empty, but should not be null. + * @throws java.io.IOException If values have been found, but an error + * occurred while reading them. + */ + Set readValues(final Path folder) throws IOException; + + /** + * Write a given set of {@link AdditionalValue} in a specific folder, if the + * current service is designed to treat input data type. Do nothing + * otherwise. + * + * @param folder To put data into. + * @param toWrite Set of values to serialise. + * @return True if current service is able to write input values (and has + * succeeded in doing so). False otherwise. + * @throws java.io.IOException If an error occurs while writing given + * values. + */ + boolean writeValues(final Path folder, final Set toWrite) throws IOException; +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/result/DashboardResultItem.java b/core/src/main/java/fr/cenra/rhomeo/api/result/DashboardResultItem.java new file mode 100644 index 0000000..c62d3ae --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/result/DashboardResultItem.java @@ -0,0 +1,124 @@ +/** + * 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.result; + +/** + * POJO representing a result item in the dashboard table. + * + * @author Cédric Briançon (Geomatys) + */ +public class DashboardResultItem { + private int year; + private String site; + private String indicator; + private Double value; + private boolean published; + + public DashboardResultItem() { + } + + public DashboardResultItem(int year, String site, String indicator, Double value, boolean published) { + this.year = year; + this.site = site; + this.indicator = indicator; + this.value = value; + this.published = published; + } + + public int getYear() { + return year; + } + + public void setYear(int year) { + this.year = year; + } + + public String getSite() { + return site; + } + + public void setSite(String site) { + this.site = site; + } + + public String getIndicator() { + return indicator; + } + + public void setIndicator(String indicator) { + this.indicator = indicator; + } + + public Double getValue() { + return value; + } + + public void setValue(Double value) { + this.value = value; + } + + public boolean isPublished() { + return published; + } + + public void setPublished(boolean published) { + this.published = published; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + DashboardResultItem that = (DashboardResultItem) o; + + if (year != that.year) return false; + if (!site.equals(that.site)) return false; + return indicator.equals(that.indicator); + + } + + @Override + public int hashCode() { + int result = year; + result = 31 * result + site.hashCode(); + result = 31 * result + indicator.hashCode(); + return result; + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/result/DefaultIndex.java b/core/src/main/java/fr/cenra/rhomeo/api/result/DefaultIndex.java new file mode 100644 index 0000000..9e9a58b --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/result/DefaultIndex.java @@ -0,0 +1,112 @@ +/** + * 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.result; + +import java.util.Objects; + +/** + * {@link Index} implementation which contains a value for a given year + * and references a specific {@link IndexSpi}. + * + * @author Samuel Andrés (Geomatys) + * + * @param The type of the {@link Index} value. + */ +public class DefaultIndex implements Index { + + private final V value; + private final int year; + private final IndexSpi indexSpi; + + /** + * @param value + * @param indexSpi + * @param year + */ + public DefaultIndex(final V value, final IndexSpi indexSpi, final int year){ + this.value = value; + this.indexSpi = indexSpi; + this.year = year; + } + + @Override + public V getValue() { + return value; + } + + @Override + public int getYear() { + return year; + } + + @Override + public IndexSpi getSpi() { + return indexSpi; + } + + @Override + public int hashCode() { + int hash = 3; + hash = 83 * hash + this.year; + hash = 83 * hash + Objects.hashCode(this.value); + hash = 83 * hash + Objects.hashCode(this.indexSpi); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final DefaultIndex other = (DefaultIndex) obj; + if (this.year != other.year) { + return false; + } + if (!Objects.equals(this.value, other.value)) { + return false; + } + return Objects.equals(this.indexSpi, other.indexSpi); + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/result/DefaultTrackingPointIndex.java b/core/src/main/java/fr/cenra/rhomeo/api/result/DefaultTrackingPointIndex.java new file mode 100644 index 0000000..3e9b69c --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/result/DefaultTrackingPointIndex.java @@ -0,0 +1,107 @@ +/** + * 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.result; + +import fr.cenra.rhomeo.api.data.TrackingPoint; +import java.util.Objects; +import org.apache.sis.util.ArgumentChecks; + +/** + * Holds a value for a specific indicator, at a given tracking point. + * + * @param The type of the {@link Index} value. + * @author Alexis Manin (Geomatys) + */ +public class DefaultTrackingPointIndex implements TrackingPointIndex { + + private final V value; + private final TrackingPoint location; + private final IndexSpi spi; + + public DefaultTrackingPointIndex(final V value, final TrackingPoint location, final IndexSpi spi) { + ArgumentChecks.ensureNonNull("Value", value); + ArgumentChecks.ensureNonNull("Tracking point", location); + ArgumentChecks.ensureNonNull("Index spi", spi); + this.value = value; + this.location = location; + this.spi = spi; + } + + @Override + public V getValue() { + return value; + } + + @Override + public int getYear() { + return location.getYear(); + } + + @Override + public IndexSpi getSpi() { + return spi; + } + + @Override + public TrackingPoint getPoint() { + return location; + } + + @Override + public int hashCode() { + int hash = 5; + hash = 47 * hash + Objects.hashCode(this.value); + hash = 47 * hash + Objects.hashCode(this.location); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!TrackingPointIndex.class.isAssignableFrom(obj.getClass())) + return false; + + final TrackingPointIndex other = (TrackingPointIndex) obj; + return Objects.equals(this.value, other.getValue()) + && Objects.equals(this.location, other.getPoint()); + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/result/Index.java b/core/src/main/java/fr/cenra/rhomeo/api/result/Index.java new file mode 100644 index 0000000..bab1e7f --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/result/Index.java @@ -0,0 +1,71 @@ +/** + * 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.result; + +import fr.cenra.rhomeo.api.process.Indicator; +import javax.validation.constraints.NotNull; + +/** + * An index computed from an {@link Indicator}. Should be immutable, as it + * describes a result of a finished process. + * + * @author Alexis Manin (Geomatys) + * @param Type of number value (double, int, etc.). + */ +public interface Index { + + /** + * + * @return Computed value. Should never be null. + */ + T getValue(); + + /** + * + * @return The year for which this index is valid. + */ + int getYear(); + + /** + * + * @return Thee SPI associated with this value. + */ + @NotNull + IndexSpi getSpi(); +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/result/IndexMapper.java b/core/src/main/java/fr/cenra/rhomeo/api/result/IndexMapper.java new file mode 100644 index 0000000..7a444d7 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/result/IndexMapper.java @@ -0,0 +1,122 @@ +/** + * 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.result; + +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.ReadOnlyObjectProperty; +import javafx.beans.property.SimpleObjectProperty; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +/** + * An utility class to map association between instances from a given base + * class and some indexed numeric values. + * + * The equality of two {@link IndexMapper} is based ont the equality of their + * included "key" instances. + * + * @param The type of the base class. + * + * @author Samuel Andrés (Geomatys) + * @author Cédric Briançon (Geomatys) + */ +public class IndexMapper { + + private final ObjectProperty keyProperty = new SimpleObjectProperty<>(); + + private final Map> map = new HashMap<>(); + + /** + * + * @param key + */ + public IndexMapper(final C key){ + this.keyProperty.set(key); + } + + public C getKey(){return keyProperty.get();} + + public ReadOnlyObjectProperty keyProperty(){return keyProperty;} + + public ReadOnlyObjectProperty valueProperty(final String k){return map.get(k);} + + public void setValue(final String k, final Number v){ + if(valueProperty(k)==null){ + map.put(k, new SimpleObjectProperty<>()); + } + map.get(k).set(v); + } + + public Collection> getValues() { + return map.values(); + } + + public Set getValueAccessors(){ + return map.keySet(); + } + + @Override + public int hashCode() { + int hash = 3; + hash = 97 * hash + Objects.hashCode(this.keyProperty); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final IndexMapper other = (IndexMapper) obj; + if (!Objects.equals(this.keyProperty, other.keyProperty)) { + return false; + } + return true; + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/result/IndexSpi.java b/core/src/main/java/fr/cenra/rhomeo/api/result/IndexSpi.java new file mode 100644 index 0000000..a734138 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/result/IndexSpi.java @@ -0,0 +1,106 @@ +/** + * 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.result; + +import fr.cenra.rhomeo.api.IdentifiedObject; +import fr.cenra.rhomeo.api.data.TrackingPoint; +import fr.cenra.rhomeo.api.process.Indicator; +import javax.measure.unit.Unit; +import javax.validation.constraints.NotNull; + +/** + * Describe a particular type of index, including its name, description, unit, etc. + * + * Note : Must be a Spring component + * + * @author Alexis Manin (Geomatys) + * + * @param Type of index value + * @param Type of index base (Integer for a year, {@link TrackingPoint}…) + */ +public interface IndexSpi extends IdentifiedObject, Comparable { + + /** + * + * @return The unit of this index value. Should never be null. If no unit is + * defined for the value, {@link Unit#ONE} should be returned. + */ + @NotNull + Unit getUnit(); + + /** + * + * @return The indicator associated to this index. + */ + @NotNull + Indicator getIndicator(); + + /** + * Create an index initialized with given value. + * @param value The value to set on created index. + * @param entity The base the index is associated with. For instance an integer to represent a year, a {@link TrackingPoint}… + * @return The created index. + */ + @NotNull + Index createIndex(final V value, final B entity); + + /** + * Denotes this index as a major indicator, or a minor indicator. It differs + * from {@link Indicator#getDefaultIndex() } by the fact that multiple + * indice types can be primary for an indicator, but only one is the default + * index shown on dashboard. + * + * @return True if this spi indices are considered as main results for the + * target indicator (see {@link #getIndicator() }. False if it describes a + * complementary index. + */ + default boolean isPrimary() { + return getName().equals(getIndicator().getDefaultIndex()); + } + + @Override + default int compareTo(IndexSpi o) { + if (o == null) { + return -1; + } + + return (getIndicator() == o.getIndicator())? 0 : + getIndicator() == null? 1 : getIndicator().compareTo(o.getIndicator()); + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/result/IndicatorValuesByYearItem.java b/core/src/main/java/fr/cenra/rhomeo/api/result/IndicatorValuesByYearItem.java new file mode 100644 index 0000000..b49a583 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/result/IndicatorValuesByYearItem.java @@ -0,0 +1,121 @@ +/** + * 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.result; + +import java.util.HashMap; +import java.util.Map; + +/** + * POJO regrouping indicator values for each year. + * + * @author Cédric Briançon (Geomatys) + */ +public class IndicatorValuesByYearItem implements Comparable { + private final int year; + + private final Map indicatorValues = new HashMap<>(); + + public IndicatorValuesByYearItem(final int year) { + this.year = year; + } + + public int getYear() { + return year; + } + + /** + * Get the value for the given indicator. May return {@code null} if not found. + * + * @param indicator Indicator name. + * @return The value or {@code null} if not defined for this indicator + */ + public PublishedValue getValueForIndicator(final String indicator) { + return indicatorValues.get(indicator); + } + + public void addValueForIndicator(final String indicator, final Double value, final boolean published) { + indicatorValues.put(indicator, new PublishedValue(value, published)); + } + + @Override + public int compareTo(IndicatorValuesByYearItem o) { + if (o == null) { + return -1; + } + return year < o.getYear() ? -1 : year == o.getYear() ? 0 : 1; + } + + /** + * Try to find if the value for this indicator is published. + * + * @param indicatorName + * @return True or false depending if the value has been published or not for this indicator, + * or {@code null} if not defined for this indicator. + */ + public Boolean isPublished(final String indicatorName) { + final PublishedValue pubVal = indicatorValues.get(indicatorName); + if (pubVal == null) { + return null; + } + return pubVal.published; + } + + public static final class PublishedValue { + + private Double value; + private boolean published; + + PublishedValue(final Double value, final boolean published) { + this.value = value; + this.published = published; + } + + public Double getValue() { + return value; + } + + public boolean isPublished() { + return published; + } + + public void setPublished(boolean published) { + this.published = published; + } + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/result/TrackingPointIndex.java b/core/src/main/java/fr/cenra/rhomeo/api/result/TrackingPointIndex.java new file mode 100644 index 0000000..d0edc96 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/result/TrackingPointIndex.java @@ -0,0 +1,59 @@ +/** + * 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.result; + +import fr.cenra.rhomeo.api.data.TrackingPoint; +import javax.validation.constraints.NotNull; + +/** + * Describe an index computed on a single {@link TrackingPoint}. Should be + * immutable, as it describes a result of a finished process. + * + * @author Alexis Manin (Geomatys) + * @param Type of number value (double, int, etc.). + */ +public interface TrackingPointIndex extends Index { + + /** + * + * @return The point on which this index has been computed on. + */ + @NotNull + TrackingPoint getPoint(); +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/ui/AdditionalResultSpi.java b/core/src/main/java/fr/cenra/rhomeo/api/ui/AdditionalResultSpi.java new file mode 100644 index 0000000..311afdd --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/ui/AdditionalResultSpi.java @@ -0,0 +1,57 @@ +/** + * 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.ui; + +import fr.cenra.rhomeo.api.data.Protocol; +import fr.cenra.rhomeo.api.result.AdditionalValue; +import java.util.Collection; +import java.util.Optional; +import javafx.scene.Node; + +/** + * An SPI providing view component to display a set of additional results. + * + * @author Alexis Manin (Geomatys) + */ +public interface AdditionalResultSpi { + + Protocol getProtocol(); + + Optional getResultNode(final Collection values); +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/ui/DashboardMenuItem.java b/core/src/main/java/fr/cenra/rhomeo/api/ui/DashboardMenuItem.java new file mode 100644 index 0000000..2ade0ee --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/ui/DashboardMenuItem.java @@ -0,0 +1,59 @@ +/** + * 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.ui; + +import fr.cenra.rhomeo.api.result.IndicatorValuesByYearItem; +import java.util.Optional; +import javafx.scene.control.MenuItem; +import javafx.scene.control.TableView; +import org.springframework.stereotype.Component; + +/** + * Describe a menu item which an be added to the context menu of the dashboard + * result table. + * + * Note : implementations should be {@link Component}s. This way, the dashboard + * will be able to inject all available items. + * + * @author Alexis Manin (Geomatys) + */ +public interface DashboardMenuItem { + + public Optional createItem(final TableView target); +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/ui/FilterTable.java b/core/src/main/java/fr/cenra/rhomeo/api/ui/FilterTable.java new file mode 100644 index 0000000..b94c3e3 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/ui/FilterTable.java @@ -0,0 +1,58 @@ +/** + * 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.ui; + +import fr.cenra.rhomeo.api.data.Statement; +import java.util.function.Predicate; +import javafx.beans.property.ObjectProperty; +import javafx.scene.control.TableView; + +/** + * + * @author Alexis Manin (Geomatys) + * @param Type of filter given by this component. + */ +public abstract class FilterTable extends TableView { + + public abstract Predicate getPreFilter(); + + public abstract void setPreFilter(final Predicate filter); + + public abstract ObjectProperty> preFilterProperty(); +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/ui/FilterTableSpi.java b/core/src/main/java/fr/cenra/rhomeo/api/ui/FilterTableSpi.java new file mode 100644 index 0000000..da1403b --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/ui/FilterTableSpi.java @@ -0,0 +1,56 @@ +/** + * 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.ui; + +import fr.cenra.rhomeo.api.data.Protocol; +import java.util.function.Predicate; +import javafx.scene.control.TableView; + +/** + * A simple pojo capable to provide a {@link TableView} to display information + * of filters o apply on a specific dataset. + * + * @author Alexis Manin (Geomatys) + */ +public interface FilterTableSpi { + + Protocol getProtocol(); + + FilterTable createEmptyTable(); +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/ui/PreferencePane.java b/core/src/main/java/fr/cenra/rhomeo/api/ui/PreferencePane.java new file mode 100644 index 0000000..c8e5467 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/ui/PreferencePane.java @@ -0,0 +1,70 @@ +/** + * 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.ui; + +import fr.cenra.rhomeo.api.preferences.PreferenceGroup; +import javafx.scene.Node; + +/** + * + * A simple interface which allows to discover JavaFX components able to edit + * a specific {@link PreferenceGroup}. + * + * @author Samuel Andrés (Geomatys) + * @param + */ +public interface PreferencePane { + + /** + * Saves preferences edited by the pane. + */ + void save(); + + /** + * + * @return + */ + PreferenceGroup getPreferenceGroup(); + + /** + * + * @return The editor node to include in the scene. + */ + Node getEditor(); +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/ui/ProtocolEditorSpi.java b/core/src/main/java/fr/cenra/rhomeo/api/ui/ProtocolEditorSpi.java new file mode 100644 index 0000000..e80d4a1 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/ui/ProtocolEditorSpi.java @@ -0,0 +1,71 @@ +/** + * 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.ui; + +import fr.cenra.rhomeo.api.data.Protocol; +import fr.cenra.rhomeo.core.WorkflowStep; +import java.util.Set; +import javafx.scene.Node; + +/** + * Define edition rules for a specific protocol. For example, it allows to + * replace a {@link WorkflowStep} panel by one chosen here. + * + * @author Alexis Manin (Geomatys) + */ +public interface ProtocolEditorSpi { + + Protocol getProtocol(); + + /** + * + * @param step The step user required to display. + * @return A node allowing to edit protocol related data for the given step. + * Can be null, in which case application considers it can use a default + * editor. + */ + Node getEditor(final WorkflowStep step); + + /** + * + * @return A set of steps which must be ignored for given protocol. Can be + * empty, but should never be null. + */ + Set getStepsToIgnore(); +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/ui/StatementEditor.java b/core/src/main/java/fr/cenra/rhomeo/api/ui/StatementEditor.java new file mode 100644 index 0000000..1a4f67c --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/ui/StatementEditor.java @@ -0,0 +1,81 @@ +/** + * 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.ui; + +import fr.cenra.rhomeo.api.data.Statement; +import javafx.beans.property.ObjectProperty; +import javafx.collections.ObservableList; + +/** + * An editor created from {@link StatementEditorSpi#createEditor() }. + * @author Alexis Manin (Geomatys) + * @param Manageable data type. + */ +public interface StatementEditor { + + /** + * + * @return Data type manageable by current editor. + */ + Class getDataType(); + + /** + * Asks the editor to focus on a particular item. Optionally, user can also + * give a property name to focus on into input object. + * + * @param item The item to focus on in the editor. + * @param propertyName If not null, this represents a property of the given + * item to focus on. + */ + void focusOn(final T item, final String propertyName); + + /** + * + * @return List of items contained (to edit) in this component. + */ + ObservableList getItems(); + + /** + * + * @param items Configure this component to work with given set of items. + */ + void setItems(ObservableList items); + + ObjectProperty> itemsProperty(); +} diff --git a/core/src/main/java/fr/cenra/rhomeo/api/ui/StatementEditorSpi.java b/core/src/main/java/fr/cenra/rhomeo/api/ui/StatementEditorSpi.java new file mode 100644 index 0000000..fd9c286 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/api/ui/StatementEditorSpi.java @@ -0,0 +1,65 @@ +/** + * 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.ui; + +import fr.cenra.rhomeo.api.data.Statement; +import javax.validation.constraints.NotNull; + +/** + * A provider which can return back an editor to fill objects of a specific type. + * + * @author Alexis Manin (Geomatys) + * @param Manageable data type. + */ +public interface StatementEditorSpi { + + /** + * + * @return A new editor for data seizure. Never null. + */ + @NotNull + StatementEditor createEditor(); + + /** + * + * @return Data type manageable by current editor provider. + */ + @NotNull + Class getDataType(); +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/BeanUtils.java b/core/src/main/java/fr/cenra/rhomeo/core/BeanUtils.java new file mode 100644 index 0000000..370ffbe --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/BeanUtils.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.core; + +import org.geotoolkit.data.bean.BeanFeature; +import org.geotoolkit.feature.type.FeatureType; +import org.opengis.feature.Feature; +import org.opengis.filter.identity.FeatureId; +import org.opengis.referencing.crs.CoordinateReferenceSystem; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class BeanUtils { + + /** + * Build a feature type corresponding to given bean class, i.e which reproduce + * its properties. + * + * @param beanClass The class to build a feature type for. + * @return A feature type to map pojo properties into {@link Feature} API. + */ + public static FeatureType createFeatureType(final Class beanClass) { + return createMapping(beanClass).featureType; + } + + public static BeanFeature.Mapping createMapping(final Class beanClass) { + return new Mapping(beanClass, "no namespace", null, null); + } + + public static BeanFeature.Mapping createMapping(final Class beanClass, final String namespace) { + return new Mapping(beanClass, namespace, null, null); + } + + private static class Mapping extends BeanFeature.Mapping { + + public Mapping(Class clazz, String namespace, CoordinateReferenceSystem crs, String idField) { + super(clazz, namespace, crs, idField); + } + + @Override + public FeatureId buildId(Object bean) { + if (idAccessor == null) { + return new FeatureId() { + + @Override + public String getID() { + return ""; + } + + @Override + public boolean matches(Object o) { + return false; + } + }; + } else { + return super.buildId(bean); + } + } + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/CSVDecoder.java b/core/src/main/java/fr/cenra/rhomeo/core/CSVDecoder.java new file mode 100644 index 0000000..cd591e7 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/CSVDecoder.java @@ -0,0 +1,426 @@ +/** + * 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.core; + +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; +import java.io.BufferedReader; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.logging.Level; +import java.util.regex.Pattern; +import org.apache.sis.util.Numbers; +import org.apache.sis.util.ObjectConverter; +import org.apache.sis.util.ObjectConverters; +import org.geotoolkit.util.collection.CloseableIterator; + +/** + * Read a given CSV file, trying to create a list of pojo of the given type to hold + * its data. + * + * @author Alexis Manin (Geomatys) + */ +public class CSVDecoder extends CSVMapper { + + /** + * At runtime, we detect doubled double-quote in escaped strings, to replace + * them by single ones. + */ + static final Pattern DOUBLED_DOUBLE_QUOTE = Pattern.compile("\"\""); + static final String DOUBLE_QUOTE_REPLACEMENT = "\""; + + /** + * Contains all cell value decoders. For each line read, we take each column + * value, and give it to an appropriate converter which will put them into + * the right properties of a target Pojo. + */ + private final BiConsumer[] propertySetters; + + /** + * Create a new decoder whose aim is to read data hold by input file, and + * return it as a list of pojos of the given type. + * @param input The file to read. MUST BE READABLE + * @param beanClass The class defining POJO object to use as data container. + * @throws IOException If we cannot analyze input file header. + * @throws IntrospectionException If we cannot analyze input pojo type. + */ + public CSVDecoder(Path input, Class beanClass) throws IOException, IntrospectionException { + this(input, beanClass, null); + } + + /** + * Create a new decoder whose aim is to read data hold by input file, and + * return it as a list of pojos of the given type. + * @param input The file to read. MUST BE READABLE + * @param beanClass The class defining POJO object to use as data container. + * to read. + * @param fileEncoding Encoding to use for reading. + * @throws IOException If we cannot analyze input file header. + * @throws IntrospectionException If we cannot analyze input pojo type. + */ + public CSVDecoder(Path input, Class beanClass, Charset fileEncoding) throws IOException, IntrospectionException { + this(input, beanClass, fileEncoding, null); + } + + public CSVDecoder(Path input, Class beanClass, Charset fileEncoding, Set ignorableProperties) throws IOException, IntrospectionException { + this(input, beanClass, null, fileEncoding, ignorableProperties); + } + + public CSVDecoder(Path input, Class beanClass, final Character separator, final Charset fileEncoding, final Set ignorableProperties) throws IOException, IntrospectionException { + super(input, beanClass, separator, fileEncoding, ignorableProperties); + + if (!Files.isReadable(input)) { + throw new IOException("Given file is not readable : ".concat(input.toString())); + } + + /* Prepare data conversion. For each property present in input bean type, + * we ensure that a read method is available. Then, we analyze its return + * type. We try to find an appropriate converter to get a string + * representation writable in CSV file. + */ + final PropertyDescriptor[] pDescriptors = beanInfo.getPropertyDescriptors(); + propertySetters = new BiConsumer[pDescriptors.length]; + for (int i = 0; i < pDescriptors.length; i++) { + final PropertyDescriptor p = pDescriptors[i]; + final Method writeMethod = p.getWriteMethod(); + if (writeMethod == null) + throw new IllegalArgumentException( + new StringBuilder("Property ") + .append(p.getName()) + .append(" from class ") + .append(beanClass.getCanonicalName()) + .append("is not writable.") + .toString()); + + writeMethod.setAccessible(true); + final Class propertyType = p.getPropertyType(); + final Function conv = createPropertyConverter(propertyType); + + final BiConsumer setter; + setter = (pojo, value) -> { + try { + writeMethod.invoke(pojo, value); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RhomeoRuntimeException(e); + } + }; + + if (conv == null) { + propertySetters[i] = (BiConsumer) setter; + } else { + propertySetters[i] = (pojo, strValue) -> setter.accept(pojo, conv.apply(strValue)); + } + } + } + + /** + * Read given string (must be a line in the csv, not header) and map its + * data into a POJO. + * + * @param line A line of the CSV file. + * @param lineNumber Number of the read line. It serves to build error messages. + * @return A Pojo containing line data. If input line is blank, a null value is returned. + * @throws InstantiationException + * @throws IllegalAccessException + * @throws IOException + */ + private T decodeLine(final String line, int lineNumber) throws InstantiationException, IllegalAccessException, IOException { + final List groups = splitByProperty(line); + if (groups.isEmpty()) + return null; + final T newInstance = dataType.newInstance(); + CharBuffer buffer; + for (int i = 0; i < groups.size(); i++) { + buffer = groups.get(i); + try { + if (buffer.hasRemaining() && propertyOrder[i] >= 0) { + propertySetters[propertyOrder[i]].accept(newInstance, unescape(buffer)); + } + } catch (Exception e) { + throwWithDescription(lineNumber, i, buffer, e); + } + } + + return newInstance; + } + + /** + * + * @return A list of POJO, each one containing data of a line. Pojos are + * sorted according to line number in the source file. + * + * @throws IOException Reading fails. + * @throws InstantiationException Cannot create a new pojo (Mostly no default builder found). + * @throws IllegalAccessException A property of the pojo type cannot be used by the decoder. + */ + public List decode() throws IOException, InstantiationException, IllegalAccessException { + try (final BufferedReader reader = Files.newBufferedReader(target, charset)) { + // No data ... + String line = reader.readLine(); + if (line == null) { + return new ArrayList<>(); + } else { + updatePropertyOrder(line); + } + + // Do not check header content. It has been done at built. + final List result = new ArrayList<>(); + int lineCount = 1; + T read; + while ((line = reader.readLine()) != null) { + read = decodeLine(line, lineCount++); + if (read != null) + result.add(read); + } + return result; + } + } + + /** + * /!\ You MUST CLOSE the iterator once you're done with it. + * @return An iterator which will decode lines of the source file as we iterate + * on them. + */ + public CloseableIterator decodeLazy() { + return new CloseableIterator() { + + BufferedReader fileReader; + T next; + int lineCount = 0; + + @Override + public boolean hasNext() { + if (next == null) { + try { + // first time, check header. + if (fileReader == null) { + fileReader = Files.newBufferedReader(target, charset); + final String header = fileReader.readLine(); + lineCount++; + // check header + if (header == null) + return false; + else + updatePropertyOrder(header); + } + + // read next line + String line; + while (next == null) { + line = fileReader.readLine(); + if (line == null) + break; + next = decodeLine(line, ++lineCount); + } + } catch (IOException e) { + throw new RhomeoRuntimeException(e.getMessage(), e); + } catch (InstantiationException | IllegalAccessException ex) { + RhomeoCore.LOGGER.log(Level.WARNING, "Cannot set output properties.", ex); + } + } + + return next != null; + } + + @Override + public T next() { + if (next == null) { + throw new IllegalStateException("No more element available !"); + } + + try { + return next; + } finally { + next = null; + } + } + + @Override + public void close() { + if (fileReader != null) { + try { + fileReader.close(); + } catch (IOException ex) { + RhomeoCore.LOGGER.log(Level.WARNING, "A reader cannot be closed on file ".concat(target.toString()), ex); + } + } + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + close(); + } + }; + } + + /** + * Analyze a line of input CSV file, and split its character by column. To + * find columns, we search for separators which are not enclosed in an + * escaped character sequence. + * + * NOTE : return char buffers are already trimmed, but are still escaped (if any). + * + * @param line input line to find property indices for. + * @return A list of buffer. Each represents a part of the original string. + * They're sorted by order of appearance in the input string. + */ + private List splitByProperty(final String line) { + final CharBuffer cLine = CharBuffer.wrap(line); + final ArrayList groups = new ArrayList<>(); + int lastGroup = cLine.position(); + boolean escapeMode = false; + char c; + for (int i = cLine.position(); i < cLine.limit(); i++) { + c = cLine.get(i); + if (c == '"') { + escapeMode = !escapeMode;// If two double quotes follows, escape mode is reactivated. + } else if (!escapeMode) { + if (c == separator) { + groups.add(cLine.subSequence(lastGroup, i)); + lastGroup = i + 1; + } else if (Character.isWhitespace(c) && i == lastGroup) { + lastGroup++; // remove trailing spaces + } else if (c == COMMENT_CHAR) { + break; // A comment have been found. + } + } + } + + // last value on the line + if (lastGroup < cLine.limit()) { + groups.add(cLine.subSequence(lastGroup, cLine.remaining())); + } + + return groups; + } + + /** + * + * @param input A char buffer representing one cell data. + * @return A string which is the cell data, from which we remove trailing + * double-quotes and doubled ones if needed. + */ + private String unescape(final CharBuffer input) { + if (!input.hasRemaining()) { + return ""; + } + + if (input.get(input.position()) == '"' && input.get(input.limit() -1) == '"') { + if (input.remaining() < 3) // Empty escaped sequence. + return ""; + return DOUBLED_DOUBLE_QUOTE.matcher(input.subSequence(1, input.remaining() -1)).replaceAll(DOUBLE_QUOTE_REPLACEMENT); + } + + return input.toString(); + } + + /** + * Search for an appropriate converter between given type and string. + * + * Note : for numbers and primitives, we use direct conversion using wrapping + * class utilities. We make a distinction between primitive and wrapping class + * case, as the first one cannot hold null value information. + * + * @param inputType Type of object to convert. + * @return A ready-to-use converter, or null if we do not need any. + */ + private Function createPropertyConverter(final Class inputType) { + final Function result; + if (CharSequence.class.isAssignableFrom(inputType)) { + return null; + // boolean + } else if (Boolean.class.isAssignableFrom(inputType)) { + result = input -> Boolean.valueOf(input); + } else if (Boolean.TYPE.isAssignableFrom(inputType)) { + result = input -> Boolean.parseBoolean(input); + // character + } else if (Character.class.isAssignableFrom(inputType)) { + result = input -> input == null || input.isEmpty()? null : input.charAt(0); + } else if (Character.TYPE.isAssignableFrom(inputType)) { + result = input -> input == null || input.isEmpty()? '?' : input.charAt(0); + // bytes + } else if (Byte.class.isAssignableFrom(inputType)) { + result = input -> Byte.valueOf(input); + } else if (Byte.TYPE.isAssignableFrom(inputType)) { + result = input -> input == null || input.isEmpty()? 0 : Byte.parseByte(input); + // short + } else if (Short.class.isAssignableFrom(inputType)) { + result = input -> Short.valueOf(input); + } else if (Short.TYPE.isAssignableFrom(inputType)) { + result = input -> input == null || input.isEmpty()? 0 : Short.parseShort(input); + // integer + } else if (Integer.class.isAssignableFrom(inputType)) { + result = input -> Integer.valueOf(input); + } else if (Integer.TYPE.isAssignableFrom(inputType)) { + result = input -> input == null || input.isEmpty()? 0 : Integer.parseInt(input); + // long + } else if (Long.class.isAssignableFrom(inputType)) { + result = input -> Long.valueOf(input); + } else if (Long.TYPE.isAssignableFrom(inputType)) { + result = input -> input == null || input.isEmpty()? 0 : Long.parseLong(input); + // float + } else if (Float.class.isAssignableFrom(inputType)) { + result = input -> Float.valueOf(input); + } else if (Float.TYPE.isAssignableFrom(inputType)) { + result = input -> input == null || input.isEmpty()? Float.NaN : Float.parseFloat(input); + // double + } else if (Double.class.isAssignableFrom(inputType)) { + result = input -> Double.valueOf(input); + } else if (Double.TYPE.isAssignableFrom(inputType)) { + result = input -> input == null || input.isEmpty()? Double.NaN : Double.parseDouble(input); + } else { + final Class tmpClass = Numbers.primitiveToWrapper(inputType); + final ObjectConverter sisConverter = ObjectConverters.find(String.class, tmpClass); + result = input -> (input == null || input.isEmpty())? null : sisConverter.apply(input); + } + + return result; + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/CSVEncoder.java b/core/src/main/java/fr/cenra/rhomeo/core/CSVEncoder.java new file mode 100644 index 0000000..4c153ba --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/CSVEncoder.java @@ -0,0 +1,298 @@ +/** + * 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.core; + +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.Iterator; +import java.util.Set; +import java.util.function.Function; +import java.util.logging.Level; +import java.util.regex.Pattern; +import org.apache.sis.util.Numbers; +import org.apache.sis.util.ObjectConverter; +import org.apache.sis.util.ObjectConverters; + +/** + * Encode data holded by POJO of a specific type into a CSV file. + * + * @author Alexis Manin (Geomatys) + */ +public class CSVEncoder extends CSVMapper { + + static final Pattern DOUBLE_QUOTE = Pattern.compile("\""); + static final String DOUBLE_QUOTE_REPLACEMENT = "\"\""; + + private final Function[] converters; + + /** + * Create a new encoder whose aim is to write pojo properties in the given file. + * @param output The file to write. If not exists, we'll try to create it. + * However, its parent directory MUST exist already. + * @param beanClass The class defining POJO object we'll have to extract data from. + * @throws IOException If we cannot create the file, or it already exists and we cannot analyze its header. + * @throws IntrospectionException If we cannot analyze input pojo type. + */ + public CSVEncoder(Path output, Class beanClass) throws IOException, IntrospectionException { + this(output, beanClass, null); + } + + /** + * Create a new encoder whose aim is to write pojo preoprties in the given file. + * @param output The file to write. If not exists, we'll try to create it. + * However, its parent directory MUST exist already. + * @param beanClass The class defining POJO object we'll have to extract data from. + * to read. + * @param fileEncoding Encoding to use for writing. + * @throws IOException If we cannot create the file, or it already exists and we cannot analyze its header. + * @throws IntrospectionException If we cannot analyze input pojo type. + */ + public CSVEncoder(Path output, Class beanClass, Charset fileEncoding) throws IOException, IntrospectionException { + this(output, beanClass, fileEncoding, null); + } + + public CSVEncoder(Path output, Class beanClass, Charset fileEncoding, Set ignorableProperties) throws IOException, IntrospectionException { + this(output, beanClass, null, fileEncoding, ignorableProperties); + } + + public CSVEncoder(final Path output, final Class beanClass, final Character separator, final Charset fileEncoding, final Set ignorableProperties) throws IOException, IntrospectionException { + super(output, beanClass, separator, fileEncoding, ignorableProperties); + + /* Prepare data conversion. For each property present in input bean type, + * we ensure that a read method is available. Then, we analyze its return + * type. We try to find an appropriate converter to get a string + * representation writable in CSV file. + */ + final PropertyDescriptor[] pDescriptors = beanInfo.getPropertyDescriptors(); + converters = new Function[pDescriptors.length]; + for (int i = 0 ; i < pDescriptors.length; i++) { + final PropertyDescriptor p = pDescriptors[i]; + final Method readMethod = p.getReadMethod(); + if (readMethod == null) + throw new IllegalArgumentException( + new StringBuilder("Property ") + .append(p.getName()) + .append(" from class ") + .append(beanClass.getCanonicalName()) + .append("is not readable.") + .toString()); + + readMethod.setAccessible(true); + final Class returnType = readMethod.getReturnType(); + Function conv = createPropertyConverter(returnType); + final Function getter = in -> { + try { + return readMethod.invoke(in); + } catch (IllegalAccessException|InvocationTargetException e) { + throw new RhomeoRuntimeException(e); + } + }; + + if (conv ==null) { + converters[i] = getter; + } else { + converters[i] = getter.andThen(conv); + } + } + } + + /** + * Create string representation of a given object. + * @param data the object to encode in CSV. + * @return A line to put in CSV file. + */ + private String encode(T data) { + final StringBuilder builder = new StringBuilder(); + Object value = getPropertyValue(data, 0); + if (value != null) { + builder.append(trimAndEscape(value)); + } + + for (int i = 1; i < converters.length; i++) { + builder.append(this.separator); + value = getPropertyValue(data, i); + if (value != null) { + builder.append(trimAndEscape(value)); + } + } + + return builder.toString(); + } + + /** + * Extract value of a property from input pojo, the one located on the given + * column index in the file. + * @param data The pojo to extract value from. + * @param colIndex Index of the property to extract in target file columns. + * @return The extracted value or a default one if input object property is + * null or does not exists. Can return a null value. + */ + private Object getPropertyValue(final T data, final int colIndex) { + Object value; + final int pIndex = propertyOrder[colIndex]; + if (pIndex < 0) + value = null; + else + value = converters[pIndex].apply(data); + return value; + } + + /** + * Write data pointed by given iterator. + * @param data An iterator which provides objects to write. + * @param replaceExisting If true, data previously written will be erased. + * Otherwise, we'll append data at the end of the file. + * @throws IOException If an error occurs while writing data. + */ + public synchronized void encode(Iterator data, final boolean replaceExisting) throws IOException { + if (!Files.exists(target)) { + Files.createFile(target); + } + + /* Check target file header. If we're in append mode, but no header exists, + * we set a flag to ensure it will be created. If it is here but is not + * compatible with our data type, we raise an exception. + */ + boolean emptyHeader = false; + try (final BufferedReader reader = Files.newBufferedReader(target, charset)) { + final String firstLine = reader.readLine(); + if (firstLine == null) { + emptyHeader = true; + } else if (!replaceExisting) { + if (isValidHeader(firstLine)) { + updatePropertyOrder(firstLine); + } else { + throw new IllegalArgumentException("Given file already exists, but its header is not complient with given data type."); + } + } + } + + try (BufferedWriter writer = Files.newBufferedWriter(target, charset, + StandardOpenOption.CREATE, + replaceExisting ? StandardOpenOption.TRUNCATE_EXISTING : StandardOpenOption.APPEND)) { + if (replaceExisting || emptyHeader) { + writer.write(buildHeader()); + } + while (data.hasNext()) { + writer.newLine(); + writer.write(encode(data.next())); + + } + } + } + + /** + * Write data pointed by given collection. + * @param data A collection which provides objects to write. + * @param replaceExisting If true, data previously written will be erased. + * Otherwise, we'll append data at the end of the file. + * @throws IOException If an error occurs while writing data. + */ + public void encode(Iterable data, final boolean replaceExisting) throws IOException { + final Iterator it = data.iterator(); + try { + encode(it, replaceExisting); + } finally { + if (it instanceof AutoCloseable) { + try { + ((AutoCloseable)it).close(); + } catch (Exception ex) { + RhomeoCore.LOGGER.log(Level.WARNING, "Cannot close a resource !", ex); + } + } + } + } + + /** + * Search for an appropriate converter between given type and string. + * @param Type of object to convert. + * @param inputType Type of object to convert. + * @return A ready-to-use converter, or null if we don't need any. + */ + private Function createPropertyConverter(final Class inputType) { + final Function result; + if (inputType.isPrimitive() + || Number.class.isAssignableFrom(inputType) + || CharSequence.class.isAssignableFrom(inputType) + || Boolean.class.isAssignableFrom(inputType)) { + result = null; + + } else { + final Class tmpClass = Numbers.primitiveToWrapper(inputType); + ObjectConverter sisConverter = ObjectConverters.find(tmpClass, String.class); + result = input -> { + return input == null? null : sisConverter.apply(input); + }; + } + + return result; + } + + /** + * Analyze input string, and modify it if the CSV separator character is + * found inside. First, we remove blank spaces at start and end of the + * string. Then, we'll search for provided separator character. If we find + * it, we escape the string using '"' character. If the string also contains + * '"' characters, we double them. + * + * @param input String to analyze. + * @return Input string if we don't have to escape it. A new one otherwise. + */ + private String trimAndEscape(final Object input) { + String result = input.toString().trim(); + if (result.contains(String.valueOf(separator)) || result.contains(String.valueOf(COMMENT_CHAR))) { + result = new StringBuilder(result.length() +2) + .append('"') + .append(DOUBLE_QUOTE.matcher(result).replaceAll(DOUBLE_QUOTE_REPLACEMENT)) + .append('"') + .toString(); + } + + return result; + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/CSVMapper.java b/core/src/main/java/fr/cenra/rhomeo/core/CSVMapper.java new file mode 100644 index 0000000..b284431 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/CSVMapper.java @@ -0,0 +1,286 @@ +/** + * 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.core; + +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.io.BufferedReader; +import java.io.IOException; +import java.nio.charset.CharacterCodingException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import org.apache.sis.util.ArgumentChecks; + +/** + * TODO : Create a builder, to manage encoder / decoder creation. + * + * @author Alexis Manin (Geomatys) + * @param Type of java bean to map to the CSV file. + */ +public abstract class CSVMapper { + + public static final char COMMENT_CHAR = '#'; + public static final char DEFAULT_SEPARATOR = ';'; + + /** + * Expected objects in input or output of the file. + */ + protected final Class dataType; + + /** + * Information about {@link #dataType}. + */ + protected final BeanInfo beanInfo; + + /** + * Separator between columns. + */ + protected final char separator; + + /** + * Charset to use with given file. + */ + protected final Charset charset; + + /** + * Path to the CSV file to read or write. + */ + protected final Path target; + + /** + * For each column of the file, give the property index corresponding in + * {@link #beanInfo}. + */ + protected int[] propertyOrder; + + /** + * List properties that can be missing in the read / written file. + */ + private final Set ignorable; + + protected CSVMapper(Path target, Class beanClass, Character separator, Charset fileEncoding) throws IOException, IntrospectionException { + this(target, beanClass, separator, fileEncoding, null); + } + + protected CSVMapper(Path target, Class beanClass, Character separator, Charset fileEncoding, Set ignorableProperties) throws IOException, IntrospectionException { + ArgumentChecks.ensureNonNull("Output path", target); + ArgumentChecks.ensureNonNull("Data type", beanClass); + + if (ignorableProperties != null) { + ignorable = Collections.unmodifiableSet(ignorableProperties); + } else { + ignorable = Collections.EMPTY_SET; + } + + // Check global information + beanInfo = Introspector.getBeanInfo(beanClass, Object.class); + this.dataType = beanClass; + + this.separator = separator == null ? DEFAULT_SEPARATOR : separator; + + charset = fileEncoding == null ? Charset.defaultCharset() : fileEncoding; + + // If input file exists, we check its header is compatible with given data type. + String firstLine; + if (Files.isReadable(target)) { + try (final BufferedReader reader = Files.newBufferedReader(target, charset)) { + // We read lines until we find the first not empty / commented line. + firstLine = reader.readLine(); + while (firstLine != null && ((firstLine = firstLine.trim()).isEmpty() || firstLine.charAt(0) == COMMENT_CHAR)) + firstLine = reader.readLine(); + + if (firstLine != null && !isValidHeader(firstLine)) { + throw new IllegalArgumentException("L'entête du fichier n'est pas compatible avec le type de donnée associé."); + } + } catch (CharacterCodingException e) { + throw new IllegalArgumentException("Le jeu de caractères du fichier est invalide. Attendu : ".concat(charset.displayName())); + } + } else if (Files.exists(target)) { + throw new IllegalArgumentException("Le fichier source est illisible !"); + } else { + firstLine = null; + } + + updatePropertyOrder(firstLine); + + this.target = target; + } + + public Class getDataType() { + return dataType; + } + + /** + * Create a string displaying names of all properties (except the transient + * and {@link Object} inherited ones) defined by given bean information. + * + * @return A string which is the list of found properties, splitted by a + * given separator. + */ + public String buildHeader() { + final StringBuilder builder = new StringBuilder(); + final PropertyDescriptor[] pDs = beanInfo.getPropertyDescriptors(); + + for (int i = 0; i < propertyOrder.length; i++) { + final PropertyDescriptor p = pDs[propertyOrder[i]]; + // Ignore properties inherited from object. + if (p.getReadMethod() == null || p.getReadMethod().getDeclaringClass().equals(Object.class)) + continue; + builder.append(p.getName()).append(separator); + } + + return builder.substring(0, builder.length() - 1); + } + + /** + * Check if given header lists all properties defined in given bean type. + * + * @param firstLine The header to check. + * @return True if the file header describes the current reference type, + * false otherwise. + */ + public final boolean isValidHeader(final String firstLine) { + return isValidHeader(firstLine, separator, beanInfo, ignorable); + } + + /** + * Check if given header lists all properties defined in given bean type. + * + * @param firstLine The header to check. + * @param separator The character which is used as separator between + * columns. + * @param beanInfo Bean information to check header against. + * @return True if the file header describes the current reference type, + * false otherwise. + */ + public static boolean isValidHeader(final String firstLine, final char separator, final BeanInfo beanInfo) { + return isValidHeader(firstLine, separator, beanInfo, null); + } + + public static boolean isValidHeader(final String firstLine, final char separator, final BeanInfo beanInfo, final Set ignorable) { + + final String[] splitted = firstLine.split(new StringBuilder("\\s*").append(separator).append("\\s*").toString()); + final Set headerNames = new HashSet<>(Arrays.asList(splitted)); + if (ignorable != null) + headerNames.addAll(ignorable); + + for (final PropertyDescriptor p : beanInfo.getPropertyDescriptors()) { + // Ignore properties unreadable or inherited from object. + if (p.getReadMethod() == null || p.getReadMethod().getDeclaringClass().equals(Object.class)) + continue; + + if (!headerNames.remove(p.getName())) { + return false; + } + } + + /* If we arrive here, it means all mandatory properties have been found + * in input header. If we're in read-only mode, we set it as valid, + * because for columns not present in java model, we can ignore them. + * On the contrary, if we must write into the file, we cannot allow + * losing data contained in it, so we ensure each column of the header + * can be bound to the java model. + */ + return true; + } + + /** + * Index property columns. + * + * @param header the header of the file. + */ + protected final void updatePropertyOrder(String header) { + // No header. Natural order initialized. + if (header == null) { + propertyOrder = new int[beanInfo.getPropertyDescriptors().length]; + for (int i = 0; i < propertyOrder.length; i++) { + propertyOrder[i] = i; + } + } else { + final String[] splitted = header.split(new StringBuilder("\\s*").append(separator).append("\\s*").toString()); + propertyOrder = new int[splitted.length]; + Arrays.fill(propertyOrder, -1); + final Map columns = new HashMap<>(splitted.length); + int i = 0; + for (final String columnName : splitted) { + columns.put(columnName, i++); + } + + i = 0; + for (final PropertyDescriptor p : beanInfo.getPropertyDescriptors()) { + final Integer colIndex = columns.get(p.getName()); + if (colIndex != null) + propertyOrder[colIndex] = i; + i++; + } + } + } + + /** + * Throw a new IOException whose message describe location (line, column) of + * the error. + * + * @param line Number of the line where error happened. Must be > 0. + * @param column Index of the field (not character column) on which error occurred. Must be > 0. + * @param token The field value we failed against. + * @param cause Original exception raised. + * @throws IOException In all cases. + */ + protected static void throwWithDescription(final int line, int column, Object token, final Exception cause) throws IOException { + final StringBuilder msg = new StringBuilder("Erreur : "); + if (line > 0) { + msg.append("ligne ").append(line).append(", "); + } + + if (column > 0) { + msg.append("colonne ").append(column).append(", "); + } + msg.append("valeur ").append(token); + throw new IOException(msg.toString(), cause); + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/CSVMappingBuilder.java b/core/src/main/java/fr/cenra/rhomeo/core/CSVMappingBuilder.java new file mode 100644 index 0000000..8806443 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/CSVMappingBuilder.java @@ -0,0 +1,79 @@ +/** + * 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.core; + +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class CSVMappingBuilder { + + Path target; + + Charset charset; + + char separator = CSVMapper.DEFAULT_SEPARATOR; + + public CSVMappingBuilder forPath(final Path target) { + if (Files.isDirectory(target)) { + throw new IllegalArgumentException("Provided path is a directory !"); + } + + this.target = target; + return this; + } + + public CSVMappingBuilder withEncoding(final Charset charset) { + this.charset = charset; + return this; + } + + public CSVMappingBuilder withSeparator(final char separator) { + this.separator = separator; + return this; + } + + public TypedCSVMappingBuilder forType(final Class dataType) { + return new TypedCSVMappingBuilder<>(this, dataType); + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/RhomeoCore.java b/core/src/main/java/fr/cenra/rhomeo/core/RhomeoCore.java new file mode 100644 index 0000000..059aa7e --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/RhomeoCore.java @@ -0,0 +1,554 @@ +/** + * 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.core; + +import com.fasterxml.jackson.databind.ObjectMapper; +import fr.cenra.rhomeo.api.Version; +import fr.cenra.rhomeo.core.data.UpdateInfo; +import fr.cenra.rhomeo.core.preferences.net.NetPreferences; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.GeneralSecurityException; +import java.text.NumberFormat; +import java.util.Optional; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Pattern; + +import org.apache.sis.referencing.CRS; +import org.apache.sis.util.logging.Logging; +import org.geotoolkit.factory.Hints; +import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.opengis.util.FactoryException; +import fr.cenra.rhomeo.core.list.CodeValue; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; +import java.nio.file.FileSystem; +import java.nio.file.spi.FileSystemProvider; +import java.text.DecimalFormat; +import java.text.ParseException; +import java.time.LocalDate; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javafx.scene.control.TableCell; +import javafx.util.Callback; +import javafx.util.StringConverter; + + +/** + * Regroups generic methods / constants used by the whole application. + * JavaFX features should be deported to fr.cenra.rhomeo.Rhomeo class, + * in the desktop module, not here. + * + * @author Cédric Briançon (Geomatys) + */ +public class RhomeoCore { + /** + * Generic logger to use in the whole application. + */ + public static final Logger LOGGER = Logging.getLogger("fr.cenra.rhomeo"); + + /** + * Title to display for all popups in the application. + */ + public static final String APPLICATION_TITLE = "Calculette RhoMeo"; + + /** + * Application main folder, in the user home. + */ + public static final String NAME = "rhomeo"; + + /** + * Key for the environment variable for the .rhomeo folder. + */ + public static final String ENV_RHOMEO_PATH_KEY = "rhomeo.path"; + + /** + * Path for the configuration app main folder. + */ + public static final Path CONFIGURATION_PATH; + static { + final String rhomeoPath = System.getProperty(ENV_RHOMEO_PATH_KEY) != null ? System.getProperty(ENV_RHOMEO_PATH_KEY) : NAME; + Path tmpPath = Paths.get(System.getProperty("user.home"), "."+ rhomeoPath); + + if (!Files.isDirectory(tmpPath)) { + try { + Files.createDirectory(tmpPath); + } catch (IOException ex) { + try { + tmpPath = Files.createTempDirectory(NAME); + } catch (IOException ex1) { + ex.addSuppressed(ex1); + throw new ExceptionInInitializerError(ex); + } + } + } + CONFIGURATION_PATH = tmpPath; + } + + /** + * System preference for the home directory of derby. + */ + public static final String DERBY_HOME_KEY = "derby.system.home"; + + /** + * Spring application context path in the resources. + */ + public static final String SPRING_CONTEXT_XML = "/fr/cenra/rhomeo/spring/spring-context.xml"; + + /** + * Path of the EPSG database. + */ + public static final Path EPSG_PATH = CONFIGURATION_PATH.resolve("EPSG"); + + /** + * Path to the folder which will contain reference lists. + */ + public static final Path REFERENCE_PATH = CONFIGURATION_PATH.resolve("references"); + + /** + * Path to the folder which will contain geographic reference datas. + * Path content will look like : + * ./site_id/dataname_year/*.shp + */ + public static final Path REFERENCIELS_GEO_PATH = CONFIGURATION_PATH.resolve("referential_geo"); + + /** + * Sites folder and shp name. + */ + public static final String SITES = "sites"; + + /** + * Path of the sites folder. + */ + public static final Path SITES_PATH = CONFIGURATION_PATH.resolve(SITES); + + /** + * Path of the sites folder. + */ + public static final Path SITES_SHP_PATH = SITES_PATH.resolve(SITES +".shp"); + + /** + * Path of the CSV file for dashboard published results. + */ + public static final Path DASHBOARD_PUBLISHED_RESULTS = CONFIGURATION_PATH.resolve("dashboard_results.csv"); + + /** + * Path of the JSON file for data contexts for sites / protocols. + */ + public static final Path DATA_CONTEXT_SITE_PATH = CONFIGURATION_PATH.resolve("data_contexts.json"); + + public static final Path RESULT_PATH = CONFIGURATION_PATH.resolve("results"); + /** + * Path to the context restoration folder. + */ + public static final Path RESTORATION_FOLDER = CONFIGURATION_PATH.resolve("state"); + + /** + * Number of millis for opening the connection before timeout. + */ + public static final int CONNECTION_TIMEOUT = 5000; + + /** + * Number of millis to wait after launching a timeout if no data has been transferred. + */ + public static final int READ_TIMEOUT = 20000; + + private static CoordinateReferenceSystem SITES_CRS; + private static final int SRID = 2154; + + /** + * Check for word character at the start of a text. + */ + public static final Pattern CODE_PATTERN = Pattern.compile("^[\\w\\.]+"); + + public enum FT_PROPERTIES { + the_geom, NAME, COUNTY, ODONATE, ORTHOPTERE, REFERENT, ORG, TYPE, REMARKS + } + + /** + * A regex to detect file extensions. + */ + public static final Pattern EXT_PATTERN = Pattern.compile("\\.\\w+$"); + + public static final DecimalFormat SIMPLE_DECIMAL_FORMAT = new DecimalFormat("0.##"); + public static final DecimalFormat SECOND_DECIMAL_FORMAT = new DecimalFormat("0.00"); + + /** + * Initializes the EPSG database, generating it if not yet present on the computer. + * + * @throws FactoryException + * @throws IOException + */ + public static void initEpsgDB() throws FactoryException, IOException { + initEpsgDB(true); + } + + /** + * Initialize properties needed by EPSG database. If input boolean is true, + * we'll fully load the database. + * + * @param checkInit Set to true if you want to ensure EPSG database is fully + * initialized. + * + * @throws FactoryException + * @throws IOException + */ + public static void initEpsgDB(final boolean checkInit) throws FactoryException, IOException { + // create a database in user directory + Files.createDirectories(RhomeoCore.EPSG_PATH); + + // work in lazy mode, do your best for lenient datum shift + Hints.putSystemDefault(Hints.LENIENT_DATUM_SHIFT, Boolean.TRUE); + + String derbyProp = null; + try { + derbyProp = System.getProperty(DERBY_HOME_KEY); + } finally { + if (derbyProp == null) { + System.setProperty(DERBY_HOME_KEY, EPSG_PATH.toAbsolutePath().toString()); + } + } + + // force loading epsg + if (checkInit) { + getSiteCRS(); + } + } + + public static CoordinateReferenceSystem getSiteCRS() throws FactoryException { + if (SITES_CRS == null) { + SITES_CRS = CRS.forCode("EPSG:"+ SRID); + } + + return SITES_CRS; + } + + /** + * Get current application version. + * + * @return The application version, may be empty or null if not found in the application packaging. + */ + public static String getVersion() { + return RhomeoCore.class.getPackage().getImplementationVersion(); + } + + /** + * Verify the presence of a new update for the application. + * + * @return The new version to install if an update exists, {@code null} if no updates found + * or no need to update. + */ + public static UpdateInfo existingUpdate() { + final String version = getVersion(); + if (version == null || version.isEmpty()) { + LOGGER.log(Level.INFO, "Invalid or not found version for this application"); + return null; + } + final Version localVersion = new Version(version); + final NetPreferences netPrefs = new NetPreferences(); + final String updateUrl = netPrefs.getPreference(NetPreferences.UPDATE_URL); + try (final InputStream stream = netPrefs.openConnection(netPrefs.getUpdateURL()).getInputStream()) { + final UpdateInfo update = new ObjectMapper().readValue(stream, UpdateInfo.class); + if (update.getVersion() != null && update.getVersion().compareTo(localVersion) > 0) + return update; + } catch (IOException|GeneralSecurityException e) { + LOGGER.log(Level.WARNING, "Cannot access update service : ".concat(updateUrl), e); + } + + return null; + } + + /** + * Convert byte number given in parameter in a human readable string. It tries + * to fit the best unit. Ex : if you've got a number higher than a thousand, + * input byte number will be expressed in kB. If you've got more than a million, + * you've got it as MB + * @param byteNumber Byte quantity to display + * @return A string displaying byte number converted in fitting unit, along with unit symbol. + */ + public static String toReadableSize(final long byteNumber) { + final NumberFormat format = NumberFormat.getNumberInstance(); + format.setMinimumFractionDigits(2); + format.setMaximumFractionDigits(2); + if (byteNumber < 0) { + return "inconnu"; + } else if (byteNumber < 1e3) { + return "" + byteNumber + " octets"; + } else if (byteNumber < 1e6) { + return "" + format.format(byteNumber / 1e3) + " ko"; + } else if (byteNumber < 1e9) { + return "" + format.format(byteNumber / 1e6) + " Mo"; + } else if (byteNumber < 1e12) { + return "" + format.format(byteNumber / 1e9) + " Go"; + } else { + return "" + (byteNumber / 1e12) + " To"; + } + } + + /** + * + * @param first First string to test. + * @param second Second string to test. + * @return True if both strings are null or blank. False if at least one of + * them contains something else than spaces. + */ + public static boolean bothEmpty(final String first, final String second) { + return (first == null || first.trim().isEmpty()) && (second == null || second.trim().isEmpty()); + } + + /** + * + * @param first First string to test. + * @param second Second string to test. + * @return True if both strings are equal or blank. False if one of them is + * not blank, or they're not equal. + */ + public static boolean equivalent(final String first, final String second) { + if (bothEmpty(first, second)) { + return true; + } + + return first == null || second == null? false : first.equals(second); + } + + /** + * Try to find an object of given type with the given code. + * Note : Works only with enums. + * + * @param Type of target coded list. + * @param dataType Type of enum to search into + * @param code Code of the object to return. + * @return An object of the queried type with queried code, or nothing if we + * cannot find any object matching. + */ + public static Optional getByCode(final Class dataType, Object code) { + if (dataType.isEnum() && code != null) { + for (final T candid : dataType.getEnumConstants()) { + if (candid.getCode().equals(code)) { + return Optional.of(candid); + } + } + } + + return Optional.empty(); + } + + /** + * Compute the quantile of a given data suite. For more details, see + * https://en.wikipedia.org/wiki/Quantile + * + * Note : we differ from above wiki definition on even computing. Instead of + * arbitrary ceiling computed position, we get the average of its two + * ascending value in the data suite. + * + * @param data Data suite to find a quantile for. If input array is null or + * empty, the method will miserably fail, so be careful.IMPORTANT : IT MUST + * BE SORTED BY ASCENDING ORDER ! + * @param factor Quantile factor. It must be between 0 and 1 (otherwise, the + * algorithm will end up very badly) representing which portion of the data + * we want. + * @return The queried quantile + */ + public static float quantile(final float[] data, final float factor) { + final float position = (data.length -1) * factor; + final double floor = StrictMath.floor(position); + final int floorInt = (int)floor; + if (position == floor) { + // We take directly the pointed value. + return data[floorInt]; + } + + final double ratio = position - floor; + final double extraValue = (data[floorInt + 1] - data[floorInt]) * ratio; + + return (float) (data[floorInt] + extraValue); + } + + /** + * Compute the quantile of a given data suite. For more details, see + * https://en.wikipedia.org/wiki/Quantile + * + * Note : we differ from above wiki definition on even computing. Instead of + * arbitrary ceiling computed position, we get the average of its two + * ascending value in the data suite. + * + * @param data Data suite to find a quantile for. If input array is null or + * empty, the method will miserably fail, so be careful.IMPORTANT : IT MUST + * BE SORTED BY ASCENDING ORDER ! + * @param factor Quantile factor. It must be between 0 and 1 (otherwise, the + * algorithm will end up very badly) representing which portion of the data + * we want. + * @return The queried quantile + */ + public static double quantile(final double[] data, final float factor) { + final float position = (data.length -1) * factor; + final double floor = StrictMath.floor(position); + final int floorInt = (int) floor; + if (position == floor) { + // We take directly the pointed value. + return data[floorInt]; + } + + final double ratio = position - floor; + final double extraValue = (data[floorInt + 1] - data[floorInt]) * ratio; + + return data[floorInt] + extraValue; + } + + /** + * Create a new file system, allowing to view the content of a zip file as + * a file system. + * /!\ Close the returned {@link FileSystem} once you're done with it ! + * + * @param zipPath A path pointing on a zip file. If it does not exist, it + * will be created. + * @return A file system pointing on given zip file. + * @throws URISyntaxException If we cannot create a valid URI from given + * path. + * @throws IOException If the file occurs while accessing zip file. + */ + public static FileSystem toZipFileSystem(final Path zipPath) throws URISyntaxException, IOException { + // Don't call FileSystems.newFileSystems(URI, Map), because of a bug which + // encode twice URIs in jar file system : https://bugs.openjdk.java.net/browse/JDK-8131067 + final List installedProviders = FileSystemProvider.installedProviders(); + for (final FileSystemProvider fsp : installedProviders) { + if ("jar".equals(fsp.getScheme())) { + Map properties = new HashMap<>(); + properties.put("encoding", StandardCharsets.UTF_8.name()); + properties.put("create", "true"); + return fsp.newFileSystem(zipPath, properties); + } + } + + throw new IOException("No file system found for ZIP encoding."); + } + + /** + * Ensure input dates are either strictly equals, or represent the same moment. + * @param first + * @param second + * @return True if the 2 dates are same reference, or respect {@link LocalDate#isEqual(java.time.chrono.ChronoLocalDate) }. + */ + public static boolean checkEquality(final LocalDate first, final LocalDate second) { + return first == second || first != null && second != null && first.isEqual(second); + } + + /** + * Write given local date into the specified object output. If input is null, + * a special flag is written, so a null value will be returned by {@link #readDate(java.io.ObjectInput) }. + * @param toWrite Local date to serialize. + * @param destination Output to write into. + * @throws IOException If an error occcurs while writing in output stream. + */ + public static void writeDate(final LocalDate toWrite, final ObjectOutput destination) throws IOException { + if (toWrite == null) { + destination.writeBoolean(true); + } else { + destination.writeBoolean(false); + destination.writeShort(toWrite.getYear()); + destination.write(toWrite.getMonthValue()); + destination.write(toWrite.getDayOfMonth()); + } + } + + /** + * Read date contained in given source at current position. + * IMPORTANT : Only read dates written using {@link #writeDate(java.time.LocalDate, java.io.ObjectOutput) } + * method. + * @param source Object stream to read from. + * @return Read date, or null. + * @throws IOException + */ + public static LocalDate readDate(final ObjectInput source) throws IOException { + if (source.readBoolean()) + return null; + return LocalDate.of(source.readShort(), source.readByte(), source.readByte()); + } + + public static final Callback ROUNDING_CELL_FACTORY = value -> { + return new TableCell() { + @Override + protected void updateItem(Number item, boolean empty) { + super.updateItem(item, empty); + if (empty || item == null) { + setText(null); + } else { + setText(SIMPLE_DECIMAL_FORMAT.format(item)); + } + } + }; + }; + + public static final StringConverter DOUBLE_CONVERTER = new StringConverter() { + @Override + public String toString(Double object) { + if (object == null) + return ""; + else + return SECOND_DECIMAL_FORMAT.format(object); + } + + @Override + public Double fromString(String string) { + if (string == null || (string = string.trim()).isEmpty()) { + return 0d; + } else + try { + return SECOND_DECIMAL_FORMAT.parse(string).doubleValue(); + } catch (ParseException ex) { + try { + return Double.valueOf(string); + } catch (Exception ex2) { + ex.addSuppressed(ex2); + RhomeoCore.LOGGER.log(Level.FINE, "Unconvertible string.", ex); + } + } + + return 0d; + } + }; +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/RhomeoRuntimeException.java b/core/src/main/java/fr/cenra/rhomeo/core/RhomeoRuntimeException.java new file mode 100644 index 0000000..5705d16 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/RhomeoRuntimeException.java @@ -0,0 +1,58 @@ +/** + * 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.core; + +/** + * @author Cédric Briançon (Geomatys) + */ +public class RhomeoRuntimeException extends RuntimeException { + public RhomeoRuntimeException() {} + + public RhomeoRuntimeException(String message) { + super(message); + } + + public RhomeoRuntimeException(String message, Throwable cause) { + super(message, cause); + } + + public RhomeoRuntimeException(Throwable cause) { + super(cause); + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/Session.java b/core/src/main/java/fr/cenra/rhomeo/core/Session.java new file mode 100644 index 0000000..6dcbcce --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/Session.java @@ -0,0 +1,533 @@ +/** + * 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.core; + +import fr.cenra.rhomeo.api.Version; +import fr.cenra.rhomeo.api.data.DataContext; +import fr.cenra.rhomeo.api.data.Dataset; +import fr.cenra.rhomeo.api.data.ObjectWrapper; +import fr.cenra.rhomeo.api.data.Protocol; +import fr.cenra.rhomeo.api.data.Reference; +import fr.cenra.rhomeo.api.data.ReferenceDescription; +import fr.cenra.rhomeo.api.data.Site; +import fr.cenra.rhomeo.api.data.Statement; +import fr.cenra.rhomeo.api.process.ProcessContext; +import fr.cenra.rhomeo.api.result.Index; +import fr.cenra.rhomeo.api.ui.StatementEditor; +import fr.cenra.rhomeo.api.process.Indicator; +import fr.cenra.rhomeo.api.result.AdditionalValue; +import fr.cenra.rhomeo.api.ui.StatementEditorSpi; +import fr.cenra.rhomeo.core.data.DashboardResultsManager; +import fr.cenra.rhomeo.core.data.DataContextManager; +import fr.cenra.rhomeo.core.data.ReferenceManager; +import fr.cenra.rhomeo.core.preferences.ftp.FTPPreferences; + +import java.beans.IntrospectionException; +import java.io.IOException; +import java.net.UnknownHostException; +import java.security.GeneralSecurityException; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +import fr.cenra.rhomeo.core.util.SerializableDataContext; +import java.util.HashMap; +import java.util.HashSet; +import javafx.beans.property.ReadOnlyObjectProperty; +import javafx.beans.property.ReadOnlyObjectWrapper; +import javax.validation.constraints.NotNull; + +import org.apache.commons.net.ftp.FTPClient; +import org.apache.sis.util.ArgumentChecks; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.support.AbstractApplicationContext; +import org.springframework.stereotype.Component; + +/** + * Represents the application session for a user. + * + * @author Alexis Manin (Geomatys) + */ +@Component +public class Session implements ApplicationContextAware { + + private static Session INSTANCE; + private ApplicationContext ctx; + + private Dataset dataset; + private DataContext dataContext; + private ProcessContext processContext; + private Set results; + private final Set additionalValues = new HashSet<>(); + + @Autowired + private List protocols; + + @Autowired + private List indicators; + + @Autowired + private DataContextManager contextManager; + + @Autowired + private DashboardResultsManager resultsManager; + + private final ReadOnlyObjectWrapper workflowStep = new ReadOnlyObjectWrapper<>(); + + public static Session getInstance() throws IllegalStateException { + if (INSTANCE == null) { + throw new IllegalStateException("Application context not initialized !"); + } + + return INSTANCE; + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + if (applicationContext != null) { + ctx = applicationContext; + INSTANCE = this; + } else { + INSTANCE = null; + } + } + + /** + * Close the session, releasing all resources. + */ + public void close() { + if (ctx instanceof AbstractApplicationContext) { + ((AbstractApplicationContext)ctx).close(); + } + + INSTANCE = null; + } + + /** + * Try to create a new instance for given bean name. + * + * @param Type of the wanted bean. + * @param qualifier Name of the wanted prototype. + * @param beanClass The class to use to create Spring prototype. + * @return A new bean corresponding to the prototype registered for given qualifier. + * @throws IllegalArgumentException If given bean definition is not a prototype. + */ + public T createPrototype(final String qualifier, final Class beanClass) throws IllegalArgumentException { + if (ctx.getAutowireCapableBeanFactory().isPrototype(qualifier)) { + return ctx.getBean(qualifier, beanClass); + } else { + throw new IllegalArgumentException("Given qualifier does not represent a prototype object !"); + } + } + + /** + * Try to create a new instance for given bean name. + * + * @param qualifier Name of the wanted prototype. + * @return A new bean corresponding to the prototype registered for given qualifier. + * @throws IllegalArgumentException If given bean definition is not a prototype. + */ + public Object createPrototype(final String qualifier) throws IllegalArgumentException { + if (ctx.getAutowireCapableBeanFactory().isPrototype(qualifier)) { + return ctx.getBean(qualifier); + } else { + throw new IllegalArgumentException("Given qualifier does not represent a prototype object !"); + } + } + + /** + * Try to create a new instance of given type. + * + * @param Type of the wanted bean. + * @param beanClass The class to use to find Spring prototype definition. + * @param constructorArgs Possible list of constructor arguments for the requiered prototype. + * @return A new bean of given type. + * @throws IllegalArgumentException If given bean definition is not a prototype. + */ + public T createPrototype(final Class beanClass, final Object... constructorArgs) throws BeansException { + return ctx.getBean(beanClass, constructorArgs); + } + + /** + * Create a new connection over the FTP service providing {@link Reference} + * data. The provided {@link FTPClient} must be closed using {@link FTPClient#disconnect() } + * once you've finished your work. + * + * @return A client to exchange data with FTP service which contains reference files. + * + * @throws IOException If we cannot connect to distant service. + * @throws java.security.GeneralSecurityException If an authentication is + * required, but we cannot access to password. + */ + @NotNull + public FTPClient connectReferenceFTP() throws IOException, GeneralSecurityException { + return ctx.getBean(FTPPreferences.class).getAccess(FTPPreferences.ACCESS_POINTS.REFERENCES).createClient(); + } + + /** + * Create a new connection over the FTP service providing result data. + * data. The provided {@link FTPClient} must be closed using {@link FTPClient#disconnect() } + * once you've finished your work. + * + * @return A client to exchange data with FTP service which contains result files. + * + * @throws UnknownHostException If we cannot connect to distant service. + * @throws java.security.GeneralSecurityException If an authentication is + * required, but we cannot access to password. + */ + @NotNull + public FTPClient connectResultFTP() throws IOException, GeneralSecurityException { + return ctx.getBean(FTPPreferences.class).getAccess(FTPPreferences.ACCESS_POINTS.RESULTS).createClient(); + } + + /** + * Try to find a singleton or prototype for the given class. + * + * @param Type of the wanted bean. + * @param beanClass The class to use to find Spring prototype definition. + * @return A new bean of given type. + */ + public T getBean(final Class beanClass) { + return ctx.getBean(beanClass); + } + /** + * Try to find a singleton or prototype for the given class. + * + * @param beanName The name of a bean to find Spring prototype definition. + * @return A new bean of given type. + */ + public Object getBean(final String beanName) { + return ctx.getBean(beanName); + } + + + public DataContext getDataContext() { + return dataContext; + } + + public Dataset getDataset() { + return dataset; + } + + /** + * Request a new edition context for given site and protocol. + * + * /!\ Use with care ! Any call to this method will reset previously seized + * data. + * + * @param site The site to start edition for. + * @param protocol The protocol defining data type to seize. + */ + public void startEdition(final Site site, final Protocol protocol) { + ArgumentChecks.ensureNonNull("Site", site); + ArgumentChecks.ensureNonNull("Protocol", protocol); + if (!protocol.isCompatible(site)) { + throw new IllegalArgumentException("Target site is not compatible with chosen protocol !"); + } + + final SerializableDataContext srDataContext; + try { + srDataContext = contextManager.loadContext(site, protocol); + } catch (IOException ex) { + throw new RhomeoRuntimeException(ex); + } + + if (srDataContext != null) { + final DataContext context = srDataContext.toDataContext(this); + if (context != null) { + this.dataContext = context; + } else { + this.dataContext = new DataContext(site, protocol); + } + } else { + this.dataContext = new DataContext(site, protocol); + } + + // Now that we've got the data context, we'll check that its reference + // versions are installed. If not, we'll remove them from data context. + checkDataContext(dataContext); + + this.dataset = new Dataset(protocol); + } + + private static void checkDataContext(final DataContext ctx) { + for (final ReferenceDescription description : ctx.getProtocol().getReferenceTypes()) { + final ReferenceManager manager; + try { + manager = ReferenceManager.getOrCreate(description); + } catch (IntrospectionException ex) { + throw new RhomeoRuntimeException(ex); + } + if (!manager.getInstalledVersions().contains(ctx.getReferences().get(description.getReferenceType()))) { + ctx.getReferences().remove(description.getReferenceType()); + } + } + } + + /** + * A site name has been updated so update this old name in all serialized files + * working on the old name. + * + * @param site New site containing new name. + * @param oldName Old site name. + */ + public void serializeUpdateSiteName(Site site, String oldName) throws IOException, IntrospectionException, ReflectiveOperationException { + resultsManager.updateDashboardResultsSiteName(site, oldName); + contextManager.updateReferencesSiteName(oldName, site.getName()); + } + + /** + * A site has been deleted so delete all references of this site name in previously + * serialized files for this site. + * + * @param siteName + */ + public void serializeDeleteSite(final String siteName) throws IOException, IntrospectionException, ReflectiveOperationException { + resultsManager.removeDashboardResultsForSite(siteName); + contextManager.removeReferencesForSite(siteName); + } + + /** + * Get results for the current {@linkplain DataContext data context}. + * + * @return A set of results, may be {@code null} or empty. + */ + public Set getResults() { + return results; + } + + /** + * Set results for the current {@linkplain DataContext data context}. + * + * @param results a set of results. + */ + public void setResults(final Set results) { + this.results = results; + } + + public Set getAdditionalValues() { + return additionalValues; + } + + /** + * Get the process context. + * + * @return process context, may be {@code null}. + */ + public ProcessContext getProcessContext() { + return processContext; + } + + public void setProcessContext(ProcessContext processContext) { + this.processContext = processContext; + } + + /** + * + * @return Observable property describing current application state. + */ + public ReadOnlyObjectProperty workflowStepProperty() { + return workflowStep.getReadOnlyProperty(); + } + + /** + * + * @return application current working step. If null, it means application is + * waiting for the user to choose a protocol to operate on. + */ + public WorkflowStep getWorkflowStep() { + return workflowStep.get(); + } + + /** + * Request application to focus on given workflow step. This method will + * first ensure that all needed data can be found. If not, the step is left + * unchanged. + * + * @param newStep The step we want to go to. + * @return True if session succeeded to update the application mode. False + * if it cannot perform queried operation (due to missing data). + */ + public boolean requestWorkflowStep(final WorkflowStep newStep) { + if (newStep == null) { + clearWorkflow(); + + } else { + switch (newStep) { + case DATASET: + if (dataContext != null) + workflowStep.set(newStep); + break; + case PROCESS: + if (processContext != null && dataContext != null) { + checkDataContext(dataContext); + if (dataContext.getReferences().size() >= dataContext.getProtocol().getReferenceTypes().size()) { + workflowStep.set(newStep); + } + } + break; + case RESULT: + case FINALIZATION: + if (results != null) + workflowStep.set(newStep); + } + } + + return newStep == workflowStep.get(); + } + + private void clearWorkflow() { + dataContext = null; + dataset = null; + processContext = null; + results = null; + additionalValues.clear(); + + workflowStep.set(null); + } + + /** + * Get all protocols found. + * + * @return All protocols. + */ + public List getProtocols() { + return protocols; + } + + /** + * Get all indicators found. + * + * @return All indicators. + */ + public List getIndicators() { + return indicators; + } + + /** + * Return the description object corresponding to given {@link Reference} class. + * @param Type of reference to get a description for. + * @param refType Type of reference to get a description for. + * @return Description object for requested reference class. + */ + public ReferenceDescription getDescription(final Class refType) { + final Map beans = ctx.getBeansOfType(ReferenceDescription.class); + for (final ReferenceDescription desc : beans.values()) { + if (desc.getReferenceType().equals(refType)) { + return desc; + } + } + + return null; + } + + /** + * Analyze the given object, and inject autowired fields according to the + * current application context content. + * @param o The object to inject dependencies into. + */ + public void injectDependencies(Object o) { + ctx.getAutowireCapableBeanFactory().autowireBean(o); + } + + public Optional findEditor(Class dataType) { + ArgumentChecks.ensureNonNull("Data type", dataType); + final Map beans = ctx.getBeansOfType(StatementEditorSpi.class); + StatementEditorSpi fallback = null; + Class editorType; + for (final StatementEditorSpi spi : beans.values()) { + editorType = spi.getDataType(); + if (dataType.equals(editorType)) { + return Optional.of(spi.createEditor()); + } else if (editorType.isAssignableFrom(dataType)) { + if (fallback == null || fallback.getDataType().isAssignableFrom(editorType)) { + fallback = spi; + } + } + } + + return fallback == null? Optional.empty() : Optional.of(fallback.createEditor()); + } + + /** + * Find and return the first found wrapper for given data type, if any. + * + * @param Data type to wrap. + * @param dataType The type we want to export. + * @return First found wrapper for input class, or an empty optional if no + * wrapper can be found. + */ + public Optional> getWrapper(final Class dataType) { + if (dataType == null) + return Optional.empty(); + final Map beans = ctx.getBeansOfType(ObjectWrapper.class); + for (final ObjectWrapper wrapper : beans.values()) { + if (wrapper.getInputType().equals(dataType)) + return Optional.of(wrapper); + } + + return Optional.empty(); + } + + /** + * Create a new map whose keys are description for given reference type. + * Values are not changed. + * + * We need this to convert reference versions provided by data context into + * something usable for metadata export. + * + * @param input The map to get values and keys to transform from. + * @return Copy of input map, with transformed keys. + */ + public Map transform(final Map, Version> input) { + if (input == null || input.isEmpty()) + return (Map)input; + + final Map result = new HashMap<>(input.size()); + for (final Map.Entry, Version> entry : ((Map, Version>) input).entrySet()) { + result.put(getDescription(entry.getKey()), entry.getValue()); + } + + return result; + } +} \ No newline at end of file diff --git a/core/src/main/java/fr/cenra/rhomeo/core/TypedCSVMappingBuilder.java b/core/src/main/java/fr/cenra/rhomeo/core/TypedCSVMappingBuilder.java new file mode 100644 index 0000000..1e3025b --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/TypedCSVMappingBuilder.java @@ -0,0 +1,100 @@ +/** + * 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.core; + +import java.beans.IntrospectionException; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Path; +import java.util.HashSet; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class TypedCSVMappingBuilder extends CSVMappingBuilder { + + private final Class type; + + private final HashSet ignorable = new HashSet<>(); + + public TypedCSVMappingBuilder(final CSVMappingBuilder builder, final Class type) { + this.target = builder.target; + this.charset = builder.charset; + this.separator = builder.separator; + + this.type = type; + } + + public TypedCSVMappingBuilder setIgnorable(String propertyName) { + if (propertyName != null && !(propertyName = propertyName.trim()).isEmpty()) { + ignorable.add(propertyName); + } + return this; + } + + public final CSVEncoder acquireEncoder() throws IOException, IntrospectionException { + return new CSVEncoder<>(target, type, separator, charset, ignorable); + } + + + public final CSVDecoder acquireDecoder() throws IOException, IntrospectionException { + return new CSVDecoder<>(target, type, separator, charset, ignorable); + } + + @Override + public TypedCSVMappingBuilder withSeparator(char separator) { + super.withSeparator(separator); + return this; + } + + @Override + public TypedCSVMappingBuilder withEncoding(Charset charset) { + super.withEncoding(charset); + return this; + } + + @Override + public TypedCSVMappingBuilder forPath(Path target) { + super.forPath(target); + return this; + } + + +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/WorkflowStep.java b/core/src/main/java/fr/cenra/rhomeo/core/WorkflowStep.java new file mode 100644 index 0000000..7791f47 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/WorkflowStep.java @@ -0,0 +1,55 @@ +/** + * 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.core; + +/** + * Describes possible states for the application. More accurately, it represents + * each step of the working process a user must go through to extract / publish + * results. In apparition order it is : + * + * DATASET : Data seizure / import / edition. + * PROCESS : Process parameterisation and execution. + * RESULT : Result compilation and consultation. + * FINALIZATION : Options of publication / extraction of the computed results. + * + * @author Alexis Manin (Geomatys) + */ +public enum WorkflowStep { + DATASET, PROCESS, RESULT, FINALIZATION; +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/data/DashboardResultsManager.java b/core/src/main/java/fr/cenra/rhomeo/core/data/DashboardResultsManager.java new file mode 100644 index 0000000..06a4b23 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/data/DashboardResultsManager.java @@ -0,0 +1,560 @@ +/** + * 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.core.data; + +import com.fasterxml.jackson.core.JsonEncoding; +import fr.cenra.rhomeo.api.data.Protocol; +import fr.cenra.rhomeo.api.data.Site; +import fr.cenra.rhomeo.api.process.Indicator; +import fr.cenra.rhomeo.api.result.DashboardResultItem; +import fr.cenra.rhomeo.api.result.Index; +import fr.cenra.rhomeo.api.result.IndicatorValuesByYearItem; +import fr.cenra.rhomeo.core.CSVDecoder; +import fr.cenra.rhomeo.core.CSVEncoder; +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.RhomeoRuntimeException; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.result.ResultStorage; +import fr.cenra.rhomeo.core.util.ExportUtils; +import fr.cenra.rhomeo.core.util.GeometryUtils; +import fr.cenra.rhomeo.core.data.site.SiteRepositoryImpl; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import org.apache.commons.net.ftp.FTPClient; +import org.apache.sis.storage.DataStoreException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.beans.IntrospectionException; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.security.GeneralSecurityException; +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.StringJoiner; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.stream.Collectors; +import org.geotoolkit.data.geojson.GeoJSONStreamWriter; +import org.geotoolkit.nio.IOUtilities; + +/** + * Handle results displayed on the dashboard. + * + * @author Cédric Briançon (Geomatys) + */ +@Component +public class DashboardResultsManager { + + protected static final String HISTORY_LOG = "history.log"; + + @Autowired + private Session session; + + @Autowired + private ResultStorage resultStorage; + + /** + * Get all previously-published result items in the dashboard. + * + * @return A list of results items. + * @throws IOException + * @throws ReflectiveOperationException + * @throws IntrospectionException + */ + private List getDashboardResultsItems() throws IOException, ReflectiveOperationException, IntrospectionException { + if (!Files.exists(RhomeoCore.DASHBOARD_PUBLISHED_RESULTS)) { + return new ArrayList<>(); + } + final CSVDecoder decoder = new CSVDecoder<>(RhomeoCore.DASHBOARD_PUBLISHED_RESULTS, DashboardResultItem.class); + return decoder.decode(); + } + + + /** + * Regroups results for indicator by year. + * + * @param site Site to use. Should not be {@code null}. + * @return Results, never {@code null} + * @throws IntrospectionException + * @throws ReflectiveOperationException + * @throws IOException + */ + public ObservableList getDashboardResultsByYear(final Site site) throws IntrospectionException, ReflectiveOperationException, IOException { + final ObservableList items = getDashboardResultsForSite(site); + final Map indicatorsByYear = new HashMap<>(); + for (final DashboardResultItem item : items) { + final int year = item.getYear(); + if (indicatorsByYear.containsKey(year)) { + final IndicatorValuesByYearItem itemToUpdate = indicatorsByYear.get(year); + itemToUpdate.addValueForIndicator(item.getIndicator(), item.getValue(), item.isPublished()); + } else { + final IndicatorValuesByYearItem itemToAdd = new IndicatorValuesByYearItem(year); + itemToAdd.addValueForIndicator(item.getIndicator(), item.getValue(), item.isPublished()); + indicatorsByYear.put(year, itemToAdd); + } + } + return FXCollections.observableArrayList(indicatorsByYear.values()); + } + + /** + * Get previously-published result items for the specified site. + * + * @param site the selected site. + * @return A list of results items, never {@code null} + * @throws IOException + * @throws ReflectiveOperationException + * @throws IntrospectionException + */ + public ObservableList getDashboardResultsForSite(final Site site) throws IOException, ReflectiveOperationException, IntrospectionException { + final List allRes = getDashboardResultsItems(); + final ObservableList resForSite = FXCollections.observableArrayList(); + resForSite.addAll(allRes.stream() + .filter(item -> site.getName() != null && site.getName().equals(item.getSite())) + .collect(Collectors.toList())); + return resForSite; + } + + /** + * Add or replace a list of result items. + * + * @param itemsToAdd A list of items to serialize. + * @throws IOException + * @throws ReflectiveOperationException + * @throws IntrospectionException + */ + public void addDashboardResultsItems(final List itemsToAdd) throws IOException, ReflectiveOperationException, IntrospectionException { + // Ensures the CSV file to write will exist + if (!Files.exists(RhomeoCore.DASHBOARD_PUBLISHED_RESULTS)) { + Files.createFile(RhomeoCore.DASHBOARD_PUBLISHED_RESULTS); + } + + // First get existing results + final List existingResults = getDashboardResultsItems(); + + // Merge new / updates results into existing results. + for (final DashboardResultItem itemToAdd : itemsToAdd) { + boolean toAdd = true; + for (final DashboardResultItem existing : existingResults) { + if (existing.getSite().equals(itemToAdd.getSite()) && + existing.getIndicator().equals(itemToAdd.getIndicator()) && + existing.getYear() == itemToAdd.getYear()) + { + // Same site, indicator and year, so just update the value + existing.setValue(itemToAdd.getValue()); + existing.setPublished(itemToAdd.isPublished()); + toAdd = false; + break; + } + } + + // Not found for update, so just add it. + if (toAdd) { + existingResults.add(itemToAdd); + } + } + + // Serialize them + final CSVEncoder encoder = new CSVEncoder<>(RhomeoCore.DASHBOARD_PUBLISHED_RESULTS, DashboardResultItem.class); + encoder.encode(existingResults, true); + } + + /** + * Rename site name in dashboard results. Use it when a site is renamed. + * + * @param site New site containing new name. + * @param oldName Old site name. + * @throws IntrospectionException + * @throws ReflectiveOperationException + * @throws IOException + */ + public void updateDashboardResultsSiteName(final Site site, final String oldName) throws IntrospectionException, ReflectiveOperationException, IOException { + if (!Files.exists(RhomeoCore.DASHBOARD_PUBLISHED_RESULTS)) { + return; + } + // First get existing results + final List existingResults = getDashboardResultsItems(); + existingResults.stream().filter(item -> item.getSite().equals(oldName)) + .forEach(item -> item.setSite(site.getName())); + + // Serialize them + final CSVEncoder encoder = new CSVEncoder<>(RhomeoCore.DASHBOARD_PUBLISHED_RESULTS, DashboardResultItem.class); + encoder.encode(existingResults, true); + } + + /** + * Update existing results, for published and value properties. + * + * @param itemsToUpdate + * @throws IntrospectionException + * @throws ReflectiveOperationException + * @throws IOException + */ + public void updateResults(final List itemsToUpdate) throws IntrospectionException, ReflectiveOperationException, IOException { + if (itemsToUpdate == null || itemsToUpdate.isEmpty()) { + return; + } + + final CSVEncoder encoder = new CSVEncoder<>(RhomeoCore.DASHBOARD_PUBLISHED_RESULTS, DashboardResultItem.class); + // Ensures the CSV file to write will exist. If not, create it and directly serialize them + if (!Files.exists(RhomeoCore.DASHBOARD_PUBLISHED_RESULTS)) { + Files.createFile(RhomeoCore.DASHBOARD_PUBLISHED_RESULTS); + // Serialize them + encoder.encode(itemsToUpdate, true); + return; + } + + // First get existing results + final List existingResults = getDashboardResultsItems(); + for (final DashboardResultItem itemToUp : itemsToUpdate) { + final int index = existingResults.indexOf(itemToUp); + if (index > -1) { + existingResults.set(index, itemToUp); + } + } + + encoder.encode(existingResults, true); + } + + /** + * Remove results entries for the specified site name. + * + * @param siteName + * @throws IntrospectionException + * @throws ReflectiveOperationException + * @throws IOException + */ + public void removeDashboardResultsForSite(final String siteName) throws IntrospectionException, ReflectiveOperationException, IOException { + if (siteName == null) { + return; + } + if (!Files.exists(RhomeoCore.DASHBOARD_PUBLISHED_RESULTS)) { + return; + } + + // First get existing results + final List existingResults = getDashboardResultsItems(); + final List filteredList = existingResults.stream() + .filter(item -> !item.getSite().equals(siteName)) + .collect(Collectors.toList()); + + // Delete all result files associated to the site + resultStorage.deleteIfExists(siteName); + + // Serialize them + final CSVEncoder encoder = new CSVEncoder<>(RhomeoCore.DASHBOARD_PUBLISHED_RESULTS, DashboardResultItem.class); + encoder.encode(filteredList, true); + + } + + /** + * Send results currently contained in the session to the FTP service for + * result publication. + * + * Structure on the FTP is: + *
+     * results
+     * |- county code
+     * |--|- SHA1 geometry site
+     * |--|--|- protocol
+     * |--|--|--|- UUID
+     * |--|--|--|--|- site.geojson
+     * |--|--|--|--|- metadata.json
+     * |--|--|--|--|- result.csv
+     * ...
+     * 
+ */ + public void publishResults() throws IOException, DataStoreException, IntrospectionException, GeneralSecurityException { + // Move to the right directory + final AtomicReference dirRef = new AtomicReference(); + resultStorage.publish(() -> { + FTPClient ftpClient = null; + try { + ftpClient = session.connectResultFTP(); + final String rootDir = ftpClient.printWorkingDirectory(); + prepareSiteDirectory(session.getDataContext().getSite(), ftpClient); + prepareResultDirectory(session.getDataContext().getProtocol(), ftpClient); + dirRef.set(ftpClient.printWorkingDirectory().replace(rootDir, "")); + return ftpClient; + } catch (Exception e) { + if (ftpClient != null) + try { + ftpClient.disconnect(); + } catch (IOException ex) { + e.addSuppressed(ex); + } + throw new RhomeoRuntimeException(e); + } + }); + + // log publication + final Object bundlePath = dirRef.get(); + if (bundlePath != null) { + Optional log = fromSession(session, bundlePath.toString()); + if (log.isPresent()) { + log(session.connectResultFTP(), log.get()); + } + } + } + + /** + * Publish site results on the FTP. + * Structure on the FTP is: + *
+     * results
+     * |- county code
+     * |--|- SHA1 geometry site
+     * |--|--|- protocol
+     * |--|--|--|- UUID
+     * |--|--|--|--|- site.geojson
+     * |--|--|--|--|- metadata.json
+     * |--|--|--|--|- result.csv
+     * ...
+     * 
+ * + * @param site + * @param resultsForSite + * @param ftpClient + * @throws IOException + * @throws IntrospectionException + * @throws ReflectiveOperationException + */ + public void publishResults(final Site site, final List resultsForSite, final FTPClient ftpClient) + throws IOException, IntrospectionException, ReflectiveOperationException, DataStoreException + { + final Path tempFolder = Files.createTempDirectory("site"); + final Path siteJsonPath = ExportUtils.writeGeoJson(site, tempFolder); + final ArrayList reallyPublished = new ArrayList<>(resultsForSite.size()); + final ArrayList logs = new ArrayList<>(resultsForSite.size()); + final String rootDir = ftpClient.printWorkingDirectory(); + try { + prepareSiteDirectory(site, ftpClient); + for (final DashboardResultItem item : resultsForSite) { + final Object prototypeIndic = session.getBean(item.getIndicator()); + if (prototypeIndic instanceof Indicator) { + final Indicator indicator = (Indicator) prototypeIndic; + prepareResultDirectory(indicator.getProtocol(), ftpClient); + + try (final InputStream in = Files.newInputStream(siteJsonPath, StandardOpenOption.READ)) { + ftpClient.storeFile("site.geojson", in); + } + + resultStorage.publish(item, ftpClient); + item.setPublished(true); + reallyPublished.add(item); + + logs.add(new Log(site, ftpClient.printWorkingDirectory().replace(rootDir, ""), new int[]{item.getYear()}, indicator)); + + if (!ftpClient.changeToParentDirectory()) { + throw new IOException("Unable to change to parent directory"); + } + if (!ftpClient.changeToParentDirectory()) { + throw new IOException("Unable to change to parent directory"); + } + } + } + + } finally { + try { + IOUtilities.deleteRecursively(tempFolder); + } catch (Exception e) { + RhomeoCore.LOGGER.log(Level.WARNING, "Cannot clear temporary files.", e); + } + + if (!logs.isEmpty() && ftpClient.changeToParentDirectory() && ftpClient.changeToParentDirectory()) { + log(ftpClient, logs.toArray(new Log[logs.size()])); + } + + // Update results publication state. + updateResults(reallyPublished); + } + } + + /** + * Create (if needed) folders in which input site results will be put. + * Working directory is changed to the created/detected directory. + * @param site The site we want to post results for. + * @param ftpClient The FTP connection to work with. + */ + private static void prepareSiteDirectory(final Site site, final FTPClient ftpClient) throws IOException, DataStoreException { + // Move to county code ftp folder + String department = site.getCountyCode(); + if (department == null || department.trim().isEmpty()) + department = "00"; + ftpClient.makeDirectory(department); + if (!ftpClient.changeWorkingDirectory(department)) { + throw new IOException("Unable to change of directory to " + department); + } + + // Move to geom SHA1 ftp folder + final String sha1geom = GeometryUtils.getSha1(site.getGeometry()); + ftpClient.makeDirectory(sha1geom); + if (!ftpClient.changeWorkingDirectory(sha1geom)) { + throw new IOException("Unable to change of directory to " + sha1geom); + } + + if (ftpClient.listFiles(ExportUtils.SITE_JSON).length < 1) { + try (final OutputStream out = ftpClient.storeFileStream(ExportUtils.SITE_JSON)) { + GeoJSONStreamWriter.writeSingleFeature(out, SiteRepositoryImpl.toFeature(site), JsonEncoding.UTF8, 2, true); + } + ftpClient.completePendingCommand(); + } + } + + /** + * Check directories for result publication for a specific protocol. It will + * find or create, and then move to a folder named as input protocol, and + * then create and move to a folder whose name is an UUID. + * + * Note : For publication, you should already be in the site folder, i.e + * have called {@link #prepareSiteDirectory(fr.cenra.rhomeo.api.data.Site, org.apache.commons.net.ftp.FTPClient) }. + * + * @param p The protocol to post results for. + * @param ftpClient The FTP connection to work with. + */ + public static void prepareResultDirectory(final Protocol p, final FTPClient ftpClient) throws IOException { + final String protocolName = p.getName(); + ftpClient.makeDirectory(protocolName); + if (!ftpClient.changeWorkingDirectory(protocolName)) { + throw new IOException("Unable to change of directory to " + protocolName); + } + + final String uuid = UUID.randomUUID().toString(); + ftpClient.makeDirectory(uuid); + if (!ftpClient.changeWorkingDirectory(uuid)) { + throw new IOException("Unable to change of directory to " + uuid); + } + } + + private static void log(final FTPClient ftpClient, Log... toLog) throws IOException { + try (OutputStream out = ftpClient.appendFileStream(HISTORY_LOG); + final OutputStreamWriter outWriter = new OutputStreamWriter(out, StandardCharsets.UTF_8); + final BufferedWriter writer = new BufferedWriter(outWriter)) { + for (final Log log : toLog) { + writer.newLine(); + writer.write(log.toString()); + } + } finally { + ftpClient.completePendingCommand(); + } + } + + private static Optional fromSession(final Session session, final String bundlePath) { + if (session.getDataContext() == null || session.getResults() == null || session.getResults().isEmpty()) + return Optional.empty(); + + final Set years = new HashSet<>(); + final Set indicators = new HashSet<>(); + + for (final Index i : session.getResults()) { + years.add(i.getYear()); + indicators.add(i.getSpi().getIndicator()); + } + + if (years.isEmpty() || indicators.isEmpty()) + return Optional.empty(); + + final int[] primYears = new int[years.size()]; + int count = 0; + for (Integer year : years) + primYears[count++] = year; + + return Optional.of(new Log(session.getDataContext().getSite(), bundlePath, primYears, indicators.toArray(new Indicator[indicators.size()]))); + } + + private static class Log { + final String siteName; + final String referent; + final String organisation; + final String targetBundle; + final String indicateurs; + final String annees; + + public Log(final Site site, final String targetBundle, final int[] years, final Indicator... indicators) { + this(targetBundle, site.getName(), site.getReferent(), site.getOrganization(), years, indicators); + } + + public Log(final String target, final String siteName, final String ref, final String org, final int[] years, final Indicator... indicators) { + this.siteName = siteName; + referent = ref; + organisation = org; + targetBundle = target; + + Arrays.sort(years); + StringJoiner joiner = new StringJoiner(", "); + for (final int year : years) + joiner.add(String.valueOf(year)); + this.annees = joiner.toString(); + + Arrays.sort(indicators); + joiner = new StringJoiner(", "); + for (final Indicator i : indicators) + joiner.add(i.getName()); + indicateurs = joiner.toString(); + } + + @Override + public String toString() { + return new StringBuilder(256) + .append(ZonedDateTime.now().toString()).append(" : ") + .append(siteName).append(", ") + .append(referent == null || referent.isEmpty()? "referent inconnu" : referent) + .append(" (").append(organisation == null || organisation.isEmpty()? "organisation inconnue" : organisation).append(")") + .append(" publie ").append(targetBundle) + .append(" pour ").append(indicateurs) + .append(" en ").append(annees) + .toString(); + } + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/data/DataContextManager.java b/core/src/main/java/fr/cenra/rhomeo/core/data/DataContextManager.java new file mode 100644 index 0000000..83e8db6 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/data/DataContextManager.java @@ -0,0 +1,178 @@ +/** + * 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.core.data; + +import com.fasterxml.jackson.databind.ObjectMapper; +import fr.cenra.rhomeo.api.data.DataContext; +import fr.cenra.rhomeo.api.data.Protocol; +import fr.cenra.rhomeo.api.data.Site; +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.util.SerializableDataContext; +import org.apache.sis.util.ArgumentChecks; +import org.springframework.stereotype.Component; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * Handle data context serialization. + * + * @author Cédric Briançon (Geomatys) + */ +@Component +public class DataContextManager { + private final ObjectMapper jsonMapper; + + public DataContextManager() { + jsonMapper = new ObjectMapper(); + } + + /** + * Write data context + * @param dc Data context to serialize. + * @throws IOException + */ + public void writeDataContext(final DataContext dc) throws IOException { + SerializableDataContext[] contexts = getContexts(); + final SerializableDataContext srDataContext = SerializableDataContext.fromDataContext(dc); + boolean found = false; + for (int i=0; i finalContexts = + Stream.of(contexts).filter(context -> !context.siteName.equals(siteName)) + .collect(Collectors.toList()); + // Something to serialize if we have less contexts in the end + if (contexts.length != finalContexts.size()) { + final Path contextsPath = RhomeoCore.DATA_CONTEXT_SITE_PATH; + try (final BufferedWriter writer = Files.newBufferedWriter(contextsPath, StandardCharsets.UTF_8)) { + jsonMapper.writeValue(writer, finalContexts.toArray()); + } + } + } + + public void updateReferencesSiteName(final String oldName, final String newName) throws IOException { + final SerializableDataContext[] contexts = getContexts(); + if (contexts.length == 0) { + return; + } + + boolean aChange = false; + final List finalContexts = new ArrayList<>(); + for (final SerializableDataContext context : contexts) { + if (context.siteName.equals(oldName)) { + aChange = true; + context.siteName = newName; + } + finalContexts.add(context); + } + + // Something to serialize if we have less contexts in the end + if (aChange) { + final Path contextsPath = RhomeoCore.DATA_CONTEXT_SITE_PATH; + try (final BufferedWriter writer = Files.newBufferedWriter(contextsPath, StandardCharsets.UTF_8)) { + jsonMapper.writeValue(writer, finalContexts.toArray()); + } + } + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/data/ReferenceManager.java b/core/src/main/java/fr/cenra/rhomeo/core/data/ReferenceManager.java new file mode 100644 index 0000000..abb8270 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/data/ReferenceManager.java @@ -0,0 +1,508 @@ +/** + * 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.core.data; + +import fr.cenra.rhomeo.api.Version; +import fr.cenra.rhomeo.api.data.Reference; +import fr.cenra.rhomeo.api.data.ReferenceDescription; +import fr.cenra.rhomeo.core.CSVDecoder; +import fr.cenra.rhomeo.core.CSVMapper; +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.RhomeoRuntimeException; +import fr.cenra.rhomeo.core.Session; +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.lang.ref.WeakReference; +import java.nio.charset.StandardCharsets; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.function.Supplier; +import java.util.logging.Level; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javafx.collections.FXCollections; +import javafx.collections.ObservableMap; +import javafx.concurrent.Task; +import javax.validation.constraints.NotNull; +import org.apache.commons.net.ftp.FTPClient; +import org.apache.commons.net.ftp.FTPFile; +import org.apache.sis.util.ArgumentChecks; +import org.apache.sis.util.collection.Cache; + +/** + * Contains the list of available and installed version of a specific reference + * type. Also allow to get data contained in each installed version. + * + * @author Alexis Manin (Geomatys) + * @param Type of reference managed. + */ +public class ReferenceManager { + + /** + * A regex to detect CSV files containing a version number composed of dot separated digits . + */ + private static final Pattern REF_FILE_PATTERN = Pattern.compile("(?i)(\\d+(?:\\.\\d+)*)(.csv)?$"); + + /** + * We register created managers here. + */ + private static final Cache INSTANCES = new Cache<>(13, 13, true); + + /** + * + * @param The type of reference to get a manager for. + * @param descriptor A descriptor for the reference list to check. + * @return The manager corresponding to the given reference description. + * @throws java.beans.IntrospectionException If we cannot analyze given reference type. + */ + public static ReferenceManager getOrCreate(final ReferenceDescription descriptor) throws IntrospectionException { + try { + return INSTANCES.getOrCreate(descriptor.getName(), () -> new ReferenceManager<>(descriptor)); + } catch (IntrospectionException | RuntimeException ex) { + throw ex; + } catch (Exception e) { + throw new RhomeoRuntimeException(e); + } + } + + /** + * Target (managed) reference type. + */ + private final ReferenceDescription refType; + /** + * Information about reference pojo (properties, methods, etc.). + */ + private final BeanInfo refInfo; + + /** + * Directory where installed versions should be located. + */ + private final Path refDir; + + /** + * A map containing installed versions we found on {@link #refresh() }. + */ + private final ObservableMap installed; + /** + * A map containing versions found in FTP server on {@link #refresh() }. + */ + private final ObservableMap distant; + + private final Cache> loadedVersions = new Cache(2, 0, false); + + private WeakReference> lastLoaded; + + private final Set operations; + + private Task refreshTask; + + private ReferenceManager(@NotNull ReferenceDescription refType) throws IntrospectionException { + this.refType = refType; + final String refName = refType.getName(); + ArgumentChecks.ensureNonEmpty("Reference type name", refName); + + refInfo = Introspector.getBeanInfo(refType.getReferenceType(), Object.class); + refDir = RhomeoCore.REFERENCE_PATH.resolve(refName); + + installed = FXCollections.observableMap(new HashMap<>()); + distant = FXCollections.observableMap(new HashMap<>()); + + operations = new HashSet<>(); + } + + /** + * Force this manager to rebuild its data from scratch. The local files and + * FTP service will be scanned anew to find available and installed reference + * lists. + * + * Note : local data is checked first, so if the distant service does not + * provide correct answers and the task fails, we can still access installed + * versions. + * @return A task which refresh data. If a refresh is ready to run or + * already running, the corresponding task is returned. Otherwise, a new + * task is returned which must be launched by the caller. + */ + public synchronized Task refresh() { + if (refreshTask == null || refreshTask.isDone()) { + refreshTask = new Task() { + + @Override + protected Object call() throws Exception { + updateTitle("Recherche de versions : ".concat(refType.getTitle())); + + updateMessage("Vérification des versions installées"); + installed.clear(); + Files.createDirectories(refDir); + + Files.walkFileTree(refDir, new SimpleFileVisitor() { + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + final Matcher matcher = REF_FILE_PATTERN.matcher(file.getFileName().toString()); + if (matcher.find()) { + if (isValid(file)) { + installed.put(new Version(matcher.group(1)), file); + } + } + return super.visitFile(file, attrs); + } + }); + + updateMessage("Vérification des versions disponibles sur le FTP"); + distant.clear(); + final FTPClient ftp = Session.getInstance().connectReferenceFTP(); + try { + if (ftp.changeWorkingDirectory(refType.getName())) { + ftp.listFiles(".", file -> { + if (file.isFile() && file.getSize() > 0) { + final Matcher matcher = REF_FILE_PATTERN.matcher(file.getName()); + if (matcher.find()) { + try (final InputStream retStream = ftp.retrieveFileStream(file.getName())) { + if (isValid(retStream)) { + distant.put(new Version(matcher.group(1)), file); + return true; + } + } catch (IOException e) { + RhomeoCore.LOGGER.log(Level.WARNING, "An error occurred while reading an FTP file : ".concat(file.getName()), e); + } finally { + try { + // Ensures pending command are finished + if (!ftp.completePendingCommand()) { + final int replyCode = ftp.getReplyCode(); + final String replyMessage = ftp.getReplyString(); + final Supplier msgSupplier = () -> { + final StringBuilder builder = new StringBuilder("Error on pending command completion."); + builder.append(System.lineSeparator()).append("File : ").append(file.getName()); + builder.append(System.lineSeparator()).append("Reply code : ").append(replyCode); + builder.append(System.lineSeparator()).append("Reply message : ").append(replyMessage); + return builder.toString(); + }; + RhomeoCore.LOGGER.log(Level.INFO, msgSupplier); + } + } catch (IOException ex) { + RhomeoCore.LOGGER.log(Level.WARNING, "An error occurred while trying to complete pending command for FTP file : ".concat(file.getName()), ex); + } + } + } + } + return false; + }); + } + } finally { + try { + ftp.disconnect(); + } catch (IOException e) { + RhomeoCore.LOGGER.log(Level.WARNING, "An FTP client cannot be disconnected : References.", e); + } + } + + return this; + } + }; + } + + return refreshTask; + } + + /** + * + * @return Set of versions available on FTP server. Unmodifiable. The Set is + * automatically updated when the manager is refreshed. + */ + public Set getDistantVersions() { + return distant.keySet(); + } + + /** + * + * @return Set of versions installed locally. Unmodifiable. The Set is + * automatically updated when the manager is refreshed. + */ + public Set getInstalledVersions() { + return installed.keySet(); + } + + /** + * Create a task in charge of the installation of a new reference version. + * @param toInstall Version of the reference list to install. + * @return A task (not submitted yet) to run to install given version. + * @throws IllegalStateException If an installation or uninstallation procedure + * is already running for the version. + */ + public Task install(@NotNull final Version toInstall) throws IllegalStateException { + synchronized (operations) { + if (operations.contains(toInstall)) { + throw new IllegalStateException( + new StringBuilder("An operation is already running for version ") + .append(toInstall.toString()) + .append(" of list ") + .append(refType.getName()) + .toString() + ); + } + } + + return new Task() { + + @Override + protected Object call() throws Exception { + final boolean alreadyRunning; + synchronized (operations) { + alreadyRunning = !operations.add(toInstall); + } + try { + if (alreadyRunning) { + updateMessage( + new StringBuilder("An operation is already running for version ") + .append(toInstall.toString()) + .append(" of list ") + .append(refType.getName()) + .toString() + ); + cancel(); + + } else if (installed.containsKey(toInstall)) { + updateMessage("Queried version is already installed : ".concat(toInstall.toString())); + cancel(); + + } else { + updateTitle("Téléchargement ".concat(toInstall.toString())); + FTPFile ftpFile = distant.get(toInstall); + if (distant == null) { + throw new IllegalArgumentException("Queried version is not available : ".concat(toInstall.toString())); + } + + final Path newRef = refDir.resolve(toInstall.toString().concat(".csv")); + final FTPClient ftp = Session.getInstance().connectReferenceFTP(); + ftp.changeWorkingDirectory(refType.getName()); + try (final OutputStream out = Files.newOutputStream(newRef)) { + ftp.retrieveFile(ftpFile.getName(), out); + } finally { + try { + ftp.disconnect(); + } catch (IOException e) { + RhomeoCore.LOGGER.log(Level.WARNING, "An FTP client cannot be disconnected : References.", e); + } + } + + installed.put(toInstall, newRef); + return newRef; + } + } finally { + synchronized (operations) { + if (!alreadyRunning) { + operations.remove(toInstall); + } + } + } + + return false; + } + }; + } + + /** + * Create a task in charge of removing a local reference version. + * @param toUninstall Version of the reference list to uninstall. + * @return A task (not submitted yet) to run to uninstall given version. + * @throws IllegalStateException If an installation or uninstallation procedure + * is already running for the version. + */ + public Task uninstall(@NotNull final Version toUninstall) throws IllegalStateException { + synchronized (operations) { + if (operations.contains(toUninstall)) { + throw new IllegalStateException( + new StringBuilder("An operation is already running for version ") + .append(toUninstall.toString()) + .append(" of list ") + .append(refType.getName()) + .toString() + ); + } + } + + return new Task() { + + @Override + protected Object call() throws Exception { + final boolean alreadyRunning; + synchronized (operations) { + alreadyRunning = !operations.add(toUninstall); + } + try { + if (alreadyRunning) { + updateMessage( + new StringBuilder("An operation is already running for version ") + .append(toUninstall.toString()) + .append(" of list ") + .append(refType.getName()) + .toString() + ); + cancel(); + + } else if (!installed.containsKey(toUninstall)) { + updateMessage("Queried version is already uninstalled : ".concat(toUninstall.toString())); + cancel(); + + } else { + updateTitle("Suppression ".concat(toUninstall.toString())); + final Path toDelete = installed.get(toUninstall); + Files.delete(toDelete); + return installed.remove(toUninstall); + } + } finally { + synchronized (operations) { + if (!alreadyRunning) { + operations.remove(toUninstall); + } + } + } + + return false; + } + }; + } + + /** + * Check if given file header lists all properties defined in reference + * type. + * + * @param file The file to check. + * @return True if the file header describes the current reference type, + * false otherwise. + * @throws IOException If we cannot read the file. + * @throws IntrospectionException If we cannot extract property description + * from current reference type. + */ + private boolean isValid(@NotNull final Path file) throws IOException { + final String line; + try (final BufferedReader reader = Files.newBufferedReader(file, StandardCharsets.UTF_8)) { + line = reader.readLine(); + } + + return isValidHeader(line); + } + + /** + * Check if given file header lists all properties defined in reference + * type. + * + * @param file The file to check. + * @return True if the file header describes the current reference type, + * false otherwise. + * @throws IOException If we cannot read the file. + * @throws IntrospectionException If we cannot extract property description + * from current reference type. + */ + private boolean isValid(@NotNull final InputStream file) throws IOException { + final String line; + try (final InputStreamReader in = new InputStreamReader(file, StandardCharsets.UTF_8); + final BufferedReader reader = new BufferedReader(in)) { + line = reader.readLine(); + } + + return isValidHeader(line); + } + + /** + * Check if given header lists all properties defined in reference type. + * + * @param firstLine The header to check. + * @return True if the file header describes the current reference type, + * false otherwise. + */ + private boolean isValidHeader(@NotNull final String firstLine) { + return CSVMapper.isValidHeader(firstLine, CSVMapper.DEFAULT_SEPARATOR, refInfo); + } + + /** + * Try to load reference values for the given version. Before calling this + * method, you MUST have called + * {@link #refresh() } at least once, and checked the queried version is + * already installed. + * @param toLoad The version of the list to load. + * @return A read-only list containing all values for the queried references. + * @throws IllegalArgumentException If the queried version is not installed, + * or the manager has not been refreshed yet. + * @throws RhomeoRuntimeException If an error occurs while reading list file. + */ + public synchronized List getValues(final Version toLoad) throws IllegalArgumentException, RhomeoRuntimeException { + try { + final List result = loadedVersions.getOrCreate(toLoad, () -> { + final Path p = installed.get(toLoad); + if (p == null) { + throw new IllegalArgumentException("Queried version is not installed, or the manager has not been refreshed yet !"); + } + + return Collections.unmodifiableList( + new CSVDecoder<>(p, refType.getReferenceType(), StandardCharsets.UTF_8).decode()); + }); + lastLoaded = new WeakReference(result); + return result; + } catch (Exception ex) { + throw new RhomeoRuntimeException(ex); + } + } + + /** + * + * @return The list of references which have been loaded the last time {@link #getValues(fr.cenra.rhomeo.api.Version) } + * has been called, if any. + */ + public synchronized Optional> getLastLoaded() { + if (lastLoaded == null) + return Optional.empty(); + else return Optional.ofNullable(lastLoaded.get()); + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/data/TrackingPointValue.java b/core/src/main/java/fr/cenra/rhomeo/core/data/TrackingPointValue.java new file mode 100644 index 0000000..5234d84 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/data/TrackingPointValue.java @@ -0,0 +1,75 @@ +/** + * 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.core.data; + +import fr.cenra.rhomeo.api.data.TrackingPoint; + +/** + * @author Cédric Briançon (Geomatys) + */ +public class TrackingPointValue implements Comparable { + private final TrackingPoint trackingPoint; + private final Double value; + + public TrackingPointValue(final TrackingPoint trackingPoint, final Double value) { + this.trackingPoint = trackingPoint; + this.value = value; + } + + public TrackingPoint getTrackingPoint() { + return trackingPoint; + } + + public Double getValue() { + return value; + } + + @Override + public int compareTo(TrackingPointValue o) { + if (value == null) { + return 1; + } + + if (o == null || o.getValue() == null) { + return -1; + } + + return getValue().compareTo(o.getValue()); + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/data/UpdateInfo.java b/core/src/main/java/fr/cenra/rhomeo/core/data/UpdateInfo.java new file mode 100644 index 0000000..0c47686 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/data/UpdateInfo.java @@ -0,0 +1,163 @@ +/** + * 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.core.data; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import fr.cenra.rhomeo.api.Version; +import fr.cenra.rhomeo.core.util.VersionDeserializer; +import fr.cenra.rhomeo.core.util.VersionSerializer; +import fr.cenra.rhomeo.core.util.ZonedDateTimeDeserializer; +import fr.cenra.rhomeo.core.util.ZonedDateTimeSerializer; +import java.net.URL; +import java.time.ZonedDateTime; + +/** + * A simple pojo which contains information about application available package + * + * @author Alexis Manin (Geomatys) + */ +public class UpdateInfo { + + private Version version; + private ZonedDateTime date; + private String[] releaseNote; + private URL win32; + private String win32MD5; + private URL deb64; + private String deb64MD5; + private URL rpm64; + private String rpm64MD5; + private URL macOS64; + private String macOS64MD5; + + @JsonSerialize(using = VersionSerializer.class) + public Version getVersion() { + return version; + } + + @JsonDeserialize(using = VersionDeserializer.class) + public void setVersion(Version version) { + this.version = version; + } + + public URL getWin32() { + return win32; + } + + @JsonSerialize(using = ZonedDateTimeSerializer.class) + public ZonedDateTime getDate() { + return date; + } + + @JsonDeserialize(using = ZonedDateTimeDeserializer.class) + public void setDate(ZonedDateTime date) { + this.date = date; + } + + public String[] getReleaseNote() { + return releaseNote; + } + + public void setReleaseNote(String[] releaseNote) { + this.releaseNote = releaseNote; + } + + public void setWin32(URL win32) { + this.win32 = win32; + } + + public URL getDeb64() { + return deb64; + } + + public void setDeb64(URL deb64) { + this.deb64 = deb64; + } + + public URL getRpm64() { + return rpm64; + } + + public void setRpm64(URL rpm64) { + this.rpm64 = rpm64; + } + + public URL getMacOS64() { + return macOS64; + } + + public void setMacOS64(URL macOS64) { + this.macOS64 = macOS64; + } + + public String getWin32MD5() { + return win32MD5; + } + + public void setWin32MD5(String win32MD5) { + this.win32MD5 = win32MD5; + } + + public String getDeb64MD5() { + return deb64MD5; + } + + public void setDeb64MD5(String deb64MD5) { + this.deb64MD5 = deb64MD5; + } + + public String getRpm64MD5() { + return rpm64MD5; + } + + public void setRpm64MD5(String rpm64MD5) { + this.rpm64MD5 = rpm64MD5; + } + + public String getMacOS64MD5() { + return macOS64MD5; + } + + public void setMacOS64MD5(String macOS64MD5) { + this.macOS64MD5 = macOS64MD5; + } + + +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/data/county/County.java b/core/src/main/java/fr/cenra/rhomeo/core/data/county/County.java new file mode 100644 index 0000000..22c9a88 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/data/county/County.java @@ -0,0 +1,89 @@ +/** + * 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.core.data.county; + +import org.apache.sis.util.ArgumentChecks; + +/** + * A simple POJO to display the name and code of a county. + * + * @author Alexis Manin (Geomatys) + */ +public class County implements Comparable { + + /** + * Code of the county. An Integer most of the time, except for Corse (2A, 2B). + */ + protected final String code; + /** + * Name of the county (Corse, Isère, etc.). + */ + protected final String name; + + /** + * Build a new county object. + * @param code The code of the county. Not null + * @param name The name of the county. Not null. + */ + protected County(final String code, final String name) { + ArgumentChecks.ensureNonNull("County code", code); + ArgumentChecks.ensureNonNull("County name", name); + + this.code = code; + this.name = name; + } + + public String getCode() { + return code; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return new StringBuilder(code).append(' ').append(name).toString(); + } + + @Override + public int compareTo(County o) { + return o == null? -1 : code.compareTo(o.code); + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/data/county/CountyRepository.java b/core/src/main/java/fr/cenra/rhomeo/core/data/county/CountyRepository.java new file mode 100644 index 0000000..68e1ac6 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/data/county/CountyRepository.java @@ -0,0 +1,255 @@ +/** + * 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.core.data.county; + +import com.vividsolutions.jts.geom.Geometry; +import fr.cenra.rhomeo.core.RhomeoCore; +import java.io.IOException; +import java.io.InputStream; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.regex.Matcher; +import javafx.util.StringConverter; +import javax.annotation.PreDestroy; +import org.apache.sis.storage.DataStoreException; +import org.geotoolkit.data.FeatureCollection; +import org.geotoolkit.data.FeatureReader; +import org.geotoolkit.data.query.QueryBuilder; +import org.geotoolkit.data.shapefile.ShapefileFeatureStore; +import org.geotoolkit.factory.FactoryFinder; +import org.geotoolkit.factory.Hints; +import org.geotoolkit.feature.Feature; +import org.geotoolkit.nio.IOUtilities; +import org.geotoolkit.referencing.CRS; +import org.opengis.filter.FilterFactory2; +import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.opengis.util.FactoryException; +import org.opengis.util.GenericName; +import org.springframework.stereotype.Component; + +/** + * A repository to load / search for counties. + * + * @author Alexis Manin (Geomatys) + */ +@Component +public final class CountyRepository implements AutoCloseable { + + /** + * List of resources to load to read County data. + */ + private static final String[] RESOURCES = new String[]{ + "DEPARTEMENT.shp", + "DEPARTEMENT.shx", + "DEPARTEMENT.dbf", + "DEPARTEMENT.prj" + }; + + /** + * Attributes to read into the shapefile embedding county data. + */ + private static final String COUNTY_CODE = "CODE_DEPT"; + private static final String COUNTY_NAME = "NOM_DEPT"; + + private final ShapefileFeatureStore store; + private final GenericName name; + private final StringConverter converter; + private final CoordinateReferenceSystem siteCRS; + private final FilterFactory2 ff; + + private final Map counties; + + private final Path dataDir; + + CountyRepository() throws IOException, URISyntaxException, DataStoreException, FactoryException { + // Copy resources on local filesystem + dataDir = Files.createTempDirectory("countyShape"); + for (final String str : RESOURCES) { + try (final InputStream tmpStream = County.class.getResourceAsStream(str)) { + Files.copy(tmpStream, dataDir.resolve(str)); + } + } + + siteCRS = RhomeoCore.getSiteCRS(); + store = new ShapefileFeatureStore(dataDir.resolve(RESOURCES[0]).toUri()); + name = store.getName(); + converter = new Converter(); + + final Hints hints = new Hints(); + hints.put(Hints.FILTER_FACTORY, FilterFactory2.class); + ff = (FilterFactory2) FactoryFinder.getFilterFactory(hints); + + counties = readCounties(); + } + + /** + * Find a county for the given code. + * @param code The code of the county. Ex : 34 for Hérault. + * @return The matching county, or null if we cannot find any. + */ + public County get(final String code) { + return code == null? null : counties.get(code); + } + + /** + * + * @param geom The geometry to find counties for. + * @return List of counties intersecting the input geometry. Never null, but + * can be empty. + */ + public List get(final Geometry geom) { + final ArrayList result = new ArrayList<>(); + if (geom == null || geom.isEmpty()) + return result; + try { + final QueryBuilder builder = new QueryBuilder(name); + final CoordinateReferenceSystem fCRS = store.getFeatureType(name).getCoordinateReferenceSystem(); + if (fCRS != null && !CRS.equalsApproximatively(fCRS, siteCRS)) { + builder.setCRS(siteCRS); + } + + final GenericName geomName = store.getFeatureType().getGeometryDescriptor().getName(); + builder.setProperties(new String[]{COUNTY_CODE, geomName.tip().toString()}); + + builder.setFilter(ff.intersects(ff.property(geomName), ff.literal(geom))); + try (FeatureReader reader = store.getFeatureReader(builder.buildQuery())) { + while (reader.hasNext()) { + result.add(counties.get(reader.next().getPropertyValue(COUNTY_CODE))); + } + } + + } catch (Exception e) { + RhomeoCore.LOGGER.log(Level.FINE, "Cannot perform intersection on counties !", e); + } + + return result; + } + + /** + * + * @return Complete list of metropolitan France counties, indexed by code. + */ + public Map getAll() { + return counties; + } + + public FeatureCollection getFeatures() { + return store.createSession(false).getFeatureCollection(QueryBuilder.all(name)); + } + + /** + * Load all counties in memory. + * @return An unmodifiable map of available counties. Key is code, value is + * county. + * @throws DataStoreException + * @throws FactoryException + */ + private Map readCounties() throws DataStoreException, FactoryException { + final QueryBuilder builder = new QueryBuilder(name); + final CoordinateReferenceSystem fCRS = store.getFeatureType(name).getCoordinateReferenceSystem(); + if (fCRS != null && !CRS.equalsApproximatively(fCRS, siteCRS)) { + builder.setCRS(siteCRS); + } + + builder.setProperties(new String[]{COUNTY_CODE, COUNTY_NAME}); + + // read and convert data. + Map tmpCounties = new HashMap(); + try (FeatureReader reader = store.getFeatureReader(builder.buildQuery())) { + Feature dep; + County county; + while (reader.hasNext()) { + dep = reader.next(); + county = new County( + dep.getPropertyValue(COUNTY_CODE).toString(), + dep.getPropertyValue(COUNTY_NAME).toString() + ); + tmpCounties.put(county.code, county); + } + } + + return Collections.unmodifiableMap(tmpCounties); + } + + @PreDestroy + @Override + public void close() throws Exception { + try { + store.close(); + } finally { + IOUtilities.deleteRecursively(dataDir); + } + } + + public StringConverter getStringConverter() { + return converter; + } + + private class Converter extends StringConverter { + + @Override + public String toString(County object) { + if (object != null) + return object.toString(); + return null; + + } + + @Override + public County fromString(String string) { + if (string == null || (string = string.trim()).isEmpty()) { + return null; + } + + final Matcher matcher = RhomeoCore.CODE_PATTERN.matcher(string); + if (matcher.find()) { + return get(matcher.group()); + } + + return null; + } + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/data/reference/FloreBassinReference.java b/core/src/main/java/fr/cenra/rhomeo/core/data/reference/FloreBassinReference.java new file mode 100644 index 0000000..9e13d89 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/data/reference/FloreBassinReference.java @@ -0,0 +1,140 @@ +/** + * 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.core.data.reference; + +import fr.cenra.rhomeo.api.data.Reference; + +import javax.validation.constraints.NotNull; + +/** + * @author Cédric Briançon (Geomatys) + */ +public class FloreBassinReference implements Reference { + /** + * Primary key. + */ + private int cd_nom; + + private int cd_ref; + + private String nom; + private Integer nutriment; + private Integer humidite; + private Integer cc; + + public FloreBassinReference() { + } + + public FloreBassinReference(@NotNull int cdNom, String nom, Integer nutriment, Integer humidite, Integer cc) { + this.cd_nom = cdNom; + this.nom = nom; + this.nutriment = nutriment; + this.humidite = humidite; + this.cc = cc; + } + + public @NotNull int getCd_nom() { + return cd_nom; + } + + public void setCd_nom(@NotNull int cd_nom) { + this.cd_nom = cd_nom; + } + + public @NotNull int getCd_ref() { + return cd_ref; + } + + public void setCd_ref(@NotNull int cd_ref) { + this.cd_ref = cd_ref; + } + + public String getNom() { + return nom; + } + + public void setNom(String nom) { + this.nom = nom; + } + + public Integer getNutriment() { + return nutriment; + } + + public void setNutriment(Integer nutriment) { + this.nutriment = nutriment; + } + + public Integer getHumidite() { + return humidite; + } + + public void setHumidite(Integer humidite) { + this.humidite = humidite; + } + + public Integer getCc() { + return cc; + } + + public void setCc(Integer cc) { + this.cc = cc; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + FloreBassinReference that = (FloreBassinReference) o; + + return cd_nom == that.cd_nom; + + } + + @Override + public int hashCode() { + return cd_nom; + } + + @Override + public String toString() { + return nom; + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/data/reference/FloreBassinReferenceDescription.java b/core/src/main/java/fr/cenra/rhomeo/core/data/reference/FloreBassinReferenceDescription.java new file mode 100644 index 0000000..ec39465 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/data/reference/FloreBassinReferenceDescription.java @@ -0,0 +1,72 @@ +/** + * 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.core.data.reference; + +import fr.cenra.rhomeo.api.data.ReferenceDescription; +import org.springframework.stereotype.Component; + +import java.util.Collection; +import java.util.Collections; + +/** + * @author Cédric Briançon (Geomatys) + */ +@Component +public class FloreBassinReferenceDescription implements ReferenceDescription { + + @Override + public Class getReferenceType() { + return FloreBassinReference.class; + } + + @Override + public String getName() { + return "flore_bassin"; + } + + @Override + public Collection getAlias() { + return Collections.singletonList("Valeurs indicatrices des espèces floristiques"); + } + + @Override + public String getRemarks() { + return "Référentiel flore agrégeant l'ensemble des taxons du bassin RMC (cf. Gilles PACHE)"; + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/data/reference/GeoReferential.java b/core/src/main/java/fr/cenra/rhomeo/core/data/reference/GeoReferential.java new file mode 100644 index 0000000..716516b --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/data/reference/GeoReferential.java @@ -0,0 +1,325 @@ + +/** + * 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.core.data.reference; + +import com.vividsolutions.jts.geom.Geometry; +import fr.cenra.rhomeo.api.data.Site; +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.util.GeometryUtils; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import javafx.beans.binding.BooleanExpression; +import javafx.beans.property.BooleanProperty; +import javafx.beans.property.ReadOnlyBooleanWrapper; +import javafx.beans.property.SimpleBooleanProperty; +import org.apache.sis.internal.system.DefaultFactories; +import org.apache.sis.storage.DataStoreException; +import org.geotoolkit.data.FeatureCollection; +import org.geotoolkit.data.FeatureIterator; +import org.geotoolkit.data.FeatureStore; +import org.geotoolkit.data.query.QueryBuilder; +import org.geotoolkit.data.session.Session; +import org.geotoolkit.filter.DefaultPropertyName; +import org.geotoolkit.geometry.jts.JTS; +import org.geotoolkit.storage.DataStores; +import org.opengis.filter.FilterFactory; +import org.opengis.filter.FilterFactory2; +import org.opengis.util.GenericName; + +/** + * + * @author Johann Sorel (Geomatys) + */ +public class GeoReferential implements Comparable, AutoCloseable{ + + private final Site site; + private final int year; + private final SimpleBooleanProperty zoneHydro = new SimpleBooleanProperty(); + private final SimpleBooleanProperty tacheUrbaine = new SimpleBooleanProperty(); + private final SimpleBooleanProperty tacheArtif = new SimpleBooleanProperty(); + private final SimpleBooleanProperty rpg = new SimpleBooleanProperty(); + private final SimpleBooleanProperty wfszoneHydro = new SimpleBooleanProperty(); + private final SimpleBooleanProperty wfstacheUrbaine = new SimpleBooleanProperty(); + private final SimpleBooleanProperty wfstacheArtif = new SimpleBooleanProperty(); + private final SimpleBooleanProperty wfsrpg = new SimpleBooleanProperty(); + private final SimpleBooleanProperty download = new SimpleBooleanProperty(); + + private FeatureStore store; + + public GeoReferential(Site site, int year) { + this.site = site; + this.year = year; + } + + public int getYear() { + return year; + } + + public BooleanProperty zoneHydroLocal() { + return zoneHydro; + } + + public BooleanProperty tacheUrbaineLocal() { + return tacheUrbaine; + } + + public BooleanProperty tacheArtifLocal() { + return tacheArtif; + } + + public BooleanProperty rpgLocal() { + return rpg; + } + + public BooleanProperty zoneHydroWFS() { + return wfszoneHydro; + } + + public BooleanProperty tacheUrbaineWFS() { + return wfstacheUrbaine; + } + + public BooleanProperty tacheArtifWFS() { + return wfstacheArtif; + } + + public BooleanProperty rpgWFS() { + return wfsrpg; + } + + public BooleanProperty toDownloadProperty() { + return download; + } + + public boolean hasLocalTypes(String ... types){ + for(String type : types){ + switch(type.toLowerCase()){ + case GeoReferentials.TYPE_RPG: + if(!rpg.get()) return false; + break; + case GeoReferentials.TYPE_ZONE_HYDRO: + if(!zoneHydro.get()) return false; + break; + case GeoReferentials.TYPE_TACHE_ARTIF: + if(!tacheArtif.get()) return false; + break; + case GeoReferentials.TYPE_TACHE_URBAINE: + if(!tacheUrbaine.get()) return false; + break; + } + } + return true; + } + + public boolean hasWFSTypes(String ... types){ + for(String type : types){ + switch(type.toLowerCase()){ + case GeoReferentials.TYPE_RPG: + if(!wfsrpg.get()) return false; + break; + case GeoReferentials.TYPE_ZONE_HYDRO: + if(!wfszoneHydro.get()) return false; + break; + case GeoReferentials.TYPE_TACHE_ARTIF: + if(!wfstacheArtif.get()) return false; + break; + case GeoReferentials.TYPE_TACHE_URBAINE: + if(!wfstacheUrbaine.get()) return false; + break; + } + } + return true; + } + + /** + * Check if given types are available either locally or on configured WFS service. + * @param types Name of the types to check presence. If null, empty, or if + * no valid name is present, we consider that predicate cannot be tested, so + * we return false. + * @return True if all given names can be found locally or on WFS service. + * False otherwise, or if input data is null or empty. + */ + public boolean areAvailable(final String... types) { + if (types == null || types.length < 1) + return false; + boolean validNameFound = false; + for (final String type : types) { + if (type != null && !type.isEmpty()) { + validNameFound = true; + break; + } + } + + if (!validNameFound) + return false; // No valid name to test. + + for (final String type : types) { + if (type == null || type.isEmpty()) + continue; + if (!(hasLocalTypes(type) || hasWFSTypes(type))) + return false; // One of the given names is not available. + } + + return true; + } + + /** + * + * @param typeName + * @return + * @throws DataStoreException + */ + public FeatureCollection getFeatureCollection(String typeName, Geometry intersectGeom) throws DataStoreException{ + if (store == null) { + Path folder = RhomeoCore.REFERENCIELS_GEO_PATH.resolve(GeometryUtils.getSha1(site.getGeometry())).resolve(String.valueOf(year)); + if (!Files.isDirectory(folder)) { + folder = RhomeoCore.REFERENCIELS_GEO_PATH.resolve(site.getName()).resolve(String.valueOf(year)); + } + final Map parameters = new HashMap(); + parameters.put("identifier", "shapefile-folder"); + parameters.put("path", folder.toUri()); + parameters.put("namespace", "no namespace"); + store = (FeatureStore) DataStores.open(parameters); + } + + Set names = store.getNames(); + if (names == null || names.isEmpty()) + throw new DataStoreException("No geo-reference available !"); + GenericName name = null; + final String lcTypeName = typeName.toLowerCase(); + for (final GenericName tmpName : names) { + if (tmpName.tip().toString().toLowerCase().startsWith(lcTypeName)) { + name = tmpName; + } + } + + if (name == null) + throw new IllegalArgumentException("No reference available for name ".concat(typeName)); + + final Session session = store.createSession(true); + final QueryBuilder qb = new QueryBuilder(); + qb.setTypeName(name); + + if(intersectGeom!=null){ + final FilterFactory2 ff = ((FilterFactory2)DefaultFactories.forBuildin(FilterFactory.class)); + qb.setFilter(ff.intersects(new DefaultPropertyName("the_geom"), ff.literal(intersectGeom))); + } + + return session.getFeatureCollection(qb.buildQuery()); + } + + /** + * Compute a geometry which is the union of all geometries in specified + * referential which intersect the geometry given as input. + * @param typeName Name of the geo-referential to use to get geometies to merge. + * @param source Filter geometry. + * @return Computed union, or nothing if we cannot find any geometry intercepting given source. + * @throws IllegalArgumentException If given type name is not available locally. + * @throws DataStoreException If an error occurs while accessing reference data. + */ + public Optional unionIntersecting(final String typeName, final Geometry source) throws DataStoreException { + final FeatureCollection refData = getFeatureCollection(GeoReferentials.TYPE_ZONE_HYDRO, source); + Geometry union = null; + try (FeatureIterator ite = refData.iterator()) { + if (ite.hasNext()) + while (ite.hasNext()) { + final Geometry tmp = (Geometry) ite.next().getDefaultGeometryProperty().getValue(); + union = union==null ? tmp : tmp.union(union); + } + } + + if (union != null) { + JTS.setCRS(union, refData.getFeatureType().getCoordinateReferenceSystem()); + } + return Optional.ofNullable(union); + } + + @Override + public int compareTo(GeoReferential o) { + return year - o.year; + } + + @Override + public void close() throws Exception { + if(store!=null){ + store.close(); + } + } + + public BooleanExpression completed(final String... types) { + if (types == null || types.length < 1) + return new ReadOnlyBooleanWrapper(false).getReadOnlyProperty(); + + final ArrayList deps = new ArrayList<>(types.length); + for (final String type : types) { + if (type == null || type.isEmpty()) + continue; + switch (type.toLowerCase()) { + case GeoReferentials.TYPE_RPG: + deps.add(rpg); + break; + case GeoReferentials.TYPE_ZONE_HYDRO: + deps.add(zoneHydro); + break; + case GeoReferentials.TYPE_TACHE_ARTIF: + deps.add(tacheArtif); + break; + case GeoReferentials.TYPE_TACHE_URBAINE: + deps.add(tacheUrbaine); + break; + } + } + + if (deps.isEmpty()) + return new ReadOnlyBooleanWrapper(false).getReadOnlyProperty(); + + BooleanExpression result = deps.get(0); + for (int i = 1 ; i < deps.size(); i++) { + result = result.and(deps.get(i)); + } + + return result; + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/data/reference/GeoReferentials.java b/core/src/main/java/fr/cenra/rhomeo/core/data/reference/GeoReferentials.java new file mode 100644 index 0000000..c5f74ef --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/data/reference/GeoReferentials.java @@ -0,0 +1,531 @@ + +/** + * 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.core.data.reference; + +import com.vividsolutions.jts.geom.Geometry; +import fr.cenra.rhomeo.api.data.Site; +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.preferences.net.NetPreferences; +import fr.cenra.rhomeo.core.util.GeometryUtils; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.logging.Level; +import java.util.stream.Collectors; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import org.apache.sis.storage.DataStoreException; +import org.geotoolkit.data.FeatureReader; +import org.geotoolkit.data.FeatureStoreRuntimeException; +import org.geotoolkit.data.FeatureWriter; +import org.geotoolkit.data.query.Query; +import org.geotoolkit.data.query.QueryBuilder; +import org.geotoolkit.data.shapefile.ShapefileFeatureStore; +import org.geotoolkit.data.wfs.GetFeatureRequest; +import org.geotoolkit.data.wfs.WebFeatureClient; +import org.geotoolkit.data.wfs.WebFeatureException; +import org.geotoolkit.display2d.GO2Utilities; +import org.geotoolkit.feature.Feature; +import org.geotoolkit.feature.FeatureTypeBuilder; +import org.geotoolkit.feature.FeatureUtilities; +import org.geotoolkit.feature.type.AttributeDescriptor; +import org.geotoolkit.feature.type.FeatureType; +import org.geotoolkit.feature.type.PropertyDescriptor; +import org.geotoolkit.feature.xml.XmlFeatureReader; +import org.geotoolkit.feature.xml.jaxp.JAXPStreamFeatureReader; +import org.geotoolkit.filter.DefaultPropertyName; +import org.geotoolkit.map.FeatureMapLayer; +import org.geotoolkit.map.MapBuilder; +import org.geotoolkit.map.MapItem; +import org.geotoolkit.nio.IOUtilities; +import org.geotoolkit.wfs.xml.WFSVersion; +import org.opengis.filter.Filter; +import org.opengis.util.FactoryException; +import org.opengis.util.GenericName; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * Manage geographic referential. + * + * @author Johann Sorel (Geomatys) + */ +@Component +public class GeoReferentials { + + public static final String TYPE_ZONE_HYDRO = "zonehydro"; + public static final String TYPE_RPG = "rpg"; + public static final String TYPE_TACHE_ARTIF = "tacheartif"; + public static final String TYPE_TACHE_URBAINE = "tacheurbaine"; + private static final List NAMES = Arrays.asList(TYPE_ZONE_HYDRO,TYPE_RPG,TYPE_TACHE_ARTIF,TYPE_TACHE_URBAINE); + + @Autowired + private NetPreferences prefs; + + //cache WFS client + private WebFeatureClient wfs; + + private synchronized WebFeatureClient getWFSClient() throws MalformedURLException, DataStoreException, WebFeatureException{ + if(wfs==null){ + String url = prefs.getPreference(NetPreferences.WFS_URL); + if (url == null || (url = url.trim()).isEmpty()) + throw new IllegalStateException("Aucune URL disponible pour les référentiels géographiques"); + wfs = new WebFeatureClient(new URL(url), null, WFSVersion.v110, true); + wfs.getNames(); + } + return wfs; + } + + /** + * Combine local and server referentials. + * + * @param site + * @return + */ + public ObservableList getReferentials(Site site) throws IllegalArgumentException, IOException, DataStoreException{ + final ObservableList refs = getLocalReferentials(site); + + try { + ObservableList wfsReferentials = getWFSReferentials(); + loop: + for(GeoReferential gr : wfsReferentials){ + for(GeoReferential r : refs){ + if(r.compareTo(gr)==0){ + r.tacheArtifWFS().set(gr.tacheArtifWFS().get()); + r.tacheUrbaineWFS().set(gr.tacheUrbaineWFS().get()); + r.zoneHydroWFS().set(gr.zoneHydroWFS().get()); + r.rpgWFS().set(gr.rpgWFS().get()); + continue loop; + } + } + refs.add(gr); + } + } catch (Exception ex) { + if(refs.isEmpty()){ + throw ex; + }else{ + RhomeoCore.LOGGER.log(Level.WARNING, null, ex); + } + } + + //sort by year + Collections.sort(refs); + + return refs; + } + + /** + * List available local referentials for given site. + * + * @param site + * @param year + * @return + */ + public GeoReferential getLocalReferential(Site site, int year) throws IllegalArgumentException, IOException { + Path folder = RhomeoCore.REFERENCIELS_GEO_PATH.resolve(GeometryUtils.getSha1(site.getGeometry())); + if (!Files.isDirectory(folder)) { + folder = RhomeoCore.REFERENCIELS_GEO_PATH.resolve(site.getName()); + } + final String strYear = String.valueOf(year); + for(Path p : IOUtilities.listChildren(folder)){ + if(Files.isDirectory(p)){ + if(p.getFileName().toString().equals(strYear)){ + final GeoReferential ref = new GeoReferential(site, year); + for(Path tp : IOUtilities.listChildren(p)){ + final String tName = tp.getFileName().toString().toLowerCase(); + if(tName.startsWith(TYPE_ZONE_HYDRO)){ + ref.zoneHydroLocal().set(true); + }else if(tName.startsWith(TYPE_TACHE_URBAINE)){ + ref.tacheUrbaineLocal().set(true); + }else if(tName.startsWith(TYPE_TACHE_ARTIF)){ + ref.tacheArtifLocal().set(true); + }else if(tName.startsWith(TYPE_RPG)){ + ref.rpgLocal().set(true); + } + } + return ref; + } + } + } + throw new IOException("Referential for year "+year+" not found"); + } + + /** + * List available local referentials for given site. + * + * @param site + * @return + */ + public ObservableList getLocalReferentials(Site site) throws IllegalArgumentException, IOException { + final ObservableList lst = FXCollections.observableArrayList(); + Path folder = RhomeoCore.REFERENCIELS_GEO_PATH.resolve(GeometryUtils.getSha1(site.getGeometry())); + if (!Files.isDirectory(folder)) { + folder = RhomeoCore.REFERENCIELS_GEO_PATH.resolve(site.getName()); + } + if(Files.isDirectory(folder)){ + for(Path p : IOUtilities.listChildren(folder)) { + if (Files.isDirectory(p)) { + final int year; + // Ignore directories not matching year names. + try { + year = Integer.valueOf(p.getFileName().toString()); + } catch (NumberFormatException e) { + continue; + } + + final GeoReferential ref = new GeoReferential(site,year); + for(Path tp : IOUtilities.listChildren(p)){ + final String tName = tp.getFileName().toString().toLowerCase(); + if(tName.startsWith(TYPE_ZONE_HYDRO)){ + ref.zoneHydroLocal().set(true); + }else if(tName.startsWith(TYPE_TACHE_URBAINE)){ + ref.tacheUrbaineLocal().set(true); + }else if(tName.startsWith(TYPE_TACHE_ARTIF)){ + ref.tacheArtifLocal().set(true); + }else if(tName.startsWith(TYPE_RPG)){ + ref.rpgLocal().set(true); + } + } + lst.add(ref); + } + } + } + return lst; + } + + /** + * List server referentials. + * + * @return + * @throws DataStoreException + * @throws MalformedURLException + */ + public ObservableList getWFSReferentials() throws DataStoreException, MalformedURLException, WebFeatureException{ + + final Map count = new HashMap<>(); + try (WebFeatureClient client = getWFSClient()) { + final Set names = client.getNames(); + for(GenericName name : names){ + final String[] parts = name.tip().toString().toLowerCase().split("_"); + if(parts.length==2 && NAMES.contains(parts[0])){ + GeoReferential ref = count.get(parts[1]); + if(ref==null) ref = new GeoReferential(null, Integer.valueOf(parts[1])); + switch(parts[0]){ + case TYPE_ZONE_HYDRO : ref.zoneHydroWFS().set(true); break; + case TYPE_RPG : ref.rpgWFS().set(true); break; + case TYPE_TACHE_URBAINE : ref.tacheUrbaineWFS().set(true); break; + case TYPE_TACHE_ARTIF : ref.tacheArtifWFS().set(true); break; + } + count.put(parts[1], ref); + } + } + } + + return FXCollections.observableArrayList(count.values()); + } + + public MapItem getWFSLayers(final Optional filter, final String... referentialNames) throws DataStoreException, MalformedURLException { + MapItem result = MapBuilder.createItem(); + result.setName("WFS layers"); + try (WebFeatureClient client = getWFSClient()) { + final Set names = client.getNames().stream() + .filter(name -> { + if (referentialNames == null || referentialNames.length < 1) + return true; + for (final String refName : referentialNames) { + if (name.tip().toString().toLowerCase().startsWith(refName.toLowerCase())) + return true; + } + return false; + }) + .collect(Collectors.toSet()); + for (GenericName name : names) { + Query q = filter + .map(f -> { + final QueryBuilder builder = new QueryBuilder(name); + builder.setFilter(f); + builder.setProperties(new String[]{"geom"}); + return builder.buildQuery(); + }) + .orElseGet(() -> QueryBuilder.all(name)); + final FeatureMapLayer layer = MapBuilder.createFeatureLayer( + client.createSession(false).getFeatureCollection(q) + ); + layer.setName(name.tip().toString()); + layer.setVisible(false); + result.items().add(layer); + } + } + return result; + } + + /** + * Download from WFS service the referential for specified year. + * + * @param site analyze site + * @param year georeferential year + * @throws IllegalArgumentException If we cannot find any hydrographic zone + * intersecting site buffer. + * @throws Exception Any other exception is a read/write error. + */ + public void downloadReferential(Site site, int year) throws Exception { + + final Path localFolder = RhomeoCore.REFERENCIELS_GEO_PATH.resolve(GeometryUtils.getSha1(site.getGeometry())).resolve(String.valueOf(year)); + + //extract only data on site envelope + //not : this will be replace by hydro area after it has been downloaded + final Geometry buffer = GeometryUtils.computeBuffer(site.getGeometry()); + + //connect to WFS service + try (WebFeatureClient client = getWFSClient()) { + // First, we download hydrology data, because there's a special treatment over it. + downloadReferential(TYPE_ZONE_HYDRO + '_' + year, localFolder, buffer, false, client); + Geometry[] zhs = getLocalReferential(site, year).getFeatureCollection(TYPE_ZONE_HYDRO, null).stream() + .map(feat -> feat.getDefaultGeometryProperty().getValue()) + .filter(geom -> geom instanceof Geometry) + .toArray(size -> new Geometry[size]); + Geometry zhUnion = GO2Utilities.JTS_FACTORY.createGeometryCollection(zhs).union(); + + // Get other referentials + final Set names = new HashSet<>(NAMES); + names.remove(TYPE_ZONE_HYDRO); + for (String name : names) { + //some layers may be missing, P08 and P09 use different refentials. + try { + downloadReferential(name + '_' + year, localFolder, zhUnion, true, client); + } catch (IllegalArgumentException e) { + RhomeoCore.LOGGER.log(Level.FINE, "Cannot download referential", e); + } + } + } catch (Exception ex) { + //erase local folder if an error occurs + IOUtilities.deleteRecursively(localFolder); + throw ex; + } + } + + /** + * Download a single referential using given parameters. + * @param refName Name of the layer to request. + * @param targetDir Folder to put downloaded data into. + * @param zone Geometry delimiting the area to download (intersection filter performed). + * @param cut + * @param client Client to use to query WFS service. + * @throws DataStoreException Error on reading / writing. + * @throws IOException Error on reading / writing. + * @throws FactoryException Error on reading / writing. + * @throws XMLStreamException Error on reading / writing. + * @throws IllegalArgumentException If we cannot find given layer name on + * the server, or no data intersects given zone. + */ + protected void downloadReferential(final String refName, final Path targetDir, final Geometry zone, final boolean cut, final WebFeatureClient client) + throws DataStoreException, IOException, FactoryException, XMLStreamException { + //find feature type full name + GenericName fullName = null; + for (GenericName n : client.getNames()) { + if (n.tip().toString().equalsIgnoreCase(refName)) { + fullName = n; + break; + } + } + + if (fullName == null) { // TODO : throw illegalArgumentException managed above. + throw new IllegalArgumentException("No layer found for name ".concat(refName)); + } + + //prepare query + final FeatureType featureType = client.getFeatureType(fullName); + final FeatureTypeBuilder outputBuilder = new FeatureTypeBuilder(); + outputBuilder.setName(fullName); + final QueryBuilder qb = new QueryBuilder(fullName); + // We are only able to store simple features, so we remove complex + // structure from WFS data. + final List props = new ArrayList<>(); + for (PropertyDescriptor desc : featureType.getDescriptors()) { + if (isSimpleAttribute(desc)) { + props.add(desc.getName().toString()); + outputBuilder.add(desc); + } + } + + qb.setProperties(props.toArray(new String[0])); + qb.setCRS(RhomeoCore.getSiteCRS()); + //extract only data on site envelope + qb.setFilter(GO2Utilities.FILTER_FACTORY.intersects( + new DefaultPropertyName(featureType.getGeometryDescriptor().getName().tip().toString()), + GO2Utilities.FILTER_FACTORY.literal(zone) + )); + + //copy data to local folder + Files.createDirectories(targetDir); + try (final FeatureReader reader = getStreamingReader(client, qb.buildQuery()); + final ShapefileFeatureStore outStore = new ShapefileFeatureStore(targetDir.resolve(refName + ".shp").toUri())) { + if (!reader.hasNext()) + throw new IllegalArgumentException("No data intersects given zone for layer ".concat(fullName.toString())); + outStore.createFeatureType(fullName, outputBuilder.buildSimpleFeatureType()); + try (final FeatureWriter writer = outStore.getFeatureWriterAppend(fullName)) { + if (cut) { + while (reader.hasNext()) { + final Feature next = reader.next(); + Object value = next.getDefaultGeometryProperty().getValue(); + if (value instanceof Geometry) + next.getDefaultGeometryProperty().setValue(zone.intersection((Geometry) value)); + FeatureUtilities.copy(next, writer.next(), false); + } + } else { + while (reader.hasNext()) { + FeatureUtilities.copy(reader.next(), writer.next(), false); + } + } + } + } + } + + private boolean isSimpleAttribute(final PropertyDescriptor property) { + return property.getMinOccurs() == 1 && + property.getMaxOccurs() == 1 && + property instanceof AttributeDescriptor; + } + + /** + * Perform a getFeature on the distant server, browing its content lazily. + * @param client The client to use for request. + * @param query The query which contains reading parameters. + * @return A reader to stream service response. + * @throws DataStoreException + * @throws IOException + * @throws XMLStreamException + */ + private FeatureReader getStreamingReader(final WebFeatureClient client, final Query query) throws DataStoreException, IOException, XMLStreamException { + + final GetFeatureRequest request = client.createGetFeature(); + request.setTypeName(new QName(query.getTypeName().tip().toString())); + + final Filter filter = query.getFilter(); + if (filter == null) { + request.setFilter(Filter.INCLUDE); + } else { + request.setFilter(filter); + } + + final Integer max = query.getMaxFeatures(); + if (max != null) { + request.setMaxFeatures(max); + } + + request.setPropertyNames(query.getPropertyNames()); + + XmlFeatureReader reader = null; + reader = new JAXPStreamFeatureReader(client.getFeatureType(query.getTypeName())); + reader.getProperties().put(JAXPStreamFeatureReader.SKIP_UNEXPECTED_PROPERTY_TAGS, true); + final InputStream stream; + if (client.getUsePost()) { + stream = request.getResponseStream(); + } else { + final URL url = request.getURL(); + stream = url.openStream(); + } + + // If reader creation fails, stream isn't hanging on. + try { + return new StreamingFeatureReader(reader.readAsStream(stream), stream); + } catch (Throwable t) { + try { + stream.close(); + } catch (Throwable t1) { + t.addSuppressed(t1); + } + throw t; + } + } + + private static class StreamingFeatureReader implements FeatureReader { + + final FeatureReader source; + final InputStream dataSource; + + public StreamingFeatureReader(final FeatureReader source, final InputStream dataSource) { + this.source = source; + this.dataSource = dataSource; + } + + @Override + public FeatureType getFeatureType() { + return source.getFeatureType(); + } + + @Override + public Feature next() throws FeatureStoreRuntimeException { + return source.next(); + } + + @Override + public boolean hasNext() throws FeatureStoreRuntimeException { + return source.hasNext(); + } + + @Override + public void close() { + try { + source.close(); + } finally { + try { + dataSource.close(); + } catch (IOException ex) { + RhomeoCore.LOGGER.log(Level.WARNING, "An error occurred while closing data stream.", ex); + } + } + } + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/data/reference/OdonataDepartmentReference.java b/core/src/main/java/fr/cenra/rhomeo/core/data/reference/OdonataDepartmentReference.java new file mode 100644 index 0000000..58f0819 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/data/reference/OdonataDepartmentReference.java @@ -0,0 +1,218 @@ +/** + * 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.core.data.reference; + +import fr.cenra.rhomeo.api.data.Reference; +import java.util.Objects; + +/** + * Odonata presence by department. + * + * Colonne | Type | Modificateurs + * ---------+------------------------+--------------- + * espece | character varying(255) | + * dept | character varying(255) | + * valeur | double precision | + * id_dept | character varying(2) | + * cd_nom | integer | + * cd_ref | integer | + * + * (Source : base issue du script RhoMéO_Geomatys.backup) + * + * Note : There is no explicit primary key, but it seems logic for the key to be + * (cd_nom, id_dept). + * + * Remarques : + * + * L'absence de contrainte d'intégrité rend l'analyse sémantique de la table non + * triviale. + * + * Sémantique + * ========== + * + * Même si logiquement la clef devrait être (cd_nom, id_dept), il + * semble que les combinaisons (cd_ref, id_dept) soient également "sémantiquement" uniques + * car en nombre identique. + * + * select count(*) from (select distinct cd_ref, id_dept from odo_especes_par_dept) as tab; + * count + *------- + * 2436 + * + * select count(*) from (select distinct cd_nom, id_dept from odo_especes_par_dept) as tab; + * count + *------- + * 2436 + * + * Toutefois, on ne peut pas en déduire l'identité entre cd_nom et cd_ref dans la + * table (ce qui est logique). Nous avons d'ailleurs : + * + * select distinct cd_nom, cd_ref from odo_especes_par_dept where cd_nom<>cd_ref; + * cd_nom | cd_ref + *--------+-------- + * 820003 | 645873 + * + * + * Creation of the reference list from the database + * ================================================ + * + * Export csv + * ---------- + * copy ( + * select * from odo_especes_par_dept + * ) + * to '/…/odo_especes_par_dept.csv' delimiter ';' csv header; + * + * Dumps + * ----- + * pg_dump -t referentiels_non_geo.odo_especes_par_dept rhomeo > /…/odo_especes_par_dept.copy.sql + * pg_dump --inserts -t referentiels_non_geo.odo_especes_par_dept rhomeo > /…/odo_especes_par_dept.inserts.sql + * + * + * + * @author Samuel Andrés (Geomatys) + */ +public class OdonataDepartmentReference implements Reference { + + // META-INFORMATION : ATTRIBUTE NAMES + // MUST BE CONSISTENT WITH CLASS ATTRIBUTES + public static final String ATT_CD_NOM = "cd_nom"; + public static final String ATT_CD_REF = "cd_ref"; + public static final String ATT_ESPECE = "espece"; + public static final String ATT_ID_DEPT = "id_dept"; + public static final String ATT_DEPT = "dept"; + public static final String ATT_VALEUR = "valeur"; + + // Species attributes + private int cd_nom; + private int cd_ref; + private String espece; + + // Department attributes + private String id_dept; + private String dept; + + private double valeur; + + public int getCd_nom() { + return cd_nom; + } + + public void setCd_nom(int cd_nom) { + this.cd_nom = cd_nom; + } + + public int getCd_ref() { + return cd_ref; + } + + public void setCd_ref(int cd_ref) { + this.cd_ref = cd_ref; + } + + public String getEspece() { + return espece; + } + + public void setEspece(String espece) { + this.espece = espece; + } + + public String getId_dept() { + return id_dept; + } + + public void setId_dept(String id_dept) { + this.id_dept = id_dept; + } + + public String getDept() { + return dept; + } + + public void setDept(String dept) { + this.dept = dept; + } + + public double getValeur() { + return valeur; + } + + public void setValeur(double valeur) { + this.valeur = valeur; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 89 * hash + this.cd_nom; // same cd_nom => same cd_ref and same espece (interpretation) + hash = 89 * hash + Objects.hashCode(this.id_dept); // same id_dept => same dept + hash = 89 * hash + (int) (Double.doubleToLongBits(this.valeur) ^ (Double.doubleToLongBits(this.valeur) >>> 32)); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final OdonataDepartmentReference other = (OdonataDepartmentReference) obj; + if (this.cd_nom != other.cd_nom) { + return false; + } // same cd_nom => same cd_ref and same espece (interpretation) + if (Double.doubleToLongBits(this.valeur) != Double.doubleToLongBits(other.valeur)) { + return false; + } + if (!Objects.equals(this.id_dept, other.id_dept)) { + return false; + } // same id_dept => same dept + return true; + } + + @Override + public String toString() { + return new StringBuilder(Integer.toString(cd_nom)).append('|').append(espece).append('|').append(dept).append('|').append(valeur).toString(); + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/data/reference/OdonataDepartmentReferenceDescription.java b/core/src/main/java/fr/cenra/rhomeo/core/data/reference/OdonataDepartmentReferenceDescription.java new file mode 100644 index 0000000..619dcf5 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/data/reference/OdonataDepartmentReferenceDescription.java @@ -0,0 +1,75 @@ +/** + * 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.core.data.reference; + +import fr.cenra.rhomeo.api.data.ReferenceDescription; +import java.util.Collection; +import java.util.Collections; +import org.springframework.stereotype.Component; + +/** + * + * @author Samuel Andrés (Geomatys) + */ +@Component +public class OdonataDepartmentReferenceDescription implements ReferenceDescription { + + public static final String ODONATA_DEPARTMENT_DESCRIPTION_NAME = "odo_especes_par_dept"; + + @Override + public Class getReferenceType() { + return OdonataDepartmentReference.class; + } + + @Override + public String getName() { + return ODONATA_DEPARTMENT_DESCRIPTION_NAME; + } + + @Override + public Collection getAlias() { + return Collections.singleton("Répartition des odonates par département"); + } + + @Override + public String getRemarks() { + return null; + } + +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/data/reference/OdonataHabitatReference.java b/core/src/main/java/fr/cenra/rhomeo/core/data/reference/OdonataHabitatReference.java new file mode 100644 index 0000000..b7994f8 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/data/reference/OdonataHabitatReference.java @@ -0,0 +1,208 @@ +/** + * 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.core.data.reference; + +import fr.cenra.rhomeo.api.data.Reference; +import java.util.Objects; + +/** + * + * Affinity of Odonata species with different kinds of odonatologic habitat. + * + * Value range is from 1 to 4. + * + * Colonne | Type | Modificateurs + *---------+------------------------+--------------- + * espece | character varying(255) | + * biogeo | character varying(255) | + * habitat | character varying(255) | + * valeur | character varying(255) | + * zbio | character varying(255) | + * cd_nom | integer | + * cd_ref | integer | + * + * (Source : base issue du script RhoMéO_Geomatys.backup) + * + * Note : There is no explicit primary key, but it seems logic for the key to be + * (cd_nom, zbio, habitat). + * + * Creation of the reference list from the database + * ================================================ + * + * Export csv + * ---------- + * copy ( + * select * from odo_dependance_habitat + * ) + * to '/…/odo_dependance_habitat.csv' delimiter ';' csv header; + * + * Dumps + * ----- + * pg_dump -t referentiels_non_geo.odo_dependance_habitat rhomeo > /…/odo_dependance_habitat.copy.sql + * pg_dump --inserts -t referentiels_non_geo.odo_dependance_habitat rhomeo > /…/odo_dependance_habitat.inserts.sql + * + * @author Samuel Andrés (Geomatys) + */ +public class OdonataHabitatReference implements Reference { + + // META-INFORMATION : ATTRIBUTE NAMES + // MUST BE CONSISTENT WITH CLASS ATTRIBUTES + public static final String ATT_CD_NOM = "cd_nom"; + public static final String ATT_CD_REF = "cd_ref"; + public static final String ATT_ESPECE = "espece"; + public static final String ATT_ZBIO = "zbio"; + public static final String ATT_BIOGEO = "biogeo"; + public static final String ATT_HABITAT = "habitat"; + public static final String ATT_VALEUR = "valeur"; + + // Species attributes + private int cd_nom; + private int cd_ref; + private String espece; + + // biozone attributes + private String zbio; + private String biogeo; + + // Habitat + private String habitat; + + // Value for a association between a species, a biozone and an habitat. + private int valeur; + + public int getCd_nom() { + return cd_nom; + } + + public void setCd_nom(int cd_nom) { + this.cd_nom = cd_nom; + } + + public int getCd_ref() { + return cd_ref; + } + + public void setCd_ref(int cd_ref) { + this.cd_ref = cd_ref; + } + + public String getEspece() { + return espece; + } + + public void setEspece(String espece) { + this.espece = espece; + } + + public String getZbio() { + return zbio; + } + + public void setZbio(String zbio) { + this.zbio = zbio; + } + + public String getBiogeo() { + return biogeo; + } + + public void setBiogeo(String biogeo) { + this.biogeo = biogeo; + } + + public String getHabitat() { + return habitat; + } + + public void setHabitat(String habitat) { + if (habitat != null && habitat.startsWith("0")) + habitat = habitat.substring(1); + this.habitat = habitat; + } + + public int getValeur() { + return valeur; + } + + public void setValeur(int valeur) { + this.valeur = valeur; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 59 * hash + this.cd_nom; // same cd_nom => same cd_ref and same espece (interpretation) + hash = 59 * hash + Objects.hashCode(this.zbio); // same zbio => same biogeo (interpretation) + hash = 59 * hash + Objects.hashCode(this.habitat); + hash = 61 * hash + this.valeur; + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final OdonataHabitatReference other = (OdonataHabitatReference) obj; + if (this.cd_nom != other.cd_nom) { + return false; + } // same cd_nom => same cd_ref and same espece (interpretation) + if (!Objects.equals(this.zbio, other.zbio)) { + return false; + } // same zbio => same biogeo (interpretation) + if (!Objects.equals(this.habitat, other.habitat)) { + return false; + } + if (this.valeur != other.valeur) { + return false; + } + return true; + } + + @Override + public String toString() { + return new StringBuilder(Integer.toString(cd_nom)).append('|').append(cd_ref).append('|').append(espece).append('|').append(habitat).append('|').append(valeur).toString(); + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/data/reference/OdonataHabitatReferenceDescription.java b/core/src/main/java/fr/cenra/rhomeo/core/data/reference/OdonataHabitatReferenceDescription.java new file mode 100644 index 0000000..d191838 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/data/reference/OdonataHabitatReferenceDescription.java @@ -0,0 +1,75 @@ +/** + * 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.core.data.reference; + +import fr.cenra.rhomeo.api.data.ReferenceDescription; +import java.util.Collection; +import java.util.Collections; +import org.springframework.stereotype.Component; + +/** + * + * @author Samuel Andrés (Geomatys) + */ +@Component +public class OdonataHabitatReferenceDescription implements ReferenceDescription { + + public static final String ODONATA_HABITAT_DESCRIPTION_NAME = "odo_dependance_habitat"; + + @Override + public Class getReferenceType() { + return OdonataHabitatReference.class; + } + + @Override + public String getName() { + return ODONATA_HABITAT_DESCRIPTION_NAME; + } + + @Override + public Collection getAlias() { + return Collections.singleton("Liste des affinités des odonates par habitat odonatologique"); + } + + @Override + public String getRemarks() { + return null; + } + +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/data/reference/OrthopteraIndicatorReference.java b/core/src/main/java/fr/cenra/rhomeo/core/data/reference/OrthopteraIndicatorReference.java new file mode 100644 index 0000000..43914ad --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/data/reference/OrthopteraIndicatorReference.java @@ -0,0 +1,245 @@ +/** + * 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.core.data.reference; + +import fr.cenra.rhomeo.api.data.Reference; + +/** + * Orthopterans indicator reference representation. + * + * Colonne | Type | Modificateurs + * -------------------+------------------------+--------------- + * cd_nom | integer | non NULL + * cd_ref | integer | + * lb_nom | character varying(255) | + * pres_lr | integer | + * pres_ra | integer | + * pres_paca | integer | + * hs_code | integer | + * hs_val | integer | + * dm_code | integer | + * dm_val | integer | + * mediterraneen1_ml | integer | + * mediterraneen1_ma | integer | + * mediterraneen2_ma | integer | + * mediterraneen2_tb | integer | + * alpin_ma | integer | + * alpin_tb | integer | + * continental_ma | integer | + * continental_tb | integer | + * + * (Source : base issue du script RhoMéO_Geomatys.backup) + * + * @author Samuel Andrés (Geomatys) + */ +public class OrthopteraIndicatorReference implements Reference { + + /** + * CD_REF of the reference taxon. + */ + private int cd_ref; + + private int mediterraneen1_ml;// Pourquoi pas booleen ? + private int mediterraneen1_ma;// Pourquoi pas booleen ? + private int mediterraneen2_ma;// Pourquoi pas booleen ? + private int mediterraneen2_tb;// Pourquoi pas booleen ? + private int alpin_ma;// Pourquoi pas booleen ? + private int alpin_tb;// Pourquoi pas booleen ? + private int continental_ma;// Pourquoi pas booleen ? + private int continental_tb;// Pourquoi pas booleen ? + + /** + * Name of the taxon. + */ + private String lb_nom; + + private int hs_code; + + /** + * Environment humidity + */ + private int hs_val; + + private int dm_code; + + /** + * Sedimentary dynamics + */ + private int dm_val; + + public int getCd_ref() { + return cd_ref; + } + + public void setCd_ref(int cd_ref) { + this.cd_ref = cd_ref; + } + + public int getMediterraneen1_ml() { + return mediterraneen1_ml; + } + + public void setMediterraneen1_ml(int mediterraneen1_ml) { + this.mediterraneen1_ml = mediterraneen1_ml; + } + + public int getMediterraneen1_ma() { + return mediterraneen1_ma; + } + + public void setMediterraneen1_ma(int mediterraneen1_ma) { + this.mediterraneen1_ma = mediterraneen1_ma; + } + + public int getMediterraneen2_ma() { + return mediterraneen2_ma; + } + + public void setMediterraneen2_ma(int mediterraneen2_ma) { + this.mediterraneen2_ma = mediterraneen2_ma; + } + + public int getMediterraneen2_tb() { + return mediterraneen2_tb; + } + + public void setMediterraneen2_tb(int mediterraneen2_tb) { + this.mediterraneen2_tb = mediterraneen2_tb; + } + + public int getAlpin_ma() { + return alpin_ma; + } + + public void setAlpin_ma(int alpin_ma) { + this.alpin_ma = alpin_ma; + } + + public int getAlpin_tb() { + return alpin_tb; + } + + public void setAlpin_tb(int alpin_tb) { + this.alpin_tb = alpin_tb; + } + + public int getContinental_ma() { + return continental_ma; + } + + public void setContinental_ma(int continental_ma) { + this.continental_ma = continental_ma; + } + + public int getContinental_tb() { + return continental_tb; + } + + public void setContinental_tb(int continental_tb) { + this.continental_tb = continental_tb; + } + + public String getLb_nom() { + return lb_nom; + } + + public void setLb_nom(String lb_nom) { + this.lb_nom = lb_nom; + } + + public int getHs_code() { + return hs_code; + } + + public void setHs_code(int hs_code) { + this.hs_code = hs_code; + } + + public int getHs_val() { + return hs_val; + } + + public void setHs_val(int hs_val) { + this.hs_val = hs_val; + } + + public int getDm_code() { + return dm_code; + } + + public void setDm_code(int dm_code) { + this.dm_code = dm_code; + } + + public int getDm_val() { + return dm_val; + } + + public void setDm_val(int dm_val) { + this.dm_val = dm_val; + } + + @Override + public int hashCode() { + return cd_ref; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final OrthopteraIndicatorReference other = (OrthopteraIndicatorReference) obj; + return getCd_ref() == other.getCd_ref() + && getHs_val() == other.getHs_val() + && getDm_val() == other.getDm_val(); + } + + @Override + public String toString() { + return new StringBuilder().append(cd_ref).append(' ').append(lb_nom).toString(); + } + +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/data/reference/OrthopteraIndicatorReferenceDescription.java b/core/src/main/java/fr/cenra/rhomeo/core/data/reference/OrthopteraIndicatorReferenceDescription.java new file mode 100644 index 0000000..2d57add --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/data/reference/OrthopteraIndicatorReferenceDescription.java @@ -0,0 +1,75 @@ +/** + * 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.core.data.reference; + +import fr.cenra.rhomeo.api.data.ReferenceDescription; +import java.util.Collection; +import java.util.Collections; +import org.springframework.stereotype.Component; + +/** + * + * @author Samuel Andrés (Geomatys) + */ +@Component +public class OrthopteraIndicatorReferenceDescription implements ReferenceDescription { + + public static final String ORTHOPTERA_INDICATOR_DESCRIPTION_NAME = "ortho_indicateurs"; + + @Override + public Class getReferenceType() { + return OrthopteraIndicatorReference.class; + } + + @Override + public String getName() { + return ORTHOPTERA_INDICATOR_DESCRIPTION_NAME; + } + + @Override + public Collection getAlias() { + return Collections.singleton("Liste des valeurs indicatrices des orthoptères"); + } + + @Override + public String getRemarks() { + return null; + } + +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/data/reference/Taxref.java b/core/src/main/java/fr/cenra/rhomeo/core/data/reference/Taxref.java new file mode 100644 index 0000000..50b32ab --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/data/reference/Taxref.java @@ -0,0 +1,202 @@ +/** + * 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.core.data.reference; + +import fr.cenra.rhomeo.api.data.Reference; +import java.util.Objects; + +/** + * Taxref taxonomic referential representation. + * + * + * Colonne | Type | Modificateurs + * --------------+----------------------+--------------- + * regne | text | + * phylum | text | + * classe | text | + * ordre | text | + * famille | text | + * cd_nom | character varying(6) | non NULL + * cd_taxsup | character varying(6) | + * cd_ref | character varying(6) | + * rang | text | + * lb_nom | text | + * lb_auteur | text | + * nom_complet | text | + * nom_valide | text | + * nom_vern | text | + * nom_vern_eng | text | + * habitat | text | + * fr | text | + * gf | text | + * mar | text | + * gua | text | + * sm | text | + * sb | text | + * spm | text | + * may | text | + * epa | text | + * reu | text | + * taaf | text | + * pf | text | + * nc | text | + * wf | text | + * cli | text | + * aphia_id | text | + * + * (Source : base issue du script RhoMéO_Geomatys.backup) + * + * @author Samuel Andrés + * + * @see TaxrefDescription + */ +public class Taxref implements Reference { + + // META-INFORMATION : ATTRIBUTE NAMES + // MUST BE CONSISTENT WITH CLASS ATTRIBUTES + public static final String ATT_CD_NOM = "cd_nom"; + public static final String ATT_CD_TAXSUP = "cd_taxsup"; + public static final String ATT_CD_REF = "cd_ref"; + public static final String ATT_RANG = "rang"; + public static final String ATT_NOM_COMPLET = "nomComplet"; + + // Other constants + public static final String RANG_SSES = "SSES"; + + /** + * Primary key. + */ + private int cd_nom; + + private int cd_taxsup; + + private int cd_ref; + + private String rang; + + private String lb_nom; + + private String ordre; + + private String classe; + + public int getCd_nom() { + return cd_nom; + } + + public void setCd_nom(int cd_nom) { + this.cd_nom = cd_nom; + } + + public int getCd_taxsup() { + return cd_taxsup; + } + + public void setCd_taxsup(int cd_taxsup) { + this.cd_taxsup = cd_taxsup; + } + + public int getCd_ref() { + return cd_ref; + } + + public void setCd_ref(int cd_ref) { + this.cd_ref = cd_ref; + } + + public String getRang() { + return rang; + } + + public void setRang(String rang) { + this.rang = rang; + } + + public String getLb_nom() { + return lb_nom; + } + + public void setLb_nom(String nomComplet) { + this.lb_nom = nomComplet; + } + + public String getOrdre() { + return ordre; + } + + public void setOrdre(String ordre) { + this.ordre = ordre; + } + + public String getClasse() { + return classe; + } + + public void setClasse(String classe) { + this.classe = classe; + } + + @Override + public int hashCode() { + return cd_nom; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Taxref other = (Taxref) obj; + if (!Objects.equals(this.cd_nom, other.cd_nom)) { + return false; + } + return true; + } + + @Override + public String toString() { + return lb_nom; + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/data/reference/TaxrefDescription.java b/core/src/main/java/fr/cenra/rhomeo/core/data/reference/TaxrefDescription.java new file mode 100644 index 0000000..0b7fa40 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/data/reference/TaxrefDescription.java @@ -0,0 +1,76 @@ +/** + * 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.core.data.reference; + +import fr.cenra.rhomeo.api.data.ReferenceDescription; +import java.util.Collection; +import java.util.Collections; +import org.springframework.stereotype.Component; + +/** + * Description of the {@link Taxref} reference type. + * + * @author Samuel Andrés (Geomatys) + */ +@Component +public class TaxrefDescription implements ReferenceDescription { + + private static final String TAXREF_DESCRIPTION_NAME = "taxref"; + + @Override + public Class getReferenceType() { + return Taxref.class; + } + + @Override + public String getName() { + return TAXREF_DESCRIPTION_NAME; + } + + @Override + public Collection getAlias() { + return Collections.singletonList("Référentiel taxonomique"); + } + + @Override + public String getRemarks() { + return null; + } + +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/data/site/DuplicatedKeyException.java b/core/src/main/java/fr/cenra/rhomeo/core/data/site/DuplicatedKeyException.java new file mode 100644 index 0000000..d230d98 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/data/site/DuplicatedKeyException.java @@ -0,0 +1,55 @@ +/** + * 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.core.data.site; + +/** + * Exception to launch when trying to use the same key for several items in the same collection. + * + * @author Cédric Briançon (Geomatys) + */ +public class DuplicatedKeyException extends Exception { + + public DuplicatedKeyException() { + super(); + } + + public DuplicatedKeyException(final String message) { + super(message); + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/data/site/RhomeoRepository.java b/core/src/main/java/fr/cenra/rhomeo/core/data/site/RhomeoRepository.java new file mode 100644 index 0000000..6cdb58b --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/data/site/RhomeoRepository.java @@ -0,0 +1,103 @@ +/** + * 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.core.data.site; + +import fr.cenra.rhomeo.api.IdentifiedObject; +import javafx.collections.ObservableList; +import javax.validation.constraints.NotNull; +import org.hibernate.validator.constraints.NotBlank; + + +/** + * Generic data access methods all project repositories should have. + * + * @author Cédric Briançon (Geomatys) + * @param + */ +public interface RhomeoRepository { + /** + * Find the item for the given key. + * + * @param key An item key + * @return The matching item, or {@code null} if not found. + */ + I findOne(@NotBlank String key); + + /** + * Create an item in the data source if the item key is not already present in the store, + * otherwise throws {@link DuplicatedKeyException}. + * + * @param object The new item to create, should not be {@code null} + * @throws DuplicatedKeyException if an object already exists with the same key + */ + void create(@NotNull I object) throws DuplicatedKeyException; + + /** + * Find all items in the data source. + * + * @return A list of items stored, eventually an empty list, never {@code null} + */ + ObservableList findAll(); + + /** + * Update an existing item in the data source. Its key should be the same in the + * given object and in the stored version in order to know which item has to be updated. + * If the given object key is not known in the store, then do nothing. + * + * @param object Item to update, with new values. Should not be {@code null}. + */ + void update(@NotNull I object); + + /** + * Update an existing item in the data source. The given object may have a new key specified, + * so use the old key parameter to know which item should be updated. + * + * @param object Item to update, with new values. Should not be {@code null}. + * @param oldKey Existing item key to update. + * @throws DuplicatedKeyException if the given key in the object parameter is already used. + */ + void update(@NotNull I object, String oldKey) throws DuplicatedKeyException; + + /** + * Delete an existing item in the data source. + * + * @param key Key of the item to delete. + */ + void delete(@NotBlank String key); +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/data/site/SiteImpl.java b/core/src/main/java/fr/cenra/rhomeo/core/data/site/SiteImpl.java new file mode 100644 index 0000000..e6af6f1 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/data/site/SiteImpl.java @@ -0,0 +1,229 @@ +/** + * 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.core.data.site; + +import com.vividsolutions.jts.geom.MultiPolygon; +import fr.cenra.rhomeo.api.InternationalResource; +import fr.cenra.rhomeo.api.annotations.RefersTo; +import fr.cenra.rhomeo.api.data.Site; +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.list.HumidZoneType; +import fr.cenra.rhomeo.core.list.OdonateZoneBio; +import fr.cenra.rhomeo.core.list.OrthoptereZoneBio; + +import java.util.Collection; +import java.util.Collections; +import java.util.Objects; + +/** + * POJO representing a site. No intelligence in here. + * + * @author Cédric Briançon (Geomatys) + */ +public class SiteImpl implements Site, Cloneable, InternationalResource { + + private MultiPolygon geometry; + private String countyCode; + private String referent; + private String organization; + private String zoneType; + private String odonateType; + private String orthoptereType; + private String name; + private String remarks; + + private SiteImpl() {} + + public SiteImpl(MultiPolygon geometry) { + this.geometry = geometry; + } + + public SiteImpl(MultiPolygon geometry, String countyCode, String referent, String organization, String zoneType, + String odonateType, String orthoptereType, String name, String remarks) { + this.geometry = geometry; + this.countyCode = countyCode; + this.referent = referent; + this.organization = organization; + this.zoneType = zoneType; + this.odonateType = odonateType; + this.orthoptereType = orthoptereType; + this.name = name; + this.remarks = remarks; + } + + @Override + public MultiPolygon getGeometry() { + return geometry; + } + + public void setGeometry(MultiPolygon geometry) { + this.geometry = geometry; + } + + @Override + public String getCountyCode() { + return countyCode; + } + + public void setCountyCode(final String county) { + this.countyCode = county; + } + + @Override + public String getReferent() { + return referent; + } + + public void setReferent(String referent) { + this.referent = referent; + } + + @Override + public String getOrganization() { + return organization; + } + + public void setOrganization(String organization) { + this.organization = organization; + } + + @RefersTo(type = HumidZoneType.class, property = "code") + @Override + public String getZoneType() { + return zoneType; + } + + public void setZoneType(String zoneType) { + this.zoneType = zoneType; + } + + @RefersTo(type = OdonateZoneBio.class, property = "code") + @Override + public String getOdonateType() { + return odonateType; + } + + public void setOdonateType(String odonateType) { + this.odonateType = odonateType; + } + + @Override + public SiteImpl clone() { + final SiteImpl newSite = new SiteImpl(geometry); + newSite.setCountyCode(countyCode); + newSite.setName(name); + newSite.setOdonateType(odonateType); + newSite.setOrthoptereType(orthoptereType); + newSite.setOrganization(organization); + newSite.setReferent(referent); + newSite.setRemarks(remarks); + newSite.setZoneType(zoneType); + + return newSite; + } + + @RefersTo(type= OrthoptereZoneBio.class, property = "code") + @Override + public String getOrthoptereType() { + return orthoptereType; + } + + public void setOrthoptereType(String orthoptereType) { + this.orthoptereType = orthoptereType; + } + + @Override + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String getRemarks() { + return remarks; + } + + public void setRemarks(String remarks) { + this.remarks = remarks; + } + + @Override + public Collection getAlias() { + return Collections.singleton(name); + } + + @Override + public String toString() { + return name; + } + + @Override + public boolean equals(Object o) { + if (o == null) + return false; + if (getClass() != o.getClass()) + return false; + final SiteImpl other = (SiteImpl) o; + + return Objects.equals(this.geometry, other.geometry) && + RhomeoCore.equivalent(this.countyCode, other.countyCode) && + RhomeoCore.equivalent(this.referent, other.referent) && + RhomeoCore.equivalent(this.organization, other.organization) && + RhomeoCore.equivalent(this.zoneType, other.zoneType) && + RhomeoCore.equivalent(this.odonateType, other.odonateType) && + RhomeoCore.equivalent(this.orthoptereType, other.orthoptereType) && + RhomeoCore.equivalent(this.name, other.name) && + RhomeoCore.equivalent(this.remarks, other.remarks); + } + + @Override + public int hashCode() { + int result = geometry.hashCode(); + result = 31 * result + name.hashCode(); + return result; + } + + @Override + public int compareTo(Site o) { + return o == null ? -1 : getName().compareTo(o.getName()); + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/data/site/SiteRepository.java b/core/src/main/java/fr/cenra/rhomeo/core/data/site/SiteRepository.java new file mode 100644 index 0000000..a3bca63 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/data/site/SiteRepository.java @@ -0,0 +1,52 @@ +/** + * 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.core.data.site; + +import fr.cenra.rhomeo.api.data.Site; +import javafx.collections.ObservableList; + +/** + * For spring injection. + * + * @author Cédric Briançon (Geomatys) + */ +public interface SiteRepository extends RhomeoRepository, AutoCloseable { + + ObservableList findNames(); +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/data/site/SiteRepositoryImpl.java b/core/src/main/java/fr/cenra/rhomeo/core/data/site/SiteRepositoryImpl.java new file mode 100644 index 0000000..3ee9443 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/data/site/SiteRepositoryImpl.java @@ -0,0 +1,483 @@ +/** + * 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.core.data.site; + +import com.vividsolutions.jts.geom.MultiPolygon; +import fr.cenra.rhomeo.api.data.Site; +import fr.cenra.rhomeo.core.RhomeoCore; +import static fr.cenra.rhomeo.core.RhomeoCore.SITES; +import static fr.cenra.rhomeo.core.RhomeoCore.SITES_SHP_PATH; +import fr.cenra.rhomeo.core.RhomeoRuntimeException; +import fr.cenra.rhomeo.core.data.site.SiteImpl; +import java.lang.ref.WeakReference; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javax.annotation.PreDestroy; +import org.apache.sis.storage.DataStoreException; +import org.apache.sis.util.ArgumentChecks; +import org.apache.sis.util.collection.Cache; +import org.apache.sis.util.iso.Names; +import org.geotoolkit.data.FeatureCollection; +import org.geotoolkit.data.FeatureIterator; +import org.geotoolkit.data.FeatureReader; +import org.geotoolkit.data.FeatureWriter; +import org.geotoolkit.data.query.Query; +import org.geotoolkit.data.query.QueryBuilder; +import org.geotoolkit.data.shapefile.ShapefileFeatureStore; +import org.geotoolkit.data.shapefile.ShapefileFeatureStoreFactory; +import org.geotoolkit.factory.FactoryFinder; +import org.geotoolkit.factory.Hints; +import org.geotoolkit.feature.Feature; +import org.geotoolkit.feature.FeatureBuilder; +import org.geotoolkit.feature.FeatureTypeBuilder; +import org.geotoolkit.feature.type.FeatureType; +import org.geotoolkit.parameter.Parameters; +import org.opengis.filter.Filter; +import org.opengis.filter.FilterFactory2; +import org.opengis.parameter.ParameterValueGroup; +import org.opengis.util.FactoryException; +import org.opengis.util.LocalName; +import org.springframework.stereotype.Repository; +import org.springframework.validation.annotation.Validated; + + +/** + * Access point to sites stored in the file system. + * An {@linkplain ObservableList observable list} can be followed for listening + * changes via the {@link #findAll()} method. + * + * @author Cédric Briançon (Geomatys) + */ +@Repository +@Validated +public class SiteRepositoryImpl implements SiteRepository { + + private static final LocalName NAME = Names.createLocalName(null, ":", SITES); + + private static FeatureType SITE_TYPE; + + private final FilterFactory2 ff; + + /** + * Cache result of {@link #findNames() ()} method, to avoid reading the + * shapefile each time a site is updated, created or deleted. + */ + private WeakReference> allNames; + + /** + * Cache loaded sites, to ensure their uniqueness in memory. + */ + private final Cache cache; + + /** + * Feature store to use. + */ + private final ShapefileFeatureStore store; + + /** + * Get or create the {@linkplain #store feature store}, creating all folders needed + * if necessary. + * @throws java.lang.Exception If an error occurs while initializing shapefile. + */ + public SiteRepositoryImpl() throws Exception { + Files.createDirectories(RhomeoCore.SITES_PATH); + + final ParameterValueGroup parameters = ShapefileFeatureStoreFactory.PARAMETERS_DESCRIPTOR.createValue(); + Parameters.getOrCreate(ShapefileFeatureStoreFactory.PATH, parameters) + .setValue(SITES_SHP_PATH.toUri()); + Parameters.getOrCreate(ShapefileFeatureStoreFactory.NAMESPACE, parameters) + .setValue("no namespace"); + + final ShapefileFeatureStoreFactory fact = new ShapefileFeatureStoreFactory(); + + if (Files.exists(SITES_SHP_PATH)) { + store = (ShapefileFeatureStore) fact.open(parameters); + } else { + store = (ShapefileFeatureStore) fact.create(parameters); + store.createFeatureType(NAME, getSiteType()); + } + + // Empty or corrupted file + if (store.getName() == null || !store.getName().equals(NAME)) { + store.createFeatureType(NAME, getSiteType()); + } + + final Hints hints = new Hints(); + hints.put(Hints.FILTER_FACTORY, FilterFactory2.class); + ff = (FilterFactory2) FactoryFinder.getFilterFactory(hints); + + cache = new Cache(4, 0, false); + } + + /** + * + * @return Cached data, or null if cache has not been initialized yet. + */ + private synchronized ObservableList getCachedNames() { + return allNames == null ? null : allNames.get(); + } + + /** + * Create a new filter which keeps only sites whose name is equal to given one. + * @param nameValue The name to filter against. + * @return A new filter. + */ + private Filter newNameFilter(final String nameValue) { + return ff.equals(ff.property(RhomeoCore.FT_PROPERTIES.NAME.name()), ff.literal(nameValue)); + } + + /** + * + * @param name The name to filter against. + * @return A collection of sites whose names are equal to given one. + */ + private FeatureCollection filteredByName(final String name) { + ArgumentChecks.ensureNonEmpty("Name to search", name.trim()); + return store.createSession(false).getFeatureCollection( + QueryBuilder.filtered(this.NAME, newNameFilter(name)) + ); + } + + /** + * + * @param siteName A name to find sites for. + * @return True if at least one site with the same name already exists. + */ + private synchronized boolean exists(final String siteName) { + ArgumentChecks.ensureNonEmpty("Name to search", siteName.trim()); + // Do not use cache here, because if an existing site name has been modified, + // it would appear in cache. + return !filteredByName(siteName).isEmpty(); + } + + /** + * {@inheritDoc} + */ + @Override + public synchronized Site findOne(final String name) { + if (name == null || name.isEmpty()) + return null; + + try { + return cache.getOrCreate(name, () -> { + final FeatureCollection col = filteredByName(name); + if (col.isEmpty()) { + return null; + } + + try (final FeatureIterator it = col.iterator()) { + return toSite(it.next()); + } + }); + } catch (Exception e) { + throw new RhomeoRuntimeException("Cannot load site named ".concat(name), e); + } + } + + /** + * {@inheritDoc} + */ + @Override + public synchronized void create(final Site site) throws DuplicatedKeyException { + ArgumentChecks.ensureNonNull("Site", site); + + if (exists(site.getName())) { + throw new DuplicatedKeyException(); + } + + try { + final Feature toAdd = toFeature(site); + store.addFeatures(NAME, Collections.singleton(toAdd)); + } catch (DataStoreException e) { + throw new RhomeoRuntimeException(e); + } + + ObservableList cached = getCachedNames(); + if (cached != null) { + cached.add(site.getName()); + Collections.sort(cached); + } + + cache.put(site.getName(), site); + } + + /** + * {@inheritDoc} + */ + @Override + public synchronized ObservableList findAll() { + throw new UnsupportedOperationException("Cannot load full site list in memory !"); + } + + public synchronized ObservableList findNames() { + ObservableList result = getCachedNames(); + if (result == null) { + final List sites = new ArrayList<>(); + final Query query; + try { + final QueryBuilder builder = new QueryBuilder(store.getName()); + builder.setProperties(new String[]{RhomeoCore.FT_PROPERTIES.NAME.name()}); + query = builder.buildQuery(); + try (final FeatureReader reader = store.getFeatureReader(query)) { + while (reader.hasNext()) { + sites.add(reader.next().getPropertyValue(RhomeoCore.FT_PROPERTIES.NAME.name()).toString()); + } + } + } catch (DataStoreException ex) { + throw new RhomeoRuntimeException(ex); + } + Collections.sort(sites); + result = FXCollections.observableList(sites); + allNames = new WeakReference<>(result); + } + + return FXCollections.unmodifiableObservableList(result); + } + + /** + * Update the first encountered feature matching given filter. + * + * @param filter + * @param site + * @throws DataStoreException + */ + private synchronized void updateFeature(final Filter filter, final Site site) throws DataStoreException { + // There is a bug in the shp method getFeatureWriter(name, filter), it never uses the filter parameter! + // Consequently we have to test each filter afterwards, via filter.evaluate(feature) + boolean found = false; + try(final FeatureWriter writer = store.getFeatureWriter(NAME, Filter.INCLUDE)) { + while (writer.hasNext()) { + final Feature f = writer.next(); + if (filter.evaluate(f)) { + toFeature(f, site); + writer.write(); + found = true; + } + } + } + + if (!found) { + // If we've got until here, no element has been found for given filter. + throw new IllegalArgumentException("Cannot update unexisting site !"); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void update(final Site site) { + try { + update(site, null); + } catch (DuplicatedKeyException ex) { + throw new RhomeoRuntimeException(ex); // should not happen, as key is not modified. + } + } + + /** + * {@inheritDoc} + */ + @Override + public synchronized void update(final Site site, String oldName) throws DuplicatedKeyException { + ArgumentChecks.ensureNonNull("Site", site); + + // Defines if we need to sort the sites list in cache or not. + // If user updated the site name, then it is required to ensure keeping this list sorted. + boolean needsToSort = false; + if (oldName == null || oldName.trim().isEmpty() || oldName.equals(site.getName())) { + oldName = site.getName(); + } else { + // Here we want to rename the current site name, and its position in the list might be impacted. + needsToSort = true; + } + + ArgumentChecks.ensureNonNull("Name to update", oldName); + if (!oldName.equals(site.getName()) && exists(site.getName())) { + throw new DuplicatedKeyException("Cannot change site name because another one already has the same name !"); + } + + // Persist change + try { + // Ok not already used key, we can update the matching feature + updateFeature(newNameFilter(oldName), site); + } catch (Exception e) { + throw new RhomeoRuntimeException(e); + } + + // update caches + if (needsToSort) { + final ObservableList cached = getCachedNames(); + if (cached != null) + cached.set(cached.indexOf(oldName), site.getName()); + Collections.sort(cached); + } + + if (needsToSort) { + cache.remove(oldName); + cache.put(site.getName(), site); + } else { + cache.replace(oldName, site); + } + } + + /** + * {@inheritDoc} + */ + @Override + public synchronized void delete(final String name) { + ArgumentChecks.ensureNonEmpty("Site name", name.trim()); + // There is a bug in the shp method getFeatureWriter(name, filter), it never uses the filter parameter! + // Consequently we have to test each filter afterwards, via filter.evaluate(feature) + final Filter filter = newNameFilter(name); + try (final FeatureWriter writer = store.getFeatureWriter(this.NAME, Filter.INCLUDE)) { + while (writer.hasNext()) { + final Feature f = writer.next(); + if (filter.evaluate(f)) { + writer.remove(); + } + } + } catch (DataStoreException e) { + throw new RhomeoRuntimeException(e); + } + + ObservableList cached = getCachedNames(); + if (cached != null) { + cached.removeAll(Collections.singleton(name)); + } + + cache.remove(name); + } + + /** + * {@inheritDoc} + */ + @PreDestroy + @Override + public synchronized void close() throws Exception { + allNames = null; + store.close(); + } + + public static final FeatureType getSiteType() { + if (SITE_TYPE == null) { + final FeatureTypeBuilder ftb = new FeatureTypeBuilder(); + ftb.setName(NAME); + try { + ftb.add(RhomeoCore.FT_PROPERTIES.the_geom.name(), MultiPolygon.class, RhomeoCore.getSiteCRS()); + } catch (FactoryException ex) { + throw new RhomeoRuntimeException(ex); + } + ftb.add(RhomeoCore.FT_PROPERTIES.NAME.name(), String.class); + ftb.add(RhomeoCore.FT_PROPERTIES.REMARKS.name(), String.class); + ftb.add(RhomeoCore.FT_PROPERTIES.COUNTY.name(), String.class); + ftb.add(RhomeoCore.FT_PROPERTIES.REFERENT.name(), String.class); + ftb.add(RhomeoCore.FT_PROPERTIES.ORG.name(), String.class); + ftb.add(RhomeoCore.FT_PROPERTIES.TYPE.name(), String.class); + ftb.add(RhomeoCore.FT_PROPERTIES.ODONATE.name(), String.class); + ftb.add(RhomeoCore.FT_PROPERTIES.ORTHOPTERE.name(), String.class); + ftb.setDefaultGeometry(RhomeoCore.FT_PROPERTIES.the_geom.name()); + SITE_TYPE = ftb.buildFeatureType(); + } + + return SITE_TYPE; + } + + /** + * Converts a {@link Site} into a {@link Feature}. + * + * @param site Site to convert. + * @return A new feature matching this site, never {@code null} + * @throws DataStoreException + */ + public static Feature toFeature(final Site site) throws DataStoreException { + final FeatureBuilder sfb = new FeatureBuilder(getSiteType()); + sfb.setPropertyValue(RhomeoCore.FT_PROPERTIES.the_geom.name(), site.getGeometry()); + sfb.setPropertyValue(RhomeoCore.FT_PROPERTIES.COUNTY.name(), site.getCountyCode()); + sfb.setPropertyValue(RhomeoCore.FT_PROPERTIES.NAME.name(), site.getName()); + sfb.setPropertyValue(RhomeoCore.FT_PROPERTIES.ODONATE.name(), site.getOdonateType()); + sfb.setPropertyValue(RhomeoCore.FT_PROPERTIES.ORTHOPTERE.name(), site.getOrthoptereType()); + sfb.setPropertyValue(RhomeoCore.FT_PROPERTIES.ORG.name(), site.getOrganization()); + sfb.setPropertyValue(RhomeoCore.FT_PROPERTIES.REFERENT.name(), site.getReferent()); + sfb.setPropertyValue(RhomeoCore.FT_PROPERTIES.REMARKS.name(), site.getRemarks()); + sfb.setPropertyValue(RhomeoCore.FT_PROPERTIES.TYPE.name(), site.getZoneType()); + return sfb.buildFeature(site.getName()); + } + + /** + * Apply site values into an existing feature. + * + * @param feature existing feature to update + * @param site new values to extract + * @throws DataStoreException + */ + public static void toFeature(final Feature feature, final Site site) throws DataStoreException { + feature.setPropertyValue(RhomeoCore.FT_PROPERTIES.the_geom.name(), site.getGeometry()); + feature.setPropertyValue(RhomeoCore.FT_PROPERTIES.COUNTY.name(), site.getCountyCode()); + feature.setPropertyValue(RhomeoCore.FT_PROPERTIES.NAME.name(), site.getName()); + feature.setPropertyValue(RhomeoCore.FT_PROPERTIES.ODONATE.name(), site.getOdonateType()); + feature.setPropertyValue(RhomeoCore.FT_PROPERTIES.ORTHOPTERE.name(), site.getOrthoptereType()); + feature.setPropertyValue(RhomeoCore.FT_PROPERTIES.ORG.name(), site.getOrganization()); + feature.setPropertyValue(RhomeoCore.FT_PROPERTIES.REFERENT.name(), site.getReferent()); + feature.setPropertyValue(RhomeoCore.FT_PROPERTIES.REMARKS.name(), site.getRemarks()); + feature.setPropertyValue(RhomeoCore.FT_PROPERTIES.TYPE.name(), site.getZoneType()); + } + + /** + * Converts a {@link Feature} into a {@link Site}. + * + * @param feature Feature to convert into a site. + * @return A new instance of site, never {@code null} + */ + public static Site toSite(final Feature feature) { + final SiteImpl newSite = new SiteImpl((MultiPolygon)feature.getProperty(RhomeoCore.FT_PROPERTIES.the_geom.name()).getValue()); + newSite.setCountyCode(feature.getProperty(RhomeoCore.FT_PROPERTIES.COUNTY.name()).getValue().toString()); + newSite.setName(feature.getProperty(RhomeoCore.FT_PROPERTIES.NAME.name()).getValue().toString()); + newSite.setOdonateType(feature.getProperty(RhomeoCore.FT_PROPERTIES.ODONATE.name()).getValue().toString()); + newSite.setOrthoptereType(feature.getProperty(RhomeoCore.FT_PROPERTIES.ORTHOPTERE.name()).getValue().toString()); + newSite.setOrganization(feature.getProperty(RhomeoCore.FT_PROPERTIES.ORG.name()).getValue().toString()); + newSite.setReferent(feature.getProperty(RhomeoCore.FT_PROPERTIES.REFERENT.name()).getValue().toString()); + newSite.setRemarks(feature.getProperty(RhomeoCore.FT_PROPERTIES.REMARKS.name()).getValue().toString()); + newSite.setZoneType(feature.getProperty(RhomeoCore.FT_PROPERTIES.TYPE.name()).getValue().toString()); + return newSite; + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/list/CodeValue.java b/core/src/main/java/fr/cenra/rhomeo/core/list/CodeValue.java new file mode 100644 index 0000000..bed82ad --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/list/CodeValue.java @@ -0,0 +1,49 @@ +/** + * 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.core.list; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public interface CodeValue { + + Object getCode(); + Object getValue(); +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/list/HumidZoneType.java b/core/src/main/java/fr/cenra/rhomeo/core/list/HumidZoneType.java new file mode 100644 index 0000000..17d07bd --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/list/HumidZoneType.java @@ -0,0 +1,103 @@ +/** + * 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.core.list; + +/** + * @author Cédric Briançon (Geomatys) + */ +public enum HumidZoneType implements CodeValue { + + GRANDS_ESTUAIRES ("1", "Grands estuaires"), // Indicateurs : 1, 2, 3, 5, 6, 8, 12, 13 + BAIES_ESTUAIRES ("2", "Baies et estuaires moyens plats"), // Indicateurs : 1, 2, 3, 5, 6, 8, 12, 13 + MARAIS_LAGUNES ("3.1", "Marais et lagunes côtiers - lagunes"), // Indicateurs : 1, 2, 3, 5, 6, 8, 9, 10, 11, 12, 13 + MARAIS_LAGUNES_PERI_LAGUN ("3.2", "Marais et lagunes côtiers - péri-lagunaire"), // Indicateurs : 1, 2, 3, 5, 6, 8, 9, 10, 11, 12, 13 + MARAIS_LAGUNES_PERI_LAGUN_EAU("3.3", "Marais et lagunes côtiers - péri-lagunaire avec rapport d'eau"), // Indicateurs : 1, 2, 3, 5, 6, 8, 9, 10, 11, 12, 13 + MARAIS_SAUMATRES ("4", "Marais saumâtres aménagés"), // Indicateurs : 1, 2, 3, 6, 8, 9, 10, 11, 12, 13 + BORDURES_COURS_EAU ("5", "Bordures de cours d'eau"), // Indicateurs : 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 + PLAINES_ALLUVIALES ("6", "Plaines alluviales"), // Indicateurs : 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13 + ZH_BAS_FOND_ALTITUDE ("7.1", "Zones humides de bas-fonds en tête de BV - altitude"), // Indicateurs : 1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13 + ZH_BAS_FOND_TOURB_ACIDE ("7.2", "Zones humides de bas-fonds en tête de BV - tourbière acide"), // Indicateurs : 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 + ZH_BAS_FOND_TOURB_ALCALINE ("7.3", "Zones humides de bas-fonds en tête de BV - tourbière alcaline"), // Indicateurs : 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13 + ZH_BAS_FOND_PENTES ("7.4", "Zones humides de bas-fonds en tête de BV - pentes et sources"), // Indicateurs : 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13 + ZH_BAS_FOND_COMBES ("7.5", "Zones humides de bas-fonds en tête de BV - combes et bordure de ruisseau"), // Indicateurs : 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13 + REGIONS_ETANGS ("8", "Régions d'étangs"), // Indicateurs : 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 + BORDURES_PLAN_EAU_ACIDE ("9.1", "Bordures de plan d'eau (lac) - ZH acide"), // Indicateurs : 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13 + BORDURES_PLAN_EAU_ALCALINE ("9.2", "Bordures de plan d'eau (lac) - ZH alcaline"), // Indicateurs : 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13 + MARAIS_LANDES_TOURB ("10.1", "Marais et landes humides de plaine - tourbière de plaine"), // Indicateurs : 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13 + MARAIS_LANDES_PRAIRIES ("10.2", "Marais et landes humides de plaine - prairies humides"), // Indicateurs : 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13 + MARAIS_LANDES_PRES ("10.3", "Marais et landes humides de plaine - Prés salés continentaux"), // Indicateurs : 1, 2, 3, 6, 8, 9, 10, 11, 12, 13 + ZH_PONCT_MARE_SAUMATRE ("11.11", "Zones humides ponctuelles - Mare temporaire saumâtre"), // Indicateurs : 1, 2, 3, 6, 8, 9, 10, 11, 12, 13 + ZH_PONCT_MARE_ALCALINE ("11.12", "Zones humides ponctuelles - Mare temporaire alcaline"), // Indicateurs : 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13 + ZH_PONCT_MARE_ACIDE ("11.13", "Zones humides ponctuelles - Mare temporaire acide"), // Indicateurs : 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13 + ZH_PONCT_MARE_PERMANENTE ("11.2", "Zones humides ponctuelles - Mare permanente"), // Indicateurs : 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13 + MARAIS_AMENAGES_AGRICOLE ("12", "Marais aménagés dans un but agricole"), // Indicateurs : 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13 + ZH_ARTIFICELLES ("13", "Zones humides artificielles"); // Indicateurs : 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13 + + private final String code; + private final String value; + + HumidZoneType(final String code, final String value) { + this.code = code; + this.value = value; + } + + @Override + public String getCode() { + return code; + } + + @Override + public String getValue() { + return value; + } + + public static HumidZoneType getByCode(final String code) { + for (final HumidZoneType candid : values()) { + if (candid.getCode().equals(code)) { + return candid; + } + } + return null; + } + + @Override + public String toString() { + return code +" "+ value; + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/list/OdonateZoneBio.java b/core/src/main/java/fr/cenra/rhomeo/core/list/OdonateZoneBio.java new file mode 100644 index 0000000..61c34cf --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/list/OdonateZoneBio.java @@ -0,0 +1,130 @@ +/** + * 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.core.list; + +import fr.cenra.rhomeo.core.data.reference.OdonataHabitatReference; + +/** + * L_zone_bio_odonate. + * + * id_zone_bio_odo nom_zone_bio_odo + * ------------------------------------- + * 1 Alpin + * 2 Continental + * 3 Méditerranéen occidental + * 4 Méditerranéen oriental + * 5 Pyrénéen + * + * (Source : Champs_et_Listes.xlsx) + * + * We add the column "zbio" to join {@link OdonataHabitatReference} and a new + * entry to represent 'zglobal' value. + * + * select distinct zbio, biogeo from odo_dependance_habitat; + * + * zbio | biogeo + *--------------------------+-------------------------- + * mediterraneen oriental | Méditerranéen oriental + * pyreneen | pyreneen + * continental | Continental + * alpin | Alpin + * mediterraneen occidental | Méditerranéen occidental + * zglobal | Z Global + * + * (Source : RhoMéO_Geomatys.backup) + * + * @author Cédric Briançon (Geomatys) + * @author Samuel Andrés (Geomatys) + */ +public enum OdonateZoneBio implements CodeValue { + ALPIN ("1", "Alpin", "alpin"), + CONTINENTAL ("2", "Continental", "continental"), + MED_OCCIDENTAL("3", "Méditerranéen occidental", "mediterraneen occidental"), + MED_ORIENTAL ("4", "Méditerranéen oriental", "mediterraneen oriental"), + PYRENEEN ("5", "Pyrénéen", "pyreneen"), + ZGLOBAL ("", "Z Global", "zglobal"); + + private final String code; + private final String value; + private final String zbio; + + + OdonateZoneBio(final String code, final String value, final String zbio) { + this.code = code; + this.value = value; + this.zbio = zbio; + } + + @Override + public String getCode() { + return code; + } + + @Override + public String getValue() { + return value; + } + + public String getZbio() { + return zbio; + } + + public static OdonateZoneBio getByCode(final String code) { + for (final OdonateZoneBio candid : values()) { + if (candid.getCode().equals(code)) { + return candid; + } + } + return null; + } + + public static OdonateZoneBio getByZbio(final String code) { + for (final OdonateZoneBio candid : values()) { + if (candid.getZbio().equals(code)) { + return candid; + } + } + return null; + } + + @Override + public String toString() { + return code +" "+ value; + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/list/OrthoptereZoneBio.java b/core/src/main/java/fr/cenra/rhomeo/core/list/OrthoptereZoneBio.java new file mode 100644 index 0000000..621b938 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/list/OrthoptereZoneBio.java @@ -0,0 +1,97 @@ +/** + * 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.core.list; + +/** + * L_zone_bio_orthoptere. + * + * id_zone_bio_ortho nom_zone_bio_ortho + * --------------------------------------- + * 1 Alpin_marais_alluvial + * 2 Alpin_tourbière + * 3 Mediterranen1_marais_alluvial + * 4 Mediterranen1_marais_littoral + * 5 Mediterranen2_tourbière + * 6 Mediterranen2_marais_alluvial + * + * (Source : Champs_et_Listes.xlsx) + * + * @author Cédric Briançon (Geomatys) + */ +public enum OrthoptereZoneBio implements CodeValue { + + ALPIN_MARAIS_ALLUVIAL("1", "Alpin_marais_alluvial"), + ALPIN_TOURBIERE ("2", "Alpin_tourbière"), + MED1_MARAIS_ALLUVIAL ("3", "Mediterranen1_marais_alluvial"), + MED1_MARAIS_LITTORAL ("4", "Mediterranen1_marais_littoral"), + MED2_TOURBIERE ("5", "Mediterranen2_tourbière"), + MED2_MARAIS_ALLUVIAL ("6", "Mediterranen2_marais_alluvial"); + + private final String code; + private final String value; + + OrthoptereZoneBio(final String code, final String value) { + this.code = code; + this.value = value; + } + + @Override + public String getCode() { + return code; + } + + @Override + public String getValue() { + return value; + } + + public static OrthoptereZoneBio getByCode(final String code) { + for (final OrthoptereZoneBio candid : values()) { + if (candid.getCode().equals(code)) { + return candid; + } + } + return null; + } + + @Override + public String toString() { + return code +" "+ value; + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/list/VonPost.java b/core/src/main/java/fr/cenra/rhomeo/core/list/VonPost.java new file mode 100644 index 0000000..15b9b3b --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/list/VonPost.java @@ -0,0 +1,76 @@ +/** + * 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.core.list; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public enum VonPost implements CodeValue { + H1 ("Eau limpide"), + H2 ("eau peu colorée"), + H3 ("eau trouble pâle"), + H4 ("eau trouble foncée"), + H5 ("eau trouble et particules"), + H6 ("1/3 du matériel passe entre les doigts"), + H7 ("1/2 du matériel passe entre les doigts"), + H8 ("2/3 du matériel passe entre les doigts"), + H9 ("Presque tout le matériel"), + H10("Tout le matériel"); + + private final String value; + private VonPost(final String value) { + this.value = value; + } + + @Override + public String getCode() { + return name(); + } + + @Override + public String getValue() { + return value; + } + + @Override + public String toString() { + return new StringBuilder(name()).append(" : ").append(value).toString(); + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/preferences/ftp/FTPAccess.java b/core/src/main/java/fr/cenra/rhomeo/core/preferences/ftp/FTPAccess.java new file mode 100644 index 0000000..a75fba3 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/preferences/ftp/FTPAccess.java @@ -0,0 +1,206 @@ +/** + * 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.core.preferences.ftp; + +import fr.cenra.rhomeo.core.util.EncryptionResult; +import fr.cenra.rhomeo.core.util.SecretGenerator; +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.util.prefs.Preferences; +import javax.validation.constraints.NotNull; +import org.apache.commons.net.ftp.FTPClient; + +/** + * Holds connection information over a single FTP service. The service is defined + * by its host name, but also by a login, password and optionally a root directory. + * + * NOTE : If, for some reason, security context cannot initialize, passwords become + * unavailable. + * + * @author Alexis Manin (Geomatys) + */ +public class FTPAccess { + + private static enum PROPERTIES { + ADRESS, + PORT, + LOGIN, + PASSWORD, + WORKING_DIR + } + + private final Preferences node; + + /** + * Encryption manager. Can be null if an error occurred at initialisation. In + * this case, no password will be read or written. + */ + private final SecretGenerator cipher; + + protected FTPAccess(@NotNull final Preferences infoContainer) { + this.node = infoContainer; + cipher = SecretGenerator.getInstance().orElse(null); + } + + private String getProperty(final PROPERTIES p) { + return node.get(p.name(), null); + } + + private void setProperty(final PROPERTIES p, final String value) { + if (value == null || value.trim().isEmpty()) { + node.remove(p.name()); + } else { + node.put(p.name(), value); + } + } + + public String getAdress() { + return getProperty(PROPERTIES.ADRESS); + } + + public void setAdress(final String newAdress) { + setProperty(PROPERTIES.ADRESS, newAdress); + } + + public int getPort() { + return node.getInt(PROPERTIES.PORT.name(), 21); + } + + public void setPort(final int port) { + node.putInt(PROPERTIES.PORT.name(), port); + } + + public String getLogin() { + return getProperty(PROPERTIES.LOGIN); + } + + public void setLogin(final String newLogin) { + setProperty(PROPERTIES.LOGIN, newLogin); + } + + + public String getWorkingDir() { + return getProperty(PROPERTIES.WORKING_DIR); + } + + public void setWorkingDir(final String newDir) { + setProperty(PROPERTIES.WORKING_DIR, newDir); + } + + public synchronized String getPassword() throws GeneralSecurityException { + final String tmpValue = getProperty(PROPERTIES.PASSWORD); + if (tmpValue == null || tmpValue.isEmpty()) { // No pw stored. + return ""; + } + + if (cipher == null) { + throw new GeneralSecurityException("no security manager available. Passwords cannot be read or written from preferences."); + } + + byte[] sk = node.getByteArray("ftp_access_skey", null); + byte[] sr = node.getByteArray("ftp_access_sran", null); + if (sk == null || sr == null) { + throw new GeneralSecurityException("no security manager available. Passwords cannot be read or written from preferences."); + } + + return cipher.decrypt(tmpValue, sk, sr); + } + + public synchronized void setPassword(final String newPassword) throws GeneralSecurityException { + if (cipher == null) { + throw new GeneralSecurityException("no security manager available. Passwords cannot be read or written from preferences."); + } + + // Empty value, no encryption needed. + if (newPassword == null || newPassword.isEmpty()) { + setProperty(PROPERTIES.PASSWORD, ""); + return; + } + + final EncryptionResult encrypted = cipher.encrypt(newPassword); + setProperty(PROPERTIES.PASSWORD, encrypted.output); + + node.putByteArray("ftp_access_skey", encrypted.getKey()); + node.putByteArray("ftp_access_sran", encrypted.getSecureRandom()); + } + + /** + * Create a new connection over the FTP service provided by holded information. + * The provided {@link FTPClient} must be closed using {@link FTPClient#disconnect() } + * once you've finished your work. + * + * @return A client to exchange data with FTP service which contains + * reference files. + * + * @throws IOException If we cannot connect to distant service. + * @throws java.security.GeneralSecurityException If an authentication is + * required, but we cannot access to password. + */ + public FTPClient createClient() throws IOException, GeneralSecurityException { + return createClient(getAdress(), getPort(), getWorkingDir(), getLogin(), getPassword()); + } + + public static FTPClient createClient(final String adress, final int port, final String workDir, final String login, final String password) throws IOException, GeneralSecurityException { + if (adress == null) { + throw new IllegalStateException("No adress configured for FTP access !"); + } + + final FTPClient client = new FTPClient(); + client.enterLocalActiveMode(); + if (port < 1) { + client.connect(adress); + } else { + client.connect(adress, port); + } + + if (login != null) { + if (!client.login(login, password)) { + throw new GeneralSecurityException("Unable to authenticate with the login "+ login); + } + } + + if (workDir != null) { + if (!client.changeWorkingDirectory(workDir)) { + throw new IOException("Unable to change of working directory to:"+ workDir); + } + } + + return client; + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/preferences/ftp/FTPPreferences.java b/core/src/main/java/fr/cenra/rhomeo/core/preferences/ftp/FTPPreferences.java new file mode 100644 index 0000000..bb2d85b --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/preferences/ftp/FTPPreferences.java @@ -0,0 +1,75 @@ +/** + * 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.core.preferences.ftp; + +import fr.cenra.rhomeo.api.preferences.PreferenceGroup; + +import javax.validation.constraints.NotNull; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public interface FTPPreferences extends PreferenceGroup { + + public static enum ACCESS_POINTS { + REFERENCES("Références"), + RESULTS("Résultats"); + + private final String title; + + ACCESS_POINTS(final String value) { + this.title = value; + } + + public String getTitle() { + return title; + } + } + + /** + * Give all information about a specific FTP end point. + * + * @param ap The FTP service to retrieve. + * + * @return an object capable to open a connection over the queried FTP service. + */ + @NotNull + FTPAccess getAccess(@NotNull final ACCESS_POINTS ap); +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/preferences/ftp/FTPPreferencesImpl.java b/core/src/main/java/fr/cenra/rhomeo/core/preferences/ftp/FTPPreferencesImpl.java new file mode 100644 index 0000000..bfa138a --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/preferences/ftp/FTPPreferencesImpl.java @@ -0,0 +1,188 @@ +/** + * 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.core.preferences.ftp; + +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.preferences.net.NetPreferences; +import fr.cenra.rhomeo.core.util.SecretGenerator; +import java.io.IOException; +import java.io.InputStream; +import java.security.GeneralSecurityException; +import java.util.Collections; +import java.util.List; +import java.util.logging.Level; +import java.util.prefs.Preferences; +import javax.annotation.PostConstruct; +import javax.validation.constraints.NotNull; +import org.apache.sis.util.ArgumentChecks; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; +import org.springframework.validation.annotation.Validated; + +/** + * Holds preferences over FTP connections. You can retrieve information about a + * specific FTP connection by using {@link #getAccess(fr.cenra.rhomeo.core.preferences.ftp.FTPPreferences.ACCESS_POINTS) + * }. + * + * Known connections are listed in {@link ACCESS_POINTS}. + * + * @author Alexis Manin (Geomatys) + */ +@Component +@Qualifier(FTPPreferencesImpl.NAME) +@Validated +public class FTPPreferencesImpl implements FTPPreferences { + + public static final String NAME = "FTPPreferencesImpl"; + + private final Preferences root; + + public FTPPreferencesImpl() { + root = Preferences.userNodeForPackage(FTPPreferencesImpl.class); + } + + /** + * DO NOT USE IT ! + * + * @param key DO NOT USE IT ! + * @return DO NOT USE IT ! + */ + @Override + public String getPreference(Object key) { + throw new UnsupportedOperationException("No value stored on root."); + } + + /** + * DO NOT USE IT ! + * + * @param key DO NOT USE IT ! + * @param value DO NOT USE IT ! + */ + @Override + public void setPreference(Object key, String value) { + throw new UnsupportedOperationException("No value stored on root."); + } + + @Override + public List getKeys() { + return Collections.EMPTY_LIST; + } + + /** + * Give all information about a specific FTP end point. + * + * @param ap The FTP service to retrieve. + * + * @return an object capable to open a connection over the queried FTP + * service. + */ + @NotNull + @Override + public FTPAccess getAccess(@NotNull final ACCESS_POINTS ap) { + ArgumentChecks.ensureNonNull("Input access point", ap); + return new FTPAccess(root.node(ap.name())); + } + + @Override + public int getPriority() { + return 0; + } + + /** + * If no FTP account has been parameterised, a default one is set for result + * publication and reference data. + */ + @PostConstruct + private void checkDefaultAccesses() { + FTPAccess results = getAccess(FTPPreferences.ACCESS_POINTS.RESULTS); + if (setDefaultAccess(results)) { + results.setWorkingDir("results"); + } + + FTPAccess references = getAccess(FTPPreferences.ACCESS_POINTS.REFERENCES); + if (setDefaultAccess(references)) { + references.setWorkingDir("references"); + } + } + + private boolean setDefaultAccess(final FTPAccess access) { + if ((access.getAdress() == null || access.getAdress().trim().isEmpty()) + && (access.getLogin() == null || access.getLogin().trim().isEmpty()) + && (access.getWorkingDir() == null || access.getWorkingDir().trim().isEmpty())) { + + access.setAdress("constellation.cenra-outils.org"); + access.setLogin("rhomeoftp"); + final SecretGenerator gen = SecretGenerator.getInstance().orElse(null); + if (gen == null) + return false; + + try { + access.setPassword(gen.decrypt("4Iru5sD2uzixbWHhu7R72s658w/l3yCz", getDefaultKey(), getDefaultSR())); + return true; + } catch (IOException | GeneralSecurityException ex) { + RhomeoCore.LOGGER.log(Level.WARNING, null, ex); + } + } + return false; + } + + private byte[] getDefaultKey() throws IOException { + final byte[] buf = new byte[16]; + int read = 0; + try (final InputStream stream = NetPreferences.class.getResourceAsStream("defaultKey")) { + do { + read += stream.read(buf, read, buf.length - read); + } while (read < buf.length - 1); + } + + return buf; + } + + private byte[] getDefaultSR() throws IOException { + final byte[] buf = new byte[8]; + int read = 0; + try (final InputStream stream = NetPreferences.class.getResourceAsStream("defaultSR")) { + do { + read += stream.read(buf, read, 8 - read); + } while (read < 7); + } + + return buf; + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/preferences/net/NetKey.java b/core/src/main/java/fr/cenra/rhomeo/core/preferences/net/NetKey.java new file mode 100644 index 0000000..c8df1d6 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/preferences/net/NetKey.java @@ -0,0 +1,77 @@ +/** + * 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.core.preferences.net; + +import fr.cenra.rhomeo.api.preferences.InternationalPreferenceKey; +import org.apache.sis.util.ArgumentChecks; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class NetKey implements InternationalPreferenceKey { + + private final String keyId; + private final String defaultValue; + + public NetKey(final String netKey) { + this(netKey, null); + } + + public NetKey(final String netKey, final String defaultValue) { + ArgumentChecks.ensureNonNull("Key", netKey); + this.keyId = netKey; + this.defaultValue = defaultValue; + } + + @Override + public String name() { + return keyId; + } + + @Override + public String getKey() { + return keyId; + } + + @Override + public String getDefaultValue() { + return defaultValue; + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/preferences/net/NetPreferences.java b/core/src/main/java/fr/cenra/rhomeo/core/preferences/net/NetPreferences.java new file mode 100644 index 0000000..5475368 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/preferences/net/NetPreferences.java @@ -0,0 +1,172 @@ +/** + * 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.core.preferences.net; + +import fr.cenra.rhomeo.api.preferences.UserPackagePreferenceGroup; +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.RhomeoRuntimeException; +import fr.cenra.rhomeo.core.util.EncryptionResult; +import fr.cenra.rhomeo.core.util.SecretGenerator; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.security.GeneralSecurityException; +import java.util.Arrays; +import java.util.Base64; +import java.util.Collections; +import java.util.List; +import java.util.logging.Level; +import org.springframework.stereotype.Component; + +/** + * + * @author Alexis Manin (Geomatys) + */ +@Component +public class NetPreferences extends UserPackagePreferenceGroup { + + public static final NetKey UPDATE_URL = new NetKey("update_url", "http://updates-bao.cenra-outils.org/updates/update.json"); + public static final NetKey UPDATE_USER = new NetKey("update_user", "rhomeo"); + public static final NetKey UPDATE_PASSWORD = new PassNetKey("update_pass", null); + public static final NetKey WFS_URL = new NetKey("wfs_url", "http://constellation.cenra-outils.org/WS/wfs/referential"); + + private static final List KEYS = Collections.unmodifiableList(Arrays.asList(new NetKey[] { + UPDATE_URL, UPDATE_USER, UPDATE_PASSWORD, WFS_URL + })); + + private static final String UPDATE_KEY_PREF = "net_update_pass_key"; + private static final String UPDATE_SR_PREF = "net_update_pass_sr"; + + private final SecretGenerator gen; + + public NetPreferences() { + gen = SecretGenerator.getInstance().orElse(null); + // Default values for password and secret key. + if (getPreference(UPDATE_PASSWORD) == null) { + prefs.put(UPDATE_PASSWORD.getKey(), "4Iru5sD2uzixbWHhu7R72s658w/l3yCz"); + try { + final byte[] buf = new byte[16]; + int read = 0; + try (final InputStream stream = NetPreferences.class.getResourceAsStream("defaultKey")) { + do { + read += stream.read(buf, read, buf.length - read); + } while (read < buf.length -1); + prefs.putByteArray(UPDATE_KEY_PREF, buf); + } + read = 0; + try (final InputStream stream = NetPreferences.class.getResourceAsStream("defaultSR")) { + do { + read += stream.read(buf, read, 8 - read); + } while (read < 7); + prefs.putByteArray(UPDATE_SR_PREF, Arrays.copyOf(buf, 8)); + } + } catch (IOException ex) { + RhomeoCore.LOGGER.log(Level.FINE, "cannot set default values", ex); + } + + } + } + + @Override + public List getKeys() { + return KEYS; + } + + @Override + public void setPreference(NetKey key, String value) { + if (UPDATE_PASSWORD.equals(key) && value != null && !(value = value.trim()).isEmpty()) { + if (gen != null) { + try { + EncryptionResult encrypted = gen.encrypt(value); + prefs.putByteArray(UPDATE_KEY_PREF, encrypted.getKey()); + prefs.putByteArray(UPDATE_SR_PREF, encrypted.getSecureRandom()); + value = encrypted.getOutput(); + } catch (GeneralSecurityException ex) { + throw new RhomeoRuntimeException(ex); + } + } else { + throw new RhomeoRuntimeException("no security manager available. Passwords cannot be written into preferences."); + } + } + super.setPreference(key, value); + } + + @Override + public int getPriority() { + return 1; + } + + public URL getUpdateURL() throws MalformedURLException { + return new URL(getPreference(UPDATE_URL)); + } + + public URLConnection openConnection(final URL toReach) throws GeneralSecurityException, IOException { + final URL updateURL = getUpdateURL(); + String user = getPreference(UPDATE_USER); + if (toReach.getHost().equals(updateURL.getHost()) && toReach.getUserInfo() == null && user != null && !(user = user.trim()).isEmpty()) { + final String pass = getPreference(UPDATE_PASSWORD); + URLConnection con = toReach.openConnection(); + String dpw = null; + if (pass !=null && !pass.isEmpty()) { + final byte[] key = prefs.getByteArray(UPDATE_KEY_PREF, null); + final byte[] sr = prefs.getByteArray(UPDATE_SR_PREF, null); + if (key == null && sr == null) { // No encryption parameter + dpw = pass; + } else if (gen == null) { // No cipher + throw new RhomeoRuntimeException("no security manager available. Passwords cannot be read from preferences."); + } else { + dpw = gen.decrypt(pass, key, sr); + } + } + final StringBuilder authInfo = new StringBuilder(user); + if (dpw != null) { + authInfo.append(':').append(dpw); + } + final String b64 = Base64.getEncoder().withoutPadding().encodeToString( + authInfo.toString().getBytes() + ); + con.addRequestProperty("Authorization", "Basic ".concat(b64)); + return con; + } else { + return toReach.openConnection(); + } + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/preferences/net/PassNetKey.java b/core/src/main/java/fr/cenra/rhomeo/core/preferences/net/PassNetKey.java new file mode 100644 index 0000000..6fcb849 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/preferences/net/PassNetKey.java @@ -0,0 +1,56 @@ +/** + * 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.core.preferences.net; + +import fr.cenra.rhomeo.api.preferences.PasswordKey; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class PassNetKey extends NetKey implements PasswordKey { + + public PassNetKey(String netKey) { + super(netKey); + } + + public PassNetKey(String netKey, String defaultValue) { + super(netKey, defaultValue); + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/result/ResultStorage.java b/core/src/main/java/fr/cenra/rhomeo/core/result/ResultStorage.java new file mode 100644 index 0000000..2cfee3b --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/result/ResultStorage.java @@ -0,0 +1,341 @@ +/** + * 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.core.result; + +import com.fasterxml.jackson.databind.ObjectMapper; +import fr.cenra.rhomeo.api.data.Site; +import fr.cenra.rhomeo.api.process.Indicator; +import fr.cenra.rhomeo.api.result.DashboardResultItem; +import fr.cenra.rhomeo.api.result.Index; +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.RhomeoRuntimeException; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.util.ExportUtils; +import fr.cenra.rhomeo.core.util.GeometryUtils; +import fr.cenra.rhomeo.core.data.site.SiteRepository; +import fr.cenra.rhomeo.core.util.SerializableDataContext; +import java.beans.IntrospectionException; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Optional; +import java.util.function.Supplier; +import java.util.logging.Level; +import org.apache.commons.net.ftp.FTPClient; +import org.apache.sis.storage.DataStoreException; +import org.apache.sis.util.collection.IntegerList; +import org.geotoolkit.nio.IOUtilities; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * Component in charge of storing indicator results locally. + * + * @author Alexis Manin (Geomatys) + */ +@Component +public class ResultStorage { + + @Autowired + private ResultWriter writer; + + @Autowired + private Session session; + + @Autowired + private SiteRepository siteRepo; + + @Autowired + private ResultWriter resultWriter; + + final String[] expectedFiles = new String[]{ExportUtils.METADATA_JSON, ResultWriter.RESULT_FILE_NAME, ResultWriter.ADDITIONAL_RESULT_FILE_NAME}; + + private ResultStorage() { + Arrays.sort(expectedFiles); + } + + public void store() throws IOException, IntrospectionException { + if (session.getResults() == null || session.getResults().isEmpty() || session.getDataContext() == null) + return; + + final String sha1 = GeometryUtils.getSha1(session.getDataContext().getSite().getGeometry()); + final Path root = RhomeoCore.RESULT_PATH.resolve(sha1); + Files.createDirectories(root); + + /* Sort results by indicator and year, as publication / export via dashboard + * has to be able to export results only for a specific indicator at a + * specific year. We iterate on indices and not on the tracking points + * related to process context, because some protocols appear to use no + * tracking point at all. + */ + final IntegerList years = new IntegerList(10, Short.MAX_VALUE); + for (final Index i : session.getResults()) { + if (years.occurrence(i.getYear()) < 1) + years.add(i.getYear()); + } + + for (final Indicator indic : session.getProcessContext().getIndicators()) { + final Path indicPath = root.resolve(indic.getName()); + Files.createDirectories(indicPath); + for (final int year : years) { + final Path yearPath = indicPath.resolve(Integer.toString(year)); + IOUtilities.deleteRecursively(yearPath); + Files.createDirectory(yearPath); + writer.prepareWriting(yearPath) + .writeMetadataJSON() + .writeResults((i) -> i.getYear() == year && i.getSpi().getIndicator().equals(indic)); + } + } + } + + /** + * Notify the result storage manager that a site had its name changed. + * @param oldSiteName + * @param newSiteName + * @throws IOException + */ +// public void siteNameChanged(final String oldSiteName, final String newSiteName) throws IOException { +// final Base64.Encoder encoder = Base64.getEncoder().withoutPadding(); +// String oldName = encoder.encodeToString(oldSiteName.getBytes(StandardCharsets.UTF_8)); +// final Path oldPath = RhomeoCore.RESULT_PATH.resolve(oldName); +// if (!Files.exists(oldPath)) +// return; // Nothing to move +// +// final String newName = encoder.encodeToString(newSiteName.getBytes(StandardCharsets.UTF_8)); +// Files.move(oldPath, RhomeoCore.RESULT_PATH.resolve(newName)); +// } + + /** + * Remove results associated to the input site, If any. Otherwise, do nothing. + * @param siteName Name of the site to delete results for. + * + * @throws IOException If an error occurs while deleting files. + */ + public void deleteIfExists(String siteName) throws IOException { + if (siteName == null || (siteName = siteName.trim()).isEmpty()) + return; + deleteIfExists(siteRepo.findOne(siteName)); + } + + /** + * Remove results associated to the input site, If any. Otherwise, do nothing. + * @param site The site to delete results for. + * + * @throws IOException If an error occurs while deleting files. + */ + public void deleteIfExists(final Site site) throws IOException { + if (site == null) + return; + final String sha1 = GeometryUtils.getSha1(site.getGeometry()); + IOUtilities.deleteRecursively(RhomeoCore.RESULT_PATH.resolve(sha1)); + } + + /** + * Copy the results associated to the input dashboard item in the FTP pointed + * by given client. + * + * Note : All files are uploaded on the current working directory of the FTP client. + * + * @param target Dashboard item to upload results for. + * @param ftp Connection to the FTP. + * @return true if we succeeded + * @throws IOException + */ + public boolean publish(final DashboardResultItem target, final FTPClient ftp) throws IOException { + Optional directory = getDirectory(target); + if (!directory.isPresent()) + return false; + + final Path root = directory.get(); + try { + Files.list(root).forEach(p -> { + final String fileName = p.getFileName().toString(); + if (Files.isRegularFile(p) && Arrays.binarySearch(expectedFiles, fileName) >= 0) { + + try (final InputStream stream = Files.newInputStream(p)) { + ftp.storeFile(fileName, stream); + } catch (IOException e) { + throw new RhomeoRuntimeException(e); + } + } + }); + } catch (RhomeoRuntimeException e) { + if (e.getCause() instanceof IOException) { + throw (IOException) e.getCause(); + } else { + throw e; + } + } + return true; + } + + /** + * Publish results currently contained in the session into the current + * working directory of the input client. + * + * @param ftpSupplier Provides an FTP client positioned in the directory we + * want to send data to. The FTP CLient is closed internally. + * + * @throws IOException + * @throws DataStoreException + * @throws IntrospectionException + */ + public void publish(final Supplier ftpSupplier) throws IOException, DataStoreException, IntrospectionException { + Path tmpDir = Files.createTempDirectory("results"); + try { + resultWriter.prepareWriting(tmpDir).writeMetadataJSON().writeResults().writeAdditionalValues(); + + final FTPClient ftp = ftpSupplier.get(); + try { + Files.list(tmpDir).forEach(p -> { + final String fileName = p.getFileName().toString(); + if (Files.isRegularFile(p)) { + + try (final InputStream stream = Files.newInputStream(p)) { + if (!ftp.storeFile(fileName, stream)) + throw new RhomeoRuntimeException("A file cannot be copied via FTP : ".concat(fileName)); + } catch (IOException e) { + throw new RhomeoRuntimeException(e); + } + } + }); + } finally { + ftp.disconnect(); + } + + } catch (RhomeoRuntimeException e) { + if (e.getCause() instanceof IOException) { + throw (IOException) e.getCause(); + } else { + throw e; + } + } finally { + // If the task fails, it does not halt publication process. + try { + IOUtilities.deleteRecursively(tmpDir); + } catch (Exception e) { + RhomeoCore.LOGGER.log(Level.WARNING, "Cannot clear temporary data", e); + } + } + } + + /** + * Return a path to the CSV file containing main indices related to the + * given dashboard item. + * @param item + * @return A path to the requested results, or an empty optional if there's + * no result available, or they're not accessible. + * @throws java.io.IOException If an error occurs while checking result path. + */ + public Optional getMainResults(final DashboardResultItem item) throws IOException { + Optional directory = getDirectory(item); + if (directory.isPresent()) { + + final Path root = directory.get(); + // Read main results + Path results = root.resolve(ResultWriter.RESULT_FILE_NAME); + if (Files.isReadable(results)) { + return Optional.of(results); + } + } + + return Optional.empty(); + } + + /** + * Return a path to the CSV file containing additional indices related to + * the given dashboard item. + * @param item + * @return A path to the requested results, or an empty optional if there's + * no result available, or they're not accessible. + * @throws java.io.IOException If an error occurs while checking result path. + */ + public Optional getAdditionalResults(final DashboardResultItem item) throws IOException { + Optional directory = getDirectory(item); + if (directory.isPresent()) { + + final Path root = directory.get(); + // Read main results + Path results = root.resolve(ResultWriter.ADDITIONAL_RESULT_FILE_NAME); + if (Files.isReadable(results)) { + return Optional.of(results); + } + } + + return Optional.empty(); + } + + public Optional readMetadata(final DashboardResultItem item) throws IOException { + Optional directory = getDirectory(item); + if (directory.isPresent()) { + + final Path root = directory.get(); + // Read main results + Path results = root.resolve(ExportUtils.METADATA_JSON); + if (Files.isReadable(results)) { + try (final BufferedReader reader = Files.newBufferedReader(results, StandardCharsets.UTF_8)) { + return Optional.of(new ObjectMapper().readValue(reader, SerializableDataContext.class)); + } + } + } + + return Optional.empty(); + } + + private Optional getDirectory(final DashboardResultItem target) throws IOException { + if (target.getSite() == null || target.getSite().isEmpty() + || target.getIndicator() == null || target.getIndicator().isEmpty()) + return Optional.empty(); + + final Site site = siteRepo.findOne(target.getSite()); + if (site == null) + return Optional.empty(); + + final String sha1 = GeometryUtils.getSha1(site.getGeometry()); + final Path root = RhomeoCore.RESULT_PATH.resolve(sha1).resolve(target.getIndicator()).resolve(Integer.toString(target.getYear())); + if (!Files.isDirectory(root) || !Files.list(root).findAny().isPresent()) + return Optional.empty(); + + return Optional.of(root); + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/result/ResultWriter.java b/core/src/main/java/fr/cenra/rhomeo/core/result/ResultWriter.java new file mode 100644 index 0000000..69bc206 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/result/ResultWriter.java @@ -0,0 +1,281 @@ +/** + * 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.core.result; + +import fr.cenra.rhomeo.api.Version; +import fr.cenra.rhomeo.api.data.DataContext; +import fr.cenra.rhomeo.api.data.Dataset; +import fr.cenra.rhomeo.api.data.Reference; +import fr.cenra.rhomeo.api.data.ReferenceDescription; +import fr.cenra.rhomeo.api.data.TrackingPoint; +import fr.cenra.rhomeo.api.data.Warning; +import fr.cenra.rhomeo.api.process.Indicator; +import fr.cenra.rhomeo.api.result.AdditionalValue; +import fr.cenra.rhomeo.api.result.AdditionalValueMapper; +import fr.cenra.rhomeo.api.result.Index; +import fr.cenra.rhomeo.api.result.TrackingPointIndex; +import fr.cenra.rhomeo.core.CSVEncoder; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.util.ExportUtils; +import fr.cenra.rhomeo.core.util.SerializableDataContext; +import java.beans.IntrospectionException; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Predicate; +import javax.validation.ConstraintViolation; +import javax.validation.Validator; +import org.apache.sis.storage.DataStoreException; +import org.apache.sis.util.ArgumentChecks; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * + * @author Alexis Manin (Geomatys) + */ +@Component +public class ResultWriter { + + static final String ADDITIONAL_RESULT_FILE_NAME = "additionalResults.csv"; + static final String RESULT_FILE_NAME = "results.csv"; + + @Autowired + Session session; + + @Autowired(required = false) + Set avMappers; + + public WritingContext prepareWriting(final Path root) throws IOException { + return new WritingContext(root, session, avMappers); + } + + /** + * An object independent from {@link Session} variations, designed to write + * a snapshot of results stored in session at a precise time (creation of + * an instance of this class). + */ + public static class WritingContext { + final Path root; + final DataContext dataContext; + final Map referenceVersions; + final Set indicators; + final Set trackingPoints; + final List indices; + final Validator validator; + final Dataset ds; + + final Set additional; + final Set mappers; + + private WritingContext(final Path root, final Session session, final Set avMappers) throws IOException { + ArgumentChecks.ensureNonNull("Root path", root); + ArgumentChecks.ensureNonNull("Session", session); + if (!Files.isDirectory(root)) { + Files.createDirectories(root); + } + this.root = root; + + final DataContext dc = session.getDataContext(); + ArgumentChecks.ensureNonNull("Data context", dc); + ArgumentChecks.ensureNonNull("Site", dc.getSite()); + ArgumentChecks.ensureNonNull("Protocol", dc.getProtocol()); + dataContext = dc; + + referenceVersions = new HashMap<>(); + if (dc.getReferences() != null) { + for (final Map.Entry, Version> entry : dc.getReferences().entrySet()) { + for (final ReferenceDescription refDescriptor : dc.getProtocol().getReferenceTypes()) { + if (refDescriptor.getReferenceType().equals(entry.getKey())) + referenceVersions.put(refDescriptor, entry.getValue()); + } + } + } + + indicators = new HashSet<>(session.getProcessContext().getIndicators()); + + trackingPoints = new HashSet<>(session.getProcessContext().getTrackingPoints()); + + indices = new ArrayList<>(session.getResults()); + // #40 : Sort results. + indices.sort(new IndexComparator()); + + validator = session.getBean(Validator.class); + + ds = session.getDataset(); + + mappers = avMappers; + if (mappers == null || mappers.isEmpty()) // If no writer is available, there's no need to keep a reference of additional values. + additional = Collections.EMPTY_SET; + else additional = session.getAdditionalValues(); + } + + public WritingContext writeSite() throws IOException, DataStoreException { + ExportUtils.writeGeoJson(dataContext.getSite(), root); + return this; + } + + public WritingContext writeMetadataJSON() throws IOException { + ExportUtils.writeMetadata(SerializableDataContext.fromDataContext(dataContext), root); + return this; + } + + public WritingContext writeMetadataText() throws IOException { + final Set> datasetErrors = validator.validate(ds); + datasetErrors.removeIf(cv -> cv.getConstraintDescriptor().getPayload().contains(Warning.class)); + + ExportUtils.writeMetadataText(root.resolve("metadata.txt"), dataContext.getSite(), dataContext.getProtocol(), referenceVersions, indicators, dataContext.getUserData(), datasetErrors); + + return this; + } + + /** + * Write all results in CSV files (results.csv for main ones, + * additionalResults.csv for others). + * + * @return This context. + * @throws IOException + * @throws IntrospectionException + */ + public WritingContext writeResults() throws IOException, IntrospectionException { + return writeResults(null); + } + + /** + * Write results accepted by given predicate in CSV files (results.csv + * for main ones, additionalResults.csv for others). + * + * @param filter A predicate to filter results. + * @return This context. + * @throws IOException + * @throws IntrospectionException + */ + public WritingContext writeResults(final Predicate filter) throws IOException, IntrospectionException { + final ArrayList mainResults = new ArrayList(); + final ArrayList additionalResults = new ArrayList(); + + boolean primaryHasLocation = false; + boolean additionalHasLocation = false; + for (final Index i : indices) { + if (filter != null && !filter.test(i)) + continue; + + boolean isPrimary = i.getSpi().isPrimary(); + if (isPrimary) { + mainResults.add(new SimpleLocationIndex(i)); + if (i instanceof TrackingPointIndex) + primaryHasLocation = true; + } else { + additionalResults.add(new SimpleLocationIndex(i)); + if (i instanceof TrackingPointIndex) + additionalHasLocation = true; + } + } + + // Write main results + if (!mainResults.isEmpty()) { + final Path mainResultPath = root.resolve(RESULT_FILE_NAME); + Files.deleteIfExists(mainResultPath); + new CSVEncoder( + mainResultPath, + primaryHasLocation ? SimpleLocationIndex.class : SimpleYearIndex.class, + StandardCharsets.UTF_8 + ).encode(mainResults, true); + } + + // Write additional results. + if (!additionalResults.isEmpty()) { + final Path additionalResultPath = root.resolve(ADDITIONAL_RESULT_FILE_NAME); + Files.deleteIfExists(additionalResultPath); + new CSVEncoder( + additionalResultPath, + additionalHasLocation ? SimpleLocationIndex.class : SimpleYearIndex.class, + StandardCharsets.UTF_8 + ).encode(additionalResults, true); + } + + return this; + } + + public void writeAdditionalValues() throws IOException { + if (mappers == null || mappers.isEmpty()) + return; + for (final AdditionalValueMapper mapper : mappers) + if (mapper.writeValues(root, additional)) + return; + } + } + + /** + * Sort index by type, year, eventually tracking point, and finally by value. + */ + private static class IndexComparator implements Comparator { + + @Override + public int compare(Index o1, Index o2) { + + int comparison = o1.getSpi().compareTo(o2.getSpi()); + if (comparison == 0) { + comparison = o1.getYear() - o2.getYear(); + if (comparison == 0) { + if (o1 instanceof TrackingPointIndex) { + if (o2 instanceof TrackingPointIndex) { + comparison = ((TrackingPointIndex) o1).getPoint().getName().compareTo(((TrackingPointIndex) o2).getPoint().getName()); + } else { + comparison = 1; + } + } else if (o2 instanceof TrackingPointIndex) { + comparison = -1; + } + } + } + + return comparison == 0 ? Double.compare(o1.getValue().doubleValue(), o2.getValue().doubleValue()) : comparison; + } + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/result/SimpleLocationIndex.java b/core/src/main/java/fr/cenra/rhomeo/core/result/SimpleLocationIndex.java new file mode 100644 index 0000000..e18001f --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/result/SimpleLocationIndex.java @@ -0,0 +1,71 @@ +/** + * 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.core.result; + +import fr.cenra.rhomeo.api.result.Index; +import fr.cenra.rhomeo.api.result.TrackingPointIndex; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class SimpleLocationIndex extends SimpleYearIndex { + + private String location; + + public SimpleLocationIndex(){} + + public SimpleLocationIndex(Index source) { + super(source); + if (source instanceof TrackingPointIndex) + location = ((TrackingPointIndex)source).getPoint().getName(); + else location = null; + } + + public String getLocation() { + return location; + } + + public void setLocation(final String location){this.location=location;} + + @Override + public String toString() { + return "SimpleLocationIndex{" + "name=" + name + ", year=" + year + ", location=" + location + ", value=" + value +'}'; + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/result/SimpleYearIndex.java b/core/src/main/java/fr/cenra/rhomeo/core/result/SimpleYearIndex.java new file mode 100644 index 0000000..364db85 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/result/SimpleYearIndex.java @@ -0,0 +1,81 @@ +/** + * 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.core.result; + +import fr.cenra.rhomeo.api.result.Index; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class SimpleYearIndex { + + protected String name; + protected int year; + protected Number value; + + public SimpleYearIndex(){} + + protected SimpleYearIndex(final Index source) { + name = source.getSpi().getTitle(); + year = source.getYear(); + value = source.getValue(); + } + + public String getName() { + return name; + } + + public int getYear() { + return year; + } + + public Number getValue() { + return value; + } + + public void setName(final String name){this.name=name;} + public void setYear(final int year){this.year=year;} + public void setValue(final Number value){this.value=value;} + + @Override + public String toString() { + return "SimpleYearIndex{" + "name=" + name + ", year=" + year + ", value=" + value + '}'; + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/state/DatasetManager.java b/core/src/main/java/fr/cenra/rhomeo/core/state/DatasetManager.java new file mode 100644 index 0000000..2f3f0e7 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/state/DatasetManager.java @@ -0,0 +1,282 @@ +/** + * 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.core.state; + +import com.fasterxml.jackson.databind.ObjectMapper; +import fr.cenra.rhomeo.api.data.DataContext; +import fr.cenra.rhomeo.api.data.Dataset; +import fr.cenra.rhomeo.api.data.Statement; +import fr.cenra.rhomeo.core.CSVDecoder; +import fr.cenra.rhomeo.core.CSVEncoder; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.WorkflowStep; +import fr.cenra.rhomeo.core.util.SerializableDataContext; +import java.beans.IntrospectionException; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.List; +import java.util.logging.Level; +import javafx.beans.InvalidationListener; +import javafx.beans.Observable; +import javax.annotation.PreDestroy; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * Listens given dataset and data context over time, to save them on change. + * + * @author Alexis Manin (Geomatys) + */ +@Component +class DatasetManager implements StepStateManager { + + private static final String CONTEXT_FILE = "context.json"; + private static final String DATASET_FILE = "dataset.csv"; + + @Autowired + private Session session; + + @Autowired + private StateManager manager; + + private Path target; + private DataContext context; + private Dataset dataset; + + private final ObjectMapper jsonMapper; + + private final InvalidationListener datasetListener; + private final InvalidationListener contextListener; + + private StateManager.Trigger contextTrigger; + private StateManager.Trigger datasetTrigger; + + + /** + * + */ + public DatasetManager() { + jsonMapper = new ObjectMapper(); + contextListener = this::contextChanged; + datasetListener = this::datasetChanged; + } + + @Override + public WorkflowStep getStep() { + return WorkflowStep.DATASET; + } + + @Override + public synchronized void setBackupFolder(Path toWriteInto) { + target = toWriteInto; + } + + @Override + public synchronized void startSaving() { + if (session.getDataContext() == context && session.getDataset() == dataset) + return; // Already listening on changes. + + if (context != null || dataset != null) + stopSaving(); + + context = session.getDataContext(); + context.getReferences().addListener(contextListener); + contextTrigger = manager.prepareTask(this::writeContext, "Data context state"); + // If data context does not exists, we create it now + if (target != null && !Files.exists(target.resolve(CONTEXT_FILE))) { + contextChanged(null); + } + + dataset = session.getDataset(); + dataset.getItems().addListener(datasetListener); + datasetTrigger = manager.prepareTask(this::writeDataset, "Dataset state"); + // If dataset does not exists, we create it now + if (target != null && !Files.exists(target.resolve(DATASET_FILE))) { + datasetChanged(null); + } + } + + @PreDestroy + @Override + public synchronized void stopSaving() { + if (dataset != null) { + datasetTrigger.close(); + dataset.getItems().removeListener(datasetListener); + datasetTrigger = null; + dataset = null; + } + + if (context != null) { + contextTrigger.close(); + context.getReferences().removeListener(contextListener); + contextTrigger = null; + context = null; + } + } + + @Override + public boolean restoreStep() { + if (dataset != null || context != null) { + throw new IllegalStateException("Cannot restore dataset while backup is running !"); + } + + if (target == null) { + return false; + } + + /* + * We start restoration with data context, as no dataset can be + * initialized without it. The dataset is read once we're sure we've + * loaded a valid context. + */ + try { + final SerializableDataContext ctx = readContext(); + if (ctx == null || !ctx.restoreDataContext(session)) + return false; + + final List data = readDataset(); + if (data != null) { + session.getDataset().getItems().addAll(data); + } + + return true; + + } catch (Exception e) { + StateManager.LOGGER.log(Level.WARNING, "Cannot restore dataset from folder ".concat(target.toString()), e); + return false; + } + } + + /** + * + * @return A data context loaded from backup folder. Null if no context is + * available. + * @throws IOException If a backup file is present, but something goes wrong + * at reading. + */ + private SerializableDataContext readContext() throws IOException { + final Path ctxFile = target.resolve(CONTEXT_FILE); + if (Files.isReadable(ctxFile)) { + try (final BufferedReader reader = Files.newBufferedReader(ctxFile, StandardCharsets.UTF_8)) { + return jsonMapper.readValue(reader, SerializableDataContext.class); + } + } + + return null; + } + + /** + * + * @return A dataset loaded from backup folder. Null if none is available. + * @throws IntrospectionException If a backup file is present, but something + * goes wrong at reading. + * @throws IOException If a backup file is present, but something goes wrong + * at reading. + * @throws ReflectiveOperationException If an error happens with the read + * datatype. + */ + private List readDataset() throws IntrospectionException, IOException, ReflectiveOperationException { + final Path datafile = target.resolve(DATASET_FILE); + if (Files.isReadable(datafile)) { + return new CSVDecoder(datafile, session.getDataContext().getProtocol().getDataType(), StandardCharsets.UTF_8).decode(); + } + + return null; + } + + /** + * + * @return + * @throws IOException + * @throws IntrospectionException + */ + private boolean writeDataset() throws IOException, IntrospectionException { + final Path tmpFile = Files.createTempFile("tmpDataset", ".csv"); + new CSVEncoder(tmpFile, context.getProtocol().getDataType(), StandardCharsets.UTF_8).encode(dataset.getItems(), true); + + Files.move(tmpFile, target.resolve(DATASET_FILE), StandardCopyOption.REPLACE_EXISTING); + return true; + } + + /** + * Save current data context. First, we write it in a temporary file. We replace + * the backup only once we're sure the context has been successfully written. + * @throws IOException + */ + private boolean writeContext() throws IOException { + final Path tmpFile = Files.createTempFile("tmpContext", ".json"); + // Prepare a serializable object. + final SerializableDataContext ctx = SerializableDataContext.fromDataContext(context); + try (final BufferedWriter writer = Files.newBufferedWriter(tmpFile, StandardCharsets.UTF_8)) { + jsonMapper.writeValue(writer, ctx); + } + + Files.move(tmpFile, target.resolve(CONTEXT_FILE), StandardCopyOption.REPLACE_EXISTING); + return true; + } + + /** + * Notify writer that we want it to store the current context state. We both + * set trigger value and notify it, so if the writer is waiting, it will + * be notified, and if it is already running, it will immediately be aware + * that a new saving is required. + * + * @param obs + */ + private void contextChanged(final Observable obs) { + contextTrigger.arm(); + } + + /** + * Notify writer that we want it to store the current dataset state. We both + * set trigger value and notify it, so if the writer is waiting, it will + * be notified, and if it is already running, it will immediately be aware + * that a new saving is required. + * + * @param obs + */ + private void datasetChanged(final Observable obs) { + datasetTrigger.arm(); + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/state/ProcessManager.java b/core/src/main/java/fr/cenra/rhomeo/core/state/ProcessManager.java new file mode 100644 index 0000000..4d5b4a2 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/state/ProcessManager.java @@ -0,0 +1,305 @@ +/** + * 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.core.state; + +import fr.cenra.rhomeo.api.process.Indicator; +import fr.cenra.rhomeo.api.process.ProcessContext; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.WorkflowStep; +import java.beans.IntrospectionException; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Optional; +import java.util.function.Predicate; +import java.util.logging.Level; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.collections.MapChangeListener; +import javafx.collections.SetChangeListener; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * + * @author Alexis Manin (Geomatys) + */ +@Component +public class ProcessManager implements StepStateManager { + + private static final String INDICATOR_FILE = "indicators.txt"; + private static final String FILTER_FILE = "filter"; + private static final String USER_DATA_FILE = "userData"; + + @Autowired + private Session session; + + @Autowired + private StateManager manager; + + private Path target; + + private ProcessContext ctx; + + private StateManager.Trigger indicatorTrigger; + private StateManager.Trigger filterTrigger; + private StateManager.Trigger userDataTrigger; + + private final SetChangeListener indicatorListener = this::indicatorsChanged; + private final ChangeListener filterListener = this::filterChanged; + private final MapChangeListener userDataListener = this::userDataChanged; + + @Override + public void setBackupFolder(Path toWriteInto) { + target = toWriteInto; + } + + @Override + public WorkflowStep getStep() { + return WorkflowStep.PROCESS; + } + + @Override + public void startSaving() { + if (ctx != null) + stopSaving(); + + ctx = session.getProcessContext(); + + // Submit backup tasks. + filterTrigger = manager.prepareTask(this::writeFilter, "Process context filter"); + indicatorTrigger = manager.prepareTask(this::writeIndicators, "Process context indicators"); + userDataTrigger = manager.prepareTask(this::writeUserData, "Process context indicators"); + + // Force writing process context in current state. + filterTrigger.arm(); + indicatorTrigger.arm(); + userDataTrigger.arm(); + + // listens on process context change. + ctx.filterProperty().addListener(filterListener); + ctx.getIndicators().addListener(indicatorListener); + ctx.getDataCtx().getUserData().addListener(userDataListener); + } + + @Override + public void stopSaving() { + if (ctx != null) { + ctx.filterProperty().removeListener(filterListener); + filterTrigger.close(); + filterTrigger = null; + + ctx.getIndicators().removeListener(indicatorListener); + indicatorTrigger.close(); + indicatorTrigger = null; + + ctx.getDataCtx().getUserData().removeListener(userDataListener); + userDataTrigger.close(); + userDataTrigger = null; + + ctx = null; + } + } + + @Override + public boolean restoreStep() { + final ProcessContext ctx = readProcessContext(); + if (ctx != null) { + session.setProcessContext(ctx); + return true; + } + + return false; + } + + ProcessContext readProcessContext() { + // Cannot restore process context if no data has been prepared before hand. + if (target == null || session.getDataContext() == null || session.getDataset() == null) + return null; + + final Predicate filter; + final Collection indics; + final Map userData; + try { + filter = readFilter(); + indics = readIndicators(); + userData = readUserData(); + } catch (Exception e) { + StateManager.LOGGER.log(Level.WARNING, "Cannot restore process context.", e); + return null; + } + + final boolean noIndic = indics == null || indics.isEmpty(); + final boolean noUserData = userData == null || userData.isEmpty(); + if (filter == null && noIndic && noUserData) { + return null; + } + + final ProcessContext context = new ProcessContext(session.getDataset(), session.getDataContext()); + if (filter != null) { + context.setFilter(filter); + } + if (!noIndic) { + context.getIndicators().addAll(indics); + } + if (!noUserData) { + context.getDataCtx().getUserData().putAll(userData); + } + return context; + } + + /** + * @return Tracking points saved in backup file. + */ + private Predicate readFilter() throws IOException, ClassNotFoundException { + final Path file; + if (target == null || !Files.isReadable((file = target.resolve(FILTER_FILE)))) + return null; + + try (final InputStream source = Files.newInputStream(file); + final ObjectInputStream input = new ObjectInputStream(source)) { + final Object read = input.readObject(); + if (read instanceof Predicate) + return (Predicate) read; + } + + return null; + } + + private Collection readIndicators() throws IOException { + final Path file; + if (target == null || !Files.isReadable((file = target.resolve(INDICATOR_FILE)))) + return null; + + final HashSet indicators = new HashSet<>(); + try (final BufferedReader r = Files.newBufferedReader(file, StandardCharsets.UTF_8)) { + r.lines().forEach(line -> { + final Optional optIndicator = session.getIndicators().stream() + .filter(indicator -> line.equals(indicator.getName())) + .findFirst(); + optIndicator.ifPresent(indicators::add); + }); + } + + return indicators; + } + + private Map readUserData() throws IOException, ClassNotFoundException { + final Path file; + if (target == null || !Files.isReadable((file = target.resolve(USER_DATA_FILE)))) + return null; + + try (final InputStream source = Files.newInputStream(file); + final ObjectInputStream input = new ObjectInputStream(source)) { + final Object read = input.readObject(); + if (read instanceof Map) + return (Map) read; + } + + return null; + } + + private boolean writeFilter() throws IOException, IntrospectionException { + if (ctx.getFilter() == null) + return false; + + final Path tmpFile = Files.createTempFile(target, FILTER_FILE, ".tmp"); + try (final OutputStream destination = Files.newOutputStream(tmpFile); + final ObjectOutputStream output = new ObjectOutputStream(destination)) { + output.writeObject(ctx.getFilter()); + } + Files.move(tmpFile, target.resolve(FILTER_FILE), StandardCopyOption.REPLACE_EXISTING); + return true; + } + + private boolean writeIndicators() throws IOException { + if (ctx.getIndicators().isEmpty()) + return false; + + final Path tmpFile = Files.createTempFile(target, INDICATOR_FILE, ".tmp"); + try (final BufferedWriter w = Files.newBufferedWriter(tmpFile, StandardCharsets.UTF_8)) { + for (final Indicator i : ctx.getIndicators()) { + w.write(i.getName()); + w.newLine(); + } + } + Files.move(tmpFile, target.resolve(INDICATOR_FILE), StandardCopyOption.REPLACE_EXISTING); + return true; + } + + private boolean writeUserData() throws IOException { + // Defensive copy. Moreover, Serialization does not work with observable map. + final Map userData = new HashMap(ctx.getDataCtx().getUserData()); + if (userData.isEmpty()) + return false; + + final Path tmpFile = Files.createTempFile(target, USER_DATA_FILE, ".tmp"); + try (final OutputStream destination = Files.newOutputStream(tmpFile); + final ObjectOutputStream output = new ObjectOutputStream(destination)) { + output.writeObject(userData); + } + + Files.move(tmpFile, target.resolve(USER_DATA_FILE), StandardCopyOption.REPLACE_EXISTING); + return true; + } + + private void filterChanged(final ObservableValue obs, Predicate oldValue, Predicate newValue) { + filterTrigger.arm(); + } + + private void indicatorsChanged(final SetChangeListener.Change c) { + indicatorTrigger.arm(); + } + + private void userDataChanged(final MapChangeListener.Change c) { + userDataTrigger.arm(); + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/state/ResultManager.java b/core/src/main/java/fr/cenra/rhomeo/core/state/ResultManager.java new file mode 100644 index 0000000..d59cda1 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/state/ResultManager.java @@ -0,0 +1,270 @@ +/** + * 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.core.state; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.module.SimpleModule; +import fr.cenra.rhomeo.api.data.TrackingPoint; +import fr.cenra.rhomeo.api.result.AdditionalValueMapper; +import fr.cenra.rhomeo.api.result.Index; +import fr.cenra.rhomeo.api.result.IndexSpi; +import fr.cenra.rhomeo.api.result.TrackingPointIndex; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.WorkflowStep; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.Future; +import java.util.logging.Level; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * + * Special case : The results are immutable, so we just save data once, when the + * manager is activated. + * + * @author Alexis Manin (Geomatys) + */ +@Component +public class ResultManager implements StepStateManager { + + private static final String RESULT_FILE = "results.json"; + private static final String ADDITIONAL_VALUE_DIR = "additional"; + + @Autowired + private Session session; + + @Autowired + private StateManager manager; + + @Autowired(required=false) + private Set avMappers; + + private Path target; + + private Future writeState; + + private ObjectMapper mapper; + + /** + * Initialises Jackson serialisation feature in order to allow index reading + * and writing. + * + * @param spis SPIs registered for index building. + */ + @Autowired + void init(final List spis) { + final HashMap spiMap = new HashMap<>(spis.size()); + for (final IndexSpi spi : spis) { + spiMap.put(spi.getName(), spi); + } + + final SimpleModule mod = new SimpleModule("Index SPI"); + mod.addSerializer(new JsonSerializer() { + @Override + public Class handledType() { + return Index.class; + } + + @Override + public void serialize(Index value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + if (value.getSpi() == null) + return; + + jgen.writeStartObject(); + if (value instanceof TrackingPointIndex) { + jgen.writeStringField("location", ((TrackingPointIndex)value).getPoint().getName()); + } + jgen.writeNumberField("year", value.getYear()); + jgen.writeStringField("spi", value.getSpi().getName()); + jgen.writeObjectField("value", value.getValue()); + jgen.writeEndObject(); + } + }); + + mod.addDeserializer(Index.class, new JsonDeserializer() { + @Override + public Index deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { + jp.nextToken(); + + final String location; + if ("location".equals(jp.getCurrentName())) { + location = jp.nextTextValue(); + jp.nextToken(); + } else { + location = null; + } + + final int year = jp.nextIntValue(0); + jp.nextToken(); + + final String strSpi = jp.nextTextValue(); + jp.nextToken(); + + jp.nextToken(); + final Number value = jp.getNumberValue(); + jp.nextToken(); + + IndexSpi spi = spiMap.get(strSpi); + if (spi != null) { + Object entity = null; + if (location != null) { + for (final TrackingPoint tp : (List) session.getDataset().getTrackingPoints()) { + if (tp.getYear() == year && location.equals(tp.getName())) { + entity = tp; + break; + } + } + } else { + entity = year; + } + return spi.createIndex(value, entity); + } + + return null; + } + }); + + mapper = new ObjectMapper(); + mapper.registerModule(mod); + } + + @Override + public void setBackupFolder(Path toWriteInto) { + target = toWriteInto; + } + + @Override + public WorkflowStep getStep() { + return WorkflowStep.RESULT; + } + + @Override + public void startSaving() { + if (writeState != null && !writeState.isDone()) { + writeState.cancel(true); + } + + writeState = manager.threadPool.submit(this::writeResults); + } + + @Override + public void stopSaving() { + // Nothing to do. + } + + @Override + public boolean restoreStep() { + final Path file; + if (target == null || !Files.isReadable(file = target.resolve(RESULT_FILE))) { + return false; + } + + try (final BufferedReader r = Files.newBufferedReader(file)) { + Index[] read = mapper.readValue(r, Index[].class); + session.setResults(new HashSet<>(Arrays.asList(read))); + } catch (Exception e) { + StateManager.LOGGER.log(Level.WARNING, "Cannot restore results."); + return false; + } + + if (avMappers != null && !avMappers.isEmpty()) { + final Path avDir = target.resolve(ADDITIONAL_VALUE_DIR); + try { + if (Files.exists(avDir)) { + Set read; + for (final AdditionalValueMapper mapper : avMappers) { + read = mapper.readValues(avDir); + if (!read.isEmpty()) { + session.getAdditionalValues().addAll(read); + break; + } + } + } + } catch (Exception e) { + StateManager.LOGGER.log(Level.WARNING, "Cannot restore additional results."); + } + } + + return true; + } + + boolean writeResults() throws IOException { + final Set results = session.getResults(); + if (results == null || results.isEmpty()) { + return false; + } + + final Path tmpFile = Files.createTempFile(target, "results", ".tmp"); + try (final BufferedWriter w = Files.newBufferedWriter(tmpFile, StandardCharsets.UTF_8)) { + mapper.writeValue(w, results); + } + + Files.move(tmpFile, target.resolve(RESULT_FILE), StandardCopyOption.REPLACE_EXISTING); + + if (avMappers != null && ! avMappers.isEmpty() && !session.getAdditionalValues().isEmpty()) { + final Path tmpDir = Files.createTempDirectory(target, ADDITIONAL_VALUE_DIR); + for (final AdditionalValueMapper avMapper : avMappers) { + if (avMapper.writeValues(tmpDir, session.getAdditionalValues())) { + Files.move(tmpDir, target.resolve(ADDITIONAL_VALUE_DIR), StandardCopyOption.REPLACE_EXISTING); + break; + } + } + } + + return true; + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/state/StateLoader.java b/core/src/main/java/fr/cenra/rhomeo/core/state/StateLoader.java new file mode 100644 index 0000000..e03180b --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/state/StateLoader.java @@ -0,0 +1,47 @@ +/** + * 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.core.state; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class StateLoader { + +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/state/StateManager.java b/core/src/main/java/fr/cenra/rhomeo/core/state/StateManager.java new file mode 100644 index 0000000..b2f59dd --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/state/StateManager.java @@ -0,0 +1,360 @@ +/** + * 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.core.state; + +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.RhomeoRuntimeException; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.WorkflowStep; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; +import javafx.beans.property.ReadOnlyObjectProperty; +import javafx.beans.property.ReadOnlyObjectWrapper; +import javafx.beans.value.ObservableValue; +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import org.apache.sis.util.logging.Logging; +import org.geotoolkit.nio.IOUtilities; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * + * @author Alexis Manin (Geomatys) + */ +@Component +public class StateManager { + + static final Logger LOGGER = Logging.getLogger("fr.cenra.rhomeo.core.state"); + + @Autowired + private Session session; + + final ExecutorService threadPool; + + private final ReadOnlyObjectWrapper folder; + + private final Map stepManagers; + + StateManager() throws IOException { + Files.createDirectories(RhomeoCore.RESTORATION_FOLDER); + threadPool = Executors.newCachedThreadPool(); + + // Register state savers. + this.stepManagers = new HashMap<>(WorkflowStep.values().length); + + folder = new ReadOnlyObjectWrapper<>(this, "state folder"); + folder.addListener(this::pathChanged); + } + + @PostConstruct + private void init() { + session.workflowStepProperty().addListener(this::stepChanged); + } + + @Autowired + private void initManagers(final Collection stepManagers) { + for (final StepStateManager ssm : stepManagers) { + this.stepManagers.put(ssm.getStep(), ssm); + } + } + + @PreDestroy + private void shutdown() { + threadPool.shutdown(); + try { + threadPool.awaitTermination(10, TimeUnit.SECONDS); + } catch (InterruptedException ex) { + threadPool.shutdownNow(); + } + } + + /** + * Try to restore applicative state from file-system backup. + * + * /!\ You MUST NOT call this method once user has started seizure. Once in + * edition mode, the manager performs backups as daemon, so it cannot restore + * previous data. + * + * @return True if a backup have been found and loaded. False otherwise. + * @throws IllegalStateException If a backup is running. + * @throws IOException If an error happens while analysing backup files. + */ + public synchronized boolean restoreState() throws IOException { + if (session.getWorkflowStep() != null) { + throw new IllegalStateException("Cannot restore dataset while backup is running !"); + } + + final List dirs; + if (folder.get() == null) { + dirs = Files.list(RhomeoCore.RESTORATION_FOLDER) + .filter(input -> { + if (!Files.isDirectory(input)) { + return false; + } + + try { + return Long.parseLong(input.getFileName().toString()) > 0; + } catch (NumberFormatException e) { + return false; + } + }).collect(Collectors.toList()); + + dirs.sort((o1, o2) -> Long.compare(Long.parseLong(o1.getFileName().toString()), Long.parseLong(o2.getFileName().toString()))); + } else { + dirs = Collections.singletonList(folder.get()); + } + + int stepCount = 0; + final Iterator it = dirs.iterator(); + while (it.hasNext() && stepCount < 1) { + folder.set(it.next()); + while (restoreStep(WorkflowStep.values()[stepCount])) { + session.requestWorkflowStep(WorkflowStep.values()[stepCount++]); + } + } + + /* + * We remove last scanned folder from the previously built list, because + * we'll use it as backup folder. For the remaining ones, we'll delete + * them. They've got no reason to remain if they don't serve our backup + * purpose. + */ + if (!dirs.isEmpty()) { + it.remove(); + for (final Path p : dirs) { + submitDeletion(p); + } + } + + return stepCount > 0; + } + + private synchronized void resetContext() { + try { + final Path newPath = RhomeoCore.RESTORATION_FOLDER.resolve(Long.toString(System.currentTimeMillis())); + Files.createDirectories(newPath); + folder.set(newPath); + } catch (IOException ex) { + LOGGER.log(Level.SEVERE, "Impossible to set a new restoration context.", ex); + folder.set(null); + } + } + + public ReadOnlyObjectProperty folderProperty() { + return folder.getReadOnlyProperty(); + } + + public Path getFolder() { + return folder.get(); + } + + /* + * STATE OPERATIONS + */ + + private boolean restoreStep(WorkflowStep target) { + final StepStateManager ssm = stepManagers.get(target); + if (ssm != null) { + return ssm.restoreStep(); + } + + return false; + } + + private void startSaving(final WorkflowStep target) { + final StepStateManager ssm = stepManagers.get(target); + if (ssm != null) { + ssm.startSaving(); + } + } + + private void stopSaving(final WorkflowStep target) { + final StepStateManager ssm = stepManagers.get(target); + if (ssm != null) { + ssm.stopSaving(); + } + } + + /* + * PROPERTY LISTENERS + */ + + private void stepChanged(final ObservableValue obs, WorkflowStep oldStep, WorkflowStep newStep) { + if (oldStep != null) { + stopSaving(oldStep); + } + + if (newStep != null) { + if (folder.get() == null) { + resetContext(); // No folder parameterized yet. Create a new one. + } + startSaving(newStep); + } else { + resetContext(); // Seizure properly stopped. We clear backups. + } + } + + /** + * When changing backup folder, we notify each step manager with a new sub-directory. + * Once done, we delete the old backup. + * @param obs + * @param oldPath + * @param newPath + */ + private void pathChanged(final ObservableValue obs, final Path oldPath, final Path newPath) { + try { + if (newPath != null) { + for (final Map.Entry entry : stepManagers.entrySet()) { + final Path subDir = newPath.resolve(entry.getKey().name()); + try { + Files.createDirectories(subDir); + } catch (IOException ex) { + throw new RhomeoRuntimeException("Cannot create a backup directory", ex); + } + entry.getValue().setBackupFolder(subDir); + } + } else { + for (final StepStateManager ssm : stepManagers.values()) { + ssm.setBackupFolder(null); + } + } + } finally { + if (oldPath != null) { + submitDeletion(oldPath); + } + } + } + + private void submitDeletion(final Path dir) { + threadPool.submit(() -> { + Thread.currentThread().setName("State deletion"); + try { + IOUtilities.deleteRecursively(dir); + } catch (IOException ex) { + LOGGER.log(Level.WARNING, "Cannot remove directory ".concat(dir.toString()), ex); + } + }); + } + + /** + * Setup a trigger which controls the call to a given task. The aim is to + * provide a simple way to launch a process with the following constraints : + * - One unique instance of the process must be running at any time. + * - Whatever the number of time the process is queried between two calls, + * it will be triggered for execution only once. + * @param task The task to put as triggerable process. + * @return A trigger to allow calling input process anytime needed. + */ + Trigger prepareTask(final Callable task, final String name) { + return new Trigger(task, name); + } + + /** + * A trigger which controls the call to a given task. The aim is to provide + * a simple way to launch a process with the following constraints : + * - One unique instance of the process must be running at any time. + * - Whatever the number of time the process is queried between two calls, + * it will be triggered for execution only once. + */ + class Trigger implements AutoCloseable { + + final AtomicBoolean flag; + final Future taskState; + + private Trigger(final Callable task) { + this(task, null); + } + + private Trigger(final Callable task, final String name) { + flag = new AtomicBoolean(false); + taskState = threadPool.submit(() -> { + final Thread thread = Thread.currentThread(); + if (name != null && !name.isEmpty()) + thread.setName(name); + while (!thread.isInterrupted()) { + if (flag.getAndSet(false)) { + try { + task.call(); + } catch (Exception e) { + LOGGER.log(Level.WARNING, "A state management task has failed.", e); + } + } else + synchronized (flag) { + flag.wait(); + } + } + return true; + }); + } + + /** + * Ask for a call of the associated process. + */ + public void arm() { + flag.set(true); + synchronized (flag) { + flag.notify(); + } + } + + /** + * Definitely cancel associated process. + */ + public void close() { + taskState.cancel(true); + } + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/state/StepStateManager.java b/core/src/main/java/fr/cenra/rhomeo/core/state/StepStateManager.java new file mode 100644 index 0000000..5b79039 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/state/StepStateManager.java @@ -0,0 +1,82 @@ +/** + * 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.core.state; + +import fr.cenra.rhomeo.core.WorkflowStep; +import java.nio.file.Path; + +/** + * Describes an operator designed to save a particular {@link WorkflowStep} data. + * the aim is to provide for each step a way to activate or de-activate saving. + * + * @author Alexis Manin (Geomatys) + */ +interface StepStateManager { + + /** + * Specify the folder in which this manager will have to write saved data. + * + * @param toWriteInto Path to use for saving. + */ + void setBackupFolder(final Path toWriteInto); + + /** + * + * @return The step this object is designed for. + */ + WorkflowStep getStep(); + + /** + * Ask to this component to save step related changes over time, until we + * ask for it to stop using {@link #stopSaving() }. + */ + void startSaving(); + + /** + * Ask to this component to stop saving changes related to the given step. + */ + void stopSaving(); + + /** + * Ask to this object to load step related data from backup. + * @return True if information has been successfully loaded. Return false if + * no backup is available, or it failed to load. + */ + boolean restoreStep(); +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/util/AOC.java b/core/src/main/java/fr/cenra/rhomeo/core/util/AOC.java new file mode 100644 index 0000000..b6d7c0e --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/util/AOC.java @@ -0,0 +1,73 @@ +/** + * 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.core.util; + +import java.util.Collections; +import java.util.Set; +import org.apache.sis.math.FunctionProperty; +import org.apache.sis.util.ObjectConverter; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public abstract class AOC implements ObjectConverter { + private final Class inputType; + private final Class outputType; + + public AOC(Class inputType, Class outputType) { + this.inputType = inputType; + this.outputType = outputType; + } + + @Override + public Set properties() { + return Collections.EMPTY_SET; + } + + @Override + public Class getSourceClass() { + return inputType; + } + + @Override + public Class getTargetClass() { + return outputType; + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/util/EncryptionResult.java b/core/src/main/java/fr/cenra/rhomeo/core/util/EncryptionResult.java new file mode 100644 index 0000000..d5d90ff --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/util/EncryptionResult.java @@ -0,0 +1,70 @@ +/** + * 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.core.util; + +import java.util.Arrays; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class EncryptionResult { + + public final String output; + private final byte[] key; + private final byte[] sr; + + public EncryptionResult(String output, byte[] key, byte[] sr) { + this.output = output; + this.key = key; + this.sr = sr; + } + + public String getOutput() { + return output; + } + + public byte[] getKey() { + return Arrays.copyOf(key, key.length); // defensive copy + } + + public byte[] getSecureRandom() { + return Arrays.copyOf(sr, sr.length); // defensive copy + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/util/ExportUtils.java b/core/src/main/java/fr/cenra/rhomeo/core/util/ExportUtils.java new file mode 100644 index 0000000..8ee9041 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/util/ExportUtils.java @@ -0,0 +1,686 @@ +/** + * 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.core.util; + +import com.fasterxml.jackson.core.JsonEncoding; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.GeometryCollection; +import com.vividsolutions.jts.geom.LineString; +import com.vividsolutions.jts.geom.MultiPolygon; +import com.vividsolutions.jts.geom.Point; +import com.vividsolutions.jts.geom.impl.CoordinateArraySequence; +import fr.cenra.rhomeo.api.IdentifiedObject; +import fr.cenra.rhomeo.api.InternationalResource; +import fr.cenra.rhomeo.api.data.Dataset; +import fr.cenra.rhomeo.api.data.Protocol; +import fr.cenra.rhomeo.api.data.Site; +import fr.cenra.rhomeo.api.process.Indicator; +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.list.HumidZoneType; +import fr.cenra.rhomeo.core.list.OdonateZoneBio; +import fr.cenra.rhomeo.core.list.OrthoptereZoneBio; +import fr.cenra.rhomeo.core.data.site.SiteImpl; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.nio.charset.StandardCharsets; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.zip.ZipOutputStream; +import javax.xml.stream.XMLStreamException; + +import org.apache.sis.storage.DataStoreException; +import org.apache.sis.util.ArgumentChecks; +import org.geotoolkit.atom.AtomFactory; +import org.geotoolkit.atom.DefaultAtomFactory; +import org.geotoolkit.atom.xml.AtomConstants; +import org.geotoolkit.data.FeatureStoreUtilities; +import org.geotoolkit.data.geojson.GeoJSONFeatureStore; +import org.geotoolkit.data.kml.DefaultKmlFactory; +import org.geotoolkit.data.kml.KmlFactory; +import org.geotoolkit.data.kml.model.AbstractGeometry; +import org.geotoolkit.data.kml.model.Boundary; +import org.geotoolkit.data.kml.model.Kml; +import org.geotoolkit.data.kml.model.KmlException; +import org.geotoolkit.data.kml.model.LinearRing; +import org.geotoolkit.data.kml.xml.KmlConstants; +import org.geotoolkit.data.kml.xml.KmlWriter; +import org.geotoolkit.data.kml.xsd.SimpleTypeContainer; +import org.geotoolkit.data.shapefile.ShapefileFeatureStore; +import org.geotoolkit.feature.Feature; +import org.geotoolkit.feature.type.FeatureType; +import org.geotoolkit.geometry.jts.JTS; +import org.geotoolkit.referencing.CRS; +import org.geotoolkit.xal.xml.XalConstants; +import org.opengis.referencing.operation.MathTransform; +import org.opengis.referencing.operation.TransformException; +import org.opengis.util.FactoryException; +import java.util.Set; +import javax.validation.ConstraintViolation; +import org.geotoolkit.feature.FeatureTypeBuilder; +import org.geotoolkit.feature.FeatureUtilities; +import org.geotoolkit.nio.ZipUtilities; +import static fr.cenra.rhomeo.core.data.site.SiteRepositoryImpl.toFeature; +import java.io.OutputStream; +import java.net.URI; +import java.util.Iterator; +import java.util.Optional; +import java.util.StringJoiner; +import java.util.stream.Collectors; +import org.apache.sis.referencing.CommonCRS; +import org.geotoolkit.data.FeatureStore; +import org.geotoolkit.data.geojson.GeoJSONStreamWriter; +import org.geotoolkit.data.query.QueryBuilder; +import org.geotoolkit.feature.FeatureBuilder; +import org.geotoolkit.feature.GeometryAttribute; +import org.geotoolkit.nio.IOUtilities; +import org.opengis.feature.Property; +import org.opengis.util.GenericName; + +/** + * Export utilities. + * + * @author Samuel Andrés (Geomatys) + * @author Cédric Briançon (Geomatys) + */ +public class ExportUtils { + + public static final String SITE_JSON = RhomeoCore.SITES.concat(".geojson"); + + public static final String METADATA_JSON = "metadata.json"; + + public static final String RHOMEO_PREFIX = "rhomeo"; + + public static final KmlFactory KML_FACTORY = DefaultKmlFactory.getInstance(); + + public static final AtomFactory ATOM_FACTORY = DefaultAtomFactory.getInstance(); + + public static MathTransform TRANSFORM; + static { + try { + // Set transform from site CRS to .kml CRS. + TRANSFORM = CRS.findMathTransform(RhomeoCore.getSiteCRS(), CommonCRS.WGS84.normalizedGeographic(), true); + } catch (FactoryException ex) { + RhomeoCore.LOGGER.log(Level.WARNING, "Unable to build MathTransform to Kml export.", ex); + } + } + + public static enum ExportType { + SHP("ESRI Shapefile", "shp"), + KML("Google KML", "kml"), + GJSON("GeoJSON", "json"); + + public final String title; + public final String extension; + private ExportType(final String title, final String extension) { + this.title = title; + this.extension = extension; + } + + @Override + public String toString() { + return title; + } + } + + /** + * Builds a list of KML {@link AbstractGeometry} (WGS 84) from a {@link Site} + * {@link MultiPolygon} (Lambert 93). + * + * @param multiPolygon The site Lambert 93 geometry. + * @return A list of KML WGS 84 geometries mapping the site geometry. + */ + static List toKmlGeometries(Geometry geom) throws TransformException { + final List result; + if (geom instanceof GeometryCollection) { + final GeometryCollection col = (GeometryCollection) geom; + result = new ArrayList<>(); + for (int i = 0 ; i < col.getNumGeometries() ; i++) { + result.addAll(toKmlGeometries(col.getGeometryN(i))); + } + } else { + AbstractGeometry converted = null; + if (geom != null) + geom = JTS.transform(geom, TRANSFORM); + if (geom instanceof com.vividsolutions.jts.geom.Polygon) { + final com.vividsolutions.jts.geom.Polygon currentPolygon = (com.vividsolutions.jts.geom.Polygon) geom; + // Exterior ring + final LinearRing extRing = KML_FACTORY.createLinearRing(new CoordinateArraySequence(currentPolygon.getExteriorRing().getCoordinates())); + final Boundary extBoundary = KML_FACTORY.createBoundary(extRing, null, null); + + // Interior rings + final List intBoundaries = new ArrayList<>(); + for (int j = 0; j < currentPolygon.getNumInteriorRing(); j++) { + final LinearRing intRing = KML_FACTORY.createLinearRing(new CoordinateArraySequence(currentPolygon.getInteriorRingN(j).getCoordinates())); + intBoundaries.add(KML_FACTORY.createBoundary(intRing, null, null)); + } + converted = KML_FACTORY.createPolygon(extBoundary, intBoundaries); + } else if (geom instanceof com.vividsolutions.jts.geom.LinearRing) { + converted = KML_FACTORY.createLinearRing(((com.vividsolutions.jts.geom.LinearRing) geom).getCoordinateSequence()); + } else if (geom instanceof LineString) { + converted = KML_FACTORY.createLineString(((com.vividsolutions.jts.geom.LineString) geom).getCoordinateSequence()); + } else if (geom instanceof Point) { + converted = KML_FACTORY.createPoint(((Point) geom).getCoordinateSequence()); + } + + result = converted == null? Collections.EMPTY_LIST : Collections.singletonList(converted); + } + + return result; + } + + /** + * Builds a description from some {@link Site} fields. + * + * @param countyCode + * @param zoneType + * @param odonateType + * @param orthoptereType + * @return + */ + static String description(final String countyCode, final String zoneType, final String odonateType, final String orthoptereType, final String remarks){ + final StringBuilder sb = new StringBuilder(); + + if (countyCode != null && !countyCode.isEmpty()) { + sb.append(InternationalResource.getFormatedResourceString(SiteImpl.class, "countyCode.kml", countyCode)); + } + + if (zoneType != null) { + final HumidZoneType zone = HumidZoneType.getByCode(zoneType); + if (zone != null) { + if (sb.length() > 0) + sb.append(System.lineSeparator()); + + sb.append(InternationalResource.getFormatedResourceString(SiteImpl.class, "zoneType.kml", zone.getValue(), zone.getCode())); + } + } + if (odonateType != null) { + final OdonateZoneBio zone = OdonateZoneBio.getByCode(odonateType); + if (zone != null) { + if (sb.length() > 0) + sb.append(System.lineSeparator()); + + sb.append(InternationalResource.getFormatedResourceString(SiteImpl.class, "odonateType.kml", zone.getValue(), zone.getCode())); + } + } + if (orthoptereType != null) { + final OrthoptereZoneBio zone = OrthoptereZoneBio.getByCode(orthoptereType); + if (zone != null) { + if (sb.length() > 0) + sb.append(System.lineSeparator()); + + sb.append(InternationalResource.getFormatedResourceString(SiteImpl.class, "orthoptereType.kml", zone.getValue(), zone.getCode())); + } + } + if (remarks != null && !remarks.isEmpty()) { + if (sb.length() > 0) + sb.append(System.lineSeparator()); + sb.append(InternationalResource.getFormatedResourceString(SiteImpl.class, "remarks.kml", remarks)); + } + return sb.toString(); + } + + /** + * Writes the given {@link Site} to the given output as .kml v2.2 format. + * + * @param site + * @param output + * @throws XMLStreamException + * @throws IOException + * @throws KmlException + * @throws TransformException + * @throws DataStoreException + */ + public static void writeKml(final Site site, final Object output) throws XMLStreamException, IOException, KmlException, TransformException, DataStoreException{ + ExportUtils.writeKml(toFeature(site), output); + } + + /** + * Writes the given {@link Site} {@link Feature} to the given output as .kml v2.2 format. + * + * @param site + * @param output + * @throws XMLStreamException + * @throws IOException + * @throws KmlException + * @throws org.opengis.referencing.operation.TransformException + */ + public static void writeKml(final Feature site, final Object output) throws XMLStreamException, IOException, KmlException, TransformException { + + // Retrieve site data incompatible with KML base semantics. + final Property county = site.getProperty(RhomeoCore.FT_PROPERTIES.COUNTY.name()); + final Property type = site.getProperty(RhomeoCore.FT_PROPERTIES.TYPE.name()); + final Property odonate = site.getProperty(RhomeoCore.FT_PROPERTIES.ODONATE.name()); + final Property orthoptere = site.getProperty(RhomeoCore.FT_PROPERTIES.ORTHOPTERE.name()); + final Property remarks = site.getProperty(RhomeoCore.FT_PROPERTIES.REMARKS.name()); + + // Build containers for rhomeo specific semantics. + final List rhomeoExtensions = new ArrayList<>(); + if (county != null) + rhomeoExtensions.add(KML_FACTORY.createSimpleTypeContainer(RhomeoKmlWriter.NAMESPACE, RhomeoKmlWriter.TAG_COUNTY, county.getValue())); + if (type != null) + rhomeoExtensions.add(KML_FACTORY.createSimpleTypeContainer(RhomeoKmlWriter.NAMESPACE, RhomeoKmlWriter.TAG_TYPE, type.getValue())); + if (odonate != null) + rhomeoExtensions.add(KML_FACTORY.createSimpleTypeContainer(RhomeoKmlWriter.NAMESPACE, RhomeoKmlWriter.TAG_ODONATE, odonate.getValue())); + if (orthoptere != null) + rhomeoExtensions.add(KML_FACTORY.createSimpleTypeContainer(RhomeoKmlWriter.NAMESPACE, RhomeoKmlWriter.TAG_ORTHOPTERE, orthoptere.getValue())); + + final Property org = site.getProperty(RhomeoCore.FT_PROPERTIES.ORG.name()); + + final GeometryAttribute geomProp = site.getDefaultGeometryProperty(); + final List geoms = geomProp == null || geomProp.getValue() == null? null : toKmlGeometries((Geometry)geomProp.getValue()); + + final Property nameProp = site.getProperty(RhomeoCore.FT_PROPERTIES.NAME.name()); + final String name; + if (nameProp == null || nameProp.getValue() == null) + name = null; + else + name = nameProp.getValue().toString(); + + final String description; + if (county != null || type != null || odonate != null || orthoptere != null || remarks != null) + description = description( + county == null? null : String.valueOf(county.getValue()), + type == null? null : String.valueOf(type.getValue()), + odonate == null? null : String.valueOf(odonate.getValue()), + orthoptere == null? null : String.valueOf(orthoptere.getValue()), + remarks == null? null : String.valueOf(remarks.getValue())); + else description = null; + + final Property referent = site.getProperty(RhomeoCore.FT_PROPERTIES.REFERENT.name()); + + // Build placemark mapping site data. + final Feature placemark = KML_FACTORY.createPlacemark(null, + null, + name, + true, + true, + name==null ? null : ATOM_FACTORY.createAtomPersonConstruct(Collections.singletonList(name)), + null, + name, + null, + null, + null, + description == null? null : description, + null, + null, + null, + new ArrayList<>(), + null, + null, + null, + null, + KML_FACTORY.createMultiGeometry(null, null, null, null, geoms, null, null), + rhomeoExtensions, + null); + + final Kml kml = KML_FACTORY.createKml(); + + // Set KML version + kml.setVersion(KmlConstants.URI_KML_2_2); + + // Set prefixes for URIs. + final Map extensions = new HashMap<>(); + extensions.put(AtomConstants.URI_ATOM, KmlConstants.PREFIX_ATOM); + extensions.put(XalConstants.URI_XAL, KmlConstants.PREFIX_XAL); + extensions.put(RhomeoKmlWriter.NAMESPACE, RHOMEO_PREFIX); + kml.setExtensionsUris(extensions); + + // Set site placemark + kml.setAbstractFeature(placemark); + + final KmlWriter writer = new KmlWriter(); + try{ + writer.setOutput(output); + writer.addExtensionWriter(RhomeoKmlWriter.NAMESPACE, new RhomeoKmlWriter()); + writer.write(kml); + } + finally{ + writer.dispose(); + } + } + + /** + * Writes the given {@Site} as a shapefile to the given output file. + * + * @param site + * @param outputFile + * @throws DataStoreException + * @throws MalformedURLException + */ + public static void writeShp(final Site site, final File outputFile) throws DataStoreException, MalformedURLException, IOException { + ArgumentChecks.ensureNonNull("Output zip file", outputFile); + final Feature toAdd = toFeature(site); + write(toAdd, outputFile.toPath(), ExportType.SHP); + } + + /** + * Writes the selected site into a geojson file. + * + * @param site Selected site to serialize. + * @param outputFolder Geojson in which to write the site. + * @return The json path created. + * @throws IOException + * @throws DataStoreException + */ + public static Path writeGeoJson(final Site site, final Path outputFolder) throws IOException, DataStoreException { + final Path outputJson = outputFolder.resolve(SITE_JSON); + Files.deleteIfExists(outputJson); + final Path outputTypeJson = outputFolder.resolve(RhomeoCore.SITES +"_Type.json"); + Files.deleteIfExists(outputTypeJson); + final Feature toAdd = toFeature(site); + + + write(toAdd, outputJson, ExportType.GJSON); + return outputJson; + } + + public static void write(final Feature feature, final Path outputFile, final ExportType format) throws IOException, DataStoreException { + switch (format) { + case KML: + try { + writeKml(feature, outputFile); + break; + } catch (Exception e) { + throw new IOException(e); + } + case GJSON: + // HACK : Force long/lat coordinates, because our writer uses + // comas in big numbers (Ex: 10000 --> 10,000), which breaks format. + FeatureStoreUtilities.collection(feature).subCollection(QueryBuilder.reprojected(feature.getType().getName(), CommonCRS.defaultGeographic())); + try (final OutputStream out = Files.newOutputStream(outputFile); + final GeoJSONStreamWriter writer = new GeoJSONStreamWriter(out, feature.getType(), JsonEncoding.UTF8, 4)) { + FeatureUtilities.copy( + FeatureStoreUtilities.collection(feature) + .subCollection(QueryBuilder.reprojected(feature.getType().getName(), CommonCRS.defaultGeographic())) + .iterator().next(), + writer.next(), false); + writer.write(); + } + break; + + default: + final GenericName name = feature.getType().getName(); + final FeatureStore store = create(outputFile.toUri(), String.valueOf(name.scope()), format); + try { + store.createFeatureType(name, feature.getType()); + store.addFeatures(name, FeatureStoreUtilities.collection(feature)); + } finally { + // TODO : replace with try/w/r once FeatureStore implements auto-closeable. + if (store != null) + store.close(); + } + } + } + + public static FeatureStore create(final URI dataPath, final String namespace, final ExportType format) throws DataStoreException, MalformedURLException { + ArgumentChecks.ensureNonNull("Output path", dataPath); + switch (format) { + case SHP: return new ShapefileFeatureStore(dataPath, namespace); + case KML: throw new IllegalArgumentException("No feature store available for KML data"); + default: + return new GeoJSONFeatureStore(dataPath, namespace, null); + } + } + + /** + * Writes the given {@Site} as a zipped shapefile to the given output which + * is assumed end with ".zip" extension. + * + * @param site + * @param outputFile + * @throws java.io.IOException + * @throws org.apache.sis.storage.DataStoreException + * @throws IllegalArgumentException if outputPath does not end with ".zip" extension. + */ + public static void writeZip(final Site site, final File outputFile) throws IOException, DataStoreException{ + + ArgumentChecks.ensureNonNull("Output zip file", outputFile); + + if(!outputFile.getName().endsWith(".zip")) throw new IllegalArgumentException("Output file name must end with .zip extension."); + + final Path tmpDirectory = Files.createTempDirectory("site"); + tmpDirectory.toFile().deleteOnExit(); + final File shpFile = new File(tmpDirectory.toFile(), outputFile.getName().replaceFirst(".zip$", ".shp")); + + writeShp(site, shpFile); + + final Collection resources = new ArrayList<>(); + + Files.walkFileTree(tmpDirectory, new SimpleFileVisitor() { + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + final File toAdd = file.toFile(); + toAdd.deleteOnExit(); + resources.add(file); + return FileVisitResult.CONTINUE; + } + }); + + ZipUtilities.zip(outputFile.toPath(), ZipOutputStream.DEFLATED, 9, null, resources.toArray(new Path[0])); + } + + /** + * Write metadata in a JSON file using information stored in the {@linkplain SerializableDataContext context}. + * + * @param context Data to serialize. + * @param outputFolder Folder which will contain the json file. + * @return Path of the generated metadata json. + * @throws IOException + */ + public static Path writeMetadata(final SerializableDataContext context, final Path outputFolder) throws IOException { + final Path metadataJsonFile = outputFolder.resolve(METADATA_JSON); + Files.deleteIfExists(metadataJsonFile); + try (final BufferedWriter writer = Files.newBufferedWriter(metadataJsonFile, StandardCharsets.UTF_8)) { + final ObjectMapper jsonMapper = new ObjectMapper(); + jsonMapper.writeValue(writer, context); + } + return metadataJsonFile; + } + + /** + * Export Site and its buffer in a given zip archive. + * + * @param outputFile The ZIP file in which we must insert data. Must not be null + * @param site The site to export. Must not be null. + * @param buffer The computed buffer for input site. Must not be null + * @param territory Geometry representing hydrographic zones which intersects the buffer. Optional. + * @param type File format to use for data. Must not be null + * + */ + public static void exportSiteAndBuffer(File outputFile, Site site, Geometry buffer, Optional territory, ExportType type) throws Exception { + if (outputFile == null || type == null) + return; + + final Path outputZipFile = outputFile.toPath(); + final Path tmpDir = Files.createTempDirectory("export"); + try { + // issue #40 : write concatenation of site + buffer + Feature siteFeat = toFeature(site); + final FeatureTypeBuilder ftb = new FeatureTypeBuilder(); + ftb.copy(siteFeat.getType()); + ftb.setName("site_buffer"); + ftb.add("type_contour", String.class); + final FeatureType siteBufType = ftb.buildFeatureType(); + siteFeat.getDefaultGeometryProperty().setValue(buffer.difference(site.getGeometry())); + FeatureBuilder fb = new FeatureBuilder(siteBufType); + for (final Property p : siteFeat.getProperties()) { + fb.setPropertyValue(p.getName(), p.getValue()); + } + fb.setPropertyValue("type_contour", "site+buffer"); + // write site + write(fb.buildFeature(site.getName()), tmpDir.resolve("site_buffer.".concat(type.extension)), type); + + // issue #40 : write intersecting hydrologic zones + + if (territory.isPresent()) { + final Geometry territoryGeom = territory.get(); + ftb.reset(); + ftb.setName("territoire"); + ftb.add("the_geom", territoryGeom.getClass(), JTS.findCoordinateReferenceSystem(territoryGeom)); + ftb.add("type_contour", String.class); + final FeatureType featureType = ftb.buildFeatureType(); + final Feature feat = FeatureUtilities.defaultFeature(featureType, "territoire"); + feat.getDefaultGeometryProperty().setValue(territoryGeom); + feat.setPropertyValue("type_contour", "territoire"); + write(feat, tmpDir.resolve("territoire.".concat(type.extension)), type); + } + // Zip all data + ZipUtilities.zip(outputZipFile, ZipOutputStream.DEFLATED, 9, null, Files.list(tmpDir).collect(Collectors.toList()).toArray(new Path[0])); + } finally { + IOUtilities.deleteRecursively(tmpDir); + } + } + + /** + * Write result metadata file from input parameters. The output format is + * simple text. + * @param output File to write into. + * @param site Site to write. + * @param protocol Protocol to write. + * @param referenceVersions Reference versions used for computing. (Key = reference or reference name, value = version) + * @param userData + * @param indicators computed indicators + * @param errors Errors which occurred while processing results. + * @throws IOException + */ + public static void writeMetadataText( + final Path output, + final Site site, + final Protocol protocol, + final Map referenceVersions, + final Collection indicators, + final Map userData, + final Set> errors) throws IOException { + try (final BufferedWriter writer = Files.newBufferedWriter(output, StandardCharsets.UTF_8)) { + writer.write("---- Site ----"); + writer.newLine(); + writer.write("Nom : "); + writer.write(site.getName()); + writer.newLine(); + writer.write("Referent : "); + writer.write(site.getReferent() == null? "Non renseigné" : site.getReferent()); + writer.newLine(); + writer.write("Organisation : "); + writer.write(site.getOrganization() == null? "Non renseigné" : site.getOrganization()); + writer.newLine(); + writer.write("Département : "); + writer.write(site.getCountyCode()); + writer.newLine(); + writer.newLine(); + + writer.write("---- Protocole ----"); + writer.newLine(); + writer.write(protocol.getTitle()); + writer.newLine(); + writer.newLine(); + + if (!referenceVersions.isEmpty()) { + writer.write("---- Versions des référentiels ----"); + for (final Map.Entry ref : referenceVersions.entrySet()) { + writer.newLine(); + writer.write(toString(ref.getKey())); + writer.write(" : "); + writer.write(toString(ref.getValue())); + } + writer.newLine(); + writer.newLine(); + } + + writer.write("---- Indicateurs calculés ----"); + for (final Indicator i : indicators) { + writer.newLine(); + writer.write(i.getTitle()); + } + + if (userData != null && !userData.isEmpty()) { + for (final Map.Entry data : userData.entrySet()) { + writer.newLine(); + writer.newLine(); + writer.write("---- " + data.getKey() + " ----"); + writer.newLine(); + writer.write(toString(data.getValue())); + } + } + + if (!errors.isEmpty()) { + writer.newLine(); + writer.newLine(); + writer.write("---- Erreurs sur le lot de données ----"); + for (final ConstraintViolation v : errors) { + writer.newLine(); + writer.write(v.getMessage()); + } + } + } + } + + private static String toString(final Object o) { + if (o == null) + return "N/A"; + else if (o instanceof Collection) { + final StringJoiner joiner = new StringJoiner(", ", "[", "]"); + final Iterator it = ((Collection)o).iterator(); + while (it.hasNext()) + joiner.add(toString(it.next())); + return joiner.toString(); + } else if (o instanceof IdentifiedObject) { + return ((IdentifiedObject)o).getTitle(); + } else { + final String value = o.toString().trim(); + if (value.isEmpty()) + return "N/A"; + return value; + } + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/util/GeometryConverters.java b/core/src/main/java/fr/cenra/rhomeo/core/util/GeometryConverters.java new file mode 100644 index 0000000..8acd8e8 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/util/GeometryConverters.java @@ -0,0 +1,99 @@ +/** + * 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.core.util; + +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.io.ParseException; +import com.vividsolutions.jts.io.WKTReader; +import org.apache.sis.util.ObjectConverter; +import org.apache.sis.util.UnconvertibleObjectException; + +/** + * Simple object converter between {@link Geometry} and {@link String} types. + * @author Alexis Manin (Geomatys) + */ +public class GeometryConverters { + + public static class GeometryToString extends AOC { + + public GeometryToString() { + super(Geometry.class, String.class); + } + + @Override + public String apply(Geometry object) throws UnconvertibleObjectException { + if (object == null) + return null; + return object.toText(); + } + + @Override + public ObjectConverter inverse() throws UnsupportedOperationException { + return new StringToGeometry(); + } + } + + + + public static class StringToGeometry extends AOC { + + final WKTReader reader; + public StringToGeometry() { + super(String.class, Geometry.class); + reader = new WKTReader(); + } + + @Override + public Geometry apply(String object) throws UnconvertibleObjectException { + if (object == null || (object = object.trim()).isEmpty()) + return null; + + try { + return reader.read(object); + } catch (ParseException ex) { + throw new UnconvertibleObjectException(ex); + } + } + + @Override + public ObjectConverter inverse() throws UnsupportedOperationException { + return new GeometryToString(); + } + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/util/GeometryUtils.java b/core/src/main/java/fr/cenra/rhomeo/core/util/GeometryUtils.java new file mode 100644 index 0000000..a62a544 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/util/GeometryUtils.java @@ -0,0 +1,87 @@ +/** + * 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.core.util; + +import com.vividsolutions.jts.geom.Geometry; +import org.apache.commons.codec.digest.DigestUtils; + +/** + * @author Cédric Briançon (Geomatys) + * @author Johann Sorel (Geomatys) + */ +public class GeometryUtils { + /** + * Get a SHA1 representation of a geometry. + * + * @param geometry Geometry to convert. Must not be {@code null} + * @return SHA1 of the geometry, never {@code null} + */ + public static String getSha1(Geometry geometry) { + return DigestUtils.sha1Hex(geometry.toText()); + } + + /** + * Compute geometry buffer.
+ *
+ * Java version of SQL : + *
+     * {@code
+     * CREATE OR replace FUNCTION outils.calcul_geom_buffer()
+     * returns TRIGGER AS $body$DECLARE surf_buff DOUBLE PRECISION;radius DOUBLE PRECISION;BEGIN
+     *      surf_buff := st_area(new.geom);
+     *      radius := ( |/ (surf_buff*2/pi()) ) - ( |/ (surf_buff/pi()) );
+     *      new.geom_buffer := st_multi(st_difference(st_buffer(new.geom,radius,40),new.geom));
+     *      return new;
+     *  end;$BODY$ language plpgsql volatile cost 100;
+     * }
+     * 
+ * + * @return buffer geometry + */ + public static Geometry computeBuffer(Geometry geom){ + final double surfBuff = geom.getArea(); + final double radius = Math.sqrt(surfBuff*2.0/Math.PI) - Math.sqrt(surfBuff/Math.PI); + Geometry g = geom.buffer(radius, 40); + //.difference(geom); + //note : by comparing result in database dump, the difference operator is not used anymore + g.setSRID(geom.getSRID()); + g.setUserData(geom.getUserData()); + return g; + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/util/RelationResolver.java b/core/src/main/java/fr/cenra/rhomeo/core/util/RelationResolver.java new file mode 100644 index 0000000..a1e5a43 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/util/RelationResolver.java @@ -0,0 +1,256 @@ +/** + * 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.core.util; + +import fr.cenra.rhomeo.api.Version; +import fr.cenra.rhomeo.api.annotations.RefersTo; +import fr.cenra.rhomeo.api.data.DataContext; +import fr.cenra.rhomeo.api.data.Reference; +import fr.cenra.rhomeo.api.data.ReferenceDescription; +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.RhomeoRuntimeException; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.data.ReferenceManager; +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Objects; +import java.util.Set; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.logging.Level; +import javafx.beans.value.ObservableValue; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * Tries to find boundaries declared by the {@link RefersTo} annotation. + * + * @author Alexis Manin (Geomatys) + */ +@Component +public class RelationResolver { + + @Autowired + private Session session; + + /** + * Try to find all available objects of the type matching input annotation + * referred class. + * + * @param reference The annotation describing class to get instances for. + * @return A set of available values, or an empty set if we cannot find any. + * Never null. + * @throws IntrospectionException + */ + public Set getTargetObjects(final RefersTo reference) throws IntrospectionException { + final Class referedType = reference.type(); + Set result = Collections.EMPTY_SET; + if (Reference.class.isAssignableFrom(referedType)) { + ReferenceDescription desc = session.getDescription(referedType); + if (desc != null) + result = getReferences(desc); + + } else if (ReferenceDescription.class.isAssignableFrom(referedType)) { + final ReferenceDescription desc = (ReferenceDescription) session.getBean(referedType); + if (desc != null) + result = getReferences(desc); + + } else if (Enum.class.isAssignableFrom(referedType)) { + result = new LinkedHashSet(Arrays.asList(referedType.getEnumConstants())); + + } else { + // TODO : try to acquire a repository. + } + + if (!result.isEmpty()) { + final Class filter = reference.filterClass(); + try { + if (filter != null && !filter.isInterface() && !Modifier.isAbstract(filter.getModifiers())) { + final Predicate p = filter.newInstance(); + result.removeIf(p.negate()); + } + } catch (Exception e) { + RhomeoCore.LOGGER.log(Level.WARNING, "Cannot filter objects !", e); + } + } + return result; + } + + /** + * Try to find all possible values for the property described by input + * annotation. + * + * @param reference An annotation describing a property of a specific class. + * @return A set of possible values for the described property. Never null, + * but can be empty. + * @throws IntrospectionException + * @throws NoSuchMethodException + */ + public Set getPossibleValues(final RefersTo reference) throws IntrospectionException, NoSuchMethodException { + final Function extractor = acquireExtractor(reference); + + final Set objects = getTargetObjects(reference); + if (objects.isEmpty()) { + return Collections.EMPTY_SET; + } + + final LinkedHashSet result = new LinkedHashSet(objects.size()); + for (final Object o : objects) { + result.add(extractor.apply(o)); + } + + return result; + } + + /** + * Find objects of type specified by given annotation, whose property quoted + * the same annotation is equal to given object. + * + * @param reference The reference annotation giving target type and + * property. + * @param sourceValue Value of the property to compare to available + * referenced objects. + * @return A set of object whose property described in input annotation is + * equal to given object. + * @throws IntrospectionException If we cannot analyze input refered type. + * @throws NoSuchMethodException If we cannot acquire a getter for refered + * property. + */ + public Set getMatchingObjects(final RefersTo reference, final Object sourceValue) throws IntrospectionException, NoSuchMethodException { + Function extractor = acquireExtractor(reference); + + final HashSet result = new HashSet(); + final Set possibleObjects = getTargetObjects(reference); + Object extracted; + for (final Object o : possibleObjects) { + extracted = extractor.apply(o); + if (Objects.equals(sourceValue, extracted)) { + result.add(o); + } + } + + return result; + } + + /** + * Try to find loaded values for the given reference type. + * + * IMPORTANT : This method won't try to load any data. It's the caller job + * to ensure that queried reference has already been loaded using + * {@link ReferenceManager} mechanism. + * + * @param Type of reference object to get values for. + * @param desc Descriptor of the wanted type. + * @return Available values for given reference type. + * @throws IntrospectionException If we cannot analyze reference type. + */ + private Set getReferences(final ReferenceDescription desc) throws IntrospectionException { + final DataContext dataContext = session.getDataContext(); + if (dataContext != null) { + Version refVersion = dataContext.getReferences().get(desc.getReferenceType()); + if (refVersion != null) { + return new LinkedHashSet<>(ReferenceManager.getOrCreate(desc).getValues(refVersion)); + } + } + return Collections.EMPTY_SET; + } + + /** + * Create a function to get value of the property referenced by input + * annotation from an object of the class referenced by input annotation. + * + * @param reference The annotation containing target class and property + * information + * @return A function, never null. + * @throws IntrospectionException If the class referenced by input + * annotation cannot be analyzed. + * @throws NoSuchMethodException If we cannot find any getter in the + * referenced class for the wanted property. + */ + public static Function acquireExtractor(final RefersTo reference) throws IntrospectionException, NoSuchMethodException { + String pName = reference.property(); + if ((pName == null || (pName = pName.trim()).isEmpty())) { + throw new IllegalArgumentException("Given reference annotation does not refer to any property !"); + } + + final Class referedType = reference.type(); + final BeanInfo beanInfo = Introspector.getBeanInfo(referedType); + Function extractor = null; + for (final PropertyDescriptor d : beanInfo.getPropertyDescriptors()) { + if (d.getName().equals(pName)) { + final Method getter = d.getReadMethod(); + if (getter != null) { + getter.setAccessible(true); + extractor = input -> { + try { + return getter.invoke(input); + } catch (ReflectiveOperationException ex) { + throw new RhomeoRuntimeException(ex); + } + }; + } + break; + } + } + + if (extractor == null) { + final Method pGetter = referedType.getMethod(pName.concat("Property")); + if (pGetter != null && ObservableValue.class.isAssignableFrom(pGetter.getReturnType())) { + pGetter.setAccessible(true); + extractor = input -> { + try { + return ((ObservableValue) pGetter.invoke(input)).getValue(); + } catch (ReflectiveOperationException ex) { + throw new RhomeoRuntimeException(ex); + } + }; + } + } + + return extractor; + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/util/RhomeoKmlWriter.java b/core/src/main/java/fr/cenra/rhomeo/core/util/RhomeoKmlWriter.java new file mode 100644 index 0000000..d56e6b6 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/util/RhomeoKmlWriter.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.core.util; + +import fr.cenra.rhomeo.core.RhomeoCore; +import java.io.IOException; +import java.util.List; +import javax.xml.stream.XMLStreamException; +import org.geotoolkit.data.kml.model.Extensions; +import org.geotoolkit.data.kml.model.Extensions.Names; +import org.geotoolkit.data.kml.model.KmlException; +import org.geotoolkit.data.kml.xml.KmlExtensionWriter; +import org.geotoolkit.data.kml.xsd.SimpleTypeContainer; +import org.geotoolkit.xml.StaxStreamWriter; + +/** + * Customized {@link KmlExtensionWriter} for Rhomeo site attribute data. + * + * @author Samuel Andrés (Geomatys) + */ +public class RhomeoKmlWriter extends StaxStreamWriter implements KmlExtensionWriter{ + + public static final String NAMESPACE = "http://rhomeo.cenra.fr/kml"; + + public static final String TAG_COUNTY = RhomeoCore.FT_PROPERTIES.COUNTY.name(); + public static final String TAG_TYPE = RhomeoCore.FT_PROPERTIES.TYPE.name(); + public static final String TAG_ODONATE = RhomeoCore.FT_PROPERTIES.ODONATE.name(); + public static final String TAG_ORTHOPTERE = RhomeoCore.FT_PROPERTIES.ORTHOPTERE.name(); + + public RhomeoKmlWriter(){ + super(); + } + + /** + * + * @param output + * @throws XMLStreamException + * @throws IOException + */ + @Override + public void setOutput(Object output) throws XMLStreamException, IOException{ + super.setOutput(output); + } + + private void writeStringElement(final String tag, final String content) throws XMLStreamException{ + writer.writeStartElement(NAMESPACE, tag); + writer.writeCharacters(content); + writer.writeEndElement(); + } + + @Override + public boolean canHandleComplex(final String kmlVersionUri, final Names ext, final Object contentObject) { + if(contentObject instanceof List){ + return true; + } + return false; + } + + @Override + public boolean canHandleSimple(final String kmlVersionUri, final Names ext, final String elementTag) { + if(TAG_COUNTY.equals(elementTag) + || TAG_TYPE.equals(elementTag) + || TAG_ODONATE.equals(elementTag) + || TAG_ORTHOPTERE.equals(elementTag)){ + return true; + } + return false; + } + + @Override + public void writeComplexExtensionElement(String kmlVersionUri, Extensions.Names ext, Object contentElement) + throws XMLStreamException, KmlException { + throw new UnsupportedOperationException("Does not support complex types."); + } + + @Override + public void writeSimpleExtensionElement(final String kmlVersionUri, final Extensions.Names ext, final SimpleTypeContainer contentElement) + throws XMLStreamException, KmlException { + if(TAG_COUNTY.equals(contentElement.getTagName()) + || TAG_TYPE.equals(contentElement.getTagName()) + || TAG_ODONATE.equals(contentElement.getTagName()) + || TAG_ORTHOPTERE.equals(contentElement.getTagName())){ + final Object value = contentElement.getValue(); + if(value!=null) this.writeStringElement(contentElement.getTagName(), value.toString()); + } + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/util/SecretGenerator.java b/core/src/main/java/fr/cenra/rhomeo/core/util/SecretGenerator.java new file mode 100644 index 0000000..5a5d815 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/util/SecretGenerator.java @@ -0,0 +1,121 @@ +/** + * 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.core.util; + +import fr.cenra.rhomeo.core.RhomeoCore; +import java.nio.charset.StandardCharsets; +import java.security.GeneralSecurityException; +import java.security.SecureRandom; +import java.util.Base64; +import java.util.Optional; +import java.util.logging.Level; +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class SecretGenerator { + + private static SecretGenerator INSTANCE; + + private final Cipher cipher; + private final Base64.Encoder encoder; + private final Base64.Decoder decoder; + private final KeyGenerator keyGen; + private final SecureRandom sr; + + private SecretGenerator() throws GeneralSecurityException { + cipher = Cipher.getInstance("Blowfish/CBC/PKCS5Padding"); + keyGen = KeyGenerator.getInstance("Blowfish"); + encoder = Base64.getEncoder().withoutPadding(); + decoder = Base64.getDecoder(); + sr = new SecureRandom(); + } + + public synchronized EncryptionResult encrypt(final String toEncrypt) throws GeneralSecurityException { + keyGen.init(128); + final byte[] keyBytes = keyGen.generateKey().getEncoded(); + if (keyBytes == null) { + throw new GeneralSecurityException("No key can be generated for queried encryption."); + } + + final byte[] srBytes = new byte[cipher.getBlockSize()]; + sr.nextBytes(srBytes); + + cipher.init( + Cipher.ENCRYPT_MODE, + new SecretKeySpec(keyBytes, "Blowfish"), + new IvParameterSpec(srBytes) + ); + + return new EncryptionResult( + encoder.encodeToString(cipher.doFinal(toEncrypt.getBytes(StandardCharsets.UTF_8))), + keyBytes, + srBytes + ); + } + + public synchronized String decrypt(final String toDecrypt, final byte[] key, final byte[] rs) throws GeneralSecurityException { + cipher.init( + Cipher.DECRYPT_MODE, + new SecretKeySpec(key, "Blowfish"), + new IvParameterSpec(rs) + ); + return new String( + cipher.doFinal(decoder.decode(toDecrypt)), + StandardCharsets.UTF_8 + ); + } + + public static final Optional getInstance() { + if (INSTANCE == null) { + try { + INSTANCE = new SecretGenerator(); + } catch (GeneralSecurityException e) { + RhomeoCore.LOGGER.log(Level.WARNING, "Cannot initialize encryption management mechanism.", e); + } + } + + return Optional.ofNullable(INSTANCE); + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/util/SerializableDataContext.java b/core/src/main/java/fr/cenra/rhomeo/core/util/SerializableDataContext.java new file mode 100644 index 0000000..2153f7f --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/util/SerializableDataContext.java @@ -0,0 +1,194 @@ +/** + * 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.core.util; + +import fr.cenra.rhomeo.api.Version; +import fr.cenra.rhomeo.api.data.DataContext; +import fr.cenra.rhomeo.api.data.Protocol; +import fr.cenra.rhomeo.api.data.Reference; +import fr.cenra.rhomeo.api.data.Site; +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.data.site.SiteRepository; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.logging.Level; +import javafx.collections.ObservableMap; + +/** + * A simple POJO writable using Jackson. The aim is to persist information of a + * {@link DataContext}. + * + * @author Alexis Manin (Geomatys) + */ +public class SerializableDataContext { + + /** + * Name of the target site. + */ + public String siteName; + + /** + * Person in charge of the pointed site. + */ + public String referent; + + /** + * Organisation in charge of the site management. + */ + public String organisation; + + /** + * Name of the target protocol. + */ + public String protocolName; + + /** + * ISO Zoned date and time of the creation of the context. + */ + public String date; + + /** + * Contains versions used for reference list inside application. The key is + * the canonical name of the pointed {@link Reference} class, and value is + * the string representation of the {@link Version}. + */ + public Map referenceVersions = new HashMap<>(); + + public Map userData = new HashMap<>(); + + /** + * Try to set the session data context from the current object. + * @param session + * @return True if we succeeded to set session data context according to + * current object. False if there's missing information which prevent us + * from doing so. + */ + public boolean restoreDataContext(final Session session) { + final Site site = session.getBean(SiteRepository.class).findOne(siteName); + if (site == null) + return false; + + final Optional protocolOptional = session.getProtocols().stream() + .filter(protocolCandidate -> protocolName.equals(protocolCandidate.getName())) + .findFirst(); + if (!protocolOptional.isPresent()) { + return false; + } + + final Protocol protocol = protocolOptional.get(); + session.startEdition(site, protocol); + if (referenceVersions != null && !referenceVersions.isEmpty()) { + ObservableMap, Version> refs = session.getDataContext().getReferences(); + for (final Map.Entry entry : referenceVersions.entrySet()) { + // Using protocol class loader should be good, as it is sensed to reference the reference class it use. + try { + refs.put((Class) Class.forName(entry.getKey(), true, protocol.getClass().getClassLoader()), new Version(entry.getValue())); + } catch (ClassNotFoundException e) { + RhomeoCore.LOGGER.log(Level.WARNING, "Cannot restore a reference version preference.", e); + } + } + } + + session.getDataContext().getUserData().putAll(userData); + + return true; + } + + /** + * Converts into a {@linkplain DataContext data context}. + * + * @param session + * @return A data context representing this instance, or {@code null} if no site or protocol defined in the session. + */ + public DataContext toDataContext(final Session session) { + if (session == null) { + return null; + } + final Site site = session.getBean(SiteRepository.class).findOne(siteName); + if (site == null) + return null; + + final Optional protocolOptional = session.getProtocols().stream() + .filter(protocolCandidate -> protocolName.equals(protocolCandidate.getName())) + .findFirst(); + if (!protocolOptional.isPresent()) { + return null; + } + + final Protocol protocol = protocolOptional.get(); + final DataContext dataContext = new DataContext(site, protocol); + if (referenceVersions == null || referenceVersions.isEmpty()) { + return dataContext; + } + + ObservableMap, Version> refs = dataContext.getReferences(); + for (final Map.Entry entry : referenceVersions.entrySet()) { + // Using protocol class loader should be good, as it is sensed to reference the reference class it use. + try { + refs.put((Class) Class.forName(entry.getKey(), true, protocol.getClass().getClassLoader()), new Version(entry.getValue())); + } catch (ClassNotFoundException e) { + RhomeoCore.LOGGER.log(Level.WARNING, "Cannot restore a reference version preference.", e); + } + } + + dataContext.getUserData().putAll(userData); + + return dataContext; + } + + public static SerializableDataContext fromDataContext(final DataContext context) { + final SerializableDataContext ctx = new SerializableDataContext(); + ctx.protocolName = context.getProtocol().getName(); + ctx.siteName = context.getSite().getName(); + ctx.referent = context.getSite().getReferent(); + ctx.organisation = context.getSite().getOrganization(); + ctx.date = context.getDate().toString(); + for (final Map.Entry, Version> entry : context.getReferences().entrySet()) { + ctx.referenceVersions.put(entry.getKey().getCanonicalName(), entry.getValue().toString()); + } + + ctx.userData.putAll(context.getUserData()); + + return ctx; + } + +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/util/SimplePredicateChain.java b/core/src/main/java/fr/cenra/rhomeo/core/util/SimplePredicateChain.java new file mode 100644 index 0000000..9961438 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/util/SimplePredicateChain.java @@ -0,0 +1,92 @@ +/** + * 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.core.util; + +import fr.cenra.rhomeo.api.data.Statement; +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.function.Predicate; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class SimplePredicateChain implements Predicate, Externalizable { + + protected static final long serialVersionUID = 1L; + + public final Set predicates = Collections.synchronizedSet(new HashSet<>()); + + @Override + public boolean test(Statement t) { + synchronized (predicates) { + for (final Predicate p : predicates) { + if (p.test(t)) + return true; + } + } + + return false; + } + + @Override + public void writeExternal(ObjectOutput out) throws IOException { + final Predicate[] toWrite; + synchronized (predicates) { + toWrite = predicates.toArray(new Predicate[predicates.size()]); + } + + out.writeObject(toWrite); + } + + @Override + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + final Object read = in.readObject(); + if (read != null && read.getClass().isArray()) + synchronized (predicates) { + predicates.addAll(Arrays.asList((Predicate[]) read)); + } + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/util/TemporalConverters.java b/core/src/main/java/fr/cenra/rhomeo/core/util/TemporalConverters.java new file mode 100644 index 0000000..ec25f20 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/util/TemporalConverters.java @@ -0,0 +1,319 @@ +/** + * 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.core.util; + +import java.time.DateTimeException; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.chrono.ChronoZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.time.format.DateTimeParseException; +import java.time.temporal.ChronoField; +import java.util.ArrayList; +import java.util.regex.Pattern; +import org.apache.sis.util.ObjectConverter; +import org.apache.sis.util.Static; +import org.apache.sis.util.UnconvertibleObjectException; + +/** + * A set of converters to switch from {@link ChronoZonedDateTime} to various types + * (string, number). + * + * @author Alexis Manin (Geomatys) + */ +public class TemporalConverters extends Static { + + /** + * Literal value expected between temporal fields in a string. + */ + private static final char DEFAULT_SEPARATOR = ':'; + + /** + * A regex to detect separator character behind each field of a date. + */ + private static final Pattern SEPARATOR_PATTERN = Pattern.compile("(\\d+)[^\\d](\\+|-)?"); + private static final String SEPARATOR_REPLACEMENT = new StringBuilder("$1") + .append(DEFAULT_SEPARATOR).append("$2").toString(); + + /** + * A zoned date time formatter whose aim is to find a date formed as following : + * + * YYYY MM dd H(H) m(m) s(s) z(zz) (Zone) + * + * Time of the day is optional, and time precision can be from hour to milliseconds. + * The zone can be a zone id or offset, also optional (even if recommended). + */ + private static final DateTimeFormatter YEAR_FIRST_DTF =new DateTimeFormatterBuilder() + .parseLenient() + .appendPattern("yyyy:M:d[:H:m:s][:xxx][:X][:Z][:0][:VV]") + .parseDefaulting(ChronoField.HOUR_OF_DAY, 0) + .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0) + .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0) + .parseDefaulting(ChronoField.OFFSET_SECONDS, 0) + .toFormatter(); + + /** + * A zoned date time formatter whose aim is to find a date formed as following : + * + * dd MM YYYY H(H) m(m) s(s) z(zz) (Zone) + * + * Time of the day is optional, and time precision can be from hour to milliseconds. + * The zone can be a zone id or offset, also optional (even if recommended). + */ + private static final DateTimeFormatter DAY_FIRST_DTF = new DateTimeFormatterBuilder() + .parseLenient() + .appendPattern("d:M:yyyy[:H:m:s][:xxx][:X][:Z][:0][:VV]") + .parseDefaulting(ChronoField.HOUR_OF_DAY, 0) + .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0) + .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0) + .parseDefaulting(ChronoField.OFFSET_SECONDS, 0) + .toFormatter(); + + private static final DateTimeFormatter DAY_FIRST_DF = new DateTimeFormatterBuilder() + .parseLenient() + .appendPattern("d-M-yyyy") + .toFormatter(); + + /** + * Get timestamp (number of milliseconds since the epoch, UTC) from a given + * date. + * + * @param input The zoned date to extract timestamp from. + * @return number of milliseconds between given date and the UTC epoch. + */ + public static long toTimestamp(final ChronoZonedDateTime input) { + return input.toInstant().toEpochMilli(); + } + + /** + * Create a new zoned date/time object from a given timestamp (milli from epoch, UTC). + * @param time The timestamp to read. + * @return The date object corresponding to input object. + */ + public static ZonedDateTime fromTimestamp(final long time) { + return ZonedDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneOffset.UTC); + } + + + /** + * DATE TO TIMESTAMP + */ + public static class ZonedDateTime2Long extends AOC { + + public ZonedDateTime2Long() { + super(ZonedDateTime.class, Long.class); + } + + @Override + public Long apply(ZonedDateTime s) throws UnconvertibleObjectException { + return toTimestamp(s); + } + + @Override + public ObjectConverter inverse() throws UnsupportedOperationException { + return new Long2ZonedDateTime(); + } + } + + /** + * TIMESTAMP TO DATE + */ + public static class Long2ZonedDateTime extends AOC { + + public Long2ZonedDateTime() { + super(Long.class, ZonedDateTime.class); + } + + @Override + public ZonedDateTime apply(Long s) throws UnconvertibleObjectException { + return fromTimestamp(s); + } + + @Override + public ObjectConverter inverse() throws UnsupportedOperationException { + return new ZonedDateTime2Long(); + } + } + + /** + * STRING TO DATE. + */ + public static class String2ZonedDateTime extends AOC { + + public String2ZonedDateTime() { + super(String.class, ZonedDateTime.class); + } + + @Override + public ZonedDateTime apply(String s) throws UnconvertibleObjectException { + // TODO : change case order ? + try { + return fromTimestamp(Long.parseLong(s)); + } catch (NumberFormatException e) { + try { + return ZonedDateTime.parse(s, DateTimeFormatter.ISO_ZONED_DATE_TIME); + } catch (DateTimeParseException e1) { + e1.addSuppressed(e); + try { + return tryFormatters( + SEPARATOR_PATTERN.matcher(s).replaceAll(SEPARATOR_REPLACEMENT), + YEAR_FIRST_DTF, DAY_FIRST_DTF + ); + } catch (DateTimeParseException e2) { + e2.addSuppressed(e1); + UnconvertibleObjectException toThrow = new UnconvertibleObjectException("No known format fit input : ".concat(s), e2); + throw toThrow; + } + } + } + } + + /** + * Try to read the given string as a zoned date and time. We iterate on + * each provided formatters until we find one able to parse data. + * + * @param toConvert A string to convert as a date. + * @param formatters A list of formatters to try for conversion. + * @return The parsed string as a {@link ZonedDateTime}. + * @throws DateTimeParseException If no provided format can parse given string. + */ + private ZonedDateTime tryFormatters(final String toConvert, final DateTimeFormatter... formatters) throws DateTimeParseException { + if (formatters == null || formatters.length < 1) { + return ZonedDateTime.parse(toConvert); + } + + final ArrayList exceptions = new ArrayList<>(); + for (final DateTimeFormatter format : formatters) { + try { + if (format != null) { + return ZonedDateTime.parse(toConvert, format); + } + } catch (DateTimeParseException e) { + exceptions.add(e); + } + } + + if (exceptions.isEmpty()) { + throw new UnconvertibleObjectException("No format provided for conversion !"); + } else { + final DateTimeParseException toThrow = exceptions.get(0); + for (int i = 1 ; i < exceptions.size() ; i++) { + toThrow.addSuppressed(exceptions.get(i)); + } + + throw toThrow; + } + } + + @Override + public ObjectConverter inverse() throws UnsupportedOperationException { + return new ZonedDateTime2String(); + } + } + + public static class String2LocalDate extends AOC { + + public String2LocalDate() { + super(String.class, LocalDate.class); + } + + @Override + public LocalDate apply(String object) throws UnconvertibleObjectException { + try { + return LocalDate.parse(object, DAY_FIRST_DF); + } catch (DateTimeParseException e) { + try { + return LocalDate.parse(object); + } catch (DateTimeParseException e2) { + // Unreadable as an ISO local date. Maybe it's a date time ? + return new String2ZonedDateTime().apply(object).toLocalDate(); + } + } + } + + @Override + public ObjectConverter inverse() throws UnsupportedOperationException { + return new LocalDate2String(); + } + } + + /** + * DATE TO STRING. + */ + public static class ZonedDateTime2String extends AOC { + + public ZonedDateTime2String() { + super(ChronoZonedDateTime.class, String.class); + } + + @Override + public String apply(ZonedDateTime s) throws UnconvertibleObjectException { + return String.valueOf(toTimestamp(s)); + } + + @Override + public ObjectConverter inverse() throws UnsupportedOperationException { + return new String2ZonedDateTime(); + } + } + + public static class LocalDate2String extends AOC { + + public LocalDate2String() { + super(LocalDate.class, String.class); + } + + @Override + public String apply(LocalDate object) throws UnconvertibleObjectException { + try { + return object.format(DAY_FIRST_DF); + } catch (DateTimeException e) { + return object.toString(); + } + } + + @Override + public ObjectConverter inverse() throws UnsupportedOperationException { + return new String2LocalDate(); + } + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/util/TrackingPointComparator.java b/core/src/main/java/fr/cenra/rhomeo/core/util/TrackingPointComparator.java new file mode 100644 index 0000000..3f3d525 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/util/TrackingPointComparator.java @@ -0,0 +1,69 @@ +/** + * 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.core.util; + +import fr.cenra.rhomeo.api.data.Statement; +import fr.cenra.rhomeo.api.data.TrackingPoint; +import java.util.Comparator; + +/** + * Sort {@link Statement} objects per year and then by tracking point name. + * Ascendent order. + * + * @author Alexis Manin (Geomatys) + */ +public class TrackingPointComparator implements Comparator { + + @Override + public int compare(TrackingPoint o1, TrackingPoint o2) { + if (o1 == null) { + return o2 == null? 0 : 1; + } else if (o2 == null) { + return -1; + } + + final int yearOrder = o1.getYear() - o2.getYear(); + if (yearOrder != 0) { + return yearOrder; + } + + return o1.getName().compareTo(o2.getName()); + } + +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/util/VersionDeserializer.java b/core/src/main/java/fr/cenra/rhomeo/core/util/VersionDeserializer.java new file mode 100644 index 0000000..0fa1d74 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/util/VersionDeserializer.java @@ -0,0 +1,67 @@ +/** + * 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.core.util; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import fr.cenra.rhomeo.api.Version; +import java.io.IOException; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class VersionDeserializer extends StdDeserializer { + + public VersionDeserializer() { + super(Version.class); + } + + @Override + public Version deserialize(JsonParser jp, DeserializationContext dc) throws IOException, JsonProcessingException { + final String text = jp.getText(); + if (text == null || text.isEmpty()) { + return null; + } else { + return new Version(text); + } + } +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/util/VersionSerializer.java b/core/src/main/java/fr/cenra/rhomeo/core/util/VersionSerializer.java new file mode 100644 index 0000000..835686a --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/util/VersionSerializer.java @@ -0,0 +1,65 @@ +/** + * 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.core.util; + +import com.fasterxml.jackson.core.JsonGenerationException; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import fr.cenra.rhomeo.api.Version; +import java.io.IOException; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class VersionSerializer extends StdSerializer { + + public VersionSerializer() { + super(Version.class); + } + + @Override + public void serialize(Version t, JsonGenerator jg, SerializerProvider sp) throws IOException, JsonGenerationException { + if (t != null) { + jg.writeString(t.toString()); + } + } + +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/util/ZonedDateTimeDeserializer.java b/core/src/main/java/fr/cenra/rhomeo/core/util/ZonedDateTimeDeserializer.java new file mode 100644 index 0000000..946b9db --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/util/ZonedDateTimeDeserializer.java @@ -0,0 +1,73 @@ +/** + * 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.core.util; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import java.io.IOException; +import java.time.ZonedDateTime; +import org.apache.sis.util.ObjectConverter; +import org.apache.sis.util.ObjectConverters; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class ZonedDateTimeDeserializer extends StdDeserializer { + + final ObjectConverter converter; + + ZonedDateTimeDeserializer() { + super(ZonedDateTime.class); + converter = ObjectConverters.find(String.class, ZonedDateTime.class); + } + + @Override + public ZonedDateTime deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { + final String text = jp.getText(); + if (text != null && !text.isEmpty()) { + return converter.apply(text); + } + + return null; + } + +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/util/ZonedDateTimeSerializer.java b/core/src/main/java/fr/cenra/rhomeo/core/util/ZonedDateTimeSerializer.java new file mode 100644 index 0000000..c5b3738 --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/util/ZonedDateTimeSerializer.java @@ -0,0 +1,66 @@ +/** + * 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.core.util; + +import com.fasterxml.jackson.core.JsonGenerationException; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import java.io.IOException; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class ZonedDateTimeSerializer extends StdSerializer { + + ZonedDateTimeSerializer() { + super(ZonedDateTime.class); + } + + @Override + public void serialize(ZonedDateTime t, JsonGenerator jg, SerializerProvider sp) throws IOException, JsonGenerationException { + if (t != null) { + jg.writeString(t.format(DateTimeFormatter.ISO_ZONED_DATE_TIME)); + } + } + +} diff --git a/core/src/main/java/fr/cenra/rhomeo/core/validation/ReferenceValidator.java b/core/src/main/java/fr/cenra/rhomeo/core/validation/ReferenceValidator.java new file mode 100644 index 0000000..374844a --- /dev/null +++ b/core/src/main/java/fr/cenra/rhomeo/core/validation/ReferenceValidator.java @@ -0,0 +1,154 @@ +/** + * 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.core.validation; + +import fr.cenra.rhomeo.api.InternationalResource; +import fr.cenra.rhomeo.api.Version; +import fr.cenra.rhomeo.api.annotations.RefersTo; +import fr.cenra.rhomeo.api.data.Reference; +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.util.RelationResolver; +import java.util.Collections; +import java.util.Set; +import java.util.logging.Level; +import javafx.collections.MapChangeListener; +import javafx.collections.ObservableMap; +import javax.annotation.PostConstruct; +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +/** + * Ensure the property value is referring to an existing object. However, it + * tests NEITHER nullity NOR blankness. + * + * @author Alexis Manin (Geomatys) + */ +@Component +@Scope("prototype") +public class ReferenceValidator implements ConstraintValidator { + + @Autowired + private Session session; + + @Autowired + private RelationResolver resolver; + + private Set expectedValues; + + private String propertyTitle; + + private RefersTo annot; + + private final MapChangeListener changeListener; + + private ReferenceValidator() { + changeListener = c -> { + if (annot != null && annot.type() == c.getKey()) + initialize(this.annot); + }; + } + + @PostConstruct + private void init() { + // Force refresh when edition step change. + session.workflowStepProperty().addListener((obs) -> { + if (annot != null) + initialize(annot); + }); + } + + @Override + public void initialize(RefersTo annot) { + this.annot = annot; + try { + final boolean bundleAvailable = InternationalResource.class.isAssignableFrom(annot.type()); + expectedValues = resolver.getPossibleValues(annot); + // If possible, we try to get a readable title for referred property. + propertyTitle = annot.property(); + if (bundleAvailable) { + try { + propertyTitle = InternationalResource.getResourceString((Class) annot.type(), annot.property(), "label"); + } catch (Exception e) { + RhomeoCore.LOGGER.log( + Level.FINE, e, + () -> new StringBuilder("No bundle available for property ") + .append(annot.property()) + .append(" of type ") + .append(annot.type()).toString() + ); + } + } + } catch (Exception ex) { + RhomeoCore.LOGGER.log(Level.SEVERE, "Impossible to initialize validation capabilities for a reference !", ex); + expectedValues = Collections.EMPTY_SET; // Cannot initialize comparison point : ALWAYS BAD. + } + + // expected values could change if user modify the reference version to use. + if (session.getDataContext() != null && Reference.class.isAssignableFrom(annot.type())) { + final ObservableMap, Version> refs = session.getDataContext().getReferences(); + refs.removeListener(changeListener); + refs.addListener(changeListener); + } + } + + @Override + public boolean isValid(Object value, ConstraintValidatorContext context) { + if (value == null || ((value instanceof String) && ((String) value).trim().isEmpty())) { + return true; // IGNORE NULLITY / BLANKNESS. Use @Blank and @Null annotations for this. + + } else if (!expectedValues.contains(value)) { + final StringBuilder b = new StringBuilder(); + if (propertyTitle != null) + b.append(propertyTitle).append(" : "); + b.append("Aucune correspondance trouvée pour la valeur ").append(value); + ConstraintValidatorContext.ConstraintViolationBuilder builder = + context.buildConstraintViolationWithTemplate(b.toString()); + builder.addConstraintViolation(); + context.disableDefaultConstraintViolation(); + + return false; + } + + return true; + } +} diff --git a/core/src/main/resources/META-INF/services/org.apache.sis.util.ObjectConverter b/core/src/main/resources/META-INF/services/org.apache.sis.util.ObjectConverter new file mode 100644 index 0000000..4bf723d --- /dev/null +++ b/core/src/main/resources/META-INF/services/org.apache.sis.util.ObjectConverter @@ -0,0 +1,8 @@ +fr.cenra.rhomeo.core.util.TemporalConverters$ZonedDateTime2Long +fr.cenra.rhomeo.core.util.TemporalConverters$Long2ZonedDateTime +fr.cenra.rhomeo.core.util.TemporalConverters$ZonedDateTime2String +fr.cenra.rhomeo.core.util.TemporalConverters$String2ZonedDateTime +fr.cenra.rhomeo.core.util.TemporalConverters$String2LocalDate +fr.cenra.rhomeo.core.util.TemporalConverters$LocalDate2String +fr.cenra.rhomeo.core.util.GeometryConverters$GeometryToString +fr.cenra.rhomeo.core.util.GeometryConverters$StringToGeometry \ No newline at end of file diff --git a/core/src/main/resources/fr/cenra/rhomeo/api/data/TrackingPoint.properties b/core/src/main/resources/fr/cenra/rhomeo/api/data/TrackingPoint.properties new file mode 100644 index 0000000..3f31aa1 --- /dev/null +++ b/core/src/main/resources/fr/cenra/rhomeo/api/data/TrackingPoint.properties @@ -0,0 +1,2 @@ +year=Ann\u00e9e +name=Nom du point diff --git a/core/src/main/resources/fr/cenra/rhomeo/core/data/county/DEPARTEMENT.dbf b/core/src/main/resources/fr/cenra/rhomeo/core/data/county/DEPARTEMENT.dbf new file mode 100644 index 0000000000000000000000000000000000000000..8169cc34f809bf1475afc52cbf442657e995ec3b GIT binary patch literal 17186 zcmbuH&2r;da)oO=i&@y-JG_`cgcrSH#QpzSf+R{p2T5>1Qf}3z=Nl3zXTAr93Z{JpO z^gph?vg+2&pX+9Sd^`RxSI2kV_U-Wb_kX`SKKy?5{GHvy`Tu%#Tz-E(d_Hcjj{hM? z|J=0A>Dx{Y{q5@b>lerQeX~3EUAvzA{oUh({eAPqWe5Am?*DxFeEh$z?ECi$=hgkO z*{aWfF6Gy5w`;1YKV@8f`lIRl>936ZG&E5p7j4?WRqr3@KvPNYeyj4M|#O=Q{ zy;wV3c~Nin&EfiFsn|9ls4()ES@7iN`l5p8q&wxPaqsG^Ox+&tBqkQirkKhNuT~aK%_<&q)aGnDz<`k!RxHK`+_o|al?@KCRdWNuIo2Vz55&^KP?;m z6m+8MQg(wi1cOU~q7i*GEWLuf%evRyy`om(o_f>lR`cS)B^CvBOebq86UvC?eD;`I zu+$70yxkD`RJE6uFuI9iV-vY$H>;*q6}3G{K%^X8sH_RbO3`2eCU2Ld#jgtacg;w6kYrXYR8bSBhTwHkgBhHPu$B^0XPT3tlKTN?Ydp; zU&%s^1l@#pVI_6nHcyl0Xk)&2?L2@}Ri3&)q#8x8&A@YN8_8_oK1Jqc8{6IbC!M%4 z8)^u&o0-QdZ)A}L%nUiPjyGaAk)_}<0-84sMUU#YZGN;w`oxzn_nHjB3nC+-;a#?X zydhIGQYxXA)+&f8#91(zxVc&E`;OGMdXEYf)f%)5^5;uSs`OWu4koj*pb^2^n6;uz z03b;VE<|m!eZRt)vLiB}F|2>9f1Exr+wrAlfgZ>uSCIVTBtF1i?|%2mYXnwpu{ELI$KA32ZC!+Rx|NZR%Z#NWTVizVH6hRQ7mxwyKq)f2V;yGkrT7ikT zMj(p_Uw!&=b$$9N3KPs1HUT6jk%7zz1|m2{Rbp-?!q$}6#X&&i*eU`D?%J-u7cZX- zJ#RP`8C8L5ft~0K&Pm?YWQJH`t^@(42 z)N|1sRj3Sc42>621guj)ElGtndG~-Sa)K<3C?1L`{d>JywcUtSQ@a4+fu~RSLWL9H zQD{#P6_r?a!v&{)`nG?(2y+7UL~5A+u}*nMNY6_Q{%>|eN^r`F9J!+#uMr~Ww zhr`_l(UrwgaAE4C2g-a!4z?C<0Z#)%7LXsRWIQJ_WSmj|nv}N9<}@$uR?y&qs$+8m zGi1;i-i5k}e|{a2N$=>4ci;2wb&#rr%yU7%S5BPT)XLcbKIVizrjbHCDh{qOCYB_! zNb}(7uA-#0txv1xDZ?iAdx$y`B(a*ZtsGhti2}L75)dW9fEX}^#m<(XkxAnK#&hlW z2}_6F4qz*|K_kK;_KTo{9!)6V;ey@-(pz}%UyNT~X^$)bYG`f?^!P7iuaGhd1H~6p z*+SKUW&#0XaY7g~G_d#aAvH=vx{cM*_Kc_j7@nXb4(U=THSTb2a@ xATm-- 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 literal 0 HcmV?d00001 diff --git a/core/src/main/resources/fr/cenra/rhomeo/core/data/county/DEPARTEMENT.prj b/core/src/main/resources/fr/cenra/rhomeo/core/data/county/DEPARTEMENT.prj new file mode 100644 index 0000000..56757fc --- /dev/null +++ b/core/src/main/resources/fr/cenra/rhomeo/core/data/county/DEPARTEMENT.prj @@ -0,0 +1 @@ +PROJCS["RGF93_Lambert_93",GEOGCS["GCS_RGF_1993",DATUM["D_RGF_1993",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",700000.0],PARAMETER["False_Northing",6600000.0],PARAMETER["Central_Meridian",3.0],PARAMETER["Standard_Parallel_1",44.0],PARAMETER["Standard_Parallel_2",49.0],PARAMETER["Latitude_Of_Origin",46.5],UNIT["Meter",1.0]] \ No newline at end of file diff --git a/core/src/main/resources/fr/cenra/rhomeo/core/data/county/DEPARTEMENT.shp b/core/src/main/resources/fr/cenra/rhomeo/core/data/county/DEPARTEMENT.shp new file mode 100644 index 0000000000000000000000000000000000000000..272a065a1f16ada2570b02b037cd6845a7191a92 GIT binary patch literal 3134040 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�?Ak(^p<6J>Kjn;_v2Z2&Ug(in+K?Nih9gEAHy^ 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

Vl>Kj_4Ev-&%_5C0~{qxOj(-{Sw5GmC;b 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�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 z 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≪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ȇFG+z|hCFEI7=xugEC?0$&D4`e?6&%n?f zU+lTm^E@*C{e^Jw6EMmJ^zxGDIeWh_`{um*yybjWuQr~Sj5;1~t2d>9*fYu-kH+(t zp*y>daTz?H88V&CE&hLn#2(cLOg-ztwDWwJ`WJ(--FLCsa*=Sa4_fb zu5wnGaRBmRdqySW=bAr(>(6{OP2UMyufI!6{nSsvoL6QgnRguT2crK9r{s(FH~(YR z#qN{e{2$lQ^?88%kLVv?Q|HI~k(jSCnEPcqnEg+JKl?pq9E^J82r&Cg^%V|o1ZKVi zWpsUt8c)Xa#MxgC?zdw91@-yj{#jt=zk+^HFX<|n`L@8${NIC_Z*n=Y#|<<-35Gp* z0GN7TmDly|4rczJD@gssj^nMAbHUB)?Uusb>^>sl#=ACW# zm&HOaHfMIS`_BsD`RLH$XaJ_(5m;aPmjqMaldOfkfGQOADUxQhv6PR^h;Cb!f7(Xz# zFF=2Y3wgu%6rKl^<;rr?+BRw33xs|@@4aWTiVn7wcp(PHSaVQ4k%{+cY}mO|FHXc z9l6JqXRQEp{kD$KeErNn zCrUWBD46-Hj+S`u!p8f+oPR;%c>Mnc*4c{txtT9(qRwLunDgy2N%EzQw)?%mP!0(K zGk+8Oe+tNUl`wwk5`V`5yWhOzWYv=bW`6^w=sY%p8J_`$p15^j*4z4x=!sr!d~~|l zLl>L>u~^kt9!%X;XX*R~;r@N*s{+RM=&oSq>tObdX78sQch;U4@B$23K@niaub-p( z*5dgGjNdd@@@LP+^B!oAS5Eo{%zhSuQ7<{#o(HitNIzN7u8Tn96L*=*4paT&~dPcRS2$V>xMZz=S{`bWUj_X2tu zcgT2oy!fYV0dxCXi&ame@ewe#hix|Qu|)KQkeP4YQi*r21+(6|6{5%QE3>;+>;BZh z*t1sbsRfLi{-}B$SJr&9*J=IRVCJj*ljc7K=Kk)#McB2;?9QKsGdCEQ{6#ouqj74I z)C>O2;#+N%`~myH>~}C2c_R;lIlqZu)b*S;dombpy3ZTW-=_J_fvGQRyXX(3KF%Xy zr}#S$nt#<@IUJ>e727R(l9pS1w>=u~Z~lc+B!5OiCDr>682d|TEimWN zd7tF-t_o(pZTr=~44C@rACUTKZdjqqNxghzos#tvWOtA+%ub}-zUKe}pZ7}0o zc+~%IF#CCNU;AGMrrz5xg`)y3ewFdz@)}?KiOeHsJec~vdZhk?z|2<%j68w;!OWKj z%(}hJzpipnJF~CQ`0P3sfB&)SdE~3{vrrG=DOZd`pNjs(<6y4WgB;bf$?Q*_3HvTI z`+(g|kp?yq^weo^Z=&zDpGBryCE&Vbp+axna}(#(EHHjC&R7Ue3C?fiTT7s#kw*9}e zJ#VU>!uWq_$Qv68X20RS;vYV*wEAzVp#MLuJDBy`SCRRq)-wBPF#5=;4rcs){J%l; z6IBh&{svdm`8bW+)sXlIAB#T$hQCiSvp4b6^(zQwzNKK~2`gg$TaSN7-@ofTl^KL*n__?u3uT~nTsv{Ohw_8eHOo8+3T43XMv$7kk4=9 zJjYkker|!Ox0L2jt%Z5A{t%sqPfMHkm)d_ql-WDu|21-c$HAP}H?_5X0M?8BJOXn* z7mZ82CHRkBPPY`R%%5 zck}(g{(>4vy{tdL?5_j<|0MhR4a|B?n(O>~n*ZsR>Yooxzx`nD-%nAW{p?c?$TB_8 z)j#rz@ihH^mzgKPtQXQ+_5E&q>0O=I1~BzKZX@~QR)AUW%KO6E-x;^>BKX}n9GLyC17p5%Jl@j&OygtT zF?;_(IL>{sJ$zg_2P$0y`U)LTEkV(Ofd5wjFNez?FKX7!AasD z-Ugp9)H7ZGziogIKHr$X$2`fOu@=nu8B4Xk6Q8GyAGKQS(KGDxb~Bj!%N()xKr>|7Ge42cxe*-jBxkk{jjwvG6uv)}QpFd>@rC7L2+9 z1J~&HcfW%fAGun;@B5~O&gZ0C@(1w#Tl%k7j@n^d9pBF(Z^Ah+>mAhZ>*9HT3iC}s zK5TaJesji0ZIS%3Cylr7lz8u@VCs9kOX_7Wu=qjvJ`epw^LlsYOSA9ua<6~iqu=L+ zE;f6Y1N!}40+{u(!H7%TV)lv$rJiRSn0iNo@#5SE=Kk=7awhKwrhO{%Lsty1kEQ(` zFm;p$Gyh)b!E1W%{jJyVeI)FWRn7mu-?V=+<7$KP>Zk&i^+5mZ?+vr(2cv9IQRB>C zwVxc*zhkrZ^JZ?m{(ccz8%#Z$v7Xd3$m|=G<3?G&ark`$`CT*3e$;r5#n)OV@u6$L z>^BF$m%!hhdp+%U`u(f-FXmr&tIp$RF#NpQ>w0>4KMwmnjrBvHsXNS``Mc!HJa4?? zi1e3JsFnJk_*3jDxz|hip3?op&+N|YI^Vj+i@=;CnR++g5dA(*Ft^Y4X#N7`e+i8F zWP5=*uZzY{Oiy1h=W_|ne1*Zt<9!Cqe8GR|`u%A3YnLT|eD3`6UDA3B%zpBmaC9P= z^YA||_2Wi^Ij=707j=?vVSTCR$uX_B*7$guu!qk_pq}q^{|x`f-oI6py+(nV@BcqO z6w>Ft#NP^3`wo5nN(O&Frh9ule+7McN;T8|&W@4iJ;b&EQ_t6Uz6#u2AA_m?ApF73 z`C!JkKt8;r9JlyMsE2%hITpVf&sRZQB(EQ%{~CQhif?H!`zf$k;)9wP*ITX6!{`j= zyesSTeEhnAWq(>L`9ea#)HhI{Zxryp*?0dW&%20v!+0H@Uqn55z^osH=bL~Na<9iK z3r60=-%S50#MAF5Fze;l=P5-;fw_Gh^r5Z~=RqC>{oo{CPeuP*^VD9^>@Dy-D7d++ zgW2ypc%BblGlI?k^tWPn^8Q}hZ^nq8tbt(ZAB^oegUtTsRL#fhyV(C9c>WY#LwkZ* zzob5|CV=-JFn+8)FD8ih12g|NJWq!6sBHWNp4Y=Zc>Mt5+baiU+5WK(>&fl8`^*2g zKh^N^8aT87;vprV&yNkLCGMh6FRA_dR72KGes@x@ck{w$sDqWfyn5ml?n(a^6noC2 zj_Ush7}~sxga~`afKl7OA(;8=Dm%IxPxY4gjJaT>b-gaoQ0nhjd(vt!wufH>a~9>5 zy^42|d`SiKi`{Dg7}bpC7=S z-!Ak^PE+>jX#Kx~e6R;Ru>J2O?40je-T%Dmf>Adt)%Lf2+2S91T>X<=$^q%d#gvmy zfDsqJ?t$dT>V$;|7P|XV5G?;LtolpwP)vYsM>?}YP@fKwa2BZ ze@G!P*2(V(nCo>YOZ3JbHBS3S_3krn2Zo<#xA8xBbiT=8=nZIpTjCuFYWLK>CH^tn zz+AuKe~bQ5#-ktKwqWRXFuc_W>%@_Z3rsxUm z2! zjFX0%|K}PXIM3|om6MNYeA2jMI`3EJ{{hyI^X!M?A?H5E_=+7bXY2aL=h5SBJehv{ zeBxX>fH{W`^myy_7xDw06T#HG0*w6GOTb)@Ibg))@biQ51Hs7W;O7V2liF!~_&PAQ zr=5g;=A)fFLHkc%17^M{I#2I-WzQwd8~(0EW*?yI6Gc09?>ZuOckbuc^}|~K1njJT z91OjoXTiwhW$bg+;?KYi-GLz=s-78O)>{U~cHdCV7jhKL?bi;;yn{XJAF>Awzl^KK z6T$Ecx&&rFP1HYv%=mv&MNj$_uoUgoU`~AV8r>BhCb?OuN=QwIlQ0wp8`Xl;}bAm z)7I1F2D84?_W#%LXFu(A|Ic^@hF||Eb0s)Sf;K3_TIY)Sf&W%zWp;(3SY3+C7)R@JrZb_J6^s=PK7-=l!>FH8ArX zSO4HbVAHo?XfTkCnYVVCMa(r}lHt;s=A7 zuRroLei|6@UQ6ur{et>?KF8-j=N;Bd_m2)ZKY)MKb}-|E^!y{TVsFhq9?Us(R`zT# z9tNiWyEvagnUo1&*6Xh4JO1;)tn>L_YF}XS)o{LqIRBZ-5w|^3KWT^Y>|3hmI+*#6 z+}8Ci7pD0({Uh;d5yk;oqAxHSO#hL}VN=1VlQs*C%_+;x-WQC1L-(pZBpvy<|CH^c z`MZKSkAYysxthbDddGsf|IF9?(c{4EKU3|FTzlQSICgpBi?4-5N~2 z|JwO?fZ0F&PxW=v__Sy+>IU~xd%(YH&z@rbC2@X_G|sukv%&E9{?q(_1hf8SFxN2^ z%yoHcoDD`FiH$ze{q-rB`8t5ApHo<1}6WtYq;2q3XQj zBb)dCKU#1_4VPIh)`}KundOSIViAi`qiob@gB3N(&9V$jxP(P4MvWGhsG~*AD$zz= zEy{{=M~fOQ%JqA`&g;F8$M^Twc|6bS-9Mjm=FB9M5HELu_fziH;Ck<;s%}_yyzx~s zzv3;h`h9}^&9PQ2{Q+3@ybW_qy=lGUlmEk<&ZqYGetOXM`5j>5WN$Us?+?rWGMKt5 zj@Ads6GdJuf!CJ==Sp7cC z{RRKxKM(YJw7~c`trEPA_156>i=R3EGU)PO0mi>|eDGt|+pdC@|8o4v*Zv($-1H3* zZ~12TvoEZ5m;hs!TN@^9^)b zmuK6*_yzHl?+sYzUx1lk<2#|B#Onj++yAznd&sXZL;pC~_OJQV=6^A)^{)zU zGPf=ryfI9?iX~z7v#$Ls7c*zy=l!qpy-z;PF9mZPI56_}`}MxKQ1CK-J?vf3T)vCf zOX9Zt6IMM(#p~&>%vbZ;GhUzHfR%qYzaK8$Y`u6M&qF%@P3U!gUaD>*9_O>Wypi-* z74yw5Xl{K4UGdAWdp$l2ejcWu{`sQ6;P!<)kNg|9Z__++FG{EEzNM_E+RV)x*uS)1 z#A^ti!t)^UyH9~RmbZhMSKZX`UlG=NoCb5gaQ~}Ge?#;1!(q<%o*eNW<^39*o)Yo4 zg%x+-&=2BylsWWl9q~RYC0x6w?Q;vDE8kJD<{{QR&o&po!e0C9lCYm;&fIJ+>-{|W zo9>3SetW_ky6y>H(|Vh9#r^pu*L$1&bM>(5of-O{Jbz=?axtuW{{4d2<1E{k?|wev z_AZz_`D=Op=h*y|_1s7O&i|?Xi!Z^%tNl9sABE|s^@q@Jg~?yD=^!H%C6qb{%P5(jdfu4 zbECOy?ePEMi6nmaDC_z4VdA$g5q#g{Nj<&)uzhhwSoy`&Q$FXh#J?;id_Dzp>{>AF zCqL@`|BUs|!1y(6h_3!GfwfOhg>}3g=6vrAbM|T5_g@FA{vX0$>m@$T`I_H>HJ{C0 zUvd6J&9}qKw+W1SemeaTzc3wEzH8in`-SGLSaGkied-KY>wY(^eka<#{4A{Xzlr$h zL#e~8A7rjvE_i9zGh7QR?)|R6=0NMYw;oCA>pvP+UBC2t{aQjF3#-m!&E*#!c0Z@W zq%Up@6Si6Yia+(C#J+Ox@W1Uruji_8GVcd$|Ev4Stzgc71uOr9_b2nI`zZQ7!QAu~ ztU26UO!V}IMT{fMuGmH%Vu{k@N{it~Tu=dBP-VZJFAMW{`0~5cd z0@nIlfU+srCGAwof(Kzqlz(J;MjXs_!}1({lz) z-rON^y>x{A$}s2qFAe+O=|_2H!pi?I@7F|EKiZ$zS4<0g?ML!u_6t7G`>$miSaCLB z{^~aab1YAf^%)=bpLl&+543&ZDp>P46efLsU-Q7x_RrPYzVQ_6sf}Uvc^<6e4%Vx> zV9j?4_6O&Ceuq`hdfv|i3mxJ0+27o@Jgk1F!yKAdgYnD03~Qe21-}DxzIOfKCFw_Y z<6zBa75CR(YrQnf{g=nW>i;`fc{Z|raUoyNH4{Rg-`9KPwlMV;hCT1@-C^a~-}j65 z{p_E4%=F z9{WlA>w9x?dHYwaG{t(}{&m~Kn(u4&ubm33|Ie(a2h91$U{2>(Im-GC=B`Pw<}}^@ zL%YDLuOj$hm@TE|E*!{np$DyuQ2x>7d(~qCT_MB_EY{PydZq4Gs>wEvTECFkMs$t^xE(t6CZ@wO~@)y4YW7l6D{@=y*vKFj4 zEN=giv9RK`!JHq=2EPc)U;U`Qx2^YG1rtAgx&3=zhpD$zZ@qcG7T3Q9{iu#b%%!7Y z?WaXy<-gwgz=E*ie{4PTSHxQ&uAd)Z*^l!)E5C96!uGzN>c0*9g6;d2pSsI~)(6wh zpPireAx>Y7xwIOr{WU)HDs$^L_RmeTe|~>hee45c-*}Mq^3JZecp|L&4s-uq=Y_tu zx&9JZ^Ldc@6KCXBSo6Ei>(g*o_+JaFzDL6TMsxn@(3keSo4yPE44AmJ3monI&%^Xx z^AA}0Cb+)Fy3nV=TIa)H&HGrGeD!&AvBo@jci8Xlc;y52XJdwD&_zj+R< z`TTLOuZNdm!WTb*RZnoH+uT18@h*j#XVoCA`CSnFUGO5X;(h_sPxe3eB=NeHPrNFu z{)^_)4|jWg&V|+ADzNO1gBAaxyOMglTEl*AnD_&2u-0SKJDqQ4@R>c%_nGap=icFd zmN>@oZ@4{)H#ip7e2#^Q)4L(8x(~CS-xyXMTfjPQ533$Ae(guwzq}XBJX%k&e|jqU zG@o1SUuvWt{05&4|ERa=#bEV=UOg-9XSn~$!(r94QOx&3+oy(L>{EAHPxr@q_S-)@ z&g(t+a_AqKQ?J6*UEYoTfqQ)k*1UiAekrRS>92Y}HUA7N&sc&5=3L6~e1qOLH~4Qq z@3jAF`^;s2UTR$AILAAZ=X=e66s-JD`29e>+IqU+_fLIWTF<=A`#0KZo(5BAZe!l> z!PU=%{WQP-Yke>HYU^EM)u;E9*blx0Ykrgcel>F+%=y$?yuZb+mz4_5va-$>#YFAROyoVm-K8J?5qou9zOO?SPS_&0wCYhIJyO5&G>Vd7e)6gcZLIR-CEUbN_<1K0Ac{SlbsL_Iw+cgH>OT*Q4*psP{^*U*%6x?|rPd z>e({KYIU;Xo)?0(mV3DdVWtbSItUNH_<|G)5gBJrCx2>n8HdR>@w#e2Bk z(A$=VHNVAt{pEirpZrha^FQs6{{`#%g^MfOKeIDT-dg2X{l9R%!yTi7A2MebhKX1H zjQfZ5_aojS=Ipbu>VMt$pO)FdSDCYYu=dyfuL;0t-}rt!yl3d^;4l4bnEZwHVUBgzhCVLhKMt#&^{lsj9{MuYYkvuS z5m@W<8?1gVi2MIPPO<+1FmWoEfK~s?e!Xa35?20;&3Uo(1I%5ESx>*i>y7&TllYpi zKA+S)e~x@h!a6?y(|&OcKA*&Xs2^7S%kuh$ebs%i;=kh8$KeaDmpFsA z_?2RQnZ>NgPyv=Pvfo?h0$JhuFR##(vH*;eTTIUlsPJ z!>ac>Sp9Tc&)ja#d}_V+QCRuzpgzsvv(Ve!PtDT*c0X^zvSQJ)0 z{|S9QSow~Fsju!2=Sv@Cy?;33?;HHB^+MU{#%yf!mu&h_=wxP8>WkFTepUBiAon6Q0&g#Hxo514P` zZsycFu;OQ79S?cP@wWDL}ic(}$~=z%q-boifUE~V_B+S>M2ng{XA zV`1v4{sh*1M%ljSqv-$k2fY4on)55d*ympjzVrU1-iC)^)w4H@p6Y@%--)pLYl9VE zpD%D6I>7#^r+9y+{WTs|Jxju>=P&lZ;_SxzJM4RA!Nf1D=l6T5xZd)s!}zrqeEpPf z=l!AbogMZIm|KI>JMsQoan7)wo&YP~G&tE0*4vJYc<pM9tM{}onUANu`r{wH(#KHg7rzDfRy ze-lic=6UfigUMI(we{lJF!@?kkLGzi%shsdqkjBSr&#YvM}NzZ552g3@Ge{lt`U+x|Jskd$YSkFDpg-v1Nl4;#Un z*JxOM4%)wQO<4238CE~i#qG}5Ay(X&Z>Q|l-}dO7@7^HnYaOpu_Xo<$ujY6o6Jg>O z{-z)78xAt3x3yk4A?(i#|2(Yv-hnw*-WLAf!}wRcX}$Eb_3WQ8=gZRNH{WTl{~~kk zKCtp<%^ioqvY+dE+NZ#p=VP$!#L{oIUULMje$Rk0t3L#0JjLU}|3K^6-K`Jq4lCYx zSo?8O@QT(`+uJ{L^(@bCa`>+cEB@iZH8Az`o&~F}A8zyhz0&^0Q()C~i|tDX!1xb} zRo^Z!edKO})z4U%IO(fwpB)qWd13$GTa$RTX9t&H>_?Pe@h*Ug-*u+_ODFsvd&NHj z*7enH`{es|)Ymf$o~Pqq{bcB^j$i1vo;%C&Dqn%s@6|B&sX3v)XZwL~VV(coJhIp{ z^W5-1$ef?g{k2~MEC1T&?q`B8GM7Jvm2Z^i-Slzz?-ui)3)6q*Y_CuAyRhbd15Ce- zub8tR!sKZ<&;F@OuYc<#Sn;*LbiJ+yE8cDFN9=1B3Hz_i4GX}kcO3T{{L;VEukwxM zekxuf;&q$rmJI&^n6dOp$3D9p_iOCy{^5AJXM8_z{*`#7FCOUEgT7^KUz!QyS6d59 zzto)F*Z$=cuP@YZn*U^i6r5fXffK{&c^&eOmOR=NI(;W8H6d z7-m0YjtG1G{G0kl#=)xp>R#ttKJ-8Q{57&8tURN6KSI5!|G*sbcf-`zqWNkbyZL#q z=`NV_rN4L{)p_kt`7gu!SB|*{Ve(}b^84N4Ct=0CJl@|wXU;GGoab|P`2WY;Tp#{d z!NhOMz{>Y3tm|Xd@Za(IggfWAeerJ?``-6rKQ8#9=XV3Fy8iicq7Up3tL{@^&R6Ju zseX5RCF!?k=g{|g)$yBxQ?DglJPKBSkG!7noC{&<%YF~5&P#%~IBpInjD<+_y>mLSyh{u=1}0 ztKMg=H|hPJ_Tx7&^Q!!f=Pj+z8sB+-U&5;Yrtj^q=U?gf{*dTB#{_={s~^2zRlVQB z0oC%Y!G~;)#-zLF-|C#KM_NuUd zlkZd0NBcAJeA>eIu~qk5@jSbwzrWr5RXneL0ju5x@z;7C=&*BH!xPJN5Ylc?!FkGf(jOiFg=$>g_l>K2Q11`P19L>hD`~ z(`I4+Py08n08?(hd8x#|<;D1X>4T*`&u9GkQvUK~lKL`z*0ayU${U~Wm3FCe{$l8- zE}QUBCoH>zmh<=HcY>)WH)Z)mFWniRkIuhB!ad*e`LpV|6J5tk;`8Wc7{3aA9!W%p&w!Y=Ivm`KLOUdY#sIo zubISaoEUuETAu$n`c23DVcZj{8UInDOv!~T`{H`ay!lueR)+pdY9j~)*bx8h1z`*72`B!1<6po9p* zYQulCon6o7F#b6)`7<@4_rt1hzxe%wF}oz3S_;y^_&zXhiL*1ci% z^A4=~Cs;2nzFU&NVl1rrYz7m5Xf0Uv&V)Ii8e{+R4Oi=_&C zC-(JE$M2tQGC7G?+8I{-yt(7;dA}dnp#96gnv46`zw*1#pMkZXK8@cmy=p)E$M2`+f7?H)r*2Dh?bo{w zu>E|t&u@2Nq8A3@_i1l$PU`D96W02?0~5dTjNnBNO6=S6F!h$3V2%xE+dqH7!H(Y* z_NN|_=>7WrX2lzU=`Zylto}|pEU|CBIQZS1<4=Y)uVar){L3H4?_ckCRKo2OVB%$W zY)QELet!R3ai2Qc@oVGv!T$?mSGzi_>*?fU620r6VSf%xf1P5@=Qih`ncO%*vESJ^|10bALn}C*x&Um)|$ktUl&$AADrm=U)|6Be{^yZzrO}n ze@$(PK62>3_TL94Zv8>9_QM{*`@_mN$@YbPVD+-h=yyc+sR7bN}XUa_A0v?Gb1egjs2AHf`}m)ytx1LnS2O`g{su=dAylilxG_HWt? z);b*lbL`Rgi#7i}thY^qHP3%pFKrt3Yg$i_wS9UmSouf6s{cY**ZUuPJKu8`njeOx ze+gq>UxYQUkE~Z+Y(1B`DCw{5qrL3E@rPdLr?%@fc$pW5b< zB!A|yUF|>H{WSf(i~Xx%*}V;G|J1?M+xiNuxzDwpzb@=QcYoC76IT3>VXeo!__Z?=z4Saf?G-PEu^V_K;`hRoS6>YMf9Am(LSOW9 z&+F>Y*SNy--rJn{4W_>C@u5F@Wn$mEF0Az$Tkw1`VSf=!zUB>K&36dKu46TGZtbfQ z|B+vIc0c#Sn$sn)=6Jx>Nxa78%=s;0T8ISo`lb&%gST1OLIDVAZp+=QEInRc{%_zvdKJ{T<`=Y@BKT-2JfTe}nzA zr+K|oMxFgnQRu|4DCtJmI=) zVfp8tNc{U3+QI92T3@2K9UZ*PQ|8xU^|Ra4iG5CgZ%p$%`>Dp6dh3?3>S=m0>8G?#@cZW4g<{vV{SP!^rvC+_Du`_ z%GZ;629C9TX-k-V4F|v+%XM!g_Ji-&o3}IPcQNM{GFKn7rSta%A2GrGeFm$pC1KSy z7iRr3&u-!Q-D|z+CRlpL{`DKcn$PCu!G|`t{hpy;0?WQ&uATxbPYq1`#@5ZOFK)g0 zNEp2!);te`iJw}=Ty6|~HQNtv56f;-n0TFAhu&kZ`g>FB`g^qKbMAx{{~B0x+X>eG zm=3Ft4Pn)*`mry5ROkM-GIw4FOV@nSTTg`L-vkq{Jp-$rtE@Nvyh);GZZ^;P23G!A zwlBX2t3TRZ+OvA9dvFX8=Nu|x2yzJK&)ZD0PK`wRKpkZMzXcPoVNY1=HI{m?9~@`S92E7f4lC{*)~nOO`$m5Y1y6y=)4M?M zrPiAlhB;r*{ayQ`I`oBnzpCE?R{qtPxBA{X^j+irvZ*O?2dn=LVb!~A_`ebN zzmbjH|ADaT{s>n5590p%FswZHdp!s4fQgg32Il%gk-IqPj>!vAOcSFZwVJG?rTed4&U$XL`yE&Y*8FromS6vP z_qVXQVtZKnK{3yfjN>l{Gw(!QnRqvy$FXwy5**{kSYrVeP z(Do~MKeRszYpyBVr_YC(Z{|bxlk%NpF7|rARUQs2{^c;ouI8}+#QV3j8?5>c^Yhjm zvHJO(=P`~=dxZUyFm^461fTBbwTd%f%|%T7zDw+%o*I0)_1vG&C3@-+`xoDYskiFM zus;bVPJ2JBdf)2z{wi57Tx+g>C3rt`*Gpkvcs7YQXEv;QUgP;veccgy9wu)6HRjYf zKYtEue#$q@^QrotYX972=7Gtu_U}ow8#4Hv-JmG*_Pt2@)2y%eUd=GO4<3;Sctg|%FNxVwY>s{E;dTt3=bJ_%^tm0R^e^UOfV4WWY6Q}(!`=`2j zzs32E^KGA*V(yt?dw!qY{b``uYCV>efbe{ z>&md^eWlWeT?fJ-qLz%W&DYs+cE5SihT3tJ3malCGB_OrXKE1@@I5? zkT0_cj9%Fn{4np&F{>YhRrf4d_3C<4p2uP4G_bs{$Mh4{t7>7zyT$(1>jj@?`#Lds zvSmIWApT%=_}_2t8)f_AX|VEEhQ6b@A+Gn-Z+zaMKHhP?#n;VU_rY4f$IbO8ShEyZlV8w!eg-W4Yt~Qx$GM*VXS|-N>Zq>^R{me_PwKDO z1J*olggIZgjk!3%+?Iir@4aFYf4C;>cZWIOzhdYw-J7gW$FE~;pN2L6&&=g3?@9bK z-NDT;b@uE6tDaZP9Y3$<{k1$y+g<&z^jq#u;-yau{S@n|WkX-h`RZoZI{zZ~CH1x6 z0@GgcBI+ehZw}Tx-+?*Q*V?}Piu>ta1;#FYkozyxg#8+xf9Jul=CzXNUDazY?#Jgx z#H(Jx^`zJEerr4=>buSRE%iXu|CjaR*Rbk2n*B}Qfem7Q?XlmtfTint(0pp^ zJ<0yM;1hg(&bi54{)ex}KFwSGTm>`lp_^fjrN3a#k93){_i?{r|5RNW{*$=Bp|_m| zlRiI#`=^e_!isnL?8JV~8lm6j&$H6cMnApW->I|vZdmz>@p@Mbp6u6`*50ts_<1Mu zraAuy&qvDtW7wbJ_XFJ(k?%%7-!-L!uQ&H9zUFnUp9d?hfHkj~=JF|_A7F0S8CE}= z*}raASoJO+_Irl@EBUdj+YeT}Q+OUE&ER^l_QS1y-s^sq{UHC(=|}dhv437L7bd{U z_oR7X9ISZzxc}l0>$?6S&u92!nDE63e!Wfg!->D=nYqziSl4>ri_3hfO=LbKpmEVHZ-->>H?-65Pc#Qo;{Q6HrKiK;%Gmro0*YlRSwoh*a ztB>b`xAp$*y~+NWGkJZb&Y?3S-ksj>ncYG^8YW-YmazJ&@#}Bp+OXpO=If_rd2{Y7 zUq8Kz+P}DwU*GzlU(5U9X1~5xKM1Rz?P2EEc#}Cj;_JEnVwm{3$6(F(RG9p!Sulsb zV?w_UrvB^!u;#U}?dPm*&V0!IhdA9!hW$gn-`Cu_rsI!?iC6z`bNOTLXR50y_~_tK zu=4-N{ZIFU-Wu~*^KhFvf2r@Mg}q_w$(+ai7W?AAVD+;YO#EK4_Qx#0K9qKXIiFtN z+;T8Xy8Ji3|5r{4eGM49wv&Rt-29A7T1!Jr`EK4EZ##6JYF8 zyTRmXpJKgquDN_Tto&EQ#3@LZ{SToZ4=ese_djwntohD?@vE5@ddl;w6w7}rSaDAc zo))ivJDc;p=9-DYgI=Ge8d&jvhpE4D0dw(xq5m|-`Up&#!OzXb=goch!s>th(07GZ zPr>!o{>)beWn2>e159uUtGoh z=}G1}OTxq{Z3kQ!y#ed^x$Qe&2>S~1lehl)&~Na1 zb-x<^S?Wdadoc82*Ppv8_%!!lyaUEAHHvwWr{b0HzYtcv--i8;em+SpLH$~v4s(9d z=ugitn#X*w=Jzv9yc+e#vAh}AtKttuyrW^}GV}qg{BQbtZafp#ytXp8R)zoCwy&ML zn&VG`aT}ZkbIk7zEAMUQRKZ+#Ev)>@`F_%Sra8BTpPz>Jg4Jhmao1qkv>gvJHgoH=E6Ge0c$>Iz^YI7;_X5o3#;CY{rN{>*0-=;v556l*80FV)wVwp z*8Y4JR-P&5s;8}|CfmQ^Hdu9SZvVP#VAZ`b>%sYf*5H*{U&U*LRo{Ftc0CJ(zJ$4D zcvbJupV=>(!>6#0ANzXhc;9;I3G0Jz1YcmzzaI7r*}hUtp6u1$kL5RE>MGm~Q_t|n zVSkS~^G(=a0+TkcdMLNpVE^2o)=TNo{|f!XxPOhn^6T*RI_EoB^U3=9$*Uj5TOC#% zZ`nTegRjT7+2Q|*ug8Xa!~O$bk8`dvXX5&-x+r*M$Lno{S+DX2&ObZ_R{zsrt;;^J z>WTLgBYVM`@AK#!2F0@fI_wX$o?kQiKO*#YSo1p!RzLssJW`Wk?UxmpzmB_xekZJc zC&D_e>-DbO*7oJ=Vt-^{<$uU}c6Iw_9yWKZYP}?T>aAWDR=o4A4=oOJKEI*$zCTv+ zJdShz^c+}o*xUP~<<(%l9?LH{dl~%@x9MGUoj>0F*L)c9R*C+9uz$9~{dfIo`(&QX zC$n)$Qb9DB|Eo5O_7+~WPvxiPH%kA^w6jSlZcq9f_|BXwz|_|; z7nc3`Fm+YF3#*?~ZC`jU{ExGJcQNd@H&3>cKto42f=2(5UIkm3!*5gC} z_O_&+^g;H|yatnhXfIfEn+>b}tzgaTMp*M*-~Opd<~hrm^Pk_E=#77`-P`;+hF2W?ri(~MPa`x ztop_1wTr?WOIO0We!gGP`=`fx&j2j@0hs!mAB0tZt?TQa9())~oSp;B9;fdUhUH+CTprI(GfP zq`jV#>|gUXtofbo_>H&2q|d(?^U1;Lw-45SJv98M!m9HC`)8Jh)$d;RPkq?s_1F{U zeBq4i6aUs7t>Ps`e{`kjl;`HB>*cx}O-ui*NcVdZ_#TncV_5!QT;wVv*S z74I7RH{2Hb=jPl6u=-hx{K_{KR=%@f;x`=<_D`7Wn!TJEC2Ig{L-(4{nfTlRkB}Y|FG@L`*{D> z&4KABb7}A(tbRU*)!%UF%liJ){kOTeKg{}et{U^M^!+Ti4XpeR!02;MgB5=)_dnHl zedy<#>+gd(pPC!@%NK25%y2&?&cJuD>bW%Tw^hC#QsaI99^Ty7OKBPI|Ac974t=g) z4{FW|y_we^?f>gxt;3sseJb4xtKMgM{Zf6ehX4G$-eTYQwK;zVEM4~->8|qQK z)65m6s9!pDwcTmG)Cv>7_1vg`L+c~cV8vM$CQiqxp}#=AzCgE*1Rr_^_y(HVj8S@JOAEr-^TlZI=Y2i@u4?PqhyA?J zTwy(Rsn@IJwb-8xF!36$gSCF2vEKAkIx_a>6j*uJ4*Lh#FPhJf%X@y?!PpOd2CIy> z*uq0H`A&dU?^dw-TgUd* zYli((T)+7D{ckzX<8oimjYF{FT>vZ2$1umjDX{8!*Y>4FVB+^Y7QB(~FFhTw@^y3n z!M^~bra`+iy0^_&bV|NF3xm%-$#d<#~64_P0171kWy zf>qyhu=0Oo&OH(KbIsikg#BxZjM?B1u==^} zDzE>S!CRUKJ`ekKVeG4=tG?A>_4}1ME0+En%rPI_^*5~jvv}Aq68$_^Nczn#9ra%i zW7oZS=u5%WHS$;FYrE3(R6gRTmN2L12EXI)5A^E)(M!J_rvK#s)2sifmnZ(cgAs3I zSazS;KL7Jf^UuNe!}txTKCNFXOuS4ztbR6!Io7lUuVwB(7gpTS=7s{S{G(t_=Vt}K zd70<+EUfjv6;}K=&6%UjjdMerDK+elwRYF*h$0*Y|8#^^f=UUy?n3 zmG%EWXSae?-$S-9Y#082T$=c&PYk^srvAZ8t(RAZskiEZ(BHWv(d(auRbK;4y$zq( zKDPmkedDLWUtgTWFX(=!{`WNZ${x-z4`a>|KOs;zWL|i z`(gU(mA%$$J#+eVSnDwTLhm=_Q@kfT+|OrWe+aC(%r)o!xFE^j@kZ!R!t~Snbok!@ z6Swb4Sp6IdlefD!c-OF>$E#Scc+>vbrOXY=ue=k@in&9+N6I#9Y?vC-GAkxu4W_u=c}L zSas}VF8=EN>-U0nejS*+6$gg>%gjspCc`@Zb-wFS{i<&aEc-v1FURtn|0H_bmtK!j zJ51b;Utr}QZ!Rt3e5Fs%OXf4Yyg7S5tof}T`5rsh^V=}&e`!y6&b;S^=V0vX^I`uT zOum*gVdYx@fAqoWu<8x2J|E_MO8)d!S1{*Kfz`(?Fy{+{=eXal@W0DEaJBVxaJtia z`6_hfSA5bJ+hOhRb8KHY#Clfss=l|+PU>quKDY>DKYR?VdfQ>G%SqOYk55nZ%%#@L z4+mcn{!hTz4_zPjA6u`w2Ub685>Nf<`Hc4SA3I;?*D!viH>i*E)hopF-z&kRVb$?` z@S5h*GYrSuL=xc>O7FNF5&Q~=CR{smZoNr#%Tx@jxJ&OmwdzRPxPxq6# z2G)AbtG6}uxz>wET5tLw`fIR0{FeL6{v-64Va;RqnV!ef!82ghGuxbA)_U%V;6L(S zPqEhL1z2;L=l{$ZiT_|9y8653^u)gNc3AWMWm>{T?H}>EFmd`j!hSKB{Kq)LKyq@(_rjUhnQ04l@mg%3zv9%yzhNS*{y(4U`Re|sJ`RJi zZ`S=$_5IM6aMx&9^(+XpKj-XXE-q_5rF@E43#*?QFvs#vw(sn*o<12S?$B#6dGdMN zm)|p|q~q89h5d7l_Rstr_S?YZY5N6MzNO6rzlQy{|4!n!`~a)}JWRdCfzUUF$y=@U zSN_#(pVULV^#4xr{Is7mj}i08XJJ1W`s%Si#frZcOuW=+;%R+$G3WP!Rp*r83(R$A zz>41qlEo_-frJy*k;x8Com-j8A8=jOd1T-^OPjpzNM^8Xm|_KNq9H=twR zaB;l9`~@a&<()9+%W2k|JazZkK6{$ifAC3I@s?u0VBhlutUmTO*FJ9h(hacAOIN&Z zSoO+Z`{hNLFnurBKfQ_f=g1c@=kv|x!q2egaU-mJOT_!_rF=aMZVoHYC|^IFjpp=< z!3T%^uio#~Cx-qOto1oH_)eHQ+r{c{N!zDd&H3Bh&%iwU%Upl{g3u3!)#s}b?`YdM zeGGFxccJa;N5Xy9b(P|2M4sqqyJDR@b#KanpC3`<{jse`D@X*tfhF_K*60mH)(CUX%No=DYx( z-^jlnCT_)Iu-0prxc`m!=Q|~_@^1=bSC&2VZk-TZj{D(cSov>dia_%YHZO^{?ALy9tb6_MPD6tPj3v|J07|r$YW(pJ!MPj@^n+*i1J} z+`3s|f1}qce~b0v4YqH;I`oOQPhScv?>*lCbIuFi&HJNYKYx(^r}tOeS+MG_h3ThC ztT_*Pe`e2zHNPLdfBSBQHLnWWcRn5VW6iA}!HTz&zS=>-}J2g%Uf8lel+YW?B8&&_1r+*4{wJxpE`5B=A-yGazCa1IXA=9RT}U6Yj)oJ zX2kva5yvZ^4G`m zzn(dNGtB9}&4Y`6y~^wz{@pO~S`L6Irzm^+>J=;AH0vFQ1g{QrI)AYJ%S%`?<%ma z$8Ou_k2*H7uYW)6N5NW`RmiV>^58L!zbVZ5^qMg7>(#&VeS37mUDv^y=a<2^*}m`* zjNgEMzA61Db3s2Jh09wyes)QIeyY5)%q^$+=dIaqVCwB$o}VXce|%1TaO3f?>S?AQ z^?Nm}_{$ydd3_&0f9`?R??&#qrL86|et@gxl7$UV0&y z)YtJ(SpDq-bL{_#`B7f}=fe`c@;w;;%ye@}^Va$u2xC|MiuK~M);rz`o^xmtujU7s zxaAjM{Azy*{SKJUu;Vu$?fS}Vn)COE{k4fP_+WPR;u=Y#+ z!HM2JA1u554@%4!gOudB}u+HyfP9JBk*6$}I^MjSI71sKnY5%%5 z>-kx>Z=N3ZGtK#1Vdekn0AC+Zz?#p?`+MH+h5pBWNq;??dcLJ+VDfeE>G>8H#$M|& zGxQ75;WqvLiRyoM--MeUv7X(}Tz4_7`qv3v*Nf_@fH~Hl36rPXvrp3h;2E&yzu#o% zzuuhb*xU1Z2UfggVGdot2j9P!PUcEtF&+}Nnf5Z9w-PQ+pgH=z~{vFf8 zKV@#Y4px7k@0sKu>4H_?4KQ&AZw&tnVdAvhWdHK!wlCZq`YP6IWiS7f^^vP>pZj5t zq~G?-VDhD3YfSPD%op}o?VhYx@u--`Z@al)-5*u|-NEzbwWGOX5MA}Zy0hn}`yck% z6SB_tkhyd)tn<&p+Rxj<@|*YjZcD)2ABO)M`o}va{{7#=s`ru|68pL;em{`8q(0l; z`)hRYtVynk6* zjr(~FX5N{_%(YL#TK_k6(KUB5e!UaJ{&4Gkdqscyo9mmxei<0Q+Wl>x zKXt1lUcFfHo~n2LU18O`Kdku6TQ99>z2$T2mHqs%`gqskS*;p)4C7n+c)SEKf) z_V3g!l6f`U4imq;EliwB%}?9`>-9vxpQ-#;S?~Be{I9ov`y#HdtiNZ9UH4R2>$SQ$ zHyu`8Y5NbI4{N^fZti*?fK~rBu+G07`b6ugh2!^SmxigQb7fd|M{VZ*^!vT|mtNb{ z>wh||{TB5wR-K=WcK^Eu?{2O>6((MKXBfMVmtfVizxC9+u;OKj$9h+7>Um^O z8sm9g1FPR@)W@;ryU;H-_m7M3OPuHWdryFsZ@$oH!&W8-@SClI9~r|8NQWzXcO7yB<36dl%&UQ|iCT@w%6Rwg2kKr~Eqx zPof^pqYKvlIHM}zs@Fq*5$1gN`>^IS43nqwzp&zrreF2-tGTd)xnT_7|5E)sdLDIK z#`nSQ#$R=99N!m9J6`QNu+D$xdWLJv=|?=joLKws4w(EsYr^VRe}5joI{B;qbnw=& z^4HQYb{%Jj|AC%o@hZmvdR=wL=uRIneZfbt7Pm|)Q-#1x5<(X_ff0fsBa9ddYtN;_gWkTqa7Ejh^ zczozjRC@k9hkidSdwri!^@@p8(_}sMB&_}pu%7+U_SqwYhiur2v(eNuD|IqSozmA4?Ge6>)XHT zSy=hBp7d3r@9W}USj+Vc{BAw_N%UJ0-v=Ha{pkDMgfDi%%%}0d`2O$JFmZ?e1Jg%p zs{2j8|4g2o{58+Pu;1MFC4HY+`lH_8gGa!`$*#xsq&TOBz9+18IK$s}PF-ld@6xcJ zcRgMe_Sd14uk%h=_3HZ7oIbLB>DY+30^i@)`MqslT+LjVX#2Xc!K>Q7e|uQ*g4=h3 zRpn*uNVa~Um6#k1Z=lLHH z_G`j~sou+6*x#JrKJ=T-U0a5}QoLS`hnZjICRq8`5Bn{7eIwtZU&5h?^f0ex5C<2I|Tpj*VE3H;H7!J#=fZ?);zz2iQo4%top|A zdQaTSb(k;b^A$V~sJ?AueO`lQufHFmJm;_Cc;~>_r3ZPw;C%bMzd!PNb<%I^=Mk@+ z=M(JO;_q3MC-b~SzM(_;dlsB8Y{Byn@vBdURnNLL33pAio<7{1Iu*vRbfbCjL>Rx+ z89X0yzD0j;MEzX~bL`$O_*rws4zTK-pXW>5x^{yV?{rxEXNv7}>-c%Jd~Mht1Y_TK zul4dp=D`KkNNK{r7CNadh#n}e0?^I_54pVXPSAxK>X}%So2M15-#cQZ&7Z3uZ==%l#Vsn7O zwx09p@1GGTdl2tW$Wyl&tobH4Nh z&+pjP+yaxf_#4+J@mlrwk?GoGPCcxNL-WT>S`FXwlx#00I^>hw~{bcTc#BcvC_^IU*y>ZEZ zx!)Ch|LxrbR()Ud`oVEvS6KaZ`1PbTkM(*@PgOVP9+y``^v2r^1T28usXOHVXf{ ztj~Ed*1H`hZp)Lf>e?mrdtv2U7pDH2+hM{L5BP`szdZaGgr#3#J@fRUNxaf@`)BWl z=`($fxpV+bn)-|FU*5s?m6ySq$Br=Z`n$uw%iQo@`2P)S-k;h(m*#mE?%ja?lxHbe z@h^=2D`3T&5qu-{V%K)7=aK!7>u-p^H(8hf(|7IN==kLpHg|-5sn7XGG=KE+2{87R zov`wMxkxgfVd-#TM;JYO9jx`x|0`oX8fOJpRk;4Q!#@7M*_>fm@rw(&-&MVT%b&vX z-yWvV{2!rDH>Z9z_r3yay;h6(pTVkQCi#im{ZrU)LVeUZu*oK_ceLxD(+Xo>s)n&| zzsa1P5%#ab>SrUbPkUvZ;|EtP2`m42bn5I|3D!K;4IUr%E7`w)QrLgx{Ef$0F9lbf z5dL?eQ&-Em;eVRz>%SuG|E53Xdjh8J+|#i7dj;lv>h#b*fH|L@;(0Xa@58Fzl=ak* zIdcv3W8T9*+rF>~O#a%`rtbem=B;^F!pisSf=Rx@VzB1@CX9b^VOaS$g0buWk$7M} zw?GoF^eL=)?>&EFKj%4fwsStO_uVjl<;Bd!8(`I6opQg^Vby={-^u^qtBJp7o7oS> zuI>=)nc4qKxM{11cLq!y^&7*gukWwq{|OegUaIGxF#b)8+CF!+|G!`E_gMc^Va5L` z__sg&|0q9!IbYZhChXt--+pQ(IaeYJk<>8ll(QzWfpY?~wCDtHaDQ z^O!lic-S8h`fyxdzy0L@cld#?r~E1~{*|+XuNzM0Q@9(}{@4^oZ@JU{nGgAYi=1x| zYhD|fyKfHv+x-6<>#hy|MPT;RoSDJD`~N{!&Vq@XT@NNsZwc0ZDEt3M)_!cxd}8kT zCj6yq9n=qg>4osu{bf^J-h4~1Um{g^$~+>-TvEYGWNUs&~xxWASo!~b=d z^Qjj5mku>|iFJMn+t(f+_80sAb+(>nPLGDEZ|FQ&^Sph?d>PF7(xNc+R$L0J?mzhd zpB!sWhZX-o|3A>aqpg=$w%&cX_57D#+F$jm|0`hKFI1oM-S9;+zY*0(xcup`)@KT= ze22lD@5;ei|1HA)U|8$(BLAP13A5w+I?Wf+YMIT2f)fdChQLj z`%$ps9s$d4Dce`i>+h*@(ocI^=x3X|b$?R)^p!0LaTxvcx8;=TQ;>y@r}V`1`lULF2d`TxIm7GTv^ zUS08&G^Y+sWbABh=mnXnluZ_ZfadYE3uWFHD}=YQKJ!x3ZqDjn}hPVf@-R_3KxDl(}I-*dGbgf0h3JI_dNC(ZAN`Aei*U zOJV%GkG6g87jy0$SpB79-ZQM17cviA0;`{~u;N}3{`&vCs^@0w`De@xw+Fw;`Vx2O zjamv5>|06ffwtZ%K|NrCE zi^1pl^)&MbvJjsgUoHa!&;v+Vb#$J>v##wd|Ic5{xVFQO8vhC<^MkX zue6?7hu44X8*d0c&|JJJ{4etJLht=B;q!06n$OFy;w{4S1^#oshc&M&Vbxo;h1c^J zKaX^eg=K#h&nvQTf@Qx7&pV3O9`+l;s^=0|{frI1+MGYp&qvkI!MZ;BVB++A82;~C z@A?|%eCb12^?YwV{ieBT1SW6pQJ7=*->~u>1>@JT#01ZKeVBTN_5UkW{{+{cSryj& zzjXgqyTbB+9mc=%V%z7$I{$Fk-w0Dr-HW!*H<}Bd+P?gb=iT-*j9vOrbKP&jzj*!X zhV7ry^P2kn9@g=Gm~_ow!J5zc=K9a{}Zq ze)dY3W9?S3`tLJmcZ1dEi!kvkn#_6WaDOiRJ7Mw-OocfXjP|m`Ku%T|43nLKaZ7;N7p>=uJ^q5jC#kx>i1|^`+F1Xr3+xi z-!k;m=vVV?hSlf8=AI*MpIyT9E1V4Dmpat*?LI#IXPNtt2>a(@^0gie(_g06>tC@Q ztoYl+`cJTbdIy-WU2BBCY1mhX|4P=I7l*OSSHh}yB>LC=ihRW%V9i_h%JU5@`~A%Q zb79pp!~Q+*hX0)~c7p@3*5@tTR}8|M-}+n+TGucBA6M@l-*f%{|F2?^A?7rNIlY|b zkVVa@IZZK<5ii21R+z|;sTeU~j&mAePSatIbDHBiSjwVIF~^ZcOb&~zl<)2KxZhlU z@6Yf3$NSm!c|YCm_s8S;-0Su7+-nw}_VE71{LELuuD?{S2mQx`p(ncl%zU-%`b`t( zm9*lFVy-v6Rb%2C-r1=H^inEgG1_s_^1 zU9qjL_h5TJ?F|J}&*!rD7XJ=LSjJE=^HkUS^U+}H=?}*F^jPr>vnP{T?^7`571`oAl`F!DyVHGM%fz>uGo0{zJ6;}K5)BagSH`RBc0_Bh7Ve<;?Ab$WuC zzYzNYdE+z8Kk9QZ`}#-z3(fBPSVxE$dw zZnD{Pp9Hg?3Sb;F3sH}C!)(8MvZSY%U0)H0q~{yE{{3>m)W6p54*^%qKQ9H$>w)=T z4^P$op}OjCG4`no<~+_BCpQ)svwDeP($`Pd-xx6a+iiMN-Ud@|O}id)UzOe8_G8>o zv->=-`6nlW(Pv&?tS9wtQ2YSPjxc>UHTHhoNuP-OWgv7E+6)T_?X?saSKeZ&$o(y$>O8VfT_y^ z#xeb(_=a5{Ib_z?zbAzJ24?V^)Jy|(^6 zW;~er8-OwQlz1?XQ6BRT{6hXE&F(oO{>k#k_;#`NT5I)v>wr10USQNq?gi$28p{7| z`9ERyxc9)E$M^Q{4N>#J)c+9}=QGwB2locEpRKaDHhW+OnDv4be;CYq|JwdYyDI+t)E*x!sTE?-nB_)~vnFzg9c75~mAmoIW882-UWH#&dc)nL}! z4Mto@uIyztI}T`4-tr$nKGwOEfThlG(F@z{s1`&*Ebbidhf-1-bGs z4ThAs`{Jn{$I0b`OiyVr>c%z%b018t?cx)=fT`zI@i_UHGmbb6X8n7$Tz}yOVD?<6 zfy-C8s-f}7Agi|+O#jhf923rhS?_Hy^@cYxJqN)!pSc*!`okN#eCg#Hn|)s+XZIa0 z?%LdOR3@1I3!iuSf=e|qp47tZ!C>lZ)yCz^iITng3yuTc5YI6#d|kXg)agxq8%(`( zJ2?NODPY%cM_b>yVD`7rIAMkSONY7oo*nXU1cuIl4EgT?v;PBN>d)xx<`ua|cK>h} zAGT9G>=lcjBmcr)#y8aed;OfA=y$->=NIYn$K2377rbffu>;J09v$lPXLgmnFBp38 z1(6oN(Cm3tz&!66=Is7CTEADp?0Y|$_LsoyZ#J0yJZtv+Az=Ddv-p_)VCt&^#v!Ar z;)B7^6<-`oeHn^BuKiW)9cRz`KzvX92AK6e8)5m{ieDS;{5=8kzctSE76mi^f$@$L zo)rJ^zQtD%cl^L{ZbdNlmz(JN%c%@zy-IOz9@$UHUVgI67tVP0H|8V9sinnVOm+Dp z&*^&n8;rbuC&l}x+kDf(oaaw7Y<+ftnJ;Ok)gx1X)@;WGd&NcOI(o9&+*VgXI7FkFK6yN7*lDJN*IvVD^)E(#88+*ZqF@8Rs8fQTAy8r+gIRz24aZqOfmv_SZR0#~>Yo;0SNE4E3T%B} z5Enx}$cp>|%zXXO505#r5B<&Nc@Ipz{$S3bf$oQ&=DGO51-c(jw|NAe22;;yn@3w91JU%<#)kgxdfY(C+0!0hjfzbt={_!gM!(GbkO+Y~zXv;-R7tM~8Y z&L6)nX7=U9oPXi7vTp%HS4>kd`w0LekLPLG4i-2y`(Vl(2|z#uGX_}DOWEu7tHx=@^_p!8O-(B@RZA+&ZG$v+JYzx+D#_p4>|E7bmcq^{XVi{Ai4SK<)u*Dm$U zznA#a`qpn}FzerJYW2U-^-&|(#YcRt>tW@yuD_I1VD`5kj6>jAF#E63%yCApcz<&j zpM6>WrJi&3WAngV?>WXf=fJFg8;pFRCuINXdFwx2{8WgGFZ>M5`t8IE!JKapnCBGCpsOjVDN7n!21!oWVQTLO7VaNG|lVIjeZ0q{R?;D!_oOaGX z=QG)7cd+~eWFOSYane=X?>L`zFPpvyF#9jo&E@lS22=kfad+__uh{&fz^s3~r}NJo z1E$`n-d6t|`KN-BH-5NyXdkEF?_K#H0YgXHXxTe?t-r~#x9@B7Uk9eXlKm`S2AK7G zf>Afzgn&Ye!;`sii_q5`V8mAS(JlKEv0Zwl~AejA50ponZ^P1PsvUiZZ>pKY4{kkiD_YlYV_2pk-q{|m~UwXH{=QwgT znEAYutRKD~VZJsWIX&r}lz)1>&7b>){_SVD{Na7I-!{y2cJCB%u>{kg>T)!JNlu+ibo5)_M%yW$UvS%=mig=D$Jqr}nsd zAs@=V8O(V`gPFgSYl1m{ z&X?y8>~vg6rk>eg>Zd>F6$N&4kiXckDVXz~3Om9=pO^oaV4N>#A#RL%VE3LA z?G)d_IDvXuf4{{CCxO{d1u*rVk^jN%R*$cTsOx^3W1j_J>RArvd~bsp-^2VPp9(f^ zg8f0guZe$yKjIQ!7uUyrLf+_^VCtER{RU25D88iqx)IFzjQhg&&pI&cSN+VfcL|vK z=HvRH{uzodT<17;tL%ATl!-hFX1?$g>*uok<1Id^`m<(#8u?KtB3>M49J3D0dKsTP zdraGA)^7^*@%(Y|Dbt&N8_fQAeWGsOD?0WGti067$4>7$j zpg!_Me*k8_tEMM?KA7u26ZaGJ7nUsl0h^t_-zG5iT?DiLjbQ5Rj`aq|Z&3W};!nZM z-^ccY-zQ-BMKuAl&I0k%V5Esm6mLX+*h8p?@h=&BKNkC$p6FQlKMJO<7%=meFfMpY z_IlrgV<=+|iC&a}zZDIQEgOS&F1eo~?&FE#H?1ymuF>abT0gSvUWafXv zuFtdtF!g)z^OSntl%BI|94CAQX1(&bKfoSdq_xG5!2JPrvpb4+*!?1-r}$^Hr@bz| z3P#<$7%=mlG)|cbX8m^{YW2?B1Q?%+*d$!Pj8s ze-Dg$nOR`wzhkc-JSW9#@cIYw>3=AG_X@{3C10@kAuq zCw9G!0aO3gWzIiwv;3Qzf7*{==9`AsTaX!7D%9dz+3U0T8er<@JaEW83g&vfX7}@? z=h~Wm0~mD^GQq5;^^GqCQ%^Yd1N*Ph&UiBJS2&+qSG>qL$OC44vT=Sj*(cfkEiC{{ zJw9OSt|a@1+Hd|~>Kg)vS4JuMzpeUzOYghlYhdO{7Jn!H*5ZBkihlz`SHT`I^Or(> z96jHH*&JpyL_5vIrYSMfd5pL|39U+U*!iT37S5zP29VAk{C^(peFloMCN&sXRS zqMdqQvFkClDVY6twf&tvOnlt-Yx+en_56VSg|vZD9W4IzQny|Kl{;F!m5XhCW`LQm zI~aXNd?LG_*>ktZerBPIFMK-8;%k99m+@d8|Hbl$`#dmpuLbk?q;dW}FzcO9 zbpEji6~8RO_3t~Tlj&bF)8;)zT+%piE|~dNOn3U@c8eQ*?D8eu1XItVDXxBW!i&a5 z!92ej%z0M;Lx=AgF!LRo>f%Fg$^JDM{xJ<-GW#RboIRi>nDh0WW&X9rPlD<15!VJI zZ*(&->+Uyu+6UrWV91D^0p>g=&Nh7;#1--W6!y3uz|{NZJgeWlv-z(ABd>oOF!g87 zcbwf-ydLvqd~Y!0FWUV528-+C{Uh}a6W=lp9|xx1C0Kv-88B1))DqjD?}DkfGxi(e zQy<#z+5I%Lhw?SU{-xie^6!QHjeI$`)ZYo?bTaD|!}S8Yx2Wo!HqNQ2d>`QYVm*)S z^T22;G6c-^cntoq=kFEo(9gG~T`d1jF#H2sfT`;m82(xPz&z^pT;U)v=f&60IOIl& zgHR7T3*G{=-UibX{wA3EAK&2g7Y>mB$HoD#$o~g0>iUL*S^u8yPp!eM{|jCZQeTMd zW9{`*LOXFYydFT^fSzFL^S9Sii6doCw%1cBQ^Cx4bDOIdRwUf~8{zd7<2Qh*x2(M% zOFaL7IXf53_)D^1m3=>$eg6k${hs#vC#6|e%hv#mxcrXdin7lEGv8}qgk}5;W}fZ# zdM)_jh?ish6Doq`TTL;TN5M^mH)ohjWeF$u7=sA^UyUp(n5@nEm#$e#7g@ULO7Od@03` z08{@H;%u8oUI{Su&x0Q5&3{ty!+&%02(BdiPRtAW0s_R<(I2>wcJ7a@)_-C}FzWb> zzvAjemXv+db(i1oQ(S-4HTVx_&t0PHaXpy(XD*oWlWti2Q2CF$V|u>8{fqMvr+udT zStr;T_X(KCAqBR+mB8$8+HI#d_JDp~)V}5P1icTY{uQW?yzzr%ubXfA7JymL2aIFb zQZVxsz2@S>*C_s9n@0|r{_kLZ>~j*Bdcwdw&w4z5W%EuLEPE#~+(H}4-U`fmwPg22 zJnR`c`1#BDla{}5F_?OKV|`#x9-^Pm!?a#+$sPy2um_&j>jCzMxR~$6>9B(%(#3CE zf6<@o^}?%Q^b?ybzJJx}OL-NHygv0UU%^j!y~4gPVZCt-87N)`hVJ+;_4?^2^Y>r< ze>poD%=I`0JB|q}#U(60Y>s%l<&S-U*Ke%%h1q>`#mQjiISS^y(vS~+Ia~1hkMr88 z>+?8Xf0Bn{o;W7%0MkDe*CYJBe7#Hl3)dItGa1ahcg5qx-QbTg#0>>gkFU+Ykgw;N z-|u(ZZ&7-E{s~GGq8<={E-*onj5wd&1ut&$pz7NcP$<)!su9y6G!K^nG3>^U<%ASqu zi+Q)meizptbsm#_z&-2#;rox1|GN6ge80i`Wqs?q`srZm-BzM5e@phN zRh@tAW$CF^)A|`8ezKO?$70`6zp&w|lUP$zN8mezj*FxR6E zn0g)qGe4Pn@2j7}){f)<)8`MpLtVc7NHF7HHI5#j&m)F{8Q&kw`l%hAe^xm#^S67+ z`uk0vuj~uA{`vU}^Bw46dS4OefsrSrgFas=72)E&Z4_Tg93r0Jb^T|*iO+jje@%bK z5vTQeSlaGAzZpMQNg#OV+G z8qE3c7-sez^6xO**&{y}{|4q9lEK^`XT-EK{-bxCf5wmU|8=CzClGoV_u{)Yk2=zq zGs@*FXd`>=(XO9>P%!5?*4Wz~%z9hKxc->AaV|b*hvI$4JO6}7G|y#V z=!gi@=V{lC3!=f)f5ZHvC&-@pzV(wW`}hxCzN|W0&p#%(dP(nqskeBX=41bJrn`Fh zZ7s`xWwzyC0cO4m^IX4?KgiyEfvcBYU-!SBVCHEIrhnaqHvf0Q)H`gk)hhtguX&Q` z_2B->>*eSYXZP(5=KTAB5tjR*?B5_B9J*ZhtM+Og+~= zvHIs^Z=Y=I|EuB;eC{~*DwujoYRi_0HX`?|9KHN}kMoQ-d!(P@ zM}aXnkFWSB>XCPAKTL)`*8N`ld)5KRe*fZnVE*f1_{XmkKWqI2Ow{!<91NW?{lKi> z&e-2y+*Vu!%sM@dv+wD8Ou{^HK0Fo7^}S;ADNL3<_Zw#q8V9DHao^iK2g*PFu+taS zPxc#GPETSV*_Zre@e#5&&UW*QBvbF*UtD}%Gce~p?v#s9D&xF!l8VcFp>G5sdRu#jaa_Waf_q;~3Hy%=#aLkteN= z;x~a2=c%punSZ$W=o;dpH=I4pBYxth(;wO#Og&ZqboP{{VCHXHX#Jj5|Dzwc`T>Pt z>U*|mJ?e>VsC?fQcbvrgBlFFD!u>8u$`@efd#Xe|9^*by{PSSMrzeWL8i!1ie|RYu z?^{6}Ro?2&*8M%Ag5~4=pLzyXbnMeZ>$@C`bqIPH%=r~OW%b@x{KTj0QD@?C#aF0e zdinm2`rkJWn<{&;sxCetN%5b7Iq!|KH?QXEhw}Xl>lF)h_V^5OoN*MH`TeRp|BQXI zzX@g^JHedSDlqbRH^_fK7;*lq<$uaJai;uFn}5In({6jtGkKaSLc_%b->~~i8k5Y}Df8Ggk zI2io|(rzcRQHA;cn=u)^2n^0+SU2zGM+rE-Ij^aMLSuUh^= z>Ms+FylGKj_R*uaiw}QO@xFar{(wj@>(4We?JchAb@ADq<^O13)7uctdAfxfp9kUmeg&g`Y!2Q}(%yBj>EEmOn?Hcz z7Pvxu!Z`O6z5o32byq+2O)%>hf5UNBAK5#DaXznw?32LAmmC0Qz1C5#UivXTFO&4P z8~>HKEA&B6bejD8 zK|kza%fttbQx=2S&n%ml?*cIO&mH6Zqvnctzi0DaDsCI=?7kbsb>DZKatO?PRX%j{ z$)R4iza}{L-j=_2lGB&)2>NAzJ|CIB$JKw8DQ^8U?kiuBsb>E}@%O=ynS5HD5byGZ zeP!JJ2B+5KdH4)L)2AI0;G z>~}5nGH-b>kITTwpHob{&N%6D@rIdZ@1^G_(-RzfJBp9Zw)q5#yUekE{K4EmjpsW5 z*gy6BW;^5bJUzcz9}FFdYsF;{&p8BwdAv2t)@u}=S7pAY#!;vByz6=CS)u1+UxOWe zhPM^Z1+&kJVCE|dz2LN2cpjPa8ZNFaW_{QTb~HA7H8Ap}z9)VR3>}^>VCHLrcpm?1 zWZVgQxPRw>Iq%Ig9Ov=(5$IPR>qGk=4J`j|Ti?Q|VA?m^`un~FW_%4>&yZqZ_OTj_ z^U){kn|=Irx4(Qo2h+X{>qULx;`x{_+Kek&&+IAU%XO{(apR0sFzdZI&+<ZpIKM&E5WFrToVjkQ9Bnp{|GYkO7Y^Y{O`j_Gapg^Le91?K$yQ;m;+*{^ql<=-U# z1zX+vMD>^d!JUrdJ@UVp?l`Z6{2T3YobsE;^6v+uPWE9i=T&;I)91JR|8n>T@-G5A z{riB~N3!MfJSzW@#(9ToTmF4u==LUwD=Pm)Fzamx^B?C<80Xv zpRj%yPyg{bmTxMU^-rC4oIgrD>x|`lOa52SI{hiF!0cz*IqSbFnEEE3xA|QOwE9_K zoDbU#rrne4?7_put-;V29RjAFa4_=b)CN;eOY<+dQO$U&`KN9Nv#+COPfP?eKfj9u zaWU_MsqZh?kv6ig{EsW&^{N)X*X+4JfEhpE?EagMLrTKLt#EAEQ6& zA1Zq=7;&)!z|^-9^P!#yF!PnxygGqdZxrSWd-n6<^QWBN+-BlSC!O7&cGg>l^+VqL z7i1s*i`DBQZkug-MuJ(twC$gO>0s(Vf&GU=d6ky^ zKitna-!ql1{*4URPwE~p`L73 zOm8ZFelSlS7=FR~w>$lLUxL|xC;Ys@(Jvm%`nj7eezw?ull8Y0%>IXMbor83f|+;w z2CKhHTr<_>OIQqM{;%-!lKX-A=|4?B-@AiZFKC^u-?QRwcs+pgzE#1jSAC7Em-}Bu z%XfQ~j?&tB;`VknsXE`c37QtOH58vEUGv3^%(4Nz2!d@uh)<#u??8>d~3er;EJ+0!|O%H{aMcXDKpD)`VlbC zzdY0W+YRRWG?-y}Qsv+LW9x5@xTU?`^?V@SW$%Zwhk}`JDi|_yBV|tlbsb3X6M{<-PPnGR;YwP5CZUv|D<0B1yjarF5+!NvRb1T)_pTp3&Yn5~Og+Eh{V@*7?Zp#EyLvJ8!JN}DyuW6j z<-x2sW0d3kf6ACW);K&DO#2!zbi}R&GwvlY@}wkzS#O@bzmJLsQ*Zi6=bt`VoH@ez zhdqXRw5Nd)7FbgH-Us7+P8sQ0^^Vh9P(u90aHlWmKJrn|<6!s~UI(+Et;4L|E->|7 zA7c8(i`y7y4hFM6{$MBl^80|P-`_a(Wia!95M}GpM)9@Yu>94;D3#-ZjRVo546A6=m_>wc;GxKfZ}z)=xEkfw8iuLO=8L71u_8 zaLerk=J|S9f94GZQ_py;KkUg(z|1!T^P!%avM;gu75IS}_ZsGnJOv+@G@g(3VBRP& zkIij;0y@c_i}mCAXT`_CC=(a}X8k7cN8b1=eiq-*@<%Ka4+3-U^T0f2VSSM=I~Yto zSD+W?^ADCV{jb`7&RGp+-L28i9(3*rix0H^J(I!gx31>#B$)o+!XKyO5{jF>H5hgB zRu?n9yO1CC63T&Dzq@ht#mBXtcD;lx1=HT#^d|NKvtEMrhZhW{XNt`)BH!2IU&r+T zx8y}&>M4vgZUAQd^8Ti8Xi?*4VCac%1ZKUvuQ|QG#br-7PB~u0>K*H6`dfpUFQc!U zXWH?{tX^5;;HBbDeat^l{G)x|AMxd*79S2qnz$9>B|U9@s)M;+^}#&;{)p+j5n=a( zbTI252Qz+w_$V0uL9ffd&^Y>ZEUjfYg>%llA|Ng+f zCvk%54P6hWeS2@K_YRozJA;0C{kD?-W0(i`=@Vccn__-A=KS=Z#UHeJ=BI)gzY_C? z{`^s3_T3rlgLO=N7R>d;9}MRCgiHULy&stUd=93b(qQB-j03Y?53T1QFyoJ+9*+K_ zz^s=8eXKK0@!h<({>h3TVf_T8D*ht+MO@xS`M(BczAa$p%g21EXOrUF+q`lg>bqm} z4qhSqGgu$Q7fb?E-?|=d-jT7gpLxaRHv-K5Mt8UM9tfsxZ#SEVSMm3|+Wg4$uiVAu z4}M$rK`%Ldo-ttR9q^*_PvyMG&vr6BN%FtY(fNn%12f;i4vtf9fH~h6+dDnE)wMo1 z+gW@w@o#M%#|#A1e;*jf*f+q`-vo@b$uaVOHPre0PXSZUOD{P8fcc8w*xJ?4TrO_h z()kCk7Kc9X^7*V4zu(Mp#%EyG+Z}BCBMr=c>Nj=y@-k$f*Tl`k?>Lz2k=e-lzXhiL z(G5*cN$u~M4P5=~=3x5YspstJgTT~Z3yiw?BgHG~IRC_W@idR~&zT3No+Y&{|6b^34XbUPukcSs#j{s+;~{VApS;&Er+sM}rZU-5E@Mb*j1ig-?s)tGf8; z5@6QLt77^d1vB4;r)^&MF%QPit7v-v1JnQK(k_3@J#p19w@oaZCO zT)wDp#M6pezboWl6pXOYL@?|BUBvlk&IPmnHZb$dP<+;7&h8m1``Jfq{VRZ3zaAL= z>9?_enePQ3=O4dc`*|~-f1%$T+0*~C=XpF}&ij4i*a!D5ev$YLn0gAq$eW)Ermk1) zd77m8;;N{JJZW9!-xo~(An`D>2R|Yn2!@=vOaEBDieTi;`4&t)KO#Sl1!>|zR?oW{ z%>EWb5A6O4VD{DfUwfV?Ry_6}*I(@GVCrq~w>=N!6@UAeJ^%CynDrLlvFC%@gW2zr z0@rV9WBK>G?Vc}+uPS@kE%PrX`v7|$De~&yre`dkSAx#yFTt$;9iC@m-Xw7oJnsa1 zPzx~YkFn>c;&&Gs_ql5G9tLKA{=d6=IhDc86Mxy|%UgWUxEdIFvWI|~Z-kytdqVay z_B@yG@xRQ!1)lffyoZR7+w){`FM%0f+@2rHtR(v`Jii7Rxy5B)eZl5;@UHo{Hjdm5 zX1`zOI{o3xz|`9YjPvP3<=+&H^YL9|Z(;rkjTAotjCyh9!R$ZB?9q>ax&Bq{dAz(s zcg%j=^um9Q84@UwfTnJ{L{Du<`2Dvzk#WLE!GEl z{m#k0Am8ctJumxMtS@9{TmiHGMeGOUO)La+9^5}TpIRLC$O+hAv{wZ)e_h*uIWI`h z^LJhT%>H2ZUtRlkxcnR6bMZ0nfthb27;d?-@-J%pJ$Rh_H-b?obEN!_;QD}nXg~4( z`_@l8Fz1nq>j`=jYRF#0uD6&{vS-=-!0(#+tE~IW3GpZ};-mL~seh_?HJJH70^=An zUEBoBK3)TJ9>v?_WWc1Z7}0M#D0T+0Gax?+kVXY6U_KU*w2WM zEUSEpc7KR^8caQDxE|o=X(+y8*Gpt``M-?oiR;}=+ymD$>Si~Q|5#jqVE?+ZKYCvC z1|u%(k+V);(i!QC#q+s1@3&q0F8u83$2Sv)+w;E}w{M!hFOE6?pfln(z|iZP1!n)R zn>{N7%z6vJXe%^b{>_mOeu-OTFR=W9o5j&?OrIjo#5|BEeju3o z+JT`X|5Y&c)WiJXANw+x^@`cNeO^(#2hVd;??eAJM{IwLRlZ_){+o4YD}MeVXHOfd z_z7U-&Fd=vOW(SDxy8Y(9}31X=+{3?-}jlO=P(#`eU2Y=_JmKttkc%mFG>FEzH#|{ z62Q!N?rRtCogi+o&-e*(Yy5rz{T^I5|KE4pJZ^$n@4s}@mk(yWJpBFw&tH|j>rUG* z4|(@?XV3UU_VsD5->3pG>)hSy?8&#lobUZD&hGhL{!73}AD0W}`n+qL`-|-1V4U|q z45ps4#xWbk_cz;oXM>qPbCb&#I#}_!8%$qqF!d}=b(~v7_B;4}59CkG&A0khz{nGJ z1k8Gq);oWnRbbBH`;`BWS?_5u;tSTnPJUsXt=BgBf3?cl(@IF+hbtY&JO^g}{mZQ$ z^|JpUFwW+&yS z`Lh0!Jr)eV*y7q>qoD_L3#u!Ab%o2H`2v{z-Uh=zpsVbI(I4mBOZMYn_7f$0^<)?{@$fv=BWzCF`xUN_4Zi4*uApvF+F+bWM8BC-2t=jo;F|4KjMz+ z=dR*^w|V3ygIWJ}lFctd{_~dDye?{9Ig6d$GYU-q_Ye<#;aj!d{h=3i{mX*UM^ZVg zKi4Dgn)!QdKV*LcW`8%(57GoKm%TWceNK~o5&A>E>`7prUyk*`F>ko+)X(`x%U;*| z2_&=swx&O@jW}wd?Oz}HuTOOOBMw}({Qc)Uj#((qoa_2aeG|-nSI)71x`CvyaF%oNL?A+GR|%NM-`%zj2ra`wdKV8-+J>u~fY%3k$-t50S>Z^b%$ z`fTxuajt&k3^4UH1H&&SPCR0)vuAXZf7BS4FX(yk>mx0H?iGvA9AWj(fT^!B7)Rf1 zF#FGa$MhbSy-&2upF0ms{o95)f6q8^e=zk#fvK+p7->R#%ib7_xY#aW*8A*j$4OW6 ztltiAxqR_~VCJs~M!te=_*)?4>rsx=__slre+!s;d+Be5WDIbeGEMdweNE45F#CD7 zr|CHe=6sKJbMDcpnB(lmVAhXs=llzMi7&Kv^URtmuHMS>FID`I z7N&P2n0h~I?&3po!PK*`nX?z<%m2rwE?;yx^w0U!Zsh#EL%{TJ+tBpAFD@Ts_61<( z|Gl28ADJzFy^iS#ylnB0dn~>SnEnH5yZH1$VAk7T!_`l?B>yNd`u5(J{aB#02aUk` zaehJ7oIUoQ*8BUaZvJ7_wBMG2Q762ucrX}oi9^AxA8q!mF<|!B5cOb>=%?#(9rWUK zAg^EA{m~C}hTVU7eOiB!5BcA^&Oh!k_;bAyF%RY|sr$jt^&J<~SH71Un7-%4E5Yzj z>!kQRF#8{<_%fI`b;Qem0GR#cgE_x}VDy#XgZm-Q2TwG;dB?%*_dn|=^r|=&^QXRQ zxWCfBM=h5>w=0ub7ve*Ae!u2J3f?^&h$@fOSAeJIzHchI_^dj* z-;b)`{4>M!^I%aqS1-~F=Df-q$Gt9l31gp!KhNq|eEeg0J;yne3~=$uxApq(iq*@% zr`LZ|z;KHztJk-GAs%&ddWrMOJG;+hz240)YyO2`_B;MbTd!B~{(}9KEbZb0Mu2Hw z>+3kFo!+m^1*2Xvnf`qqv-N#a+yadA{-wd}_rFJ-e`I-amEsmZ7R>xB!SIWHUwi}1 zIg{D{oF~jaO7_)Y9`H~3M*dZw zcK(U?<$nkJh4~6)AC3J4j=v@QHoIR0>;>a|)Z2}nJ#UYAxZPjEkBig5(2@QNnDq~V zIk$6Q_J7L!^RLPOEEsN)Wz_!$+`qsXef9pjrQP2GqQH#5{k*H6xfe`5{cyj;F{O*% z-=6~`K6C&WN1vzKxOoJ<4W^FT?M>fWeLhh(%<8?O&x=xCbR2kBpC=vY;`ICP(C1qR z!(F_$xjsLu)75dnBl2{C;?il>1&4}KoYej~w%i~ddA)j0nanDgr+|04RlcM=$J z{!f8v&jv$JVKA6_+u6^b#E1XB(g%#waqr2$1sHL@6Xjn8jQZhI!Q7wUARqh#mx~Wt ze)sQ7?C%~J@$vlk7V-y{Kk%IVf;eAIInQ?7!A?R*(N4 zLH)y@b)2zB_T|COKjwt&kzo2=0yF=4?azB)>hZPx8(s_lKFIm>!u7#^>*C)VX)gn2 z{g?Fbj|&?*y*WF@i@>la9t5+_V&jM-VCtP>?0-T0mT~rVF!kKBp9lF*;@?ME|7|em z)m;C6+ScshFNkmB=MBn4zN~*wZ4HJ_zc&?s2|vGJPmY%T8h*afe}dwF#?L?G_sj&d zeofpTU=K`Dyr11aQZ~pQjh{E@!+#T)^LV?at=AXwZ(*+og4TeM$7dsc{xI)S@eO-D z5I$Y;?ZKRH448hm@$(5`$%Dmx!K~L7%=wkGpI<2Y3KVCvh9pHI+{&H0hvHTIt^|4GIL z^TiD-+I;tjr{U)r`#GohE4Y8NzAyg$ocU_tevf0oH1SOQJOCFi(7&&H@birIw}Ywk z(UMMYDXD&mXW}`s3FBWO04`yv6z0nR-4U*2n3O z`xs1}L;iE$zZ5x2_P6f4@1F{5qWCso&bPk&D}q_4rTjDhcHifex=(zv(8c@yA^*1c zz9;y5OX7J7);n<5+2j4eoW~9OJ~#g&;zsuUZIS;de#xJ%e!)F)4>0Fl2!^iUpX~eH z^6rDVetnHIi>lsTd><7~2bK}9x9_Jas45<9@I0){NtK|+2>gE4}KBMdNaZ3 zBek32&lu;wCI3Ich)YifGv5cs0n25tW&S~Xz|{LR7=9@~f|+0J$(H>E`~Iw)H}w3< zIDMa16qx?~!8jI-1XFKE`#!J0Q{t8OeRg4w;Q1NOzY)HVkNT6rtRH6IPv-qm&)ZzY z_n*O@e?s(9imvls``W zwK2|3P=C)Ue!Kj;fKfMmkNm6P`$dsIwvwLb`hB0xdpwx=7ob1xuUUBhi}R}cmCgTe zJrB0)YiIX=ThE*Q_KoFV2Bv=i7Z=Aup4iLc39H?FqV6cZQL>8S*Mwvm-K}l zdBXea`N*eWr>+d~X8XS4=zK8iM}s-v2Vmx@WcJiDdVVwu-=EF-b;R?f%v0a&L0iP* z%${`t%zXPkvHt4ndD-PjuD^nEVD{H-k?B97=T$Eznmqh*{4i#{;55|T;H)DIeSbG`M*Bi>4|F~J{M#9*Q0;tZ!*l~ z&x{op19N|pS?|i*j)U9DJ}b)f_<-3*t=CP@B>5K^>^NKAsGIlv0(PczwgC9 z)_|GsWQ60Or?r0H_HgyRNm{=&y0joBq`-P_{(;`wsso#wTEzXmh^_18@A zAUw}bPC@_B={po=zptC3(k<~$w+BVR%d{XRz+)&uzpTZtzOaQ6I``hAXGm_O_R z?ZDJ~p_|SBp*{16corD>y?*-rmp8$jM+GqF zb+faxhdd94U(#$ab@Y*cL$e1=6CZiW^5rXjueb<)--db)fZ2aT@y}q?i|eA_&uNZ) zsGGS(JP3@qw6o&rX3smP_$n{jy#EAKZ?8@+pU++Kh%n24TmG%ung2EM=9Z2N!*2)~BR+dmYFA)xey` z$F-b)3hm^{HEg~+kdN^%RWoh{=G_0NYW14R9%q~x1g4(*Rh)l5nfdNlH2-GevHos- za&oag?6(gXhrqMq_F&YBJ_=_1lja}$C7AiomUZ@oowDyL?cziGgQ;&vNtZvMmUuQ8 zeWX+ev!BU+jy=!G{#9|)TMo>68;iO5ByPn1WW6LXjydbJU)LCWSAdx>7mT{$3*Az+^ZZ`K!$0OUnEHB_ zFnvFXFQFdn1!U%*1V&uKaWM5h1IFpxQ{o)xg}?t5`L6-P&-Xf*^*;Ll@f7PXI$!ZU z#GflZ7z|ypi@?Ym+`!lJPr?1mQV1X{JmKAQ3=fB`I|02xICEisf52b zi(|ok#B+U)fRQi%8kqL6h)16E95DNfwR{=hs@?}+`hPBd%ly5)!OS-XjH9Qfc)xMx z4gG%9MvKql&oBCaXz>Bd!PJ|NzmH3OoxrSL1%FQ$dc04|ehz>C7hG5s%zhVx;qPAy z%zV4>_jq}}nK%H9w4v?9zuMpP%^D46zdzdFD-JphX51kBeP0~C)u5kxzD7KBM8~P0 zmZqohH}N}Q&V#={N4=B5)WP{Oemoe5+>%<4{<2pF)9;q`6Wbch_}%KKz3e?rPg1Dt zpFux$w*vEc9DlzU`7>USeJ{Q#6nPRDPkTE4{xOd)g4th}OE#}w;?iKmN4~1~L%+KI zV>>B+!$s$xSQ<>dz0SJ)es?slv=gr1_{N&&_rEy*h=26@CDu6jnt0dG&R(zw%zUL` z$1!gKnEGA>Lr?NBaa}OZ7dBD+I>f^sSP6`yPX#dg4KE`5^5ZUl+FiZ=@&&^!@*0@+ z#^dj8;~1Z(*J~Y)x%>g=z?}cPKe_nqU*!Ld{k`t!A7l>$bAMzie#=o?@10=Ixzi68 z|Ax4GmaCu9PX6P+clL-Idi{F+ko7kk%=jR2Z!r67lxh8>^EN_iL;-9rMC5dOeu> zJT~wAhri$TGMI6E|Ht)PYU`66srVPLeu(#bfcKA#?}GgFzXWD~yD&eT&%Pr2IMb7w zC+-eL-q_#78=)T@asbSFtG_dS%fZaI9`nE<^bPqZ*gVq*iu>5Sf?or(zouXu^ZSaA zf9v9N2Z5<`)YoP|Bd!dlo_pdQ_Ono`)9s56u{mc66*SY+8pMYr}3C8)f zYPepgzn0nKlf^z@_yxR(>yQ5B%^tNv*JBThPvq~vGJd?-Gd~AY-)u1Zdief)p7{r# zlK*Hh^2YuKX8v%C5BnWVy*1Z3eeV4_?SofYf5UOVV*Zn0&UZPO^;;!7PB{gp|AQ57 z-qA&Mf87R#oa7?n=w;5He@FgXlB{3;elhb+UgG=%H-Op4wMC9YslH z^IUw$cyWI)@`RC@uK^f+C5{!Jo@?td3e5Z;&$9YG#Ji`PzS`pRQ!JjJ7tp`YM90CA zTCZO3JAIKQ#SOvG8RQ41-Z|sUpP#32zNbdoJXT>pP+zlmT>YHE+AkHsC=(f}{ZePR z&6mvjONLp0apEtA+I-f7S?^ge)*;}4?Bj=+ouBuxUU@KdMDX(-`geTW@>Q3_>3}4NLxag6xUos9Kqxc8V$Gm^ae?RmiO>&y{+b708y)@tE=$HO! zVD6tl%m>Hxzr@{aUV;4mbk1)TnCts5m~lUYaZG(wKi>o2bsSU*O#8(V#$Cbe{|(eb zo`OZ%k7J`f;%a`~KnEGc8w)J`VdUf*|FU)$5

*pAldiHg) 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%0AY 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 l@hzNAei=l!FbFrVEy+julavLJoWxwNjPo{ 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

xQz43spA%Ds-uu=IZA`Fg!%`JRPke;Fok z_7t~we%bcZ80Y=32LIaDu=4+09ys$fSbB!O9=P~Kw^zIoIN@KPUynBfSN!Vpy|BXi zd)e*IY1?3}&lv3JDti%@zPh&q7q0O5%ijt4Qm4b3-9dfpb~vp1cYP81Pe0r3AHwSUM7MwVW$@43w1z#MgC)<$p7*J}z_n5}5PV zva9}6zXkua58PhzN644^Ev&flf7(3i-2PgF^?xdQWIyxY;9vAItbDH@9qwBz_}BGz zKOx*_mUfNLCz1QywBO!>wIANF``&7Hx_#y;!JhaLto#RzW5k;G3$b>en*3#7d|J2< zE`GDy?>r;iSC{Y*tp5Ky)9$OwcD|eY@>KUD*FPC1PxMq+`L8p3?453pz&bw;R)3va z1^;4QkCf*gzwhy3zaGBEeV59Y2FrgL_lxt;5&{CC3~tFHI!Zv#yJwCiB`pUHiz z^1B>XfAhG{RsNT{|K`hVKD}Y-`kwn_)#pIxxz|{~i#%mjzH{k4&*L}VY5sbBp!i1F!5+zmRqqd&LwtW&{l0v6$XC+EpTFDP6XMg`dHk2K z{5yF3)QN$k{^9kI)^j1B3&38!!(Shbwfpuf*Zb?Ie;=GuV0u2~^|JKufwlkUz{iyvU2gr|($f>?wy^Z5W zJFhYS!bYsG=96w5S?K#=lE=67{WS!AH+?PGGgmnGcs+1M8|UNR3i)%& zT<>jf+dOk&^_#gpaQr=P|M;E2x%zub^KHH()XO@;|GXRWC+P8|_zmyb`cHJu;CCu? zewcISr=fn~i$32qpIg7T`g|L{w*8;)>#=%oh_5~J_wO&?1$$Dqujjizn*UX>=CyyH z>FESZZ|VME&(`0!(ou9U)Qj|W|LETXS5J5QjWAoag-={4-vMb$&05uGC78|M0Not8xDyqr&H+<1S!6 z^8fH?doMWE`FcJ_jozAJKEIFbbJ~^TVD($y$l|BEz1Tjd9w~79bUxQk-t;wYZ^`H0 z$(OO!?H|MRo%jx{{wMIg0?fJWpz|D<_}F^q#<9V_GRoJx8%(~af3Qn`9G|-L==iB!v&pSzy-CuP42rhf7&f4_1Vta^I? zQh7U>e@3SBZ+x$d`XA)}m&5ocUI;7yUg{B75%2!*^Sv*ej<4taQO##AthztK%KxwF zPbhZYE1Ezepe6pH==bX0M5Np6cAp-@na) z@hkqx-*3JNCV%!ju;Tl|nok)lJtxEH$$#AK&#^zGZ?1EK?U%x_?tcgSiG1nTxV^pY z$GrFX{|wFJG~3U$qy7IoUf_FV)X(qy|A^{s<$Gk%k$M-bx%D>A9OVCha=H^cJ>+r9TPg7`=!8e-Y2N$7kkQu=1z+xyH$J+`lE)fBH(j0aky< z@jWV}tvLxMt}xA>Pm1*aYqEdZH00-dd(8e0%=x_WZr=x^BfXFF@%H?a-yN3TGwk`M zYWMx7x2x4pxEhw-Ir9ow`uk$%bo}M+Uuph%jbQ2fj(+ei%(Dk8vwXfK~4wm^=wFZqH!#yebvGZmgFT|HW3aj1(9#8V0 z3ro)^u5YT>0ha#hu;MR-HNPPjS^WdE%|4Xtlj4>-?=sHIfu-*@u5Z#e*!d+`^-^KQ z&FT{D#R;(VG`%!%MfohNcgtmAzIC_5@?UaIs9!U8rrB5Y3HhoHPl2WHT$p1?8|TJmuRqKA zKlG5Ntg*-c2vfJ>`+F_^e3-Hs=fJA}5B=hw(`UNrdl5!o=^4(i8D}34Yo0A^9@&ph zv-n?(3(kbq-vd@ZXZuv^r_SmpJm!2tdeD>52Ub7J2Zeg+pH4B(zTW1a1FPQl8-l$c z8PZBFV^3`dOaETy<6*`BZ5;j6-4=g-rp@C6SpFShjyaXE z<}n1;vBLeUjjNuArT?fgp}&|sx3`5kpLZ{;e4Sv%lbZvpzP^`H`SY_azVFyz&$!_( z^Ir+euQ#l@HXj!_tBZ31jGlrsozEF>^Ze;f^S>V^EaMI5r_CM_EAKuSeHG8TC!NoCF1Gl{XA{i-Wf)zxIk4taVg4nzxczJ6y6&*@{bQVXj{9GDdzerB zzqeVw{;=|GgEgNUVDLCc;as=(GmbkRmY$95FLV@CjyL~_w*QJt zVd?7&6Q8`w?Z=pZ)fiZHKVd&oC-G8P`o1>Kig*8iV9lqA+nag*V?6#6n6RP)GOa=JQNXC9HnVcYfP> z8?5-#;4lxfSNt^E{7Yf_j(ZGN{{^u2^8>Kz>wEDz=J$8|H&#FKJhxAQ$s7CQEvCo0 z>Ko@_*r{Jr<=n~QOWttae}B+l@f<9DdB(Lx&QH&_d0ct3>AfFTKiy#Iod&b+(aFyG zo_5(kzsd65XzNjS8?1g}%^rUgj9=8bW^b5&qp^RFd-dNL#<$&P{f&gBZ!xTS41l%Y zn%jES9~@==buj1iUWcV`2>sxnxCvJM+vp#A@m%-6cz&3FS-RT~!`LgXb^DtSg!)z8 zoWFsU|1wzl{a($=IGFR9Zco@W(&~L|{>5uy=`XWcdZxqZsa_Aue+n%Bxo%%z96!PB8_d6OIIQ*i873|*4OaaD)I)duWw7)w zLl5U`n|k~crZ?fh5UV$k{*73yHM|iB;Z?x-U z#g%T??*c0Ru^X)3665q0u<||N_9e~*Fm)r7ou6_4v9R=vwf&LZ%K2gTE9c9ey5914 z<@!n+@qJzVbm+aG5?aJps@EWO=~ zqvpDQZ+pIs9_9Wov7g9We+8_5GK^!-hqX`iJ@T6W+0H32`Qw{-{0Orb{xQJ(7g&73 zx3Ki>hRGYf-FYwdmG>_9Uu=)h+Elk!*nW;nhSl%4#?=?X(svH~TkCba`?rSitNNwC zuaE8j>YcFa90M!vb?05=!#}$e*7+aMLw{utI5)G`8|lqq>7T;mQTmT}?$7HTxc2qy zOy3Y*4-uc72h0EMyMw*r6z6D|)8%{nS-mgp^;X&!u-4~V7<8&A1AoIDNO!`g>L_D zjQKwcOW!(P50f|ceOUQB8kc_L_Cc9pJrY0h_*tVv|HXUU{_c&zUiUJr{$3p!IBl)_ z-^btgR_Aq_t;hc_w=B*uo?3Zw}$agYvG*2`yX1b3t-i|f%hZe z)XUwTcb(1qDp>jN>lL`BC#?C5>|y((m-Eup5T7Z#<`I3Z&Es0)kHlG*rrzFFg-<?$Cc>(JyS?9Cx4O6KefZQ+KWhoB zd~IVbJ_nY6-6>&y3Aa1{4?E`*PJ&f$ym98HUY75Ai!WUR%ianmZP7|t{p2+Z`g2CZ z%AW#rK5dl8A7~Qn$sL?ujgIeJ@mlw)RMYc2jLw2< zVdbm0dPOZ^#qTzI>HcfYUTX1WwXpQGG5`3Vjxhh9PM)m(o`2tO_W$Rf!1DhHrhZPf zbNa8rzwUEbx*k7Z|Ns7x+hh42ZSAK`ZvXg;kgqDb>4X z?gv3<;t5CQ^JefbXzugt08_T6Gpzb=yb@>~ zW;FX#ddI=kD~W-n@3oghe58f%-(R>tMsrJob$rzB|EWp!_(m}2W71&h`HlN?v>rV? zzT~-}w`eo<760dE)3?U;ocgr&I}_Ht-YBtn?RV*U3MOrQ5BGlpMt4GcSo(i@GUUsd zLH~*$1mmA^46OKf@aGt}-q+(s|B}@qUy|y{-s^Gm|C{}!e$xH^ zuPwg6>L0av%y52UW$;fO3aj6CD+1?rg|!~-mIwcoc=tb481zPdyxQ#5W-s~}R=-P# z=a{t}mY$=@kB;=`VClI9CT+@6SoLl*&RyXCjf^wycmE!XgMY@U&Lt1oe);k$i%;YJ zJ@S^m=KMJK_fa?DY3Gvp7XR&)R(~}t`xnml!RW2~3|7C3=7xOr@|XStdDidI|XP zsaqwzs&{x;@UOeh?a#rSujm4+|Nh3AZQXy-P^;g<{aYF*$GZQ)NXQp+g8P35tKQ-6 zRxbvB@~0kz)qhWm~+<9=ezYoYTT=7EfqyI`F^i~EOl9Ot|rCSSrRSb8I4t^ezt zABFKR>ji6m&lo3P>hWX8nZEtq%-(W*;H34i=Cc4MZTv)7`AcE)MFu%PYxaz5VfAw< z`Ebj4_cGJ_0QESZzS?;;dS$;GmY$v97XN%^uqU1YD}NO%zgSqu z$6)j{{E=+j4_16FEdSR=o4pFw+&aV5kKf_;CZmGAdZOE#j|}#raWH;SXR-du(*u^y zCs{A$zuNs%Z2y#Wf#vrd`;oBR#vVU1!}PDa)b!1S<#!{j{BOeaQGAheE8E|3e_mqt zGuaQ+O?(Vi{T$mL)iYrA^A1d!aRX)u zw(DosKv?<5+#K|k9q)Vt`;GGrFJEN!X0zYvBYmFp9k&0YW;risKdaAfu<~7DT+kMl zz6!3V%GV5*-?3cpIGy`LNAo{xka4N=>Vcu3=qF(LKRdwsSq7`0q5W+?On0vBXZc4t zuj(5(`5KrxRMz(}|Fs=V&m7~ZM_}c<9Hvg}0=ExM4fXO@!-^kpb+8wF;P%?9Y`qUU z@43?A7g0}o$950(tKW3)-Yxj2z2baS*T7kYu9y8hPpTqd&jfbVD zGyc>`9|UW@x5L;Iy1V~t_;b4E7`K1cCHU8W;{AM_6znN)!_r&PG3YIP+51`1!ScNc zYdtT8IhK9u_7BU4$G&+<>g=hbRHY;W9?&;M~c<0$7w zl_6i!*%w;;TYR37_~>bgR&SMmp76H|EdC)rPl&y?3YMNt_W8n$O6P;H&KJSb-(Xz5 z0G7Vf-ZlGVx5vWhDe4bP_k;N37t4z@-poF*{HO5w zNF6)5|KEJR5-e}-_Pu=mlKg4s!qV3dCVz4Z=X31ynR&8H?<3`=Zw#z@|Jdh4Q$K*! z=Uv8`HEv(b=SlHP*al0-1AIP}Jayl*T(W?^F7_z^PhE|$md%L%a{$T zek)k|#=^?i@9AJqY3|$-mX2@Ew|v)`y=Ikjrt=KvC(OUPC#?S0!04@Q{Qq;_39#y2 zf?YaxBv`-2PX+(fJXrIXzA4xfPj~xHn7pw^w>JIn85jK4%KS$ehwrLU-q9t&zy2V0 z>3Qi%o6jLw_5XV!)XVJZ`SMm-{#mf>f3LLtF&mbi#VZ2ybI?}*#pUL|%(;JI;OqkT zzvGd>rE_8B+r{@KaLAYmOV93yLVsyJJ-*F6t2fX&KR5WtKjge`TF_gu3znX-#t9$8 zTBq4lt)C-245m)DSoOc;^Z%MlKhO8PeIGzvAGeT{QZ@D$(OMc1Y=Vk^yCGWt}Kg7O2pzurg|L0~~{}X&a zj5W@04y&IZ`F;WVN$l+Q3RwMib)LrO*>Nk+b^kYD{IeFa|5R^YM&QbI?02olnK0)g zjd(n1P6tPY_?nab@fC+1zw|R<)jvQz{BtI{{Ur1$&lI;mPru|TSp#dH4`l_8*#oQo zg?C#0WBu{{^TZHedL^tppH2!~&<~cLb(2HAvf=K3I-jqX-qFr?8YkcFeBSgBUp3IL zcYR=F=Z=GwFT?EFv)w-DUh8**+iPc-o?2LXeu34`e&=J^pW-{Xo-5yB?DQGE4Ay+U zCm-kYx41o<{R*eu=FbN`rv&}UJ$SxQ{&ZN!H0KLo(xiwruSe;R{0UdWs#nN7I3`}? z_6v;D5@F5zZ01Q^+*R)X?mfZ3?ppW%o9`rVFP%WkmpodWCVTz{JLyLZ`op5o8vJ6&csy~8UF@&l=h^o;)NX|pf0^0qzwp=d z5g7e--+26k_V`X3=zovwvHhEs2W$TSnV!ref8YFyoqFlx`1?op*T;o?`R5<`dkw~3 z&>NQC4KO-VZ}q>|ZlNF6EBPZ>>-{*4Jz<~Q7cvjccLRTKD*tORY2u&qzfb?<@uYlP zVf7!+JXNR6IUiQOmF~aG=3PA#mfr|pp9kIkI{SswDchafu%F=gTIZJbc#Uo8e_#KN zKf0?s``_1tJbt8ewC%r`sqX(P`;9(go`6+96Fd4c--D(9KJvrSiM(H+es@^C($3C5 zn7y_OtoVOn4n;kkm)Q4l#MQX}W47O;Zua*xI$FKjeX!zN^Z21&-jDu%$j$b6s%ymi zEz+}}>ydPv;P1zrMm_O~ZXa*+tvKE79oP@b`ys63&$d6)$N2kA30yy^SFs;f{(tTI zoc6Q7|8xlEeAPi%`=OOx&!d|1ewy-4v+H-=dH#OelXkt%xWwOYi;N8M*@Ixsb>Hxy zH*K`@m|?b_OJUXTHPrlf!>V_DB>30$;r&N(*%0ezoWEbW&Nw$0mY%0z{Nk27e{c5q zZLsFlfqdvl-RtoW7-u%P{X45yd7QtWdM0{Eo7>2_x9dB?1*X5~u;*Jn!t%Ft|L=Sr zx4_c>4bM-SLv!BW)v^06wtj8>{ovs+^~$@$>SwOm>+W!#2P3ox*?KH@-Tnme(%I`;tCvT9;_Bal6+ixpP_H&R)$ILX{Ikx4)$jSR{M)+y z0gEpf>Gn3JH}g(db#Cfz^IG8cdh{s%S?5k&L%oET-2d}S0!M!gYknQOg!+kR_b@$o zbh3W4Vd+`gAQ&s;-{MQ#1Ws)>z~bkhZ}aU2OYe0FrgyU2qhRtDKMX7X=dA;0 z>i#Y97sj=FoPU8yQ`Bal+4IORZVgLsJxpA53t0U`p^szo-^7di!}!-Uz#OA;+nc^W zosYUG_!s^QE8i779>|w^wAVYBWb2s-D}HciTc1l{t>;RZI*~qZ-wboU;CkoxVdWbP zOV2^(OP!L*9v^4(Z}<;Z{c;}f_{D8Zw|>`L8R9E`cYYnlUM5z)39PUBKWC8fuP`!e zl40fh!MLb9EWLw0ekrVe`lQ(P<2{dWY5Sw$Uzog^ySd(wC#K6_%Rdz+PyIu%>`xMp zz3vTI`AV)0oc5{v_u=}BfBN6fLwg0ic`@8ysrXl6;uFt;)lYh#;GZhyP5W|tN$z*|LTvOqj`O#^*G@1$D>z%Kf3)@>p!j9?Q@wA z=8P)mAzZJ>7dHpySok{gSNsgOJLk@Xb$$_c`bm?&c4mWLr?CHY z><4Q;H}U+0J@$g(R&N}S56;KzfaRAAqa*Smto*0K9LgUWVe>kV=P&6!d!+GTn7Gug zu>7w!t{4of-XP+!Cmc1(?8n&iPgWyX^;)1u_1nSnUus;^3D)|&1CzGqQuqJc?D^f? zU(ZkE$-5F({o%YGfQvI>&GQF)eG!%I{;llsR5H=+t9iT=mb=9HY#x7b#v11(_INCN z6IT8XJl@D3-2h8(5v+N2$}lds$K(I~Ji;61pE?=4^n7TX(C9|%|7W`%BtHVn?$?iu za#;PJ%6d|^=mWRMU-N&sI`6ou3-ABq2sN*%kpnfwb#vfIa*zubj;J(Tl!F|&aN@!o zS1nwiDK4C7N~Smp*DW<1;UX6<9Eqvqz=;bp{k>l293PL*_tzi2AJ2Qvd7ale@An;C z;a*{nFM4Txc`)kyyMyWPl3ovvFym`r#NB^_ska}`cg%0qTl;mu{U5i-4m6&I=S!ZC z$zbYv==J71&3FTtdU0UtZ3FYT%FR@SD9{s!3pT+s7-$!8fSpr5p z=!w-2QjV?|ruq#vKct@VQ@y@2n}g}+02uxw+JQOuM-7D2ezy2yJYV7Vq(8v)S504! z#dYbY{X18e{UjIful-tpp_@_~3^~8bVAMI@2eUq^n(Fz1>Aw`1@z22Yvss_dGx_&S zjJqo7J{DMfXa&)aS`McEi*l+LZ`=orx^yz@>z5V%@K`YSoe#`;e+08%^Y?|lDh$wg zH^h+^-w4e3M(B}ygW2z4dFh|<((+fr5B&SqAE^BnC}%Y_-VH{*Pc!2|6{S9G5*W98 zRMPo!4uiR$uXX;wGJ~{VsjA{HdjObzhUxrVCVb>-|@VCJ9De77H%{U71=A@YOAfH_BA>07jpb&y4ez)_xy? z>F*^NanGAJ-+#ECaJwT4%>I?3&-i%b_J~t2$heALf3cr{aeG(;=yATz7XP%Q(hBMII>_pGg4s6?%=38;jH7p=M z*5K3B<~;_6kE~H(>Wwd=*VhJ%r>LLwyI|_x0i)hkdYJBWsp*FrPjyHIlV^arkF{^Bzm3C{XMmxTc^J%jvI~e_Pzspmb9G+z!@r-V|JYpG ze;}CsNByVYo6z03$_x3P1n&Ws{}mX09T8ymZwp49=Tb2Hwa?M`8jCM`F7=UXjh{W$ z?^*aB%zl48sUZ6qXYpf?B_7lhOua4-<+~GNZ(&~g{rs-h?==1pjJ(JlwvTtg7&G8! zF!k4D35OeIPT?x!Zc=ML9jb{R0|tEe1N%J?lX(p+TfC)^Ou z$Ys3js^|y0asH_{HAD2gelTu^@4Z7^Ag>qtX>>~cr5cw!A{-wHX8%ivWnSO$V9sB_ zxEGlH-#Mgy+gp9+L7B(Rzh7s3AHEk2^ThJ;g#8|Zp&OmgcoV+&3^qgCf~o)1t@E6- z`rm&RPOgFZIM26W)H^-`Gv7G1zVW*o)&C{i$G1P~ylw1!ezjKj{k5I%!9OSu0aJhE zYGLo8VCpwnrSmh+eXP{)sS4|5`M)k#|I}lBp=CPno9lTczQ>B^bC~Hh)bF(l8Vu$> z#xK$Nc)f977xBGS$dCBU;!hXqJ{uS}ou}N{xH=eZ144|0=ZfFNxnTO;iSKoSZq!9E z=a~zJzSlJ{{gwhFFYAuw2jF{{$W=yYJU70FiTVw|tiLc*_53Y93ye9^TN-EKdyv?# zgYi*(&k^(--Hq!^ll+_kV9v|$Cc!afFqr#z56phUEI%85=(m1^&a(i15zp9R+y(O^ zo|FYEb&NxQDSI=+6SdD*z`#1H6MXLS>VEWqzrcM(ueem;I*nfgP9wZkU zr~DX9zd>N;XF?xq%n1BOxtX$S4w!x_gOL}t&f*_{p`XLgr(rzI>YsqwuOj?IKl>q= z=jYT`@f)3O`K9%H5j~5H*Lcrg)z1;DU$9&A!;DMp)p>TC-)J!Wq(s|1t@lYhq(7Mb zV)gMk=q8x{B9H05J~BTCPYY*FG(TUS)BP2OAMT9|nb2Zj&eQ0;_=_EF+~tDgCwNRy z{rMO5eD*aSbV>a9Z!va)xxZvE_1&n)F}>hK`U>lhG=y6iwIY+EM=7i`aUIKG}PV5VHf!>p} z-Z-ipnEsNFtNt$InyAM--pR&&pwD^t8~<=t_Lue&%=zENe26=1x|BQqrM%eq;T83F z2~0mn@cfNKMzzVxT{Rvz3`{@G_4z*YD46q&_*?W+@=VeEf3NBJ`w-0jx$t^{^MzQv z{y%!Yf42BtF#V;2aSYpcQ#kXjsjBy#zFu+n0JDD&yq=-%42!>q*E_6R4yK<#Fzye* zt1UhRj5^0EJnt`9{&B)9RF=feI|%x~XUlAlrtOg~p%3nx6W zeYEh<*Pr)||JK)^8S}vO*(|@rQ|p1*udTlRb@21PsMiOtw~?3m(9TEVyZZXKqUjYY zA+NvF-f%T4l@%}gT(|Uo~{{`NkX20EFUQeElg}ts@d&GqMU*G>tyI>suiSFkS7&?CKf>bZt>UV&l6Osj{{?N}g|5vLo&|dP> zz5>%e~RO2H(rCn4-!A=J&phO``}MB;&a!K}#(=6Smb zX0PXqtMc}Mx8GLIS|seM2&V6P3#*EUCdMb`i+*ZXFy}r9#xb^=@d7aPGP;A=FE&;< zG{Wjv&lQeeWBKnWyLMQ9_3y=BAPHEw=>%pT|QO&Q3>jn7< zoxtoD4u-B{IGA%JfpL5Gw_x@=sqw5C#y7M+lg#-tl@nsD{+&4KAF>cke_^;@p_6se zc${9(&NQq4SFiWPlJBZs>@wL;z{kcpVEFRx3Z~xtKk*(DQ-9f}Uk^@D`~ zvYH>I?A0C2xQEs!xWU}-wXL$R@O@zV+yX{k)Ln}&(YSB5avD!pPW=*0z31lleIM<2 zZHMl+7nu9HxKq!^8Zi4+aqB*kEPwfL5)W!rUgNKKNxjcRFza9LmU!w`i$D8a{d!l> z{@eCyek7RtNd{w%^vTAj!RVVtX8$|~BtN4_Mb#gdB6`t#jlB*^eaJm9=X-ou^S`O2 z_3e&GzGE|(`|1ovp64kr`)48_zM~sg*7~E$j=^B|-vs87zjw|0BVg1Ao;QA=@uWgd zjW>cmbsHIn9M$?8VCoD7L&xpJ?@e=GgTP1+_!>!3@=et;}iarcw_*WzV{vzzrkZIzVf*4XE~Vl zQ%_31|8>jXbxQn)7O1BFzDUz~y};CKd0P8bHSTdn{kH>CFZ!(Njkfwy=OjOM9+>kz z0CT=0mOt{mEb8$Q!vlp=V0VTjWTWthL5Zq%lA=E ztmdozkEniRUodsQH~q=RRlulsoHZ_Id;?5BCBQg(=C7gkZz)HWH9m{^Ae-?inE6>c zZ`8LIk3l~65OKk{m-_cCSX1+hU66gatAn{uugj9}HQnN){}O+`M=f6aiu!#8=6=U3 z`%NQrt@Zr7HP&wh zqdp-F%=}AW)Q1cObAHe3lApZF`1>0Y_nu?-r-5|ev;OLd;GdSLcn3r1N+bBmAG zxU-klpMM~F!8?tAc%=DHE&nl?Iv$vZ{!_Ar9r=yNJ(hf*0$}?43yisU+4`YjA*KZkNiS&L8BemT{^?B@Z7eCUV9`OIHK zF#Gyo9_Zz~`8!Ov?kD9d#Hrsx_ZPtHk^N7BaeLNxVEP?^{XiyQp2hb;AAMta|6>2P z@P|C78%({+|LXjQj6eTR_xGpqcdzt%K5o1NjQY%zVCtp37Qf!YW|eNs==;PPM}TpA;C!q9 zpsw!c2$=eL>S_LQ%fF2{`h;9Hu7^1LW?Ftnf0;kp%ly`Ar2blfsdv4pkNKU!(DCHol~Zq3H{pa|E#48#{EJ}f z{cd{qjla?Q1U??IejpgK8TE~?q8`4z`FHX3zq6JW>$Ud?v8CM3g-!|jnVDxbp#`7!vj8OJ352pV4!J_9i%$|RbDW^qP{@-An z*PziBUo%wl<-IA^w-_dVodZlSe7Igu&8>bJnDg>;1~~6#FnkC5fO)-~1mhU}uEqZY z!)IV_tG^ea`{4bb`42{le!v0a!DB=}E*?z%Z3IUlb__6wda`XLwW zdObQ#^}e&~`@blir?Oq&o`_?vkaCva08HI7U>>hS565ta!B`^(&e z*R!&J<%Gdt)-#UN=&EZR14f?zNA~)6!EDh_^aJyJ=l@>MPjlnqb0y#1%JK)y6Fr}% zVCwG!W3MR2Kx+iF?2KJJiV=g+oFRr=O(Fx}T4&zQh*YcWsNG z216&OhQ&wzEOAF=F!ej{QvW3^e(DeP;{eldK#FksyT;qWu<3e^pZ~b8)ra(YjWYiI zuyQjn^*0_-e}CK0tGQE^yBQY&LodV2em>oRe9V=21wa3?{xbZaPue=;dCI}_jD3~; zBEaz(Ie4*)RB@@jd`K02q@S9PlozN~&6V8&m9;WzUwyIO! zbCfr(b4TV&i?H{%Uf&db|N8d+*EulqQ$8{-0mj(L#f*Q{`7)p3{Wb1m9vFQR|FQSm z=7KrrMT=*Ek>-;Mrk~d658pWn#tq;P`4QcXTVfvMWi_|@H9Bu3-w$NJZML5>_I}|k zF#I|Tf;ne6nEjvG`;T*NUx&c#zxAP>j|h7|a#OZ&_{U)C4|^*0*?ElL%Mty+llFe+ zM=!*`I~mOU%`Y{7vvKoRy6?5d7hX%g_rLc3>)*y%_Wo>)M|JUi&*CF;Ri{s1GUvDf z#=auo0du~5xvR6U%Z>McInN8tcg#25sQK<1V7dOl)TwIma~h9x8Xs1UdfwvE*neqZWC$5{S~@~XcE%>Gv@3wvi9w{mK{ z2>fuK^~&BQz|_zCf#|v3vv@EVI^l1Fskchw@z1RPB`|cnu3G=vRdn7MF!eTr5l`w4 z=Dr_;adSopn0l3cbzcpvJ{FAI6F;*2iD1-6@cN|RebvN&Tzk8ITvdhBm*U@B81Dgn z?9KCS`}dbX%!hvQyX@b4_E!}BtTABjw>KDZpNSS<4(9Ejf$8tA=7(1W)BiRwjv+tW zzbAFle9ul`=C7_GeuK~3zemM@IqzOD;|rBTe+A=qj~{V<;5&AR#jESS6Tb$t-%ZSm zx~#Xs^tDL$;q|-yd)Sg%dOlBpssD$cuzw+|KiWX&FK6{#{3RYq=Dx->()pcW`Z)+j zpQwsff2OI<%l?di*+S3nY5VuLm0@-$5=eAi|G09HV*75`PqNk`N|h6?3WGZ zelIC!SF-D&!PgRxZ3d=ae=zie+S&PUp`6+Q%)TLDqy>zy`n_78_M_#u>LvAAM=ifr zZ{24>yFSCg+;?#>^{y)?lrdi1NBl&P>F1vTdcNKRbN*pNwf}4A^L$Pmrt`isKYfNP z=S4o_`$q_Su^;uuMyQ_(7Oy{2{5b1@>1XOF)ep7!=+RQ26b0t~@{W=Gl=T)LK32Jb zJ)W0~lzhKKVESzWhOX}^iw^@+Cml?GXTY%K`U^~dqsB>n>=ldu0Y<(%157=?ZzMnd z2AF(f;Wj z!R+^1{RMw*Jbi-r37vq)OX^<-LoaHPJ$^<_l>T0BF#VUEB>5R9!JOaIrRRgs?~E6m zEcwBC?D=aO7&bx+fZ4x8l;o$E0y95)y0Cv$%kMu!II_0I?|{)Kwjr4PhRoFS(bn=O z&XWANp~fFYtG_vx{{+lF+rivNSd8T7Tm{q5QRTQ-mhU-7;^|HC{K)tUFzTZQfT{C9 zIdc-2dY^qS{gSua^Xc%py04$CK6#$bKga3^#7aD3yv0Y%mwq8lz?|<7<;Y|3!}F10 zyutkbWchu->>mt$`EOpIOxmLH zT2}vZtIk{7_}Na?s|jYma=Uc?@)n;8hOAE+i^pqRe&2!lkM_v?nIGEy-}`sTk1uch z6&QKxnRq-Be_;4e8v^FO=PO542lM>(1mhU~mOXy8g+6b8jOPc|f1E7r`?0Zeub%(m z_WTlZK9leGza-zC3g&$GZc2Uz^~jm`B<{b^c+o@EqaU6Rj~tDU1ap5|{?&LN zu;xD#}-G6@Z754iNanARC9jVW`X|FF@fzdaM%=i#6 z`h~tQ?&qiHqrTnWQtN7dpgmu^>WNnl``5O| zyH#M^o=^kK`R6rOe)IVEMN{qf)av&&(|SH0((kdB!jYSeuYqyCBKCl(ciiIpt^R4C z=tbAG$JYm~B|m!rnEvLsk@=JP`&8sjZAIUm-=2R4wG&QnW6wXcKhgarfSDijnfeRC z^Ox-N3(@najQ1~ifB3Gm^mp8}_cvyAk$8L!ydT2+-C*c=wzc<1E@?dAb9?_J;VbDE z+yw8}aK3guBtP?py?@iMuj==+_m5hHOMX&rynjW1O@^ueIre^5^)c!%4DX-ueBBx= z@yJbJ`WgC-?!T`L0JxeaLL%(ere^FfjE_ELQ(@tiH?& zsrP%^^5a*EpVSxF7xTY}m-FX51LpiuVB8$K2~0n4uTp>0EFJ=ekHkoeSNlQw=hOpJ zuTg@;eP84JkYBG;|LJzVS|$nyCxbapaFXaJm$SHQo5UlsasKJ2#18Qn^{4TbovQcd zb5slNl77*35a;#XYLD*srd?lo52&9MyZ+XtNPYI)H}S(de@igy?RU$w_uKV5AHQpk zF)}8D>1Xdj(Mx?`*LyWE_LQCu=DrR@1?Pd702dVrB1+1B#Q zg5e{H?}yTlam3pezqU{6v!>Ynb#=1%5A(45>o73&p4$DpvBskwg6Z!F_5R#1%|JLqhR_Q{hRKGzaPo^S-(ntz-%!6)iVyZ{I|i#^S^G7KUr?cciphp z*KRP*d(Z_i``6XD#}+X4!naF2G0Ps$n&SH4?Nz|c&-q3CL{$Rw_Ay}Sg;xagdg=Z38qEGr?D^p1pH;sznEuOwaR?~%CXRgQMnD>kQ{`i#* z;x}j$m^yLT7y1MaHXd&KBXggtY~Pc?)H%6U`ui_79$UJncoM@dAlr=dHsUG-2Vp)b^dhpV?2Gn?q@HU@tR=ndk2{P zx6KnyI%EDK=1Tvt=N1qAUizihfj;xgf^qcv$oi+v7WS)T{R6?UolyeJdCtXX|9lp| ziRUZc?zVoh`h4fz3{1ayz?`q3^&h0qm;QI`?+La|lYZGp?C%HmM5+E}Fz4I)ozw@d zHcrFyJ^Q6v{&u`R;2eI?XZ|M>Rj;-A`Er8fr&qK7g~sbVuTanP;nLR|L0P8fKTi5N zj#h;3l@xsKN_?7z%@71^0EQpXld&Zhw!_{cD})68>I;^~HKfzku^#&O5QY=m#D(uF_5Q)`98wZ@hkk zt>hJ8>hA)hE^Cp+>w%%`o&=_TvoFy z-S=uR`xi%?^RF`AiPx9t6Eef{zsEfA6J5jN!!a-NJw3tn(*^s0zH4z|?bmgH&RfrT zS%1;<|Mwm3cQ#D&<0HV_Pg&*AreNxM^wE58Fmyd4dnw;5r193e@3i$`#@mPL`D|eP zjqcmo)uH-T!ANtp0&~B)!078}0%rYPoDcS`XZ$M|d6`wfygd&XX`#8n^gBw=PteVR z8Xt@Efq2FaF!#APMDwSBsqcsLL%p}a?EgL(c}Wl6RxYC)kpZTDJuv#_Y%t#2QS^Kc z7SQ||!4h}JgP9)+hOXygF#Q@wEii75IQj+8xBP`2gk!^u8@AW$ClE}3iJ$3ys#yJr zPqqL17N4u^DsA=YpQv9l=S^>;=f9H0pS6~_KlSLhI~abltAXkFZh-dt!s4Dy)lazb z*e0SEHV91pw8o+r*W37AFmBFxQ-8jp_N#?B=P6Q8G#vxI!{TfFARon|6*YJ-%(5FDPnxGrf||bVCwZ&_9|%c)EeR^`BgrR z8+-fFh>dx5A3b#b^aWt<^CbL0HrZudTm2>tGybN!_)7>i zKCAo5_ykNp52{Fgd`mF>9C6A%+^xa%bEC2{^BKQWN!b4jF#A^qGB|(qTdt_|j|{T&Ii`rzXM|b24w&=u{L|m{!V(XdW$`72)K4K?U-Y-I zfL>1n?RqPx96rph$5Hup-r*L%l27VA2V4Cx<*+_r?q^kA>F2@gn|?3k5l+5heySpl zysT6(`_I$-(AgH>494x=k>EFaI3~8Wczw;!xMBNx4t?aicY&$51&sOAegLz7Gv(|# zw$DoTerQA<-OsuI^!?Hv#<>tjeMDI>^%#dvU;&FC()U+$zRIoj9$@%$9Lc5mkMVvi z>SL3@>|X?NaPWLEj($DBxZQIUnDY$><1_^fxB5f+{%mM1Fwb9J51A*{Y4MN1sEd9V zOnpCPM=mh+Z=oK?qsfwv_~G0Yjq6~)=;tg5X1@ixf3KJSs=sw$Q%-6P=Kiz6)U9dp zPw;q8|L=f#`+a5K-=8Q?RsDbmkF~xi82P?QVEWx)^T&bd?{Dmfw@gCH93wK+-++-@#MZXWm`q&v1W)PKpD}{EGVg?VgyWemdd)jhi$6yrcc<>HR%? zFPQ!-fO)=lgIS+XA1}h{fVpo!Jl;@$`faU0q>qRG<-v?+;PINr?`|spppV~KV~neT zp&uItX20T=|F!WwJYRDUpE=!1yk=l7Z1!7w*#}^g}=4FI2e0ObA!3h za>}tk8PC%E?qK%24yM0WVD95R_`@-wrm>f@vjUj_7az^h@3krtdt;@jH$0;r9nnm$}|J7vf;&a;xtJ##~)jtry*77r{z_o>J9b<47na}hdngCqyQulsZ|Q!H7*AC8+5o2hGW>oA zbvuKpmm7>@&IcAB^pE&SEeNLne9GakFR1?V8=~)Z4NSdHugSat`;GVht><^2@$wAS zKL=*N+gBu>nE|Gc2xZSZ7B2!up7#smahD|D)5rXr!0)&4I{VoCe~;gPVSW?icKZ7; zS&hKdk3T2z^m-OwdRF^8Ej|FuIV*yB`~*z>3YH&>-^bzgP|0}F5y_8Wf9B7`@9%Jb z0T$1T-~VCXX2#L@{UESsQ!sU>>+cVx)v@}2{?LBZ=ROaCadeaeQ)jZqeRw`tAFlDN zC$^s@#@s*Sef0O0qT7M#?>HF#A}biX;0Lz{zev~f@izQ|v#*1hUj@v0{{plB7%=KX z(u}KOUc|F@8V>=ZZN^Vv`v32!=y_$FS3fm%f6)iP)T<8W`C4i5XUIpL?|9>WVB|TQ zTK)vvcYZMH;x3{e;+c2OX}<%u-<8Juun)u&dVo2PYoE^l`mFZ9y+`~d#e(VgBQTDM zk;VzTB|q*9dsN^1GMIJmYX8)|7Vi$f)Y)X5y-W8M4d(6Le${<`VfD-1dj8shIsXSc z)PD<$zq?iP{aRZ6nk{<$d?`8jPoN7?-cnEjq7NWU<*)w`5awi$2!LHDuT^5a+Q z{$^X;3yisf#v7-u()d6y`zM02*NApt&OaB-n$N`5fw8UJaCa;Vi81Ea5dl;!6Fv(Ffd{}dhy#9vZDdwj?{ML0XRJ^t*Stn3G-A0IIG72U)hkCsf(d3%EC=gD~S>m3H>{`|*C zeZ)2}_wwH;iANp-Q!hP2{oOWRI70LjcUk_j;oAQfFwg(*!-SJI80Q(H`m2pS28+J` zW-#@ShpRsOvwk#~J`aQGZ!8$cw7L=UkKLDf7oe$49^z*d8#8Zme^HEtaZqNP{%=&`L zNukC~!Dy2)3Cw;&lmng_7Y4(pXL&qdGVTPkUywbYey;J%ukHEtkk-2*!Ss_3f9RXI z!nmN$ld;n3_kihdp|PEh*im5i>xc7$ev!kBLvjAtzlP5V&gwGp0mU9=WE>KBAEIf%078)e+|(Ow+B_XeY@ZX`u=UeoIe5n5%=wD zTxO*9Utqi#`$B(LqSYV7K2aaJ&El`^{zqp2OG72!gZbq5z})wG%U`bNKW-zK^QP+k z%gb%?Q@Fptm)AWo_j^b=?V-g(_5PPp&|YtrKt1#7+w02!y}x_&^(XgO%k;;CnRiF) zLl;{8486Zcthac6<>1}MkI^4GA!N?e6U=>_1XI5xu6Nw-cxr6-pOjMe`gvJDJ->W? z&Hg!k#cx7&F!z6@hv=u*w0J*d|Jq>oTiIRo!|NJ9?WXyBz0de4<;YL}FS|bjv)_iU z($6#0eqKxNtbVT8&vW&Zy>cvG63n^&1@ruPD|^2(Zre%xM3=V2i`ImWnE8$BO$to~@A==mjD{7d}(Ao@o0{RaB~wYm6@EP?kc*ne&_>F3eN-oL09 zAoa0BE&gv4^}o(|Tw|&CziZsOp~RDe?ERI5`kH?g%zpdoO8=m`ct3{yc7CLO`q}$4 zsdYrpoo?~w%IS|RUI~o(osYqszm#!~<=?C=dWj$4{UOGif^qb2Y+S6C?ys})of>+6 zhJfkE*H`stTYOhF;gpTW=c|fdP70XkZwnZHQjQq=D<_<{{QXsAe%Avq&)c03#Gh|v zd;hIA82-{f2Xj9|E2+PI7OxLRpP+-r$rXjO(!iXrcm=5sDQNHiwJ$IAnN`5-*W1U= zhsFOcCmi1s%znRtk(bcN@~^xv@zCX#Kf09Y`~PR$3yd`dkXavMoco6QiS^cg1C8GY z)5mcz_nTWeA=~0-N@~C6cz=_5e}kdxHN?0&@-e47&Ul(~+zv43e+ou^#8EKM$M5F% zip8gw7Jb(pt1nwdujec<{rHy^e^Jb5{oB|Fj*h>K>tTQB6L}TPd7tP$1E|OPvDi1_ zAy2{dvq$$I=wa{QR>Jw=eoKR?@2}^}yAGK7@7wtcviL64BQHD>O#Ovm&Nm&*{j>(- z=48GD=L=$7V(DQ8yzQ-6zcY*#S* z&(Qkx{+2)UJ()LXi}6!0o&PA9{anh9i(vZe@{ah4Z*TuTP!!C4bq3RK{X%+vMu3_B zqM+_C*5aezR{u%HZ3^f}vT7@c9++mDu0-z<>Jr9_zvMn*c^#=0>aUfX~l>54XSl`%0lFQXjqCI31tA zfw=chF#An=q@M?J5=^~)_&g6Bvx?cj-~4k|^b_8qYB+x{-==g9<31k+#NtGXX=+g~a^e+D}KkL`T+Qx3Ud z=ljAH>F1el=l2yp-v&OTj)JMzAB?>u@_JzZ5PTjE^m2As{7|~&2TnBZt)Hh8+0HoS zjQTBYJoL1j?~Ge^Jy!u!_mW-jJMj5DocmYfM0|b^`a5cXdHZZIjv-aStQ!Z0&Cp85 zO^-`F@?YHlx$m<_#b4N6JbsZIfvNMeJ)Tw8&v%NdVO&H%zbWW_Ft3NNEPmb|-v?_v z^=B~knrYlQ-s1H&o;cFtzv1(X=r;gNzsksD7-Kh0r!0fvqQSy^|*z1*9V9b^CrNz%~kp8|wVEVbZUgGXr zVCr34C-LYfc>P4ZWnkWZ+y1?(z>oU)uno+8-B_#F%Re4!8VG ztF=B9Ox-H0bRQv>-*lzscL%fohbtsMzL(WEU#>g|O#cDPghMA7A6_b)Jl*nBmI!++ zH~uqD*tHH!e>e5>**rFb=_j{xz#A@u&v#>=jh264zV2hS@jx)+@n9Zj>gUTvaUayL zhtH#9cmbI6Je{NGV+ol1s|?2NiPU4f$85>>NwWIWG14z;KbZOf%9)p~{$aG}`DcUa ze+?MNz|wX;Cn~4ZGhPXXucY3_-x_}prr-RU@446FKg<$8p{K#@|KK}4-)~-DUNU}y z>yz{B0V6H>nO(27Crf^|kKJFcOcH;dEx^>WdBFH`Z<#mY4>0G+3x;m`N#p5XYrj-5_tCYd zaE2Sq{yTc;{bP&81Hnj3=Idq7x39bA_X4y3UNCNVwm0^L9&|$PVL#MgrTQ+u-X|Yd z_Lu=?KR1{@BW$1j!O+X>Y4Ji<9}H%{*XW01_NNwKq5Z?i)UTrcT%TF~iEes6J6QgI zUrE29?iOzarvDLO`dIy?#%Egma)|WvyY@efyzqROm;Rq24i2heoEP<+f4J?Vsm4?P z1ap6XcNM+ZT=w`s56pS_^9ASY)bnFznm28fd>=VD4vmebw7-`6cQ}y>mO5 z{cG2i`oxXK2mQo<+G6AUVD57!nEPv6NAx{LfvNBRq2zmY0CRu&z&Q8>f$1l-w)$yo z_3diuewtc-VkPkx_rk8H)?nx+Juxl@hMwy&nEErz=sX=!PybI!OFVvn=^ZJh`h&pq zR~(G8_;BNO-ohTtXT862XsFeHSVH0f^}w8WNO94N{m|-j71n)cn7=OXNIZf}z5HPG z^Wozk`+rbS@`DPSUc}oHPc8!He!AqBdM`5PbAnm_|8Zzh#Hl|&ubz)Eu;?o%3=frF*vwuTmU1_V~c+N zeBztmN2&qF&8{1!w+Nr#k3La%O)nhGJS;{tfRpua}?dG}F?_IPp& zjC}9!@cNZHufRB_#ek{z42(G(e1C!Q-!wmDCzyIIl-+KNPg8#hC#}A@_V?%e2dpow z@vu+vdYe2*zt6zaZ9jhx#rGZHcCQln`IzUSm41JM^MU=mTwA~IAt}^e-|xF5{!-s? z3B=(mGZAt6KZ@^zz#+gNKTlBa8NR;(^91GC&ll71{SCN1y{7#%4WqjE}_k;c$O}VCwmU>AS7v zAI10Q&_9{+r0tUL|I+$p;QNWFa}3P*C!18i+nfIQekb@&i#ESK*9ZqsvUwWe`=How zD405HS8IHL<=0g9>u>p2R_T1-SbQlM`d;(F)R_S0Jd428>kNji&`ri2&>tK>+Wf5s zbH4AutbZSVnZFUteRlvuC;Fh}H&G6{0_OQEZ+y%0U+R2m@7VtS0wXUc9!&jB+TXR; z_E}5g={LaiyAS(7-|Sab-&{GCzrV_Uo?!Yf24;Q<><64t2~597R|*ICS^R?);@`I( z7X+#Ek0p?qUocMMvGpy#%VOPE0GNJWEt2`-+FAWMFv{XP z8qWiBo}OUp{kTB=T>x_*>9NAe?H{V%vw4!AG|RXS7-c@&z?}DwxzaE44>0GQ4~9<4 zQHyuR_v_*I*et8xI7juLT0XzOj&=W8eyJE`k4LJ1Gg|UJUL#JwxxvtndT5*+rPurP z|I0y9V9xXPce?L!VD4x5x2hj$@p)5(lO`GupDg_XW?Ft9m-Gu<45rU(lZ2hCz?}bG zFmyw>59)hQl={#;mcL@W`rQYnpMvA``s04c?Z%3~tTZs^TQo-M<1ZSI87=h**_MA` zl=zMHwEdI@qs--PymF+lM^!NOI)mZUw=S6d&O``1+E_e$gw}s!@y%f5JC=btk9{{} z^e)Rkgg9<@XBd})9yp!9-_Cu+g1M*C*;-#+{Up~1v;SL|2l0rJVEWsI`FZ<3dpZpKOqv#en05GeI{G}SUn%<8^P3%0i(`qtMMW*=Oc5za6P}C zS;jSS{-K}p!4uU#1V(;PKQMjf)9WQW22B0;z`Q*POuZYLpY@N`Z&OYz@KpVOkABcg z>;-0BCF?)M_`J^NjC!Vev0(U*t@2#`*goPSz^qTjzIfaRrk`WV&I^`b4E5+2{RB*Z zKC17TJ4gNaf^mCJDKPR<@1P#+9}cG8ZZHl3abWiO0t`RFM=hR)>zni3xB64xh#zOg z7uv4^7;#64@ln10 z{od32Ti_zgUx0eVT^(NPe5U8w1I+p_)n9a9F#EN|^$4Bp5C2oW)3`r!FWte+p9aQ$ zLSigF1C0FGAHl3o()(}nUNHClKY((@lN z3rzi`xPIZo`IE&D>-Cg+6wH3B_4-YC2&QjdugFix^IGdiD5sPJGygT1#}C2G_nIp6 zczpz>pR!=w?(nzzzF_3L1Hs%!89bhXbH;(G(+AA?`1gCPp95w+|Gtm;bHO-9{cZ7i znxA|Z%=ui(0R`~)gVei@ez-aQ6Z`wZ81)lA7)-sqU>sAH8vmv9r`!i~o_5Na{QE`v z8G(I47hi0vf3NtBK0c)N1vCGK-5-WpJX^0Xj|oU{nEM(8#?iS3OueaK z`1U?)_0u#S_`dzU?sAR$Hw1IOlN!(LVtfePv!7#@aKI|#-|+f_ z{tM&piP?W2UY}66f&Kk)2fV(4-?X{L^YMBJ9KpZOr`|;{^N)c!S4q5{!tH^VEM9z( z@)G?0KjS;WIC||gP6eaCgUs`hq4`n2gXw3(VyTb1X50&}2ay-_=JN`?mngTf&nIw! zxzADd`2}^B%Dg_e!0aCdhF|~k_W24wgP9);X8$D3&lqX(|NZ`F*nubKx;Nh=U8F)y z*})#%y;z%YtroStkLBq1NT15f3Gkh$=vzFfCUc@+oYcKN|D>ku;Xg2IPl8!n^pwth zTH~=Ff>~c0^^i(#X7Q6?`1b5>T>n#H=XlE>2u59O3>bM~pMt5s(&B%jo_p8{X8$e9 z?qkLWK9hLJ!8ENpziwdo38)07em0o>J_gh8oQ^WD?`g~L)LD1+&Kb?0 z07m~1FXNHM6~NqCDP`}C#{YCuec!WMUs~ht_F(#Vf^p311ZMwv$fy2j%bx&-&y*Jy zp8=--;^$QF7uAn&f>~bzdN`)l0YfM5?3cpXF<|!l_$$$mn``msVCaRCS>L9c_;Jj# z_zN)N8Kc46SBp?RUkkvp|K6H^!g%FCou})0-ABDaQt#>prhb63M^EEDgT`))NJH(L6|p990UM}x6iU*m%M9Um$A;iJH; zuRBity)y3njm+oS@#=4oahVBHpF9psy_w3P6OA1cr9N^Jn0^i+ zjy%tWV4j~2%3&M8)c*}>fh(3ab+;-lS*7tKlM^A_6cyO@Ae}zAA#GuQne*g^q#NlB2J+ACK63qE}PS$yR{?hn&-|GCIU(xzk zVD2j%%zn||>As_k*H72_+!>nho*{AH;$Z4;ohkdtENAhq(Gt(9Zd@%!{AT-t>CZJ= z*sBGY{r1ffP8tZtTz=8tD}QVCd%)}yWBHFX9-IK??SIVEdEU9I^}QA;xB6RoMV!>9 zJOi_T{UzGJ!ZnT0Q%?E_Oua2&>@%ybv16&Qqm$+L1Jh?HnCBH=h$rVG+~RGPOMYSm znEfiP5DtICv%u)%xe{^CUu&hrgZ{Ss|Gm_Bxb>Gvs^ zelnG#JKoT^+js$(@fl#~q`Qrmsvl>PaRc2~7@7WeV4v`lavRKkQM&I8SEk0B&zF6B z1pTA>4Hrs&=4vqgZbm)*<-e)%ql+aTH3!Un*Teo855J}Q+1M}IhE}|-^=HAzOK1S5 zpVwgMhBUJHF!*Pm1z`Fs48}3r4d%S1z&M7Vu=*RyzS+k2!O(Y-sdEGSM}2U|JE}K3 zLHA!bOZBd;SN})A^fP>e^!L6DW_=tO{T%;*>F2vdnaB0=0012>CYF8Jg*L5 z*3U*gWJCLdxt~kg&pE~N_kgK8&En6H502evT;&(h4?J^E`ybw>^EY{*{T_m$@6+12 z@OG&WZUg2#KZ4OW^Gl0gvv@x+{dC-+=PSnY7rR9-W8*`uuK|Xiv|C`#^JJ%_5u5wZ;F@eCPLI_J6ud^OLhR|IY8~r^93I*Kxn-C%D1PUjxRT zqsjD>0Y;mE-4-8nK=fh{8yERQ>ci44e+C%&$+y8gU-y*bUs-;~6xA#KME89a%sv&s zJXSj>aaTPs{fq$Pn9$yME*N>~p;kX#^D_p5xsNWI?;LIMN!l-TKA3*GfT8DH4yOKR zVBDU##_~Vcc-Svs>MaIy-{-*ecSkw

YTF{s}x%;R$%%zgvG zI0ildqt4Icn6m#f?U(^nGCJKe?&(>_@$p_jKMJ z7H{@Q`~~;7`u?_y=2({}w<^b-H>{l@#i=F`CZ=Ac{W(QUUA{D z6=3=sQbK=r3o(Abr1+1hY4w$rlkyoC0dsFJ?EY5_dhq479n9Nf(2u$^Eq+V=<&3uY zM_|s;-Qou@4>-1+@dPmU-w@1w_0@P%Nig@Z5Da}^hjEO~n{~||Uk-y|BmOUYd`T;& z`uo82RZ{2i+hBauTjq~j3ueEF($YWk2QYnJFDw0`e>R?7PV_Ujf;sO=AIT4-KI`k2 z*Zm#>vtK_je5W4=%k`q{z6qxO0p&sbR!JK!jvd2j<{Re2i*Ge$wb%5DtipA4a-+zR~mw}NN-N!f-`QXHYmfslrXP=FD zey9E(F!STV)NO@*uup4y{@+qd_Ze>7y{^Q4XIOrZhFTv8rf#i9GH+Z1F!dKS7S5?? z_05~=`7C1bzXQaNS1#i_tt3D4q`e;bs;%_*+yth6>SyXd*m%nq5|63`rtfVX#ZMMr zA924GJBwb(YJ0sjC`9KA1XFLrm#Wvwxc*lX4`Q7ASgM@Z228!O-E`hBEZzr9ov$oD zRpW`hEWQWK^UpZVD>)`hORRh%=6VxIj}C6{m#22-#@p-zXL-j z_99+yvwv$a>U@6#v%ZSvyElPZ|9Fzl69Z-VFvADI3ZgV{e24E^};!R$9x;|Y1e)E}$$iLdSFm7-SP1WdnOl%p!(=ON}d z1Vbici~aocp~f>4jPrxJ*EsumDjkeEfBt+%y@yj|{;VEg`g;IIes)KzFF95H2U&f0 zFyd*gEPv#;QlHA7|5%?mTl8~ETYbm5dOk~9eXcn1>yw3_FPYzSsj$lp<~|aaYdir= ze;brTmxDR)EHLWAzqNQFjmKBBc=|G(w=kIc0buB4UbmlbE21AbY9W~Y3WJg7;LpEg zALZ1(VAjvp{J^XD`I&weD|=o9bFYWN@Z~;YoEQC2m$l2dEg12TEnw;&QFgDe_(RQ4 zoDb%FQ+2-RUSRg$4W{3=7B99!=8LFq90;bbGGHDrf$7KFxZX;=K1x~soz)UgXPo{6 z6V&fJVD`HYhRx&x#y8ii-YvYpz_`a|$&Wq*X1}{XOFZ(hz5n2`L$8m$#xH*rPC8=w zwUdQ|f3tWMWv?k<>IZ>wbab-#5-|N#w|LQg>ZcFh|KPqp0b`D&Kzn~=1Q_+cwe9_p zamtDBS$ve$AIAGL^xs75)27?|H3h7`m&K3nmHr-0!0fjO%5^3+B%~6gD zwD@|9R|50=KGk~vOuQdQ{Yvl$UC;W)VY=@im%V>?N7L zN7CO6<3YybbRWr;z^t#SoN)y2cQQW#dYHp|wDGs_!+l(}_fNZmIp-#OzqFIa&7&QT4$* z9}(w-Qyi8*@Vv&aq^m#Ul#9mG5r>TH0+{umUeN1tDwz7qFG@V18JKf^d`bF;l(YEs z%Q|1mdChtW4!@=A~yVTKb7MPgSnsHVD5X%G3Bnx z!E3*Xg4C!jzMf+t1f;n%D`SSr&f4t6@eD6<d!l*`&tg>J~|u}4w!E7%X)v!8f07r3>ly9VCwz5U;Ozu0n`5`-2ZWNXfexo z=;M9#%T(1L`Tw{&@Aw+;_y5O=B3i_XDhHJsF{7<$Y1$GiwPMALmQYeFR?JwjV#W$e zY8)$OYQ&5cE45CmV#bQm7!_5a_`P1&b>;E+eZKy1Kc4rsUf1=$@B5sbbDwh#Y5uEV z`Zv_;iCe7MGxT~BSk?F%nEl^9t$OprpZZrC_fd{%4racCnlIAJ?47h;+T~MP|BUKM z>0^8m*C*spy?#>jJJBEV2mK6Yf9JJ-pLSs8ziC{-{Lg~1KVZiR^`E5n_#Vck!N}*T z2xfdR>Vac!9oKq|Fh8*GY%uK`p^w|%X78nXPP%}MD-8YEu7d0%;V`JJYPY6AJ<{^FS1iOx|i{R9cuRhv+pU&f$4`-&v-EEr%eOX zo}}#XF)oID=*x8{N$p29fBbSV`^V7!JOA8W^b@p=h60{ z#wYBPeq#SRpnMz*|DcD)Wo*7Pz?`o?){FT%@7Mejbv={)z^uOy3_Xzr%zi}eQMdQ0 z{^iP{5yoS{$d}my%zk$3@f>+;ujcEe9Cr}R`UCZR2>;3KH*q{5%+UnQ`R&!`N0E8W zUIEPG>Cqm|zZ(6)KW+z@{^u|c@=~*J*ZG7kFne>XKkOlaW-o+!BQD^5#qkxr|WYt^#|zjp6L#z{sMM< z-~3hcy|nos1k*lIkN41cFyoD#>%i>iS3O_7oEBe0kMGQ?VAk)b*9V^*VCHLt;|1GH zSAud5J-(9mfazZz$0O_sql`!4_(dI`&S2Iri|ZfxGcfCqwCiID^AEt|5#l}5wyS?t zeLfg`2F!WA1|v<{ezX6G$2Zh<-vMU6mUuh_M@1V?#N#FP4gyo(XLx+2y@$oW(Z}DI z7GU`KcEs~d)XA!B@s03&gvVDt<4$SkO7Q{M@-`sFCGk&q zw?*wUz|a-^1Wfy5Fv9%r8t2yMx4yrDslTi~-}Bx9rrz(bN_^}RFzemFF7@Mk7~j32 z>)F`+|4I`*-WAQB@22+WF#9LBB%jxl&6@887=6Vjfmy%9ZPD*qZaiB#VE~x@^IkCM za&K%r9}HO`o?z;04n`ioj7_S459+i3)?nH%K_BZpjn{gO!OXkG*oA&zkLU>I{;gol z&E*N^{4Q$0fsZ$;y@t-i;{=%YPz5{cf?nk>oH$JJU*~qFNXniFd)QSIeFsyfym*FzR`7{_OWW7;Z^|Q0I9X%z5zd1?-Ri(>NT@hp6ka@wa$<;=B%mS^pz_e&rblroNw*Go!$a z%XdWQ9cuOu!K~8)%=)k4k2vqTVD5i|{MbhPyGHZZ1jC-Z7R-FVt3ID$X7>Wap56(} ze0R0qtN`Pjuv4cWnED#4f2cQ@`8t8I2`K_*eZIcKe6Lq)zCvnuyA5WZB+Z}tCz$bV zlq3ECGyfPo{v%H!{mI?+`Jmff;~TnuA@9JfH%8Yt{3FwwN7+@z^bFPGCAoy@J&xlI zWh3*0ng3HgJ`nEh-3Lw3>= z=ph$G{p^02KVJ1jo`;?FZ)!jBi@~(}V;^ zZ@oh2+sf+yxm4{}z|=cxvDW{?>{l15zUyYMu~6*c56$ksKse#K*#|~TzQ}df|M3~x z?@r_OVAS#30jAz6)5RV?7R-5kHcjjijlk?Lc(Ua4uZ8^NXOm6WBdqAzx`mI5BH-a-rHsKsD=8}^OtdV)gSVQ@v>Pu{{vvo$2Cvu&op~Z%m=!o z0?htRtoBpFcnlb29Roh|9|6w?7HThQQ8x_4)~?4mU3FqaJVL!OTDQ2j#I~_A@U;*mE$L z>ocgM%r7$4><5Fy9`wNM&K8p2?=LX*=K*s)(u}WtC;pk&&3`5s_T)=o>U$9=_Jr(t zxPy_$@2tg7Y%KNT4w`>jL$PP=wS1BOnt!eNNBXJ#Gqdlgt?P4liS}2nrue%Sf!Tk2 zHL=IH0#i@%syhF=#&2v5{x6GbVR_yLIto}4GWQH^ZbG|prh&`&S*-L+@yu$dpm#$Y6^w0kO zP^Ed>C&VWGUsUL{G*v??-GoR=W&q6--m-L=+%yTg9Bf;3F{{yC;Hel!vdkJQ} z0y)GU>TmgnWXb(|2{FcXUkJxs12ewgbGctIv9g^X=WstD_NQL6^JfkGS+|LuZ!f@H zr*3wBJ~HlO_S0a<@UMpRnSMF{)%zEJG2Ze@I6Bp?NB_PS|G0*@{!xGaH+sM4Y%uF) zf}tlX$*z~3-E_S!ftmlCoO-^}*EJRQrv7VETXlTkjX;;{(^T=~H3% zU1tB{iQbP%X8*taCG&_p0%m>JL-jvp{thtq`~41PzA_JVJ`ar>;{H$U56@%z*4z`j zS7|Wwd)$$HQB#dS!TqD~ck%I?`M$CHO&=S7h5J!ye+6d0f8zdC`nlQTu><$FV!ux= zF!TR&N$(HM2d3Ws=QtD$z3E%QoKFGu_djL!Lb_gAnPBEi*7Z$!3ue8kV8*%I-)no+9$nD>zI&nf zQ>PXK)BiLWTUT)~`&k0U#!=qlJAjeTS;=^}-kRn| z$GtLk*Zb)MyzTX$YGC9`8)mQXlmjDg{1hE|E3Cz^fEVX?cWn?3!I)bo!9Gk*Y>_2|#z;AoQg$4s#Jd0^;sOa^1?HWW<1 z85Z9GOntL0zR*FjN9C~B&jR;r{5<2+`@}!x7cliM0z*g4TC*?OEB+xz%|6xmlyQIM zxC`drP&w&5n7Td#V=jK#_8>6wd;VwfG0MJv_WGa)m^#LTIghJ*RL^`c`;7p@p0UF0 zt-;Ly3z+qc6IX$mCx`lbY_Ry*i4yM-Z}D$;OaAap=D&8A*yDc#GhgwYVt2hYyN7Wu zyxvNC+zzq(dfDr*t-;tI^|8G^>;0?h|J?i+CFt>+&Aq^!H<|qn1~c9V%;Twn+C58H zzH0b95%zm!nx6P=;_rL{W_$xM^F0D{ejaKMeQox%tzr-V!0I)G9bs|bTK=zL2Rnkn z?C;M_GLOK1VCMTA%z5`RE~B5H3TOwW-a+_06y_fIg>l*S+HWN=*JI~u$?x{1*$?9L zZ>Zzl22B0yS7`p$W=~lz{{EZ~^H%{=M@jQP_OtfuW_)Ft`t$W{`W;*<`4VS<*$+Se zhW(k@uTT3Zdv>+?yjm#nNv+I3Xuj%uXvcR(jLz>4n0nuUu}OPk_MPxY{_y@*|Axkg zjsUa&LF(_e)3`N0zlZ(N=gfciY|)$g9{QpGt(mI7p!FXDM!mSaX0Hq8{PKg@Z&bAS zdwpd7r)G#fit}dwZNb#r-t5L9+3Wow;+b!#`OnjQeiOmW|F_zsW`L2$Z7J$g=Q8mB zr`KzZ#dm-|=k37z8??WeF8Q6)?EQ~i%HGxO{S*%{(mLwc`zMY5563}2j)UN#uv5=V z*pWAIpYawj?U%vSM}}W`rtv!U_jzajQ^0VGtYGi|c&mTH=V0bvtp3qofvLYS`eD6b zF!P^M_UUH+|AA58>jyCB&GmtQbT6~}&JsOAmBGx{0PBr9F1{Z{ZlmiT5oBBj{>T%M zY1|cd)}3hYzpb95^WSg$JM8dJerFu7`8{*s{X6!vN;${_%sgwr)aPyQ_c=8_zz@vx z?W)@2hZ}!@dI(FJ1ZKWtVD`Df;%}=xF3#+&=jwdP^!p6QJL3Hpn*9;Z2lh7&Og+^W z$UJ!!(@*2QO4|FYotCJ7 z_WQ4QV#@6)#-VY|{u=v9EesKu$Lr+E(FzZ#s^$GFr9l`AH z5w2g@pSscFo9Oi};sBWQ$pFJG^0mc(rT&Te?EUWrnlCgjnE5*C_0P9}y&ql)jNSf) z%zh00qn?+S#iu|Y>><^RuR}j|27o#5OfPNF}~v!~r3@J{31BaENvdPYw&|4?1O1TyoTg&yQf+iLdh z%8q?t>f?ICFXFs$0@e$=XyddA~4 zf9jVO?*?YxeqhlDf24^V2Il@k`uLJ?#^V3M;{o-#+5H%E^!QINVE1d}P);so_O4*& zoe1W3Fc`W$7J#Yuw)%S~nmrNc5AE&k{*k??kGRybxL<|+jsPRf5d>!ZM777Z12g{^ zoNv$_)ct?i)dS3a#%MpTdBzX$c!{{IjbI+XeUxMOTl@~_!T#hF<0`5z{xX>LbLsgW zejQAGcKwL#xJT`k^?DheU|bB0dWpY+si%`Z{)OH!{?D%OtM_WY>v}y8-vDNRr@+|y ztvCCeDSAAvGtQ6iUts?`!R+Vcc$ufqMKJX)kJR~1%~)Hi*k z1(@|}^b;cu= zGg$KlfmuIaTgeyjHJI~lA0++6{{UwGtTw_KLyWJ2d45J3|It$Q9sx67<>uOdmhrS^ z5+C*w%z1sN?D5*{lbh8Z}{#Y%rSGev3-|N`g=z- ze?07{6aPJ!^Zpg_)VTo6dhI?Id)Rv8+7;D*kNMB8B>q`vjB{0!`cAi_8lT}S^}`2% z*{}0U)%()y8yo0)kXhG5=N!)OMKj?!!=p^ja z{j(nL@y$;t|ItYFWLyVR&t)(+ab-?wy*tW|a$wqXf>Fmk|0(4c-%5N~8!+cFPv;vm z0!&?Z^!Rs<1hf8?ueATM<{t;f{?s|GdzY!Ws4dU5}SUA291*#_@ps{?)|4co;(;J(; z1^kgGs*}Y}((7gLPUGC@kNPsr{}(+z(<`3U{2lc8jQY5stj=d_>Nx*jpF!OVBt*0b<=wch}&te;*psf8*v>e+0i*jk%V5T$sL@A9mB)6E>EV9R4_$a=<4(FaESv!A|8WfrN4^VR=dtmOAt21ee{bBo2EINA6y`eFXTV8%a-QN2NC zZvcilvZdL3&eQze!K_~&47(%L{L6!pCombzerwqLPa5}{Eq0$hVAlP8g6PkzXz_i= zYrYcZUq4dw6$De?g`vV3hhnt87ntk22h9Ek4-tKS%Z!f>6uWOHFzemwFZQf&jhBV# zJZpnx{{3`5K49wqx3B2&uVP&FN1aDS<9nf^C;DSB^Uv?4^*;eKU&Zd)Z#^*euWKh9 z&w9-N$9Li%ThQV!ek1I4X`bfm<0th(;*Cf8ir&yYV8$1#sd^8BS#O$;>NyH#y|_xs zyNwHdBJu7!z|>o%y!O8f%zQt6B>I2i?t)SFP zVSlV&vw--=G_-yTy6b$pnSE9+@ek~6@eSXVpsu)nX8-b439hU62#X)|kFax+`8Rl0 zf^`C;jEnqTf;zJ%f_Xg5zbpBY`hcmY$u+U3ehp^7KU@~OTejYn7uCPA`PciSg!p-b z+5e2wn!hZV^V@n#?4AzGSL=l6OXvEter+(~yjp@;fAbOHh~{ACJ90qkg){*(U)&z; zuQ6EGW0&Ut&irHJ#U2`Ad~=cHOZ>{X@T5Se*qi#Ozvl$i^AVW+wHmAW{=xA;E;Lm9lk0-%?>0=>{bRGA3s*fK zfLXukK(U8Do2&7=`|CV1j34&aco&%YzVEJj4}lpU(?RrP?gX~l*>{nR&eH2*qJVLuPpS?^Xs;RxnqynjxuSJL8- zy(`ZBfd#;WOuW{?g#i`r-4w!m(Jrs7HHhYJA z>c0`p`eSd4J$(Y0`exk{jv8e=^`_|Y>1$ldC3g3q+3G*_sO0m1HcR!aN)S#f17`j? zTSc$y?o72;+#>PGr;Xoj)czKOsrRe(!okDLzGWH9bw6b`Z7uy*S;k7xDdl4Zxg7&?EJ~WqR9y zS?3a%+Yx3zWA+n&i@*1BF#C6Zsq51O%zPW)h<;c44DEk|a?lMh`(FU&_KMlVz!#cuZuU8ep z)O)nBa9D1$w=SXAlaW)@z8TjO`1w=;Gk!9d^DJlfE_%K3`_Sx(dVR`FiBkXBpGf_< zHekg07N{ceL3NC`_=r8p3(WK9Wi9RJ!DNjefa@XpaK8s;{Ebh=?jlpq-p_L=Gjf2{vS8?mQ; zZG0SzI>}_}f6-Rw{iWFpbe8-lzb`MCTV=`UgGap#JIr^YF{%^=TlkP z<7Y7I#etD7X(5>NxQoYMaN5fWYQH~7?U`WKt%S#G_{ESJUr*U}*Z9?7jXw@%z7EQ6 zTg={5^TjO&Ghg}u(HlGg%=J62{fGQy_9Z&6=x$)H-`IZQpA`URelIX|xYsp%AGJq( zYVj*=o)5;W-d|A<{sD2u$>NRMZSoe&cNOvMr=xLc*pbik@3E?{Bc7k3ZiX+I^)iR(dRH@hTQK&!YJ-{o z1lAi{?>c6W26KM3%sViKP&eb^cs@vfKjQ{HbUp=*=X4jn?m3Jvb`^iOzelUSSTO2(WPsWK zLFMSnVCtC<#(vL}VAc-FPjlevvv~E#}L4tOB$CuZ5Mb4pV$43^{TFfkKv(8Wi+40u|9WO` z&_U-}9xVCv@g?}dP_3T{MxKn@VAem}Tk~Hw`xQJsAuj49nDNj0>b#Gb{|lVY*zZoJ zo(+1v&p2-U3XHUA**pT*8}|Lr5S>p1u3xbGM;LF>zc&K{!K_yVe{aG+tC4XfyIBi} zc^*vvspG}&Pi9{aA|*c61?D`Wz|?aYOnqDN9hL*n>8204mV8(CMknrC zUG9p1#xS#=#p@p!W5^Wa4q)Vop9*Ha26#OLd0Z30)K?gPufsobIGFPfNE3E+G4{Ep z^)u}HarCO@I|pX`5is(Fp8_*~@#_+w<^!hQ?~o7sGfrYX=>OFX$(K3?Ed9VA+ssbJ zKWP5w4~-XG*8J}oN8t4cj*rL-T5q@6%Yxw->}_1)cUhm%Lw39$ z26JAc!0bQ2vRh{`^Z%gni4Bb>(tF&=eZ5c z{Xxcm8aD(}Pm!^jub%PB(OQ2~nA#5y*Z4BV?R8!u@A|3zW6XzoAA-4lRnZT&F*m@h z`=Y&Nw^|G((xr6zz z?nN-STO*}j{2a57n4t3v2XnnIgW;DP_P-p^*W&NP4nL1oKWe@cm>1S5>pL*}orZaF zeZB>A{mPD#d;xX9oNx7!THhPYdbu$__-F3vqxLh<&$y{z+TT;VYn*Xu%pdl|9$@-4 zMt_J8Z(!U3jJSALZ_T$vkEgW$VEWJ2`8qp-ska0e`~BLR|5dCHWcqhD|HL0ffBIN3 z^)%@%_N2DP*L!LGZ;g|F(0SAZv)|}0sy7#y^%u00e9rVxt^Z>)iBC9ZJpOCZpK`>w zn4jjKVZ67F*aLfknZJvV>hl6~eLczvC-3TIdOs45S_r0py;8#7Bf-=&t+@8z&bV_i zJ^llXs}&NvS0OO_56Lg_&RadTUYC5LC;BRw`BU;ryjv=m`Nx2v%l)?5OM!WO+_(5p zcZm;sVD`s(bY6Fjw}W{+l3BleZne{&{octb_2QnHeYKnTr&BNW4EwJb{nA^4>3{fT zG3JThX#GtAQ%{2RcU0|x2aMmomH6ZnHt#apf9QH!?+swaZ@2ZmQ9$&?z5uh{9_7>m zI6kSTA(;D18jnRhb|+N;i$551ORQwa^8n2s-pcHoZQkQ8z6copsY}6}&n3(k>~|K- z<9iC`i~J$i%|A)!n{^k=dLft>{1URy$LE+A^Ypg!_t{oM6< za8I!Kf_8k-pU2xKF#O}UgIR9^=7(+66^pNn`NN)Z&*F1=2z%tj^_=xeg5jV10hs;f zRd#ony&>j}{V|ix{*kihRB*OF=DBVDZJ?j)Qvr`B+}|vRX;wb^O!w;z6XZ8|5@X{|EfQq|Fi#E%AT*m)Ia`(%-@^O2Ux%1bLD3C ze4%fq=4)&AHh+oTeFm8MUf6vF&LicL@&^{5;!^)an@8XUo!4TU$I`P> zFS4!8W5;h2A79qE)+u3+e=u+AS$$ab#Dl3fB1!8xjr$#tdI2kqZ|s+P!DQ-txJUcn zX7&nT%q=Jp%=wi_5PQVWVAkulO6S?i{6AW$dIG^*uRgy>z0hyL%)jJk$>*Di>$UtA*1`Tl{t~ zbj8;&ZUsiY@cPDqIG(v4UxJzMimqQ^P2&VG{9V<+)W2Ohro7pE;CMiN_nc;Lf%Rs+ zd#2Y7=MUmzt{E5C^C#gfnEAr=e2Hjgd|{L5@w@kf&ad-U<+Wh?KSlq@AK1g}Sv$p^ zb>(~2-xb#*uIJ}q)b%}nQsx!8xQE(1<9fzEOM^N8I_JgiHabM}mjPqHcYovDVAS*Y z5zKsRH9oi!n0aO%mwdrqVECn^?3I2Kj&@gju&!UkL@@P_M1R<%jW)ic=WoI<=HE`& z&wUS=`HJKGf`8m&IUmO0=ow(BM<2641 zXE6Ku0F1nzpMg1_(ufDky`IwF0-a|W*vV~X$h-oETfWz0gp*fW{Dgs0FY6AN`EL&p zeJPL3KIbPrKHj%}-TFy+JpU8ngxSW^KbHJnOTet(p`6xV3TD0nAF1BO#*Iq~htIM2eIJN_NK3O~05iS{7#silVD_`=x#UaEY3FCJzqMX&Fz5Z*qoS-6{}24hr*4XW z)G>>XxGeRSd8RkFcHE-#^Ax zwhO1V#`T-|8i3)S+TO13yTI7*(beoD6SUv6VCI{k_Kdprc;~xK*Rva#{qEc>{dq?l z-`}Kq7lK)Dtnm^s=QY%LzS$dqnP;}eZ-`fYlfgV5vSNk(nu4ik>TI1~EwlSZNqr~2 zFWAnDyO4L{E^*xOfZ67hBOD?~erPdR78cM+O)h|7!O5KNkL|o7@o0`qf*D zJ#M_k4+zrw`^mUdqf}OA6p7%jR!OTwQq&}qRrmAuG)V#yH|Bxzja`yKkTjZUk&EGo|Vyl zmxHOVub0+KF#CuSnvZ|)(muVo==VHhJnI8pABR03+?hx6rws-(f6jNFtQ+~jxYU2b zY0d5L&#(UV6u)@m$$u*!1~WeY6HoRT&es#k-Wi_Mk?xD-zT;~(1JTLt%te{5a+JxM)t_Xr1%1G9d= zT@oLEAI$!q?@;^uct3;o%wM%$c`(;wWrFmVR@>|?w`)K3&0c7m*8j@*a=iE_H8y^4 zz2wVk1?K#Et`-0AHel8pzgpNc*!;_YQ8uo#+1IWTy&0j#`IalM!23DW_jG~g=lkEx ze=$bvVXf``FXtT9y9>;ItIra9%0Kr0SN$1UucE!bUvIkVuL0)#8cosl{{qZ0zGnAxbnhbh{Qd^B z|1F)wo?gZ77x4zmTC3v_p=mk zEb-2o#=m_d9Mv1ld1lnr_#JjX%d1MlZVueP!}WbuTG)Sz-QSb9q{Mr#w)=ak7twj` zHv5bM+V4Iv^A~?pg#Cp-1T){O$3-~zw4%5_iSu80SL{JG!So+;vk3bLu5b4*eSJ;+ zL(HChxrp>1Y4M%Th`(Q6+@UJR z0X;1Ki``=P{|U_eb$1De47T{Vt)ky|sri4hQQ|{)8JGJ-?5<;AEWhulW!moni|?{n z`LfybF4TUXn0@sE)%&k;O)%z}S!Ar{TRUI;-F%Ea!JKzJF!eT=BYL7ngV|rJ+2S8J z1I+m^nJM$~nrHE;Gla7i8TX2m`YFfEKV_t_hZD^Fog&nKwfX-%TF$XdJ@i> z{rE7^E*`h`c)ex>|Nb>%0%%`8U|+l3#!*E9nAUuf__jh z=8bW`S)wn(BU1B?1Hm5#i)}OmV=j#DG=h1Pk&a<|~=h>#~+0%IK9<{dt z^Z3qpNa`oo05iY;N!90W9Ck|LGxHe7pO$*j`HUO1NvijUds?slWUYS#jP-T}gQ-6a%)H&e?C-q# z2TU{ju=_fXhEW>-!2{L10nGS|up>U>fZ6}lc=vl?>YI04>|ukaX#At=I=}zGj6Z7q z|1wqW6)-RCj@&v;`8MVSU8!4)7r`I)Br^3@z`RgD{#Uc_!1WPz-E&XZ`qfd7=bHzZ zeTIQycRGwm>--#9#+$+Li{|Gk=$}*PneI7L^>~3%KaHOk;d=h2dfiISQqFN!>Uqur z!_V#Uap9nPV9w*}QC**W#v^vCzMqkg_W3)s-$h{7kJ>Kv+@_kn&sv>NlWhAMorjoPUilixc+ck#rzvY2}e}}v;KFJg`Jhmf8ZqH9 z>YWIt9`7!?K7+wrpC+x;zlr$=HB4QBj>a+1&IUoiDF_(vM`7|j0WzAjAt zA^)2H=6?$_uUF~WHt)a19@oUU*@MEOdnA~8PTUp$;Ak-QoV+0%yAI6!&94=vpU)OB z`whD&pN03_YVlwGF8R|onf>`W@lSDD{FPIxXCavLo|P>2uqcac`6|s%ebhfUPUqtUQ*Xs3YCmJ#e6iF^`p@D&HqK%5NLr-+xxuXG0mjzpX7-&i zVo&h_vtFWdU<0$?nkV_w`dEA<82$SU0aMSoxsoqxn(>jD;_t@ugZXMqm;N&ojSofX ze2#%RpUV>@Uq&*R^Nk#=`fA(p)2gS~8g6FfEoXDXW_`2VAh+|N$Po5H+F#ecwN=_MX=! z+CluYyp7Mbk$R3U=D)3l_Osl0S99@CO#pMAeoZysA>(3=MUUqhF!Q@N(&H&Do4*nE zeF&z$-y29iuV-ND%U54G_NCc(*Aq6Loo9#sjBnsmTj-B zdPabm|4=2(zsiqUB8t1g!TnfU!kvs111}1C_ASZ_xV=)B{SX+^F!UlNnoyjKoeoV;pSf&>w&cX z9gPD5#U9+u{D-vE_=;fW8{SGd_CqlHDbZTv%bL9w)*t)5s$2X8FxD}up4qPi2|GKP zy;EE1-!;(e&6Q&YgSq}W)jxfL@i(ZCe+(FO3*dQ?H{UgpV=mOSK%zk&_e52pjU~at|N`Enf&7Oth3w~Zx zEqC6bwMWj*mvnPB#Ba6Y2{NXBF9_I?dv|NG|u8O|53 zujdlgSHWB2qrV3;Us6Twrw^F*_}w_rm$d-Qc^$Fu%2{ImJK;~i1hcQe`O7?4EWWs& zkI^}nYQ9RJO8rbfFy|BWnZyUy1~dOVKVAPiX7Bxlu4g^7SH?WJzWiMV*1d@973w*= znthXA-(pr-{3fgy{L}seQ`f8SB)_lcGOgEH&p)p!VCpG>_2=9^Gv1}ge?Utx>xH(H zdI1A0ej|=g?9aGw{-5^M{=59F^PljO*yAUFS^u;Cy55t)tT$zV*nI|rncsV$*n|69 z{5OMj9(|2(fg#VI%zVj1h2t2{`F%TF^+cHe9WbAtus-Vz8lnBoHveBD)V|UD!$#_S zj+pvbMcVAgN7R`o149^w>^TL7m1#%om1G>hN7 zQrOuA%sOGeXn!q@pT~*ao6Pv^=V$G}tk)NI%p)NLOnvLr-`UsV-Sqig*nW%83%ziQ z3y;(O7i`x2F<{o;w^jP{S`23XF59%9pUqxe+5e8k{{nx+MP>hP)hXn|T>bdF8Jurb ztS9WrqJ?b1IO z^#VQsv;IWXL*0zZtF*t(VD`!1^e5oMunRQvYMd>t9R$&{XrU^hW3P2+Vp_z?h3q4%3_T zR`vVX{AS|sU9NXsn_pTE`Fl8-%=vW4E%t;uVCtKpe?LcOa}5vud%8aCtmosYuMhlf zdR7fiVLT@%{pfT^Rp#W!@w z-|LZN`kx2GFTRfP%<{rM?ajY`CCQ&Y3C#IFuPO14Wnkvr|C#!8{^UdTrCt{8)cxN# z67O7U+*e>2@IWyb&U74(fFQVnP)qVp9W?>>)T8Hs1;!9{i}n-2XD6cCEdgx z>fu!Xn>}?N>0t2>70#HsR_pusmi%cg)~Vg4968Cj#E;@1HWSSL`YXrJ1HhW9FUje^}hp0#Y5_rD?X&h(3)YBV`dBvPIdm>&BgkK{4nJ;OM_FvfQ z=f~@d@OS05dbyWqeD?3Q&W{yN7;o|4fLU)anEEFyRt_){4Qnve<>za08_{^d7&TYY~e{3+&5{fDC^-kZPs%J{a%X~rW_5BsCX+4@8* zmwcZ59T@5zvRc@6%htEj8l7i4nE94(*8D!^-+!<6A8#CaK=el5u>8S?B|fVF^m6`B zk|jR0HkkG5rD%WMte?>r#2z&Y%z1o$RrAd@|2B6;f659l^TlLH{?z$k_W$ys_{Y_^ z_*5|F<(vJxF-74I_B>&F2O3WSGrqra%t+Ip4~+fJf#&c3m*h|4@2FDWc)b6BHbPp0 zIiKis^>1YS_Kwbzzneq*?|44~aS=Vh?0*TE+aJNqR}M_S-sa!&matEE^G~}e@rfP4 z>^}hveNn!~ufd29e1Y|1-p>#Zd-7vj&+^a%d-N{jLYOD!5x&m+FKB=M--D^+{b!o5 zEtvK4{v#aL*|_j&edVJH7@NR(+N2_}T{M@#Js*amubX#`{!H)+zH3S5C}> z>k0d9s`dS+f!XhWMfLss?CaZqcz>UIx0`>emvG`9^Dl$@0T35<((EoU^teu&{qRS^ z31qIv^fID9?Kqh8sZ~zu1teSiYj3e9T?TW$BR&_q^Mmzzzr;^Xb-fxJcW$M627{^p zY8&wn9S>%`)j{I#5ow&it@_V2KG9z4`G2`VS47cli)M?CuT9dEp_ zrNq1OcUag@zII{{>JzVe+u?o==!%crq<&F#pKf60Z>#r@IQcv9^g9EljtDU4<-q+W z*ak#fdO?UnEC7Iyki%DsmD*}7qj2&gW-?* zUXHD*uaeFGGcf)0n!e^{r#|ct?_~BMolochF#9;&P4z4=`-2dfN7`z$pZ!7Sy)T<_ zzYg`M8Ta^6^<)~C=qsGX-z8x`^T6oOSrp89Zto{{zhJYwhpByt+0XnWdOiOEQ(x8o z!kHbnYk!@=ocla5?FsM)dp|Y4hI}aN|51Y0ua0`C>(e!xRge2fFz59Z`r$nHfJI*~ z@eg#F|Hs(@owLXUf+7gA*hG_VNG|~@rV1R;O~A9%=xqp z7rpX37UT^>#6KhdPR-wKsOXD*A56U;;eIaU3#0q!pQimi zMLp`AGe_z>uNw!%D(ABNOP2~KPXTkjD{#LX;*w|V(tN)v2h1|w>XiJcTfy{Sh5PNO z?{_fup5LtTN6g-OyZ8rhvG}JurT>t{#tW0h?iX(S{&C6YLuS4|!Po|kHG78IJti2R zJ1zF`T)S0ok>9j_QR6vh#P0eS%z1PXm$2I`7zcsJ5-we}p;XmP|4W?&1 z7`k1p%-&u(^KbOa{38*MJi%j)eca@J-vG{=_O|YFe{bqRTc1n$^nT@Rj?ORl_of`O z^}Sg@?}t7O<~-6p^nT&XVCuc`zT6+|n-lpt$D^Kl|8Q@s=U!6d_nZAI zANM08PegU&&m593;VbL!d3oWOwq_5gB>6)6f?5Bo+FEZenEJMUDgC7Hw)iUFNWHM% zEIy^V#^<*AKg0dii1R1|=JC)H_g_O++$YAopBr`je89|~yQAcHuV(fq-9%qzS+l>7 z`_bVSSQ;$r-9zl*9$@NC_+It8S^UOcQqPeK%z5-5sQP-E|C-?v@9Vx-^LdPr`rf6$ z^gj%y{>otLPl!-^9WeEF8Ljq)=071)^82?2Q_rIbV$W!0_W6@VpI1{b^Oe>6?*kfv z+0T+GqQ}+1?3vRgKEA5OUx?9qf1CcM^Ce%zW9xU@0*d>>f; z2Vm&*DgtIdmwwjyeF~=j-fKmVC+pL`CqeQ#cUiu@Nn#HQ1Jl0bjOqz8o_z4;p&kg0662>=`eT#!x|GC)1kznc@ub=zs%RChJGGwqVZv0{rp%GnDd&@ zP}qmZBjYPJk$T?6?078KO#QR%Puk0TVjo(*$3IBDxMN_(Fa1&U2a#F-d4JV^+v=S{n4RjzpVDi#l`{12VLnG!OYh2z@*gT`f?%UJ&<}9&$>;N-<+gv@~-aDwA51(hm9D}BSsi%yx=L|6CQ3p(Y%fOuX z=V0tl=I;tIU&Z;_&n>ghR)3$TW}l1CPaJXnRn+>Y(9kVi$EVi#b9TDRq*{O(Cbkd%>Ksf_lqPnv3#}l`(A?gfw_L& zipuv@xR*Sl>{CYKeZs+v{~FA^L%^)>svzGtlD09MKhf_;xnS{umG%2C_JP@7h;ryo zF!S}OBKCllX3vT5x50kTS!T~uO~0>X3Yhg))ROPl2%ZS0-V6AC9QcPvTKu`Xk}sX{ z^pC;!>tLI>!|W$oss1WQHNIqP)n5xtJs-6Z|A=rjkFFzlFp8Un4)Z zeqR`W*IDADtDFCqy;V!SX%VD?u|zYi+?44C;A;rpbp^?GPLdx~)4GxLv` zDxCTlOnsfE$vpk^iF!c_O7Ir3pIgk5b&dfvI-|7w$8CyT?^5oI9*?o+-}#}|4>x`dMqJcj^M8u( zo8)}UfthblUirRE*K51Jm+;i@uiR6%Py1B-J_^_OKYM=CxuxWD-wLMvI=;Ue zb=|9j8J~jhw+4F`vga>vf<;gK89e_%9^XvZv2_hHZfDcsOU+TS4`@@5PJv!Axm z1NIqZ&!_SPie9fVW`7nS^`b@_d!v8EMbV%7mNe9Qv{T3_J6W{$BiJ`1bkhd(vN2iFzeS`D*56onSJ6iiBJC6?1z7r{HY%rhb$Mn z`}^j<35+yJFYWctNnp&+<0+WO-+j&JTxG9s{*C&a#|ZQP7tHOQ^@C?7q?7Pbq&y^!Tr|_f!4^ zqc7)r<6OsdJ{!Q)S3OztliB~#6ww>B%J_Yk&TFahMKI^H%;Fy^<9&4PKlq~dn*e6N zOa2spkG*DZeoyKpX8&$|*9@&kfA*94SU7w$nEL8uYQE86>Wg}=^}~#(zYtF0`%|oU z^GL9Nx z>Z$1=zXund!|Zd5$nVE_pSSnx-Z}L5G6|(2+Vw!^J@RUn|%n5 zZ{&$NVf@}xIljZ_&-k>5a()FT8ox}}n7}wh>p&{tSF*ync|Q#E=fvX;*R!g{yMf`KntlJ$`|xKy57;@6@f-Adm&^QXf?@Z< z2YICa$`v|K-p@uo6YzMBGX9ZZ>Y0kiS8Tm&8v7eRTdnr$%2B<+tan%A9WBiM9M2yR z@BG%d3i?GIkJqcz|Bdy(6AWFk>-F(Fd=!}d?pF3~1E!uLD@DIwUNH4G1GDbqm1>Uy zV}IB~<8;guY2tXlA@jGx<0t!>0cKq4ui9@rF!L?kA@R`-ExzMEVV}xi>RGIhmq~@q z|Lr-+7jWYjt^XE}XK+hO1~dQCt73QG1!jD4oIj}Jv(tFwGo8;V<8J>*eB?PW`>m5l zt_R_J%w7hJKC;#scLFot1~BU#)889)odmO=i}<}#_Rag5S-)dB$(Q-Y{A2L=g5CaP z*4vEVOND>LE3>b`;|VzUh1p-~@2mR!4Q9R(`2AIEA}^Z#6t0hq?`G`q7xsD`r+Qw3 z8FvfJdQJ5AUV{&Tso$%iTrbm?nLQMbFK`bDF|OBA`VA~&?Fu^Z+BzFH=3mq9vbi zAu!`}%oMx-sHK*FhU&k*MEM1ndV7MozNKb~f6{?ijsJR%&hO4*<*H!hjrkqS_4_}+ zSN$#C5qK~AcdsiwEH4^*JkeP+?Ef)qBu9VTNq+bGKrVKIdw!s^>z5VShvTOrog{BF z<+ur8&c&@k1=*j&vyV*sdQ^UWoLtDUDF!Rk-|Ex)1$n*88E%90D=6|oI_(zp0ruHheBwyTAF!T9?QO9dF zm~%Y?M&7WKVCK*3D;)jC;!A_!7nQTP>T759N`M)EUGt?nz|`|k4XNi}3Cw!ys!6?w z>K4DDvgZGPRGkNSjrZHfV+EC>QX@viN|lrnRLoehju}+U7>#wzSW)9xsgf!}iB`pE zs>BQ>YNW-X8mqC=8ZnwuF@uWve!us9=eqvydtH5>|L3{a_r8C>^PF>@b57JWuC45( zo%t?S)p{QoZv#VDG@0|+RaxwAx7o{rQO4K5q}p>U#|;Nl&xK0bZ;J6BVC3^ESxW0= zfKk_78chH7h{w8z_<*UuwV&Ai3Yq_NFmwdwHv0kShgujltB@7R-2$dRnhJnDg8N z#`(0VVCrdy{fF~@SHRrg_rN%x;9W-jcQugsL@zMyMX-MnA6f{^d9-OP@xiYx-zMew z7hu}S%=geZZwu|`o^eGm@@A2#=U=r)z64Y61u*mEMLqWO4j6vUO2*Y%iru#rnDL#1 z#h%j0xJ6sZACnKvJSW0<;X2y=35#n z`cnPMseN!C)wdVSJOlcQp3Hm3kznXfd~O_|_5`2zG~Wh|Px}bW{%U|xHmIQL zIKlLDfT1thWqiM<#0MS*Q^z#SAN8`z`f9#;V4U}_1g8Cr+G7I1)ZYN{$QRZJjH5?o z%ohjWi54HC>@gn9`ccZsb(X=oZkqGU+dIdqJ>$wCB-D&s0%vV$G&U_WL z-(qUd&JSjP1(cJDn*A*D<9uizv)>*o`5k|O+0TRVI`8TgwcgJY#XqvFans3S_s#>R z|B@*(-}L7e|I<|QkA2Vln@yK~;zt;7Q;wQq@tI)s6)^)$y@9iY1HLf(vnYuVUTplq z0%3Q6`3He9hs=+_oJU`^$JYmQ{kuhr9-laie*lJ`SB*;Q9}R|E@**((Um>3R`z^dy zV1M^5|8OwvrPM!tJecdj{K)5+WcJ*Pgj1%0+0V8vg@E-RSi9nw_oz5g&X(ZC;pzzz|N{%8y+9DxA;}^c?|*6p7e`yLwo#GRd!Saa~>ZYkp5CH;_*)ZPqdzUt6dMC z{493w1Tg1WLGAG?jXyr9^Er#_Ded1J)_SF3XFp|+>V9Zy{$9U{{_p{2{{alY&{1aJ zdR#cxVfL8c#Xqg@ru@6pDm)Sf*G%zkQ~RQm`p{feFvJ;}q(-w8%u z|B+zot@?-5i=S=w8mYqWy~aC~{nEkAcNmQL%nzWC{7~6>%=8{OC-#&cHvdKEbv|=! zeKuWC9%t*ZB~9lu%k0%I>HNoosjmwda}FK@=DbIP(Pq#H<3m@q-+!$Bk2l3XBN5Db zbo*QD?J|4846T>LOK;131H)lw{x@KRx%hm;`6p)T`kVk$&(V8QFCxI|Cp-|2sbhMl zJQDx3T42Vs!7@%I^M{FZDh*{us=7+EF*{q`e;S&Jum;1HklO z_gL&nea+tfrLa#gFypJ|s?56H%gp{m9(nH;z7NcP-32St&;ONio416c-+-xif^y1s z<9uF{FQ7b_`AZp>22)RWFb?VE%->O1{8Rb*hxyJH5xZ{$nDY#HM>u%_nEAdfR$0!+ zfvK;^yAq$Z8O;38i;KR@B;%eX#U69O{C!JFeA*E(^ZyD)-h|_3uU=aEkNVT%bCps4 z*X%36@OLntdV|Y~J$O2p`R0RZ4>$WoFwXl7159|zgJ%J z#s3OsKEDcLkJtrfe{I0@J7oOGSNz>a!ORzhc(|okvid!Z8(Y0#%isQg?8xWr4rczb zu%oY#fne786^vu_9E(pwJ-GQU1XG`@lG?v9`z$|+56A#B-{`8+f9QL5eb`=2IIy{K z?1z%iRlzs|jCu)V#<#91?5GH)o(8p~U(ZVB-?z5p%l^>pbLwdSZHyO!IsbNG=DQ8X zoZKD2oL8B;qBpUtv8$=}^9aoKy&5E(`NlYZGl|b2GyVh^eu)`i>ho$L_2aG^Hvw~g zWX`J(7;&DwUXnix7JCZkL0%4~-4D$Co~#MW%{c>?;lYA;ZHSx9n_=$=y0_+Futsu zmGl08;83aWXlQzuf{`aX(ER5P*M16sssF$Tu_tXbJ-inP{mwsezlHPp5X|_kcK@Z4 za$th-tdTn3Z^6_X48}1q-s0~%#h$X+?7LA9ZNzN@bN^&R59*|n*@i)P&{}lI|=wBZBF&B5H z-QNlTLsrngc0X#c&O0C-%zP7-6Mr*%e=z$`G`l~Tew)nxc(CO6n*(OQQY1vKZ^wBs{lip`<1mP`#<_~LR_mjJ; z-HZ31S+BO*eXrR4=>yP*xWq%o*R`L>HDK0jiGEN&V-uM1S8#oVf7SuBZ^!i&GJ~!e zj{w6SLZ+V2+6#OCY5W?`H}pSZ9H`Gn;d{XBcRHSL*xx!Z>-EF)36BBB!{HD1x{mwz z%->$?c`vj3{T;#3oz}tb?>7fSe|!L#d9Fhbj*d(Cynyj1RbNc1eSWYR3>m&#%pR!g z7dj2h{aRn=7Z(Vo-sZ-2z?@ezo9~AfzZ1-QSKd+kQ!w&)ZZdv}{792t3`~8?l#_24 z)p|9-@b^1pTpRljy0c=y)Sr&$BgFZ?Yxcg%Dfz+F_Yu~M{ogI3_4#~8SDX z4+|?-)cxR^4rZP5x*vjjff-***C(Kl*~>sb`yFKV-_Rf80zWmb52oD*%zDjH4~MW_ zZ)?7;Ew#VBUOK;g`uZ!t2h94f8tMLV7E*4l99s{}dFKJ+7*Y((`MfkPZ2q;INIh3k z^WOwU-n5cn>Pf=uL(aFf`8RK_^DG5szwyfM62_l{IX_P@>)(Z5_<0_EOa1F8yQhPx ze=%NfavmXI*4vDFIK-7U`!eW3p49UNHQ%q$k9_grVEVrW#=-Y}F#DU-Q0AF%tbp3{ zfZ^{B15@vf2HH_<-ROmsTU^45Eg?{Qu%dh^g z!O$BL24?>)tpE1LBf!X;-Oe~b*Eeenn0kt}l6;=tVCJu)?0)8{`HO&&H|B=%d3}8y zRUXWG>%hqGQxMGf0Ojo4`IO6paXR@HnDcl`<2}>C?DqxqL5H)U@e}2QDq!lH31)v4 z%pRog7yJvE{k*PMNM>HGw;l6Cos3gp>Z_sibo^@et;z|d!K{DF=KF0P_2>HIeB`s- z%AIY0Gz8OskZ~HmRw{v7rL^!c4OdomblTy8M) zC2G8LlllLv`r=!ee=*cYeDG5b&HoJbsrMY1{pQwrB%T4Y-Wo8D&R>mx)A*>b&3`$V z^Ic&4we^4gjegcVMD2;K!OZsy7)P%sua%F0A=~#KFzavEc%Kw7*SntX&#Yg~{xu%2 z&>Q+AnEiIc{zAUYg<$4C3Whz9%=k0P*`I?s|7cwQaP-;rO6@gqJx7}4LoYSoIek8g zefdK9FkU~v9=03I_zPghZwFIvR#&m7Up8KE`8<%1^-F2V7r~FTDVmdME1h zv9q|bpI%R0Wct^He#EbzW8&y~;UyaKO-StkhViDUe4W}jbQ`zveu>($YG zHNf=$Qs1v<6u10i{H4FhFA&dujkBY`)HA(?&bO`Ad!if~1V&#Tg+9{#Tpmol$27m+ z&1|(_QG3=mVCJ9pq3FrzVtlQ-*D+&25r@}ei|lI6QvPU|ItS+5!xan4m19{|Q2 zGnN?_d{62p1zG$6F#RhSUsI0G3+DV&%If~Q`=9E4SVsNJn7tVoePq`Iv;LIQQZK%h z@yX(<_X6UXuhqNaAD959|7qNhHZ( z-}CWPwciJ$KSu_b^Q-_y-PGk^);;Z`{mcY&J@SEZKBK$w!BW~EnR=h09`gA22D5%c zFb-j#8plH);-kicSuYFyBQEhv<0I$?cFz&UWxOR{%G(zI6Xt=qgsdl8ZmZL$00@Z&;a&pcxOH}h+~onYo2^-Av-?=brl+&|{|AB;bO9eN{Hn*T;H=Ho64 z=De@v()F&CrTuKot?Q8=O#NrTjQ0RDZ#gjH!yi1-c@6ZC`1E67p6?09(eH@y@He6_ zwl|ph+|Q+ca2ex{*}{HrfjO6iXQDSXxABJm^nQ6RFzXL{s{P~vQ-3_}pCfNV)m`TT(ylxp8yYAtSx1>1l`0 zBaqL(r|~y8bpA7qzq=yr`w~n&ZSZ*s;*+=Ay!YtmDb63ktZ$sT$>#qOcIXWDv-K)= zQR0Id*!qrAPVa5&I|Kg6A2txod{gxE97kI)>-+v8_PCN}zjsFa_cr@7FydWRz?|== zYEQ|jw-29B<>=x3lJWT!=Ry5AdhEsLVK^UE)%v-qpPxlNLI3ps1)r}$hjWh2qbe9W zL%Ba#Z?0SBA5z)u3&HUBde7{`)IYWWnEm-{zJ%9UAI2AhKh8&{fmv_e5q*4|u=Ohe zroMw<>irI%|AFIoS^OA$9*OwCQ)XYSpFbx2Y4N||^F#P&yfpvu`gv$(UDNYqx5hUE zGymXSI-mY#9}TANNnq-&vQzra8fiRktJu?4BR}=m*sSv?2(VfQ-avN zuNv0^!=82-%=~FT$ox{a8IMr*-)#Ifn0hXOng0bCb=?E4-(DNUp3QmCeh!ShF&@xM zp8ccPeS(Y&;PYmj_a9~b9M#XK9dTgx6QQ4XXRa~-aj>Jl&ttQnR8A^n`zaE7FvhS` z#-_)owC&IG(8Klc2Xo&0)!(-zn0@^mFZm;fgQ@omF#Ll@84m!XpVSe?4N;$SYXPR- zL2LB!a2@q|{)v6R;EM6X)sip%5}5uQzms}N1uXv6DxKFD<1ya|N1QQ!wo=&p6qxz% zuaJCxNnrN#7Z|#oyTI(HJ{ZT)#TH-sYtff{-r{fL`x6LDZ)wk8$MJm&;_Zk zFJM_ed_RME4}y9A*+Shfd(3~o@j|mNiq`eLW%~Bam;8yzR)5_*u{#zSpO4b{*Eaw2 zbHqR3kgeyf*`mj@t<7^T?9ky?(d>R;=u9|+{Xw0R&Hp>wFXv`yeeO5*lK@8l$%Bno zfRQh1ka7NLq9<^z#m||l^Z3H}J!Q8O%=w@AO!CEj0_OUR14Bnrn;f1j_Mib^)_*fj z^k%NN_~T>M{=L~Zg5ejv#Nu6QPagqhe;*?rWnG29T#pr+&w0fje`}1-f@%L-{lm6{ zsc%Ds%p+n5nEKsd&To*#e=uI>HNdzNzRyIzp~i_|3>JUS!@5El3??d!YeSP2$9nO7V=KB}^sGCZreFv0p8 z?a=-PSwF|yY5lI&@1i!sfo;H?uOnFEV;mNrD@g1$H@cj1&UfcGlvVv?`adoscJIMp)>~Ra^1GH>{Q2Ty z&sqUypVi+Ld-_f=^{n=meC|DF&n&9(TfxllQ&{Z5KbrmVThd?b7PJ2fMjpTI##0K4 zJ@R)j^%w`90<+!;wTHe0v%f`}FSLWL$9gd48Ir?YyhKl2GuWyB$=hO247By}E28}` zG5a0pg`4kk%l8oe;IK7d*6*$L0=HOvUQf{<6>I)pc}0I#n%5syCoKeFrVmHcA&SPf=B^`QrcxD+twy%G%ngxwZD*81i3 zn)Aws{xF}IVt9U{|KB>VtYu*Km%}TK!w?UBk$24hKh2l=ADHVi0`p^Bc|1Qd{|qqn z_*Me*{1S~%n+~Rb`$A$*|J&^Al;iH%^Z5$x$Mpx^?^53#U7xHK_WpiyG0~HK!ruSy z#r{Lyw1;5UKdc=4#Qc9(f1j6N&Z`|5hoD@z|3Lqp@2H-)!K_zDIoTIXy_L0}pe^Pf zsPoI3g!?n}e}esmKI4A^v)|=l#04G$Gye$mhx5THW`7s^mwuDXVCHT9MA*v-<~+7M691quvv&g{U&yBx zKNO63$8a$Fi3B50+I2AN-MFv*J?;MHDKPE5z?|o{2NIvM3C#GJS;|%H{^?&&#os5@ zcsUq(J+tiosRN8WUV(N$x2M|Oy};Dp|39_=X7_);(EgJ{aDSNkp4mKxfZ4yX?{F~n zov`^t8czd5X7Us;^|nHOuJ>58_joLNL%%c*w|>qV-_m(SAF})3`C&(zpcG@y7j-i) z8h?LJ^VPHa@gFJ&HUP7~KrrifHm-A5=9BTcalTBkXRQab-`n`@75a?KhtCJtpZyjq zCegSy?CkFinE89Fe^Oq2zQFjps0Vx42>ZODr>=M4E->>=M*sBNVtgEo^U){3%=cL5 z6M4<-Z@|zW@!U8U_8;Pd!|-_s>Uf;a$p>aU8K=`v+UF&u;ZMKf_Ib`4+rNFl)KLrj z0p_q}VCwVJ{g86YKHsT<^~d?lN%*{o`B%Ku{T6PYU+wbH>roGUKE`}Iz{uwcwa?G) zfkm%C6AjCzi>W^VvS|5?i|{)AqSy_bLy=i#r{tK^#& zzZ8skufF(vkNw=j^$U4Jqm38n^IiJ)_IaQ$82a2h%)UdfH>u~r)UylMGaS=ym_M&? z&=c?vnDa<7ee`F&eyTtEl<~^~5+CRWGhZdxQ7>u_nDd%roB(D&kCelI05g9xy&lGV zXZ}%O&NIgBbB$fb0bryF8)#fp^ZA8=S-&FmKxgJyFzemc>!If+;~+f$vcD6?nRtF? zz55ow2kQxYOwQ-MonPtx9BQA>mVGY!({C!6`FmqOp>FmWFz3@wuSd?uW-qV%FX%0N z-c0{$VE6~-eE!@9%=NDTJL6A)p~u|^%=vwR{0MU$vG`Ol&%Xq--`~~lTgg7}o^STy zVAflp_Mk~%=D(GjO_doc3_y^#E#QO4ELKlO|PGhf*^qCc&Z#TUf{h0itTLim+*K%f8O1}tbZ8KSLEKtPxblBlg$0#tIvP_+1B5FJby!1rbs=OHlX*#YtNZ*AXaXjx6K2VL;}2-f584`KJ= z_c_RGJ`#I+5BokxjasU&ADH=ugIQ;y@d#xvem{iq6~J7tgJAYI3;E#hxN00*Q|q_J z_fKd~0&{)?jZc8#@BgWBO~f8Vnt2Pr!%^XcwUR{qg-5>bj-xf4uwI_hH&L zl6XJ!OOtZmrL1mL}%q^gSGw?Fz1;K#=#W@=30cq zANhQagQ=&`P_f570<&&4Fzs)^%wHXh`K0FWqWKD|J@j2LAyrdGj~_b zcM^=co?c+ub7_2bapNw-Ro_W4^9>y#92OR$^}>|X$AYQ<9WeAH&H>YZ@Gza%PV?^q zM!&wh!R*I4{h;wTup>|KD~tbA>w66DrukPnwf=H2^G_Qs^&&1CXN}YS(5$=KOHY*k z6Sjic-$#?xo&je4&?%xXvTP6a5By9xDF{saEalMoV8)LILx0>N^Iro-zcDMpIPbB1 zn%INxn19{rQr}Sok0s{Y3PykN0bu4k0!CPR2QcHe8;6_!NR5}rBK^0{5PfO$&A*jP z>IcjNbN*A5Q!9fxpXOlZKW=)Pf}taAz3JVc?DLK3{a~)>O&JDezT;o$JnDj}|Dy%E zUrK_R|K?Z1?gY$}{x`rlAHCe>oo2iQ%>G6wXD$RY{>YcAZ?f_6Xvya{-2Cf-Q8%!s z*&m@k()b?0dNW@t7;+4V*3Y zGfsh-f9Oo9mpmBE{sw|k&#Nbx`E#p(d@qY{hJ1``Z}whMIHw{qlS+ zdJ}ira^cZd2XPBnWT z%m;SgxnRc4(Rs&CH~Y_6AMWq5V9|s1BUdy26ij^{VCJvBNbIR&?fT;hhK|hFcKxac zrtT|teVeQPA!p6LTkW2y#!Hvze%fgM3ztj0yNPi!81=K88t+*x{dnB6_!;X&Pr%2} z!@9ZGYrYnyFNfRM_3;?|kuR;U`Imw}=QqIYV>I5sIhgaxpCJB$$54;`{{ZIPe+RSP z?9Ec&JExzA%8BPq?LOSU5^f6 z&ZDMV@~2(2=feqy#XrH{o(~6rp)au_nEuk63q{BMeXU_RvI`d`ct zj^w<^>oP@8`lnX^iQc#HNH+UZypP~|-v_has~6Ibe?I7Ee6d$z5BbmRJ;0cE`a>}5 z4+JAFgUt2#R{dkLz??@i7=Dp=E&j6Fv(k-+v0LpdWFHvzg^#V`!+Cp*`o5gIB=x( zzw#Y@9ljh)eP83gCG#hOspm27b0Uo^3(S1EabKSO7R2L+dOiZ<=+rgkF9Gj+kS3_I*}n%PUub!=&j(|@B1)Qlu)Z&frJebP;eCn`e}%rU@SSbkOW%itM}gVT9enOW|EtDt{)gGWcc9E8_#fCgpZCECbKL^V zd>UxK-gdq3(?a|+))^mZDgGY2z^oJAR{BlKgXcTe-{a7E^Z|397VapVz79%lK^pUvk)sMK@En!P{l%)1!Oe9!yn z`hN~)KOO_szlZT~F!E*wng8xVITNq%{p%Tb4cGb(Fzd7#D)G*6v;U;*H5$zN z@xxV5g7N85n(rsDtoIn<_%Ms#4#xTHZ0tAM+mF@t%6Weh1colZ@vw6qYr#DBGyfJ5 zs;`&XqrlYp9hm*JQ4V?=^?3f@2|8asUop?OlXPCME#I$^k}oC=O#gde_$8#9{R}>b zM_$jLE&n-}>K_hfKF^ur??2GE5}5k=c;bADn7yspOKN;lMYFfY-{C;npug;Tb#1E7 z>j%3&r7Qb=59Yi+!S@P~-@O#fet$qb>O}MevtHX7+HauwyTQ=uUjj_MbHUVC#Qb|g z58`4T;`xI8&j-Wqc^}Mt(X%99;B$LEiJBvN!^&EGz0Y-hI$OOi^Th6245q$ZVCW7# zWA?--sTc5%#rH)#>*v8d=)YyYa2B6`*l+hQ)ql779|AL9qH(*0Vo%%wW_FIfDvmBJ1_|It4FTh0F#^ip3nd=H27 zb(sF|SBoC+X=c9+Mp)Pcv$u=W^&14{e7^$Y7?HDI62QpkYzaH-Enh3~$vN}51ZKS? z)4y(==+EZs7v?*$UgPJR{=ed-Ui>Fu>V5Y|u}8ngdU8G+e^5>}e)YZRiP>iBJpc?p z&-KO|ke~BkW_)Rl>IpFZ2lIfx`>@>)X$XdY(nc`#l>@V{wPrt}_Ovg-JYNd^5tc?axW(`Nf+gUsh)@^G{09`F8>{ z-x@HE@x#pS-Xa`6)410*(U(5U{DZa&$C0Uj`ws1IoblCN!eNQ#fBPq$XDXO_-ruA3 zbJ_e_gK<976HNQay;|?0`H$Tv{vjtV{{=ATd)4d<_DlZYyI}Tr|DePt^L`Zh*&$(< zpXFbBSn_#S15H9hH1>y>0(x9MgJZ!OS=9ckz#k zv;DaGgmCyR^FIql{*a>B@9g&m7-2z!ZU5&zDfWQR?eWqa414+p;|fF-$y}_&>@~_wfAK3m_dq>vWnPB^A%{|Tk5AK(8Ui0ot z{R}sl{rv*QI{BXhb6$fUX#TrkuHSoE!Y=NA^3x}hFX@eO)2CwhEet)3AEli94w(6i z{U`aOdB2o;=YZwB+4DS8z1+{Vmwu)Bw+>5NfH|+2atzrBxe#Zg3-+ShtZtP<`5e%IP zckTZ9c;(DYLMe(~2)@uW%-dd=KzEV4Yxjtv02Zx|g^Ph^}wZPwVym70F zQZHo|nDfcN?_zL_{@LP-RMGf@VCL@*rv9TA-w4d}DQ1rcqkc#lnDhNlfyLMABKF{!V6ICD82vi;gW3Nn<7KGNeBoVH|2pgEyY8y*Z!rC@ z=irkKNigX>L4HdGWvnp zhd1hzyO@9VQ0XVF1DJXy^in-!`p*F482O3$C#yYurP+5Y`))H{Z}$Dh7r^KvHN|*t zZ^`d_7tH>?>8tDczU|NZ{d9gGfZ1R9Fsbk33#OhLV9qON{Z{suc=uPxNB>obN8XT@ z#`TdObMPt*<~;8A5&!sGwm5#>J2St{u{uEcR#ZIyb%n2i3g0oQh%Q~<4E=Qn+4{2tOiqG7?}B)4;Cq>!gaj@pAIZX6r+y>Kb9R3fO^^dE6@@ez`4Gh2F z-^~9ZnEf9Gv)+fA&+nx1Vld}*%KQrs7k2(`++>9Ix8MA`Id#AMVEkM;Vzl|^9jW~e zGyVv68X!YDBN-#c3OTR$-8eRz!K z?`B*eLhMPMEq=*3wKoTIUcJW(du6uNd6Yyv@_R(z|?Vnu;h<@*i_?R z50v=yO~zyKctRfkDPYF8#`Oy9Xkhj@TtAT~q8^y_iiC(gp_TCsJip+4bRqNqQ=f0* z(wb;Laouzt)4VAXBBOrh zFyrRPhx2K5&3^-)UpSv2;~9AVV0?SyrsxNCyu-n)w@~}Z>}@;%&!>%(9h=0soFxPVp7zf`6VD|G)edQQ1_0$efeI3Ef-{K>k&xc^< zFX%6JpNsX?J`lhAX8pZj#>ao4^X_MS4zDj!FYe*T8b3o{Z>F9%9-wyLi(u+`p|4+) zZh={UwsPnlv)9DyVbqEI+w2d0rN0p7XMOu!xc^-+`_1_~eFaTViQ*EU-4V=w_Sx@% zI~x}OBP^&Bn0gKr6aUbbVCEb2j?_!6XWXKw`o9lm{SsitRkHY&g*CpB@mu&^Fw%s5 z2xfmx-x7OL88G!+E-3SK7XmZiQ83PX6)^h_F!IN|K!5ZfUO@cAOTx~&Epn@#ZD8u% z`%>TUeQWDI?}fa-i(PN)T`ybTUv34{|4Vy6m}vgRl^wgm)O!l=AK{jsWbr?Pao+D| zvxh&D_lJ)E%-#shKAxG~*ykyjdY?QL|Ad=h)=vVnzYAdYmmlw^!HGpJ{$IS`rjA0! zy_Mr>XPx;OQZL)nxbqG5KVkDs!ux&1$L9w#PiHX7CgpWGII8~2|P=e$!#u0`H)5CKVXH}U1Pz_ zKXt`CUcMW5Z(cPwi^j|9{IV=()jY4)1tf7m!oIl_VcOnp7ge>j-)JE8T{avmT3zm$BAc-Wc$ z=4|OF=9I;605eZ2nCn<~j_A+k^DXnGfYHA?^fXU_+-{ygO*UeC$jfpK)+1GC;vFzRQ#F?#^& z!|tDf>mTzSgMPRL6~^l;`ajVABZBPp*tS_xKWUuVC(V@jl(oh+T@oMmm-*)hqn_VQ zULS=iseHaXTM0b0={T=c%{%f;eL4C02OEB}VRSs`%?-ydVp8GDC{f<=* z|Hrtk>A41G{l9oSAdpt^BcFy~PX%=x}) ztMMO!srLyO=RMyiW`BAE@?#KIVV2jrgZdHG5Cxh!`;SjBhRZ{dXF#57vH9 zT6{h*{DRZX{#z@Z?_Xf*+totioj-xu@A}3%-=1L3<5YdICsZ+RUQ_d3xA#|H*AV}t z9Y)^hO2S`{SKuC4X2qNGQsTYlmicfIj5%iBt9<5?ECWyCzH7z zck%r$=AUGI3JhKG6D@up7=F&2`vvdn_rYSmHT$5K@_n(uU%~9>2ELC5Jw7+V)Vl%9 zd=J3vf1Z9{E%T|xhv9cVIG^N)`xms2)$g|@jt5i!ANsqUm_)nZk@`@--!>ZeOK4BK zFB}sGX1y3NPKT|x`zgk88^P@Nf!aO(H2)S4^!tHtz|`*oV?THo!~GuSUjRm2w2$#f zFm$Gs2GieR^{N}!!|(RspV`WI_FdK61I+$D1tV?TCuYBNNAou`zHwXakD-V4huzS8 zLrw3YE21~}cg#cjxvcqX+Wh_kGk;mLp8`XtUoNw|!JPMGTQAzdfkTWhXnbm(laQLHM`YSMw9-nGHM{CrheJL30mz4;n?ndhGQ4Ialf7>bTcQTm%-{AYD zIGuh3Og#%zq`!=l=D!XMd)y^3^*mAb$Zh*2FY4iZWL;ao#bD%(S_EdkZmBx2KaJDQ zDi5;zlXt<$?;2+JGf#n`+skQof75%@>;s{f{k;ZL|BRzr|6{vf+5wF7!41L4>(SFV z$hfibNHFK~(7u102&Ud!VB}9tGJ72`_5EV@zmMqpxWUXnX}{D@nrZioTY=gCd@%Fn z#rKa_6FamzEft8S)uwqu=!2^V?Dg9+B}V8s(?9<5?@Qa z=RS)s9;5YmKcDk>xU|H)Bk$*PUNaU+eD)OM3ID_N zd-A2mN11)gd|jVdF!g<`9Jd}!JsI<)pRA)`&VM5q$Ef3A<~xVqpYZWC-t3oW>pTN3 zeiNAclh+UWd(Tq;5$5lM-|N60vcc?KrmDUh7XL+r`bT0Oj6XY0`{jC5?-ekPkqeA3 z!5?$*|K0q1kC%MzH(=_23g-F`vh~O{LGlNT12g|!_4k}>ya9~-K1+>fAV1vF4_N$H zW5piofyW>7&mN=wmjZJ=mX21gZd`Aau1_oT-{@5RIoF5xM+gV5f}MKy4H5RaYU~px zoK^>)k8yo^gzCKN8`lS8o>^qp@7h!Pbv6YvU*ad4uetf(=^=Ipnf8ytI3zbQPUs~0 zgY$qn??Pbae_?tCbQJ%%2iDJUht@j+roP&3b^WG+siz#6^PFN_5R7`hWagg|EcQ@- z{zlHFoKy$Q`TpEW@~6}UQ||^a_s_@1X)PsR&_Ih{1%};wgz@$k(ogvJ=I?GU{>eAN z%x}LP4ax*l?-=;w7@cMDecGwM9X7wR?NvWN|D@jiZNwh<0?d4OTWh~R+UK=pwg04- zVEUIuKIHfR*gjv5M?Rd-o($&vu3(^?-jyA$&g0 z_;VrJ|1&WCZ(=`S9;w&t^Z2INFQ}Kq@1s!95HRy)gKmQ z;BU0#hoNve{6GBP#M1bC24(SGF8ucc{=1IH@*Q|r*mc#|4aVFeUl~trMxA-e*b)hs`&xP*d`S^6&64{zW6vliD22xT+l`fADnsJ3Fnq zh}}EV?2CG;{+z!%*M5-X%PtN(`!73E*ynAF?>kESDPr-B#t6sp?-bI%>Nu(A$-j%r z`k4`uKk>BnGibc_%fB;3y)7n6zm8L2#z#krf6RF>`~4tF>c_q@d)$2S_b-Zi(r>iZ zD-Gs){u?74)ywouT_O3h=7Oom{~Oi6*5XfrnP;2DyT8-;%@$vIjmCdyoW54-JNb9* zsMobl{KLtte>_q9IcN4o`$T`zBQWb1@!if{iKdEM6#zjsw zyGMY=lbQEvUGYz)Kj(S&V~rnS>}VkD-Pz)AfjQq6#swNGR{?XrSJgkHJec|aRF3fi zGyenl<9t+ZvwJqydauzx{kJq#JDK^mwiJ7or{y2rS?uxE!R)_&7wIpwj^%p|=KMp< z|0oz`lNT6Y2oe9-AHmc!r-%4w9yC53D)j=+fT?F=KZy^!Y+QPv)Xzva{$r4^o6LMG z221|HG_ybdRQ(T`-8Wo03C#Xl43+wh`CzW^iD43-J>K|lr}zhlf~DWl!tt%atoL}F z#5?(Sxf%b?M2)Wnrv7?!MZc?tagTWtA63)hdwwbXMl>+{qeT**6bxp*$jz$vpPcnM zD*hn@!PMitDC}L&?Dg&_m$&s>eqZ9x0@y7FBPo&?JSGYc~zqPM4zNB3*ZWJmae*fWm!+O8GQ-nGlyTHsh8g{UMdAmOC zQBL6Bk*0sBm&C{A{9WOEMT#&k%g5~diwb+^{N3vD#fmU4vXteED_w-T;`w)osdt{A z+An}vztj6tKa+pAlU(xy;S@6GxuT9T|86zozYWy-kIa6lf#^&B4@|uuHkACKIe(YB zR!6BH6#+fWe>Ft>eV66**Gv49el)!s`sqA!{?6U;0ct-8JLlUqTO*(NL@@KbHg+06f!m4sZ8!g0 zD|DWNFdyy*&sFMw*5*}dwbs7@<~+UyW4>88&He_AxcD6VzhKnOJZJuew~1b#&0x;w zs{=aEufWtd`KZpjpK*^fVh?R?@lmOgFQt{)JD-#K-c7*F_t|-!7uT2h_JEU@jf@yYxpvL#=dpKL(_EnZG%hd2iW%%LC^AIA#0sF!J&7x!3HmVE6~dfw`Vt zimKiKvztE8-PrHU-vf5!i>d@>odsU1X9gZW?CT@U1BbXWVEViANk5rK{!#nc+`=i} zfZ1PIF3FeC*f{x(uE(z#rstKcm)8(5>s@=M`|IDoHUCO5>O?mLvwk&YN6JmLPsDn& zzX8U-+I}F@e;gPG-`>W)VC3_6fH{w8V9u|k@$c#%SHSq{e`-H*L-l2uzFlDUzd`qt z_i8Zvef?7WgO?azc`fXj!_Bq-z!=L{-b2Uo7jI)j;i3YhEf05jiiFk~cm zFkXfAX8bBJ`}NJQe9rjT+rj~Fz+BJXB~WG zqI4cE^N$9jOnMZU{R}s5it7XOpEdu_z?^5k&&A)B2&TS1V4M$ZY|rP*m9yu9*vW!i@420P~FKhmBba>I_a$x+7R)IXZf$E^Q&yZAe9TYURnQr~l+J>Lxib3W6+T#wGm z$@9Pxzf=8x0ki+RJA~s0;rWyEtFTr3TVc{dH?Xu_>dE@7T zSpj5mk17jh{U5=I%d7-u{4KS|S2X`Im^aV+f;sQkTO{7E zv2k#c*b{=yfA1k-{{XWuJ*oN%f~hC;tZ?vd=wtma!N~9bll3$Bys%@h>G%Fq)-NUn zOdSp|j$VJ5{}eF#@w;gLGnAvQo4?0JvAc8nt)=->8bS~AeS1#wrF>%gU0}{{y6N2v zM%zJOoBbvjkN1de#)Xj&{-KA#oX?&Mk}o0W-#M6x`n*28fSvvB2U9hsv2#o$?`j~xvfnqYJ?qKGBQ%LNo?akh!u-IK>>U&;9>N#?_L^075#eWBZ@n4k` zyI0P?YjL8y>T#NVMn%aNHyq6M8CO|2o%$sHeeuuk3}%1Vs!G0;U@-d`6(IFI-8QeO z^);UdnEvlKReeRU->A1oEAjW+V~^i%9dsTaf@$y7MdCef+2g->SBZ~4YuAUaAsT^)bIa^>hBGv-rr$|4!`+!eLHSE7tH)V z@JE`kNnqydsvOtf{2M8!_b~qnp`zdaOS>Lt^c8mU{T|~_4irvUYuERW21$P3ukHEZ z6c{?A7lP?uFI@EwH~$1MbSL#Q{&$G@r*t-MFjV~AWa=LTMw+0WVCLK4)P4>cPZ=fo zd>(>1pBiIi|AlmgUdC@yPFx12JxV!%??*YmFTgmTaMb#1IZomeFBxx%kb15=7Jp@e z*t4>X`%P9o|ADz5{skkS*HeqHJVW{kK4JEWF7fw01ZMp-Fdk2-`@qz9ex~#j`Gs+} zS&}bvr196v2_21{V8kaj1#>=ObA@BdftmltJgJxNYxZ{+XgxnL_0IoF?8%MH?pmzt z!{=k#i^YiD6=wDa%3*wdX1z;b=+1m?{`Zz@e%>!({U26|-TAHYi}k_@skYzxe=qsN z{xJKH1esR`->&YbCbU?cvY; z#rKQ!->T~qx7hfg&MS6>#gDx!{t2_qKH#3}p9!Yk4G$%MoD0l4)v`oy{1%H30poPs z9`kPkM*V~e*59*7;vcot`swyq?9PkEEAx0WJ~`0l8Tqca#J9BheOlR@eFo;(t5*|F zsslUqT(9ZP`2=*d`38R^-#PFLG5c9CuNPsK@10s=j~Zrt7Yw~lGV>(W7f#6y#`%W%PcZWpD5vu&2&UfprG-P^HhX#r?bp}rD+$0Ci>Y0D8Ymz^@9GLlM;_-#HlHXj@d_(Z~LSLD8z?@HReLQAofZ6YOJl=7P z{?pj4kH5?f=0EYg=nZxmFLi7Fwdq>#MY6^>08{@aFm$BV1G8Q*7)QSvV9xtAu7^1I zKEJBlH^14x z)$4Qo-OH*s8`p2d2VDZ==us8%s2jWm%=)KMANwa_k=frxJ?^IwW*?d;{_zel=NG(9 z^)xcBzgg@VRl(Ggx>4*NZy6_U(t0f}X}wus&g;!zs;>f`kErV?iUXF#TWSdWAZEJ;BVE3;UPz@G}2t zZzNyBY0H1WL-xPx9GLyD%%zX#E5@0g@_5V40yE#MLc-DMX7_ko{Npc~{X!|>@Ug~c z^zrJy;ZM~!rlQmf`V7o^7jgaKdejHAAA9^q)i8V2+UnoP?4Q~~Bfu_q5R zo)WCrhsj{(9nw|wxVwQ_Z%&ACaBZ{q?I!;IJ{Erq3>~3G&Az>diVWEq_o?%}0OM>k%sKxNqFAkK~Vy0#kqee$s#H`k#fB8Ap zcL)ssxW-`mKb<3X_rbH)?|fa)reNwT^QGp?1*X0oi=>}`Evah%XPN4)3+DP2`C8{! z2TcEZVCZmEGkbv9OBm-_EcL@b{zLscgAo>29!z~5)$ZpFrk>5Hk7H6Hv*(^I{$WGT zX#BldI3$7fVjQLWD_}O5^%{@S_z#TlKo8n+?LMLX&z&NABKm{rUl98Tbuz1%{X(Spr$0*3 zdaoyne_|S#^V_QVJtM)KR}ktWPvF_#)&E<4{KV`4(>~DbKY&^9@5wrk(qQ&i74;Zj z!tCdile{gyk?vRD{N_L3CGjzZ!Ca@Ib49w!8{JzrTxG7O?ki`@poo|*>C5)l0WHBF!T4=ule_z zeHOkG47Z?dVAkVzgqe2@nEIb8C&rpRN&S<*0yE!=eNxXc*z5sde5uf%1%={(S=ziG`roK7Lwf}f9^>~3%CV8E4*JY;9IBcnK*er|B z(EXh?0n9m`0i#ajFylL578; z{2yK)KxarPF!kP0_AUwLdR#a5GTzWn;$6!QX};yXBt9_^%zDudt(W+#>Ur5t^!jxN z)1IO1*#%5J=h~~D)?n64Mm+p7TNsb(Ao)|9oB#H1;vdxB>?``p{F2&%IgfjTbv|vt ztk-9xK7N>=TpQ2#C=*6z{U7oCjq}b{Wx&)@4CieV%6HGn3!SD~hZFW!WSDcUh+ju>g z`OcYt$O^HiZ3A=tDy`J@2r&O8VARRXI;eWqt3BenaRV^x?F2J^My%$aYTPPXIDRRZ z`d{kno!EFV^|r_J9gaR5jd$Vs2yS7q=Kl!$g?&yp`x-F((;~sFcNgo&`A_;E=6uFm zd}sKxU#G=~Xnf>@1KQ8C-V*OP2WFjru|MGN`JM6j&Y~xIp83zm{(?O`0?hg++KSyZ z$o%WI7JacD&EBk)*yEa5{D$VjL8ZX#|Aewf9P>H+vi82Ro9C zqxJFX8gASK>y5c57Bb!mM*fUfd$gZpVAS`04(7a~)IZ`RnCq3M_T)BT)^FBb`iu42 zt@C;vBKh3+eo}jHF!$qSFylY(qVtah-pkFtEL3?enDrX<5xs%ajCX>O-#HyjeciQR@6W;Pe~j+` z_;u$0t37_U7)SS)`pNq(esP%O_c;!xo^}Jp?t9MsJL>g6Io0f$VAelo_KCQDqEDYa zVCuOI#xZ7z*`q&IE}G*HhJUDs`3HhgH{;n(olgMbk>7C#%zidPAMC-ufT{1g>W|xR z?3vS##aGvULyv$tKex^^U>TVD?kH!?F#F+N+V4;>^S_Jv!Y{Fd*&pcsan&?#j(Y5` z0+{()K_8A0Wi5W6>J2Yx{-?o^k^Zi6Wz3KB%1+e&cA$Uun+j&WrbE=e7fk&%aD9X> z&nY>K*X!{2?+fPsy6lwvLFJ4S@%#mUzXv-sU++=E;Y+~uuMS3?te#-b_aywm-cPn` zJx}CAeEfJY?K|xK!T)h}?(tpE@Bg3FoK~r!Mi?<+LL-f0g^7k()D)J(kd!No)I>2n34{#pJ{Sutiw8G?@s0TkK4KcR*>({}m_ebx~^Dh60@ss|OF3)Cs zG%okR$|srU8`u@x;PQh8hInQDT;7G_iTH)xVfAmc9q&oWuAk2Of_>>5FPr=vSam!J zD^4f$*~Slnm0uzLl+QsfUqC!KYr}GrcP1b7Gs|JwD?f1wtoR!}zd~5~4}g(J?s5B@ ziO2r@n_%V9%GRH_Yn-oSy-+<@x_t$#`cHE{$NH1<`ZDwXu+8V(wXpoX3A3%Qgq7b! z(~nGrRo`_m@hgg4{}A$FfA*afmj6?nA5=&GrN%p~e`%9nvUn5d4}NQgIPdWOXTgfM z0meL|r}LrK@2cr9n*4d{C4NE?tp04b=Vf`5VdXd2&tIdRhuit1@iJI>jXTf!*%n4U z?eCNjuX@`OtN-j1Y&>dUk=~dU?e?*9vGRyTZZ)^2Wfi)flFx#qDu<~DL-2CAS#^voS{=kk>nKlk^D`Fp>O~Fb0v(tIL-Uf0BigPdcOu?kH6HLy+0>>8@Tok z*PjO~ue)6TGg$Qxb^e!p$gggIb4fJBi(Cq;f0KW({#*^qPlnZ3od+x5LmEwgB&>Qz z!1ya2@A@N+6CZ`u-y@ti!17{C)b-!6--pHUyrd!M&{e&gd;xG-?yiEcmsDI5Pu&I3x!UxWL5+j&<^K0VkM z>~ZR+CSb0AA?%a!?65i7&lzy z@}Kyg2K&b89{=mx0;fj3-}7z?@$wR2`TuEP$R}qxSl_Or)-@$c}xVP3s+WpmK4cn_Ap zJ--M2rijbu@3rq2WBp&S%k-Z_u6TWawC^*;s_)D1g8%pzVdcMKr|GYN<-f&_;4f~E z%TxJYQ^$9<*Y|XteIMD|=i9%VgFNv^SmW~wOq`^DVEJG0VbG5>I3N06ke5w&zUeK? zKi%!GUTgOC-mltKfeSzK_$Tu{vHG3s)lXv5(ZokC77tU zR{WD-wvl6Q@#}r`A)Nbzwi9Nspfx;>yLraPkzDW zXP7)~3aotFPYL!_g)YCJ@8wnBqs~v;_xh0)u`DZ`L3j2?9bot`eP@VzfK%alBYZvIDMe=W|;X@ zx7d%rw_*9+;>TYvlPAXe`6rL@!B0w8Sb8mstbSeJD$fZPFXvw8y%U3e-Yi)8SCJp~ z@vp_?)I*)=yI|$F!}?v=!Ox$qVDc+H9acYDS^pcaaCs^HB#*3Fu<}WO(W_tQ`u$9v z|Aq7Kj2H64ww%9}Pa*!XE4j$8A3lUBqv&#%-_3X+Z|v{#iPVF3p=!_q-cn)pI<5Z=$*{b@>l=eB|qTQ~U4b?@92Ne74Jbay-G+=eWF& z9e?E)!}7NYCXcKv=Pf0{f6djf>YdKgfnq4)P`?A8Awm+yv^?@i7}VGoyQ!18xTS>W6@F7IaRU;ZYa zA5mETV|)wiCHBc;)%y(VDckhTu=@Yfvq8V9-sM|-ef}0!zDMx)AK1rfzG+*u*v7XN z@#XKWh~;x6EcwD0Oh3u<8}_30^H^B%j(f@MJG=f67_)L+@5|rK#u=Hg>b=r9H#;WB zA9~HVIsd&R_>aHc`91QZ{(@^@woPySn-!F3;l}} zx_leg1Lzk`bb09to6pl-{x;VS*d;v!E5GghJrUcA*I?zhuhQaear;wN1^qJJUnySi z)z*&#{P_7AW`Dg{_1yM)h?nxW`|rBW{O^TT-y3fP{q!GU>F2%~^lQFx|Icwfgukk9 zU4N`yFE#6aL-D7482Xpk;QZ*O;6Jqade0FRMT%h|+>0kY^ z^(VI8C4Xf3cSkP&ue=}npL;H>d}`md@r>P{&ZR%>Z#>!cpQfM0D@buJg^3$2aK0Fp zzF7H;vGFOM0;?Y@s)GOWQr8~}qn|q8`E$l!_5KPgp8@>68C;s{_lw=_cuZ~b`^9^n z3Gs`YVb%LM$EW)Lx9iu;HhHQ)A6!4(=G$<8J~+zG2U+uA*+0qoMftz#yy=0!3CrC6 zV7opj*7Hc^cLYp+l^bBydy{eYW|#jp-s=4Xmj9)&{BLo-t}t-ck^VfinDZxX%E)y7 z^uFM~X(%lF-wT3%#W+~;w~sQO25USg4-fOFd5Lr39l>Aj$FTZ8V5sq1&ResCeaYvr z@_)X6h*wbO@{N5%|1#&mihmufZK><;xh%*dQ(XR~ar6PdC4=cZAnZbYENas1Q z{N=j-rzX$70am_)ut%Pxe#rg}z4*Vg{O>+GW#>s79 z_3w*IL;f`fxc-BeSik>dd=&4Ki-SD+t8B1OZo);wB0_Q{d$LZ4PQH-onhm< z$@$9*Lp_Dnu>2>&n%`?(KB`yHZ`6EKJykse*UoVL=V0`+AAr@Lc=Q>!;(J~GvDxR} z-Zp6mSM z`BtxvFU4yElV4Q%$=@42g1^KmuMY-VAb2bn~mps zx4-l(%csuu^STC3+5s!xqBBCgv~OYg?*ii{;|Ey&MxP$^tD0Q@?o*BTyF8V1goEi!;D8$Dy;mY9Rp{l!SZ*}QK5eoJ>34*BZI$Uy>F2}|9yzGKCtrn z?J&zMhvj{l5anzFO<4^6$j&F<_S;JD%$K zy$0eYEq43X##Nec%4ZY57lK{Qc;~ZCUN{U^eQEZ4AxSsD%BLGlyxi-Z$J_6XBn^NS ze<8mYq2uEkSpL)ay$bdhOD_Aa_WKigSHbv+dvrNQe!qondMD>Izp;8GSG^s-4xFI;6fdPAaDF?N zNA34u>JN5#GOYO>^OyENvp*ZT;=Qrm^6BmR>tXck`Z_O1U-|Td6~7Dqs5_eN@)_p8 z^ln)G4*4qdFYZCt&muqhd(ycP#!b;|SpD8&oDo}(-@smdo#gt1VEh)|=lT~LH)}nV zUIeBOjd!}d8Gq;}-QxTwj9#(wRlI9p@+sAPQau^iYoqxnUTO6tUI(k5MaJ2hkLvd} zm~Ddkq4+DY$6w|7uK$twPwW9J-ekrLKj{~{{1q7e#7kktD`tGfSGs%)jNi;bF?}2V zggjXOzG8l0mOKVlKI@o2aFP10e6IM;`Vs4ArE$g6$QAD><|B3`OWnQ*W_Pu&&m^Du zz18;~taziC&-ks;^_BR#AFbZldVeP@e_C%8eLIz3H<-cgp9*-;9rNK7{o^c1OXgryI)6YzHef|E8 z{#5CFBz_ELlOdM<-?knlwsiZyoYf!c-(>Y>{_T8~)te$#K7+mf-@ISB#*y7F?+jB% zzQ#-SPVjtmK9~Rg#AAQvM&}*29;UtH_D@^?6Lh^G`{l-2i!;tv2VW3?f~4r1FD>kRlRee_O|;)jN}UO7d^W+-FNKv~GUqGuD_!9J zPO$S|e8lZfbomO`Pl1V_^|9+G8Yg@KE58){<2U6yx8G&?Ry4Z)mzHl_3!gvROrEd# zqWlhYdmRtTuLu6=M^5Z|VlK@7h^}AM{~ut&ChK}coaMjABvwB2I6o_&(_zi8EnE+1 zzm6BhyMyZm>{4}qCH}~+ACkq=ANX&O*LHM1_rJjT@~8Z|JD&wB{tf73S9qbzqxhr0 z*;l&#Qdsp2bo~JqFYazwc~y`f`b}eD+xR5>=zN2Z*Iu`O%JgggcKawy zzEyGl{m(cX&-j)w`^!!tAL1k&?DFj}`;*$j%BQ7`U*+L0k61nR$H3~x@iv|{C%b%? z^&`KR%ZFOOn)|`>cO3myyj)oImDqSD41<-=_b_D^ zJ)3!(>reLU+gn{8@A53?@)p6qR{1I31+cc=VAZq8u7`_Gfz|JIady4l!R0R)C$@u? ze>c<5Xzlv@Ve(B8tKRPT$4zof{I>hBY$WQXv_}mMVPoc(7`LyEt9eKvj&OgJ% zE&0KDRV%x`7pso1RI{etY9-G163fm8o+{s-24+z%`NuH0|P z{x4Ymr@`3gizPoUA;@!L@^-C*yy9QviZ|LgU-gMo+E_nh^^S+xpP+i>|7jS%HT&GY zd)weY{X1Cwcp6sxdgpo={gkaReTtiLc#xNT;s>PG_iZ|K#(<(vg;{a6btzYOm8(2KkZs~=Ev3ToY(nwzA z^6qwjnkZI2_rh$mR>I1s{urz0WtW$9vUti*@=K2m{&Jsz6+auszM>pf{PD*5^IU%w z%>ERum$Fad{+a$Hiq)S!#&vprB`&i2>&zEn<(J9*H{1M(%Ug1P4yVTA&4BS&sd&mK z=|mf!g|5FECT{a0_cyV#^+W!Y&n6iA>HlQ%ye-I8?{4Fi zZ(-%X!R0#s#NA;wxxcx;EyTmFW|zxvg7KTP!{x0_9@z$~p5c~%;b+dLpJ4rb2Uh$s z)Q|sa%{TEb`bEBVV)d^WMqd7=^KbMQZukI}|79@ot2Vm4yY;_V^B=vqEYr`39gnA) zzuY~@6>q%7OVs)z{RzgUtvLSGuO!n?Ztv?~M~l~dl5>g8mxS2)B$xR{{!PcZd?fQx z0p_ceq^7cW_%h0apAo$VdJsy8IzK z-ZM*J^>YaIAy1p@`g82~ta!%xcjMaUonN&6G%a?XPd~9QmCc%xoYD}2e{8%~!RSTjAXh#) zJdY%wx~E{(+wK$_U-et^p)mH1tK8oLlb5b`c`u%CDqrOz`%`)Tsd!@Lvlo{CS6trj zG@EZrVf1RRhuJ1*zDR!<%(htbN%A&4U&X#s`6-|8V7B!OT^=3=^l62>l?0jrPSkw4q2OPnu< zDI-HH|F2W8`qc-Pzss5baB0lnX66I>4Ly)6-wifDvc>AhAfGR1!HU<}`Wbh)%Nsae z)t?q_Uv0;4(;r^nOD0d>3CsRP=LWCWx$sL^@pig>o!ft7`i1Yi{$d!lqBmUL(e$&| zxP2q*jmB@a^El%Qjfdhd_3M)gm!AW(ziOGwbC_@RC$Y-;I={a76;^)+!O}m}>)mbg zq7z{C_YS*W$?5I=*=zGTGt=dTTK=mMAjZ0lvM{=P^3tRTL||0|a_S^hb{!ty^6mi%|u-^ckCv+6Tqe_zD;7`@`7 zolk_3C;#U9pV|4kR4ji-b3Ru8zi@e9+{%;4GJa+!?1uOn~*RO98^z+5?KL*B6b2Y5^DKNW>biJnfpN$Lh z`rWRd#q%TTOFYc$|JR-e)^~J{L#}?E>hmd4KaYwh`1?PS;Q1k3JW z=Lz=wvg#37{n^g*Hu{qAARO|8(T|LG{loovrTj~Ov^~!&n+_}fkM?{r`hx50`KIh& zart24sUN!DQ2+0>{IcGIk*CFuk2B4_c#GTLjeq2I|2W@o&m%M2`+9PxadAgq zPhPg?k7;Mas%MkclhWVi&e3e=7p(r&>tOY1q1iX}g_Yk_{Ie;F`TK?E`Ksr1qFJzQSw+{^7BHLkwI_22RL4VS}V+;|>KyzEhKUt{$~ zC%XM2dw!c2arz|~z~>38$v^*mVpKh}M;-3lw-7{-Hb!qNWs$FpGiS=thozwzXYJWKkDv)qoyn&)82 z|A5)up!lkPHXrmwtltEwKC@=>AW3{>1bB+u~*DdPw;%gXw?TFj)Qk z$o%JI!SZt)O#b=luOX~k zl1|3uu3v8RF{08Bgj+Y4+>K z2aTh8eyM&Q0u!fD&o@=yYU)?r4K817->c+*=G@A@S1A@tFOT_*eNycC=$CeUL}S;> z*V_DV+UNSe+4o$9r;(rH54G>PYP&e!&i6X>p-~*hkMDm-t2)(rn0?PxahB^}XWtKH z_kopvSO1RKYpXx{E=Qdw-{}cLH7xHh=^{wi;_EXb;((SX2OXs`%HJGqPvHP#H zvDbJmMXr3>d}j79!}5OxjNg(~&RH<~Wd6Ru71VA{97%S|D_v( zedF!U|EsZlu7y?4LgTEfocqJr7sal3Yu*d`C0dW=?*!x8Yhcy){<|h0?!3t5bDYy) z{55z*%C&yZnt1FGc5n)%WQ-%TL!2lE43YkjE<@*>9){^3oYDzXrxG zWva{nS`*}n6JW)E5ymWcoXZb}*`FR8pXXKw`x?y$#a{@MZ^=cl;vY+V*&pxz+L14u zagh7l3Zq}~7xP#4qha~~zxhi&$ZMm>v5QMx8{!pj^Z93F_V~}a1y-B`IR3FO zxB*r^T|Th<2e^DPEIqO0Gj09Iy$+VYHmpZ%qw0sao2^HwvFnRBY`x2kosagx#7pey z`hVDZmDAPvPP1?91gpQVn*W-1u;RaM>sj8RuKyDGp;r>)9=@I(iCq1dPQTQjW1O#n zsV7}5|6P1N>)`TJjN|k?N%g$z_Bvn7-$nQ*jcUEGR6dVcKZ-tv)u(rCy)Rwo@~7;4 zlBoA%(w|`G!^D@J8(`wZiw} zGj@G)b6i%dF=h_O3v>ZpB?C{-p}oPU-dudv;SxP{=)e{ zt{2qbPhsUV|0_G5YF$3+Yn%Tcz^bnrMz632RzA+@dfq2)Xt4Sh!Sbi?x!I;a4y(TP z##Q5-NBj5ALt*8+*shmKu6Fyic0E;*>GEk&o3HvlO!@4z>$BoMF8`D3Inv0`_hiav z|E>_fEE`t*(;7qlsd+B<>&?0X=X|agWp^K}eDwW4`B#l_`y#GKjnQTa>19L7E)_Px&0 zjIZ+9iCq4lgz=N4@7bjPl5ttQ_wym+`UF_=1eo~IqrAUQ;UD|(eTn3U!pJjEbo*)K zC;$4sMfuLL`CcEBKg#hVf5#wKKAmCJb2QBUyzSdV{&DSL`5$SVp?sx(ER23#?EAJ& z9G}#itM7Yc|0#@J!W*tX)a;X&!|283IzR9Ff7$V#_N40%hgHusSn(TJAE=}LG3N}J z{f%PP_YCWa{A&Cae>^OEeeWec8dg59I8S9gVt-2P?-f5Yj@;_<-@Y*UHO|#`ynG{G z?tC8CEBHxz6qdh>*93XdFj#t@as9*os;;hokX;WYAME-`#<_p__vWi%`jn-=r&Rt& z#>%(_!_qrXp~%{@zLPe_U$vKmG5U7QSHlEOp-ToXxL6u=1O|F!Uq) zepvoKofG0k-gW&yW|;rOJ)a>{Z2Y@Bmpl^uRmA@OW@1s`ghJ%%-%k^QeVqQjNcl}0 z8|104z=~IKpYbY}Uo$%NE2j!p{k!vnJZm+qe0SVw{a)_!=Wh%7M&~<6hX&4k3|9QA z++g3Rzb{a{sW+SdyPSWx$?6#hE5GlJ)2?>;#(_3p+Bmnl*7X0NKl1-cR;aK1Tj#I) z1ymcREd5BU^}rT=qg;P_pz@`<}7aE<=HTlM~t5jgKJ*MI-Q5U)UgucrDR>lN~^ z{|}b`yDtdwa`(Ibe`zNF$@PCb%lv-@%m0wBLBC;>%g;aE`nv{}zZXso^6KZEFFw)a z=R21j8@To;x9{1(^xL@no+E60y12Y+`w%~+yUTxS8|?ElTz)T1+^XKN^2=`>{KfTg z{p^HbAHBfk?GLl@I1^U?b{}H?JHs5;Y47~kR()!?()qwWZRNjN^+-SWo3@HmycJeI zTYeVwliU0F&fXa0@m+mBeDX$H*)={6E5F^a)+7D>kNTDVR^U3FU*)gj-QX{GC9Hft zdN0@~==>?}TodFO`rcFgGIIQ8{s+t7&u<5gbo2Auls7~ENxJ@0{1(fCJnwX_pA~Pz zyx>1IcK`R@T#KjYt&;bgWAz;k%YNQ0^M56*epEaW@-MjF<$p{!e`8%E|R`@`9r~fsaW-%2UBN~?yp1q$su0;3$Xleo)oy`73V$o zhj_&s-M(L;^?xg@ezhKF@nX*_^2S;|`aVeUM~n>d3jc9`6~hA8C-D43@{~O5XCkb8 za&ygJ2Y}w8!Ro?|LeiHuk_}yXl*Zt`6I}SAa&9L%+ z@A@Ebs)1#{^g8RWp06msYqNuXewEuV=^ygRSq>}TgJJYiUUmIpR|oynHO{A973A^y zeo6Y(S;4+c_KN@Y6@jb7s_%%tK|fFWlBZ{y{l{*<|B{ezcC7zDUL52ReSaqVESNZ{ zdcUf8U7TBbzdnXhD?ie?-KD`kvy1od`^(IKFXyqBhy0rLeVY1n2l-NOMDJ(Cmr)N~ zBe~)|c4e?n>kF%YU9JA;&9L&@3{zMAZLZ&g{;|9IE?EBF9ANf$!m9rX#tT201uh?K z<5>{yj7hvFBxzx*M=zEZ6C-EIu>yzy>d2g~pMuK(^$K^`A_e>?`Jj)cctzQXkD zXF6|%$unEuH_89eH;4Q)^!=9n-UYL5e#*HO^BMi7N1boHCHT+M_hGWX>eirNrQd6o z{WCE71@l}UF|K^c<->0a`9{R**WlZOe%&*$`nw-i{?EDniFcX2+U57c$V=XJd7C?J zK5T?FeiJwz$s_%JmyaeMZj;x+igywDBd?FbidRB?*i|$*-%0<_D~<7NSo+Ic-qHKH z99I3iIG%A+wA%R!JHE5@eVO8|vEw^00xQ3sHvW}QyZ&i8mcPbB`v19pZ2UU;{CNPm z`n!tbn|S5=9!>tbFyGi;80-H5#?3QafATe<-%)+PC;h{jzt}fuJlV$WXa2LlG4?&* z@P0u*Q}aRfE#!DsUUQsp;`lE6`_u!KRqLaayDEUi8)f{jlm;-Oc>9@b~RsoE5m@ z09gKJpK19^U-4_ZTEG5uzU>SfFR}bxm1_R~gJnPWG^;oE{Xz37CQtGA`NLC!Jo_A2 z{`Z|6xbz}e_4PxJpM)&eKN5S?st3S|_eYn&<@&xO)I)sa$u~M5N51T@84Sz+I+#t- zb+Ga)qCVm@^@SC04)voS>ErhQo^A0nV2$s`HXg~nVfiaRFUT9Oa6UNQ>bVk@zsqcV zi!OIw#C(t+=_~#q<`0~n?e<4xSpK)T{u&s)k`b`#d)-;zf5?6>^AY=;$u5tF(ThIj zJPZHmHO_JUzQz?VJAcM}RsCOYA2rF{Nzd28dmBltc>{$GL7t2^0wG4|-k>-YR+KMDWjpMQz-e?FfthtbQM zb#Aavyu!Jg=zkFE_3-GF#9XzPw_8j{3tuQm+OCNTy!R^ew6nJ`e`RQXE46% z=ZVfs7+?G)O0IYZ(ogb=oDD0#r>x(#y?rto)vF zo*uI|E_urJBQX9l7dcgzDZgAjoT$!iu|u^AC0fD_wr#^&!91 zH(Y)M=PUL3UFVrx&%n)JI1l3dseXy2cj--`p4?5a;_LiNm%2Wn$PmTkNB!X^GEub7BB8RSo?RHeOgzyU*q=2y8d|L zDX+tvXXILb`#BzEA2&4kFaOTDKTQ0jZ=GM``h&Q|lB@nt{QBr8=T=<5AkX|4R-A*J z4{UJe%^zwzxQs-U*n;Cp3D#RX3Tf_{^3C$nd|oRM_4~foxg`=_b{w{D((sK zO2@nXW1|8$4R`st(H39xS$2;USUnfR%CF#FJ3eCT&6fMD9<4Xh|9On%bBc4$cpJY? zZhz1HA-~*2mlsY5`tdED%O0@${`2v;V50S>6>{aj2RV5(9R;i3#gi<*Zm{xO12axp z*TEXEy=I@N`6~H97&i?gVfib;A9{^rVCDZS`Jk7r{sjLp`wNSlKlFS{VEOA{_F1!? zzqR}dG(M6aL_YY5f6@7&q7W}%$G74={h;M5R=jxb$FVDT1y=q`VD_iH4lCdNFq_=> zoU{j9t?zSn;w-LVl^s zVCB=-xbYd+|HJevpK|$3lUHc|%D&SK%kLiNj>bv1xP3SDQOk&(4|kIvdF7n%a^;IW z`7~JZ*EwtaRo}%h`zzYOs;B<3P+#Uju;Pz=H26z8!1e#M{-kLAkbRSJRO^BK--$kE zxjSL`yB${l>tXq8m=fgG@3{UD@|Ru}EPwNP9)o_(D(8@;+Gkm%!}LiLGBx7?*YQ`qLH#|Fy@# z(jV}w&37HI;{4}A{_!cU{}rsd+q?WW7`=ppVa1>POyJaJ&-c#qpr5hV`6S|@SN{#H z{#?Dl;(r{I!|cy~3zom(&P!as)b-0@<#(sa6X(L}-@o*S{T0(({~_yF`XpHXo}i!T zWsY~gX0G+C5LR6)X9q4H3d`SvvuykZy8JbJ-d3mUVd?)cGsvU*URe5vBG)zvR(`i3 zCvJL6Sn-D%SHPUt1jX<74_KykPV3HurbilAvEY(*3Q1$+P4>SoKVNF^or??ne~w zk)?qf#=`RdZiVTOf>qzvW!5kGmwvC8L;R@flfUAXmft0Af5hsbpMHVsryCb`bN+5s zh?jAqa}|uA`1WqUzcO&-Z^l>o?1Rap@n;|Z*~C-auVLkLJ1qHo&exd#20brPzkh7}ZzUhq^?%Ppj1%=++*~gw= ztzQwiNzYqU&tB_ajh?rN`@{Gt9qzo2ev@D75Lo`_ykz~j99H}%jq@&s74J|VzwT~d z?%c-hJ20Nu<>+~`{H5U^yP9KR`8#=eh@W;cEPq|em-tzyJCAt9##5|(v#6I%^$D>2 zz4?03&;OI>sp5X?g1@?5{=Bu~4IA%Gu;S@`1@=XHo-BV$VB*HV>GlI*;+N=qJ^4H6 z|Ko4*FZoBvm2V#yzxD6CzddV%|77`7yd#klCRfjk6|W`!@LLyqo?Pqk^*z7hb$%!0 z6W!=M>Am2;P|xorf2St+YxvFmZGS)b%l;i!yvsibTzQ!HYvqT*zD&=P$-DNPk3;?y z$GCjK#vso*+WYwvOq^`#tG>}NX*aZY{p3wSKfT%GeZ4uzGd}Zt27O|3^;`8;e`@u| zp69o#vv{8)S3Zr%mAC#rS$weRH)#GS{zm+(?vtGR5FfpSZg8-#4cvG>EI*HYWaD{( z%gf(2?hDIL-P=LGR?o9#-`D!rr01`S*M39L&)eYoWATsQoc}p*vi{VGr9Y2)*=Fkb znfyIw^)$;~@_%8)m4D@Tw$)b@dmeWtj9#&x2TSj=&x3wl?D^%M`jBsyj!*fYz1{k$ z=kwD4@~a?E)$@DB>-LT1lMAc=J$DBE@;jXG{5i-YS|4Qp=Wl^i=DU37A3;BP1swAK z)8emn{j2{r{t8w-SN&FZ|Ey(epgT|1B=OzbyL$CS2Ne2iW`4J#L>3lSkdR zaOfZUY%4axihm3KanqoDB;U6`j7Q;%u>79|qZj{z%YWDx^yBnATJ;?dW0#=k@3L=6 zJ@WS?to(;kFZ)xqK1#mXxI+CBH<*5|=8t&aU!mU0R9NxPAwHYr*zr_koZH&vv*{Oc z3ibCe%I7lcU&0Jn@!x>SzeeBJ%3tF@!C&rVSp8b&{m|dA^)jda{1eTu+rcr;u0Pzkb_Ohe^`>9H%(=?* zUk)qZJ%?KV_4jz89^TKZ|GIt>KMtc8xz_b}+WY*ZUa;z^INb7&U9TLNX#T{K*TVAC z8&*EY^8En*vtrMK7aVE*%ya!q_}&2h9Mz-#Z-$9qJOx(1LplckX?or(zhz0mU+rku z|I|1k7goF%V2%I9F5ihgelkDv@fw1E;*=D?inon?*yeZg@j2=!%lB92kK*q~AAgB@ zKPoQbdkMCYXPlQG7y1!5(>X3V=$GpKcc}kF8{fZS#mhsEef+f^e;llQ#=)wu^9iQ^ z6s&m9cMke_T5o0l?bKTE z=?^;F^40v5{B{_5z1C0VlL(VX&2m`z6q|ke^De&;mY;<#KMp3(EWKY+zMWw5DOG*q zi0M}kgB9}x}828Cy$$vdJ8ME1!+s1E;H>%46htLBB!g z7uo-p9`cV)b6#`4`H%how5wqJHp^c6YtY9{LswY&?s0#I!ixV4@syvgZ^Q?|=;goV z<6lC4!<8WVDf2N=$yj$NBF6at(Wg$k6udb_f3Yv=vTh$`f)J&Rk8Q~r<%O!Tja`rhS^7d zcKss!lV8SP&ii2XL#+M{_WWYkdm}Cj{b|&CEq_IQgMRiDSoN-j*$MgLa_7xYp{11y?+|_wI-)pJ9ROi&ILqBTHf#tvAnvhR{ zSo!T8VD(+(^7aFRePKUX`F=S#=-27*L!>|A#vo6c>-xL--VC?N`hG+G_)R}TA*}o|@3j1MewF^Scbi=EN%70?vHYHc74KJ={rO9r zKN)HM--qRI+bGL#H>`Ny@qM1=Ll>X_f5WoZ{gLAR;GE(7F81utydPHl$6&SzliWTX zmfy)P?@N5RQ2NSm3*Y~dM)_*z>EsI+ZG)BHAH?0w{)_l9_prM{khIws_ssOSIE zA9Z!V0uTJKxLpTWeh605!kVb%K(EdPfU z26=ky`SH~8=173ZqS*1s(0)CU9C-UzEN-^2I|?@#3KKNz!QJx^8qcTFCB16KT5 z4_SY9yT7c512=Sx{r}{}A%5LJSo&QbvwUZ|{A}am#V%j+sO7s3R=i8FC$IF+oo^$a zj^_^k|Es@ZTsg-1OPDwnkHD&T0{Ng{I@SOG^*&QApDD2Fy8~7nv9=FR3-*n&S3kam zaZ~=F+gFqX{hIq--#LC9tauCXhh5HjuHObGpVU-X{w|vmIN=0X@y|A{J>Gd5^^-?@ z0<3(_vHA=5Qor>7d?e&k{S&NsnI^CL8kYYw`pNFcZhzwR z(2vS<-M$c3|IULIufyXe&v5-(m^k&Bu>4;#)5h~ESpI*T6*w}{^;?t%`=%0D{tki3 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

>90wy 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�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 literal 0 HcmV?d00001 diff --git a/core/src/main/resources/fr/cenra/rhomeo/core/data/site/SiteImpl.properties b/core/src/main/resources/fr/cenra/rhomeo/core/data/site/SiteImpl.properties new file mode 100644 index 0000000..fcba868 --- /dev/null +++ b/core/src/main/resources/fr/cenra/rhomeo/core/data/site/SiteImpl.properties @@ -0,0 +1,6 @@ +# Properties used for KML export +countyCode.kml=D\u00e9partement : {0} +zoneType.kml=Zone humide : {0} ({1}) +odonateType.kml=Zone biog\u00e9ographique pour les odonates : {0} ({1}) +orthoptereType.kml=Zone biog\u00e9ographique pour les orthopt\u00e8res : {0} ({1}) +remarks.kml=Remarques : {0} diff --git a/core/src/main/resources/fr/cenra/rhomeo/core/preferences/ftp/FTPKey.properties b/core/src/main/resources/fr/cenra/rhomeo/core/preferences/ftp/FTPKey.properties new file mode 100644 index 0000000..db379bb --- /dev/null +++ b/core/src/main/resources/fr/cenra/rhomeo/core/preferences/ftp/FTPKey.properties @@ -0,0 +1,8 @@ +ftp_url._label=URL du serveur +ftp_url._description=URL ou IP de la machine h\u00e9bergeant le service FTP +ftp_port._label=Port +ftp_port._description=Port du service FTP (par défaut 21) +ftp_user._label=Utilisateur +ftp_user._description=Non de connexion pour le service FTP +ftp_pass._label=Mot de passe +ftp_pass._description=Mot de passe pour la connexion au service de mise \u00e0 jour \ No newline at end of file diff --git a/core/src/main/resources/fr/cenra/rhomeo/core/preferences/ftp/FTPPreferencesImpl.properties b/core/src/main/resources/fr/cenra/rhomeo/core/preferences/ftp/FTPPreferencesImpl.properties new file mode 100644 index 0000000..2117fcc --- /dev/null +++ b/core/src/main/resources/fr/cenra/rhomeo/core/preferences/ftp/FTPPreferencesImpl.properties @@ -0,0 +1,2 @@ +_label=Configuration FTP +_description=D\u00e9taille les diff\u00e9rents acc\u00e8s FTP disponibles dans l'application diff --git a/core/src/main/resources/fr/cenra/rhomeo/core/preferences/net/NetKey.properties b/core/src/main/resources/fr/cenra/rhomeo/core/preferences/net/NetKey.properties new file mode 100644 index 0000000..c1abb27 --- /dev/null +++ b/core/src/main/resources/fr/cenra/rhomeo/core/preferences/net/NetKey.properties @@ -0,0 +1,9 @@ + +update_url._label=Fichier de mise \u00e0 jour +update_url._description=Lien vers le fichier contenant les informations de mise \u00e0 jour de l'application. +update_user._label=Login +update_user._description=Login pour la connexion au service de mise \u00e0 jour +update_pass._label=Mot de passe +update_pass._description=Mot de passe pour la connexion au service de mise \u00e0 jour +wfs_url._label=URL du WFS +wfs_url._description=Service Geor\u00e9f\u00e9rentiel diff --git a/core/src/main/resources/fr/cenra/rhomeo/core/preferences/net/NetPreferences.properties b/core/src/main/resources/fr/cenra/rhomeo/core/preferences/net/NetPreferences.properties new file mode 100644 index 0000000..2a60d42 --- /dev/null +++ b/core/src/main/resources/fr/cenra/rhomeo/core/preferences/net/NetPreferences.properties @@ -0,0 +1,3 @@ + +_label=Pr\u00e9f\u00e9rences r\u00e9seau +_description=D\u00e9finit l'ensemble des pr\u00e9f\u00e9rences concernant les connexions \u00e0 des services distants via HTTP. diff --git a/core/src/main/resources/fr/cenra/rhomeo/core/preferences/net/PassNetKey.properties b/core/src/main/resources/fr/cenra/rhomeo/core/preferences/net/PassNetKey.properties new file mode 100644 index 0000000..7582084 --- /dev/null +++ b/core/src/main/resources/fr/cenra/rhomeo/core/preferences/net/PassNetKey.properties @@ -0,0 +1,2 @@ +update_pass._label=Mot de passe +update_pass._description=Mot de passe pour la connexion au service de mise \u00e0 jour diff --git a/core/src/main/resources/fr/cenra/rhomeo/core/preferences/net/defaultKey b/core/src/main/resources/fr/cenra/rhomeo/core/preferences/net/defaultKey new file mode 100644 index 0000000..45239ad --- /dev/null +++ b/core/src/main/resources/fr/cenra/rhomeo/core/preferences/net/defaultKey @@ -0,0 +1 @@ +¨«)%ëFn‚¸OÒ>ÁþÒ \ No newline at end of file diff --git a/core/src/main/resources/fr/cenra/rhomeo/core/preferences/net/defaultSR b/core/src/main/resources/fr/cenra/rhomeo/core/preferences/net/defaultSR new file mode 100644 index 0000000..f316205 --- /dev/null +++ b/core/src/main/resources/fr/cenra/rhomeo/core/preferences/net/defaultSR @@ -0,0 +1 @@ + x=væ diff --git a/core/src/main/resources/fr/cenra/rhomeo/spring/spring-context.xml b/core/src/main/resources/fr/cenra/rhomeo/spring/spring-context.xml new file mode 100644 index 0000000..817bdee --- /dev/null +++ b/core/src/main/resources/fr/cenra/rhomeo/spring/spring-context.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + diff --git a/core/src/test/java/fr/cenra/rhomeo/RhomeoTestCase.java b/core/src/test/java/fr/cenra/rhomeo/RhomeoTestCase.java new file mode 100644 index 0000000..f513b4c --- /dev/null +++ b/core/src/test/java/fr/cenra/rhomeo/RhomeoTestCase.java @@ -0,0 +1,85 @@ +/** + * 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; + +import fr.cenra.rhomeo.core.RhomeoCore; +import org.apache.sis.test.DependsOnMethod; +import org.apache.sis.test.TestCase; +import org.apache.sis.test.TestRunner; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +/** + * Base test class for Rhomeo project. Allow testing in Spring / Hibernate-validator + * environment. Also allow for use of Apache SIS test utilities, as {@link DependsOnMethod} + * annotation. + * + * TODO : Merge {@link SpringJUnit4ClassRunner} and {@link TestRunner} to get the + * best of both worlds. + * + * @author Alexis Manin (Geomatys) + */ +public abstract class RhomeoTestCase extends TestCase { + static { + System.setProperty(RhomeoCore.ENV_RHOMEO_PATH_KEY, "rhomeo-tests"); + } + + protected static ClassPathXmlApplicationContext APP_CTX; + + @BeforeClass + public static void initCtx() throws Exception { + RhomeoCore.initEpsgDB(false); + APP_CTX = new ClassPathXmlApplicationContext(RhomeoCore.SPRING_CONTEXT_XML); + } + + @AfterClass + public static void closeCtx() { + if (APP_CTX != null) { + APP_CTX.close(); + } + } + + @Before + public void injectDependencies() { + APP_CTX.getBeanFactory().autowireBean(this); + } +} diff --git a/core/src/test/java/fr/cenra/rhomeo/api/international/InternationalDescriptionTest.java b/core/src/test/java/fr/cenra/rhomeo/api/international/InternationalDescriptionTest.java new file mode 100644 index 0000000..0cf020a --- /dev/null +++ b/core/src/test/java/fr/cenra/rhomeo/api/international/InternationalDescriptionTest.java @@ -0,0 +1,72 @@ +/** + * 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.international; + +import fr.cenra.rhomeo.api.InternationalDescription; +import java.util.Locale; +import org.junit.Assert; +import org.junit.Test; + +/** + * + * @author Samuel Andrés (Geomatys) + */ +public class InternationalDescriptionTest { + + private static class InternationalDescriptionImpl implements InternationalDescription { + } + + @Test + public void testInternationalDescription() { + + final InternationalDescription objet = new InternationalDescriptionImpl(); + + // Default locale + Assert.assertEquals("titre en français", objet.getLabel()); + Assert.assertEquals("description en français", objet.getDescription()); + + // Unknown locale => default + Assert.assertEquals("titre en français", objet.getLabel(Locale.ITALY)); + Assert.assertEquals("description en français", objet.getDescription(Locale.ITALY)); + + // Other existing locale + Assert.assertEquals("title in english", objet.getLabel(Locale.ENGLISH)); + Assert.assertEquals("description in english", objet.getDescription(Locale.ENGLISH)); + } +} diff --git a/core/src/test/java/fr/cenra/rhomeo/api/international/InternationalResourceTest.java b/core/src/test/java/fr/cenra/rhomeo/api/international/InternationalResourceTest.java new file mode 100644 index 0000000..54d0f9d --- /dev/null +++ b/core/src/test/java/fr/cenra/rhomeo/api/international/InternationalResourceTest.java @@ -0,0 +1,103 @@ +/** + * 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.international; + +import fr.cenra.rhomeo.api.InternationalResource; +import java.util.Locale; +import org.junit.Assert; +import org.junit.Test; + +/** + * + * @author Samuel Andrés (Geomatys) + */ +public class InternationalResourceTest { + + private static class InternationalResourceImpl implements InternationalResource { + private final String field1 = "FIELD 1"; + private final int field2 = 5; + } + + @Test + public void testInternationalResource() { + + final InternationalResource objet = new InternationalResourceImpl(); + + // Default locale + Assert.assertEquals("champ 1", objet.getResourceString("field1")); + Assert.assertEquals("champ 2", objet.getResourceString("field2")); + Assert.assertEquals("titre du champ 1", objet.getResourceString("field1._label")); + Assert.assertEquals("titre du champ 2", objet.getResourceString("field2._label")); + Assert.assertEquals("titre du champ 1", objet.getResourceString("field1", "_label")); + Assert.assertEquals("titre du champ 2", objet.getResourceString("field2", "_label")); + Assert.assertEquals("description du champ 1", objet.getResourceString("field1", "_description")); + Assert.assertEquals("description du champ 2", objet.getResourceString("field2", "_description")); + + // Unknown locale => default + Assert.assertEquals("champ 1", objet.getResourceString(Locale.ITALY, "field1")); + Assert.assertEquals("champ 2", objet.getResourceString(Locale.ITALY, "field2")); + Assert.assertEquals("titre du champ 1", objet.getResourceString(Locale.ITALY, "field1._label")); + Assert.assertEquals("titre du champ 2", objet.getResourceString(Locale.ITALY, "field2._label")); + Assert.assertEquals("titre du champ 1", objet.getResourceString(Locale.ITALY, "field1", "_label")); + Assert.assertEquals("titre du champ 2", objet.getResourceString(Locale.ITALY, "field2", "_label")); + Assert.assertEquals("description du champ 1", objet.getResourceString(Locale.ITALY, "field1", "_description")); + Assert.assertEquals("description du champ 2", objet.getResourceString(Locale.ITALY, "field2", "_description")); + + // Other existing locale + Assert.assertEquals("field 1", objet.getResourceString(Locale.ENGLISH, "field1")); + Assert.assertEquals("field 2", objet.getResourceString(Locale.ENGLISH, "field2")); + Assert.assertEquals("title of field 1", objet.getResourceString(Locale.ENGLISH, "field1._label")); + Assert.assertEquals("title of field 2", objet.getResourceString(Locale.ENGLISH, "field2._label")); + Assert.assertEquals("title of field 1", objet.getResourceString(Locale.ENGLISH, "field1", "_label")); + Assert.assertEquals("title of field 2", objet.getResourceString(Locale.ENGLISH, "field2", "_label")); + Assert.assertEquals("description of field 1", objet.getResourceString(Locale.ENGLISH, "field1", "_description")); + Assert.assertEquals("description of field 2", objet.getResourceString(Locale.ENGLISH, "field2", "_description")); + + + Assert.assertEquals("Other field", objet.getResourceString(Locale.ENGLISH, "other")); + Assert.assertEquals("Autre champ", objet.getResourceString("other")); + + Assert.assertEquals("Hello Toto and good bye Titi!", objet.getFormatedResourceString(Locale.ENGLISH, "withParameters", "Toto", "Titi")); + Assert.assertEquals("Bonjour Toto et au revoir Titi !", objet.getFormatedResourceString("withParameters", "Toto", "Titi")); + + Assert.assertEquals("Bonjour Toto et au revoir {1} !", objet.getFormatedResourceString("withParameters", "Toto")); + Assert.assertEquals("Bonjour {0} et au revoir {1} !", objet.getFormatedResourceString("withParameters")); + Assert.assertEquals("Bonjour {0} et au revoir {1} !", objet.getResourceString("withParameters")); + } +} diff --git a/core/src/test/java/fr/cenra/rhomeo/core/data/CSVMappingTest.java b/core/src/test/java/fr/cenra/rhomeo/core/data/CSVMappingTest.java new file mode 100644 index 0000000..517f441 --- /dev/null +++ b/core/src/test/java/fr/cenra/rhomeo/core/data/CSVMappingTest.java @@ -0,0 +1,199 @@ +/** + * 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.core.data; + +import fr.cenra.rhomeo.core.CSVDecoder; +import fr.cenra.rhomeo.core.CSVEncoder; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.MessageDigest; +import java.time.ZonedDateTime; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Random; +import java.util.concurrent.atomic.AtomicInteger; +import org.apache.sis.test.DependsOnMethod; +import org.apache.sis.test.TestCase; +import org.apache.sis.util.ArgumentChecks; +import org.geotoolkit.util.collection.CloseableIterator; +import org.junit.Assert; +import org.junit.Test; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class CSVMappingTest extends TestCase { + + @Test + public void encodeStringWithSeparatorTest() throws Exception { + final MockReference ref = new MockReference(); + ref.setFirst("lalaleigni; apegnpgbpa,;\"n ebo\"; bfozb\";\""); + ref.setFifth(Float.NaN); + ref.setSecond(ZonedDateTime.now()); + + final Path tmpFile = Files.createTempFile("stringWithSeparator", ".csv"); + try { + new CSVEncoder(tmpFile, MockReference.class).encode(Collections.singleton(ref), true); + final List decoded = new CSVDecoder(tmpFile, MockReference.class).decode(); + Assert.assertEquals("Decoded file should contain one unique element !", 1, decoded.size()); + Assert.assertEquals("Decoded object is not equal to the original one !", ref, decoded.get(0)); + } finally { + Files.delete(tmpFile); + } + } + + /** + * Create randomly filled instances of {@link MockReference}, then write them + * in a CSV file. We then decode lazily, and reencode it immediately in another + * file. + * + * To check procedure validity, we compare md5 hash of the two files written. + * + * @throws Exception + */ + @DependsOnMethod("encodeStringWithSeparatorTest") + @Test + public void readWriteReferenceTest() throws Exception { + // Check written content + final MessageDigest digest = MessageDigest.getInstance("md5"); + + final Path firstPass = Files.createTempFile("referenceIO", ".csv"); + final Path secondPass = Files.createTempFile("referenceIO", ".csv"); + try { + final int count = (int) 1e2; + new CSVEncoder(firstPass, MockReference.class).encode(new RefCreator(count), false); + final byte[] md5 = computeDigest(digest, firstPass); + + final CSVDecoder decoder = new CSVDecoder(firstPass, MockReference.class); + try (final CloseableIterator decoded = decoder.decodeLazy()) { + new CSVEncoder(secondPass, MockReference.class).encode(decoded, true); + } + + Assert.assertArrayEquals("Encoded md5 is not equal to read then re-encoded data file !", md5, computeDigest(digest, secondPass)); + + } finally { + Files.delete(firstPass); + Files.delete(secondPass); + } + } + + private static byte[] computeDigest(final MessageDigest digest, final Path in) throws IOException { + final byte[] buf = new byte[8192]; + int read = 0; + try (final InputStream stream = Files.newInputStream(in)) { + while ((read = stream.read(buf)) >= 0) { + digest.update(buf, 0, read); + } + } + + return digest.digest(); + } + + /** + * An iterator creating randomly filled objects as browsed. + */ + private static class RefCreator implements Iterator { + + private final int total; + private final AtomicInteger count = new AtomicInteger(); + + private MockReference next; + + private final Random random; + + public RefCreator(final int count) { + ArgumentChecks.ensureStrictlyPositive("Number of references to create", count); + this.total = count; + + random = new Random(); + } + + @Override + public synchronized boolean hasNext() { + if (next == null && count.getAndIncrement() >= total) { + return false; + } else if (next == null) { + next = createReference(); + } + + return true; + } + + @Override + public synchronized MockReference next() { + if (hasNext()) { + try { + return next; + } finally { + next = null; + } + } else { + throw new IllegalStateException("No more element available !"); + } + } + + private MockReference createReference() { + MockReference result = new MockReference(); + + // Insert a random character sequence, or let a null value. + if (random.nextBoolean()) { + final StringBuilder b = new StringBuilder(); + final byte[] bytes = new byte[random.nextInt(128)]; + result.setFirst(new String(bytes, StandardCharsets.UTF_8)); + } + + if (random.nextBoolean()) { + result.setSecond(ZonedDateTime.now()); + } + + result.setThird(random.nextDouble() * 1e6); + + result.setFourth(random.nextBoolean()); + + result.setFifth(random.nextBoolean()? Float.NaN : random.nextFloat()); + + return result; + } + } +} diff --git a/core/src/test/java/fr/cenra/rhomeo/core/data/DatasetTest.java b/core/src/test/java/fr/cenra/rhomeo/core/data/DatasetTest.java new file mode 100644 index 0000000..0428719 --- /dev/null +++ b/core/src/test/java/fr/cenra/rhomeo/core/data/DatasetTest.java @@ -0,0 +1,111 @@ +/** + * 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.core.data; + +import fr.cenra.rhomeo.RhomeoTestCase; +import fr.cenra.rhomeo.api.data.Dataset; +import fr.cenra.rhomeo.api.data.Protocol; +import fr.cenra.rhomeo.api.data.TrackingPoint; +import java.time.LocalDate; +import java.util.HashSet; +import java.util.Random; +import javafx.collections.ObservableList; +import org.junit.Assert; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class DatasetTest extends RhomeoTestCase { + + @Autowired + @Qualifier(MockProtocol.NAME) + Protocol protocol; + + @Test + public void checkTrackingPoints() { + final Dataset dataset = new Dataset(protocol); + final MockStatement first = new MockStatement(); + dataset.getItems().add(first); + final ObservableList tPoints = dataset.getTrackingPoints(); + Assert.assertTrue("No tracking point should exist", tPoints.isEmpty()); + + final LocalDate pointDate = LocalDate.now(); + final String pointName = "lolo"; + first.setDate(pointDate); + first.setTrackingPoint(pointName); + Assert.assertTrue("Tracking point list should contain one unique element", tPoints.size() == 1); + Assert.assertEquals("Tracking point name is invalid !", pointName, tPoints.get(0).getName()); + Assert.assertEquals("Tracking point date is invalid !", pointDate.getYear(), tPoints.get(0).getYear()); + + final MockStatement second = new MockStatement("secondPoint", LocalDate.now()); + dataset.getItems().add(second); + Assert.assertTrue("Tracking point list should contain two elements", tPoints.size() == 2); + Assert.assertEquals("Tracking point name is invalid !", second.getTrackingPoint(), tPoints.get(1).getName()); + Assert.assertEquals("Tracking point date is invalid !", second.getDate().getYear(), tPoints.get(1).getYear()); + + second.setTrackingPoint("another !"); + Assert.assertTrue("Tracking point list should contain two elements", tPoints.size() == 2); + Assert.assertEquals("Tracking point name is invalid !", second.getTrackingPoint(), tPoints.get(1).getName()); + Assert.assertEquals("Tracking point date is invalid !", second.getDate().getYear(), tPoints.get(1).getYear()); + + dataset.getItems().remove(first); + Assert.assertTrue("Tracking point list should contain one unique element", tPoints.size() == 1); + Assert.assertEquals("Tracking point name is invalid !", second.getTrackingPoint(), tPoints.get(0).getName()); + Assert.assertEquals("Tracking point date is invalid !", second.getDate().getYear(), tPoints.get(0).getYear()); + } + + @Test + public void chargeTest() { + final String points[] = new String[]{"a", "B", "obzo", "ff", "papa", "tata", "titi", "tete", "lala", "lolo", "lele"}; + final Random rand = new Random(); + final Dataset d = new Dataset(protocol); + final ObservableList tPoints = d.getTrackingPoints(); + for (int i = 0 ; i < 4000 ; i++) { + d.getItems().add(new MockStatement(points[rand.nextInt(points.length -1)], LocalDate.now().minusYears(rand.nextInt(10)))); + } + + Assert.assertFalse("Tracking point list should contain data !", tPoints.isEmpty()); + final HashSet uniquePoints = new HashSet(tPoints); + Assert.assertEquals("Uniqueness broken !", uniquePoints.size(), tPoints.size()); + } +} diff --git a/core/src/test/java/fr/cenra/rhomeo/core/data/MockIndicator.java b/core/src/test/java/fr/cenra/rhomeo/core/data/MockIndicator.java new file mode 100644 index 0000000..bd5a308 --- /dev/null +++ b/core/src/test/java/fr/cenra/rhomeo/core/data/MockIndicator.java @@ -0,0 +1,90 @@ +/** + * 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.core.data; + +import fr.cenra.rhomeo.api.EditableIdentifiedObject; +import fr.cenra.rhomeo.api.data.Protocol; +import fr.cenra.rhomeo.api.process.Indicator; +import fr.cenra.rhomeo.api.process.Process; +import fr.cenra.rhomeo.api.process.ProcessContext; +import java.util.Set; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +/** + * + * @author Alexis Manin (Geomatys) + */ +@Component +@Qualifier(MockIndicator.NAME) +public class MockIndicator extends EditableIdentifiedObject implements Indicator { + + public static final String NAME = "MockIndicator"; + + @Autowired + @Qualifier(MockProtocol.NAME) + Protocol protocol; + + @Override + public Protocol getProtocol() { + return protocol; + } + + @Override + public Set createProcesses(ProcessContext ctx) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public String getDefaultIndex() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public Set getZoneTypeCodes() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public int compareTo(Indicator o) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + +} diff --git a/core/src/test/java/fr/cenra/rhomeo/core/data/MockProtocol.java b/core/src/test/java/fr/cenra/rhomeo/core/data/MockProtocol.java new file mode 100644 index 0000000..d3a3c8c --- /dev/null +++ b/core/src/test/java/fr/cenra/rhomeo/core/data/MockProtocol.java @@ -0,0 +1,81 @@ +/** + * 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.core.data; + +import fr.cenra.rhomeo.api.EditableIdentifiedObject; +import fr.cenra.rhomeo.api.data.Protocol; +import fr.cenra.rhomeo.api.data.ReferenceDescription; +import fr.cenra.rhomeo.api.data.Site; +import fr.cenra.rhomeo.api.data.Statement; +import java.util.Collections; +import java.util.Set; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +/** + * + * @author Alexis Manin (Geomatys) + */ +@Component +@Qualifier(MockProtocol.NAME) +public class MockProtocol extends EditableIdentifiedObject implements Protocol { + + public static final String NAME = "MockProtocol"; + + @Override + public Class getDataType() { + return MockStatement.class; + } + + @Override + public Set getReferenceTypes() { + return Collections.EMPTY_SET; + } + + @Override + public boolean isCompatible(Site site) { + return true; + } + + @Override + public int compareTo(Protocol o) { + return 0; + } + +} diff --git a/core/src/test/java/fr/cenra/rhomeo/core/data/MockReference.java b/core/src/test/java/fr/cenra/rhomeo/core/data/MockReference.java new file mode 100644 index 0000000..dfcb1ef --- /dev/null +++ b/core/src/test/java/fr/cenra/rhomeo/core/data/MockReference.java @@ -0,0 +1,158 @@ +/** + * 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.core.data; + +import fr.cenra.rhomeo.api.data.Reference; +import java.time.ZonedDateTime; +import java.util.Objects; +import javafx.beans.property.BooleanProperty; +import javafx.beans.property.DoubleProperty; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.property.SimpleDoubleProperty; +import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class MockReference implements Reference { + + public final SimpleStringProperty first = new SimpleStringProperty(); + public final SimpleObjectProperty second = new SimpleObjectProperty<>(); + public final SimpleDoubleProperty third = new SimpleDoubleProperty(); + public final SimpleBooleanProperty fourth = new SimpleBooleanProperty(); + + @Override + public int hashCode() { + int hash = 7; + hash = 89 * hash + Objects.hashCode(this.first.get()); + hash = 89 * hash + Objects.hashCode(this.second.get()); + hash = 89 * hash + Objects.hashCode(this.third.get()); + hash = 89 * hash + Objects.hashCode(this.fourth.get()); + hash = 89 * hash + Objects.hashCode(this.fifth.get()); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + final MockReference other = (MockReference) obj; + if (!Objects.equals(this.first.get(), other.first.get())) + return false; + if (!(this.second.get() == null)? other.second == null : this.second.get().isEqual(other.second.get())) + return false; + if (!Objects.equals(this.third.get(), other.third.get())) + return false; + if (!Objects.equals(this.fourth.get(), other.fourth.get())) + return false; + if (!Objects.equals(this.fifth.get(), other.fifth.get())) + return false; + return true; + } + public final SimpleObjectProperty fifth = new SimpleObjectProperty<>(); + + public String getFirst() { + return first.get(); + } + + public void setFirst(final String newValue) { + first.set(newValue); + } + + public StringProperty firstProperty() { + return first; + } + + + public ZonedDateTime getSecond() { + return second.get(); + } + + public void setSecond(final ZonedDateTime newValue) { + second.set(newValue); + } + + public ObjectProperty secondProperty() { + return second; + } + + + public double getThird() { + return third.get(); + } + + public void setThird(final double newValue) { + third.set(newValue); + } + + public DoubleProperty thirdProperty() { + return third; + } + + + public boolean getFourth() { + return fourth.get(); + } + + public void setFourth(final boolean newValue) { + fourth.set(newValue); + } + + public BooleanProperty fourthProperty() { + return fourth; + } + + public Float getFifth() { + return fifth.get(); + } + + public void setFifth(final Float newValue) { + fifth.set(newValue); + } + + public ObjectProperty fifthProperty() { + return fifth; + } +} diff --git a/core/src/test/java/fr/cenra/rhomeo/core/data/MockReferenceDescription.java b/core/src/test/java/fr/cenra/rhomeo/core/data/MockReferenceDescription.java new file mode 100644 index 0000000..ca27252 --- /dev/null +++ b/core/src/test/java/fr/cenra/rhomeo/core/data/MockReferenceDescription.java @@ -0,0 +1,73 @@ +/** + * 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.core.data; + +import fr.cenra.rhomeo.api.data.ReferenceDescription; +import java.util.Collection; +import java.util.Collections; +import org.springframework.stereotype.Component; + +/** + * + * @author Alexis Manin (Geomatys) + */ +@Component +public class MockReferenceDescription implements ReferenceDescription { + + @Override + public Class getReferenceType() { + return MockReference.class; + } + + @Override + public String getName() { + return "MockReference"; + } + + @Override + public Collection getAlias() { + return Collections.singleton("Reference type for tests."); + } + + @Override + public String getRemarks() { + return "A reference created for test purpose."; + } + +} diff --git a/core/src/test/java/fr/cenra/rhomeo/core/data/MockStatement.java b/core/src/test/java/fr/cenra/rhomeo/core/data/MockStatement.java new file mode 100644 index 0000000..4c2172d --- /dev/null +++ b/core/src/test/java/fr/cenra/rhomeo/core/data/MockStatement.java @@ -0,0 +1,82 @@ +/** + * 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.core.data; + +import fr.cenra.rhomeo.api.data.Statement; +import java.time.LocalDate; +import java.util.Objects; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class MockStatement extends Statement { + + public MockStatement() {} + + public MockStatement(final String tName, final LocalDate date) { + super(tName, date); + } + + @Override + public boolean equals(Object obj) { + if (obj == null || ! obj.getClass().equals(this.getClass())) { + return false; + } + + final MockStatement other = (MockStatement) obj; + return Objects.equals(date.get(), other.date.get()) && Objects.equals(trackingPoint.get(), other.trackingPoint.get()); + } + + @Override + public int hashCode() { + int hash = 0; + final String point = trackingPoint.get(); + if (point != null) { + hash += point.hashCode(); + } + + final LocalDate date = this.date.get(); + if (date != null) { + hash += 31*date.hashCode(); + } + + return hash; + } +} diff --git a/core/src/test/java/fr/cenra/rhomeo/core/data/ReferenceManagerTest.java b/core/src/test/java/fr/cenra/rhomeo/core/data/ReferenceManagerTest.java new file mode 100644 index 0000000..75e328a --- /dev/null +++ b/core/src/test/java/fr/cenra/rhomeo/core/data/ReferenceManagerTest.java @@ -0,0 +1,163 @@ +/** + * 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.core.data; + +import fr.cenra.rhomeo.RhomeoTestCase; +import fr.cenra.rhomeo.api.Version; +import fr.cenra.rhomeo.core.CSVEncoder; +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.preferences.ftp.FTPPreferences; + +import java.beans.IntrospectionException; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import javafx.concurrent.Task; +import javafx.embed.swing.JFXPanel; +import org.apache.commons.net.ftp.FTPClient; +import org.geotoolkit.nio.IOUtilities; +import org.junit.Assert; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class ReferenceManagerTest extends RhomeoTestCase { + + @Autowired + FTPPreferences prefs; + + @Autowired + MockReferenceDescription desc; + + @Test + public void testLists() throws Exception { + new JFXPanel().setVisible(false);// necessary to init fx toolkit + final FTPClient ftpClient = prefs.getAccess(FTPPreferences.ACCESS_POINTS.REFERENCES).createClient(); + + ftpClient.makeDirectory(desc.getName()); + final String pathname = Paths.get(desc.getName()).resolve("1.0.1.csv").toString(); + + // Create a new version on distant repository. + final List refs; + final Path tmpFile = Files.createTempFile("tmpVersion", ".csv"); + try { + refs = createMockList(tmpFile); + try (final InputStream stream = Files.newInputStream(tmpFile)) { + ftpClient.storeFile(pathname, stream); + } + } finally { + Files.delete(tmpFile); + } + + // Clear local test data. + IOUtilities.deleteRecursively(RhomeoCore.REFERENCE_PATH.resolve(desc.getName())); + + ReferenceManager manager = ReferenceManager.getOrCreate(desc); + Task t = manager.refresh(); + t.run(); + t.get(); + + final Set distantVersions = manager.getDistantVersions(); + Assert.assertNotNull("Distant version list", distantVersions); + Assert.assertFalse("Distant version list should not be empty.", distantVersions.isEmpty()); + + final Set localVersions = manager.getInstalledVersions(); + Assert.assertNotNull("List of installed versions", localVersions); + Assert.assertTrue("List of installed versions should be empty", localVersions.isEmpty()); + + // Install found version + final Version newVersion = distantVersions.iterator().next(); + t = manager.install(newVersion); + t.run(); + t.get(); + Assert.assertTrue("installed version set should be updated on new version install.", localVersions.contains(newVersion)); + + // Read data into downloaded version + final List values = manager.getValues(newVersion); + Assert.assertEquals("Loaded values are different from created ones !", refs, values); + + // Remove newly installed + t = manager.uninstall(newVersion); + t.run(); + t.get(); + Assert.assertFalse("Local version set should be updated when a version is deleted.", localVersions.contains(newVersion)); + + // delete distant version + ftpClient.deleteFile(pathname); + t = manager.refresh(); + t.run(); + t.get(); + Assert.assertFalse("Distant version list has not been updated", distantVersions.contains(newVersion)); + } + + private static List createMockList(final Path toWriteInto) throws IOException, IntrospectionException { + final CSVEncoder encoder = new CSVEncoder<>(toWriteInto, MockReference.class); + + final ArrayList list = new ArrayList<>(); + MockReference ref = new MockReference(); + ref.setFirst("toto"); + ref.setSecond(ZonedDateTime.now()); + ref.setThird(0.13); + ref.setFourth(true); + ref.setFifth(Float.NaN); + list.add(ref); + + ref = new MockReference(); + ref.setFirst("tata"); + ref.setSecond(ZonedDateTime.now()); + ref.setThird(100.2); + ref.setFourth(true); + ref.setFifth(9.3f); + list.add(ref); + + encoder.encode(list, true); + + return Collections.unmodifiableList(list); + } +} diff --git a/core/src/test/java/fr/cenra/rhomeo/core/data/UpdateInfoTest.java b/core/src/test/java/fr/cenra/rhomeo/core/data/UpdateInfoTest.java new file mode 100644 index 0000000..e6745d8 --- /dev/null +++ b/core/src/test/java/fr/cenra/rhomeo/core/data/UpdateInfoTest.java @@ -0,0 +1,81 @@ +/** + * 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.core.data; + +import com.fasterxml.jackson.databind.ObjectMapper; +import fr.cenra.rhomeo.api.Version; +import org.junit.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.time.ZonedDateTime; + +import static org.junit.Assert.*; + +/** + * Verify that the update json file on the server can be read properly. + */ +public class UpdateInfoTest { + /** + * Read json update file and ensures its content is conformed and readable. + * + * @throws IOException + */ + @Test + public void deserializeTest() throws IOException { + try (final InputStream is = this.getClass().getResourceAsStream("update.json")) { + final UpdateInfo update = new ObjectMapper().readValue(is, UpdateInfo.class); + assertNotNull(update); + assertEquals(new Version("0.1"), update.getVersion()); + assertEquals(ZonedDateTime.parse("2016-04-29T15:00:00+01:00"), update.getDate()); + assertNotNull(update.getReleaseNote()); + assertEquals(1, update.getReleaseNote().length); + assertEquals("Première version de l'application permettant la gestion de sites", update.getReleaseNote()[0]); + assertEquals(new URL("http://testwin32").toExternalForm(), update.getWin32().toExternalForm()); + assertEquals("testwin32MD5", update.getWin32MD5()); + assertEquals(new URL("http://testdeb64").toExternalForm(), update.getDeb64().toExternalForm()); + assertEquals("testdeb64MD5", update.getDeb64MD5()); + assertEquals(new URL("http://testrpm64").toExternalForm(), update.getRpm64().toExternalForm()); + assertEquals("testrpm64MD5", update.getRpm64MD5()); + assertEquals(new URL("http://testmacOS64").toExternalForm(), update.getMacOS64().toExternalForm()); + assertEquals("testmacOS64MD5", update.getMacOS64MD5()); + } + } +} diff --git a/core/src/test/java/fr/cenra/rhomeo/core/data/county/CountyTest.java b/core/src/test/java/fr/cenra/rhomeo/core/data/county/CountyTest.java new file mode 100644 index 0000000..764c54d --- /dev/null +++ b/core/src/test/java/fr/cenra/rhomeo/core/data/county/CountyTest.java @@ -0,0 +1,79 @@ +/** + * 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.core.data.county; + +import fr.cenra.rhomeo.core.RhomeoCore; +import java.io.IOException; +import java.util.Map; +import org.geotoolkit.lang.Setup; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.opengis.util.FactoryException; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class CountyTest { + + @BeforeClass + public static void initGeotk() throws FactoryException, IOException { + RhomeoCore.initEpsgDB(false); + Setup.initialize(null); + } + + /** + * Check some county codes we should find into read file. + */ + private static final String[] COUNTY_CODES = new String[] { + "38", "69", "01", "34", "26", "07" + }; + + @Test + public void testLoading() throws Exception { + final Map counties = new CountyRepository().getAll(); + Assert.assertNotNull("County list", counties); + Assert.assertFalse("County list should not be empty", counties.isEmpty()); + + for (final String code : COUNTY_CODES) { + Assert.assertNotNull("A county is missing : ".concat(code), counties.get(code)); + } + } +} diff --git a/core/src/test/java/fr/cenra/rhomeo/core/data/site/SiteRepositoryTest.java b/core/src/test/java/fr/cenra/rhomeo/core/data/site/SiteRepositoryTest.java new file mode 100644 index 0000000..153da37 --- /dev/null +++ b/core/src/test/java/fr/cenra/rhomeo/core/data/site/SiteRepositoryTest.java @@ -0,0 +1,191 @@ +/** + * 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.core.data.site; + +import fr.cenra.rhomeo.core.data.site.SiteRepository; +import fr.cenra.rhomeo.core.data.site.DuplicatedKeyException; +import fr.cenra.rhomeo.core.data.site.SiteRepositoryImpl; +import fr.cenra.rhomeo.RhomeoTestCase; +import fr.cenra.rhomeo.api.IdentifiedObject; +import fr.cenra.rhomeo.api.data.Site; +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.data.site.SiteImpl; +import javafx.collections.ObservableList; +import org.apache.sis.storage.DataStoreException; +import org.geotoolkit.data.FeatureReader; +import org.geotoolkit.data.query.QueryBuilder; +import org.geotoolkit.data.shapefile.ShapefileFeatureStore; +import org.junit.Test; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import org.apache.sis.test.DependsOnMethod; +import org.geotoolkit.nio.IOUtilities; +import org.junit.AfterClass; + +import static org.junit.Assert.*; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * Test reading / writing methods using the {@link SiteRepository} API. + * + * @author Cédric Briançon (Geomatys) + */ +public class SiteRepositoryTest extends RhomeoTestCase { + + /** + * Mock SHP in the resources. + */ + public static final String RESOURCES_DATA_SHP = "sites.shp"; + + @Autowired + SiteRepository repo; + + /** + * Remove tests path for sites SHP. + * + * @throws IOException + */ + @AfterClass + public static void finalization() throws IOException { + IOUtilities.deleteRecursively(RhomeoCore.SITES_PATH); + } + + /** + * Verify method {@link SiteRepository#findAll()}. + */ + @Test + public void findAllTest() { + final ObservableList sites = repo.findNames(); + assertNotNull(sites); + assertTrue(sites.isEmpty()); + } + + /** + * Verify method {@link SiteRepository#create(IdentifiedObject)} and {@link SiteRepository#delete(String)}. + * + * @throws MalformedURLException + * @throws DataStoreException + * @throws DuplicatedKeyException + */ + @DependsOnMethod("findAllTest") + @Test + public void createDeleteTest() throws MalformedURLException, DataStoreException, DuplicatedKeyException, URISyntaxException { + try (final ShapefileFeatureStore testDataStore = new ShapefileFeatureStore(this.getClass().getResource(RESOURCES_DATA_SHP).toURI(), "no namespace"); + final FeatureReader reader = testDataStore.getFeatureReader(QueryBuilder.all(testDataStore.getName()))) { + + assertTrue(reader.hasNext()); + + final Site newSite = SiteRepositoryImpl.toSite(reader.next()); + repo.create(newSite); + + final ObservableList allSites = repo.findNames(); + assertNotNull(allSites); + assertEquals(1, allSites.size()); + + repo.delete(newSite.getName()); + assertTrue(allSites.isEmpty()); + } + } + + + /** + * Ensures {@link SiteRepository#findOne(String)} works fine. + * + * @throws IOException + * @throws DataStoreException + */ + @DependsOnMethod("createDeleteTest") + @Test + public void getSiteTest() throws Exception { + try (final ShapefileFeatureStore testDataStore = new ShapefileFeatureStore(this.getClass().getResource(RESOURCES_DATA_SHP).toURI(), "no namespace"); + final FeatureReader reader = testDataStore.getFeatureReader(QueryBuilder.all(testDataStore.getName()))) { + + final Site newSite = SiteRepositoryImpl.toSite(reader.next()); + repo.create(newSite); + + final Site addedSite = repo.findOne(newSite.getName()); + assertNotNull(addedSite); + assertEquals(newSite, addedSite); + assertEquals(newSite.getCountyCode(), addedSite.getCountyCode()); + + repo.delete(newSite.getName()); + } + } + + /** + * Verify method {@link SiteRepository#update(IdentifiedObject)}}. + * + * @throws MalformedURLException + * @throws DataStoreException + * @throws DuplicatedKeyException + */ + @DependsOnMethod("getSiteTest") + @Test + public void updateTest() throws MalformedURLException, DataStoreException, DuplicatedKeyException, URISyntaxException { + try (final ShapefileFeatureStore testDataStore = new ShapefileFeatureStore(this.getClass().getResource(RESOURCES_DATA_SHP).toURI(), "no namespace"); + final FeatureReader reader = testDataStore.getFeatureReader(QueryBuilder.all(testDataStore.getName()))) { + + final Site newSite = SiteRepositoryImpl.toSite(reader.next()); + repo.create(newSite); + + final String testOrtho = "test orthoptere"; + ((SiteImpl)newSite).setOrthoptereType(testOrtho); + repo.update(newSite); + + final Site updatedSite = repo.findOne(newSite.getName()); + assertNotNull(updatedSite.getOrthoptereType()); + assertEquals(testOrtho, updatedSite.getOrthoptereType()); + assertEquals(newSite.getOrthoptereType(), updatedSite.getOrthoptereType()); + + ((SiteImpl)updatedSite).setName("myNewName"); + repo.create(updatedSite); + + try { + repo.update(updatedSite, newSite.getName()); + } catch (DuplicatedKeyException e) { + // expected behavior + } + + repo.delete(newSite.getName()); + repo.delete(updatedSite.getName()); + } + } +} diff --git a/core/src/test/java/fr/cenra/rhomeo/core/preferences/ftp/FTPPreferencesTest.java b/core/src/test/java/fr/cenra/rhomeo/core/preferences/ftp/FTPPreferencesTest.java new file mode 100644 index 0000000..e999169 --- /dev/null +++ b/core/src/test/java/fr/cenra/rhomeo/core/preferences/ftp/FTPPreferencesTest.java @@ -0,0 +1,128 @@ +/** + * 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.core.preferences.ftp; + +import fr.cenra.rhomeo.RhomeoTestCase; +import java.security.GeneralSecurityException; +import org.apache.sis.test.DependsOnMethod; +import org.junit.Assert; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +/** + * Test {@link FTPPreferencesImpl} component, by trying to get and change information + * about an FTP access. + * + * TODO : test {@link FTPAccess#createClient() } + * + * @author Alexis Manin (Geomatys) + */ +public class FTPPreferencesTest extends RhomeoTestCase { + + @Autowired + @Qualifier(FTPPreferencesImpl.NAME) + FTPPreferences prefs; + + /** + * Test that methods which should not be used by user throw exception or expected empty value. + */ + @Test + public void testForbiddenMethods() { + Assert.assertTrue("Key collection should be empty !" , prefs.getKeys().isEmpty()); + + try { + prefs.getPreference("whatever"); + Assert.fail("getProperty() method should not be usable !"); + } catch (UnsupportedOperationException e) { + // Expected + } + + try { + prefs.setPreference("whatever", "blabla"); + Assert.fail("setProperty() method should not be usable !"); + } catch (UnsupportedOperationException e) { + // Expected + } + } + + @DependsOnMethod("testForbiddenMethods") + @Test + public void testAccessPoint() throws Exception { + final FTPAccess access = prefs.getAccess(FTPPreferences.ACCESS_POINTS.RESULTS); + Assert.assertNotNull("No access point found !", access); + + final String expectedAd = "myAdress"; + final String expectedLogin = "toto"; + final String expectedWorkDir = "/my/work/dir"; + assertChanges(access, expectedAd, expectedLogin, null, expectedWorkDir); + + assertChanges(access, "newAdress", "newLogin", "newPassword!£²345*ù%", "newWorkDir"); + } + + public static void assertChanges(final FTPAccess access, final String adress, final String login, final String password, final String workDir) throws GeneralSecurityException { + // Keep reference to access previous values to rollback user configuration after the test. + final String oldAdress = access.getAdress(); + final String oldLogin = access.getLogin(); + final String oldPw = access.getPassword(); + final String oldDir = access.getWorkingDir(); + + try { + access.setAdress(adress); + access.setLogin(login); + access.setPassword(password); + access.setWorkingDir(workDir); + + Assert.assertEquals("Adress", adress, access.getAdress()); + Assert.assertEquals("Login", login, access.getLogin()); + Assert.assertEquals("Working directory", workDir, access.getWorkingDir()); + if (password == null) { + Assert.assertTrue("Password should be empty", access.getPassword().isEmpty()); + } else { + Assert.assertEquals("Password", password, access.getPassword()); + } + } finally { + // Rollback to initial values. + access.setAdress(oldAdress); + access.setLogin(oldLogin); + access.setPassword(oldPw); + access.setWorkingDir(oldDir); + } + } +} \ No newline at end of file diff --git a/core/src/test/java/fr/cenra/rhomeo/core/preferences/ftp/MockFTPClient.java b/core/src/test/java/fr/cenra/rhomeo/core/preferences/ftp/MockFTPClient.java new file mode 100644 index 0000000..4422902 --- /dev/null +++ b/core/src/test/java/fr/cenra/rhomeo/core/preferences/ftp/MockFTPClient.java @@ -0,0 +1,234 @@ +/** + * 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.core.preferences.ftp; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.StandardOpenOption; +import java.nio.file.attribute.BasicFileAttributeView; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.Date; +import java.util.GregorianCalendar; +import org.apache.commons.net.ftp.FTPClient; +import org.apache.commons.net.ftp.FTPFile; +import org.apache.commons.net.ftp.FTPFileFilter; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class MockFTPClient extends FTPClient { + + private final Path root; + private Path workDir; + + public MockFTPClient(final Path root) throws IOException { + if (!Files.isDirectory(root)) { + throw new IllegalArgumentException("Input path is not a folder !"); + } + + this.root = root; + workDir = this.root; + } + + private Path getPath(final String pathname) { + if (pathname == null) + return workDir; + Path tmp = Paths.get(pathname); + if (!tmp.isAbsolute()) { + tmp = workDir.resolve(tmp); + } + + if (!tmp.startsWith(root)) { + throw new IllegalArgumentException("Given path does not represents a file of this FTP."); + } + + return tmp; + } + + @Override + public boolean makeDirectory(String pathname) throws IOException { + Files.createDirectories(getPath(pathname)); + return true; + } + + @Override + public boolean changeToParentDirectory() throws IOException { + if (workDir.equals(root)) + return false; + workDir = workDir.getParent(); + return true; + } + + @Override + public boolean changeWorkingDirectory(String pathname) throws IOException { + final Path tmpPath = getPath(pathname); + if (Files.isDirectory(tmpPath)) { + workDir = tmpPath; + return true; + } + + return false; + } + + @Override + public FTPFile[] listFiles() throws IOException { + return listFiles(null, null); + } + + @Override + public FTPFile[] listFiles(String pathname) throws IOException { + return listFiles(pathname, null); + } + + @Override + public FTPFile[] listFiles(String pathname, FTPFileFilter filter) throws IOException { + final Path toList = getPath(pathname); + + final ArrayList files = new ArrayList<>(); + Files.walkFileTree(toList, Collections.EMPTY_SET, 1, new SimpleFileVisitor() { + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + final FTPFile ftpFile = convert(file); + if (filter == null || filter.accept(ftpFile)) { + files.add(ftpFile); + } + return super.visitFile(file, attrs); + } + + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + if (!dir.equals(toList)) { + final FTPFile ftpFile = convert(dir); + if (filter == null || filter.accept(ftpFile)) { + files.add(ftpFile); + } + } + return super.preVisitDirectory(dir, attrs); + } + }); + + return files.toArray(new FTPFile[files.size()]); + } + + @Override + public boolean deleteFile(String pathname) throws IOException { + return Files.deleteIfExists(getPath(pathname)); + } + + @Override + public OutputStream storeFileStream(String remote) throws IOException { + return Files.newOutputStream(getPath(remote)); + } + + @Override + public boolean storeFile(String remote, InputStream local) throws IOException { + return Files.copy(local, getPath(remote)) > 0; + } + + @Override + public InputStream retrieveFileStream(String remote) throws IOException { + return Files.newInputStream(getPath(remote)); + } + + @Override + public boolean retrieveFile(String remote, OutputStream local) throws IOException { + return Files.copy(getPath(remote), local) > 0; + } + + @Override + public OutputStream appendFileStream(String remote) throws IOException { + return Files.newOutputStream(getPath(remote), StandardOpenOption.CREATE, StandardOpenOption.APPEND); + } + + @Override + public boolean appendFile(String remote, InputStream local) throws IOException { + final byte[] buffer = new byte[8192]; + int total=0; + try (final OutputStream out = appendFileStream(remote)) { + int read = 0; + while ((read = local.read(buffer)) >= 0) { + out.write(buffer, 0, read); + total += read; + } + } + + return total > 0; + } + + /** + * Convert a path into {@link FTPFile}. + * @param input Path to see as {@link FTPFile} + * @return A view of given path through {@link FTPFile} API. + * @throws IOException If we cannot read attributes of input file. + */ + private static FTPFile convert(final Path input) throws IOException { + final BasicFileAttributes attrs = Files.getFileAttributeView(input, BasicFileAttributeView.class).readAttributes(); + final FTPFile ftp = new FTPFile(); + ftp.setName(input.getFileName().toString()); + ftp.setSize(attrs.size()); + final Calendar cal = new GregorianCalendar(); + cal.setTime(new Date(attrs.lastModifiedTime().toMillis())); + ftp.setTimestamp(cal); + if (Files.isDirectory(input)) { + ftp.setType(FTPFile.DIRECTORY_TYPE); + } else if (Files.isSymbolicLink(input)) { + ftp.setType(FTPFile.SYMBOLIC_LINK_TYPE); + } else { + ftp.setType(FTPFile.FILE_TYPE); + } + + return ftp; + } + + @Override + public boolean completePendingCommand() throws IOException { + return true; + } +} diff --git a/core/src/test/java/fr/cenra/rhomeo/core/preferences/ftp/MockFTPPreferences.java b/core/src/test/java/fr/cenra/rhomeo/core/preferences/ftp/MockFTPPreferences.java new file mode 100644 index 0000000..a3690af --- /dev/null +++ b/core/src/test/java/fr/cenra/rhomeo/core/preferences/ftp/MockFTPPreferences.java @@ -0,0 +1,136 @@ +/** + * 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.core.preferences.ftp; + +import fr.cenra.rhomeo.core.RhomeoCore; +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.security.GeneralSecurityException; +import java.util.List; +import java.util.logging.Level; +import java.util.prefs.Preferences; +import javax.annotation.PreDestroy; +import org.apache.commons.net.ftp.FTPClient; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Component; + +/** + * + * @author Alexis Manin (Geomatys) + */ +@Component +@Primary +public class MockFTPPreferences implements FTPPreferences { + + /** + * A temporary directory to simulate FTP file tree. + */ + private final Path mockDir; + + private final Preferences mockPreferences; + + protected MockFTPPreferences() throws IOException { + mockDir = Files.createTempDirectory("mockFTPRhomeo"); + mockPreferences = Preferences.userNodeForPackage(MockFTPPreferences.class); + } + + @Override + public FTPAccess getAccess(ACCESS_POINTS ap) { + return new MockFTPAccess(mockPreferences.node("test_".concat(ap.name()))); + } + + @Override + public String getPreference(Object key) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void setPreference(Object key, String value) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public List getKeys() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + private class MockFTPAccess extends FTPAccess { + + public MockFTPAccess(Preferences prefs) { + super(prefs); + } + + @Override + public FTPClient createClient() throws IOException, GeneralSecurityException { + return new MockFTPClient(mockDir); + } + } + + @PreDestroy + private void deleteTempDir() { + try { + Files.walkFileTree(mockDir, new SimpleFileVisitor() { + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + Files.delete(dir); + return super.postVisitDirectory(dir, exc); + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + Files.delete(file); + return super.visitFile(file, attrs); + } + + }); + } catch (IOException e) { + RhomeoCore.LOGGER.log(Level.WARNING, "A temporary resource cannot be deleted : ".concat(mockDir.toString()), e); + } + } + + @Override + public int getPriority() { + return 0; + } +} \ No newline at end of file diff --git a/core/src/test/java/fr/cenra/rhomeo/core/result/MockAnnualIndexSpi.java b/core/src/test/java/fr/cenra/rhomeo/core/result/MockAnnualIndexSpi.java new file mode 100644 index 0000000..e2a3312 --- /dev/null +++ b/core/src/test/java/fr/cenra/rhomeo/core/result/MockAnnualIndexSpi.java @@ -0,0 +1,142 @@ +/** + * 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.core.result; + +import fr.cenra.rhomeo.api.process.Indicator; +import fr.cenra.rhomeo.api.result.Index; +import fr.cenra.rhomeo.api.result.IndexSpi; +import fr.cenra.rhomeo.core.data.MockIndicator; +import java.util.Collection; +import java.util.Collections; +import java.util.Objects; +import javax.measure.unit.Unit; +import org.apache.sis.util.ArgumentChecks; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +/** + * + * @author Alexis Manin (Geomatys) + */ +@Component +public class MockAnnualIndexSpi implements IndexSpi { + + @Autowired + @Qualifier(MockIndicator.NAME) + Indicator i; + + @Override + public Unit getUnit() { + return Unit.ONE; + } + + @Override + public Indicator getIndicator() { + return i; + } + + @Override + public MockAnnualIndex createIndex(Integer value, Integer entity) { + return new MockAnnualIndex(value, entity == null? 0 : entity); + } + + @Override + public String getName() { + return "\"Mock annual SPI\""; + } + + @Override + public Collection getAlias() { + return Collections.EMPTY_SET; + } + + @Override + public String getRemarks() { + return "A mock index for test purposes."; + } + + public class MockAnnualIndex implements Index { + + private final Integer value; + private final int year; + + public MockAnnualIndex(Integer value, int year) { + ArgumentChecks.ensureNonNull("Value", value); + this.value = value; + this.year = year; + } + + @Override + public Integer getValue() { + return value; + } + + @Override + public int getYear() { + return year; + } + + @Override + public IndexSpi getSpi() { + return MockAnnualIndexSpi.this; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + Objects.hashCode(this.value); + hash = 31 * hash + this.year; + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + + final MockAnnualIndex other = (MockAnnualIndex) obj; + return this.year == other.year && Objects.equals(this.value, other.value); + } + } +} diff --git a/core/src/test/java/fr/cenra/rhomeo/core/result/MockLocationIndexSpi.java b/core/src/test/java/fr/cenra/rhomeo/core/result/MockLocationIndexSpi.java new file mode 100644 index 0000000..a1bc8f6 --- /dev/null +++ b/core/src/test/java/fr/cenra/rhomeo/core/result/MockLocationIndexSpi.java @@ -0,0 +1,150 @@ +/** + * 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.core.result; + +import fr.cenra.rhomeo.api.data.TrackingPoint; +import fr.cenra.rhomeo.api.process.Indicator; +import fr.cenra.rhomeo.api.result.IndexSpi; +import fr.cenra.rhomeo.api.result.TrackingPointIndex; +import fr.cenra.rhomeo.core.data.MockIndicator; +import java.util.Collection; +import java.util.Collections; +import java.util.Objects; +import javax.measure.unit.Unit; +import org.apache.sis.util.ArgumentChecks; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +/** + * + * @author Alexis Manin (Geomatys) + */ +@Component +public class MockLocationIndexSpi implements IndexSpi { + + @Autowired + @Qualifier(MockIndicator.NAME) + Indicator i; + + @Override + public Unit getUnit() { + return Unit.ONE; + } + + @Override + public Indicator getIndicator() { + return i; + } + + @Override + public MockLocationIndex createIndex(Double value, TrackingPoint entity) { + return new MockLocationIndex(value, entity); + } + + @Override + public String getName() { + return "\"Mock location SPI\""; + } + + @Override + public Collection getAlias() { + return Collections.EMPTY_SET; + } + + @Override + public String getRemarks() { + return "A mock index for test purposes."; + } + + public class MockLocationIndex implements TrackingPointIndex { + + private final Double value; + private final TrackingPoint location; + + public MockLocationIndex(final Double value, final TrackingPoint location) { + ArgumentChecks.ensureNonNull("Value", value); + ArgumentChecks.ensureNonNull("Tracking point", location); + this.value = value; + this.location = location; + } + + @Override + public Double getValue() { + return value; + } + + @Override + public int getYear() { + return location.getYear(); + } + + @Override + public IndexSpi getSpi() { + return MockLocationIndexSpi.this; + } + + @Override + public TrackingPoint getPoint() { + return location; + } + + @Override + public int hashCode() { + int hash = 5; + hash = 47 * hash + Objects.hashCode(this.value); + hash = 47 * hash + Objects.hashCode(this.location); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + + final MockLocationIndex other = (MockLocationIndex) obj; + return Objects.equals(this.value, other.value) && + Objects.equals(this.location, other.location); + } + } +} diff --git a/core/src/test/java/fr/cenra/rhomeo/core/state/StateManagementTest.java b/core/src/test/java/fr/cenra/rhomeo/core/state/StateManagementTest.java new file mode 100644 index 0000000..84f5441 --- /dev/null +++ b/core/src/test/java/fr/cenra/rhomeo/core/state/StateManagementTest.java @@ -0,0 +1,228 @@ +/** + * 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.core.state; + +import fr.cenra.rhomeo.RhomeoTestCase; +import fr.cenra.rhomeo.api.data.Protocol; +import fr.cenra.rhomeo.api.data.Site; +import fr.cenra.rhomeo.api.data.TrackingPoint; +import fr.cenra.rhomeo.api.process.Indicator; +import fr.cenra.rhomeo.api.process.ProcessContext; +import fr.cenra.rhomeo.api.result.Index; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.WorkflowStep; +import fr.cenra.rhomeo.core.data.MockIndicator; +import fr.cenra.rhomeo.core.data.MockProtocol; +import fr.cenra.rhomeo.core.data.MockStatement; +import fr.cenra.rhomeo.core.result.MockAnnualIndexSpi; +import fr.cenra.rhomeo.core.result.MockLocationIndexSpi; +import fr.cenra.rhomeo.core.data.site.DuplicatedKeyException; +import fr.cenra.rhomeo.core.data.site.SiteRepository; +import fr.cenra.rhomeo.core.data.site.SiteRepositoryImpl; +import fr.cenra.rhomeo.core.data.site.SiteRepositoryTest; +import static fr.cenra.rhomeo.core.data.site.SiteRepositoryTest.RESOURCES_DATA_SHP; +import java.io.IOException; +import java.net.URISyntaxException; +import java.time.LocalDate; +import java.util.Collections; +import java.util.HashSet; +import org.apache.sis.storage.DataStoreException; +import org.apache.sis.test.DependsOn; +import org.apache.sis.test.DependsOnMethod; +import org.geotoolkit.data.FeatureReader; +import org.geotoolkit.data.query.QueryBuilder; +import org.geotoolkit.data.shapefile.ShapefileFeatureStore; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +/** + * TODO : activate back when the conflict with {@link SiteRepositoryTest} is + * resolved. + * + * @author Alexis Manin (Geomatys) + */ +@DependsOn(SiteRepositoryTest.class) +public class StateManagementTest extends RhomeoTestCase { + + static final MockStatement STATEMENT = new MockStatement("toto", LocalDate.now()); + + /* + * STATE MANAGERS + */ + + @Autowired + ProcessManager processManager; + + @Autowired + ResultManager resultManager; + + /* + * GLOBAL DATA + */ + @Autowired + StateManager manager; + + @Autowired + SiteRepository repo; + + @Autowired + Session session; + + @Autowired + @Qualifier(MockProtocol.NAME) + Protocol protocol; + + @Autowired + @Qualifier(MockIndicator.NAME) + Indicator indicator; + + @Autowired + MockAnnualIndexSpi annualSpi; + + @Autowired + MockLocationIndexSpi locationSpi; + + @Ignore + @Test + public void testSaveDataset() throws Exception { + // Create a fake site for tests. + final Site newSite = createMockSite(repo); + + // insert fake data + session.startEdition(newSite, protocol); + session.requestWorkflowStep(WorkflowStep.DATASET); + + session.getDataset().getItems().add(STATEMENT); + } + + @Ignore + @DependsOnMethod("testSaveDataset") + @Test + public void restoreDataset() throws Exception { + manager.restoreState(); + + // Restore data, check result + Assert.assertTrue("Dataset has not been restored !", manager.restoreState()); + Assert.assertEquals("Dataset has not been filled !", 1, session.getDataset().getItems().size()); + Assert.assertEquals("Dataset does not contain the right statement !", StateManagementTest.STATEMENT, session.getDataset().getItems().get(0)); + } + + @Ignore + @Test + public void testProcess() throws Exception { + final Site mSite = createMockSite(repo); + session.startEdition(mSite, protocol); + session.getDataset().getItems().addAll( + new MockStatement("toto", LocalDate.now()), + new MockStatement("toto", LocalDate.now().minusYears(1)), + new MockStatement("tata", LocalDate.now().minusYears(1)), + new MockStatement("titi", LocalDate.now().minusYears(4)) + ); + + final ProcessContext pCtx = new ProcessContext(session.getDataset(), session.getDataContext()); + session.setProcessContext(pCtx); + session.requestWorkflowStep(WorkflowStep.PROCESS); + + //pCtx.getTrackingPoints().addAll(session.getDataset().getTrackingPoints()); + pCtx.getIndicators().add(indicator); + synchronized (this) { + wait(200); + } + + ProcessContext read = processManager.readProcessContext(); + Assert.assertNotNull("Backup process context", read); + //Assert.assertTrue("Selected tracking points", read.getTrackingPoints().containsAll(session.getDataset().getTrackingPoints())); + Assert.assertEquals(Collections.singleton(indicator), read.getIndicators()); + } + + @Ignore + @Test + public void testResults() throws Exception { + final Site mSite = createMockSite(repo); + session.startEdition(mSite, protocol); + session.getDataset().getItems().addAll( + new MockStatement("toto", LocalDate.now()), + new MockStatement("titi", LocalDate.now().minusYears(4)) + ); + + final ProcessContext pCtx = new ProcessContext(session.getDataset(), session.getDataContext()); + session.setProcessContext(pCtx); + + final HashSet results = new HashSet<>(4); + final MockAnnualIndexSpi.MockAnnualIndex first = annualSpi.createIndex(10, 2016); + final MockLocationIndexSpi.MockLocationIndex second = locationSpi.createIndex(4.3, (TrackingPoint) session.getDataset().getTrackingPoints().get(0)); + final MockAnnualIndexSpi.MockAnnualIndex third = annualSpi.createIndex(12, 2016); + final MockLocationIndexSpi.MockLocationIndex fourth = locationSpi.createIndex(6d, (TrackingPoint) session.getDataset().getTrackingPoints().get(1)); + + results.add(first); + results.add(second); + results.add(third); + results.add(fourth); + + session.setResults(results); + session.requestWorkflowStep(WorkflowStep.RESULT); // should start writing data + synchronized (this) { + wait(200); + } + + session.setResults(null); + Assert.assertTrue("Results should have been restored !", resultManager.restoreStep()); + + Assert.assertEquals("Restored result", results, session.getResults()); + } + + static Site createMockSite(final SiteRepository repo) throws DataStoreException, IOException, DuplicatedKeyException, URISyntaxException { + final Site newSite; + try (final ShapefileFeatureStore testDataStore = new ShapefileFeatureStore(SiteRepositoryTest.class.getResource(RESOURCES_DATA_SHP).toURI(), "no namespace"); + final FeatureReader reader = testDataStore.getFeatureReader(QueryBuilder.all(testDataStore.getName()))) { + + newSite = SiteRepositoryImpl.toSite(reader.next()); + try { + repo.create(newSite); + } catch (DuplicatedKeyException e) { + // The site already exists + } + } + + return newSite; + } +} diff --git a/core/src/test/java/fr/cenra/rhomeo/core/util/ExportUtilsTest.java b/core/src/test/java/fr/cenra/rhomeo/core/util/ExportUtilsTest.java new file mode 100644 index 0000000..c105cd8 --- /dev/null +++ b/core/src/test/java/fr/cenra/rhomeo/core/util/ExportUtilsTest.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.core.util; + +import fr.cenra.rhomeo.core.data.site.SiteRepositoryTest; +import java.io.File; +import java.io.IOException; +import javax.xml.stream.XMLStreamException; +import org.apache.sis.storage.DataStoreException; +import org.geotoolkit.data.FeatureReader; +import org.geotoolkit.data.kml.model.KmlException; +import org.geotoolkit.data.query.QueryBuilder; +import org.geotoolkit.data.shapefile.ShapefileFeatureStore; +import org.geotoolkit.feature.Feature; +import org.junit.Test; +import org.opengis.referencing.operation.TransformException; +import fr.cenra.rhomeo.core.data.site.SiteImpl; +import static fr.cenra.rhomeo.core.data.site.SiteRepositoryImpl.toSite; +import static fr.cenra.rhomeo.core.util.ExportUtils.writeKml; +import java.net.URISyntaxException; +import static org.junit.Assert.assertTrue; +import static fr.cenra.rhomeo.core.util.ExportUtils.writeKml; + +/** + * + * @author Samuel Andrés (Geomatys) + */ +public class ExportUtilsTest { + + @Test + public void test() throws IOException, XMLStreamException, DataStoreException, KmlException, TransformException, URISyntaxException { + + try (final ShapefileFeatureStore testDataStore = new ShapefileFeatureStore(SiteRepositoryTest.class.getResource("sites.shp").toURI(), "no namespace"); + final FeatureReader reader = testDataStore.getFeatureReader(QueryBuilder.all(testDataStore.getName()))) { + + assertTrue(reader.hasNext()); + + final Feature site = reader.next(); + final File output = File.createTempFile("export", "kml"); + output.deleteOnExit(); + writeKml(site, output); + assertTrue(output.length()>0); + } + } + + @Test + public void testNullValues() throws IOException, XMLStreamException, DataStoreException, KmlException, TransformException, URISyntaxException { + + try (final ShapefileFeatureStore testDataStore = new ShapefileFeatureStore(SiteRepositoryTest.class.getResource("sites.shp").toURI(), "no namespace"); + final FeatureReader reader = testDataStore.getFeatureReader(QueryBuilder.all(testDataStore.getName()))) { + + assertTrue(reader.hasNext()); + + final SiteImpl site = (SiteImpl) toSite(reader.next()); + site.setCountyCode(null); + site.setOdonateType(null); + site.setOrganization(null); + site.setOrthoptereType(null); + site.setGeometry(null); + site.setZoneType(null); + site.setName(null); + site.setReferent(null); + site.setRemarks(null); + + final File output = File.createTempFile("export", "kml"); + output.deleteOnExit(); + writeKml(site, output); + assertTrue(output.length()>0); + } + } + + @Test + public void testNullValues2() throws IOException, XMLStreamException, DataStoreException, KmlException, TransformException, URISyntaxException { + + try (final ShapefileFeatureStore testDataStore = new ShapefileFeatureStore(SiteRepositoryTest.class.getResource("sitesVide.shp").toURI(), "no namespace"); + final FeatureReader reader = testDataStore.getFeatureReader(QueryBuilder.all(testDataStore.getName()))) { + + assertTrue(reader.hasNext()); + + final Feature site = reader.next(); + final File output = File.createTempFile("export", "kml"); + output.deleteOnExit(); + writeKml(site, output); + assertTrue(output.length()>0); + } + } +} diff --git a/core/src/test/java/fr/cenra/rhomeo/core/util/SecretGeneratorTest.java b/core/src/test/java/fr/cenra/rhomeo/core/util/SecretGeneratorTest.java new file mode 100644 index 0000000..cf9ba7a --- /dev/null +++ b/core/src/test/java/fr/cenra/rhomeo/core/util/SecretGeneratorTest.java @@ -0,0 +1,60 @@ +/** + * 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.core.util; + +import java.security.GeneralSecurityException; +import org.junit.Assert; +import org.junit.Test; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class SecretGeneratorTest { + + @Test + public void testEncryptDecrypt() throws GeneralSecurityException { + final SecretGenerator gen = SecretGenerator.getInstance().orElseThrow(() -> new IllegalStateException()); + final String input = "This is My test: a random% phrase g-enerated { with str~*ge syntax ! (123] "; + final EncryptionResult encrypted = gen.encrypt(input); + + final String output = gen.decrypt(encrypted.output, encrypted.getKey(), encrypted.getSecureRandom()); + Assert.assertEquals("Decrypted string should be the same as encrypted one !", input, output); + } +} diff --git a/core/src/test/java/fr/cenra/rhomeo/core/util/TemporalConvertersTest.java b/core/src/test/java/fr/cenra/rhomeo/core/util/TemporalConvertersTest.java new file mode 100644 index 0000000..af85eec --- /dev/null +++ b/core/src/test/java/fr/cenra/rhomeo/core/util/TemporalConvertersTest.java @@ -0,0 +1,124 @@ +/** + * 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.core.util; + +import fr.cenra.rhomeo.core.RhomeoCore; +import java.sql.Timestamp; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.Month; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.logging.Level; +import org.apache.sis.internal.converter.SystemRegistry; +import org.apache.sis.util.ObjectConverters; +import org.junit.Assert; +import org.junit.Test; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class TemporalConvertersTest { + + @Test + public void testToString() { + final ZonedDateTime input = ZonedDateTime.now(); + + TemporalConverters.ZonedDateTime2String date2String = new TemporalConverters.ZonedDateTime2String(); + final String output = date2String.apply(input); + Assert.assertTrue("Formatted date is not a valid timestamp !", input.isEqual(TemporalConverters.fromTimestamp(Long.parseLong(output)))); + } + + @Test + public void testFromString() { + // Separator shuffle ! + final String firstTest = "2015-04-19_10/12.14;GMT+02:00"; + final ZonedDateTime firstExpected = ZonedDateTime.of(2015, 04, 19, 10, 12, 14, 0, ZoneId.of("UTC+02:00")); + // Simple say first date. + final String secondTest = "19-04-2016"; + final ZonedDateTime secondExpected = ZonedDateTime.of(LocalDate.of(2016, Month.APRIL, 19), LocalTime.MIDNIGHT, ZoneOffset.UTC); + // ISO date time + final ZonedDateTime thirdExpected = ZonedDateTime.now(); + final String thirdTest = thirdExpected.format(DateTimeFormatter.ISO_ZONED_DATE_TIME); + // A timestamp put in a string + final String fourthTest = Long.toString(thirdExpected.toInstant().toEpochMilli()); + + TemporalConverters.String2ZonedDateTime str2Date = new TemporalConverters.String2ZonedDateTime(); + Assert.assertTrue("Random separator conversion failed !", firstExpected.isEqual(str2Date.apply(firstTest))); + Assert.assertTrue("Simple day first date conversion failed !", secondExpected.isEqual(str2Date.apply(secondTest))); + Assert.assertTrue("ISO date conversion failed !", thirdExpected.isEqual(str2Date.apply(thirdTest))); + Assert.assertTrue("String timestamp conversion failed !", thirdExpected.isEqual(str2Date.apply(fourthTest))); + } + + @Test + public void testToLong() { + final ZonedDateTime input = ZonedDateTime.now(); + + TemporalConverters.ZonedDateTime2Long date2Long = new TemporalConverters.ZonedDateTime2Long(); + final Long output = date2Long.apply(input); + Assert.assertTrue("Formatted date is not a valid timestamp !", input.isEqual(new Timestamp(output).toInstant().atZone(ZoneOffset.UTC))); + } + + @Test + public void testFromLong() { + final long milli = System.currentTimeMillis(); + final ZonedDateTime expected = ZonedDateTime.from(Instant.ofEpochMilli(milli).atZone(ZoneOffset.UTC)); + + TemporalConverters.Long2ZonedDateTime long2Date = new TemporalConverters.Long2ZonedDateTime(); + Assert.assertTrue("Long to date and time conversion failed !", expected.isEqual(long2Date.apply(milli))); + } + + @Test + public void testDiscovery() { + try { + Assert.assertEquals(TemporalConverters.String2ZonedDateTime.class, ObjectConverters.find(String.class, ZonedDateTime.class).getClass()); + Assert.assertEquals(TemporalConverters.ZonedDateTime2String.class, ObjectConverters.find(ZonedDateTime.class, String.class).getClass()); + + Assert.assertEquals(TemporalConverters.Long2ZonedDateTime.class, ObjectConverters.find(Long.class, ZonedDateTime.class).getClass()); + Assert.assertEquals(TemporalConverters.ZonedDateTime2Long.class, ObjectConverters.find(ZonedDateTime.class, Long.class).getClass()); + } catch (Exception e) { + RhomeoCore.LOGGER.log(Level.INFO, SystemRegistry.INSTANCE.toString()); + throw e; + } + } +} diff --git a/core/src/test/java/fr/cenra/rhomeo/validation/SimpleValidationTest.java b/core/src/test/java/fr/cenra/rhomeo/validation/SimpleValidationTest.java new file mode 100644 index 0000000..57402b7 --- /dev/null +++ b/core/src/test/java/fr/cenra/rhomeo/validation/SimpleValidationTest.java @@ -0,0 +1,89 @@ +/** + * 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.validation; + +import fr.cenra.rhomeo.RhomeoTestCase; +import javax.validation.ConstraintViolationException; +import javax.validation.constraints.NotNull; +import org.junit.Assert; +import org.junit.Test; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; +import org.springframework.validation.annotation.Validated; + +/** + * A simple test to check integration of JSR-349 integration with Spring. + * + * @author Alexis Manin (Geomatys) + */ +public class SimpleValidationTest extends RhomeoTestCase { + + @Test + public void testParameterValidation() { + + final ValidationBean bean = APP_CTX.getBean(ValidationBean.class); + try { + bean.testMethod(null); + Assert.fail("Method validation failed to detect parameter error."); + } catch (ConstraintViolationException e) { + // normal behavior + } + + try { + bean.testMethod("toto"); + Assert.fail("Method validation failed to detect return value error."); + } catch (ConstraintViolationException e) { + // normal behavior + } + } + + /** + * A bean voluntarily violating validation constraints. + */ + @Component + @Scope(value = "prototype") + @Validated + public static class ValidationBean { + + @NotNull + public String testMethod(@NotNull String input) { + return null; + } + } +} diff --git a/core/src/test/resources/fr/cenra/rhomeo/api/international/InternationalDescriptionTest$InternationalDescriptionImpl.properties b/core/src/test/resources/fr/cenra/rhomeo/api/international/InternationalDescriptionTest$InternationalDescriptionImpl.properties new file mode 100644 index 0000000..29ca5da --- /dev/null +++ b/core/src/test/resources/fr/cenra/rhomeo/api/international/InternationalDescriptionTest$InternationalDescriptionImpl.properties @@ -0,0 +1,6 @@ +# To change this license header, choose License Headers in Project Properties. +# To change this template file, choose Tools | Templates +# and open the template in the editor. + +_label=titre en fran\u00e7ais +_description=description en fran\u00e7ais diff --git a/core/src/test/resources/fr/cenra/rhomeo/api/international/InternationalDescriptionTest$InternationalDescriptionImpl_en.properties b/core/src/test/resources/fr/cenra/rhomeo/api/international/InternationalDescriptionTest$InternationalDescriptionImpl_en.properties new file mode 100644 index 0000000..65ab52a --- /dev/null +++ b/core/src/test/resources/fr/cenra/rhomeo/api/international/InternationalDescriptionTest$InternationalDescriptionImpl_en.properties @@ -0,0 +1,6 @@ +# To change this license header, choose License Headers in Project Properties. +# To change this template file, choose Tools | Templates +# and open the template in the editor. + +_label=title in english +_description=description in english diff --git a/core/src/test/resources/fr/cenra/rhomeo/api/international/InternationalResourceTest$InternationalResourceImpl.properties b/core/src/test/resources/fr/cenra/rhomeo/api/international/InternationalResourceTest$InternationalResourceImpl.properties new file mode 100644 index 0000000..873e55a --- /dev/null +++ b/core/src/test/resources/fr/cenra/rhomeo/api/international/InternationalResourceTest$InternationalResourceImpl.properties @@ -0,0 +1,13 @@ +# To change this license header, choose License Headers in Project Properties. +# To change this template file, choose Tools | Templates +# and open the template in the editor. + +field1=champ 1 +field2=champ 2 +field1._label=titre du champ 1 +field1._description=description du champ 1 +field2._label=titre du champ 2 +field2._description=description du champ 2 +#Commentaire +other=Autre champ +withParameters=Bonjour {0} et au revoir {1} ! diff --git a/core/src/test/resources/fr/cenra/rhomeo/api/international/InternationalResourceTest$InternationalResourceImpl_en.properties b/core/src/test/resources/fr/cenra/rhomeo/api/international/InternationalResourceTest$InternationalResourceImpl_en.properties new file mode 100644 index 0000000..4069e20 --- /dev/null +++ b/core/src/test/resources/fr/cenra/rhomeo/api/international/InternationalResourceTest$InternationalResourceImpl_en.properties @@ -0,0 +1,13 @@ +# To change this license header, choose License Headers in Project Properties. +# To change this template file, choose Tools | Templates +# and open the template in the editor. + +field1=field 1 +field2=field 2 +field1._label=title of field 1 +field1._description=description of field 1 +field2._label=title of field 2 +field2._description=description of field 2 +#Commentaire +other=Other field +withParameters=Hello {0} and good bye {1}! diff --git a/core/src/test/resources/fr/cenra/rhomeo/core/data/site/sites.cpg b/core/src/test/resources/fr/cenra/rhomeo/core/data/site/sites.cpg new file mode 100644 index 0000000..cd89cb9 --- /dev/null +++ b/core/src/test/resources/fr/cenra/rhomeo/core/data/site/sites.cpg @@ -0,0 +1 @@ +ISO-8859-1 \ No newline at end of file diff --git a/core/src/test/resources/fr/cenra/rhomeo/core/data/site/sites.dbf b/core/src/test/resources/fr/cenra/rhomeo/core/data/site/sites.dbf new file mode 100644 index 0000000000000000000000000000000000000000..1861c06ede2fc053f9b9c315840d38f3c001ebe3 GIT binary patch literal 2322 zcmZP;V3B5IU|>*W{KyWZFo2(QxW9q>lox63=(w)$)U?T`-l34M1nOr z{{dQrE+6FT<{ISc7Xs4%iwRTSKgb=d86^LM8B;zaG63$rZ!DPd{x1H0jv-(r&Rdl-N4}di49YpS0N;|xI|$TjK~l$vmBA$9`*Ey4*_F6!x0(i39Y?#c|A(J(Mml2G zjv~qk*<^ce+okO$$ literal 0 HcmV?d00001 diff --git a/core/src/test/resources/fr/cenra/rhomeo/core/data/site/sites.shx b/core/src/test/resources/fr/cenra/rhomeo/core/data/site/sites.shx new file mode 100644 index 0000000000000000000000000000000000000000..6f5b31d1fd1dc32b7e7274180027978995b7a9c6 GIT binary patch literal 108 zcmZQzQ0HR64$NLKGcd3M<#JU{#whA)I4a%pJi$FX!qJRJS>(i39Y?#c|A(J(Mml2G Ljv{IV*W{KyWZFo2(QxW9q>lox63=+jE@9ZDy7ZM59gjGJs z)y*}?)h`5>e*YkMux4EHA&~)i-RJM(@8=i-R)W=j|DX^L|9}vn8?d{dS0N;|xFjqy eB~@V*jJOamHW_hV9`*2O2#kinXb6nh5C8z{j~e9w literal 0 HcmV?d00001 diff --git a/core/src/test/resources/fr/cenra/rhomeo/core/data/site/sitesVide.prj b/core/src/test/resources/fr/cenra/rhomeo/core/data/site/sitesVide.prj new file mode 100644 index 0000000..5adb2a9 --- /dev/null +++ b/core/src/test/resources/fr/cenra/rhomeo/core/data/site/sitesVide.prj @@ -0,0 +1 @@ +PROJCS["RGF93_Lambert_93",GEOGCS["GCS_RGF93",DATUM["D_RGF_1993",SPHEROID["GRS_1980",6378137,298.257222101]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["standard_parallel_1",49],PARAMETER["standard_parallel_2",44],PARAMETER["latitude_of_origin",46.5],PARAMETER["central_meridian",3],PARAMETER["false_easting",700000],PARAMETER["false_northing",6600000],UNIT["Meter",1]] \ No newline at end of file diff --git a/core/src/test/resources/fr/cenra/rhomeo/core/data/site/sitesVide.qpj b/core/src/test/resources/fr/cenra/rhomeo/core/data/site/sitesVide.qpj new file mode 100644 index 0000000..52a60bf --- /dev/null +++ b/core/src/test/resources/fr/cenra/rhomeo/core/data/site/sitesVide.qpj @@ -0,0 +1 @@ +PROJCS["RGF93 / Lambert-93",GEOGCS["RGF93",DATUM["Reseau_Geodesique_Francais_1993",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6171"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4171"]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",49],PARAMETER["standard_parallel_2",44],PARAMETER["latitude_of_origin",46.5],PARAMETER["central_meridian",3],PARAMETER["false_easting",700000],PARAMETER["false_northing",6600000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["X",EAST],AXIS["Y",NORTH],AUTHORITY["EPSG","2154"]] diff --git a/core/src/test/resources/fr/cenra/rhomeo/core/data/site/sitesVide.shp b/core/src/test/resources/fr/cenra/rhomeo/core/data/site/sitesVide.shp new file mode 100644 index 0000000000000000000000000000000000000000..8f2bdcd1a8f3aaa58582c376406c84b2c6b33d57 GIT binary patch literal 252 zcmZQzQ0HR64(eVoGcd3M<#JU{#whA)I4a%pJi$FX!qJRJS>(i39Y?#c|A(J(Mml2G zjv~qk*<^ce+okO$$ literal 0 HcmV?d00001 diff --git a/core/src/test/resources/fr/cenra/rhomeo/core/data/site/sitesVide.shx b/core/src/test/resources/fr/cenra/rhomeo/core/data/site/sitesVide.shx new file mode 100644 index 0000000000000000000000000000000000000000..6f5b31d1fd1dc32b7e7274180027978995b7a9c6 GIT binary patch literal 108 zcmZQzQ0HR64$NLKGcd3M<#JU{#whA)I4a%pJi$FX!qJRJS>(i39Y?#c|A(J(Mml2G Ljv{IV + + true + + + + + %msg%n + %d{dd-MM HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg%n + + + + + + + \ No newline at end of file diff --git a/desktop/pom.xml b/desktop/pom.xml new file mode 100644 index 0000000..d22bacb --- /dev/null +++ b/desktop/pom.xml @@ -0,0 +1,116 @@ + + + + 4.0.0 + + + fr.cenra.rhomeo + rhomeo + 1.2-SNAPSHOT + + + fr.cenra.rhomeo + desktop + jar + Rhomeo desktop + Rhomeo client application + + + + fr.cenra.rhomeo + core + ${project.version} + + + fr.cenra.rhomeo + protocol + ${project.version} + + + commons-codec + commons-codec + + + org.geotoolkit + geotk-widgets-javafx + + + org.quartz-scheduler + quartz + + + org.fxmisc.richtext + richtextfx + + + org.codehaus.groovy + groovy-all + + + + + org.geotoolkit + geotk-client-wfs + + + org.geotoolkit + geotk-jaxp-xsd + + + + junit + junit + test + + + org.hamcrest + hamcrest-core + 1.3 + test + + + + org.springframework + spring-test + test + + + + + + Rhomeo + + + com.zenjava + javafx-maven-plugin + + ${project.version} + fr.cenra.rhomeo.Launcher + true + + + -XX:+UseG1GC + + -Xms256m + -Xmx1G + + -Djava.net.useSystemProxies=true + + -Dfile.encoding=UTF-8 + + + src/main/deploy/additional + + + + Copyright (C) 2016, CENRA + CLUF + + + + + + + \ No newline at end of file diff --git a/desktop/src/main/deploy/additional/CLUF b/desktop/src/main/deploy/additional/CLUF new file mode 100644 index 0000000..0e5d105 --- /dev/null +++ b/desktop/src/main/deploy/additional/CLUF @@ -0,0 +1,550 @@ + + CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL + +Version 2.1 du 2013-06-21 + + + Avertissement + +Ce contrat est une licence de logiciel libre issue d'une concertation +entre ses auteurs afin que le respect de deux grands principes préside à +sa rédaction: + + * d'une part, le respect des principes de diffusion des logiciels + libres: accès au code source, droits étendus conférés aux utilisateurs, + * d'autre part, la désignation d'un droit applicable, le droit + français, auquel elle est conforme, tant au regard du droit de la + responsabilité civile que du droit de la propriété intellectuelle et + de la protection qu'il offre aux auteurs et titulaires des droits + patrimoniaux sur un logiciel. + +Les auteurs de la licence CeCILL (Ce[a] C[nrs] I[nria] L[ogiciel] L[ibre]) +sont: + +Commissariat à l'énergie atomique et aux énergies alternatives - CEA, +établissement public de recherche à caractère scientifique, technique et +industriel, dont le siège est situé 25 rue Leblanc, immeuble Le Ponant +D, 75015 Paris. + +Centre National de la Recherche Scientifique - CNRS, établissement +public à caractère scientifique et technologique, dont le siège est +situé 3 rue Michel-Ange, 75794 Paris cedex 16. + +Institut National de Recherche en Informatique et en Automatique - +Inria, établissement public à caractère scientifique et technologique, +dont le siège est situé Domaine de Voluceau, Rocquencourt, BP 105, 78153 +Le Chesnay cedex. + + + Préambule + +Ce contrat est une licence de logiciel libre dont l'objectif est de +conférer aux utilisateurs la liberté de modification et de +redistribution du logiciel régi par cette licence dans le cadre d'un +modèle de diffusion en logiciel libre. + +L'exercice de ces libertés est assorti de certains devoirs à la charge +des utilisateurs afin de préserver ce statut au cours des +redistributions ultérieures. + +L'accessibilité au code source et les droits de copie, de modification +et de redistribution qui en découlent ont pour contrepartie de n'offrir +aux utilisateurs qu'une garantie limitée et de ne faire peser sur +l'auteur du logiciel, le titulaire des droits patrimoniaux et les +concédants successifs qu'une responsabilité restreinte. + +A cet égard l'attention de l'utilisateur est attirée sur les risques +associés au chargement, à l'utilisation, à la modification et/ou au +développement et à la reproduction du logiciel par l'utilisateur étant +donné sa spécificité de logiciel libre, qui peut le rendre complexe à +manipuler et qui le réserve donc à des développeurs ou des +professionnels avertis possédant des connaissances informatiques +approfondies. Les utilisateurs sont donc invités à charger et tester +l'adéquation du logiciel à leurs besoins dans des conditions permettant +d'assurer la sécurité de leurs systèmes et/ou de leurs données et, plus +généralement, à l'utiliser et l'exploiter dans les mêmes conditions de +sécurité. Ce contrat peut être reproduit et diffusé librement, sous +réserve de le conserver en l'état, sans ajout ni suppression de clauses. + +Ce contrat est susceptible de s'appliquer à tout logiciel dont le +titulaire des droits patrimoniaux décide de soumettre l'exploitation aux +dispositions qu'il contient. + +Une liste de questions fréquemment posées se trouve sur le site web +officiel de la famille des licences CeCILL +(http://www.cecill.info/index.fr.html) pour toute clarification qui +serait nécessaire. + + + Article 1 - DEFINITIONS + +Dans ce contrat, les termes suivants, lorsqu'ils seront écrits avec une +lettre capitale, auront la signification suivante: + +Contrat: désigne le présent contrat de licence, ses éventuelles versions +postérieures et annexes. + +Logiciel: désigne le logiciel sous sa forme de Code Objet et/ou de Code +Source et le cas échéant sa documentation, dans leur état au moment de +l'acceptation du Contrat par le Licencié. + +Logiciel Initial: désigne le Logiciel sous sa forme de Code Source et +éventuellement de Code Objet et le cas échéant sa documentation, dans +leur état au moment de leur première diffusion sous les termes du Contrat. + +Logiciel Modifié: désigne le Logiciel modifié par au moins une +Contribution. + +Code Source: désigne l'ensemble des instructions et des lignes de +programme du Logiciel et auquel l'accès est nécessaire en vue de +modifier le Logiciel. + +Code Objet: désigne les fichiers binaires issus de la compilation du +Code Source. + +Titulaire: désigne le ou les détenteurs des droits patrimoniaux d'auteur +sur le Logiciel Initial. + +Licencié: désigne le ou les utilisateurs du Logiciel ayant accepté le +Contrat. + +Contributeur: désigne le Licencié auteur d'au moins une Contribution. + +Concédant: désigne le Titulaire ou toute personne physique ou morale +distribuant le Logiciel sous le Contrat. + +Contribution: désigne l'ensemble des modifications, corrections, +traductions, adaptations et/ou nouvelles fonctionnalités intégrées dans +le Logiciel par tout Contributeur, ainsi que tout Module Interne. + +Module: désigne un ensemble de fichiers sources y compris leur +documentation qui permet de réaliser des fonctionnalités ou services +supplémentaires à ceux fournis par le Logiciel. + +Module Externe: désigne tout Module, non dérivé du Logiciel, tel que ce +Module et le Logiciel s'exécutent dans des espaces d'adressage +différents, l'un appelant l'autre au moment de leur exécution. + +Module Interne: désigne tout Module lié au Logiciel de telle sorte +qu'ils s'exécutent dans le même espace d'adressage. + +GNU GPL: désigne la GNU General Public License dans sa version 2 ou +toute version ultérieure, telle que publiée par Free Software Foundation +Inc. + +GNU Affero GPL: désigne la GNU Affero General Public License dans sa +version 3 ou toute version ultérieure, telle que publiée par Free +Software Foundation Inc. + +EUPL: désigne la Licence Publique de l'Union européenne dans sa version +1.1 ou toute version ultérieure, telle que publiée par la Commission +Européenne. + +Parties: désigne collectivement le Licencié et le Concédant. + +Ces termes s'entendent au singulier comme au pluriel. + + + Article 2 - OBJET + +Le Contrat a pour objet la concession par le Concédant au Licencié d'une +licence non exclusive, cessible et mondiale du Logiciel telle que +définie ci-après à l'article 5 <#etendue> pour toute la durée de +protection des droits portant sur ce Logiciel. + + + Article 3 - ACCEPTATION + +3.1 L'acceptation par le Licencié des termes du Contrat est réputée +acquise du fait du premier des faits suivants: + + * (i) le chargement du Logiciel par tout moyen notamment par + téléchargement à partir d'un serveur distant ou par chargement à + partir d'un support physique; + * (ii) le premier exercice par le Licencié de l'un quelconque des + droits concédés par le Contrat. + +3.2 Un exemplaire du Contrat, contenant notamment un avertissement +relatif aux spécificités du Logiciel, à la restriction de garantie et à +la limitation à un usage par des utilisateurs expérimentés a été mis à +disposition du Licencié préalablement à son acceptation telle que +définie à l'article 3.1 <#acceptation-acquise> ci dessus et le Licencié +reconnaît en avoir pris connaissance. + + + Article 4 - ENTREE EN VIGUEUR ET DUREE + + + 4.1 ENTREE EN VIGUEUR + +Le Contrat entre en vigueur à la date de son acceptation par le Licencié +telle que définie en 3.1 <#acceptation-acquise>. + + + 4.2 DUREE + +Le Contrat produira ses effets pendant toute la durée légale de +protection des droits patrimoniaux portant sur le Logiciel. + + + Article 5 - ETENDUE DES DROITS CONCEDES + +Le Concédant concède au Licencié, qui accepte, les droits suivants sur +le Logiciel pour toutes destinations et pour la durée du Contrat dans +les conditions ci-après détaillées. + +Par ailleurs, si le Concédant détient ou venait à détenir un ou +plusieurs brevets d'invention protégeant tout ou partie des +fonctionnalités du Logiciel ou de ses composants, il s'engage à ne pas +opposer les éventuels droits conférés par ces brevets aux Licenciés +successifs qui utiliseraient, exploiteraient ou modifieraient le +Logiciel. En cas de cession de ces brevets, le Concédant s'engage à +faire reprendre les obligations du présent alinéa aux cessionnaires. + + + 5.1 DROIT D'UTILISATION + +Le Licencié est autorisé à utiliser le Logiciel, sans restriction quant +aux domaines d'application, étant ci-après précisé que cela comporte: + + 1. + + la reproduction permanente ou provisoire du Logiciel en tout ou + partie par tout moyen et sous toute forme. + + 2. + + le chargement, l'affichage, l'exécution, ou le stockage du Logiciel + sur tout support. + + 3. + + la possibilité d'en observer, d'en étudier, ou d'en tester le + fonctionnement afin de déterminer les idées et principes qui sont à + la base de n'importe quel élément de ce Logiciel; et ceci, lorsque + le Licencié effectue toute opération de chargement, d'affichage, + d'exécution, de transmission ou de stockage du Logiciel qu'il est en + droit d'effectuer en vertu du Contrat. + + + 5.2 DROIT D'APPORTER DES CONTRIBUTIONS + +Le droit d'apporter des Contributions comporte le droit de traduire, +d'adapter, d'arranger ou d'apporter toute autre modification au Logiciel +et le droit de reproduire le logiciel en résultant. + +Le Licencié est autorisé à apporter toute Contribution au Logiciel sous +réserve de mentionner, de façon explicite, son nom en tant qu'auteur de +cette Contribution et la date de création de celle-ci. + + + 5.3 DROIT DE DISTRIBUTION + +Le droit de distribution comporte notamment le droit de diffuser, de +transmettre et de communiquer le Logiciel au public sur tout support et +par tout moyen ainsi que le droit de mettre sur le marché à titre +onéreux ou gratuit, un ou des exemplaires du Logiciel par tout procédé. + +Le Licencié est autorisé à distribuer des copies du Logiciel, modifié ou +non, à des tiers dans les conditions ci-après détaillées. + + + 5.3.1 DISTRIBUTION DU LOGICIEL SANS MODIFICATION + +Le Licencié est autorisé à distribuer des copies conformes du Logiciel, +sous forme de Code Source ou de Code Objet, à condition que cette +distribution respecte les dispositions du Contrat dans leur totalité et +soit accompagnée: + + 1. + + d'un exemplaire du Contrat, + + 2. + + d'un avertissement relatif à la restriction de garantie et de + responsabilité du Concédant telle que prévue aux articles 8 + <#responsabilite> et 9 <#garantie>, + +et que, dans le cas où seul le Code Objet du Logiciel est redistribué, +le Licencié permette un accès effectif au Code Source complet du +Logiciel pour une durée d'au moins 3 ans à compter de la distribution du +logiciel, étant entendu que le coût additionnel d'acquisition du Code +Source ne devra pas excéder le simple coût de transfert des données. + + + 5.3.2 DISTRIBUTION DU LOGICIEL MODIFIE + +Lorsque le Licencié apporte une Contribution au Logiciel, les conditions +de distribution du Logiciel Modifié en résultant sont alors soumises à +l'intégralité des dispositions du Contrat. + +Le Licencié est autorisé à distribuer le Logiciel Modifié, sous forme de +code source ou de code objet, à condition que cette distribution +respecte les dispositions du Contrat dans leur totalité et soit +accompagnée: + + 1. + + d'un exemplaire du Contrat, + + 2. + + d'un avertissement relatif à la restriction de garantie et de + responsabilité du Concédant telle que prévue aux articles 8 + <#responsabilite> et 9 <#garantie>, + +et, dans le cas où seul le code objet du Logiciel Modifié est redistribué, + + 3. + + d'une note précisant les conditions d'accès effectif au code source + complet du Logiciel Modifié, pendant une période d'au moins 3 ans à + compter de la distribution du Logiciel Modifié, étant entendu que le + coût additionnel d'acquisition du code source ne devra pas excéder + le simple coût de transfert des données. + + + 5.3.3 DISTRIBUTION DES MODULES EXTERNES + +Lorsque le Licencié a développé un Module Externe les conditions du +Contrat ne s'appliquent pas à ce Module Externe, qui peut être distribué +sous un contrat de licence différent. + + + 5.3.4 COMPATIBILITE AVEC D'AUTRES LICENCES + +Le Licencié peut inclure un code soumis aux dispositions d'une des +versions de la licence GNU GPL, GNU Affero GPL et/ou EUPL dans le +Logiciel modifié ou non et distribuer l'ensemble sous les conditions de +la même version de la licence GNU GPL, GNU Affero GPL et/ou EUPL. + +Le Licencié peut inclure le Logiciel modifié ou non dans un code soumis +aux dispositions d'une des versions de la licence GNU GPL, GNU Affero +GPL et/ou EUPL et distribuer l'ensemble sous les conditions de la même +version de la licence GNU GPL, GNU Affero GPL et/ou EUPL. + + + Article 6 - PROPRIETE INTELLECTUELLE + + + 6.1 SUR LE LOGICIEL INITIAL + +Le Titulaire est détenteur des droits patrimoniaux sur le Logiciel +Initial. Toute utilisation du Logiciel Initial est soumise au respect +des conditions dans lesquelles le Titulaire a choisi de diffuser son +oeuvre et nul autre n'a la faculté de modifier les conditions de +diffusion de ce Logiciel Initial. + +Le Titulaire s'engage à ce que le Logiciel Initial reste au moins régi +par le Contrat et ce, pour la durée visée à l'article 4.2 <#duree>. + + + 6.2 SUR LES CONTRIBUTIONS + +Le Licencié qui a développé une Contribution est titulaire sur celle-ci +des droits de propriété intellectuelle dans les conditions définies par +la législation applicable. + + + 6.3 SUR LES MODULES EXTERNES + +Le Licencié qui a développé un Module Externe est titulaire sur celui-ci +des droits de propriété intellectuelle dans les conditions définies par +la législation applicable et reste libre du choix du contrat régissant +sa diffusion. + + + 6.4 DISPOSITIONS COMMUNES + +Le Licencié s'engage expressément: + + 1. + + à ne pas supprimer ou modifier de quelque manière que ce soit les + mentions de propriété intellectuelle apposées sur le Logiciel; + + 2. + + à reproduire à l'identique lesdites mentions de propriété + intellectuelle sur les copies du Logiciel modifié ou non. + +Le Licencié s'engage à ne pas porter atteinte, directement ou +indirectement, aux droits de propriété intellectuelle du Titulaire et/ou +des Contributeurs sur le Logiciel et à prendre, le cas échéant, à +l'égard de son personnel toutes les mesures nécessaires pour assurer le +respect des dits droits de propriété intellectuelle du Titulaire et/ou +des Contributeurs. + + + Article 7 - SERVICES ASSOCIES + +7.1 Le Contrat n'oblige en aucun cas le Concédant à la réalisation de +prestations d'assistance technique ou de maintenance du Logiciel. + +Cependant le Concédant reste libre de proposer ce type de services. Les +termes et conditions d'une telle assistance technique et/ou d'une telle +maintenance seront alors déterminés dans un acte séparé. Ces actes de +maintenance et/ou assistance technique n'engageront que la seule +responsabilité du Concédant qui les propose. + +7.2 De même, tout Concédant est libre de proposer, sous sa seule +responsabilité, à ses licenciés une garantie, qui n'engagera que lui, +lors de la redistribution du Logiciel et/ou du Logiciel Modifié et ce, +dans les conditions qu'il souhaite. Cette garantie et les modalités +financières de son application feront l'objet d'un acte séparé entre le +Concédant et le Licencié. + + + Article 8 - RESPONSABILITE + +8.1 Sous réserve des dispositions de l'article 8.2 +<#limite-responsabilite>, le Licencié a la faculté, sous réserve de +prouver la faute du Concédant concerné, de solliciter la réparation du +préjudice direct qu'il subirait du fait du Logiciel et dont il apportera +la preuve. + +8.2 La responsabilité du Concédant est limitée aux engagements pris en +application du Contrat et ne saurait être engagée en raison notamment: +(i) des dommages dus à l'inexécution, totale ou partielle, de ses +obligations par le Licencié, (ii) des dommages directs ou indirects +découlant de l'utilisation ou des performances du Logiciel subis par le +Licencié et (iii) plus généralement d'un quelconque dommage indirect. En +particulier, les Parties conviennent expressément que tout préjudice +financier ou commercial (par exemple perte de données, perte de +bénéfices, perte d'exploitation, perte de clientèle ou de commandes, +manque à gagner, trouble commercial quelconque) ou toute action dirigée +contre le Licencié par un tiers, constitue un dommage indirect et +n'ouvre pas droit à réparation par le Concédant. + + + Article 9 - GARANTIE + +9.1 Le Licencié reconnaît que l'état actuel des connaissances +scientifiques et techniques au moment de la mise en circulation du +Logiciel ne permet pas d'en tester et d'en vérifier toutes les +utilisations ni de détecter l'existence d'éventuels défauts. L'attention +du Licencié a été attirée sur ce point sur les risques associés au +chargement, à l'utilisation, la modification et/ou au développement et à +la reproduction du Logiciel qui sont réservés à des utilisateurs avertis. + +Il relève de la responsabilité du Licencié de contrôler, par tous +moyens, l'adéquation du produit à ses besoins, son bon fonctionnement et +de s'assurer qu'il ne causera pas de dommages aux personnes et aux biens. + +9.2 Le Concédant déclare de bonne foi être en droit de concéder +l'ensemble des droits attachés au Logiciel (comprenant notamment les +droits visés à l'article 5 <#etendue>). + +9.3 Le Licencié reconnaît que le Logiciel est fourni "en l'état" par le +Concédant sans autre garantie, expresse ou tacite, que celle prévue à +l'article 9.2 <#bonne-foi> et notamment sans aucune garantie sur sa +valeur commerciale, son caractère sécurisé, innovant ou pertinent. + +En particulier, le Concédant ne garantit pas que le Logiciel est exempt +d'erreur, qu'il fonctionnera sans interruption, qu'il sera compatible +avec l'équipement du Licencié et sa configuration logicielle ni qu'il +remplira les besoins du Licencié. + +9.4 Le Concédant ne garantit pas, de manière expresse ou tacite, que le +Logiciel ne porte pas atteinte à un quelconque droit de propriété +intellectuelle d'un tiers portant sur un brevet, un logiciel ou sur tout +autre droit de propriété. Ainsi, le Concédant exclut toute garantie au +profit du Licencié contre les actions en contrefaçon qui pourraient être +diligentées au titre de l'utilisation, de la modification, et de la +redistribution du Logiciel. Néanmoins, si de telles actions sont +exercées contre le Licencié, le Concédant lui apportera son expertise +technique et juridique pour sa défense. Cette expertise technique et +juridique est déterminée au cas par cas entre le Concédant concerné et +le Licencié dans le cadre d'un protocole d'accord. Le Concédant dégage +toute responsabilité quant à l'utilisation de la dénomination du +Logiciel par le Licencié. Aucune garantie n'est apportée quant à +l'existence de droits antérieurs sur le nom du Logiciel et sur +l'existence d'une marque. + + + Article 10 - RESILIATION + +10.1 En cas de manquement par le Licencié aux obligations mises à sa +charge par le Contrat, le Concédant pourra résilier de plein droit le +Contrat trente (30) jours après notification adressée au Licencié et +restée sans effet. + +10.2 Le Licencié dont le Contrat est résilié n'est plus autorisé à +utiliser, modifier ou distribuer le Logiciel. Cependant, toutes les +licences qu'il aura concédées antérieurement à la résiliation du Contrat +resteront valides sous réserve qu'elles aient été effectuées en +conformité avec le Contrat. + + + Article 11 - DISPOSITIONS DIVERSES + + + 11.1 CAUSE EXTERIEURE + +Aucune des Parties ne sera responsable d'un retard ou d'une défaillance +d'exécution du Contrat qui serait dû à un cas de force majeure, un cas +fortuit ou une cause extérieure, telle que, notamment, le mauvais +fonctionnement ou les interruptions du réseau électrique ou de +télécommunication, la paralysie du réseau liée à une attaque +informatique, l'intervention des autorités gouvernementales, les +catastrophes naturelles, les dégâts des eaux, les tremblements de terre, +le feu, les explosions, les grèves et les conflits sociaux, l'état de +guerre... + +11.2 Le fait, par l'une ou l'autre des Parties, d'omettre en une ou +plusieurs occasions de se prévaloir d'une ou plusieurs dispositions du +Contrat, ne pourra en aucun cas impliquer renonciation par la Partie +intéressée à s'en prévaloir ultérieurement. + +11.3 Le Contrat annule et remplace toute convention antérieure, écrite +ou orale, entre les Parties sur le même objet et constitue l'accord +entier entre les Parties sur cet objet. Aucune addition ou modification +aux termes du Contrat n'aura d'effet à l'égard des Parties à moins +d'être faite par écrit et signée par leurs représentants dûment habilités. + +11.4 Dans l'hypothèse où une ou plusieurs des dispositions du Contrat +s'avèrerait contraire à une loi ou à un texte applicable, existants ou +futurs, cette loi ou ce texte prévaudrait, et les Parties feraient les +amendements nécessaires pour se conformer à cette loi ou à ce texte. +Toutes les autres dispositions resteront en vigueur. De même, la +nullité, pour quelque raison que ce soit, d'une des dispositions du +Contrat ne saurait entraîner la nullité de l'ensemble du Contrat. + + + 11.5 LANGUE + +Le Contrat est rédigé en langue française et en langue anglaise, ces +deux versions faisant également foi. + + + Article 12 - NOUVELLES VERSIONS DU CONTRAT + +12.1 Toute personne est autorisée à copier et distribuer des copies de +ce Contrat. + +12.2 Afin d'en préserver la cohérence, le texte du Contrat est protégé +et ne peut être modifié que par les auteurs de la licence, lesquels se +réservent le droit de publier périodiquement des mises à jour ou de +nouvelles versions du Contrat, qui posséderont chacune un numéro +distinct. Ces versions ultérieures seront susceptibles de prendre en +compte de nouvelles problématiques rencontrées par les logiciels libres. + +12.3 Tout Logiciel diffusé sous une version donnée du Contrat ne pourra +faire l'objet d'une diffusion ultérieure que sous la même version du +Contrat ou une version postérieure, sous réserve des dispositions de +l'article 5.3.4 <#compatibilite>. + + + Article 13 - LOI APPLICABLE ET COMPETENCE TERRITORIALE + +13.1 Le Contrat est régi par la loi française. Les Parties conviennent +de tenter de régler à l'amiable les différends ou litiges qui +viendraient à se produire par suite ou à l'occasion du Contrat. + +13.2 A défaut d'accord amiable dans un délai de deux (2) mois à compter +de leur survenance et sauf situation relevant d'une procédure d'urgence, +les différends ou litiges seront portés par la Partie la plus diligente +devant les Tribunaux compétents de Paris. + + diff --git a/desktop/src/main/deploy/package/linux/Rhomeo.png b/desktop/src/main/deploy/package/linux/Rhomeo.png new file mode 100644 index 0000000000000000000000000000000000000000..216a11500af32d25d973c500d7d2fd23295eee3f GIT binary patch literal 5230 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 literal 0 HcmV?d00001 diff --git a/desktop/src/main/deploy/package/macosx/Rhomeo.icns b/desktop/src/main/deploy/package/macosx/Rhomeo.icns new file mode 100644 index 0000000000000000000000000000000000000000..3ec2838cc0683e58e9561efb86cfe9560cfd0070 GIT binary patch literal 24230 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 literal 0 HcmV?d00001 diff --git a/desktop/src/main/deploy/package/windows/Rhomeo.ico b/desktop/src/main/deploy/package/windows/Rhomeo.ico new file mode 100644 index 0000000000000000000000000000000000000000..47623503dba87f476ceafa343182c2051f4b428f GIT binary patch literal 32094 zcmeI5zi-?&6vt_J@MurXcpf_y{ts-ROGb|#y?4n!(E9#^db8an2RMP9F1Z3lQ50w- z+jV_EY~0muoAgK81G*QtHA4{feWiOgt%xV;2PNKtXYlyMqol_VA0Npl1rcI_{PLKT{IeFu-&NJ`P#gVtFx?Wx77lXak?$yDg&eeXqdwDRX6e!XNb$VBO z+k?U56;t|x5!q)enWc)cT<*1D-=_4_y)Nu?!c@gGt-OW4(Y;?vtOWn<+jZ&QAAujPa01&&bCX3#zJh&8khH=R0IyH?0l_8;SEYYXxVeq}cM-kj+T zb=c|D>0a&+YvLP_zxR`LjMfV2c4m}6?M0Gw%Tk6tLv3s)dz7R#1^I=cQFiayYeHYr zelQEmq`Jg*R5xFYA6Yl}zS`L`{{nMeO>>&;e{W?ueo^lJEWs|BomTF(<-X4%m%Kl_ zWtDS0v{?7)ahjsMvY*d-WzBPPD9TZF{s{Uki$5d$!3i+Qe{CoWM%oFUFH^_XHGj;}JVuJWt;<&LjDEA{gY^)(z{ zHJdy<rG> z__jE9;`o-&mu=Vihw|AX4#KwU_?FH0{&OM6w^Y7~&*q)~Ersz|e%|K%Ln%x-b}>@1 zb^f6kXFN|$dq>szhg^*Dj>V?z2UN1-n}ILA`=tAxB=dHBReb3kHsXnQT)|Y{GcY@s zI|7b?Bj5-)0*-(q;0QPZj({WJ2si?cfFm#u1YTeFK7Rev`Bs_fuba+CS=k)DyjVTF z>2H*op8nEX%c@7w`r!Gh|Kj=ekKg<=@Y{ij^xLJ^%Btt#O}F{vrW=?@bnPLok3P(* zmu`L7=g$}4zB0ixeofo>%6&$heT)%ZZfW%}R;%L5oNeaItiidcJ^wK{|7>{j)qmXX zs`6RjJK;QjdfnSjv(cpA(Z;HH#_uyjd_#W^-<-ryRfhR1-sUQgXN@mx`S7N*tKun_ z!zWb9GU;Bk$QO*$d$9)_<@VK`&pKaXJYu^={^#(APwHkW-+vDH!cW}3KlQTr{R_E$b<6X>mu$Gj zHf+P1LGIHz;X4Lj#24hY*&xpe-vIFm#Kml2D(f&Wd=Y0uTjaLcAkPoqZqxBK6O+d} z7;&F@;fwhiZL%rN6JNB&CbrN8I@z=@X5T+g{@2F!1NxlT=DImzgErbP^k=)VB}bf8 zmn+vpT+mj&RX@L+){lrYF|({W@g3R382%S+`2Fha^J#6a@;5x2%F31N;~9;Od})vT zph||*?v=+kFkjnz1luq4vmu5CKgF!_=F}$N78{oNBFsH5F0?$=32e1xB^T&S=R;X>my6rfLFWOn2FzARStjr z{3qPiQjBuD(f!G6Ps?re-ICP_rJV^m}zkL5y4v#9*Olp1S8R) zgEwM{!A6@&v%(DypY7^ot6hw3 { + +// if(e instanceof Exception){ +// TaskManager.INSTANCE.submit(() -> {throw (Exception) e;}); +// } +// else{ + RhomeoCore.LOGGER.log(Level.WARNING, "A throwable has not been caught.", e); +// } + }); + + // perform initialization and plugin loading tasks + final InitialLoadingTask initTask = new InitialLoadingTask(); + showLoadingStage(initTask); + TaskManager.INSTANCE.submit(initTask); + } + + /** + * {@inheritDoc} + */ + @Override + public void stop() throws Exception { + try { + Session.getInstance().close(); + } catch (IllegalStateException ex) { + // The context was not already initialized, no need to close it. + // Not a real exception since nothing to do + } + + TaskManager.INSTANCE.close(); + } + + /** + * Display splash screen. + * + * @param task the related task to show progress + * @throws IOException + */ + private void showLoadingStage(final InitialLoadingTask task) throws IOException { + // Initialize splash screen + final Stage splashStage = Rhomeo.newStage(); + splashStage.initStyle(StageStyle.TRANSPARENT); + + final FXMLLoader loader = new FXMLLoader(getClass().getResource("/fr/cenra/rhomeo/fx/FXSplashScreen.fxml")); + final GridPane root = loader.load(); + final FXSplashScreen splashScreen = loader.getController(); + splashScreen.uiCancel.setVisible(false); + splashScreen.uiProgressLabel.textProperty().bind(task.messageProperty()); + splashScreen.uiProgressBar.progressProperty().bind(task.progressProperty()); + + final Scene scene = new Scene(root); + scene.getStylesheets().add("/fr/cenra/rhomeo/splashscreen.css"); + scene.setFill(new Color(0, 0, 0, 0)); + + splashStage.setScene(scene); + splashStage.show(); + + // If the task succeeded, meaning the initialisation is finished or an update has been found + // and user wants to download it. + task.setOnSucceeded(evt -> Platform.runLater(() -> { + final Object value = task.getValue(); + // If value is an URL, then it is an update to download. + // Otherwise, nothing to download keep going with the application start. + if (value instanceof URLAndMD5) { + final DownloadUpdateTask downloadTask = new DownloadUpdateTask((URLAndMD5) value); + splashScreen.uiProgressLabel.textProperty().unbind(); + splashScreen.uiProgressLabel.textProperty().bind(downloadTask.messageProperty()); + splashScreen.uiProgressBar.progressProperty().unbind(); + splashScreen.uiProgressBar.progressProperty().bind(downloadTask.progressProperty()); + + TaskManager.INSTANCE.submit(downloadTask); + + downloadTask.setOnCancelled(evt2 -> System.exit(0)); + + downloadTask.setOnFailed(evt2 -> Platform.runLater(() -> { + GeotkFX.newExceptionDialog("Le téléchargement de la mise à jour a échoué !", downloadTask.getException()).showAndWait(); + System.exit(1); + })); + + downloadTask.setOnSucceeded((evt2) -> { + Path newValue = downloadTask.getValue(); + try { + Rhomeo.openFile(newValue); + Thread.sleep(1000); + } catch (Exception e) { + RhomeoCore.LOGGER.log(Level.WARNING, "Cannot proceed to update !", e); + } finally { + Platform.runLater(() -> splashStage.close()); + } + }); + } else { + // Launches the main window here + splashStage.toFront(); + splashScreen.uiLoadingPane.setVisible(false); + + final FadeTransition fadeSplash = new FadeTransition(Duration.seconds(1.2), root); + fadeSplash.setFromValue(1.0); + fadeSplash.setToValue(0.0); + fadeSplash.setOnFinished(actionEvent -> { + splashStage.hide(); + root.setOpacity(1.0); + try { + final Stage mainStage = createDashboardStage(); + final Preferences welcomePrefs = Preferences.userNodeForPackage(FXInitialDialogPane.class); + + final Stage popup; + if (welcomePrefs.getBoolean(FXInitialDialogPane.DISPLAY_RULE_KEY, true)) { + popup = Rhomeo.createWelcomePopup(); + popup.initOwner(mainStage); + popup.show(); + popup.requestFocus(); + } else { + popup = null; + } + + // HACK : display of both stages is done now, because if + // main stage is displayed before we've ended configuring + // popup, some properties (like resizing capabilities) + // looks shared. + mainStage.show(); + if (popup != null) { + popup.show(); + popup.requestFocus(); + } + + } catch (Throwable ex) { + try { + RhomeoCore.LOGGER.log(Level.WARNING, "Erreur inattendue lors de l'initialisation du panneau principal.", ex); + final ExceptionDialog exDialog = GeotkFX.newExceptionDialog("L'application a rencontré une erreur inattendue et doit fermer.", ex); + exDialog.setOnHidden((DialogEvent de) -> System.exit(1)); + exDialog.show(); + } catch (Throwable e) { + RhomeoCore.LOGGER.log(Level.WARNING, "Cannot show error dialog to user", e); + System.exit(1); + } + } + }); + fadeSplash.play(); + } + })); + + task.setOnCancelled(evt -> { + System.exit(0); + }); + + // Task cancelled, because of an error or a user cancellation action. + task.setOnFailed(evt -> { + splashScreen.uiProgressLabel.getStyleClass().remove("label"); + splashScreen.uiProgressLabel.getStyleClass().add("label-error"); + splashScreen.uiCancel.setVisible(true); + }); + } + + /** + * Show the updates confirmation window. User is asked if the update should be downloaded. + * + * @param newVersion The update version. + * @return {@code true} if the user wants to apply the update, {@code false} otherwise. + * @throws ExecutionException + * @throws InterruptedException + */ + private boolean showUpdatesStage(final UpdateInfo newVersion) throws ExecutionException, InterruptedException { + // Now that we found that an update is available, we can ask the user if the update should be downloaded. + final Task askForUpdate = new Task() { + + @Override + protected Boolean call() throws Exception { + final StringBuilder builder = new StringBuilder() + .append("Version installée : ").append(Rhomeo.getVersion()) + .append(System.lineSeparator()) + .append("Version de la mise à jour : ").append(newVersion.getVersion()) + .append(System.lineSeparator()) + .append("Date de publication : ").append(newVersion.getDate() == null ? "Inconnue" : newVersion.getDate()) + .append(System.lineSeparator()); + + final String[] releaseNote = newVersion.getReleaseNote(); + if (releaseNote != null && releaseNote.length > 0) { + builder.append("Release-note : "); + for (final String str : releaseNote) { + builder.append(System.lineSeparator()).append(str); + } + } + + final Alert alert = new Alert(Alert.AlertType.CONFIRMATION, + builder.toString(), ButtonType.NO, ButtonType.YES); + alert.setHeaderText("Une mise à jour est disponible. Télécharger la mise à jour ?"); + final TextArea infoArea = new TextArea(builder.toString()); + infoArea.setEditable(false); + infoArea.setPrefSize(666, 444); + alert.setResizable(true); + alert.getDialogPane().setContent(infoArea); + final Optional choice = alert.showAndWait(); + + return ButtonType.YES.equals(choice.orElse(ButtonType.NO)); + } + }; + Platform.runLater(() -> askForUpdate.run()); + return Boolean.TRUE.equals(askForUpdate.get()); + } + + + /** + * Main dashboard stage. Will be opened when the application will be launched. + * + * @return The main stage, never {@code null} + */ + private Stage createDashboardStage() { + final Stage mainStage = Rhomeo.newStage(); + mainStage.setOnCloseRequest(event -> System.exit(0)); + final FXMainPane mainPane = Session.getInstance().getBean(FXMainPane.class); + final Scene scene = new Scene(mainPane); + scene.getStylesheets().add(Rhomeo.CSS_THEME_PATH); + mainStage.setScene(scene); + mainStage.initModality(Modality.NONE); + mainStage.setMinWidth(800); + mainStage.setMinHeight(600); + mainStage.setResizable(true); + mainStage.setMaximized(true); + return mainStage; + } + + /** + * + * @return + */ + private URLAndMD5 checkUpdate() throws Exception { + final UpdateInfo newVersion = RhomeoCore.existingUpdate(); + if (newVersion != null) { + final URL updateURL; + final String md5; + if (PlatformUtil.isWindows()) { + updateURL = newVersion.getWin32(); + md5 = newVersion.getWin32MD5(); + } else if (PlatformUtil.isMac()) { + updateURL = newVersion.getMacOS64(); + md5 = newVersion.getMacOS64MD5(); + } else if (PlatformUtil.isLinux()) { + if (newVersion.getDeb64() != null && isDeb()) { + updateURL = newVersion.getDeb64(); + md5 = newVersion.getDeb64MD5(); + } else { + updateURL = newVersion.getRpm64(); + md5 = newVersion.getRpm64MD5(); + } + } else { + updateURL = null; + md5 = null; + } + + if (updateURL != null && showUpdatesStage(newVersion)) { + return new URLAndMD5(updateURL, md5); + } + } + + return null; + } + + private boolean isDeb() { + try { + return Runtime.getRuntime().exec("dpkg --version").waitFor() == 0; + } catch (InterruptedException|IOException ex) { + RhomeoCore.LOGGER.log(Level.WARNING, "Cannot detect if the system is a dpkg or RPM based OS.", ex); + } + + return false; + } + + /** + * Initial loading task, to follow with a progress bar. + * If an update has been detected, returns the download url. + */ + private final class InitialLoadingTask extends Task { + /** + * Launched when this task will be called. + * + * @return Always return {@code null}. + * @throws Exception + */ + @Override + protected Object call() throws Exception { + final int total = 4; + int inc = 0; + + try { + // CHECK UPDATES /////////////////////////////////////////////// + updateProgress(inc++, total); + updateMessage("Vérification des mises à jour..."); + final URLAndMD5 upURL = checkUpdate(); + if (upURL != null) { + return upURL; + } + + // EPSG DATABASE /////////////////////////////////////////////// + updateProgress(inc++, total); + updateMessage("Création de la base de données de projections cartographiques (EPSG) ..."); + // try to create it, won't do anything if already exist + RhomeoCore.initEpsgDB(); + + // SPRING CONTEXT ////////////////////////////////////////////// + updateProgress(inc++, total); + updateMessage("Chargement du contexte de l'application ..."); + new ClassPathXmlApplicationContext(RhomeoCore.SPRING_CONTEXT_XML); + + // RESTORE APPLICATION STATE /////////////////////////////////// + updateProgress(inc++, total); + updateMessage("Récupération des données..."); + Session.getInstance().getBean(StateManager.class).restoreState(); + + // END + updateProgress(total, total); + updateMessage("Chargement terminé"); + Thread.sleep(400); + } catch (Throwable ex) { + updateProgress(-1, -1); + updateMessage("Erreur inattendue : ".concat(ex.getLocalizedMessage())); + RhomeoCore.LOGGER.log(Level.WARNING, ex.getMessage(), ex); + + throw ex; + } + + return null; + } + } + + /** + * Application update downloader. + * When completed, returns the {@linkplain Path downloaded file}. + */ + private final class DownloadUpdateTask extends Task { + private final URLAndMD5 url; + + public DownloadUpdateTask(final URLAndMD5 url) { + this.url = url; + } + + /** + * Download the new update. + * + * @return The {@linkplain Path downloaded update} + * @throws Exception + */ + @Override + protected Path call() throws Exception { + updateMessage("Téléchargement de la mise à jour en cours ..."); + + String completeURL = url.url.toExternalForm(); + final Matcher matcher = RhomeoCore.EXT_PATTERN.matcher(completeURL); + + final Path tmpFile = Files.createTempFile("tmpInstall", matcher.find()? matcher.group() : ".tmp"); + + // Now download the update in the appropriate file + final URLConnection bundleConnec = new NetPreferences().openConnection(url.url); + bundleConnec.setConnectTimeout(RhomeoCore.CONNECTION_TIMEOUT); + bundleConnec.setReadTimeout(RhomeoCore.READ_TIMEOUT); + final long totalLength = bundleConnec.getContentLengthLong(); + long downloaded = 0; + final String totalReadableSize = RhomeoCore.toReadableSize(totalLength); + final MessageDigest digest = MessageDigest.getInstance("md5"); + try (final InputStream input = bundleConnec.getInputStream(); + final OutputStream output = Files.newOutputStream(tmpFile)) { + int readBytes; + final byte[] buffer = new byte[4096]; + while ((readBytes = input.read(buffer)) >= 0) { + output.write(buffer, 0, readBytes); + digest.update(buffer, 0, readBytes); + downloaded += readBytes; + updateProgress(downloaded, totalLength); + updateMessage("Téléchargement "+ RhomeoCore.toReadableSize(downloaded) + " / " + totalReadableSize); + } + output.flush(); + } + + // Verify that the content was fully downloaded + if (downloaded != totalLength) { + throw new IOException("La mise à jour n'a pas été entièrement téléchargée"); + } + + // MD5 checksum + if (url.md5Base64 != null && !url.md5Base64.isEmpty()) { + byte[] computed = digest.digest(); + if (!url.md5Base64.equals(new BigInteger(1, computed).toString(16))) { + throw new IOException("Downloaded file checksum is invalid !"); + } + } + + updateMessage("Mise à jour téléchargée. Veuillez cliquer sur le bouton et l'installer."); + return tmpFile; + } + } + + private static class URLAndMD5 { + final URL url; + final String md5Base64; + + public URLAndMD5(final URL packageURL, final String base64MD5) { + this.url = packageURL; + this.md5Base64 = base64MD5; + } + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/Rhomeo.java b/desktop/src/main/java/fr/cenra/rhomeo/Rhomeo.java new file mode 100644 index 0000000..d458e74 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/Rhomeo.java @@ -0,0 +1,758 @@ +/** + * 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; + +import com.sun.javafx.PlatformUtil; +import fr.cenra.rhomeo.api.InternationalResource; +import fr.cenra.rhomeo.api.data.Protocol; +import fr.cenra.rhomeo.api.data.Statement; +import fr.cenra.rhomeo.core.CSVEncoder; +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.RhomeoRuntimeException; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.util.ExportUtils; +import fr.cenra.rhomeo.fx.FXInitialDialogPane; +import java.awt.Color; +import java.awt.Desktop; +import java.awt.Font; +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URI; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.ArrayList; +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.Optional; +import java.util.ResourceBundle; +import java.util.UUID; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.logging.Level; +import java.util.prefs.Preferences; +import java.util.zip.ZipOutputStream; + +import javafx.application.Platform; +import javafx.beans.property.ReadOnlyProperty; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.collections.ObservableList; +import javafx.concurrent.Task; +import javafx.embed.swing.SwingFXUtils; +import javafx.fxml.FXMLLoader; +import javafx.scene.Node; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.control.Alert; +import javafx.scene.control.Button; +import javafx.scene.control.ButtonType; +import javafx.scene.control.ComboBox; +import javafx.scene.control.Spinner; +import javafx.scene.control.SpinnerValueFactory; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TablePosition; +import javafx.scene.control.TableView; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.stage.FileChooser; +import javafx.stage.Modality; +import javafx.stage.Stage; +import javafx.util.StringConverter; +import org.apache.sis.util.ArgumentChecks; +import org.geotoolkit.font.FontAwesomeIcons; +import org.geotoolkit.font.IconBuilder; +import org.geotoolkit.gui.javafx.util.ComboBoxCompletion; +import org.geotoolkit.gui.javafx.util.TaskManager; +import org.geotoolkit.nio.ZipUtilities; + +/** + * Regroups methods used by the application for handling JavaFX features. + * + * @author Cédric Briançon (Geomatys) + * @see RhomeoCore + */ +public final class Rhomeo extends RhomeoCore { + /** + * Application icon. + */ + public static final Image ICON = new Image(Rhomeo.class.getResource("/fr/cenra/rhomeo/images/logo.png").toString(), 16, 16, true, false); + + public static final Image ICON_NOT_PUBLISHED = new Image(Rhomeo.class.getResource("/fr/cenra/rhomeo/images/not_published.png").toString(), + 16, 16, true, true); + + public static final Color GRAY_SITE = Color.decode("#898989"); + public static final Color GREEN_SITE = Color.decode("#9CB35B"); + public static final Color BLUE_SITE = Color.decode("#5B8AA4"); + public static final Color RED_SITE = Color.decode("#D85F70"); + public static final Color ORANGE_SITE = Color.decode("#FFA500"); + + public static final Font PROGRESS_MONITOR_ICON_FONT = IconBuilder.FONT.deriveFont(16f); + + public static final Image ICON_BARS_WHITE = SwingFXUtils.toFXImage(IconBuilder.createImage(FontAwesomeIcons.ICON_BARS,24, Color.WHITE),null); + public static final Image ICON_CARET_UP = SwingFXUtils.toFXImage(IconBuilder.createImage(FontAwesomeIcons.ICON_CARET_UP,16, GRAY_SITE),null); + public static final Image ICON_CARET_DOWN = SwingFXUtils.toFXImage(IconBuilder.createImage(FontAwesomeIcons.ICON_CARET_DOWN,16, GRAY_SITE),null); + public static final Image ICON_CHECK_GRAY = SwingFXUtils.toFXImage(IconBuilder.createImage(FontAwesomeIcons.ICON_CHECK,16, GRAY_SITE),null); + public static final Image ICON_CHECK_GREEN = SwingFXUtils.toFXImage(IconBuilder.createImage(FontAwesomeIcons.ICON_CHECK,16, GREEN_SITE),null); + public static final Image ICON_CIRCLE_GRAY = SwingFXUtils.toFXImage(IconBuilder.createImage(FontAwesomeIcons.ICON_CIRCLE,8, GRAY_SITE),null); + public static final Image ICON_COG = SwingFXUtils.toFXImage(IconBuilder.createImage(FontAwesomeIcons.ICON_COG,24, GRAY_SITE),null); + public static final Image ICON_DOWNLOAD_BLUE = SwingFXUtils.toFXImage(IconBuilder.createImage(FontAwesomeIcons.ICON_DOWNLOAD,24, BLUE_SITE),null); + public static final Image ICON_EXCHANGE_GRAY = SwingFXUtils.toFXImage(IconBuilder.createImage(FontAwesomeIcons.ICON_EXCHANGE,16, GRAY_SITE),null); + public static final Image ICON_EYE_GRAY = SwingFXUtils.toFXImage(IconBuilder.createImage(FontAwesomeIcons.ICON_EYE,16, GRAY_SITE),null); + public static final Image ICON_FILE_PDF = SwingFXUtils.toFXImage(IconBuilder.createImage(FontAwesomeIcons.ICON_FILE_PDF_O,24, RED_SITE),null); + public static final Image ICON_FILE_TEXT = SwingFXUtils.toFXImage(IconBuilder.createImage(FontAwesomeIcons.ICON_FILE_TEXT_O,24, BLUE_SITE),null); + public static final Image ICON_INFO_BLUE = SwingFXUtils.toFXImage(IconBuilder.createImage(FontAwesomeIcons.ICON_INFO_CIRCLE,24, BLUE_SITE),null); + public static final Image ICON_INFO_GREY = SwingFXUtils.toFXImage(IconBuilder.createImage(FontAwesomeIcons.ICON_INFO_CIRCLE,24, GRAY_SITE),null); + public static final Image ICON_LONG_ARROW_RIGHT = SwingFXUtils.toFXImage(IconBuilder.createImage(FontAwesomeIcons.ICON_LONG_ARROW_RIGHT,48, GRAY_SITE),null); + public static final Image ICON_PENCIL_BLUE = SwingFXUtils.toFXImage(IconBuilder.createImage(FontAwesomeIcons.ICON_PENCIL,24, BLUE_SITE),null); + public static final Image ICON_PENCIL_WHITE = SwingFXUtils.toFXImage(IconBuilder.createImage(FontAwesomeIcons.ICON_PENCIL,24, Color.WHITE),null); + public static final Image ICON_STOP_RED = SwingFXUtils.toFXImage(IconBuilder.createImage(FontAwesomeIcons.ICON_STOP,16, RED_SITE),null); + public static final Image ICON_TIMES_RED = SwingFXUtils.toFXImage(IconBuilder.createImage(FontAwesomeIcons.ICON_TIMES,16, RED_SITE),null); + public static final Image ICON_TRASH_BLUE = SwingFXUtils.toFXImage(IconBuilder.createImage(FontAwesomeIcons.ICON_TRASH_O,24, BLUE_SITE),null); + public static final Image ICON_WARNING_ORANGE = SwingFXUtils.toFXImage(IconBuilder.createImage(FontAwesomeIcons.ICON_WARNING_ALIAS,24, ORANGE_SITE),null); + + public static final String CSS_FONT_AWESOME = "rhomeo-font-awesome"; + public static final String CSS_ERROR_FIELD = "error-field"; + public static final String CSS_WARNING_FIELD = "warning-field"; + public static final String CSS_INDICATOR_LABEL = "indicator-label"; + public static final String CSS_CURRENT_STEP = "current-step"; + public static final String CSS_PROTOCOL_BUTTON = "protocol-button"; + public static final String CSS_PROTOCOL_POPUP_BODY = "protocol-popup-body"; + + /** + * Main theme path + */ + public static final String CSS_THEME_PATH = "/fr/cenra/rhomeo/theme.css"; + + private static final ChangeListener SPINNER_LISTENER = Rhomeo::spinnerTextChanged; + /** + * Generates a stage with {@linkplain RhomeoCore#APPLICATION_TITLE application title} and + * {@linkplain #ICON application icon}. + * + * @return a new Rhomeo stage, never {@code null} + */ + public static Stage newStage() { + final Stage rhomeoStage = new Stage(); + rhomeoStage.getIcons().add(ICON); + final String version = RhomeoCore.getVersion(); + final String title = (version == null || version.isEmpty()) ? APPLICATION_TITLE : APPLICATION_TITLE +" ("+ version +")"; + rhomeoStage.setTitle(title); + return rhomeoStage; + } + + /** + * Generates the initial dialog. Will be shown when launching the application. + * + * @return The dialog stage, never {@code null} + */ + public static Stage createWelcomePopup() { + final Stage stage = Rhomeo.newStage(); + stage.initModality(Modality.APPLICATION_MODAL); + stage.setResizable(true); + stage.setTitle("Accueil"); + final FXInitialDialogPane dialog = new FXInitialDialogPane(); + final Scene scene = new Scene(dialog); + scene.getStylesheets().add(Rhomeo.CSS_THEME_PATH); + stage.setScene(scene); + stage.sizeToScene(); + return stage; + } + + public static void loadFXML(Parent candidate) { + final Class modelClass = null; + loadFXML(candidate, modelClass); + } + + /** + * Load FXML document matching input controller. If a model class is given, + * we'll try to load a bundle for text internationalization. + * @param candidate The controller object to get FXMl for. + * @param bundleClass A class which will be used for bundle loading. + */ + public static void loadFXML(final Parent candidate, final Class bundleClass) { + ResourceBundle bundle = null; + if (bundleClass != null) { + try{ + bundle = ResourceBundle.getBundle(bundleClass.getName(), Locale.FRENCH, + Thread.currentThread().getContextClassLoader()); + }catch(MissingResourceException ex){ + LOGGER.log(Level.INFO, "Missing bundle for : {0}", bundleClass.getName()); + } + } + loadFXML(candidate, bundle); + } + + public static void loadFXML(final Parent candidate, final ResourceBundle bundle) { + loadFXML(candidate, candidate.getClass(), bundle); + } + + public static void loadFXML(final Parent candidate, final Class fxmlClass, final ResourceBundle bundle) { + ArgumentChecks.ensureNonNull("JavaFX controller object", candidate); + final String fxmlpath = "/"+fxmlClass.getName().replace('.', '/')+".fxml"; + final URL resource = fxmlClass.getResource(fxmlpath); + if (resource == null) { + throw new RuntimeException("No FXML document can be found for path : "+fxmlpath); + } + final FXMLLoader loader = new FXMLLoader(resource); + loader.setController(candidate); + loader.setRoot(candidate); + //in special environement like osgi or other, we must use the proper class loaders + //not necessarly the one which loaded the FXMLLoader class + loader.setClassLoader(fxmlClass.getClassLoader()); + + if(bundle!=null) loader.setResources(bundle); + + fxRunAndWait(() -> { + try { + loader.load(); + } catch (IOException ex) { + throw new IllegalArgumentException(ex.getMessage(), ex); + } + }); + } + + /** + * Run given task in FX application thread (immediately if we're already in it), + * and wait for its result before returning. + * + * @param Return TYPE of the input task. + * @param toRun Task to run in JavaFX thread. + * @return Result of the input task. + */ + public static T fxRunAndWait(final Callable toRun) { + return fxRunAndWait(new TaskManager.MockTask<>(toRun)); + } + + /** + * + * @param toRun The task to run. + */ + public static void fxRunAndWait(final Runnable toRun) { + fxRunAndWait(new TaskManager.MockTask(toRun)); + } + + /** + * Run given task in FX application thread (immediately if we're already in it), + * and wait for its result before returning. + * + * @param Return TYPE of the input task. + * @param toRun Task to run in JavaFX thread. + * @return Result of the input task. + */ + public static T fxRunAndWait(final Task toRun) { + return fxRun(true, toRun); + } + + /** + * Run given task in FX application thread (immediately if we're already in it). + * According to input boolean, we will return immediately or wait for the task to + * be over. + * @param wait True if we must wait for the task to end before returning, false + * to return immediately after submission. + * @param toRun The task to run into JavaFX application thread. + */ + public static void fxRun(final boolean wait, final Runnable toRun) { + fxRun(wait, new TaskManager.MockTask(toRun)); + } + + /** + * Run given task in FX application thread (immediately if we're already in it). + * According to input boolean, we will return immediately or wait for the task to + * be over. + * @param Return TYPE of input task. + * @param wait True if we must wait for the task to end before returning, false + * to return immediately after submission. + * @return The task return value if we must wait, or we're in platform thread. Otherwise null. + * @param toRun The task to run into JavaFX application thread. + */ + public static T fxRun(final boolean wait, final Callable toRun) { + return fxRun(wait, new TaskManager.MockTask<>(toRun)); + } + + /** + * Run given task in FX application thread (immediately if we're already in it). + * According to input boolean, we will return immediately or wait for the task to + * be over. + * @param Return TYPE of input task. + * @param wait True if we must wait for the task to end before returning, false + * to return immediately after submission. + * @return The task return value if we must wait, or we're in platform thread. Otherwise null. + * @param toRun The task to run into JavaFX application thread. + */ + public static T fxRun(final boolean wait, final Task toRun) { + if (Platform.isFxApplicationThread()) + toRun.run(); + else + Platform.runLater(toRun); + + if (wait || Platform.isFxApplicationThread()) { + try { + return toRun.get(); + } catch (RuntimeException ex) { + throw ex; + } catch (ExecutionException ex) { + if (ex.getCause() instanceof RuntimeException) { + throw (RuntimeException) ex.getCause(); + } else { + throw new RhomeoRuntimeException(ex.getCause()); + } + } catch (Exception e) { + throw new RhomeoRuntimeException(e); + } + } else + return null; + } + + /** + * Try to open given file on system. + * @param toOpen The file open on underlying system. + * @return True if we succeeded opening file on system, false otherwise. + */ + public static Task openFile(final Path toOpen) { + return openFile(toOpen.toAbsolutePath().toFile()); + } + + /** + * Try to open given file on system. + * @param toOpen The file open on underlying system. + * @return True if we succeeded opening file on system, false otherwise. + */ + public static Task openFile(final File toOpen) { + return TaskManager.INSTANCE.submit("Ouverture d'un fichier", () -> { + try { + final Desktop desktop = Desktop.getDesktop(); + if (desktop.isSupported(Desktop.Action.OPEN)) { + desktop.open(toOpen); + } else if (desktop.isSupported(Desktop.Action.EDIT)) { + desktop.edit(toOpen); + } else { + throw new IOException("Impossible de communiquer avec l'OS."); + } + } catch (IOException e) { + /* + * HACK : on Windows, it seems that some file associations cannot be found + * using above method (Ex : .odt), so we try running following command as + * a fallback. + */ + if (PlatformUtil.isWindows()) { + Runtime.getRuntime().exec(new String[]{"cmd /c start", toOpen.toURI().toString()}); + } else { + throw e; + } + } + return true; + }); + } + + public static Task browse(final URL href) { + return TaskManager.INSTANCE.submit("Ouverture d'un lien", () -> { + final Desktop desktop = Desktop.getDesktop(); + if (desktop.isSupported(Desktop.Action.BROWSE)) + desktop.browse(href.toURI()); + else + throw new IOException("Impossible de communiquer avec l'OS."); + + return true; + }); + } + + public static Task mail(final String mailAdress) { + return TaskManager.INSTANCE.submit("Ouverture d'un lien e-mail", () -> { + final Desktop desktop = Desktop.getDesktop(); + if (desktop.isSupported(Desktop.Action.MAIL)) + desktop.mail(new URI(mailAdress.startsWith("mailto")? mailAdress : "mailto:".concat(mailAdress))); + else + throw new IOException("Impossible de communiquer avec l'OS."); + + return true; + }); + } + + /** + * Initializes an auto completable combo box, without selecting one. + * + * @param + * @param comboBox + * @param items + * @see #initComboBox(ComboBox, ObservableList, Object) + */ + public static void initComboBox(final ComboBox comboBox, final ObservableList items) { + initComboBox(comboBox, items, null); + } + + /** + * Add items in the combo box and make it auto completable. + * + * @param comboBox A new combo box, not {@code null}. + * @param items List of items to add. + * @param itemSelected If not null, select this item in the list. + * @param item class + */ + public static void initComboBox(final ComboBox comboBox, final ObservableList items, final I itemSelected) { + comboBox.setItems(items); + try { + comboBox.setEditable(true); + } catch (RuntimeException re) { + // A runtime exception is launched if the editable property is already bound + // Just log and let the property bound and handled by something else. + Rhomeo.LOGGER.log(Level.FINE, re.getLocalizedMessage(), re); + } + if (itemSelected != null) { + comboBox.getSelectionModel().select(itemSelected); + } + ComboBoxCompletion.autocomplete(comboBox); + } + + + /** + * Generates an alert of the given type with the given text and just an OK button. + * + * @param type {@linkplain Alert.AlertType alert type}. + * @param text Text to display. + */ + public static void showAlert(final Alert.AlertType type, final String text) { + final Alert alert = new Alert(type, text, ButtonType.OK); + alert.setResizable(true); + alert.show(); + } + + /** + * Get the previous path stored for reopening a file chooser in it. + * + * @param packageClass Class in a specific java package on which we want to attach + * the path preference + * @return the previous path stored with the last opening of the file chooser. + */ + public static File getPreviousPath(final Class packageClass) { + final Preferences prefs = Preferences.userNodeForPackage(packageClass); + final String str = prefs.get("path", null); + if (str != null) { + final File file = new File(str); + if (file.isDirectory()) { + return file; + } + } + return null; + } + + /** + * Set the path of the previously selected file into the file chooser. + * + * @param packageClass Class in a specific java package on which we want to attach + * the path preference + * @param path the path to store. Should point on a folder. + */ + public static void setPreviousPath(final Class packageClass, final File path) { + final Preferences prefs = Preferences.userNodeForPackage(packageClass); + prefs.put("path", path.getAbsolutePath()); + } + + /** + * Open modal popup asking for a file on the local path. + * + * @param initialFileName Initial file name to use. + * @param owner The owner of this popup. + * @param filters Filters to use. Possibly empty or null. The first item will be used as the default one. + * @return The file wished, or {@code null} if the user cancelled the popup. + */ + public static File askOutputFilePopup(final String initialFileName, final Node owner, final FileChooser.ExtensionFilter... filters) { + final FileChooser fileChooser = new FileChooser(); + + final File previousPath = getPreviousPath(ExportUtils.class); + if(previousPath!=null && previousPath.exists()){ + fileChooser.setInitialDirectory(previousPath); + } + + // Set some usefull filters + if (filters != null && filters.length > 0) { + fileChooser.getExtensionFilters().addAll(filters); + fileChooser.setSelectedExtensionFilter(filters[0]); + } + + if (initialFileName != null && !initialFileName.isEmpty()) { + fileChooser.setInitialFileName(initialFileName); + } + + final File outputFile = fileChooser.showSaveDialog(owner.getScene().getWindow()); + + if(outputFile==null) return null; + setPreviousPath(ExportUtils.class, outputFile.getParentFile()); + + return outputFile; + } + + /** + * Try to find a combobox under given node scene tree. + * @param source The node to search into. + * @return The first found combobox, or nothing. + */ + public static Optional findComboBox(final Node source) { + if (source instanceof ComboBox) { + return Optional.of((ComboBox)source); + } else if (source instanceof Parent) { + final ObservableList nodes = ((Parent)source).getChildrenUnmodifiable(); + Optional opt; + for (final Node n : nodes) { + opt = findComboBox(n); + if (opt.isPresent()) + return opt; + } + } + + return Optional.empty(); + } + + public static void prepareSpinners(final Node source) { + if (source instanceof Spinner) { + final Spinner spinner = (Spinner) source; + spinner.getEditor().textProperty().removeListener(SPINNER_LISTENER); + spinner.getEditor().textProperty().addListener(SPINNER_LISTENER); + final SpinnerValueFactory valueFactory = spinner.getValueFactory(); + if (valueFactory instanceof SpinnerValueFactory.DoubleSpinnerValueFactory) { + final SpinnerValueFactory.DoubleSpinnerValueFactory dvf = (SpinnerValueFactory.DoubleSpinnerValueFactory) valueFactory; + dvf.setAmountToStepBy(0.01); + dvf.setConverter(new SpinnerConverter(spinner)); + // HACK : To force display refresh immediately, we introduce temporary value change. + final Double oldValue = dvf.getValue(); + if (oldValue == null || oldValue.isNaN() || oldValue.isInfinite()) + dvf.setValue(0.0); + else dvf.setValue(oldValue + 1); + dvf.setValue(oldValue); + } + + } else if (source instanceof Parent) { + final ObservableList nodes = ((Parent)source).getChildrenUnmodifiable(); + for (final Node n : nodes) { + prepareSpinners(n); + } + } + } + + private static void spinnerTextChanged(final ObservableValue obs, final String oldValue, final String newValue) { + if (obs instanceof ReadOnlyProperty) { + final Object bean = ((ReadOnlyProperty)obs).getBean(); + if (bean instanceof Node) { + Parent parent = ((Node) bean).getParent(); + if (parent instanceof Spinner) { + final Spinner spinner = (Spinner) parent; + try { + spinner.getValueFactory().setValue(spinner.getValueFactory().getConverter().fromString(newValue)); + } catch (Exception e) { + Rhomeo.LOGGER.log(Level.FINE, "Cannot convert seized text to numeric value", e); + } + } + } + } + } + + /** + * Check column and row indices to determine if we must edit next column or + * next row. If next cell is not editable, we test the next one, etc. + * + * @param editingCell Cell currently edited. If null, this method does nothing. + */ + public static void editNextCell(final TablePosition editingCell) { + if (editingCell == null) + return; + final TableView tableView = editingCell.getTableView(); + TableColumn targetCol; + int rowIndex = editingCell.getRow(); + int colIndex = editingCell.getColumn(); + final int maxRow = tableView.getItems().size() - 1; + final int maxCol = tableView.getColumns().size() - 1; + do { + if (colIndex >= maxCol) { + rowIndex++; + colIndex = 0; + } else { + colIndex++; + } + + if (rowIndex < 0 || rowIndex > maxRow) { + targetCol = null; + } else { + targetCol = tableView.getColumns().get(colIndex); + } + + } while (targetCol != null && !targetCol.isEditable()); + + tableView.edit(rowIndex, targetCol); + } + + public static Button createProtocolDocumentButton(final Protocol protocol) { + final Button button = new Button("Fiche protocole "+ protocol.getName()); + button.setGraphic(new ImageView(ICON_FILE_PDF)); + button.getStyleClass().add("transparent"); + button.setOnAction(event -> { + final String fileName = protocol.getName() + ".pdf"; + Session.getInstance().getBean(DocManager.class).openDocument(protocol.getClass().getResource(fileName)); + }); + return button; + } + + public static Button createModelButton(final Protocol protocol) { + final Button button = new Button("Format protocole "+ protocol.getRemarks() +" ("+ protocol.getName() +")"); + button.setGraphic(new ImageView(ICON_FILE_TEXT)); + button.getStyleClass().add("transparent"); + button.setOnAction(event -> generateModelZip(protocol, button)); + return button; + } + + public static void generateModelZip(final Protocol protocol, final Node owner) { + final FileChooser.ExtensionFilter zipFilter = new FileChooser.ExtensionFilter("Archive zip", "*.zip"); + final File outputFile = Rhomeo.askOutputFilePopup(protocol.getName() +".zip", owner, zipFilter); + if (outputFile == null) { + return; + } + + final Path parentPath = Paths.get(outputFile.getParentFile().getAbsolutePath()); + final UUID uuid = UUID.randomUUID(); + final Path folderPath = parentPath.resolve(uuid.toString()); + + final Class statementClass = protocol.getDataType(); + try { + Files.createDirectory(folderPath); + + final Path formatPath = folderPath.resolve("format.csv"); + final CSVEncoder encoder = new CSVEncoder<>(formatPath, statementClass); + encoder.encode(new ArrayList<>(), true); + + final Path readmePath = createReadMeFile(statementClass, folderPath); + ZipUtilities.zip(outputFile.toPath(), ZipOutputStream.DEFLATED, 9, null, formatPath, readmePath); + + Files.deleteIfExists(formatPath); + Files.deleteIfExists(readmePath); + Files.deleteIfExists(folderPath); + } catch (IOException | IntrospectionException ex) { + Rhomeo.LOGGER.log(Level.INFO, "Cannot generate format file", ex); + } + } + + private static Path createReadMeFile(final Class statementClass, final Path outputFolderPath) throws IOException, IntrospectionException { + final boolean bundleAvailable = InternationalResource.class.isAssignableFrom(statementClass); + + final Path formatPath = outputFolderPath.resolve("readme.txt"); + Files.createFile(formatPath); + String description = null; + try (final BufferedWriter bw = Files.newBufferedWriter(formatPath, StandardOpenOption.APPEND)) { + final BeanInfo beanInfo = Introspector.getBeanInfo(statementClass, Object.class); + for (final PropertyDescriptor desc : beanInfo.getPropertyDescriptors()) { + if (bundleAvailable) { + try { + description = InternationalResource.getResourceString(statementClass, desc.getName(), "tooltip"); + } catch (MissingResourceException ex) { + description = null; + } + if (description == null || description.isEmpty()) { + try { + description = InternationalResource.getResourceString(statementClass, desc.getName(), "label"); + } catch (MissingResourceException ex) { + description = null; + } + } + bw.write(desc.getName()); + bw.write("="); + if (description == null || description.isEmpty()) { + Rhomeo.LOGGER.log(Level.WARNING, "No resources for key " + desc.getName() + ".label or " + desc.getName() + ".tooltip in bundle for class " + + statementClass.getCanonicalName()); + } else { + bw.write(description); + } + bw.newLine(); + } + } + + // Check if additional content is available for the format readme. + try (final InputStream in = statementClass.getResourceAsStream("readme.additional"); + final InputStreamReader tmpReader = new InputStreamReader(in, StandardCharsets.UTF_8); + final BufferedReader reader = new BufferedReader(tmpReader)) { + + String line; + while ((line = reader.readLine()) != null) { + bw.newLine(); + bw.write(line); + } + + } catch (NullPointerException e) { + LOGGER.log(Level.FINE, "No additional text defined for data description.", e); + } + } + return formatPath; + } + + /** + * A special string converter for Spinners. The aim is to avoid changes in + * spinner's editor when value is updated, but matches editor text. Because + * without any check, spinner will force editor text, which could bother + * user seizing. + */ + private static class SpinnerConverter extends StringConverter { + + private final Spinner target; + + public SpinnerConverter(Spinner target) { + this.target = target; + } + + @Override + public String toString(Double object) { + final String text = target.getEditor().getText(); + Object fromString = DOUBLE_CONVERTER.fromString(text); + if ((fromString instanceof Number) && (target.getValue() instanceof Number) && ((Number)fromString).doubleValue() == ((Number)target.getValue()).doubleValue()) + return text; + else return DOUBLE_CONVERTER.toString(object); + } + + @Override + public Double fromString(String string) { + return (Double) DOUBLE_CONVERTER.fromString(string); + } + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/FXDashboardMenuPane.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXDashboardMenuPane.java new file mode 100644 index 0000000..38dcf51 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXDashboardMenuPane.java @@ -0,0 +1,1282 @@ +/** + * 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.fx; + +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.GeometryFactory; +import com.vividsolutions.jts.geom.LinearRing; +import com.vividsolutions.jts.geom.MultiPolygon; +import com.vividsolutions.jts.geom.Polygon; +import fr.cenra.rhomeo.DocManager; +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.InternationalResource; +import fr.cenra.rhomeo.api.data.Protocol; +import fr.cenra.rhomeo.api.data.Site; +import fr.cenra.rhomeo.core.BeanUtils; +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.RhomeoRuntimeException; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.WorkflowStep; +import fr.cenra.rhomeo.core.data.county.County; +import fr.cenra.rhomeo.core.list.HumidZoneType; +import fr.cenra.rhomeo.core.list.OdonateZoneBio; +import fr.cenra.rhomeo.core.list.OrthoptereZoneBio; +import fr.cenra.rhomeo.core.util.ExportUtils; +import fr.cenra.rhomeo.core.data.site.SiteImpl; +import fr.cenra.rhomeo.core.data.site.DuplicatedKeyException; +import fr.cenra.rhomeo.core.data.site.SiteRepository; + +import java.beans.IntrospectionException; +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URI; +import java.util.Map; +import java.util.Set; +import java.util.StringJoiner; +import java.util.logging.Level; +import java.util.regex.Matcher; +import javafx.application.Platform; +import javafx.beans.binding.BooleanBinding; +import javafx.beans.property.BooleanProperty; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.value.ObservableValue; +import javafx.collections.FXCollections; +import javafx.concurrent.Task; +import javafx.event.EventHandler; +import javafx.fxml.FXML; +import javafx.geometry.Bounds; +import javafx.geometry.Point2D; +import javafx.scene.Scene; +import javafx.scene.control.Alert; +import javafx.scene.control.Button; +import javafx.scene.control.ButtonType; +import javafx.scene.control.ComboBox; +import javafx.scene.control.Label; +import javafx.scene.control.ProgressIndicator; +import javafx.scene.control.TextField; +import javafx.scene.control.ToggleButton; +import javafx.scene.control.Tooltip; +import javafx.scene.image.ImageView; +import javafx.scene.input.MouseEvent; +import javafx.scene.layout.Background; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.ColumnConstraints; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; +import javafx.stage.FileChooser; +import javafx.stage.Modality; +import javafx.stage.PopupWindow; +import javafx.stage.Stage; +import javafx.stage.StageStyle; +import javafx.util.StringConverter; +import javax.annotation.PostConstruct; +import javax.xml.stream.XMLStreamException; +import org.apache.sis.storage.DataStoreException; +import org.controlsfx.control.StatusBar; +import org.geotoolkit.data.FeatureCollection; +import org.geotoolkit.data.FeatureIterator; +import org.geotoolkit.data.FeatureStoreUtilities; +import org.geotoolkit.data.bean.BeanFeature; +import org.geotoolkit.data.kml.model.KmlException; +import org.geotoolkit.data.query.Query; +import org.geotoolkit.data.query.QueryBuilder; +import org.geotoolkit.data.shapefile.ShapefileFeatureStore; +import org.geotoolkit.display2d.GO2Utilities; +import org.geotoolkit.feature.Feature; +import org.geotoolkit.feature.Property; +import org.geotoolkit.gui.javafx.layer.FXFeatureTable; +import org.geotoolkit.gui.javafx.render2d.FXCoordinateBar; +import org.geotoolkit.gui.javafx.render2d.FXGeoToolBar; +import org.geotoolkit.gui.javafx.render2d.FXMap; +import org.geotoolkit.gui.javafx.render2d.FXNavigationBar; +import org.geotoolkit.gui.javafx.render2d.FXScaleBarDecoration; +import org.geotoolkit.gui.javafx.render2d.navigation.FXPanHandler; +import org.geotoolkit.gui.javafx.util.TaskManager; +import org.geotoolkit.map.FeatureMapLayer; +import org.geotoolkit.map.MapBuilder; +import org.geotoolkit.map.MapContext; +import org.geotoolkit.map.MapLayer; +import org.opengis.filter.Id; +import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.opengis.referencing.operation.TransformException; +import org.opengis.util.FactoryException; +import org.opengis.util.GenericName; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import static fr.cenra.rhomeo.core.RhomeoCore.CODE_PATTERN; +import fr.cenra.rhomeo.core.data.county.CountyRepository; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import javafx.beans.binding.Bindings; +import org.apache.sis.referencing.CommonCRS; +import org.geotoolkit.data.kml.model.AbstractGeometry; +import org.geotoolkit.data.kml.model.Kml; +import org.geotoolkit.data.kml.model.MultiGeometry; +import org.geotoolkit.data.kml.xml.KmlReader; +import org.geotoolkit.feature.FeatureBuilder; +import org.geotoolkit.feature.FeatureTypeBuilder; +import org.geotoolkit.feature.type.AttributeDescriptor; +import org.geotoolkit.feature.type.FeatureType; +import org.geotoolkit.feature.type.PropertyDescriptor; +import org.geotoolkit.geometry.jts.JTS; + +/** + * Dashboard panel menu handling protocol and site choice. + * Will be put in the top part of the {@link FXDashboardPane}. + * + * @author Cédric Briançon (Geomatys) + * @author Alexis Manin (Geomatys) + */ +@Component +@Scope("prototype") +public class FXDashboardMenuPane extends BorderPane implements InternationalResource { + + @FXML private ImageView uiConfigSiteImg; + @FXML private ImageView uiCaretSiteImg; + @FXML private Label uiSelectedSiteLbl; + + /** + * Protocols banner. + */ + @FXML private HBox protocolsBannerBox; + + /** + * Selected site banner. + */ + @FXML private ComboBox uiSitesList; + @FXML private ToggleButton uiInfoSiteToggleBtn; + @FXML private BorderPane uiProtocolSitePane; + @FXML private HBox uiToCollapseButtonsSiteHbox; + @FXML private ToggleButton uiNewSiteToggleBtn; + @FXML private BorderPane uiSiteInfoPane; + + @FXML private GridPane uiInfoSiteGrid; + + /** + * Fields for info site form. + */ + @FXML private TextField uiNameSiteTxt; + @FXML private TextField uiReferentSiteTxt; + @FXML private Button uiImportContourBtn; + @FXML private ComboBox uiDepartmentSiteComboBox; + @FXML private TextField uiStructureSiteTxt; + @FXML private ComboBox uiTypeZhSiteComboBox; + @FXML private ComboBox uiZbOdoSiteComboBox; + @FXML private ComboBox uiZbOrthoSiteComboBox; + + /** + * Buttons for selected site. + */ + @FXML private HBox uiInfoSelectedSiteBtnsBox; + @FXML private ToggleButton uiEditSelectedSiteToggleBtn; + @FXML private Button uiDownloadSelectedSiteBtn; + @FXML private Button uiDeleteSelectedSiteBtn; + + /** + * Action buttons on selected / new site. + */ + @FXML private Button uiCancelBtn; + @FXML private Button uiCreateSiteBtn; + + @Autowired + private Session session; + + @Autowired + private SiteRepository siteRepository; + + @Autowired(required = false) + private CountyRepository countyRepository; + + @Autowired + private DocManager docManager; + + /** + * Geometry of the selected / new site. + */ + private final ObjectProperty geomToAdd = new SimpleObjectProperty<>(); + + /** + * Selected site property. + */ + private final ObjectProperty selectedSiteProperty; + + /** + * List of loaded counties. Can be null if an error happens while loading counties. + */ + private Map counties; + + private final BooleanBinding odoTypeFilled; + private final BooleanBinding odoTypeNotEditable; + private final BooleanBinding odoTypeNotEditableAndNotNew; + private final BooleanBinding orthoTypeFilled; + private final BooleanBinding orthoTypeEditable; + private final BooleanBinding orthoTypeEditableOrNewSite; + private final BooleanBinding notEditing; + private final BooleanBinding notNewSite; + + public FXDashboardMenuPane() { + Rhomeo.loadFXML(this, FXDashboardMenuPane.class); + + uiConfigSiteImg.setImage(Rhomeo.ICON_COG); + uiCaretSiteImg.setImage(Rhomeo.ICON_CARET_UP); + + // Stores the site panel open or not property. + final BooleanProperty showSitesPaneProperty = new SimpleBooleanProperty(true); + + uiProtocolSitePane.visibleProperty().bind(showSitesPaneProperty); + uiProtocolSitePane.managedProperty().bind(uiProtocolSitePane.visibleProperty()); + + // Bind selected site + selectedSiteProperty = new SimpleObjectProperty<>(this, "selected site"); + uiSitesList.valueProperty().addListener(this::siteNameChanged); + selectedSiteProperty.addListener(this::siteChanged); + selectedSiteProperty.addListener(((observable, oldValue, newValue) -> { + if (oldValue != null) { + uiSelectedSiteLbl.textProperty().unbind(); + } + + if (newValue != null && newValue.getName() != null && !newValue.getName().isEmpty()) { + uiSelectedSiteLbl.textProperty().bind( + new SimpleStringProperty("SITE : ").concat(uiSitesList.getEditor().textProperty())); + } else { + uiSelectedSiteLbl.setText(null); + } + })); + + // Display selected site name only if one has been selected and the site panel is collapsed. + uiSelectedSiteLbl.visibleProperty().bind( + showSitesPaneProperty.not().and(selectedSiteProperty.isNotNull())); + uiSelectedSiteLbl.managedProperty().bind(uiSelectedSiteLbl.visibleProperty()); + + notNewSite = uiNewSiteToggleBtn.selectedProperty().not(); + + // Display info site button if an existing one has been selected + uiInfoSiteToggleBtn.visibleProperty().bind(selectedSiteProperty.isNotNull().and(notNewSite)); + + // Allow to collapse site information pane + uiToCollapseButtonsSiteHbox.setOnMouseClicked(event -> { + final boolean showPane = showSitesPaneProperty.get(); + if (showPane) { + uiCaretSiteImg.setImage(Rhomeo.ICON_CARET_DOWN); + } else { + uiCaretSiteImg.setImage(Rhomeo.ICON_CARET_UP); + } + showSitesPaneProperty.setValue(!showPane); + }); + + // Sub panel that should open only if its main panel (uiProtocolSitePane) is already opened + // and either user request to create a new site or to view info on an existing one. + uiSiteInfoPane.visibleProperty().bind(uiNewSiteToggleBtn.selectedProperty().or(uiInfoSiteToggleBtn.selectedProperty().and(uiInfoSiteToggleBtn.visibleProperty()))); + uiSiteInfoPane.managedProperty().bind(uiSiteInfoPane.visibleProperty()); + + // Display action buttons only in the new site mode or editing an existing site mode + uiCreateSiteBtn.visibleProperty().bind(uiNewSiteToggleBtn.selectedProperty().or(uiEditSelectedSiteToggleBtn.selectedProperty())); + uiCreateSiteBtn.managedProperty().bind(uiCreateSiteBtn.visibleProperty()); + uiCancelBtn.visibleProperty().bind(uiCreateSiteBtn.visibleProperty()); + uiCancelBtn.managedProperty().bind(uiCancelBtn.visibleProperty()); + + /* + * When new site button state change, we initiate or cancel complete form. + */ + uiNewSiteToggleBtn.selectedProperty().addListener((obs, old, newVal) -> { + final Site selected = selectedSiteProperty.get(); + final boolean isNewSite = selected != null && (selected.getName() == null || selected.getName().trim().isEmpty()); + if (newVal) { + /* Before setting a new site, we ensure user won't lose data on + * a previously edited object. + */ + if (!isNewSite) { + if (confirmCancelling(selected)) { + final Site newSite = new SiteImpl(null); + selectedSiteProperty.set(newSite); + } else { + uiNewSiteToggleBtn.setSelected(false); // a rollback has been decided + } + } + } else { + // If the button has been de-activated, and we're editing a new + // site, we clear selection. However, if user ask for a rollback, + // we re-activate the button. + if (isNewSite) { + if (confirmCancelling(selected)) { + selectedSiteProperty.set(null); + } else { + uiNewSiteToggleBtn.setSelected(true); // a rollback has been decided + } + } + } + uiCreateSiteBtn.setText(newVal ? getResourceString("create-site") : getResourceString("save")); + uiImportContourBtn.setText(newVal ? getResourceString("import-contour") : getResourceString("view-contour")); + }); + + // Add PDF file images in the site form + final Button typeZhBtn = createPdfButton("Typologie_Habitats.pdf"); + uiInfoSiteGrid.add(typeZhBtn, 6, 1); + final Button typeZbOdonateBtn = createPdfButton("zones_biogeo_odonates.pdf"); + uiInfoSiteGrid.add(typeZbOdonateBtn, 6, 2); + final Button typeZbOrthoBtn = createPdfButton("zones_biogeo_orthopteres.pdf"); + uiInfoSiteGrid.add(typeZbOrthoBtn, 6, 3); + + // Button info for selected site + uiInfoSiteToggleBtn.selectedProperty().addListener((observable, oldValue, newValue) -> { + if (newValue) { + uiCreateSiteBtn.setText(getResourceString("save")); + uiImportContourBtn.setText(getResourceString("view-contour")); + uiImportContourBtn.setGraphic(new ImageView(Rhomeo.ICON_EYE_GRAY)); + uiEditSelectedSiteToggleBtn.setSelected(false); + uiInfoSiteToggleBtn.setGraphic(new ImageView(Rhomeo.ICON_INFO_BLUE)); + } else { + uiInfoSiteToggleBtn.setGraphic(new ImageView(Rhomeo.ICON_INFO_GREY)); + } + }); + uiInfoSiteToggleBtn.setGraphic(new ImageView(Rhomeo.ICON_INFO_GREY)); + uiInfoSiteToggleBtn.setTooltip(new Tooltip(getResourceString("view-info-site-tooltip"))); + + // Panel containing buttons for selected site. + uiInfoSelectedSiteBtnsBox.visibleProperty().bind(uiInfoSiteToggleBtn.selectedProperty().and(notNewSite)); + uiInfoSelectedSiteBtnsBox.managedProperty().bind(uiInfoSelectedSiteBtnsBox.visibleProperty()); + // Buttons images for selected site actions. + uiDownloadSelectedSiteBtn.setGraphic(new ImageView(Rhomeo.ICON_DOWNLOAD_BLUE)); + uiDownloadSelectedSiteBtn.setTooltip(new Tooltip(getResourceString("download-selected-site-tooltip"))); + uiDeleteSelectedSiteBtn.setGraphic(new ImageView(Rhomeo.ICON_TRASH_BLUE)); + uiDeleteSelectedSiteBtn.setTooltip(new Tooltip(getResourceString("delete-selected-site-tooltip"))); + uiEditSelectedSiteToggleBtn.setGraphic(new ImageView(Rhomeo.ICON_PENCIL_BLUE)); + uiEditSelectedSiteToggleBtn.setTooltip(new Tooltip(getResourceString("edit-selected-site-tooltip"))); + uiEditSelectedSiteToggleBtn.selectedProperty().addListener((observable, oldValue, newValue) -> { + if (newValue) { + uiEditSelectedSiteToggleBtn.setGraphic(new ImageView(Rhomeo.ICON_PENCIL_WHITE)); + } else { + uiEditSelectedSiteToggleBtn.setGraphic(new ImageView(Rhomeo.ICON_PENCIL_BLUE)); + } + }); + + geomToAdd.addListener((observable, oldValue, newValue) -> { + if (uiNewSiteToggleBtn.isSelected()) { + uiImportContourBtn.setGraphic(newValue != null ? new ImageView(Rhomeo.ICON_CHECK_GRAY) : null); + } + }); + + // Bind editable form fields + notEditing = uiEditSelectedSiteToggleBtn.selectedProperty().not(); + uiNameSiteTxt.disableProperty().bind(notEditing.and(notNewSite)); + uiReferentSiteTxt.disableProperty().bind(notEditing.and(notNewSite)); + uiStructureSiteTxt.disableProperty().bind(notEditing.and(notNewSite)); + // These combo boxes are only editable in the case of a new site. + uiDepartmentSiteComboBox.disableProperty().bind(notNewSite); + uiTypeZhSiteComboBox.disableProperty().bind(notNewSite); + // The two fields below are editable until the target site values are empty (see Gitlab issue #37). + odoTypeFilled = Bindings.createBooleanBinding(() -> { + final Site ss = selectedSiteProperty.get(); + if (ss == null) + return false; + final Optional odoOpt = RhomeoCore.getByCode(OdonateZoneBio.class, ss.getOdonateType()); + return odoOpt.isPresent() && !OdonateZoneBio.ZGLOBAL.equals(odoOpt.get()); + }, selectedSiteProperty, uiZbOdoSiteComboBox.valueProperty()); + odoTypeNotEditable = notEditing.or(odoTypeFilled); + odoTypeNotEditableAndNotNew = notNewSite.and(odoTypeNotEditable); + uiZbOdoSiteComboBox.disableProperty().bind(odoTypeNotEditableAndNotNew); + orthoTypeFilled = Bindings.createBooleanBinding(() -> { + final Site ss = selectedSiteProperty.get(); + if (ss == null) + return false; + return RhomeoCore.getByCode(OrthoptereZoneBio.class, ss.getOrthoptereType()).isPresent(); + }, selectedSiteProperty, uiZbOrthoSiteComboBox.valueProperty()); + orthoTypeEditable = notEditing.or(orthoTypeFilled); + orthoTypeEditableOrNewSite = notNewSite.and(orthoTypeEditable); + uiZbOrthoSiteComboBox.disableProperty().bind(orthoTypeEditableOrNewSite); + + // Set converters to avoid bad behavior on seizure + uiTypeZhSiteComboBox.setConverter(new StringConverter() { + @Override + public String toString(HumidZoneType object) { + return object == null? null : object.toString(); + } + + @Override + public HumidZoneType fromString(String string) { + if (string == null || (string = string.trim()).isEmpty()) { + return null; + } + + final Matcher matcher = CODE_PATTERN.matcher(string); + if (matcher.find()) { + return HumidZoneType.getByCode(matcher.group()); + } + + return null; + } + }); + + uiZbOdoSiteComboBox.setConverter(new StringConverter() { + @Override + public String toString(OdonateZoneBio object) { + return object == null? null : object.toString(); + } + + @Override + public OdonateZoneBio fromString(String string) { + if (string == null || (string = string.trim()).isEmpty()) { + return null; + } + + final Matcher matcher = CODE_PATTERN.matcher(string); + if (matcher.find()) { + return OdonateZoneBio.getByCode(matcher.group()); + } + + return null; + } + }); + + uiZbOrthoSiteComboBox.setConverter(new StringConverter() { + @Override + public String toString(OrthoptereZoneBio object) { + return object == null? null : object.toString(); + } + + @Override + public OrthoptereZoneBio fromString(String string) { + if (string == null || (string = string.trim()).isEmpty()) { + return null; + } + + final Matcher matcher = CODE_PATTERN.matcher(string); + if (matcher.find()) { + return OrthoptereZoneBio.getByCode(matcher.group()); + } + + return null; + } + }); + + // Fill lists + Rhomeo.initComboBox(uiTypeZhSiteComboBox, FXCollections.observableArrayList(HumidZoneType.values())); + Rhomeo.initComboBox(uiZbOdoSiteComboBox, FXCollections.observableArrayList(OdonateZoneBio.values())); + Rhomeo.initComboBox(uiZbOrthoSiteComboBox, FXCollections.observableArrayList(OrthoptereZoneBio.values())); + } + + /** + * Initializes JavaFX components after spring components are done loading. + */ + @PostConstruct + private void postConstruct() { + Rhomeo.initComboBox(uiSitesList, siteRepository.findNames()); + final EventHandler filter = evt -> { + if (MouseEvent.MOUSE_PRESSED.equals(evt.getEventType()) || + MouseEvent.MOUSE_CLICKED.equals(evt.getEventType())) { + final Site site = siteProperty().get(); + if (site == null || site.equals(prepareSiteFromForm(null))) + return; + + if (confirmCancelling(site)) { + selectedSiteProperty.set(null); + uiSitesList.requestFocus(); + } else { + evt.consume(); + } + } + }; + uiSitesList.addEventFilter(MouseEvent.ANY, filter); + + // Load county choice + if (countyRepository == null) { + uiDepartmentSiteComboBox.disableProperty().unbind(); + uiDepartmentSiteComboBox.setDisable(true); + Rhomeo.showAlert(Alert.AlertType.WARNING, "Impossible de charger la liste des départements. Il sera impossible de créer de nouveaux sites."); + } else { + counties = countyRepository.getAll(); + final String countyCode = siteProperty().get() == null ? null : siteProperty().get().getCountyCode(); + Rhomeo.initComboBox(uiDepartmentSiteComboBox, FXCollections.observableArrayList(counties.values()).sorted(), countyCode == null? null : counties.get(countyCode)); + uiDepartmentSiteComboBox.setConverter(countyRepository.getStringConverter()); + } + + session.getProtocols().stream() + .sorted() + .forEach(protocol -> { + final Button protocolButton = new Button(protocol.getName()); + protocolButton.getStyleClass().add(Rhomeo.CSS_PROTOCOL_BUTTON); + + // Prepare tooltip destined to display bound indicators. + final StringJoiner chainBuilder = new StringJoiner(" / "); + session.getIndicators().stream() + .filter(indicator -> indicator.getProtocol() == protocol) + .sorted() + .forEach(indicator -> chainBuilder.add(indicator.getTitle().concat(" (").concat(indicator.getRemarks()).concat(")"))); + final Tooltip tt = new Tooltip(chainBuilder.toString()); + tt.getStyleClass().add(Rhomeo.CSS_PROTOCOL_POPUP_BODY); + tt.setAnchorLocation(PopupWindow.AnchorLocation.CONTENT_BOTTOM_LEFT); + // Force tooltip to show on the upper right corner of the + // associated protocol button. + tt.setOnShowing(evt -> { + final Bounds parentBounds = protocolButton.getBoundsInLocal(); + final Point2D screen = protocolButton.localToScreen(parentBounds.getMaxX(), parentBounds.getMinY()); + tt.setAnchorX(screen.getX() > 10? screen.getX() -10 : screen.getX()); + tt.setAnchorY(screen.getY() + 10); + }); + + + protocolButton.setTooltip(tt); + + // Configure protocol button behavior. + selectedSiteProperty.addListener((observable, oldValue, newValue) -> { + protocolButton.setDisable(newValue == null || !protocol.isCompatible(newValue)); + }); + protocolButton.setDisable(true); + protocolButton.setOnAction(event -> { + startEdition(selectedSiteProperty.get(), protocol); + }); + protocolsBannerBox.getChildren().add(protocolButton); + protocolsBannerBox.disableProperty().bind(uiNewSiteToggleBtn.selectedProperty()); + }); + } + + /** + * Expose the selected site property. + * + * @return a property, never {@code null}. + */ + public ObjectProperty siteProperty() { + return selectedSiteProperty; + } + + /** + * Expose the new site selected property. + * + * @return a property, never {@code null} + */ + public BooleanProperty newSiteProperty() { + return uiNewSiteToggleBtn.selectedProperty(); + } + + /** + * Switch to the selected protocol view. + * + * @param site The selected site, should not be {@code null} + * @param protocol The protocol to show, should not be {@code null} + */ + public void startEdition(final Site site, final Protocol protocol) { + // Defines the selected context + session.startEdition(site, protocol); + session.requestWorkflowStep(WorkflowStep.DATASET); + } + + /** + * Exports the current site as : + * - either a .zip file containing shapefile resources, + * - or a .kml file. + */ + @FXML + private void downloadSelectedSite() throws DataStoreException, XMLStreamException, IOException, KmlException, TransformException { + + final Site site = selectedSiteProperty.get(); + + if(site==null) return; + + final FileChooser.ExtensionFilter[] filters = new FileChooser.ExtensionFilter[] { + new FileChooser.ExtensionFilter("Archive zip", "*.zip"), + new FileChooser.ExtensionFilter("Shapefile", "*.shp"), + new FileChooser.ExtensionFilter("Keyhole Markup Language", "*.kml"), + new FileChooser.ExtensionFilter("Tous", "*") + }; + final File outputFile = Rhomeo.askOutputFilePopup(site.getName()+".zip", this, filters); + if(outputFile==null) return; + + Rhomeo.setPreviousPath(ExportUtils.class, outputFile.getParentFile()); + + if(outputFile.getName().endsWith(".shp")){ + ExportUtils.writeShp(site, outputFile); + } + else if(outputFile.getName().endsWith(".kml")){ + ExportUtils.writeKml(site, outputFile); + } + else if(outputFile.getName().endsWith(".zip")){ + ExportUtils.writeZip(site, outputFile); + } + else { + Rhomeo.showAlert(Alert.AlertType.ERROR, getResourceString("alert-site-download")); + } + } + + /** + * Delete selected site if the user validates this operation. + */ + @FXML + private void deleteSelectedSite() { + final Site selectedSite = selectedSiteProperty.get(); + final String siteName = selectedSite.getName(); + final Alert alert = new Alert(Alert.AlertType.CONFIRMATION, + getFormatedResourceString("alert-site-deleted", siteName), + ButtonType.YES, ButtonType.NO); + alert.setResizable(true); + final ButtonType res = alert.showAndWait().get(); + if (res == ButtonType.YES) { + siteRepository.delete(siteName); + try { + session.serializeDeleteSite(siteName); + } catch (IOException | IntrospectionException | ReflectiveOperationException ex) { + throw new RhomeoRuntimeException(ex); + } + cancel(); + } + } + + /** + * Import of a site into the system. Ask user for a shapefile as contour for this site. + * + * @throws MalformedURLException if the specified shapefile path is invalid + * @throws DataStoreException if unable to read the shapefile specified + */ + @FXML + private void importSite() throws MalformedURLException, DataStoreException { + uiNewSiteToggleBtn.setSelected(true); + // If no rollback has been performed, we proceed to the import. + if (uiNewSiteToggleBtn.isSelected()) { + if (!importShapefile()) { + cancel(); + } + } + } + + /** + * Ask user for a shapefile to use as contour for the site, or view the selected site SHP. + * + * @throws MalformedURLException if the specified shapefile path is invalid + * @throws DataStoreException if unable to read the shapefile specified + */ + @FXML + private void importOrViewContour() throws MalformedURLException, DataStoreException { + // Create / import new contour mode + if (uiNewSiteToggleBtn.isSelected()) { + importShapefile(); + + } else { + // View the selected site contour + final Stage viewShpStage = createShpViewStage(); + viewShpStage.initOwner(this.getScene().getWindow()); + viewShpStage.show(); + viewShpStage.requestFocus(); + } + } + + private boolean importShapefile() throws MalformedURLException { + final FileChooser fileChooser = new FileChooser(); + fileChooser.getExtensionFilters().addAll( + new FileChooser.ExtensionFilter("ShapeFile (*.shp)", "*.shp", "*.SHP"), + new FileChooser.ExtensionFilter("Keyhole Markup Language (*.kml)", "*.kml", "*.KML") + ); + final File prevPath = Rhomeo.getPreviousPath(FXDashboardMenuPane.class); + if (prevPath != null) { + fileChooser.setInitialDirectory(prevPath); + } + final File file = fileChooser.showOpenDialog(getScene().getWindow()); + if (file != null) { + Rhomeo.setPreviousPath(FXDashboardMenuPane.class, file.getParentFile()); + } else { + Rhomeo.LOGGER.log(Level.INFO, "Un fichier .shp doit être choisi."); + return false; + } + + final Task chooseFeature = choose(file.toURI()); + final Stage loadingStage = new Stage(StageStyle.TRANSPARENT); + loadingStage.initModality(Modality.APPLICATION_MODAL); + loadingStage.initOwner(this.getScene().getWindow()); + final ProgressIndicator pi = new ProgressIndicator(); + pi.setBackground(Background.EMPTY); + final Scene scene = new Scene(pi); + scene.setFill(null); + loadingStage.setScene(scene); + loadingStage.show(); + chooseFeature.runningProperty().addListener((obs, oldValue, newValue) -> { + if (!newValue) + loadingStage.close(); + }); + + chooseFeature.setOnFailed((evt) -> Platform.runLater(() + -> Rhomeo.showAlert(Alert.AlertType.ERROR, "Une erreur s'est produite lors de la lecture du fichier.") + )); + + chooseFeature.setOnSucceeded((evt) -> Platform.runLater(() -> { + final Feature feature = chooseFeature.getValue(); + if (feature == null) { + return; + } + + Geometry tmpGeom = feature.getDefaultGeometryProperty() == null? null : (Geometry) feature.getDefaultGeometryProperty().getValue(); + if (tmpGeom instanceof LinearRing) { + tmpGeom = tmpGeom.getFactory().createPolygon((LinearRing) tmpGeom); + } + if (tmpGeom instanceof Polygon) { + tmpGeom = new MultiPolygon(new Polygon[]{(Polygon) tmpGeom}, tmpGeom.getFactory()); + } + + if (tmpGeom instanceof MultiPolygon) { + geomToAdd.set((MultiPolygon) tmpGeom); + } else { + Rhomeo.showAlert(Alert.AlertType.ERROR, "Impossible d'importer la donnée car sa géométrie n'est pas un polygone."); + } + + // update fx UI + final Property nameProp = getByNameIgnoreCase(feature, Rhomeo.FT_PROPERTIES.NAME, "nom", "nom_site", "nomSite", "siteName", "site_name"); + if (nameProp != null && nameProp.getValue() != null) { + uiNameSiteTxt.setText(nameProp.getValue().toString()); + } + final Property refProp = getByNameIgnoreCase(feature, Rhomeo.FT_PROPERTIES.REFERENT); + if (refProp != null && refProp.getValue() != null) { + uiReferentSiteTxt.setText(refProp.getValue().toString()); + } + final Property orgProp = getByNameIgnoreCase(feature, Rhomeo.FT_PROPERTIES.ORG); + if (orgProp != null && orgProp.getValue() != null) { + uiStructureSiteTxt.setText(orgProp.getValue().toString()); + } + final Property dep = getByNameIgnoreCase(feature, Rhomeo.FT_PROPERTIES.COUNTY, "dept"); + County sourceCounty = dep == null || dep.getValue() == null ? null : counties.get(dep.getValue().toString().trim()); + if (geomToAdd.get() != null && countyRepository != null) { + List matching = countyRepository.get(geomToAdd.get()); + if (!matching.isEmpty() && !matching.contains(sourceCounty)) + sourceCounty = matching.get(0); + } + + if (sourceCounty != null) { + uiDepartmentSiteComboBox.setValue(sourceCounty); + } else { + uiDepartmentSiteComboBox.setValue(null); + } + + final Property type = getByNameIgnoreCase(feature, Rhomeo.FT_PROPERTIES.TYPE, "code_ty_01", "type_zone"); + if (type != null && type.getValue() != null && !type.getValue().toString().isEmpty()) { + uiTypeZhSiteComboBox.getSelectionModel().select(HumidZoneType.getByCode(type.getValue().toString())); + } + final Property odo = getByNameIgnoreCase(feature, Rhomeo.FT_PROPERTIES.ODONATE); + if (odo != null && odo.getValue() != null && !odo.getValue().toString().isEmpty()) { + uiZbOdoSiteComboBox.getSelectionModel().select(OdonateZoneBio.getByCode(odo.getValue().toString())); + } + final Property ortho = getByNameIgnoreCase(feature, Rhomeo.FT_PROPERTIES.ORTHOPTERE); + if (ortho != null && ortho.getValue() != null && !ortho.getValue().toString().isEmpty()) { + uiZbOrthoSiteComboBox.getSelectionModel().select(OrthoptereZoneBio.getByCode(ortho.getValue().toString())); + } + })); + + TaskManager.INSTANCE.submit(chooseFeature); + return true; + } + + private Property getByNameIgnoreCase(final Feature source, final Rhomeo.FT_PROPERTIES p, final String... fallback) { + for (final Property prop : source.getProperties()) { + if (prop.getName().tip().toString().equalsIgnoreCase(p.name())) + return prop; + } + + if (fallback != null && fallback.length > 0) { + final HashSet lcNames = new HashSet<>(fallback.length); + for (final String str : fallback) { + if (str != null && !str.isEmpty()) + lcNames.add(str.toLowerCase()); + } + + for (final Property prop : source.getProperties()) { + if (lcNames.contains(prop.getName().tip().toString().toLowerCase())) + return prop; + } + } + + return null; + } + + private Task choose(final URI shpFile) { + return new TaskManager.MockTask<>("Lecture d'un fichier", () -> { + Feature feature = null; + final CoordinateReferenceSystem siteCRS = Rhomeo.getSiteCRS(); + + // First, we try to read a KML file. If it fails, we'll try shapefile format. + Exception kmlError; + try { + KmlReader kmlReader = new KmlReader(); + kmlReader.setInput(shpFile); + kmlReader.setUseNamespace(false); + return mapKml(kmlReader.read(), siteCRS); + } catch (Exception e) { + kmlError = e; + } + + try (final ShapefileFeatureStore shpStore = new ShapefileFeatureStore(shpFile, "no namespace")) { + final Set names = shpStore.getNames(); + if (names != null && !names.isEmpty()) { + final GenericName layerName = names.iterator().next(); + final Query baseQuery = QueryBuilder.all(layerName); + final FeatureCollection col = shpStore.createSession(false) + .getFeatureCollection(baseQuery); + + if (col.getFeatureType().getCoordinateReferenceSystem() == null) { + Rhomeo.showAlert(Alert.AlertType.ERROR, "Aucune projection n'a été trouvée dans le fichier. Il est impossible d'importer les données."); + throw new IllegalArgumentException("No valid CRS in file ".concat(shpFile.toString())); + } + + if (col.isEmpty()) { + feature = null; + } else if (col.size() == 1) { + try (final FeatureIterator it = col.subCollection(QueryBuilder.reprojected(layerName, siteCRS)).iterator()) { + if (it.hasNext()) { + feature = it.next(); + } + } + } else { + final FeatureMapLayer tmpLayer = MapBuilder.createFeatureLayer(col); + final FXFeatureTable choiceTable = new FXFeatureTable(); + choiceTable.setLoadAll(true); + choiceTable.setEditable(false); + choiceTable.init(tmpLayer); // TODO : pagination + + feature = Rhomeo.fxRunAndWait(() -> { + final Alert a = new Alert(Alert.AlertType.CONFIRMATION, null, ButtonType.CANCEL, ButtonType.OK); + a.getDialogPane().setContent(choiceTable); + a.setHeaderText("Le fichier contient plusieurs entrées. Veuillez choisir celle à importer."); + a.setResizable(true); + if (ButtonType.OK.equals(a.showAndWait().orElse(ButtonType.CANCEL))) { + final Id selectionFilter = tmpLayer.getSelectionFilter(); + if (selectionFilter != null) { + final QueryBuilder builder = new QueryBuilder(layerName); + builder.setFilter(selectionFilter); + builder.setCRS(siteCRS); + try (final FeatureIterator it = col.subCollection(builder.buildQuery()).iterator()) { + if (it.hasNext()) { + return it.next(); + } + } + } + } + return null; + }); + } + } + } catch (Exception e) { + e.addSuppressed(kmlError); + throw e; + } + + return feature; + }); + } + + private Feature mapKml(final Kml kml, final CoordinateReferenceSystem targetCRS) throws Exception { + final Feature kmlFeature = kml.getAbstractFeature(); + final FeatureTypeBuilder builder = new FeatureTypeBuilder(); + builder.setName("site"); + GenericName geomName = null; + for (final PropertyDescriptor pType : kmlFeature.getType().getDescriptors()) { + if (AbstractGeometry.class.isAssignableFrom(pType.getType().getBinding())) { + builder.add(pType.getName(), Geometry.class); + builder.setDefaultGeometry(pType.getName()); + geomName = pType.getName(); + } else if (pType instanceof AttributeDescriptor) { + builder.add(pType.getName(), pType.getType().getBinding(), 1, 1, true, null); + } + } + + final FeatureType targetType = builder.buildSimpleFeatureType(); + final FeatureBuilder target = new FeatureBuilder(targetType); + for (final Property p : kmlFeature.getProperties()) { + if (p.getValue() == null) + continue; + if (p.getName().equals(geomName)) { + final Geometry geom = convert(p.getValue()); + if (geom != null) { + JTS.setCRS(geom, CommonCRS.WGS84.normalizedGeographic()); + target.setPropertyValue(p.getName(), JTS.convertToCRS(geom, targetCRS)); + } + } else { + target.setPropertyValue(p.getName(), p.getValue()); + } + } + + return target.buildFeature(kmlFeature.getIdentifier().getID()); + } + + /** + * Note : Return only polygons or multi-polygons. + * @param source The object to convert into polygon or multi-polygon + * @return Converted geometry, or null. + * @throws Exception + */ + private static Geometry convert(final Object source) { + if (source instanceof Polygon) + return (Geometry) source; + else if (source instanceof MultiGeometry) { + final MultiGeometry kmlMulti = (MultiGeometry) source; + final List geoms = new ArrayList<>(0); + + //loop on geometry to add id on a GeometryList + for (AbstractGeometry abstractGeometry : kmlMulti.getGeometries()) { + if (abstractGeometry instanceof Polygon) { + geoms.add((Polygon) abstractGeometry); + } + } + return new GeometryFactory().createMultiPolygon(geoms.toArray(new Polygon[geoms.size()])); + + } else + return null; + } + + /** + * Creates a {@linkplain Stage stage} with a map showing the currently selected site geometry. + * + * @return A stage with the map, never {@code null} + */ + private Stage createShpViewStage() { + final Site currentSite = selectedSiteProperty.get(); + // Should not be null when called here + if (currentSite == null) { + throw new IllegalArgumentException("Currently selected site was null here, but shouldn't be"); + } + + final Stage stage = Rhomeo.newStage(); + stage.setResizable(true); + stage.setTitle(currentSite.getName()); + stage.setWidth(1024); + stage.setHeight(768); + + final FXMap map = new FXMap(false); + map.addDecoration(new FXScaleBarDecoration()); + map.setHandler(new FXPanHandler(false)); + final FXCoordinateBar coordBar = new FXCoordinateBar(map); + coordBar.setCrsButtonVisible(false); + // Remove the first item among left items in the status bar, should be the timeline button + ((StatusBar)coordBar.getChildren().get(0)).getLeftItems().remove(0); + + final FXNavigationBar navBar = new FXNavigationBar(map); + // Remove the go to coordinate button + ((HBox)navBar.getItems().get(0)).getChildren().remove(4); + final FXGeoToolBar geoToolBar = new FXGeoToolBar(map); + final BorderPane fillPane = new BorderPane(); + fillPane.setMaxWidth(Double.MAX_VALUE); + + final GridPane topgrid = new GridPane(); + navBar.setMaxHeight(Double.MAX_VALUE); + geoToolBar.setMaxHeight(Double.MAX_VALUE); + topgrid.add(navBar, 0, 0); + topgrid.add(geoToolBar, 1, 0); + final ColumnConstraints col2 = new ColumnConstraints(); + col2.setHgrow(Priority.ALWAYS); + topgrid.getColumnConstraints().addAll(new ColumnConstraints(), col2); + + // If counties are available, we display them on the map. + final MapContext context = MapBuilder.createContext(); + + if (countyRepository != null) { + try { + context.layers().add(MapBuilder.createFeatureLayer( + countyRepository.getFeatures(), GO2Utilities.STYLE_FACTORY.style(GO2Utilities.STYLE_FACTORY.lineSymbolizer()) + )); + } catch (Exception e) { + Rhomeo.LOGGER.log(Level.WARNING, "Cannot show county layer", e); + } + } + + final BeanFeature feature = new BeanFeature(currentSite, BeanUtils.createMapping(Site.class, null)); + final MapLayer layer = MapBuilder.createFeatureLayer(FeatureStoreUtilities.collection(feature)); + context.layers().add(layer); + context.setAreaOfInterest(layer.getBounds()); + map.getContainer().setContext(context); + try { + map.getCanvas().setObjectiveCRS(Rhomeo.getSiteCRS()); + map.getCanvas().setVisibleArea(layer.getBounds()); + } catch (FactoryException | TransformException | java.awt.geom.NoninvertibleTransformException e) { + throw new IllegalArgumentException("Unable to defines canvas CRS", e); + } + + final Scene scene = new Scene(new BorderPane(map, topgrid, null, coordBar, null)); + stage.setScene(scene); + + return stage; + } + + /** + * Create or update a site, depending if we are viewing the information panel as a new or existing site. + */ + @FXML + private void createOrUpdateSite() { + // Check data validity + if (!verifyMandatoryParameters()) { + return; + } + + Site site = selectedSiteProperty.get(); + final String oldName = site == null? null : site.getName(); + site = prepareSiteFromForm((SiteImpl)site); + + try { + // If the site had no name initially, it's a new one. Otherwise, it + // already existed. + if (oldName == null || uiNewSiteToggleBtn.isSelected()) { + siteRepository.create(site); + + } else { + siteRepository.update(site, oldName); + try { + session.serializeUpdateSiteName(site, oldName); + } catch (IOException | IntrospectionException | ReflectiveOperationException ex) { + throw new RhomeoRuntimeException(ex); + } + } + + // Update selection will set the editor in read-only mode, and ensure + // that combo-box is aware of the created site. + selectedSiteProperty.set(null); + selectedSiteProperty.set(site); + + } catch (DuplicatedKeyException e) { + Rhomeo.showAlert(Alert.AlertType.WARNING, getFormatedResourceString("alert-site-createOrUpdate", site.getName())); + } + } + + /** + * Verify that all mandatory parameters are filled. + * + * @return {@code True} if all parameters are filled, {@code false} if one is missing. + */ + private boolean verifyMandatoryParameters() { + // Verify mandatory fields + boolean result = true; + if (uiNameSiteTxt.getText() == null || uiNameSiteTxt.getText().trim().isEmpty()) { + uiNameSiteTxt.getStyleClass().add(Rhomeo.CSS_ERROR_FIELD); + Rhomeo.showAlert(Alert.AlertType.WARNING, "Un nom doît avoir été renseigné pour créer un nouveau site."); + result = false; + } else { + uiNameSiteTxt.getStyleClass().remove(Rhomeo.CSS_ERROR_FIELD); + } + + if (geomToAdd.get() == null) { + uiImportContourBtn.getStyleClass().add(Rhomeo.CSS_ERROR_FIELD); + if (result) { + Rhomeo.showAlert(Alert.AlertType.WARNING, "Un contour doît avoir été importé pour créer un nouveau site."); + result = false; + } + } else { + uiImportContourBtn.getStyleClass().remove(Rhomeo.CSS_ERROR_FIELD); + } + + if (uiDepartmentSiteComboBox.getSelectionModel().isEmpty()) { + uiDepartmentSiteComboBox.getStyleClass().add(Rhomeo.CSS_ERROR_FIELD); + if (result) { + Rhomeo.showAlert(Alert.AlertType.WARNING, "Un département doît avoir été sélectionné pour créer un nouveau site."); + result = false; + } + } else { + uiDepartmentSiteComboBox.getStyleClass().remove(Rhomeo.CSS_ERROR_FIELD); + } + + if (uiTypeZhSiteComboBox.getSelectionModel().isEmpty()) { + uiTypeZhSiteComboBox.getStyleClass().add(Rhomeo.CSS_ERROR_FIELD); + if (result) { + Rhomeo.showAlert(Alert.AlertType.WARNING, "Un type de zone humide doît avoir été sélectionné pour créer un nouveau site."); + result = false; + } + } else { + uiTypeZhSiteComboBox.getStyleClass().remove(Rhomeo.CSS_ERROR_FIELD); + } + return result; + } + + /** + * Cancel site creation. + */ + @FXML + private void cancel() { + if (confirmCancelling(siteProperty().get())) { + selectedSiteProperty.set(null); + } + } + + /** + * Clears the site form. + */ + private void clearForm() { + uiNameSiteTxt.setText(""); + uiReferentSiteTxt.setText(""); + uiStructureSiteTxt.setText(""); + uiTypeZhSiteComboBox.setValue(null); + uiDepartmentSiteComboBox.setValue(null); + uiZbOdoSiteComboBox.setValue(null); + uiZbOrthoSiteComboBox.setValue(null); + geomToAdd.set(null); + + uiNameSiteTxt.getStyleClass().remove(Rhomeo.CSS_ERROR_FIELD); + uiImportContourBtn.getStyleClass().remove(Rhomeo.CSS_ERROR_FIELD); + uiDepartmentSiteComboBox.getStyleClass().remove(Rhomeo.CSS_ERROR_FIELD); + uiTypeZhSiteComboBox.getStyleClass().remove(Rhomeo.CSS_ERROR_FIELD); + } + + /** + * Generates a new {@linkplain SiteImpl site} using values filled in the site information form. + * + * @param site site to update if not {@code null}. If {@code null}, create a new one. + * @return A new site, or the same instance with values updated from the form. + * @throws IllegalArgumentException if the geometry is invalid. + */ + private SiteImpl prepareSiteFromForm(final SiteImpl site) { + final SiteImpl siteToPrepare; + if (site == null) { + siteToPrepare = new SiteImpl(geomToAdd.get()); + } else { + siteToPrepare = site; + siteToPrepare.setGeometry(geomToAdd.get()); + } + siteToPrepare.setName(uiNameSiteTxt.getText()); + siteToPrepare.setReferent(uiReferentSiteTxt.getText()); + siteToPrepare.setOrganization(uiStructureSiteTxt.getText()); + + final County selectedItem = uiDepartmentSiteComboBox.getSelectionModel().getSelectedItem(); + if (selectedItem != null) { + siteToPrepare.setCountyCode(selectedItem.getCode()); + } + + if (!uiTypeZhSiteComboBox.getSelectionModel().isEmpty()) { + siteToPrepare.setZoneType(uiTypeZhSiteComboBox.getSelectionModel().getSelectedItem().getCode()); + } + if (!uiZbOdoSiteComboBox.getSelectionModel().isEmpty()) { + siteToPrepare.setOdonateType(uiZbOdoSiteComboBox.getSelectionModel().getSelectedItem().getCode()); + } + if (!uiZbOrthoSiteComboBox.getSelectionModel().isEmpty()) { + siteToPrepare.setOrthoptereType(uiZbOrthoSiteComboBox.getSelectionModel().getSelectedItem().getCode()); + } + + return siteToPrepare; + } + + /** + * Fill the site information form using values coming from a site. + * Reverse of {@link #prepareSiteFromForm(SiteImpl)}. + * + * @param site site + */ + private void fillFormFromSite(final Site site) { + uiNameSiteTxt.setText(site.getName()); + uiReferentSiteTxt.setText(site.getReferent()); + uiStructureSiteTxt.setText(site.getOrganization()); + geomToAdd.set(site.getGeometry()); + + final String cc = site.getCountyCode(); + County sourceCounty = cc == null || counties == null? null : counties.get(cc.trim()); + if (site.getGeometry() != null && countyRepository != null) { + List matching = countyRepository.get(site.getGeometry()); + if (!matching.isEmpty() && !matching.contains(sourceCounty)) + sourceCounty = matching.get(0); + } + + if (sourceCounty != null) { + uiDepartmentSiteComboBox.setValue(sourceCounty); + } else { + uiDepartmentSiteComboBox.setValue(null); + } + + if (site.getZoneType() != null && !site.getZoneType().isEmpty()) { + uiTypeZhSiteComboBox.getSelectionModel().select(HumidZoneType.getByCode(site.getZoneType())); + } + if (site.getOdonateType() != null && !site.getOdonateType().isEmpty()) { + uiZbOdoSiteComboBox.getSelectionModel().select(OdonateZoneBio.getByCode(site.getOdonateType())); + } + if (site.getOrthoptereType() != null && !site.getOrthoptereType().isEmpty()) { + uiZbOrthoSiteComboBox.getSelectionModel().select(OrthoptereZoneBio.getByCode(site.getOrthoptereType())); + } + } + + private void siteNameChanged(final ObservableValue obs, String oldSite, String newSite) { + Site site = selectedSiteProperty.get(); + if (site != null && Rhomeo.equivalent(newSite, site.getName())) + return; + + if (newSite == null || newSite.trim().isEmpty()) + selectedSiteProperty.set(null); + else + selectedSiteProperty.set(siteRepository.findOne(newSite)); + } + + private synchronized void siteChanged(final ObservableValue obs, Site oldValue, Site newValue) { + clearForm(); + + if (newValue != null) { + fillFormFromSite(newValue); + if (newValue.getName() != null) { + uiNewSiteToggleBtn.setSelected(false); + } + uiSitesList.setValue(newValue.getName()); + } else { + uiNewSiteToggleBtn.setSelected(false); + uiSitesList.setValue(null); + } + } + + private boolean confirmCancelling(final Site toCancel) { + return Rhomeo.fxRunAndWait(() -> { + if (toCancel != null && !toCancel.equals(prepareSiteFromForm(null))) { + final Alert modifications = new Alert(Alert.AlertType.CONFIRMATION, getResourceString("unsaved-modification"), ButtonType.NO, ButtonType.YES); + modifications.setResizable(true); + if (ButtonType.NO.equals(modifications.showAndWait().orElse(ButtonType.NO))) { + return false; + } + } + + return true; + }); + } + + /** + * Generates a PDF button that will open the PDF file when clicked. + * + * @param pdfPath Path of the PDF to open. + * @return A button, never {@code null} + */ + private Button createPdfButton(final String pdfPath) { + final Button button = new Button(); + button.setGraphic(new ImageView(Rhomeo.ICON_FILE_PDF)); + button.getStyleClass().add("transparent"); + button.setOnAction(event -> + docManager.openDocument(FXDashboardMenuPane.class.getResource(pdfPath)) + ); + return button; + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/FXDashboardPane.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXDashboardPane.java new file mode 100644 index 0000000..4579439 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXDashboardPane.java @@ -0,0 +1,256 @@ +/** + * 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.fx; + +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.InternationalResource; +import fr.cenra.rhomeo.api.data.Site; +import fr.cenra.rhomeo.api.process.Indicator; +import fr.cenra.rhomeo.api.result.DashboardResultItem; +import fr.cenra.rhomeo.api.result.IndicatorValuesByYearItem; +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.data.DashboardResultsManager; +import fr.cenra.rhomeo.core.result.ResultStorage; +import fr.cenra.rhomeo.core.util.ExportUtils; +import javafx.fxml.FXML; +import javafx.scene.layout.BorderPane; +import javafx.stage.FileChooser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.io.File; +import java.nio.file.FileSystem; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collections; +import java.util.Map; +import java.util.Optional; +import javafx.application.Platform; +import javafx.beans.binding.Bindings; +import javafx.beans.property.ObjectProperty; +import javafx.collections.ObservableList; +import javafx.event.ActionEvent; +import javafx.scene.control.Button; +import javafx.scene.control.TablePosition; +import org.apache.commons.net.ftp.FTPClient; +import org.geotoolkit.gui.javafx.util.TaskManager; +import org.springframework.context.annotation.Scope; + +/** + * Dashboard panel displayed initially when opening the application. + * + * @author Cédric Briançon (Geomatys) + */ +@Component +@Scope("prototype") +public class FXDashboardPane extends BorderPane implements InternationalResource { + /** + * Body panel containing the data table and some action buttons. + */ + @FXML private BorderPane uiDashboardBodyPane; + + @FXML + private Button uiPublish; + + @FXML + private Button uiExport; + + @Autowired + private FXDashboardMenuPane menuPane; + + @Autowired + private Session session; + + @Autowired + private DashboardResultsManager resultsManager; + + @Autowired + private ResultStorage resultStorage; + + FXDashboardResultsTable resultTable; + + public FXDashboardPane() { + Rhomeo.loadFXML(this, FXDashboardPane.class); + } + + /** + * Initializes JavaFX components after spring components are done loading. + */ + @PostConstruct + private void postConstruct() { + setTop(menuPane); + + resultTable = session.createPrototype(FXDashboardResultsTable.class, true); + uiDashboardBodyPane.setCenter(resultTable); + resultTable.siteProperty().bind(menuPane.siteProperty()); + + uiDashboardBodyPane.visibleProperty().bind(menuPane.siteProperty().isNotNull().and(menuPane.newSiteProperty().not())); + uiDashboardBodyPane.managedProperty().bind(uiDashboardBodyPane.visibleProperty()); + + final ObservableList selectedCells = resultTable.getSelectionModel().getSelectedCells(); + uiPublish.disableProperty().bind(Bindings.createBooleanBinding(() -> { + if (selectedCells.size() != 1) { + return true; + } + + TablePosition pos = selectedCells.get(0); + if (pos.getTableColumn() instanceof IndicatorSiteColumn) { + final String indicName = ((IndicatorSiteColumn)pos.getTableColumn()).getIndicator().getName(); + final Boolean published = pos.getTableView().getItems().get(pos.getRow()).isPublished(indicName); + return published == null? true : published; + } + + return true; + }, selectedCells)); + + uiExport.disableProperty().bind(Bindings.createBooleanBinding(() -> { + return (selectedCells.size() != 1 || !(selectedCells.get(0).getTableColumn() instanceof IndicatorSiteColumn)); + }, selectedCells)); + } + + public ObjectProperty siteProperty() { + return menuPane.siteProperty(); + } + + @FXML + public void publishData(final ActionEvent evt) { + final ObservableList selectedCells = resultTable.getSelectionModel().getSelectedCells(); + if (resultTable == null || selectedCells.size() != 1) + return; + + final DashboardResultItem item = getSelectedItem(); + final IndicatorValuesByYearItem rowItem = resultTable.getItems().get(selectedCells.get(0).getRow()); + if (item == null || item.isPublished()) + return; + + TaskManager.INSTANCE.submit("Publication ".concat(item.getIndicator()), () -> { + final FTPClient ftp = session.connectResultFTP(); + try { + resultsManager.publishResults(menuPane.siteProperty().get(), Collections.singletonList(item), ftp); + } finally { + ftp.disconnect(); + } + + return true; + }).setOnSucceeded((evt2) -> Platform.runLater(() -> { + // Update publication state. + rowItem.getValueForIndicator(item.getIndicator()).setPublished(true); + resultTable.getItems().set(resultTable.getItems().indexOf(rowItem), rowItem); + })); + } + + @FXML + public void exportData() { + if (resultTable == null || resultTable.getSelectionModel().getSelectedCells().size() != 1) + return; + + final DashboardResultItem item = getSelectedItem(); + if (item == null) + return; + + final Indicator indic = ((IndicatorSiteColumn) resultTable.getSelectionModel().getSelectedCells().get(0).getTableColumn()).getIndicator(); + final String initialFileName = new StringBuilder(item.getSite()).append('_').append(item.getIndicator()).append('_').append(item.getYear()).append(".zip").toString(); + final FileChooser.ExtensionFilter zipFilter = new FileChooser.ExtensionFilter("Archive zip", "*.zip"); + final File outputFile = Rhomeo.askOutputFilePopup(initialFileName, this, zipFilter); + if (outputFile == null) { + return; + } + + TaskManager.INSTANCE.submit("Export de résultats", () -> { + try (final FileSystem fs = RhomeoCore.toZipFileSystem(outputFile.toPath())) { + final Path root = fs.getRootDirectories().iterator().next(); + Optional opt = resultStorage.getMainResults(item); + if (opt.isPresent()) + Files.copy(opt.get(), root.resolve(opt.get().getFileName().toString())); + opt = resultStorage.getAdditionalResults(item); + if (opt.isPresent()) + Files.copy(opt.get(), root.resolve(opt.get().getFileName().toString())); + + // Read metadata from file, and recover memory objects needed for + // re-writing as text. + final Map[] readMds = resultStorage.readMetadata(item) + .map(ctx -> ctx.toDataContext(session)) + .map(ctx -> new Map[]{session.transform(ctx.getReferences()), ctx.getUserData()}) + .orElse(new Map[]{Collections.EMPTY_MAP, Collections.EMPTY_MAP}); + + ExportUtils.writeMetadataText( + root.resolve("metadata.txt"), + menuPane.siteProperty().get(), + indic.getProtocol(), + readMds[0], + Collections.singleton(indic), + readMds[1], + Collections.EMPTY_SET + ); + } + return true; + }); + } + + /** + * + * @return A dashboard item reflecting data pointed by currently selected cell. Can be null. + */ + private DashboardResultItem getSelectedItem() { + if (resultTable == null) { + return null; + } + final ObservableList selectedCells = resultTable.getSelectionModel().getSelectedCells(); + if (resultTable.getSelectionModel().getSelectedCells().size() != 1) { + return null; + } + + TablePosition pos = selectedCells.get(0); + if (!(pos.getTableColumn() instanceof IndicatorSiteColumn)) { + return null; + } + + final Site site = menuPane.siteProperty().get(); + final String siteName = site.getName(); + final IndicatorSiteColumn col = (IndicatorSiteColumn) pos.getTableColumn(); + IndicatorValuesByYearItem tmpItem = resultTable.getItems().get(pos.getRow()); + final Indicator indic = col.getIndicator(); + final String indicName = indic.getName(); + return new DashboardResultItem( + tmpItem.getYear(), siteName, indicName, col.getCellData(tmpItem), tmpItem.isPublished(indicName) + ); + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/FXDashboardResultsTable.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXDashboardResultsTable.java new file mode 100644 index 0000000..947bb2e --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXDashboardResultsTable.java @@ -0,0 +1,234 @@ +/** + * 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.fx; + +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.data.Protocol; +import fr.cenra.rhomeo.api.data.Site; +import fr.cenra.rhomeo.api.process.Indicator; +import fr.cenra.rhomeo.api.result.IndicatorValuesByYearItem; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.data.DashboardResultsManager; +import javafx.beans.property.SimpleObjectProperty; +import javafx.scene.control.ContentDisplay; +import javafx.scene.control.SelectionMode; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.image.ImageView; +import org.geotoolkit.gui.javafx.util.FXTableCell; +import org.geotoolkit.gui.javafx.util.FXTableView; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import javafx.beans.value.ObservableValue; +import javafx.scene.control.ContextMenu; +import javafx.scene.control.TableCell; +import fr.cenra.rhomeo.api.ui.DashboardMenuItem; +import fr.cenra.rhomeo.core.RhomeoRuntimeException; +import java.text.DecimalFormat; +import java.util.Optional; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleIntegerProperty; +import javafx.geometry.Pos; +import javafx.scene.control.Label; +import javafx.scene.control.MenuItem; +import javax.annotation.PostConstruct; + +/** + * Dashboard table presenting results for the selected site. + * + * @author Cédric Briançon (Geomatys) + */ +@Component("fr.cenra.rhomeo.fx.FXDashboardResultsTable") +@Scope("prototype") +public class FXDashboardResultsTable extends FXTableView { + + @Autowired + private Session session; + + @Autowired + private DashboardResultsManager resultsManager; + + @Autowired + private List menuItems; + + private final ObjectProperty siteProperty = new SimpleObjectProperty<>(); + + /** + * Generate a table for the specified site. + * + * @param byCell true if the table has to use the selection by cell mode, false for generic by line selection. + */ + public FXDashboardResultsTable(final boolean byCell) { + setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + + if (byCell) { + getSelectionModel().setCellSelectionEnabled(true); + getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); + } + + siteProperty.addListener(this::siteChanged); + } + + + public ObjectProperty siteProperty() { + return siteProperty; + } + + /** + * Initializes JavaFX components after spring components are done loading. + */ + @PostConstruct + public void postConstruct() { + final ContextMenu menu = new ContextMenu(); + setContextMenu(menu); + for (final DashboardMenuItem menuItem : menuItems) { + final Optional item = menuItem.createItem(this); + if(item.isPresent()){ + menu.getItems().add(item.get()); + } + } + } + + private void siteChanged(final ObservableValue obs, final Site oldSite, final Site newSite) { + getColumns().clear(); + if (newSite == null) { + setItems(null); + setPlaceholder(new Label("Aucun site séléctionné")); + } else { + try { + setItems(resultsManager.getDashboardResultsByYear(newSite)); + } catch (Exception ex) { + throw new RhomeoRuntimeException(ex); + } + + if (getItems().isEmpty()) { + setPlaceholder(new Label("Aucun résultat attaché au site")); + } else { + final TableColumn yearCol = new TableColumn<>("Année"); + yearCol.setCellValueFactory(value -> new SimpleIntegerProperty(value.getValue().getYear()).asObject()); + getColumns().add(yearCol); + + final List indicators = session.getIndicators(); + final List protocols = session.getProtocols(); + + final List columnsToAdd = new ArrayList<>(); + + protocols.stream() + .filter(protocol -> protocol.isCompatible(newSite)) + .sorted() + .forEach(protocol + -> indicators.stream() + .filter(indicator -> indicator.getProtocol() == protocol) + .sorted() + .forEach(indicator -> { + final IndicatorSiteColumn siteColumn = new IndicatorSiteColumn(indicator); + siteColumn.setCellValueFactory(this::getCellValueFactory); + siteColumn.setCellFactory(this::getCellFactory); + columnsToAdd.add(siteColumn); + }) + ); + Collections.sort(columnsToAdd); + getColumns().addAll(columnsToAdd); + } + } + } + + private TableCell getCellFactory(final TableColumn input) { + // hack #61 display integers for I04/I07 + final DecimalFormat format; + if (input instanceof IndicatorSiteColumn && + (((IndicatorSiteColumn)input).getIndicator().getName().matches("I0(4|7)"))) { + format = Rhomeo.SIMPLE_DECIMAL_FORMAT; + } else { + format = Rhomeo.SECOND_DECIMAL_FORMAT; + } + final FXTableCell cell = new FXTableCell() { + + @Override + protected void updateItem(Double item, boolean empty) { + super.updateItem(item, empty); + setContentDisplay(ContentDisplay.RIGHT); + if (empty || item == null || Double.isNaN(item)) { + setText(null); + setGraphic(null); + } else { + final IndicatorValuesByYearItem itemLine = getItems().get(getIndex()); + if (itemLine == null) { + setText(null); + setGraphic(null); + } else { + setText(format.format(item)); + if (input instanceof IndicatorSiteColumn) { + final Boolean isPublished = itemLine.isPublished(((IndicatorSiteColumn) input).getIndicator().getName()); + if (isPublished != null && !isPublished) { + setGraphic(new ImageView(Rhomeo.ICON_NOT_PUBLISHED)); + } + } + } + } + } + }; + cell.setAlignment(Pos.CENTER_RIGHT); + return cell; + } + + private ObservableValue getCellValueFactory(final TableColumn.CellDataFeatures feature) { + final TableColumn col = feature.getTableColumn(); + final String indicName; + if (col instanceof IndicatorSiteColumn) { + indicName = ((IndicatorSiteColumn) col).getIndicator().getName(); + } else { + indicName = null; + } + + final IndicatorValuesByYearItem.PublishedValue valueForIndicator + = indicName == null ? null : feature.getValue().getValueForIndicator(indicName); + + if (valueForIndicator == null || valueForIndicator.getValue() == null) { + return new SimpleObjectProperty<>(); + } + + return new SimpleObjectProperty<>(valueForIndicator.getValue()); + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/FXDefaultPreferenceGroupPane.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXDefaultPreferenceGroupPane.java new file mode 100644 index 0000000..89b0210 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXDefaultPreferenceGroupPane.java @@ -0,0 +1,186 @@ +/** + * 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.fx; + +import fr.cenra.rhomeo.api.InternationalDescription; +import fr.cenra.rhomeo.api.preferences.PasswordKey; +import fr.cenra.rhomeo.api.preferences.PreferenceGroup; +import fr.cenra.rhomeo.api.ui.PreferencePane; +import java.util.HashMap; +import java.util.Map; +import javafx.beans.property.StringProperty; +import javafx.scene.Node; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.PasswordField; +import javafx.scene.control.TextField; +import javafx.scene.control.Tooltip; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.HBox; + +/** + * + * A default preference pane based on key/value structure. + * + * Each preference is displayed as a row of a {@link GridPane} in which the key + * is displayed as a {@link Label} on the left side, and the value is displayed + * in a {@link TextField} on the right side. + * + * Preferences are provided by a {@link PreferenceGroup} which must be set only + * once. + * + * @author Samuel Andrés (Geomatys) + * + * @param The TYPE of {@link PreferenceGroup} keys. + */ +public class FXDefaultPreferenceGroupPane extends GridPane implements PreferencePane { + + private PreferenceGroup preferenceGroup; + private final Map valueFields = new HashMap<>(); + + /** + * Builds a {@link FXDefaultPreferenceGroupPane} based on key/value structure of + * a {@link PreferenceGroup}. + * + * @param preferenceGroup + */ + public FXDefaultPreferenceGroupPane(final PreferenceGroup preferenceGroup){ + this(); + setPreferenceGroup(preferenceGroup); + } + + /** + * Default constructor used by Spring to produce new prototype. + * + * This constructor does not fill the pane for any {@link PreferenceGroup}. + * + * The method {@link #setPreferenceGroup(PreferenceGroup)} must be used to fill the pane. + */ + public FXDefaultPreferenceGroupPane(){ + final String css = FXDefaultPreferenceGroupPane.class.getResource(FXDefaultPreferenceGroupPane.class.getSimpleName()+".css").toExternalForm(); + getStylesheets().add(css); + getStyleClass().add("pane"); + } + + @Override + public PreferenceGroup getPreferenceGroup() { + return preferenceGroup; + } + + /** + * Sets the preference group. + * + * Must be called only once. + * + * If the current object has been built with the default constructor (for + * instance by Spring autowiring), it must be called explicitly. On the + * contrary, this method is implicitly called by the constructor using a + * {@link PreferenceGroup} parameter. + * + * For each key of the {@link PreferenceGroup}, this method adds a new row + * to the pane, with two columns. The first one contains a label relative to + * the preference key. The second one contains a text field to edit the + * corresponding preference value. + * + * @param preferenceGroup + */ + public final void setPreferenceGroup(final PreferenceGroup preferenceGroup){ + + if(this.preferenceGroup!=null) throw new IllegalStateException("The preference group has already been set."); + + this.preferenceGroup = preferenceGroup; + int row = 0; + for(final T key : preferenceGroup.getKeys()){ + final Label label = new Label(key.getLabel()); + final String comment = key.getDescription(); + if(comment!=null && !comment.equals("")){ + label.setTooltip(new Tooltip(comment)); + } + + final Node editor = createEditor(key); + addRow(row++, label, editor); + } + } + + private Node createEditor(final T key) { + if (key instanceof PasswordKey) { + final Button editBtn = new Button("Modifier"); + final HBox container = new HBox(5, editBtn); + editBtn.setOnAction((evt) -> { + final PasswordField field = new PasswordField(); + valueFields.put(key, field.textProperty()); + final Button cancelBtn = new Button("Annuler"); + cancelBtn.setCancelButton(true); + cancelBtn.setOnAction(evt2 -> { + valueFields.remove(key); + container.getChildren().clear(); + container.getChildren().add(editBtn); + }); + container.getChildren().clear(); + container.getChildren().addAll(field, cancelBtn); + }); + return container; + } else { + final TextField textField = new TextField(preferenceGroup.getPreference(key)); + textField.setPrefWidth(300); + valueFields.put(key, textField.textProperty()); + return textField; + } + } + + /** + * Save the preferences. + */ + @Override + public void save(){ + if(preferenceGroup!=null){ + for(final T key : preferenceGroup.getKeys()){ + final StringProperty value = valueFields.get(key); + if(value!=null){ + preferenceGroup.setPreference(key, value.getValue()); + } + } + } + } + + @Override + public Node getEditor() { + return this; + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/FXDefaultProcessingPane.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXDefaultProcessingPane.java new file mode 100644 index 0000000..c21243e --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXDefaultProcessingPane.java @@ -0,0 +1,674 @@ +/** + * 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.fx; + +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.InternationalResource; +import fr.cenra.rhomeo.api.data.DataContext; +import fr.cenra.rhomeo.api.data.Dataset; +import fr.cenra.rhomeo.api.data.Protocol; +import fr.cenra.rhomeo.api.data.Site; +import fr.cenra.rhomeo.api.data.Statement; +import fr.cenra.rhomeo.api.data.TrackingPoint; +import fr.cenra.rhomeo.api.process.Indicator; +import fr.cenra.rhomeo.api.process.Process; +import fr.cenra.rhomeo.api.process.ProcessContext; +import fr.cenra.rhomeo.api.result.Index; +import fr.cenra.rhomeo.api.ui.FilterTable; +import fr.cenra.rhomeo.api.ui.FilterTableSpi; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.WorkflowStep; +import fr.cenra.rhomeo.core.util.SimplePredicateChain; +import fr.cenra.rhomeo.fx.edition.FXTrackingPointTable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.ResourceBundle; +import java.util.Set; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import javafx.application.Platform; +import javafx.beans.Observable; +import javafx.beans.binding.Bindings; +import javafx.beans.binding.DoubleBinding; +import javafx.beans.property.BooleanProperty; +import javafx.beans.property.ReadOnlyBooleanProperty; +import javafx.beans.property.ReadOnlyProperty; +import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.collections.ListChangeListener; +import javafx.concurrent.Task; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.control.Alert; +import javafx.scene.control.CheckBox; +import javafx.scene.control.Label; +import javafx.scene.control.ProgressBar; +import javafx.scene.control.SelectionMode; +import javafx.scene.control.TableCell; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.control.Tooltip; +import javafx.scene.control.cell.CheckBoxTableCell; +import javafx.scene.image.ImageView; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.FlowPane; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.VBox; +import org.apache.sis.util.ArgumentChecks; +import org.geotoolkit.gui.javafx.util.TaskManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; + + +/** + * + * Default JavaFX pane to set processing parameters. + * + * For a given {@link Dataset} and a given {@link Protocol}, this pane allows to + * choose the {@link Indicator}(s) and the {@link TrackingPoint}(s) the processing + * must be computed for. + * + * @author Samuel Andrés (Geomatys) + * + * @param + */ +@Component("fr.cenra.rhomeo.fx.FXDefaultProcessingPane") +@Scope("prototype") +public class FXDefaultProcessingPane extends VBox implements InternationalResource { + + @FXML private GridPane uiIndicatorPane; + private final Collection indicatorSelections = new ArrayList<>(); + + @FXML private FlowPane uiYearPane; + private final Collection yearSelections = new ArrayList<>(); + + @FXML private BorderPane uiTrackingPointPane; + + private FilterTable uiSelectionTable; + private final TableColumn uiSelectionColumn; + + private final Map filterSelection = new HashMap<>(); + private final Function selectionComputer; + + @FXML + private VBox uiProgressBox; + + @FXML + private Label uiProgressTitle; + + @FXML + private ProgressBar uiProgress; + + @FXML + private Label uiProgressMessage; + + @FXML + private HBox uiBtnBox; + + private Dataset dataset; + private Protocol protocol; + private ProcessContext processContext; + private Site site; + + private final ChangeListener selectionListener = this::selectionChanged; + private final SimpleObjectProperty>> globalTask = new SimpleObjectProperty<>(); + + private SimplePredicateChain processFilter; + + @Autowired + private Session session; + + @Autowired + private List pointTableSpis; + + public FXDefaultProcessingPane() { + Rhomeo.loadFXML(this, FXDefaultProcessingPane.class); + + uiProgressBox.setVisible(false); + globalTask.addListener((obs, oldTask, newTask) -> { + if (oldTask != null) { + uiProgressBox.visibleProperty().unbind(); + uiProgressBox.setVisible(false); + uiProgressTitle.textProperty().unbind(); + uiProgressMessage.textProperty().unbind(); + uiProgress.progressProperty().unbind(); + uiIndicatorPane.disableProperty().unbind(); + uiTrackingPointPane.disableProperty().unbind(); + uiBtnBox.disableProperty().unbind(); + } else { + uiProgressBox.visibleProperty().bind(newTask.runningProperty()); + uiProgressTitle.textProperty().bind(newTask.titleProperty()); + uiProgressMessage.textProperty().bind(newTask.messageProperty()); + uiProgress.progressProperty().bind(newTask.progressProperty()); + uiIndicatorPane.disableProperty().bind(newTask.runningProperty()); + uiTrackingPointPane.disableProperty().bind(newTask.runningProperty()); + uiBtnBox.disableProperty().bind(newTask.runningProperty()); + } + }); + + uiSelectionColumn = new TableColumn(ResourceBundle.getBundle(FXDefaultProcessingPane.class.getCanonicalName()).getString("selectionColumn")); + selectionComputer = input -> { + final BooleanProperty bp = new SimpleBooleanProperty(input, "selection", false); + bp.addListener(selectionListener); + bp.set(true); + + return bp; + }; + } + + @PostConstruct + public void postConstruct() { + dataset = session.getDataset(); + ArgumentChecks.ensureNonNull("dataset", dataset); + + final DataContext context = session.getDataContext(); + protocol = context.getProtocol(); + ArgumentChecks.ensureNonNull("protocol", protocol); + + site = context.getSite(); + ArgumentChecks.ensureNonNull("site", site); + + /* + 1- Indicator pane. + ================*/ + final List sortedIndicators = new ArrayList<>(session.getIndicators()); + sortedIndicators.removeIf(i -> !protocol.equals(i.getProtocol())); + Collections.sort(sortedIndicators); + initIndicatorPane(sortedIndicators); + + /* + 2- Year pane. + ============*/ + final List years = new ArrayList<>(); + for(final TrackingPoint trackingPoint : dataset.getTrackingPoints()){ + final int year = trackingPoint.getYear(); + + // Do not add the same year twice… + if(!years.contains(year)){ + years.add(year); + } + } + + // Sort years… + Collections.sort(years); + initYearPane(years); + + /* + 3- Tracking point pane. + =====================*/ + initTrackingPointPane(); + + /* + 4- LISTENERS. + =====================*/ + uiSelectionTable.getItems().addListener(this::tableContentChanged); + for (final IndicatorSelection is : indicatorSelections) { + is.selectedProperty.addListener(selectionListener); + } + + // FXTrackingPointPane must only display tracking point which year is selected into FXYearPane + yearSelections.forEach(yearSelection -> + yearSelection.selectedProperty().addListener(selectionListener) + ); + + /* + 4- RESTORE PROCESS CONTEXT. + =====================*/ + // Start by extracting previous indicators / years / filters + processContext = session.getProcessContext(); + final Set previousIndics = new HashSet<>(processContext.getIndicators()); + final HashSet previousYears = new HashSet<>(); + processContext.getTrackingPoints().forEach(tp -> previousYears.add(tp.getYear())); + if (processContext.getFilter() instanceof SimplePredicateChain) + processFilter = (SimplePredicateChain) processContext.getFilter(); + else { + processFilter = new SimplePredicateChain(); + if (processContext.getFilter() != null) + processFilter.predicates.add(processContext.getFilter()); + processContext.setFilter(processFilter); + } + final Set previousFilters = new HashSet(processFilter.predicates); + + // Restore selected indicators. + for (final IndicatorSelection is : indicatorSelections) + is.selectedProperty.set(previousIndics.contains(is.indicator)); + + // Find activated years + for (final YearSelection ys : yearSelections) + ys.selectedProperty.set(previousYears.contains(ys.year)); + + // Set same filter selection + if (!previousFilters.isEmpty()) + for (final Predicate p : uiSelectionTable.getItems()) + filterSelection.computeIfAbsent(p, selectionComputer).set(previousFilters.contains(p)); + } + + /** + * + * @return The selected {@link Indicator}s. + */ + public Collection getIndicators() { + return indicatorSelections.stream() + .filter(is -> is.selectedProperty().get()) + .map(IndicatorSelection::getIndicator) + .collect(Collectors.toList()); + } + + //////////////////////////////////////////////////////////////////////////// + // indicator pane // indicator pane // indicator pane // indicator pane + + /** + * Init sub-pane for displaying indicators. + */ + private void initIndicatorPane(final List indicators){ + + for(int i=0; i years){ + for (final Integer year : years) { + final YearSelection yearSelection = new YearSelection(year); + yearSelections.add(yearSelection); + final CheckBox checkBox = new CheckBox(); + checkBox.setAllowIndeterminate(false); + final Label label = new Label(); + label.setText(year.toString()); + yearSelection.selectedProperty.bindBidirectional(checkBox.selectedProperty()); + uiYearPane.getChildren().add(new HBox(checkBox, label)); + } + } + + /** + * A simple class associating a selection boolean state to a year. + */ + private static class YearSelection extends Selection { + + private final int year; + + public YearSelection(final int year){ + this.year = year; + } + + public int getYear(){return year;} + } + + + //////////////////////////////////////////////////////////////////////////// + // trackingPoint pane // trackingPoint pane // trackingPoint pane + + /** + * Init sub-pane for displaying {@link TrackingPoint}s. + */ + private void initTrackingPointPane(){ + for (final FilterTableSpi spi : pointTableSpis) { + if (spi.getProtocol() == session.getDataContext().getProtocol()) { + uiSelectionTable = spi.createEmptyTable(); + break; + } + } + + if (uiSelectionTable == null) { + uiSelectionTable = new FXTrackingPointTable(session); + } + + uiSelectionTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + uiSelectionTable.getColumns().add(0, (TableColumn) uiSelectionColumn); + uiSelectionTable.setPrefSize(USE_COMPUTED_SIZE, USE_COMPUTED_SIZE); + + uiSelectionColumn.setCellValueFactory(param -> filterSelection.computeIfAbsent(param.getValue(), selectionComputer)); + uiSelectionColumn.setCellFactory(param -> { + final TableCell cell = new CheckBoxTableCell<>(); + cell.setEditable(true); + return cell; + }); + uiSelectionColumn.setEditable(true); + uiSelectionTable.setEditable(true); + uiSelectionTable.getSelectionModel().setSelectionMode(SelectionMode.SINGLE); + uiTrackingPointPane.setCenter(uiSelectionTable); + } + + /** + * Filter dataset tracking points according to current year selection, to set + * {@link #uiTrackingPointPane} content. If no year is selected, all points + * are activated. + */ + private void resetSelection() { + uiSelectionTable.getSelectionModel().clearSelection(); + final Set selectedYears = yearSelections.stream() + .filter(ys -> ys.selectedProperty.get()) + .map(ys -> ys.year) + .collect(Collectors.toSet()); + + if (selectedYears.isEmpty()) { + uiSelectionTable.setPreFilter((input) -> false); + } else if (selectedYears.size() == yearSelections.size()) { + uiSelectionTable.setPreFilter(null); + } else { + final Function yearChecker = tp -> selectedYears.contains(tp.getYear()); + final Predicate preFilter = st -> { + return dataset.findPoint(st) + .map(yearChecker) + .orElse(false); + }; + uiSelectionTable.setPreFilter(preFilter); + } + } + + private void tableContentChanged(final ListChangeListener.Change c) { + while (c.next()) { + if (c.wasRemoved()) { + for (final Predicate p : c.getRemoved()) { + filterSelection.computeIfAbsent(p, selectionComputer).set(false); + } + } + + if (c.wasAdded()) { + for (final Predicate p : c.getAddedSubList()) { + filterSelection.computeIfAbsent(p, selectionComputer).set(true); + } + } + } + } + + //////////////////////////////////////////////////////////////////////////// + // Utilities // Utilities // Utilities // Utilities // Utilities // + + /** + * Utility abstract class providing a selection boolean state. + */ + private static abstract class Selection { + protected final BooleanProperty selectedProperty = new SimpleBooleanProperty(this, "selection", false); + + public ReadOnlyBooleanProperty selectedProperty(){ + return selectedProperty; + } + } + + /** + * Update UI/related components when either year, indicator or filter + * selection change. + * + * @param obs Observable selection which change. For this method to actually + * do something, the given observable must be a {@link ReadOnlyProperty} + * with non-null {@link ReadOnlyProperty#getBean() } property. + * @param oldValue + * @param newValue + */ + private void selectionChanged(final ObservableValue obs, Boolean oldValue, Boolean newValue) { + final Object bean; + if (obs instanceof ReadOnlyProperty) { + bean = ((ReadOnlyProperty)obs).getBean(); + } else { + bean = null; + } + + if (bean instanceof YearSelection) { + // Synchronize tracking points state with corresponding year. + resetSelection(); + + } else if (bean instanceof IndicatorSelection) { + final Indicator i = ((IndicatorSelection)bean).getIndicator(); + if (Boolean.TRUE.equals(newValue)) { + processContext.getIndicators().add(i); + } else { + processContext.getIndicators().remove(i); + } + } else if (bean instanceof Predicate) { + if (Boolean.TRUE.equals(newValue)) { + processFilter.predicates.add((Predicate) bean); + } else { + processFilter.predicates.remove((Predicate) bean); + } + processContext.setFilter(null); + processContext.setFilter(processFilter); + } + } + + //////////////////////////////////////////////////////////////////////////// + // Process management // Process management // Process management // + + @FXML + void nextStep(ActionEvent event) { + final Computer computer = new Computer(); + globalTask.set(computer); + + computer.stateProperty().addListener(obs -> { + if (computer.isDone()) { + switch (computer.getState()) { + case FAILED: + Rhomeo.showAlert(Alert.AlertType.ERROR, getFormatedResourceString("process-failed")); + break; + case SUCCEEDED: + session.setResults(computer.getValue()); + globalTask.set(null); + session.requestWorkflowStep(WorkflowStep.RESULT); + break; + } + } + }); + + TaskManager.INSTANCE.submit(computer); + } + + @FXML + void cancelProcess(ActionEvent event) { + final Task> task = globalTask.get(); + if (task != null) + task.cancel(true); + } + + /** + * Wrap processes generated by requested indicators, execute them and wait + * for completion of the entire process set. + */ + private class Computer extends Task> { + + private final List processes = new ArrayList<>(); + + @Override + protected Set call() throws Exception { + updateProgress(-1, -1); + updateTitle(getResourceString("process.prepare")); + for (final Indicator indicator : getIndicators()) { + processes.addAll(indicator.createProcesses(processContext)); + } + + session.getAdditionalValues().clear(); + if (processes.size() < 1) { + throw new IllegalStateException("Nothing to process."); + + } else if (processes.size() == 1) { + final Process wrapped = processes.get(0); + Platform.runLater(() -> { + wrapped.titleProperty().addListener((obs) -> updateTitle(wrapped.getTitle())); + wrapped.messageProperty().addListener((obs) -> updateTitle(wrapped.getMessage())); + wrapped.workDoneProperty().addListener((obs) -> updateProgress(wrapped.getWorkDone(), wrapped.getTotalWork())); + }); + + wrapped.run(); + return (Set) wrapped.get(); + + } else { + /* + * Compute a maximal progress for this process aggregator. + * If any process has no total work defined, the aggregator total is + * the number of processes to execute. Otherwise, its the sum of all + * process to execute. + * + * The same is done for the "work done" property. If the aggregated + * total is undefined, the work done is the number of finished + * processes. Otherwise, it's the sum of work done of each process. + */ + final Observable[] totals = new Observable[processes.size()]; + final Observable[] worksDone = new Observable[processes.size()]; + for (int i = 0; i < processes.size(); i++) { + totals[i] = processes.get(i).totalWorkProperty(); + worksDone[i] = processes.get(i).workDoneProperty(); + } + + final DoubleBinding totalBinding = Bindings.createDoubleBinding(() -> { + double result = 0; + double processTotal; + for (final Process p : processes) { + processTotal = p.getTotalWork(); + if (processTotal < 0) { + return (double) totals.length; + } + result += processTotal; + } + + return result; + }, totals); + + final DoubleBinding workDoneBinding = Bindings.createDoubleBinding(() -> { + double result = 0; + double processWork; + final boolean doCount = totalBinding.get() < 0; + for (final Process p : processes) { + if (doCount) { + if (p.isDone()) + result++; + } else { + processWork = p.getWorkDone(); + if (processWork >= 0) { + result += processWork; + } + } + } + + return result; + }, worksDone); + + Platform.runLater(() -> { + workDoneBinding.addListener((obs) -> updateProgress(workDoneBinding.get(), totalBinding.get())); + }); + + final Set indices = new HashSet<>(); + updateTitle(getResourceString("process.go")); + + for (final Process p : processes) { + if (Thread.interrupted()) { + throw new InterruptedException(); + } + + TaskManager.INSTANCE.submit(p); + } + + for (final Process p : processes) { + if (Thread.interrupted()) { + throw new InterruptedException(); + } + + indices.addAll(p.get()); + } + + return indices; + } + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + for (final Process p : processes) { + p.cancel(true); + } + return super.cancel(mayInterruptIfRunning); + } + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/FXDefaultResultPane.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXDefaultResultPane.java new file mode 100644 index 0000000..38a48d5 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXDefaultResultPane.java @@ -0,0 +1,520 @@ +/** + * 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.fx; + +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.InternationalDescription; +import fr.cenra.rhomeo.api.InternationalResource; +import fr.cenra.rhomeo.api.data.Dataset; +import fr.cenra.rhomeo.api.data.Protocol; +import fr.cenra.rhomeo.api.data.TrackingPoint; +import fr.cenra.rhomeo.api.data.Warning; +import fr.cenra.rhomeo.api.process.Indicator; +import fr.cenra.rhomeo.api.result.AbstractParametrableIndex; +import fr.cenra.rhomeo.api.result.Index; +import fr.cenra.rhomeo.api.result.IndexMapper; +import fr.cenra.rhomeo.api.result.IndexSpi; +import fr.cenra.rhomeo.api.ui.AdditionalResultSpi; +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.WorkflowStep; +import fr.cenra.rhomeo.core.result.ResultWriter; +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.file.FileSystem; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.MissingResourceException; +import java.util.Set; +import java.util.logging.Level; +import javafx.application.Platform; + +import javafx.beans.binding.Bindings; +import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.property.SimpleObjectProperty; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.geometry.Pos; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.control.ToggleButton; +import javafx.scene.image.ImageView; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.VBox; +import javafx.stage.FileChooser; +import org.apache.sis.util.ArgumentChecks; +import org.geotoolkit.gui.javafx.util.TaskManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.validation.ConstraintViolation; +import javax.validation.Validator; + + +/** + * The result pane controller. + * + * @author Samuel Andrés (Geomatys) + * + */ +@Component("fr.cenra.rhomeo.fx.FXDefaultResultPane") +@Scope("prototype") +public class FXDefaultResultPane extends VBox implements InternationalResource { + + /** + * Key (or key-part) that must be used to retrieve specific headers from + * {@link IndexSpi} and or base classes implementing {@link InternationalResource}, + * to complementary table headers. + */ + public static final String COMPLEMENTARY_TABLE_HEADER_PROPERTY_KEY = "result-pane.complementary-table"; + + /** + * Fields taken into account to build columns mapping base classes into + * complementary tables. + */ + private static final List BASE_FIELDS = Arrays.asList("name", "year"); + + @FXML private Label uiSiteLbl; + @FXML private TableView> uiSitePane; + @FXML private GridPane uiInvalidateGridPane; + @FXML private TableColumn, Integer> uiSiteYearColumn; + @FXML private ToggleButton uiDisplayValuesToggleBtn; + @FXML private ScrollPane uiAdditionalValuesScrollPane; + @FXML private VBox uiAdditionalValuesBox; + @FXML private VBox uiTableBox; + + @FXML private Label uiYearsLbl; + @FXML private Label uiIndicatorLbl; + @FXML private Label uiDataStatusLbl; + @FXML private Label uiAdditionalLabel; + + @Autowired + private Session session; + + @Autowired + private Validator validator; + + @Autowired + private ResultWriter resultWriter; + + @Autowired + private List additionalSpis; + + private final SimpleBooleanProperty isInvalid = new SimpleBooleanProperty(false); + + /** + * + */ + public FXDefaultResultPane() { + Rhomeo.loadFXML(this, FXDefaultResultPane.class); + uiSitePane.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + uiSitePane.setFixedCellSize(25); + uiAdditionalLabel.visibleProperty().bind(Bindings.isNotEmpty(uiAdditionalValuesBox.getChildren())); + } + + /** + * Initializes JavaFX components after spring components are done loading. + */ + @PostConstruct + public void postConstruct() { + final Set results = session.getResults(); + ArgumentChecks.ensureNonNull("results", results); + + /* + 1- Schedule. + ==========*/ + + // Determine indicators and schedule results. + + final Map> mainResults = new HashMap<>(); + final ArrayList mainSpis = new ArrayList<>(); + final List indicators = new ArrayList<>(); + final Map> complementaryResults = new HashMap<>(); + final Map> byYearComplementary = new HashMap<>(); + final Map> indexSpis = new HashMap<>(); + for(final Index index : results){ + + // Seach for index indicators. + final Indicator indicator = index.getSpi().getIndicator(); + if(!indicators.contains(indicator)){ + indicators.add(indicator); + } + + // Detect main indices for each indicator. + if (index.getSpi().isPrimary()) { + final int year = index.getYear(); + final IndexMapper mapper = mainResults.computeIfAbsent(year, (input) -> new IndexMapper<>(input)); + if(!mainSpis.contains(index.getSpi())) + mainSpis.add(index.getSpi()); + mapper.setValue(index.getSpi().getName(), index.getValue()); + } + // Schedule AbstractParametrableIndexes by base type. + else if(index instanceof AbstractParametrableIndex) { + final AbstractParametrableIndex parametrableIndex = (AbstractParametrableIndex) index; + final Class baseClass = parametrableIndex.getBaseClass(); + final Object base = parametrableIndex.getBase(); + final IndexSpi indexSpi = parametrableIndex.getSpi(); + + if(complementaryResults.get(baseClass)==null){ + complementaryResults.put(baseClass, new HashMap<>()); + } + if(complementaryResults.get(baseClass).get(base)==null){ + complementaryResults.get(baseClass).put(base, new IndexMapper<>(base)); + } + final IndexMapper indexMapper = complementaryResults.get(baseClass).get(base); + indexMapper.setValue(indexSpi.getName(), parametrableIndex.getValue()); + + // + if(indexSpis.get(baseClass)==null) indexSpis.put(baseClass, new ArrayList<>()); + final List spis = indexSpis.get(baseClass); + if(!spis.contains(indexSpi)) spis.add(indexSpi); + + } else { + final int year = index.getYear(); + final IndexMapper mapper = byYearComplementary.computeIfAbsent(year, (input) -> new IndexMapper<>(input)); + final List spis = indexSpis.computeIfAbsent(Integer.class, i -> new ArrayList<>()); + if(!spis.contains(index.getSpi())) spis.add(index.getSpi()); + mapper.setValue(index.getSpi().getName(), index.getValue()); + } + } + + // Sort indicators. + Collections.sort(indicators); + + /* + 2- Main indicators. + =================*/ + + // Build header message listing indicators + final StringBuilder sbIndicator = new StringBuilder(); + sbIndicator.append("Indicateur(s) : "); + + final Protocol currentProtocol = session.getDataContext().getProtocol(); + boolean firstIndic = true; + for(final Indicator indicator : indicators){ + if (!firstIndic) { + sbIndicator.append(", "); + } + + sbIndicator.append(indicator.getName()).append(" - ").append(indicator.getRemarks()); + firstIndic = false; + } + sbIndicator.append(" - ").append(currentProtocol.getRemarks()); + + // Create columns for main indicator pane. + uiSiteYearColumn.setCellValueFactory(value -> value.getValue().keyProperty()); + mainSpis.stream().sorted().forEach(spi -> { + // Sometimes the displayed column name seems to be from the indexSpi itself, sometimes from its indicator (i.e. a specific name) + final TableColumn, Number> column = new TableColumn<>(getIndexSpiColumnName(spi)); + column.setCellFactory(Rhomeo.ROUNDING_CELL_FACTORY); + column.setCellValueFactory(value -> value.getValue().valueProperty(spi.getName())); + uiSitePane.getColumns().add(column); + }); + uiSitePane.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + + // Feed main indicator pane. + final ObservableList> items = FXCollections.observableArrayList(mainResults.values()); + uiSitePane.setItems(items); + uiSitePane.prefHeightProperty().bind(Bindings.size(items).multiply(uiSitePane.fixedCellSizeProperty()).add(40)); + + // Summary + uiYearsLbl.setGraphic(new ImageView(Rhomeo.ICON_CIRCLE_GRAY)); + final StringBuilder sbYears = new StringBuilder(); + sbYears.append("Année(s) : "); + boolean firstYear = true; + final List years = new ArrayList<>(mainResults.keySet()); + Collections.sort(years); + for (final Integer year : years) { + if (!firstYear) { + sbYears.append(", "); + } + sbYears.append(year); + firstYear = false; + } + uiYearsLbl.setText(sbYears.toString()); + + uiIndicatorLbl.setGraphic(new ImageView(Rhomeo.ICON_CIRCLE_GRAY)); + uiIndicatorLbl.setText(sbIndicator.toString()); + + isInvalid.addListener((obj) -> { + if (!isInvalid.get()) { + uiDataStatusLbl.setGraphic(new ImageView(Rhomeo.ICON_CHECK_GREEN)); + uiDataStatusLbl.setText("Les données sont conformes au protocole : "+ currentProtocol.getRemarks()); + } else { + uiDataStatusLbl.setGraphic(new ImageView(Rhomeo.ICON_TIMES_RED)); + uiDataStatusLbl.setText("Les données ne sont pas conformes au protocole : "+ currentProtocol.getRemarks()); + } + }); + isInvalid.set(true); + + uiInvalidateGridPane.visibleProperty().bind(isInvalid); + uiInvalidateGridPane.managedProperty().bind(uiInvalidateGridPane.visibleProperty()); + + uiTableBox.visibleProperty().bind(isInvalid.not().or(uiDisplayValuesToggleBtn.selectedProperty())); + uiTableBox.managedProperty().bindBidirectional(uiSiteLbl.visibleProperty()); + + // Verify validation. + validate(); + + /* + 3- Other indicators. + ==================*/ + + // A table for complementary results displayed by year. + if (!byYearComplementary.isEmpty()) { + final TableView> table = new TableView<>(FXCollections.observableArrayList(byYearComplementary.values())); + final TableColumn, Integer> yearColumn = new TableColumn("Année"); + yearColumn.setCellValueFactory(input -> input.getValue() == null ? null : input.getValue().keyProperty()); + table.getColumns().add(yearColumn); + // index value columns + indexSpis.get(Integer.class).stream().sorted().forEach(spi -> { + // Sometimes the displayed column name seems to be from the indexSpi itself, sometimes from its indicator (i.e. a specific name) + final TableColumn, Number> column = new TableColumn<>(getIndexSpiColumnName(spi)); + column.setCellFactory(Rhomeo.ROUNDING_CELL_FACTORY); + column.setCellValueFactory(value -> value.getValue().valueProperty(spi.getName())); + table.getColumns().add(column); + }); + table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + uiAdditionalValuesBox.getChildren().add(table); + } + + // Create one TableView by base class. + for(final Class baseClass : complementaryResults.keySet()){ + try { + final TableView tableView = buildIndexMapperTableView(baseClass, indexSpis.get(baseClass)); + final ObservableList additionalItems = FXCollections.observableArrayList(complementaryResults.get(baseClass).values()); + tableView.setItems(additionalItems); + tableView.setFixedCellSize(25); + tableView.setMinHeight(70); + tableView.setMaxHeight(300); + tableView.prefHeightProperty().bind(Bindings.size(additionalItems).multiply(tableView.fixedCellSizeProperty()).add(40)); + uiAdditionalValuesBox.getChildren().add(tableView); + } catch (IntrospectionException ex) { + RhomeoCore.LOGGER.log(Level.WARNING, "Could not create tableview mapping {0}.", baseClass); + } + } + + final Button nextStepButton = new Button(getResourceString("proceed")); + nextStepButton.getStyleClass().add("contrast"); + nextStepButton.setOnAction(value -> { + session.requestWorkflowStep(WorkflowStep.FINALIZATION); + }); + nextStepButton.visibleProperty().bind(isInvalid.not()); + nextStepButton.managedProperty().bind(nextStepButton.visibleProperty()); + final HBox bottomHBox = new HBox(nextStepButton); + bottomHBox.setAlignment(Pos.CENTER_RIGHT); + bottomHBox.setFillHeight(true); + bottomHBox.setPrefSize(USE_PREF_SIZE, USE_PREF_SIZE); + getChildren().add(bottomHBox); + + for (AdditionalResultSpi spi : additionalSpis) { + spi.getResultNode(session.getAdditionalValues()).ifPresent(node -> uiAdditionalValuesBox.getChildren().add(node)); + } + } + + /** + * Verify dataset validation. + */ + private void validate() { + final Runnable taskInit = () -> TaskManager.INSTANCE.submit("Validation du lot de données", () -> { + final Set> violations = validator.validate(session.getProcessContext().getData()); + final Iterator> it = violations.iterator(); + while (it.hasNext()) { + if (!it.next().getConstraintDescriptor().getPayload().contains(Warning.class)) { + return true; + } + } + + return false; + + }).setOnSucceeded(evt -> Platform.runLater(() -> isInvalid.set((boolean)evt.getSource().getValue()))); + if (Platform.isFxApplicationThread()) + taskInit.run(); + else Platform.runLater(taskInit); + } + + @FXML + public void exportData() { + final String initialFileName = session.getDataContext().getSite().getName().concat(".zip"); + final FileChooser.ExtensionFilter zipFilter = new FileChooser.ExtensionFilter("Archive zip", "*.zip"); + final File outputFile = Rhomeo.askOutputFilePopup(initialFileName, this, zipFilter); + if (outputFile == null) { + return; + } + + TaskManager.INSTANCE.submit("Export de résultats", () -> { + try (final FileSystem fs = RhomeoCore.toZipFileSystem(outputFile.toPath())) { + resultWriter.prepareWriting(fs.getRootDirectories().iterator().next()).writeMetadataText().writeResults().writeAdditionalValues(); + } + return true; + }); + } + + /** + * Builds a complementary table for indexes associated to a given base class (for instance {@link TrackingPoint}). + * + * This method use introspection on the given class, but it only displays information from fields which name + * are specified in {@link FXDefaultResultPane#BASE_FIELDS}. + * + * @param + * @param baseClass + * @return + * + * @throws IntrospectionException + */ + private TableView> buildIndexMapperTableView(final Class baseClass, final List indexSpis) throws IntrospectionException { + + final BeanInfo beanInfo = Introspector.getBeanInfo(baseClass); + + final TableView> tableView = new TableView<>(); + tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + + // Index base columns + for (final PropertyDescriptor desc : beanInfo.getPropertyDescriptors()) { + + final String dName = desc.getName(); + if(BASE_FIELDS.contains(dName)){ + + final TableColumn, ?> col = new TableColumn<>(getBaseColumnName(baseClass, dName)); + col.setCellValueFactory(value -> { + try { + final Method reader = desc.getReadMethod(); + if(reader!=null && value!=null && value.getValue()!=null && value.getValue() instanceof IndexMapper){ + final T target = ((IndexMapper) value.getValue()).getKey(); + if(target!=null){ + return new SimpleObjectProperty(reader.invoke(target)); + } + else return null; + } + else return null; + } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException ex) { + RhomeoCore.LOGGER.log(Level.INFO, "Unable to build CellValueFactory for property {0}.", dName); + return null; + } + }); + tableView.getColumns().add(col); + } + } + + // index value columns + indexSpis.stream().sorted().forEach(spi -> { + // Sometimes the displayed column name seems to be from the indexSpi itself, sometimes from its indicator (i.e. a specific name) + final TableColumn, Number> column = new TableColumn<>(getIndexSpiColumnName(spi)); + column.setCellValueFactory(value -> value.getValue().valueProperty(spi.getName())); + column.setCellFactory(Rhomeo.ROUNDING_CELL_FACTORY); + tableView.getColumns().add(column); + }); + + return tableView; + } + + /** + * Builds a name for the column mapping a given base class field in a complementary table. + * + * @param baseClass + * @param propertyName + * @return + */ + private static String getBaseColumnName(final Class baseClass, final String propertyName){ + + // If indexSpi implements InternationalResource, try to use specific property + if(InternationalResource.class.isAssignableFrom(baseClass)){ + + // 1- Try to retrieve some resource specific to a complementary result table. + try{ + return InternationalResource.getResourceString(baseClass, propertyName, COMPLEMENTARY_TABLE_HEADER_PROPERTY_KEY); + } + catch(MissingResourceException ex1){ + + // 2- Try to retrive resource mapping the property name. + try{ + return InternationalResource.getResourceString(baseClass, propertyName); + } + catch(MissingResourceException ex2){ + RhomeoCore.LOGGER.log(Level.FINEST, "Missing ressource to display column name from {0}", InternationalResource.class.getSimpleName()); + } + } + } + + // If no better can be done, return the property name. + return propertyName; + } + + /** + * Builds a name for the column mapping a given {@link IndexSpi} in a complementary table. + * + * @param indexSpi + * @return + */ + private static String getIndexSpiColumnName(final IndexSpi indexSpi){ + + // If indexSpi implements InternationalResource, try to use specific property + if(indexSpi instanceof InternationalResource){ + try{ + return ((InternationalResource) indexSpi).getResourceString(COMPLEMENTARY_TABLE_HEADER_PROPERTY_KEY); + } + catch(MissingResourceException e){ + RhomeoCore.LOGGER.log(Level.FINEST, "Missing ressource to display column name from {0}", InternationalResource.class.getSimpleName()); + } + } + + // If previous try failed and indexSpi implements InternationalDescription, use InternationalDescription label. + if(indexSpi instanceof InternationalDescription) return ((InternationalDescription) indexSpi).getLabel(); + + // If no other solution is found, return indexSpi name. + return indexSpi.getTitle(); + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/FXFinalizationPane.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXFinalizationPane.java new file mode 100644 index 0000000..0445b3b --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXFinalizationPane.java @@ -0,0 +1,248 @@ +/** + * 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.fx; + +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.InternationalResource; +import fr.cenra.rhomeo.api.data.DataContext; +import fr.cenra.rhomeo.api.result.DashboardResultItem; +import fr.cenra.rhomeo.api.result.Index; +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.data.DashboardResultsManager; +import fr.cenra.rhomeo.core.result.ResultStorage; +import fr.cenra.rhomeo.core.result.ResultWriter; +import javafx.concurrent.Task; +import javafx.fxml.FXML; +import javafx.scene.control.Alert; +import javafx.scene.control.Button; +import javafx.scene.control.ButtonType; +import javafx.scene.layout.VBox; +import javafx.stage.FileChooser; +import org.geotoolkit.gui.javafx.util.TaskManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.io.File; +import java.nio.file.FileSystem; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import javafx.application.Platform; +import javafx.beans.property.BooleanProperty; +import javafx.beans.property.SimpleBooleanProperty; + +import javafx.event.ActionEvent; + + +/** + * @author Cédric Briançon (Geomatys) + */ +@Component("fr.cenra.rhomeo.fx.FXFinalizationPane") +@Scope("prototype") +public class FXFinalizationPane extends VBox implements InternationalResource { + @FXML + private Button addToDashboardBtn; + + @FXML + private Button publishBtn; + + @Autowired + private Session session; + + @Autowired + private DashboardResultsManager resultsManager; + + @Autowired + private ResultWriter resultWriter; + + @Autowired + private ResultStorage resultStorage; + + /** + * Stores if the results has been published or not. + */ + private final BooleanProperty publishedProperty = new SimpleBooleanProperty(false); + + /** + * Set to true once current results are attached to dashboard. + */ + private final BooleanProperty onDashboardProperty = new SimpleBooleanProperty(false); + + public FXFinalizationPane() { + Rhomeo.loadFXML(this, FXFinalizationPane.class); + } + + /** + * Get back to the dashboard to start a new entry of results. + */ + @FXML + private void newForm() { + session.requestWorkflowStep(null); + } + + @FXML + private void exportResults() { + final String initialFileName = new StringBuilder(session.getDataContext().getSite().getName()) + .append('_').append(session.getDataContext().getProtocol().getName()).append(".zip") + .toString(); + + final FileChooser.ExtensionFilter zipFilter = new FileChooser.ExtensionFilter("Archive zip", "*.zip"); + final File outputFile = Rhomeo.askOutputFilePopup(initialFileName, this, zipFilter); + if (outputFile == null) { + return; + } + + TaskManager.INSTANCE.submit("Export de résultats", () -> { + final Path outputPath = outputFile.toPath(); + Files.deleteIfExists(outputPath); + try (final FileSystem fs = RhomeoCore.toZipFileSystem(outputPath)) { + resultWriter.prepareWriting(fs.getRootDirectories().iterator().next()) + .writeMetadataText() + .writeResults() + .writeAdditionalValues(); + } + return true; + }); + } + + /** + * Add current results to the dashboard for the current site / protocol. + */ + @FXML + private void addToDashboard() { + final Alert alert = new Alert(Alert.AlertType.CONFIRMATION, + getFormatedResourceString("alert-add-to-dashboard"), + ButtonType.YES, ButtonType.NO); + alert.setResizable(true); + final ButtonType res = alert.showAndWait().get(); + if (res == ButtonType.YES) { + final TaskManager.MockTask task = new TaskManager.MockTask("Sauvegarde des résultats", () -> { + resultStorage.store(); + resultsManager.addDashboardResultsItems(getResults()); + return true; + }); + + addToDashboardBtn.disableProperty().bind(task.runningProperty()); + + task.setOnSucceeded(evt -> Platform.runLater(() -> { + addToDashboardBtn.disableProperty().unbind(); + addToDashboardBtn.setDisable(true); + onDashboardProperty.set(true); + })); + + TaskManager.INSTANCE.submit(task); + } + } + + /** + * Get current results. + * + * @return + */ + private List getResults() { + final List items = new ArrayList<>(); + + final Set results = session.getResults(); + if (results != null && !results.isEmpty()) { + final DataContext context = session.getDataContext(); + results.forEach(result -> { + if (result.getSpi().getName().equals(result.getSpi().getIndicator().getDefaultIndex())) { + // Do not keep tracking point index, just results for a year. + items.add(new DashboardResultItem(result.getYear(), context.getSite().getName(), + result.getSpi().getIndicator().getName(), result.getValue() == null ? null : result.getValue().doubleValue(), + publishedProperty.get())); + } + }); + } + + return items; + } + + @FXML + private void publishResults(final ActionEvent evt) { + final List results = getResults(); + final Task publish = publishSiteResults(); + publishBtn.disableProperty().bind(publish.runningProperty()); + publish.setOnSucceeded(event -> Platform.runLater(() -> { + publishedProperty.set(true); + publishBtn.disableProperty().unbind(); + publishBtn.setDisable(true); + if (onDashboardProperty.get()) { + TaskManager.INSTANCE.submit("Mise à jour des résultats locaux", () -> { + for (final DashboardResultItem item : results) + item.setPublished(true); + resultsManager.updateResults(results); + return true; + }); + } + })); + + publish.setOnFailed(event -> Platform.runLater(() -> Rhomeo.showAlert(Alert.AlertType.ERROR, "La publication des résultats a échouée !"))); + + TaskManager.INSTANCE.submit(publish); + } + + /** + * Publish site results on the FTP. + * Structure on the FTP is: + *
+     * results
+     * |- county code
+     * |--|- SHA1 geometry site
+     * |--|--|- protocol
+     * |--|--|--|- UUID
+     * |--|--|--|--|- site.geojson
+     * |--|--|--|--|- metadata.json
+     * |--|--|--|--|- result.csv
+     * ...
+     * 
+ * + * @return Publication task + */ + private Task publishSiteResults() { + return new TaskManager.MockTask<>("Publication de résultats", () -> { + resultsManager.publishResults(); + return true; + }); + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/FXFullSpecificResultPane.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXFullSpecificResultPane.java new file mode 100644 index 0000000..90c8831 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXFullSpecificResultPane.java @@ -0,0 +1,266 @@ +/** + * 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.fx; + +import fr.cenra.rhomeo.api.process.Indicator; +import fr.cenra.rhomeo.api.result.DashboardResultItem; +import fr.cenra.rhomeo.api.result.Index; +import fr.cenra.rhomeo.api.result.IndicatorValuesByYearItem; +import fr.cenra.rhomeo.core.CSVDecoder; +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.result.ResultStorage; +import fr.cenra.rhomeo.core.result.SimpleLocationIndex; +import fr.cenra.rhomeo.core.result.SimpleYearIndex; +import java.beans.IntrospectionException; +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Optional; +import javafx.beans.binding.Bindings; +import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.value.ObservableValue; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.geometry.Insets; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.layout.VBox; +import javax.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +/** + * UI to display detailed information about all computed information for a given + * year and {@link Indicator}. This includes the value of the main indicator + * {@link Index} and the potential ones. + * + * @author Samuel Andrés (Geomatys) + */ +@Component("fr.cenra.rhomeo.fx.FXFullSpecificResultPane") +@Lazy +@Scope("prototype") +public class FXFullSpecificResultPane extends VBox { + + private final IndicatorValuesByYearItem selectedItem; + + private final Indicator indicator; + + private final String siteName; + + @Autowired + private ResultStorage resultStorage; + + public FXFullSpecificResultPane(final IndicatorValuesByYearItem selectedItem, final Indicator indicator, final String siteName) throws IOException, IntrospectionException, InstantiationException, IllegalAccessException { + this.selectedItem = selectedItem; + this.indicator = indicator; + this.siteName = siteName; + setPadding(new Insets(10.)); + setSpacing(10.); + setPrefSize(USE_COMPUTED_SIZE, USE_COMPUTED_SIZE); + } + + @PostConstruct + private void postConstruct() throws IOException, IntrospectionException, InstantiationException, IllegalAccessException { + final String indicatorName = indicator.getName(); + final IndicatorValuesByYearItem.PublishedValue pub = selectedItem.getValueForIndicator(indicatorName); + + if (pub != null) { + final DashboardResultItem dItem = new DashboardResultItem(selectedItem.getYear(), siteName, indicatorName, pub.getValue(), pub.isPublished()); + final ArrayList result = new ArrayList<>(); + final Optional mainResults = resultStorage.getMainResults(dItem); + if (mainResults.isPresent()) { + result.addAll((List) readResult(mainResults.get())); + } + + final Optional otherResults = resultStorage.getAdditionalResults(dItem); + if (otherResults.isPresent()) { + result.addAll((List) readResult(otherResults.get())); + } + + buildTables(result); + } + } + + /** + * Create the table view containing the result value list mapping their class. + * + * @param result + * @throws IntrospectionException + */ + private void buildTables(List result) throws IntrospectionException { + final List locValues = new ArrayList<>(); + final Iterator it = result.iterator(); + SimpleYearIndex current; + while (it.hasNext()) { + current = it.next(); + if (current instanceof SimpleLocationIndex) { + locValues.add((SimpleLocationIndex) current); + it.remove(); + } + } + + if (!result.isEmpty()) { + final TableView table = buildSimpleTableView(FXCollections.observableList((List)result)); + getChildren().add(table); + } + + if (!locValues.isEmpty()) { + final TableView table = buildLocationTableView(FXCollections.observableList(locValues)); + getChildren().add(table); + } + } + + /** + * Builds a {@link TableView} for tuples indexed by year. + * + * @param tuples + * @return + * @throws IntrospectionException + * @see SimpleYearIndex + */ + private TableView buildSimpleTableView(ObservableList values) throws IntrospectionException { + final TableView table = new TableView<>(); + addCommonColumns(table); + table.setItems(values); + initResizePolicy(table); + return table; + } + + /** + * Configure input table resize strategy, by setting preferred height + * property to follow table item number. + * + * @param table The modified table. + */ + private void initResizePolicy(final TableView table) { + table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + table.setMinHeight(50); + table.setFixedCellSize(30); + table.prefHeightProperty().bind(Bindings.createDoubleBinding(() -> table.getFixedCellSize() * table.getItems().size() + 30, table.getItems(), table.fixedCellSizeProperty())); + } + + private void addCommonColumns(final TableView table) { + final TableColumn titleColumn = new TableColumn<>("Nom"); + titleColumn.setEditable(false); + titleColumn.setCellValueFactory(FXFullSpecificResultPane::getTitle); + + final TableColumn valueColumn = new TableColumn<>("Valeur"); + valueColumn.setEditable(false); + valueColumn.setCellFactory(RhomeoCore.ROUNDING_CELL_FACTORY); + valueColumn.setCellValueFactory(FXFullSpecificResultPane::getValue); + + table.getColumns().add((TableColumn)titleColumn); + table.getColumns().add((TableColumn)valueColumn); + } + + /** + * Builds a {@link TableView} for tuples indexed by year and location. + * + * @param tuples + * @return + * @throws IntrospectionException + * @see SimpleLocationIndex + */ + private TableView buildLocationTableView(ObservableList values) throws IntrospectionException { + final TableView table = new TableView<>(); + addCommonColumns(table); + + final TableColumn locColumn = new TableColumn<>(); + if (indicator.getProtocol().getName().equalsIgnoreCase("P04")) + locColumn.setText("Habitat"); + else + locColumn.setText("Point de suivi"); + locColumn.setCellValueFactory(FXFullSpecificResultPane::getLocation); + + table.getColumns().add(1, locColumn); + + table.setItems(values); + initResizePolicy(table); + return table; + } + + /** + * Get the results stored in the file which path is given as a parameter. + * + * The results are retrieved as a list of either instances of {@link SimpleLocationIndex} + * or instances of {@link SimpleYearIndex}. The method returns an entry which + * the value it the list of results, and the key is the instances' class. + * + * @param resultsPath + * @return + * @throws IOException + * @throws IntrospectionException + * @throws InstantiationException + * @throws IllegalAccessException + */ + private static List readResult(final Path resultsPath) throws IOException, IntrospectionException, InstantiationException, IllegalAccessException { + try { + return new CSVDecoder(resultsPath, SimpleLocationIndex.class).decode(); + } catch (Exception ex) { + RhomeoCore.LOGGER.info("Impossible de lire en tant que résultat localisé. Essai de lecture en résultat non localisé."); + return new CSVDecoder(resultsPath, SimpleYearIndex.class).decode(); + } + } + + private static ObservableValue getTitle(final TableColumn.CellDataFeatures cdf) { + final SimpleYearIndex index = cdf.getValue(); + if (index == null) + return null; + return new SimpleStringProperty(index.getName()); + } + + private static ObservableValue getValue(final TableColumn.CellDataFeatures cdf) { + final SimpleYearIndex index = cdf.getValue(); + if (index == null) + return null; + return new SimpleObjectProperty<>(index.getValue()); + } + + private static ObservableValue getLocation(final TableColumn.CellDataFeatures cdf) { + final SimpleLocationIndex index = cdf.getValue(); + if (index == null) + return null; + return new SimpleStringProperty(index.getLocation()); + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/FXInitialDialogPane.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXInitialDialogPane.java new file mode 100644 index 0000000..b754512 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXInitialDialogPane.java @@ -0,0 +1,127 @@ +/** + * 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.fx; + +import fr.cenra.rhomeo.Rhomeo; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.prefs.Preferences; +import javafx.application.Platform; +import javafx.fxml.FXML; +import javafx.scene.control.Button; +import javafx.scene.control.CheckBox; +import javafx.scene.control.Hyperlink; +import javafx.scene.control.Label; +import javafx.scene.image.ImageView; +import javafx.scene.layout.BorderPane; +import javafx.stage.Stage; +import org.geotoolkit.gui.javafx.util.TaskManager; + +/** + * Panel for the initial dialog when opening the application. + * + * @author Cédric Briançon (Geomatys) + */ +public class FXInitialDialogPane extends BorderPane { + + public static final String DISPLAY_RULE_KEY = "display_disclaimer_on_startup"; + + @FXML + private Label uiVersion; + + @FXML + private ImageView uiWarning; + + @FXML + private CheckBox displayOnStartup; + + @FXML + private Hyperlink uiEMail; + + @FXML + private Hyperlink uiHref; + + @FXML + private Button uiClose; + + private final Preferences displayPref; + + public FXInitialDialogPane() { + Rhomeo.loadFXML(this, FXInitialDialogPane.class); + displayPref = Preferences.userNodeForPackage(FXInitialDialogPane.class); + displayOnStartup.setSelected(!displayPref.getBoolean(DISPLAY_RULE_KEY, true)); + displayOnStartup.selectedProperty().addListener((obs, oldValue, newValue) -> { + displayPref.putBoolean(DISPLAY_RULE_KEY, !newValue); + }); + + uiWarning.setImage(Rhomeo.ICON_WARNING_ORANGE); + + uiEMail.setOnAction(evt -> Rhomeo.mail(uiEMail.getText())); + uiHref.setOnAction(evt -> { + try { + Rhomeo.browse(new URL(uiHref.getText())); + } catch (final MalformedURLException e) { + // mimic task failure + TaskManager.INSTANCE.submit("Ouverture d'un lien", () -> { + if (e != null) + throw e; + else + return false; + }); + } + }); + + final String version = Rhomeo.getVersion(); + if (version == null || version.isEmpty()) + uiVersion.setText("Version de développement"); + else + uiVersion.setText("Version ".concat(version)); + + Platform.runLater(() -> uiClose.requestFocus()); + } + + /** + * Close the dialog box when clicking on the accept button. + */ + @FXML + private void accept() { + final Stage stage = (Stage) this.getScene().getWindow(); + stage.close(); + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/FXMainPane.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXMainPane.java new file mode 100644 index 0000000..7a29d00 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXMainPane.java @@ -0,0 +1,158 @@ +/** + * 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.fx; + +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.InternationalResource; +import fr.cenra.rhomeo.core.Session; +import javafx.fxml.FXML; +import javafx.scene.Scene; +import javafx.scene.control.MenuButton; +import javafx.scene.image.ImageView; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.HBox; +import javafx.stage.Modality; +import javafx.stage.Stage; +import org.geotoolkit.gui.javafx.util.ProgressMonitor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import org.geotoolkit.gui.javafx.util.TaskManager; + +/** + * Main application panel. + * + * @author Cédric Briançon (Geomatys) + */ +@Component +public class FXMainPane extends BorderPane implements InternationalResource { + + @FXML + private MenuButton uiMenuButton; + + @Autowired + private FXRhomeoWizard wizard; + + @Autowired + private Session session; + + public FXMainPane() { + Rhomeo.loadFXML(this, FXMainPane.class); + initProgressMonitor(); + + uiMenuButton.setGraphic(new ImageView(Rhomeo.ICON_BARS_WHITE)); + uiMenuButton.setFocusTraversable(false); + } + + /** + * Initializes JavaFX components after spring components are done loading. + */ + @PostConstruct + private void postConstruct() { + setCenter(wizard); + } + + /** + * Inserts the {@link ProgressMonitor} before the main menu button. + * HACK : Add an item in progress monitor list, allowing to clear list of + * tasks in error. + */ + private void initProgressMonitor() { + final ProgressMonitor progressMonitor = new ProgressMonitor(TaskManager.INSTANCE); + progressMonitor.getStylesheets().add(FXDashboardPane.class.getResource("/fr/cenra/rhomeo/ProgressMonitor.css").toString()); + + final HBox parent = ((HBox) uiMenuButton.getParent()); + parent.getChildren().add(parent.getChildren().size()-1, progressMonitor); + } + + /** + * Open preferences window. + */ + @FXML + private void showPreferences() { + final Stage prefStage = Rhomeo.newStage(); + prefStage.setTitle(getResourceString("preferences")); + prefStage.initModality(Modality.APPLICATION_MODAL); + final Scene scene = new Scene(session.createPrototype(FXRhomeoPreferencePane.class)); + prefStage.setScene(scene); + prefStage.setMinWidth(530); + prefStage.setMinHeight(230); + prefStage.show(); + prefStage.requestFocus(); + } + + /** + * Open references documents page. + */ + @FXML + private void showRefDocuments() { + final Stage prefStage = Rhomeo.newStage(); + prefStage.setTitle(getResourceString("ref-docs")); + prefStage.initModality(Modality.APPLICATION_MODAL); + final Scene scene = new Scene(session.createPrototype(FXRhomeoReferencePane.class)); + scene.getStylesheets().add(Rhomeo.CSS_THEME_PATH); + prefStage.setScene(scene); + prefStage.setMinWidth(800); + prefStage.setMinHeight(600); + prefStage.show(); + prefStage.requestFocus(); + } + + /** + * Open the about dialog. + */ + @FXML + private void showAboutDialog() { + final Stage popup = Rhomeo.createWelcomePopup(); + popup.initOwner(this.getScene().getWindow()); + + popup.show(); + popup.requestFocus(); + } + + /** + * Quit the application. + */ + @FXML + private void quit() { + session.close(); + System.exit(0); + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/FXProtocolReferencesPane.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXProtocolReferencesPane.java new file mode 100644 index 0000000..ecd8a51 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXProtocolReferencesPane.java @@ -0,0 +1,273 @@ +/** + * 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.fx; + +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.Version; +import fr.cenra.rhomeo.api.data.DataContext; +import fr.cenra.rhomeo.api.data.Reference; +import fr.cenra.rhomeo.api.data.ReferenceDescription; +import fr.cenra.rhomeo.core.RhomeoRuntimeException; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.data.ReferenceManager; +import javafx.beans.property.BooleanProperty; +import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.value.ObservableValue; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.concurrent.Task; +import javafx.fxml.FXML; +import javafx.geometry.Pos; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.RadioButton; +import javafx.scene.control.TableCell; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.control.ToggleGroup; +import javafx.scene.image.ImageView; +import javafx.scene.layout.BorderPane; +import org.geotoolkit.gui.javafx.util.FXTableView; +import org.geotoolkit.gui.javafx.util.TaskManager; + +import java.beans.IntrospectionException; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +/** + * Handle available versions for a reference. + * + * @param the reference to display available versions. + * @author Cédric Briançon (Geomatys) + */ +public class FXProtocolReferencesPane extends BorderPane { + @FXML + private Label uiRefNameLbl; + + private final FXTableView referencesTable; + + private final ReferenceDescription description; + + private static final String CSS_BUTTON_CLASS = "install-button"; + + public FXProtocolReferencesPane(final ReferenceDescription description) throws IntrospectionException { + this.description = description; + + Rhomeo.loadFXML(this); + uiRefNameLbl.setText("Référentiel "+ description.getTitle()); + + referencesTable = new FXTableView<>(); + referencesTable.setEditable(true); + referencesTable.setMinHeight(90); + referencesTable.setPrefHeight(getMinHeight()); + referencesTable.setMaxHeight(280); + referencesTable.setFixedCellSize(25); + + final TableColumn availableCol = new TableColumn<>("Versions disponibles"); + availableCol.setCellValueFactory(value -> new SimpleStringProperty(String.valueOf(value.getValue().getVersion()))); + referencesTable.getColumns().add(availableCol); + referencesTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + + final TableColumn installedCol = new TableColumn<>("Installées"); + installedCol.setCellValueFactory(value -> value.getValue().installedProperty); + installedCol.setCellFactory(param -> + new TableCell() { + @Override + protected void updateItem(Boolean item, boolean empty) { + setText(null); + setGraphic(null); + setAlignment(Pos.CENTER); + if (item != null && !item) { + final Button installBtn = new Button("Installer"); + installBtn.getStyleClass().add(CSS_BUTTON_CLASS); + installBtn.setOnAction(event -> { + final ReferenceManager referenceManager; + try { + referenceManager = ReferenceManager.getOrCreate(description); + } catch (IntrospectionException ex) { + throw new RhomeoRuntimeException(ex); + } + + final Task installTask = referenceManager.install(((ReferenceLineItem)getTableRow().getItem()).getVersion()); + installTask.setOnSucceeded(success -> { + ((ReferenceLineItem)getTableRow().getItem()).setInstalled(true); + }); + installBtn.disableProperty().bind(installTask.runningProperty()); + TaskManager.INSTANCE.submit(installTask); + }); + setGraphic(installBtn); + } else if (!empty && item != null){ + setGraphic(new ImageView(Rhomeo.ICON_CHECK_GREEN)); + } + } + } + ); + referencesTable.getColumns().add(installedCol); + + final TableColumn selectedCol = new TableColumn<>("Sélectionnées"); + selectedCol.setCellValueFactory(value -> value.getValue().selectedProperty); + final ToggleGroup group = new ToggleGroup(); + selectedCol.setCellFactory(param -> new RadioButtonTableCell(group)); + selectedCol.setEditable(true); + referencesTable.getColumns().add(selectedCol); + + final DataContext dc = Session.getInstance().getDataContext(); + final ReferenceManager referenceManager = ReferenceManager.getOrCreate(description); + + final Set installedVersions = referenceManager.getInstalledVersions(); + final Set distantVersions = referenceManager.getDistantVersions(); + final HashSet allVersions = new HashSet<>(installedVersions); + allVersions.addAll(distantVersions); + + final Version selectedVersion = dc.getReferences().get(description.getReferenceType()); + final ObservableList items = FXCollections.observableArrayList(); + for (final Version ver : allVersions) { + items.add(new ReferenceLineItem(ver, installedVersions.contains(ver), ver.equals(selectedVersion))); + } + Collections.sort(items); + referencesTable.setItems(FXCollections.observableList(items)); + referencesTable.setPrefHeight((items.size() + 1) * referencesTable.getFixedCellSize()); + + setCenter(referencesTable); + } + + public ObservableList getItems() { + return referencesTable.itemsProperty().get(); + } + + public Class getReferenceClass() { + return description.getReferenceType(); + } + + private class RadioButtonTableCell extends TableCell { + private RadioButton radioButton; + private BooleanProperty selProperty; + + /** + * Cell containing a radio button in the given group. + * + * @param group + */ + public RadioButtonTableCell(final ToggleGroup group) { + radioButton = new RadioButton(); + if (group != null) { + radioButton.setToggleGroup(group); + } + } + + @Override + protected void updateItem(Boolean item, boolean empty) { + super.updateItem(item, empty); + + if (empty) { + setText(null); + setGraphic(null); + } else { + // First remove potential binding + if (selProperty != null) { + radioButton.selectedProperty().unbindBidirectional(selProperty); + } + setGraphic(radioButton); + setAlignment(Pos.CENTER); + radioButton.visibleProperty().bind(((ReferenceLineItem)getTableRow().getItem()).installedProperty); + + final ObservableValue obsValue = getTableColumn().getCellObservableValue(getIndex()); + if (obsValue instanceof BooleanProperty) { + selProperty = (BooleanProperty)obsValue; + // ensures the radio button selected value will follow the item value + radioButton.selectedProperty().bindBidirectional(selProperty); + } + } + } + } + + class ReferenceLineItem implements Comparable { + private Version version; + private BooleanProperty installedProperty; + private BooleanProperty selectedProperty; + + public ReferenceLineItem() { + } + + public ReferenceLineItem(Version version, boolean installed, boolean selected) { + this.version = version; + this.installedProperty = new SimpleBooleanProperty(installed); + this.selectedProperty = new SimpleBooleanProperty(selected); + } + + public Version getVersion() { + return version; + } + + public void setVersion(Version version) { + this.version = version; + } + + public boolean isInstalled() { + return installedProperty.get(); + } + + public void setInstalled(boolean installed) { + this.installedProperty.set(installed); + } + + public boolean isSelected() { + return selectedProperty.get(); + } + + public void setSelected(boolean selected) { + this.selectedProperty.set(selected); + } + + @Override + public int compareTo(ReferenceLineItem o) { + if (version == null) { + return 1; + } + + if (o == null) { + return -1; + } + + return version.compareTo(o.getVersion()); + } + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/FXRhomeoPreferencePane.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXRhomeoPreferencePane.java new file mode 100644 index 0000000..373891d --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXRhomeoPreferencePane.java @@ -0,0 +1,144 @@ +/** + * 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.fx; + +import fr.cenra.rhomeo.api.InternationalResource; +import fr.cenra.rhomeo.api.preferences.PreferenceGroup; +import fr.cenra.rhomeo.api.ui.PreferencePane; +import fr.cenra.rhomeo.core.Session; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import javafx.scene.control.Button; +import javafx.scene.control.Tab; +import javafx.scene.control.TabPane; +import javafx.scene.control.Tooltip; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.HBox; +import javax.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +/** + * Preference editor. This panel aggregate editors for all available + * {@link PreferenceGroup}. A discovery system allows to find the most + * appropriate editor for a given group. If we cannot find any, we use a default + * editor. + * + * @author Samuel Andrés (Geomatys) + */ +@Component("fr.cenra.rhomeo.fx.FXRhomeoPreferencePane") +@Scope("prototype") +public class FXRhomeoPreferencePane extends BorderPane implements InternationalResource { + + @Autowired + private Map preferenceGroups; + + @Autowired + private List availableEditors; + + @Autowired + private Session session; + + private final String css; + + private final List preferencePanes = new ArrayList<>(); + + public FXRhomeoPreferencePane() { + css = FXDefaultPreferenceGroupPane.class.getResource(FXRhomeoPreferencePane.class.getSimpleName() + ".css").toExternalForm(); + getStylesheets().add(css); + } + + @PostConstruct + private void postConstruct() { + + // Creating one tab for each preference group. + final TabPane tabPane = new TabPane(); + final List prefGroups = new ArrayList<>(preferenceGroups.values()); + Collections.sort(prefGroups); + + PreferencePane prefEditor; + for (final PreferenceGroup preferenceGroup : prefGroups) { + prefEditor = null; + for (final PreferencePane editor : availableEditors) { + if (editor.getPreferenceGroup().equals(preferenceGroup)) { + prefEditor = editor; + break; + } + } + + // If no specific editor has been found, a default one is used. + if (prefEditor == null) { + if (preferenceGroup.getKeys().isEmpty()) { + // A group without keys does not need to be displayed + continue; + } + + final FXDefaultPreferenceGroupPane preferencePane = new FXDefaultPreferenceGroupPane(); + preferencePane.setPreferenceGroup(preferenceGroup); + prefEditor = preferencePane; + } + + preferencePanes.add(prefEditor); + final Tab tab = new Tab(preferenceGroup.getLabel(), prefEditor.getEditor()); + tab.setTooltip(new Tooltip(preferenceGroup.getDescription())); + tabPane.getTabs().add(tab); + } + setCenter(tabPane); + + // Creating preference controls + final Button ok = new Button(getResourceString("validate")); + ok.setOnAction(e -> { + for (final PreferencePane preferencePane : preferencePanes) { + preferencePane.save(); + } + getScene().getWindow().hide(); + }); + + final Button cancel = new Button(getResourceString("cancel")); + cancel.setOnAction(e -> getScene().getWindow().hide()); + + final HBox hBox = new HBox(cancel, ok); + hBox.getStylesheets().add(css); + hBox.getStyleClass().add("hBox"); + setBottom(hBox); + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/FXRhomeoReferencePane.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXRhomeoReferencePane.java new file mode 100644 index 0000000..90c49f2 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXRhomeoReferencePane.java @@ -0,0 +1,96 @@ +/** + * 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.fx; + +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.data.Protocol; +import java.util.Collections; +import java.util.List; +import javafx.fxml.FXML; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.GridPane; +import javafx.stage.Stage; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; + +/** + * @author Cédric Briançon (Geomatys) + */ +@Component("fr.cenra.rhomeo.fx.FXRhomeoReferencePane") +@Scope("prototype") +public class FXRhomeoReferencePane extends BorderPane { + + @FXML + private GridPane uiProtocolsBtnGrid; + + @FXML + private GridPane uiModelsBtnGrid; + + @Autowired + private List protocols; + + public FXRhomeoReferencePane() { + Rhomeo.loadFXML(this, FXRhomeoReferencePane.class); + } + + /** + * Initializes JavaFX components after spring components are done loading. + */ + @PostConstruct + private void postConstruct() { + Collections.sort(protocols); + + int modelIndex = 0; + for(int i=0; i editorSpis; + + private DataContext context; + private Site site; + private Protocol protocol; + private ProtocolEditorSpi editorSpi; + + private final Map stepBtns; + + private final String stopBtnOriginalText; + + public FXRhomeoWizard() { + Rhomeo.loadFXML(this, FXRhomeoWizard.class); + // Index buttons by step + final Map tmpMap = new HashMap<>(); + tmpMap.put(WorkflowStep.DATASET, uiStep1Btn); + tmpMap.put(WorkflowStep.PROCESS, uiStep2Btn); + tmpMap.put(WorkflowStep.RESULT, uiStep3Btn); + tmpMap.put(WorkflowStep.FINALIZATION, uiStep4Btn); + stepBtns = Collections.unmodifiableMap(tmpMap); + for (final Map.Entry entry : stepBtns.entrySet()) { + entry.getValue().setOnAction(evt -> session.requestWorkflowStep(entry.getKey())); + } + + uiHeader.managedProperty().bind(uiHeader.visibleProperty()); + + final ImageView im = new ImageView(Rhomeo.ICON_EXCHANGE_GRAY); + im.setRotate(90); + uiRefUsedBtn.setGraphic(im); + uiStopProcessBtn.setGraphic(new ImageView(Rhomeo.ICON_STOP_RED)); + // HACK #77 : User want a change on the button which stops process on a + // specific step, so we keep reference to its original text now. + stopBtnOriginalText = uiStopProcessBtn.getText(); + + // Prepare display of arrows linking step buttons. Each arrow state is bound + // to the step button following it. + final ImageView imgArrow1 = new ImageView(Rhomeo.ICON_LONG_ARROW_RIGHT); + imgArrow1.setDisable(true); + imgArrow1.visibleProperty().bind(uiStep2Btn.visibleProperty()); + imgArrow1.managedProperty().bind(imgArrow1.visibleProperty()); + final ImageView imgArrow2 = new ImageView(Rhomeo.ICON_LONG_ARROW_RIGHT); + imgArrow2.setDisable(true); + imgArrow2.visibleProperty().bind(uiStep3Btn.visibleProperty()); + imgArrow2.managedProperty().bind(imgArrow2.visibleProperty()); + final ImageView imgArrow3 = new ImageView(Rhomeo.ICON_LONG_ARROW_RIGHT); + imgArrow3.setDisable(true); + imgArrow3.visibleProperty().bind(uiStep4Btn.visibleProperty()); + imgArrow3.managedProperty().bind(imgArrow3.visibleProperty()); + // Limit height of arrow image, which is really too big (lot of empty space). + final Rectangle2D arrowDisplay = new Rectangle2D( + 0, Rhomeo.ICON_LONG_ARROW_RIGHT.getHeight() / 4, + Rhomeo.ICON_LONG_ARROW_RIGHT.getWidth(), Rhomeo.ICON_LONG_ARROW_RIGHT.getHeight() / 2); + imgArrow1.setViewport(arrowDisplay); + imgArrow2.setViewport(arrowDisplay); + imgArrow3.setViewport(arrowDisplay); + + uiProtocolStepsGrid.add(imgArrow1, 2, 0); + uiProtocolStepsGrid.add(imgArrow2, 4, 0); + uiProtocolStepsGrid.add(imgArrow3, 6, 0); + } + + @PostConstruct + private void init() { + session.workflowStepProperty().addListener(this::stepChanged); + unloadDataContext(); + } + + private void loadDataContext() { + this.context = session.getDataContext(); + this.site = context.getSite(); + this.protocol = context.getProtocol(); + initializeReferences(); + for (final ProtocolEditorSpi spi : editorSpis) { + if (spi.getProtocol() == protocol) { + editorSpi =spi; + break; + } + } + + // Deactivate step buttons for workflow parts marked as non available + // by the input SPI. + if (editorSpi != null && !editorSpi.getStepsToIgnore().isEmpty()) { + for (final WorkflowStep step : editorSpi.getStepsToIgnore()) { + final Button btn = stepBtns.get(step); + if (btn != null) { + btn.setVisible(false); + btn.setManaged(false); + } + } + } + + uiSelectedSiteLbl.setText(site.getName()); + uiSelectedProtocolLbl.setText(protocol.getName()); + uiProtocolChosenBox.getChildren().add(uiSelectedProtocolLbl); + uiRefUsedBtn.setDisable(protocol.getReferenceTypes().isEmpty()); + + final List indicators = session.getIndicators(); + indicators.stream() + .filter(indicator -> indicator.getProtocol() == protocol) + .sorted() + .forEach(indicator -> { + final Label lbl = new Label(indicator.getName()); + lbl.getStyleClass().add(Rhomeo.CSS_INDICATOR_LABEL); + uiProtocolChosenBox.getChildren().add(lbl); + }); + + final Button pdfBtn = Rhomeo.createProtocolDocumentButton(protocol); + pdfBtn.setText(null); + pdfBtn.setPrefHeight(28); + pdfBtn.setMaxHeight(USE_PREF_SIZE); + pdfBtn.setMinHeight(USE_PREF_SIZE); + uiProtocolChosenBox.getChildren().add(pdfBtn); + uiHeader.setVisible(true); + + // Generate protocol background + final String bgPath = "/fr/cenra/rhomeo/images/" + protocol.getName().toLowerCase() + ".png"; + if (FXRhomeoWizard.class.getResource(bgPath) != null) { + try (final InputStream stream = FXRhomeoWizard.class.getResourceAsStream(bgPath)) { + final Background backgroundProtocol = new Background(new BackgroundImage( + new Image(stream), + BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, + new BackgroundPosition(Side.LEFT, 0, true, Side.BOTTOM, 0, true), BackgroundSize.DEFAULT)); + setBackground(backgroundProtocol); + } catch (IOException e) { + Rhomeo.LOGGER.log(Level.FINE, "Cannot load a background image !", e); + } + } + + // #59 Reset results if user change reference version. + session.getDataContext().getReferences().addListener((Observable obs) -> { + if (session.getWorkflowStep() == WorkflowStep.RESULT || session.getWorkflowStep() == WorkflowStep.FINALIZATION) + session.requestWorkflowStep(WorkflowStep.PROCESS); + + session.setResults(null); + stepBtns.get(WorkflowStep.RESULT).setDisable(true); + stepBtns.get(WorkflowStep.FINALIZATION).setDisable(true); + }); + } + + private void unloadDataContext() { + final Site tmpSite = site; + context = null; + site = null; + protocol = null; + uiProtocolChosenBox.getChildren().clear(); + uiHeader.setVisible(false); + editorSpi = null; + + for (final Button stepBtn : stepBtns.values()) { + stepBtn.setDisable(true); + stepBtn.setVisible(true); + stepBtn.getStyleClass().removeAll(Rhomeo.CSS_CURRENT_STEP); + } + + final FXDashboardPane dashboard = session.getBean(FXDashboardPane.class); + dashboard.siteProperty().set(tmpSite); + + // TODO : set site + uiBody.setCenter(dashboard); + setBackground(Background.EMPTY); + } + + /** + * On {@link FXRhomeoWizard#uiRefUsedBtn} action. + */ + @FXML + private void showUsedRef() { + final DataContext dc = session.getDataContext(); + if (dc == null) { + return; + } + final Protocol protocol = dc.getProtocol(); + if (protocol == null) { + return; + } + + final Stage stage = Rhomeo.newStage(); + stage.setTitle("Choix des référentiels"); + final VBox vbox = new VBox(10); + vbox.getStyleClass().add("white-box"); + + protocol.getReferenceTypes().forEach(description -> { + try { + final FXProtocolReferencesPane protocolReferences = new FXProtocolReferencesPane(description); + vbox.getChildren().add(protocolReferences); + VBox.setVgrow(protocolReferences, Priority.SOMETIMES); + } catch (IntrospectionException ex) { + throw new RhomeoRuntimeException(ex); + } + }); + + final Button validBtn = new Button("Valider"); + validBtn.getStyleClass().add("white-button"); + validBtn.setOnAction(event -> { + // #59 If user already computed indices, changing reference versions + // would delete his results, so we warn him. + if (!stepBtns.get(WorkflowStep.RESULT).isDisabled()) { + Alert alert = new Alert(Alert.AlertType.CONFIRMATION, "Si vous changez de version de référentiel maintenant, vos résultats seront supprimés. Continuer ?", ButtonType.NO, ButtonType.YES); + alert.setResizable(true); + if (ButtonType.NO.equals(alert.showAndWait().orElse(ButtonType.NO))) + return; + } + vbox.getChildren().stream() + .filter(child -> child instanceof FXProtocolReferencesPane) + .map(child -> (FXProtocolReferencesPane)child) + .forEach(protoRefs -> + protoRefs.getItems().stream() + .filter(o -> o instanceof FXProtocolReferencesPane.ReferenceLineItem && ((FXProtocolReferencesPane.ReferenceLineItem) o).isSelected()) + .forEach(o -> dc.getReferences().put(protoRefs.getReferenceClass(), ((FXProtocolReferencesPane.ReferenceLineItem) o).getVersion())) + ); + try { + contextManager.writeDataContext(dc); + } catch (IOException ex) { + throw new RhomeoRuntimeException(ex); + } finally { + stage.close(); + } + }); + + final Button cancelBtn = new Button("Annuler"); + cancelBtn.setCancelButton(true); + cancelBtn.setOnAction(evt -> stage.close()); + cancelBtn.getStyleClass().add("white-button"); + + final HBox validHbox = new HBox(5, cancelBtn, validBtn); + validHbox.setAlignment(Pos.CENTER_RIGHT); + vbox.getChildren().add(validHbox); + + final Scene scene = new Scene(vbox); + scene.getStylesheets().add(Rhomeo.CSS_THEME_PATH); + scene.getStylesheets().add("/fr/cenra/rhomeo/fx/FXProtocolReferencesPane.css"); + stage.setScene(scene); + stage.setMinHeight(protocol.getReferenceTypes().size() * 130 + 80); + stage.setHeight(stage.getMinHeight()); + stage.setResizable(true); + stage.initModality(Modality.APPLICATION_MODAL); + stage.initStyle(StageStyle.UNDECORATED); + stage.sizeToScene(); + stage.showAndWait(); + } + + @FXML + private void stopProcess() { + // HACK #78 : Before stopping session, we check dataset state, for the + // user to be able to save its data before stopping. + final Node center = uiBody.getCenter(); + if (center instanceof FXDatasetPane) { + Task saveTask = ((FXDatasetPane) center).checkSaveChange().orElse(null); + if (saveTask != null) + saveTask.setOnSucceeded(evt -> { + if (Boolean.TRUE.equals(evt.getSource().getValue())) + Platform.runLater(() -> session.requestWorkflowStep(null)); + }); + else + session.requestWorkflowStep(null); + } else + session.requestWorkflowStep(null); + } + + private void stepChanged(final ObservableValue obs, final WorkflowStep oldStep, final WorkflowStep newStep) { + // HACK #77 : User want a change on stop button look and feel at final step. + // We reset its state before doing anything else. + uiStopProcessBtn.setText(stopBtnOriginalText); + uiStopProcessBtn.setGraphic(new ImageView(Rhomeo.ICON_STOP_RED)); + + if (newStep == null) { + // Clear and hide edition display. Go back to the dashboard. + unloadDataContext(); + + } else { + + if (oldStep == null) { + // New edition started + loadDataContext(); + } else { + Button btn = stepBtns.get(oldStep); + if (btn != null && btn.getStyleClass().contains(Rhomeo.CSS_CURRENT_STEP)) { + btn.getStyleClass().remove(Rhomeo.CSS_CURRENT_STEP); + } + } + + // Init current step UI + Button btn = stepBtns.get(newStep); + btn.setDisable(false); + btn.getStyleClass().add(Rhomeo.CSS_CURRENT_STEP); + + Node body = createNode(newStep); + if (body == null) { + switch (newStep) { + case DATASET: + body = session.getBean(FXDatasetPane.class); + break; + + case PROCESS: + body = session.getBean(FXDefaultProcessingPane.class); + break; + + case RESULT: + body = session.getBean(FXDefaultResultPane.class); + break; + + case FINALIZATION: + body = session.getBean(FXFinalizationPane.class); + // HACK #77 : Change look and feel of stop button. + uiStopProcessBtn.setText("Retour au tableau de bord"); + uiStopProcessBtn.setGraphic(new ImageView(Rhomeo.ICON)); + break; + } + } + + uiBody.setCenter(body); + } + } + + private Node createNode(final WorkflowStep step) { + final Node node; + if (editorSpi != null) { + node = editorSpi.getEditor(step); + } else { + node = null; + } + + return node; + } + + /** + * Initialize references lists for further use. + * Note : For each reference of the current protocol, we update list of + * installed and available versions. If none is installed, we propose to the + * user to install the most up to date. + * + * @throws IntrospectionException + */ + private void initializeReferences() { + if (protocol == null || protocol.getReferenceTypes().isEmpty()) + return; + + for (final ReferenceDescription description : protocol.getReferenceTypes()) { + try { + final ReferenceManager referenceManager = ReferenceManager.getOrCreate(description); + final Task task = referenceManager.refresh(); + task.setOnSucceeded(event -> { + // If we haven't any version installed for this reference, then we propose to install the newest. + if (referenceManager.getInstalledVersions().isEmpty() && !referenceManager.getDistantVersions().isEmpty()) { + Platform.runLater(() -> { + final StringBuilder builder = new StringBuilder("Aucune version du référentiel suivant n'est installée :") + .append(System.lineSeparator()) + .append(description.getTitle()) + .append(System.lineSeparator()) + .append(System.lineSeparator()) + .append("Voulez-vous télécharger la plus récente ?"); + final Alert alert = new Alert(Alert.AlertType.CONFIRMATION, builder.toString(), ButtonType.NO, ButtonType.YES); + alert.setHeaderText("Référentiel non installé"); + alert.setResizable(true); + // If agreed, we download newest version. When it's done, we set it as used version. + if (ButtonType.YES.equals(alert.showAndWait().orElse(ButtonType.NO))) { + final Version max = Collections.max((Set) referenceManager.getDistantVersions()); + TaskManager.INSTANCE.submit(referenceManager.install(max)).setOnSucceeded(evt -> { + final DataContext dc = session.getDataContext(); + if (dc != null) + Platform.runLater(() -> dc.getReferences().put(description.getReferenceType(), max)); + }); + } + }); + } else { + final Version selectedVersion = context.getReferences().get(description.getReferenceType()); + // If at least one local version exists for this reference and nothing has been selected, then select the biggest one. + // This way, for each reference a version should be selected. + if (selectedVersion == null && !referenceManager.getInstalledVersions().isEmpty()) { + final Version max = Collections.max((Set) referenceManager.getInstalledVersions()); + context.getReferences().put(description.getReferenceType(), max); + } + } + }); + + task.setOnFailed(event -> { + RhomeoCore.LOGGER.log(Level.WARNING, "Cannot update reference versions !", event.getSource().getException()); + final Version selectedVersion = context.getReferences().get(description.getReferenceType()); + // If at least one local version exists for this reference and nothing has been selected, then select the biggest one. + // This way, for each reference a version should be selected. + if (selectedVersion == null && !referenceManager.getInstalledVersions().isEmpty()) { + final Version max = Collections.max((Set) referenceManager.getInstalledVersions()); + context.getReferences().put(description.getReferenceType(), max); + } + }); + + TaskManager.INSTANCE.submit(task); + } catch (Exception e) { + Rhomeo.LOGGER.log(Level.WARNING, "Cannot initialize reference !", e); + } + } + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/FXSplashScreen.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXSplashScreen.java new file mode 100644 index 0000000..cdeddd8 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/FXSplashScreen.java @@ -0,0 +1,60 @@ +/** + * 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.fx; + +import javafx.fxml.FXML; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.ProgressBar; +import javafx.scene.layout.GridPane; + +/** + * Created by cedr on 06/04/16. + */ +public class FXSplashScreen extends GridPane { + @FXML public GridPane uiLoadingPane; + @FXML public Label uiProgressLabel; + @FXML public ProgressBar uiProgressBar; + @FXML public Button uiCancel; + + @FXML + public void closeApp() { + System.exit(0); + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/GraphDashboardItem.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/GraphDashboardItem.java new file mode 100644 index 0000000..c8536e5 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/GraphDashboardItem.java @@ -0,0 +1,139 @@ +/** + * 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.fx; + +import fr.cenra.rhomeo.api.result.IndicatorValuesByYearItem; +import java.util.HashMap; +import javafx.beans.binding.Bindings; +import javafx.collections.ObservableList; +import javafx.geometry.Insets; +import javafx.scene.Scene; +import javafx.scene.chart.NumberAxis; +import javafx.scene.chart.ScatterChart; +import javafx.scene.chart.XYChart; +import javafx.scene.control.MenuItem; +import javafx.scene.control.TablePosition; +import javafx.scene.control.TableView; +import javafx.stage.Modality; +import javafx.stage.Stage; +import javafx.stage.StageStyle; +import org.springframework.stereotype.Component; +import fr.cenra.rhomeo.api.ui.DashboardMenuItem; +import java.util.Map; +import java.util.Optional; + +/** + * + * @author Alexis Manin (Geomatys) + */ +@Component +public class GraphDashboardItem implements DashboardMenuItem { + + private static final String GRAPH_TITLE = "Évolution des valeurs indicatrices"; + + @Override + public Optional createItem(final TableView target) { + final MenuItem graphItem = new MenuItem("Graphique d'évolution"); + graphItem.setOnAction(evt -> displayGraph(target)); + graphItem.visibleProperty().bind(Bindings.size(target.getSelectionModel().getSelectedIndices()).greaterThan(1)); + return Optional.of(graphItem); + } + + + /** + * Display the evolution graph in a modal window. + */ + private static void displayGraph(final TableView source) { + if (source.getScene() == null || source.getScene().getWindow() == null) + return; + final Stage chartStage = new Stage(StageStyle.UTILITY); + chartStage.initModality(Modality.WINDOW_MODAL); + chartStage.initOwner(source.getScene().getWindow()); + chartStage.setTitle(GRAPH_TITLE); + chartStage.setScene(new Scene(createChart(source))); + + chartStage.show(); + } + + /** + * Create a point chart to display selected indicator values from dashboard. + * @return A chart to display selected values. + */ + private static XYChart createChart(final TableView source) { + final Map> series = new HashMap<>(); + final ObservableList selectedCells = source.getSelectionModel().getSelectedCells(); + Double cellData; + int year; + IndicatorSiteColumn col; + int minYear = Integer.MAX_VALUE; + int maxYear = Integer.MIN_VALUE; + double minValue = Double.MAX_VALUE; + double maxValue = Double.MIN_VALUE; + for (final TablePosition pos : selectedCells) { + if (pos.getTableColumn() instanceof IndicatorSiteColumn) { + col = (IndicatorSiteColumn) pos.getTableColumn(); + cellData = col.getCellData(pos.getRow()); + if (cellData != null && Double.isFinite(cellData)) { + year = source.getItems().get(pos.getRow()).getYear(); + minYear = StrictMath.min(year, minYear); + maxYear = StrictMath.max(year, maxYear); + minValue = StrictMath.min(cellData, minValue); + maxValue = StrictMath.max(cellData, maxValue); + + series.computeIfAbsent(col.getIndicator().getTitle(), (title) -> { + final XYChart.Series s = new XYChart.Series<>(); + s.setName(title); + return s; + }).getData().add(new XYChart.Data<>(year, cellData)); + } + } + } + + final XYChart chart = new ScatterChart<>( + new NumberAxis("Année", minYear - 1, maxYear + 1, 5), + new NumberAxis("Valeur", minValue - 0.5, maxValue + 0.5, 0.5) + ); + + chart.setTitle(GRAPH_TITLE); + chart.getData().addAll(series.values()); + chart.getData().sort((o1, o2) -> o1.getName().compareTo(o2.getName())); + chart.setPadding(new Insets(10)); + return chart; + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/IndicatorSiteColumn.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/IndicatorSiteColumn.java new file mode 100644 index 0000000..7ec7bde --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/IndicatorSiteColumn.java @@ -0,0 +1,299 @@ +/** + * 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.fx; + +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.Version; +import fr.cenra.rhomeo.api.data.ReferenceDescription; +import fr.cenra.rhomeo.api.data.Site; +import fr.cenra.rhomeo.api.process.Indicator; +import fr.cenra.rhomeo.api.result.DashboardResultItem; +import fr.cenra.rhomeo.api.result.IndicatorValuesByYearItem; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.result.ResultStorage; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.StringJoiner; +import java.util.function.Function; +import javafx.application.Platform; +import javafx.beans.InvalidationListener; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.collections.ObservableList; +import javafx.concurrent.Task; +import javafx.geometry.HPos; +import javafx.scene.control.ContentDisplay; +import javafx.scene.control.Label; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.control.Tooltip; +import javafx.scene.image.ImageView; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.ColumnConstraints; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.Priority; +import javafx.scene.layout.Region; +import javafx.scene.layout.VBox; +import org.geotoolkit.gui.javafx.util.TaskManager; + +/** + * Table column for indicators. + * Column present in the {@link FXDashboardResultsTable}. + * + * @author Cédric Briançon (Geomatys) + */ +public class IndicatorSiteColumn extends TableColumn implements Comparable { + + private final Indicator indicator; + + private final ChangeListener itemPropertyChanged; + + private final InvalidationListener referenceCheckTrigger; + + private final ObjectProperty checkTaskProperty; + + /** + * HACK : Cannot find any property to put graphic right to text in a column + * header, so we put a label in the header to contain both. + */ + private final Label header; + + public IndicatorSiteColumn(final Indicator indicator) { + this.indicator = indicator; + header = new Label(indicator.getName()); + header.setContentDisplay(ContentDisplay.RIGHT); + setGraphic(header); + + itemPropertyChanged = this::itemPropertyChanged; + referenceCheckTrigger = obs -> checkReferences(); + + tableViewProperty().addListener(this::tableChanged); + tableViewProperty().addListener(referenceCheckTrigger); + + checkTaskProperty = new SimpleObjectProperty<>(); + checkTaskProperty.addListener((obs, oldVal, newVal) -> { + if (oldVal != null && oldVal.isRunning()) + oldVal.cancel(); + if (newVal != null && !newVal.isRunning()) + TaskManager.INSTANCE.submit(newVal); + + }); + } + + public Indicator getIndicator() { + return indicator; + } + + @Override + public int compareTo(IndicatorSiteColumn o) { + if (o == null) { + return -1; + } + + if (indicator == null) { + return 1; + } + return indicator.compareTo(o.getIndicator()); + } + + /** + * Update listeners when parent table changes. + * @param obs + * @param oldVal + * @param newVal + */ + private void tableChanged(final ObservableValue obs, TableView oldVal, TableView newVal) { + if (oldVal != null) { + oldVal.itemsProperty().removeListener(itemPropertyChanged); + oldVal.itemsProperty().removeListener(referenceCheckTrigger); + } + + if (newVal != null) { + newVal.itemsProperty().addListener(itemPropertyChanged); + newVal.itemsProperty().addListener(referenceCheckTrigger); + } + } + + /** + * Update listeners when parent table items change. + * @param obs + * @param oldVal + * @param newVal + */ + private void itemPropertyChanged(final ObservableValue obs, ObservableList oldVal, ObservableList newVal) { + if (oldVal != null) + oldVal.removeListener(referenceCheckTrigger); + + if (newVal != null) + newVal.addListener(referenceCheckTrigger); + } + + /** + * Browse column indices to find all reference versions used for their computing. + * If we find multiple versions for a same reference, we will display a little + * warning to the user. + */ + private void checkReferences() { + final ObservableList items; + if (getTableView() == null || (items = getTableView().getItems()) == null || items.isEmpty()) + return; + + final Site site; + if (getTableView() instanceof FXDashboardResultsTable) + site = ((FXDashboardResultsTable)getTableView()).siteProperty().get(); + else + site = null; + + if (site == null) + return; + + final ReferenceChecker checker = new ReferenceChecker(site, items); + checker.setOnSucceeded(evt -> Platform.runLater(() -> { + final Map>> md = checker.getValue(); + if (multipleVersionsInUse(md)) { + final ImageView imgView = new ImageView(Rhomeo.ICON_WARNING_ORANGE); + final Tooltip tt = new Tooltip("Les versions de référentiels ne sont pas homogènes."); + tt.setContentDisplay(ContentDisplay.BOTTOM); + tt.getStyleClass().add("info-popup"); + tt.setGraphic(createConflictView(md)); + final Label label = new Label(null, imgView); + label.setTooltip(tt); + header.setGraphic(label); + } + })); + + checker.setOnFailed(evt -> Platform.runLater(() -> { + // TODO. For now, do as if nothing happened + })); + + checkTaskProperty.set(checker); + } + + private VBox createConflictView(final Map>> md) { + final VBox vbox = new VBox(10); + vbox.setFillWidth(true); + vbox.setStyle("font-size: 12pt;"); + for (Map.Entry>> entry : md.entrySet()) { + if (entry.getValue().size() < 2) + continue; + final BorderPane bp = new BorderPane(); + final Label title = new Label(entry.getKey().getTitle()); + title.getStyleClass().add("section-title"); + bp.setTop(title); + final GridPane gp = new GridPane(); + bp.setCenter(gp); + gp.getColumnConstraints().addAll( + new ColumnConstraints(Region.USE_COMPUTED_SIZE, Region.USE_COMPUTED_SIZE, Region.USE_COMPUTED_SIZE, Priority.NEVER, HPos.LEFT, true), + new ColumnConstraints(Region.USE_COMPUTED_SIZE, Region.USE_COMPUTED_SIZE, Region.USE_COMPUTED_SIZE, Priority.ALWAYS, HPos.CENTER, true) + ); + final Map> vMap = entry.getValue(); + int rowIndex = 0; + for (Map.Entry> vEntry : vMap.entrySet()) { + gp.add(new Label(vEntry.getKey().toString()), 0, rowIndex); + final StringJoiner sj = new StringJoiner(", "); + vEntry.getValue().forEach(val -> sj.add(String.valueOf(val))); + gp.add(new Label(sj.toString()), 1, rowIndex++); + } + vbox.getChildren().add(bp); + } + + return vbox; + } + + private boolean multipleVersionsInUse(final Map>> metadata) { + for (final Map.Entry>> entry : metadata.entrySet()) { + if (entry.getValue().size() > 1) + return true; + } + return false; + } + + /** + * Read metadata associated to given items and column indicator, to find all + * versions used for references. + */ + private class ReferenceChecker extends Task>>> { + + final List items; + final Site site; + + ReferenceChecker(final Site site, final List items) { + this.site = site; + this.items = items; + } + + @Override + protected Map>> call() throws Exception { + final Session session = Session.getInstance(); + final ResultStorage storage = session.getBean(ResultStorage.class); + + final Map>> refVersions = new HashMap<>(); + for (final IndicatorValuesByYearItem item : items) { + if (isCancelled()) + break; + final IndicatorValuesByYearItem.PublishedValue tmpVal = item.getValueForIndicator(indicator.getName()); + if (tmpVal != null) { + final DashboardResultItem tmpItem = new DashboardResultItem(item.getYear(), site.getName(), indicator.getName(), tmpVal.getValue(), tmpVal.isPublished()); + storage.readMetadata(tmpItem) + .map(sc -> sc.toDataContext(session)) + .map(ctx -> session.transform(ctx.getReferences())) + .ifPresent(map -> merge(map, refVersions, item.getYear())); + } + } + + return refVersions; + } + + void merge(final Map source, final Map>> dest, int year) { + for (final Map.Entry entry : source.entrySet()) { + dest.computeIfAbsent(entry.getKey(), MAP_CREATOR) + .computeIfAbsent(entry.getValue(), SET_CREATOR) + .add(year); + } + } + } + + private static final Function> SET_CREATOR = input -> new HashSet<>(); + private static final Function>> MAP_CREATOR = input -> new HashMap<>(); +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/MultiIndicatorsDashboardItem.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/MultiIndicatorsDashboardItem.java new file mode 100644 index 0000000..d616ab8 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/MultiIndicatorsDashboardItem.java @@ -0,0 +1,208 @@ +/** + * 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.fx; + +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.data.Site; +import fr.cenra.rhomeo.api.process.Indicator; +import fr.cenra.rhomeo.api.result.IndicatorValuesByYearItem; +import fr.cenra.rhomeo.api.ui.DashboardMenuItem; +import fr.cenra.rhomeo.core.RhomeoRuntimeException; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.protocol.p04.I04; +import fr.cenra.rhomeo.protocol.p04.I07; +import fr.cenra.rhomeo.protocol.p08.I12; +import fr.cenra.rhomeo.protocol.p09.I13; +import java.beans.IntrospectionException; +import java.io.IOException; +import java.util.Optional; +import javafx.beans.binding.Bindings; +import javafx.beans.binding.BooleanBinding; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.geometry.Pos; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.MenuItem; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TablePosition; +import javafx.scene.control.TableView; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Region; +import javafx.stage.Modality; +import javafx.stage.Stage; +import javafx.stage.StageStyle; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * + * @author Samuel Andrés (Geomatys) + */ +@Component +public class MultiIndicatorsDashboardItem implements DashboardMenuItem { + + @Autowired + private Session session; + + @Override + public Optional createItem(final TableView table) { + + if (!(table instanceof FXDashboardResultsTable)) + return Optional.empty(); + + final MenuItem graphItem = new MenuItem("Voir tous les indicateurs"); + graphItem.setOnAction(evt -> { + try { + displayStage((FXDashboardResultsTable) table); + } catch (IOException | IntrospectionException | InstantiationException | IllegalAccessException ex) { + throw new RhomeoRuntimeException("Unable to display results.", ex); + } + }); + graphItem.visibleProperty().bind(Bindings.size(table.getSelectionModel().getSelectedIndices()).isEqualTo(1) + .and(isValidIndice(table.getSelectionModel().getSelectedCells()))); + + return Optional.of(graphItem); + } + + /** + * Customized binding to test indicator column. + * + * @param op + * @return + */ + public static BooleanBinding isValidIndice(final ObservableList op) { + if (op == null) { + throw new NullPointerException("List cannot be null."); + } + + return new BooleanBinding() { + { + super.bind(op); + } + + @Override + public void dispose() { + super.unbind(op); + } + + @Override + protected boolean computeValue() { + if(op.size()!=1) return false; + final TablePosition cell = op.get(0); + final TableColumn tableColumn = cell.getTableColumn(); + if(tableColumn instanceof IndicatorSiteColumn && ((IndicatorSiteColumn) tableColumn).getIndicator()!=null){ + final String ind = ((IndicatorSiteColumn) tableColumn).getIndicator().getName(); + if (I04.NAME.equals(ind) || I07.NAME.equals(ind) || I12.NAME.equals(ind) || I13.NAME.equals(ind)) { + return tableColumn.getCellData(cell.getRow()) != null; + } + } + + return false; + } + + @Override + //@ReturnsUnmodifiableCollection + public ObservableList getDependencies() { + return FXCollections.singletonObservableList(op); + } + }; + } + + /** + * Display the evolution graph in a modal window. + */ + private void displayStage(final FXDashboardResultsTable table) throws IOException, IntrospectionException, InstantiationException, IllegalAccessException { + + if (table.getScene() == null + || table.getScene().getWindow() == null + || table.getSelectionModel().getSelectedCells()==null + || table.getSelectionModel().getSelectedCells().size()!=1) + return; + + final Site site = table.siteProperty().get(); + final TableColumn tableColumn = table.getSelectionModel().getSelectedCells().get(0).getTableColumn(); + + if(site!=null && site.getName()!=null && tableColumn!=null && tableColumn instanceof IndicatorSiteColumn){ + + final Indicator indicator = ((IndicatorSiteColumn) tableColumn).getIndicator(); + final IndicatorValuesByYearItem selectedItem = table.getSelectionModel().getSelectedItem(); + + final Stage chartStage = new Stage(StageStyle.TRANSPARENT); + chartStage.initModality(Modality.WINDOW_MODAL); + chartStage.initOwner(table.getScene().getWindow()); + + final FXFullSpecificResultPane fullResultPane = session.createPrototype(FXFullSpecificResultPane.class, + selectedItem, + indicator, + site.getName()); + + final Label label = new Label(indicator.getName() + " ("+selectedItem.getYear()+")"); + label.setAlignment(Pos.CENTER); + label.setMaxWidth(Double.MAX_VALUE); + label.getStyleClass().add("text-bold"); + + final BorderPane root = new BorderPane(); + root.setPrefSize(400, Region.USE_COMPUTED_SIZE); + root.getStyleClass().add("white-box"); + root.setTop(label); + root.setCenter(fullResultPane); + + final Button closeBtn = new Button("Fermer"); + closeBtn.setCancelButton(true); + closeBtn.setOnAction(evt -> chartStage.close()); + closeBtn.getStyleClass().add("white-button"); + final HBox hBox = new HBox(closeBtn); + hBox.setAlignment(Pos.CENTER_RIGHT); + root.setBottom(hBox); + + final Scene scene = new Scene(root); + scene.getStylesheets().add(Rhomeo.CSS_THEME_PATH); + scene.getStylesheets().add("/fr/cenra/rhomeo/fx/FXProtocolReferencesPane.css"); + + chartStage.setMaxHeight(400); + chartStage.setMaxWidth(700); + chartStage.setScene(scene); + chartStage.sizeToScene(); + chartStage.show(); + } + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/AbstractCustomStatementEditor.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/AbstractCustomStatementEditor.java new file mode 100644 index 0000000..530bace --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/AbstractCustomStatementEditor.java @@ -0,0 +1,396 @@ +/** + * 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.fx.edition; + +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.data.DataContext; +import fr.cenra.rhomeo.api.data.Protocol; +import fr.cenra.rhomeo.api.data.Statement; +import fr.cenra.rhomeo.api.data.TrackingPoint; +import fr.cenra.rhomeo.api.ui.StatementEditor; +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.protocol.p02.P02; +import fr.cenra.rhomeo.protocol.p05.P05; +import fr.cenra.rhomeo.protocol.p06.P06; +import fr.cenra.rhomeo.protocol.p07.P07; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import javafx.application.Platform; +import javafx.beans.InvalidationListener; +import javafx.beans.Observable; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; +import javafx.beans.value.ObservableValue; +import javafx.collections.ObservableList; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.Node; +import javafx.scene.control.Button; +import javafx.scene.control.DatePicker; +import javafx.scene.control.Label; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TablePosition; +import javafx.scene.control.TableView; +import javafx.scene.control.TextArea; +import javafx.scene.control.TextField; +import javafx.scene.layout.BorderPane; +import javax.annotation.PostConstruct; +import org.apache.sis.util.ArgumentChecks; +import org.geotoolkit.gui.javafx.util.TaskManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * + * This pane is a factorisation of common attributes and functionalities of + * {@link P02}, {@link P05}, {@link P06} and {@link P07} {@link StatementEditor}s. + * + * It displays a summary of a "current" {@link TrackingPoint} one the one hand, + * and a list of {@link T} on the other hand. + * + * The pane inherits Borderpane and must contain at least : + * + * 1- {@link TrackingPoint} attribute summary : + * + * - a {@link TextField} ({@link AbstractCustomStatementEditor#uiName}) mapping + * the name of the current {@link TrackingPoint}. + * - a {@link DatePicker} field ({@link AbstractCustomStatementEditor#uiDate}), + * mapping the date of the current selected statement. + * - a {@link TextArea} field ({@link AbstractCustomStatementEditor#uiRemarks}), + * mapping the remarks of the current selected statement. + * + * 2- A {@link StatementTable} of the {@link T}s of the selected {@link TrackingPoint}. + * + * /!\ Inherited classes should be {@link Component}s, as a post-construct phase + * and an autowired field are defined here. + * + * @author Samuel Andrés (Geomatys) + * @param + */ +public abstract class AbstractCustomStatementEditor extends BorderPane implements StatementEditor { + + @Autowired + protected Session session; + + // Tracking point attributes + @FXML protected TextField uiName; + @FXML protected DatePicker uiDate; + @FXML protected TextArea uiRemarks; + + // Statement control + @FXML protected BorderPane uiObsContainer; + @FXML protected Button uiDelete; + protected StatementTable uiStatementTable; + + protected final Class dataType; + + /** + * An internal field we use to know if the typed name has changed when user + * exit the name field. + */ + private String oldName = null; + /** + * An internal field we use to know if the typed date has changed when user + * exit the date field. + */ + private LocalDate oldDate = null; + /** + * An internal field we use to know if the typed remarks have changed when + * user exit the remarks field. + */ + private String oldRemarks = null; + + private final StringProperty firstEditionColumn = new SimpleStringProperty(); + + protected AbstractCustomStatementEditor(final Class dataType) { + super(); + ArgumentChecks.ensureNonNull("Data type", dataType); + this.dataType = dataType; + } + + /** + * Default {@link PostConstruct} AbstractCustomStatementEditor. + */ + @PostConstruct + protected void init() { + try { + final Class dataType = session.getDataContext().getProtocol().getDataType(); + if (getDataType().isAssignableFrom(dataType)) { + // Default behaviour : ignore some statement attributes. + uiStatementTable = new StatementTable(dataType, getFieldsToIgnore()); + uiStatementTable.setMinHeight(30); + uiStatementTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + final InvalidationListener listener = (Observable obs) -> { + for (final TableColumn col : uiStatementTable.getColumns()) { + if (col.isEditable() && (col instanceof PropertyColumn)) { + firstEditionColumn.set(((PropertyColumn)col).descriptor.getName()); + break; + } + } + }; + uiStatementTable.getColumns().addListener(listener); + listener.invalidated(uiStatementTable.getColumns()); + + uiObsContainer.setCenter((Node) uiStatementTable); + + uiName.focusedProperty().addListener(this::nameFocusChanged); + uiDate.focusedProperty().addListener(this::dateFocusChanged); + uiRemarks.focusedProperty().addListener(this::remarksFocusChanged); + + uiStatementTable.itemsProperty().addListener(this::itemsChanged); + itemsChanged(uiStatementTable.itemsProperty(), null, null); + } + } catch (Exception e) { + RhomeoCore.LOGGER.log(Level.WARNING, "Cannot initialize statement table !", e); + final Label label = new Label("Impossible d'afficher la table des relevés."); + label.getStyleClass().add(Rhomeo.CSS_ERROR_FIELD); + uiObsContainer.setCenter(label); + } + } + + @Override + public ObservableList getItems() { + return uiStatementTable.getItems(); + } + + @Override + public void setItems(ObservableList items) { + uiStatementTable.setItems(items); + } + + @Override + public ObjectProperty> itemsProperty() { + return uiStatementTable.itemsProperty(); + } + + /** + * + * @return A list of properties from {@link #dataType} which must not be + * included into edition table. + */ + protected String[] getFieldsToIgnore() { + return new String[]{"trackingPoint", "date", "remarks"}; + } + + /** + * Default behaviour dataType return behaviour. + * + * Returns the data type of the {@link Protocol} of the current {@link Session} + * {@link DataContext}. + * + * @return + */ + @Override + public Class getDataType() { + return dataType; + } + + /** + * Default behaviour to create a new {@link T}. + * + * Creates a new statement initializing common attributes from {@link TrackingPoint}. + * + * @return + * @throws ReflectiveOperationException + */ + protected T initStatement() throws ReflectiveOperationException { + // TODO : try to acquire a prototype ? + final T data = (T) session.getDataContext().getProtocol().getDataType().newInstance(); + + if (uiName.getText() != null && !uiName.getText().trim().isEmpty()) { + data.setTrackingPoint(uiName.getText()); + } + + if (uiDate.getValue() != null) { + data.setDate(uiDate.getValue()); + } + + data.setRemarks(uiRemarks.getText()); + + return data; + } + + /** + * Default behaviour on adding {@link T} event. + * + * Creates a new statement and focus on it. + * + * @param evt + * @throws ReflectiveOperationException + */ + @FXML + protected void addStatement(final ActionEvent evt) throws ReflectiveOperationException { + if (uiStatementTable == null || uiStatementTable.getItems() == null) + return; + + final T data = initStatement(); + + uiStatementTable.getItems().add(data); + final TablePosition pos = new TablePosition(uiStatementTable, uiStatementTable.getItems().size() - 1, null); + + // HACK : It appears that table cells are refreshed on next pulse, so we wait for it before asking for focus. + TaskManager.INSTANCE.submit(() -> { + synchronized (pos) { + try { + pos.wait(100); + } catch (InterruptedException ex) { + Rhomeo.LOGGER.log(Level.WARNING, null, ex); + } + } + + Platform.runLater(() -> Rhomeo.editNextCell(pos)); + }); + } + + /** + * Default behaviour of deleting {@link T} event. + * + * @param evt + */ + @FXML + protected void deleteStatements(final ActionEvent evt) { + if (uiStatementTable == null || uiStatementTable.getItems() == null) + return; + + // Defensive copy + final List indices = new ArrayList<>(uiStatementTable.getSelectionModel().getSelectedIndices()); + for (final int index : indices) { + uiStatementTable.getItems().remove(index); + } + } + + @Override + public void focusOn(T item, String propertyName) { + uiStatementTable.focusOn(item, propertyName); + } + + /** + * Default behaviour on changing current {@link TrackingPoint}. + * + * @param obs + * @param oldItems + * @param newItems + */ + protected void itemsChanged(final ObservableValue obs, final List oldItems, final List newItems) { + uiDelete.disableProperty().unbind(); + if (newItems != null && !newItems.isEmpty()) { + final T first = newItems.get(0); + uiName.setText(first.getTrackingPoint()); + uiDate.setValue(first.getDate()); + uiRemarks.setText(first.getRemarks()); + + if (uiStatementTable != null) { + uiStatementTable.getSelectionModel().selectFirst(); + } + + } else { + uiName.setText(null); + uiDate.setValue(null); + uiRemarks.clear(); + } + + if (uiStatementTable != null) { + uiDelete.disableProperty().bind(uiStatementTable.getSelectionModel().selectedItemProperty().isNull()); + } + + uiName.requestFocus(); + } + + /** + * Default behaviour when the focus has changed on {@link AbstractCustomStatementEditor#uiName}. + * + * @param obs + * @param oldValue + * @param newValue + */ + protected void nameFocusChanged(final ObservableValue obs, final Boolean oldValue, final Boolean newValue) { + final String name = uiName.getText(); + if (Boolean.TRUE.equals(newValue)) { + oldName = name; + } else if (Boolean.FALSE.equals(newValue) && !Rhomeo.equivalent(oldName, name)) { + // Update statements. Use defensive copy because each change of name can update list of available items. + final Statement[] toUpdate = uiStatementTable.getItems().toArray(new Statement[uiStatementTable.getItems().size()]); + for (int i = 0 ; i < toUpdate.length ; i++) { + toUpdate[i].setTrackingPoint(name); + } + } + } + + /** + * Default behaviour when the focus has changed on {@link AbstractCustomStatementEditor#uiDate}. + * + * @param obs + * @param oldValue + * @param newValue + */ + protected void dateFocusChanged(final ObservableValue obs, final Boolean oldValue, final Boolean newValue) { + final LocalDate date = uiDate.getValue(); + if (Boolean.TRUE.equals(newValue)) { + oldDate = date; + } else if (!(oldDate == date || oldDate != null && date != null && oldDate.isEqual(date))) { + // Update statements. Use defensive copy because each change of name can update list of available items. + final Statement[] toUpdate = uiStatementTable.getItems().toArray(new Statement[uiStatementTable.getItems().size()]); + for (int i = 0 ; i < toUpdate.length ; i++) { + toUpdate[i].setDate(date); + } + } + } + + /** + * Default behaviour when the focus has changed on {@link AbstractCustomStatementEditor#uiName}. + * + * @param obs + * @param oldValue + * @param newValue + */ + protected void remarksFocusChanged(final ObservableValue obs, final Boolean oldValue, final Boolean newValue) { + final String remarks = uiRemarks.getText(); + if (Boolean.TRUE.equals(newValue)) { + oldRemarks = remarks; + } else if (Boolean.FALSE.equals(newValue) && !Rhomeo.equivalent(oldRemarks, remarks)) { + for (final Statement st : uiStatementTable.getItems()) { + st.setRemarks(remarks); + } + } + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/AutoCommitableTableCell.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/AutoCommitableTableCell.java new file mode 100644 index 0000000..54ea94d --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/AutoCommitableTableCell.java @@ -0,0 +1,53 @@ +/** + * 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.fx.edition; + +import javafx.scene.control.TableCell; + +/** + * A table cell which knows what value to commit when editing. + * @author Alexis Manin (Geomatys) + */ +public abstract class AutoCommitableTableCell extends TableCell { + /** + * Trigger a commit, as {@link #commitEdit(java.lang.Object) }. But its the + * cell which determines the value to commit. + */ + abstract void commitEdit(); +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/ByNameAndDateFilter.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/ByNameAndDateFilter.java new file mode 100644 index 0000000..fc29352 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/ByNameAndDateFilter.java @@ -0,0 +1,125 @@ +/** + * 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.fx.edition; + +import fr.cenra.rhomeo.api.data.Statement; +import fr.cenra.rhomeo.core.RhomeoCore; +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.time.LocalDate; +import java.util.Objects; +import java.util.function.Predicate; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class ByNameAndDateFilter implements Predicate, Comparable, Externalizable { + + protected static final long serialVersionUID = 1L; + + protected String name; + protected LocalDate date; + + public ByNameAndDateFilter() {} + + public ByNameAndDateFilter(String name, LocalDate date) { + this.name = name; + this.date = date; + } + + @Override + public boolean test(Statement t) { + if (!Objects.equals(name, t.getTrackingPoint())) + return false; + return RhomeoCore.checkEquality(date, t.getDate()); + } + + public String getName() { + return name; + } + + public LocalDate getDate() { + return date; + } + + @Override + public int compareTo(ByNameAndDateFilter o) { + final int nameComparison = getName().compareTo(o.getName()); + if (nameComparison != 0) + return nameComparison; + return getDate().compareTo(o.getDate()); + } + + @Override + public int hashCode() { + int hash = 3; + hash = 61 * hash + Objects.hashCode(this.name); + hash = 61 * hash + Objects.hashCode(this.date); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + final ByNameAndDateFilter other = (ByNameAndDateFilter) obj; + if (!Objects.equals(this.name, other.name)) + return false; + return date == other.date || date != null && other.date != null && date.isEqual(other.date); + } + + @Override + public void writeExternal(ObjectOutput out) throws IOException { + out.writeUTF(name == null? "" : name); + RhomeoCore.writeDate(date, out); + } + + @Override + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + name = in.readUTF(); + date = RhomeoCore.readDate(in); + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/CSVConfigurationPane.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/CSVConfigurationPane.java new file mode 100644 index 0000000..dcf209c --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/CSVConfigurationPane.java @@ -0,0 +1,282 @@ +/** + * 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.fx.edition; + +import com.sun.javafx.PlatformUtil; +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.preferences.PreferenceGroup; +import fr.cenra.rhomeo.api.ui.PreferencePane; +import fr.cenra.rhomeo.core.CSVMapper; +import fr.cenra.rhomeo.core.CSVMappingBuilder; +import fr.cenra.rhomeo.preferences.csv.CSVKey; +import fr.cenra.rhomeo.preferences.csv.CSVPreferences; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.Optional; +import java.util.logging.Level; +import javafx.beans.binding.Bindings; +import javafx.beans.value.ObservableValue; +import javafx.collections.FXCollections; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.fxml.FXML; +import javafx.scene.Node; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ComboBox; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.scene.image.ImageView; +import javafx.scene.layout.VBox; +import javafx.stage.Modality; +import javafx.stage.Stage; +import javafx.stage.StageStyle; +import javafx.stage.Window; +import javafx.util.StringConverter; +import javax.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +/** + * A panel to edit CSV format preferences for dataset import / export. You can + * also acquire a {@link CSVMappingBuilder} from a configuration typed in a popup + * by calling {@link #showConfigurationForm(javafx.stage.Window) }. + * @author Alexis Manin (Geomatys) + */ +@Component +@Scope("prototype") +public class CSVConfigurationPane extends VBox implements PreferencePane { + + private static final String INFO_TEXT = new StringBuilder("L'échappement des chaînes de caractère est optionnel. Le caractère d'échappement est \" et doit entourer la chaine complète.") + .append(System.lineSeparator()) + .append("Pour utiliser le caractère \" dans les messages échappés, il doit être doublé.") + .append(System.lineSeparator()) + .append("Ex : \"Ceci est un texte \"\"échappé\"\".\"") + .toString(); + + @FXML + private ComboBox uiEncoding; + + @FXML + private TextField uiText; + + @FXML + private CheckBox uiTab; + + @FXML + private Label uiInfo; + + @FXML + private Button uiCancel; + + @FXML + private Button uiApply; + + @Autowired + private CSVPreferences prefs; + + private CSVMappingBuilder builder; + + private CSVConfigurationPane() { + super(); + Rhomeo.loadFXML(this); + + Charset defaultCharset; + if (PlatformUtil.isWindows()) + try { + defaultCharset = Charset.forName("windows-1252"); + } catch (Exception e) { + Rhomeo.LOGGER.log(Level.FINE, "No charset found for windows-1252.", e); + defaultCharset = StandardCharsets.ISO_8859_1; + } + else + defaultCharset = StandardCharsets.UTF_8; + + Rhomeo.initComboBox(uiEncoding, FXCollections.observableArrayList(Charset.availableCharsets().values()).sorted(), defaultCharset); + uiEncoding.setConverter(new CharsetStringConverter()); + + uiText.disableProperty().bind(uiTab.selectedProperty()); + uiText.textProperty().addListener(this::textChanged); + + uiInfo.setGraphic(new ImageView(Rhomeo.ICON_INFO_BLUE)); + uiInfo.setText(INFO_TEXT); + } + + @PostConstruct + private void init() { + init(prefs.getPreference(CSVPreferences.CHARSET_KEY), prefs.getPreference(CSVPreferences.SEPARATOR_KEY)); + } + + private void init(final String charset, final String separator) { + // Restore default values from preferences. + if (separator.equals("\t")) { + uiTab.setSelected(true); + } else { + uiText.setText(separator); + } + + if (charset != null) + uiEncoding.setValue(Charset.forName(charset)); + } + + private void initButtons() { + uiApply.setVisible(true); + uiCancel.setVisible(true); + + uiApply.setOnAction(this::createBuilder); + uiApply.disableProperty().bind(Bindings.createBooleanBinding(() -> + uiText.getCharacters().length() != 1 && uiEncoding.getValue() == null + , uiText.textProperty(), uiEncoding.valueProperty())); + uiCancel.setCancelButton(true); + } + + /** + * Ensure that typed separator is a single character. + * + * @param obs + * @param oldValue + * @param newValue + */ + private void textChanged(final ObservableValue obs, final String oldValue, final String newValue) { + if (newValue != null && newValue.length() > 1) { + uiText.setText(newValue.substring(newValue.length() -1)); + } + } + + private void createBuilder(final ActionEvent e) { + if (uiEncoding.getValue() == null || (!uiTab.isSelected() && uiText.getText() == null || uiText.getText().isEmpty())) + return; + + final char separator = uiTab.isSelected()? '\t' : uiText.getText().charAt(uiText.getText().length() -1); + builder = new CSVMappingBuilder() + .withSeparator(separator) + .withEncoding(uiEncoding.getValue()); + } + + /** + * Show a dialog allowing user to configure the basic parameters for CSV + * mapping (separator, encoding). + * + * /!\ MUST BE CALLED FROM FX-THREAD. + * + * @return A csv mapper builder if user confirmed its configuration, Nothing + * if he cancelled. + */ + public static Optional showConfigurationForm() { + return showConfigurationForm(null); + } + + /** + * Show a dialog allowing user to configure the basic parameters for CSV + * mapping (separator, encoding). + * + * /!\ MUST BE CALLED FROM FX-THREAD. + * + * @param owner The owner of the dialog to display. If the owner is null, + * then displayed stage is application modal. Otherwise, the modality is + * limited only on owner window. + * @return A csv mapper builder if user confirmed its configuration, Nothing + * if he cancelled. + */ + public static Optional showConfigurationForm(final Window owner) { + final CSVConfigurationPane content = new CSVConfigurationPane(); + content.init(StandardCharsets.UTF_8.name(), String.valueOf(CSVMapper.DEFAULT_SEPARATOR)); + content.initButtons(); + + final Stage stage = new Stage(StageStyle.UTILITY); + final EventHandler btnListener = (evt) -> stage.close(); + content.uiApply.addEventHandler(ActionEvent.ACTION, btnListener); + content.uiCancel.addEventHandler(ActionEvent.ACTION, btnListener); + + if (owner != null) { + stage.initModality(Modality.WINDOW_MODAL); + stage.initOwner(owner); + } else { + stage.initModality(Modality.APPLICATION_MODAL); + } + + stage.setScene(new Scene(content)); + stage.setTitle("Paramètres de lecture"); + stage.showAndWait(); + return Optional.ofNullable(content.builder); + } + + @Override + public void save() { + if (uiText.getText() != null && !uiText.getText().isEmpty()) { + final char separator = uiTab.isSelected() ? '\t' : uiText.getText().charAt(uiText.getText().length() - 1); + prefs.setPreference(CSVPreferences.SEPARATOR_KEY, String.valueOf(separator)); + } + if (uiEncoding.getValue() != null) + prefs.setPreference(CSVPreferences.CHARSET_KEY, uiEncoding.getValue().name()); + + } + + @Override + public PreferenceGroup getPreferenceGroup() { + return prefs; + } + + @Override + public Node getEditor() { + return this; + } + + /** + * A simple converter between string and charset types. + */ + private static class CharsetStringConverter extends StringConverter { + + @Override + public String toString(Charset object) { + if (object == null) + return null; + return object.displayName(); + } + + @Override + public Charset fromString(String string) { + if (string == null || (string = string.trim()).isEmpty()) + return null; + return Charset.forName(string); + } + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/FXDatasetPane.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/FXDatasetPane.java new file mode 100644 index 0000000..1c34352 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/FXDatasetPane.java @@ -0,0 +1,702 @@ +/** + * 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.fx.edition; + +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.data.Dataset; +import fr.cenra.rhomeo.api.data.ObjectWrapper; +import fr.cenra.rhomeo.api.data.Protocol; +import fr.cenra.rhomeo.api.data.Statement; +import fr.cenra.rhomeo.api.process.ProcessContext; +import fr.cenra.rhomeo.api.ui.FilterTable; +import fr.cenra.rhomeo.api.ui.StatementEditor; +import fr.cenra.rhomeo.core.CSVDecoder; +import fr.cenra.rhomeo.core.CSVEncoder; +import fr.cenra.rhomeo.core.CSVMapper; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.WorkflowStep; +import fr.cenra.rhomeo.fx.validation.FXValidationPane; +import fr.cenra.rhomeo.preferences.csv.CSVPreferences; +import java.io.File; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Optional; +import java.util.ResourceBundle; +import java.util.function.Predicate; +import java.util.regex.Pattern; +import javafx.application.Platform; +import javafx.beans.binding.Bindings; +import javafx.beans.binding.BooleanBinding; +import javafx.beans.binding.IntegerBinding; +import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.value.ObservableValue; +import javafx.collections.FXCollections; +import javafx.collections.ListChangeListener; +import javafx.collections.ObservableList; +import javafx.concurrent.Task; +import javafx.concurrent.Worker; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.fxml.FXML; +import javafx.scene.Node; +import javafx.scene.control.Alert; +import javafx.scene.control.Button; +import javafx.scene.control.ButtonType; +import javafx.scene.control.SelectionMode; +import javafx.scene.image.ImageView; +import javafx.scene.input.MouseEvent; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.Region; +import javafx.scene.layout.VBox; +import javafx.stage.FileChooser; +import javax.annotation.PostConstruct; +import javax.validation.ConstraintViolation; +import javax.validation.Path; +import org.apache.sis.util.ArgumentChecks; +import org.geotoolkit.gui.javafx.util.TaskManager; +import org.geotoolkit.internal.GeotkFX; +import org.geotoolkit.util.collection.CloseableIterator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; +import fr.cenra.rhomeo.api.ui.FilterTableSpi; +import fr.cenra.rhomeo.core.state.StateManager; +import java.util.concurrent.atomic.AtomicBoolean; +import javafx.beans.Observable; + +/** + * Default editor for {@link Datasset} edition. For {@link Statement} edition, + * we try to inject a {@link StatementEditor} specific to the input {@link Protocol#getDataType() + * }. + * + * IMPORTANT : Input {@link StatementEditor} does not use directly {@link Dataset#getItems() + * }, to avoid sudden changes in the editor caused by an event sourced from + * dataset. However, to keep a responsive dataset, we mirror editor data in + * dataset on the fly. It is needed for state saving (see {@link StateManager) and other mechanisms as validation. + * + * @author Alexis Manin (Geomatys) + */ +@Component +@Scope("prototype") +@Lazy +public class FXDatasetPane extends VBox { + + private static final Pattern CSV_SUFFIX = Pattern.compile("(?i)\\.csv$"); + + @Autowired + private CSVPreferences csvPrefs; + + @Autowired + private Session session; + + @Autowired + private List pointTableSpis; + + private FilterTable uiGroupTable; + + private StatementEditor uiStatementEditor; + + @Autowired + private FXValidationPane uiValidator; + + @FXML + private Button uiDisplayDocumentation; + @FXML + private Button uiDeleteDataset; + + @FXML + private BorderPane uiPointListContainer; + + @FXML + private Button uiAddPoint; + @FXML + private Button uiDeletePoints; + + @FXML + private BorderPane uiPointEditorContainer; + + @FXML + private BorderPane uiValidationContainer; + + @FXML + private Button uiExportDataset; + + @FXML + private Button uiProceed; + + protected final ResourceBundle bundle; + + private final ListChangeListener itemListener = this::itemsChanged; + + private ObservableList dataList; + + private final AtomicBoolean changeDetected = new AtomicBoolean(false); + + public FXDatasetPane() { + bundle = ResourceBundle.getBundle(FXDatasetPane.class.getCanonicalName()); + Rhomeo.loadFXML(this, FXDatasetPane.class); + } + + @PostConstruct + private void init() { + ArgumentChecks.ensureNonNull("Session containing data", session); + ArgumentChecks.ensureNonNull("Data context", session.getDataContext()); + ArgumentChecks.ensureNonNull("Target protocol", session.getDataContext().getProtocol()); + ArgumentChecks.ensureNonNull("Target dataset", session.getDataset()); + + for (final FilterTableSpi spi : pointTableSpis) { + if (spi.getProtocol() == session.getDataContext().getProtocol()) { + uiGroupTable = spi.createEmptyTable(); + break; + } + } + + if (uiGroupTable == null) { + uiGroupTable = (FilterTable) new FXTrackingPointTable(session); + } + + uiGroupTable.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); + uiGroupTable.setMinHeight(50); + uiGroupTable.setFixedCellSize(25); + final IntegerBinding size = Bindings.size(uiGroupTable.getItems()); + uiGroupTable.prefHeightProperty().bind( + Bindings.createDoubleBinding(() -> { + if (size.get() < 1) { + return 50d; + } + return size.get() * uiGroupTable.getFixedCellSize() + 30; + }, size, uiGroupTable.fixedCellSizeProperty()) + ); + + Optional optEditor = session.findEditor(session.getDataContext().getProtocol().getDataType()); + if (optEditor.isPresent()) { + uiStatementEditor = optEditor.get(); + if (uiStatementEditor instanceof Region) { + ((Region)uiStatementEditor).setMinHeight(50); + } + uiStatementEditor.itemsProperty().addListener(this::itemsPropertyChanged); + uiGroupTable.getSelectionModel().selectedItemProperty().addListener((obs, oldGroup, newGroup) -> { + if (newGroup == null) { + uiStatementEditor.setItems(FXCollections.observableArrayList()); + } else { + uiStatementEditor.setItems(FXCollections.observableArrayList(session.getDataset().getItems().filtered(newGroup))); + } + }); + + uiStatementEditor.setItems(FXCollections.observableArrayList()); + uiPointEditorContainer.setCenter((Node) uiStatementEditor); + } else { + uiAddPoint.setVisible(false); + uiAddPoint.setManaged(false); + } + + uiPointListContainer.setCenter(uiGroupTable); + uiPointEditorContainer.managedProperty().bind(uiPointEditorContainer.visibleProperty()); + + uiValidationContainer.setCenter(uiValidator); + uiValidator.getWarningList().getSelectionModel().setSelectionMode(SelectionMode.SINGLE); + uiValidator.getWarningList().getSelectionModel().selectedItemProperty().addListener(this::selectedErrorChanged); + uiValidator.getErrorList().getSelectionModel().setSelectionMode(SelectionMode.SINGLE); + uiValidator.getErrorList().getSelectionModel().selectedItemProperty().addListener(this::selectedErrorChanged); + /* + * HACK : Error list force focus on itself after click. So we + * have to repeat the selectedErrorChanged on mouse released. + */ + final EventHandler handler = evt -> { + final ConstraintViolation violation; + if (evt.getSource() == uiValidator.getWarningList()) { + violation = uiValidator.getWarningList().getSelectionModel().getSelectedItem(); + } else if (evt.getSource() == uiValidator.getErrorList()) { + violation = uiValidator.getErrorList().getSelectionModel().getSelectedItem(); + } else { + violation = null; + } + + if (violation != null) + selectedErrorChanged(null, null, violation); + }; + uiValidator.getErrorList().addEventHandler(MouseEvent.MOUSE_RELEASED, handler); + uiValidator.getWarningList().addEventHandler(MouseEvent.MOUSE_RELEASED, handler); + + /* + * Disability + */ + BooleanBinding emptyDataset = Bindings.isEmpty(session.getDataset().getItems()); + uiDeleteDataset.disableProperty().bind(emptyDataset); + uiExportDataset.disableProperty().bind(emptyDataset); + uiProceed.disableProperty().bind(emptyDataset); + + uiDeletePoints.disableProperty().bind(uiGroupTable.getSelectionModel().selectedItemProperty().isNull()); + + // Icons + uiDeleteDataset.setGraphic(new ImageView(Rhomeo.ICON_TRASH_BLUE)); + uiDeletePoints.setGraphic(new ImageView(Rhomeo.ICON_TRASH_BLUE)); + uiDisplayDocumentation.setGraphic(new ImageView(Rhomeo.ICON_FILE_TEXT)); + + session.getDataset().getItems().addListener(this::changeDetected); + } + + @FXML + void addPoint(ActionEvent event) { + // No tracking point selected. However, a null value will allow creation + // of a fresh one. We force editor visibility. + uiGroupTable.getSelectionModel().clearSelection(); + uiStatementEditor.setItems(FXCollections.observableArrayList()); + } + + @FXML + void deleteDataset(ActionEvent event) { + final Alert alert = new Alert(Alert.AlertType.CONFIRMATION, bundle.getString("dataset.delete.confirm"), ButtonType.NO, ButtonType.YES); + alert.setResizable(true); + if (ButtonType.YES.equals(alert.showAndWait().orElse(ButtonType.NO))) { + // issue #79 : focused filter is not suppressed. + uiGroupTable.getSelectionModel().clearSelection(); + session.getDataset().getItems().clear(); + if (uiStatementEditor != null) + uiStatementEditor.setItems(FXCollections.observableArrayList()); + uiValidator.reset(); + } + } + + @FXML + void deletePoints(ActionEvent event) { + final Alert alert = new Alert(Alert.AlertType.CONFIRMATION, bundle.getString("point.delete.confirm"), ButtonType.NO, ButtonType.YES); + alert.setResizable(true); + if (ButtonType.YES.equals(alert.showAndWait().orElse(ButtonType.NO))) { + // Defensive copy + final ArrayList selected = new ArrayList<>(uiGroupTable.getSelectionModel().getSelectedItems()); + // HACK : filter table won't delete entries if they're focused. + uiGroupTable.getSelectionModel().clearSelection(); + if (!selected.isEmpty()) { + Predicate filter = selected.get(0); + for (int i = 1; i < selected.size(); i++) { + filter = filter.or(selected.get(i)); + } + session.getDataset().getItems().removeIf(filter); + } + } + } + + @FXML + void displayDocumentation(ActionEvent event) { + final Protocol protocol = session.getDataContext().getProtocol(); + Rhomeo.generateModelZip(protocol, uiDisplayDocumentation); + } + + @FXML + Task exportDataset(ActionEvent event) { + final File chosen = chooseCSV(uiExportDataset.getText(), true); + if (chosen != null) { + final TaskManager.MockTask export = new TaskManager.MockTask(bundle.getString("dataset.export.task"), () -> { + final char sep; + final String separator = csvPrefs.getPreference(CSVPreferences.SEPARATOR_KEY); + if (separator == null || separator.isEmpty()) + sep = CSVMapper.DEFAULT_SEPARATOR; + else + sep = separator.charAt(separator.length() - 1); + + // Check if we must transform data when encoding. + Class dataType = session.getDataContext().getProtocol().getDataType(); + Iterator toEncode = session.getDataset().getItems().iterator(); + Optional opt = session.getWrapper(dataType); + if (opt.isPresent()) { + dataType = opt.get().getOutputType(); + toEncode = new Transformer(opt.get(), toEncode); + } + + final CSVEncoder encoder = new CSVEncoder( + chosen.toPath(), dataType, sep, Charset.forName(csvPrefs.getPreference(CSVPreferences.CHARSET_KEY)), null); + encoder.encode(toEncode, true); + return true; + }); + + export.setOnSucceeded(evt -> changeDetected.set(false)); + + export.setOnFailed(evt -> Platform.runLater(() -> { + GeotkFX.newExceptionDialog(bundle.getString("dataset.export.error"), export.getException()); + })); + + export.runningProperty().addListener((obs, oldValue, newValue) -> { + setDisable(newValue); + // TODO : show a loading popup + }); + + return TaskManager.INSTANCE.submit(export); + } + + return null; + } + + @FXML + void importDataset(ActionEvent event) { + Task previousTask = null; + if (!session.getDataset().getItems().isEmpty()) { + final String contentText = bundle.getString("save.before.import"); + final Alert saveCurrent = new Alert(Alert.AlertType.WARNING, contentText, ButtonType.CANCEL, ButtonType.NO, ButtonType.YES); + saveCurrent.setResizable(true); + ButtonType choice = saveCurrent.showAndWait().orElse(ButtonType.CANCEL); + if (ButtonType.CANCEL.equals(choice)) { + return; + } else if (ButtonType.YES.equals(choice)) { + previousTask = exportDataset(event); + if (previousTask == null) { + return; // user cancelled saving. Stop the entire process. + } + } + } + + final File input = chooseCSV(bundle.getString("dataset.import.choice"), false); + if (input == null) + return; + + /* On dataset change, the trigger serving to notify user on possible + * unsaved entries. But, as we are just importing data, we must keep + * the same state as before the task. + */ + final boolean previousStatus = changeDetected.get(); + final TaskManager.MockTask importTask = new TaskManager.MockTask(bundle.getString("dataset.import.task"), () -> { + final HashSet ignorable = new HashSet<>(2); + ignorable.add("trackingPoint"); + ignorable.add("remarks"); + final char sep; + final String separator = csvPrefs.getPreference(CSVPreferences.SEPARATOR_KEY); + if (separator == null || separator.isEmpty()) + sep = CSVMapper.DEFAULT_SEPARATOR; + else + sep = separator.charAt(separator.length() - 1); + final CSVDecoder decoder = new CSVDecoder( + input.toPath(), + session.getDataContext().getProtocol().getDataType(), + sep, + Charset.forName(csvPrefs.getPreference(CSVPreferences.CHARSET_KEY)), + ignorable + ); + + // Check doublons. + int integrated = 0; + int doublons = 0; + final ObservableList dataset = session.getDataset().getItems(); + final HashSet doublonDetector = new HashSet(dataset); + try (final CloseableIterator it = decoder.decodeLazy()) { + Object read; + while (it.hasNext()) { + read = it.next(); + if (doublonDetector.add(read)) { + integrated++; + } else { + doublons++; + } + } + } + + // Update dataset with new elements. + doublonDetector.removeAll(dataset); + final TaskManager.MockTask t = new TaskManager.MockTask(() -> dataset.addAll(doublonDetector)); + Platform.runLater(t); + t.get(); + + if (doublons <= 0) + return String.format(bundle.getString("dataset.import.result.no-doublon"), integrated); + else + return String.format(bundle.getString("dataset.import.result"), integrated, doublons); + }); + + importTask.setOnFailed(evt -> Platform.runLater(() -> { + GeotkFX.newExceptionDialog(bundle.getString("dataset.import.error"), importTask.getException()); + })); + + importTask.setOnSucceeded(evt -> Platform.runLater(() -> { + changeDetected.set(previousStatus); + Rhomeo.showAlert(Alert.AlertType.INFORMATION, importTask.getValue()); + })); + + if (previousTask != null) { + final SimpleObjectProperty previousState = new SimpleObjectProperty<>(); + previousState.addListener((obs, oldState, newState) -> { + if (Worker.State.SUCCEEDED.equals(newState)) { + TaskManager.INSTANCE.submit(importTask); + } + }); + previousState.bind(previousTask.stateProperty()); + } else { + TaskManager.INSTANCE.submit(importTask); + } + } + + @FXML + void nextStep(ActionEvent event) { + Task previousTask = checkSaveChange().orElse(null); + + final Runnable proceed = () -> { + setProcessContext(session); + + /* + * Check if we're able to jump to the next step. If not, we try to guess + * why, and inform user of what is wrong. + */ + if (!session.requestWorkflowStep(WorkflowStep.PROCESS)) { + if (session.getDataContext().getReferences().size() < session.getDataContext().getProtocol().getReferenceTypes().size()) { + Rhomeo.showAlert(Alert.AlertType.WARNING, "Les versions des référentiels associés au protocole ne sont pas définies !"); + } else { + Rhomeo.showAlert(Alert.AlertType.WARNING, "Impossible de passer à l'étape suivante. Veuillez vérifier votre lot de données."); + } + } + }; + + if (previousTask != null) { + previousTask.setOnSucceeded(evt -> { + if (Boolean.TRUE.equals(evt.getSource().getValue())) + Platform.runLater(proceed); + }); + } else { + proceed.run(); + } + } + + /** + * If changes have been detected in currently edited dataset, ask to user if + * he wants to save them, and launch export process if he agrees. + * + * /!\ You must call this method from FX thread. + * + * @return An empty object if there's no change to save. Otherwise, a task + * is returned, which returns false if user cancelled saving, or true if + * data has been successfully written. + */ + public Optional> checkSaveChange() { + if (!changeDetected.get()) { + return Optional.empty(); + } + + final String contentText = bundle.getString("save.before.next"); + final Alert saveCurrent = new Alert(Alert.AlertType.CONFIRMATION, contentText, ButtonType.CANCEL, ButtonType.NO, ButtonType.YES); + saveCurrent.setResizable(true); + ButtonType choice = saveCurrent.showAndWait().orElse(ButtonType.CANCEL); + + if (ButtonType.YES.equals(choice)) { + final Task exportTask = exportDataset(null); + if (exportTask != null) + return Optional.of(exportTask); + } else if (ButtonType.NO.equals(choice)) { + return Optional.empty(); + } + + final TaskManager.MockTask t = new TaskManager.MockTask(() -> false); + t.run(); + return Optional.of(t); + } + + /** + * When a change is detected on input dataset, we notify user that changes + * occurred and some data may not have been saved. + * + * @param obs + */ + private void changeDetected(final Observable obs) { + /* If dataset has been emptied, we clear change state. We check it here, + * so it is valid either if user deleted it manually or via "clear dataset" + * button. + */ + if (session.getDataset().getItems().isEmpty()) + changeDetected.set(false); + else + changeDetected.set(true); + } + + /** + * When we change items of inner {@link StatementEditor}, we update + * listeners registered on it. + * + * @param obs + */ + private void itemsPropertyChanged(final Observable obs) { + if (dataList != null) + dataList.removeListener(itemListener); + + dataList = uiStatementEditor.getItems(); + if (dataList != null) { + dataList.addListener(itemListener); + } + } + + /** + * Report changes from editor list to dataset. + * @param c + */ + private void itemsChanged(final ListChangeListener.Change c) { + ObservableList dataset = session.getDataset().getItems(); + while (c.next()) { + if (c.wasRemoved()) { + // Delete strict reference, because if the user has added multiple new + // objects in the table, they could be equal. + final ArrayList removedCopy = new ArrayList(c.getRemoved()); + dataset.removeIf(item -> { + final Iterator it = removedCopy.iterator(); + while (it.hasNext()) { + if (item == it.next()) { + it.remove(); + return true; + } + } + return false; + }); + } + if (c.wasAdded()) { + dataset.addAll(c.getAddedSubList()); + } + } + } + + /** + * Utility method to set {@link Session}'s {@link ProcessContext}. + * + * @param session + */ + public static void setProcessContext(final Session session){ + final ProcessContext processContext; + if (session.getProcessContext() != null) { + processContext = session.getProcessContext(); + // We keep previous selection, but clean tracking points which does + // not exist anymore. After this operation, if we've got no more + // point selected, we reset selection. +// processContext.getTrackingPoints().retainAll(session.getDataset().getTrackingPoints()); +// if (processContext.getTrackingPoints().isEmpty()) { +// processContext.getTrackingPoints().addAll(session.getDataset().getTrackingPoints()); +// } + } else { + // Create a process context. By default, we activate all available indicators for the edited protocol. + processContext = new ProcessContext(session.getDataset(), session.getDataContext()); + session.getIndicators().stream() + .filter(i -> i.getProtocol() == session.getDataContext().getProtocol()) + .forEach(i -> processContext.getIndicators().add(i)); + //processContext.getTrackingPoints().addAll(session.getDataset().getTrackingPoints()); + } + + session.setProcessContext(processContext); + } + + /** + * On error selection, we try to retrieve the origin statement, then focus + * on it in the statement editor. + * + * @param obs + * @param oldValue + * @param newValue + */ + private void selectedErrorChanged(final ObservableValue obs, final ConstraintViolation oldValue, final ConstraintViolation newValue) { + if (newValue != null) { + if (newValue.getLeafBean() instanceof Statement) { + final Statement st = (Statement) newValue.getLeafBean(); + /* + * Find group related to the target statement. We + * need it to initialize statement editor. + */ + for (final Predicate p : uiGroupTable.getItems()) { + if (p.test(st)) { + uiGroupTable.getSelectionModel().select(p); + break; + } + } + + final Iterator it = newValue.getPropertyPath().iterator(); + String pName = null; + while (it.hasNext()) { + pName = it.next().getName(); + } + uiStatementEditor.focusOn(st, pName); + } + } + } + + /** + * Display a file chooser to allow user to choose a CSV file to open or save. + * @param title The title to display on the file chooser header. + * @param saveMode True to show file chooser in save mode (see {@link FileChooser#showSaveDialog(javafx.stage.Window) }). + * False to use opening mode (See {@link FileChooser#showOpenDialog(javafx.stage.Window) }. + * + * @return The file selected by user. Can be null if user cancelled. + */ + private File chooseCSV(final String title, final boolean saveMode) { + final FileChooser chooser = new FileChooser(); + chooser.setTitle(title); + chooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Fichier CSV", "*.csv")); + final File previousPath = Rhomeo.getPreviousPath(FXDatasetPane.class); + if (previousPath != null) { + chooser.setInitialDirectory(previousPath); + } + + File result = saveMode? + chooser.showSaveDialog(getScene().getWindow()): + chooser.showOpenDialog(getScene().getWindow()); + + if (result != null) { + Rhomeo.setPreviousPath(FXDatasetPane.class, result.getParentFile()); + if (!CSV_SUFFIX.matcher(result.getName()).find()) { + result = new File(result.getParentFile(), result.getName().concat(".csv")); + } + } + + return result; + } + + private static class Transformer implements Iterator { + + final ObjectWrapper wrapper; + final Iterator source; + + public Transformer(ObjectWrapper wrapper, Iterator source) { + this.wrapper = wrapper; + this.source = source; + } + + @Override + public boolean hasNext() { + return source.hasNext(); + } + + @Override + public O next() { + return wrapper.apply(source.next()); + } + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/FXFloreEditor.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/FXFloreEditor.java new file mode 100644 index 0000000..a46bacf --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/FXFloreEditor.java @@ -0,0 +1,160 @@ +/** + * 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.fx.edition; + +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.ui.StatementEditor; +import fr.cenra.rhomeo.api.ui.StatementEditorSpi; +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.protocol.p02.list.PhysionomyFlore; +import fr.cenra.rhomeo.protocol.p02.FloreStatement; +import java.util.Arrays; +import java.util.List; +import javafx.beans.value.ObservableValue; +import javafx.collections.FXCollections; +import javafx.fxml.FXML; +import javafx.scene.control.ComboBox; +import javafx.util.StringConverter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +/** + * + * @author Alexis Manin (Geomatys) + */ +@Component +@Scope("prototype") +public class FXFloreEditor extends AbstractCustomStatementEditor { + + @FXML + private ComboBox uiPhysio; + + public FXFloreEditor() { + super(FloreStatement.class); + Rhomeo.loadFXML(this, FXFloreEditor.class); + + Rhomeo.initComboBox(uiPhysio, FXCollections.observableList(Arrays.asList(PhysionomyFlore.values()))); + uiPhysio.valueProperty().addListener(this::physionomyChanged); + uiPhysio.setConverter(new StringConverter() { + @Override + public String toString(PhysionomyFlore object) { + if (object == null) + return null; + return new StringBuilder(object.getCode()).append(" - ").append(object.getValue()).toString(); + } + + @Override + public PhysionomyFlore fromString(String string) { + if (string == null || (string = string.trim()).isEmpty()) { + return null; + } + + return RhomeoCore.getByCode(PhysionomyFlore.class, string.split("\\s")[0]).orElse(null); + } + }); + } + + @Override + protected void init() { + super.init(); + if (uiStatementTable != null) + uiStatementTable.sortColumns(Arrays.asList("cd_nom", "abundance")); + } + + @Override + protected String[] getFieldsToIgnore() { + final String[] toIgnore = super.getFieldsToIgnore(); + final String[] overrided = new String[toIgnore.length + 2]; + overrided[0] = "physionomy"; + overrided[1] = "strate"; + System.arraycopy(toIgnore, 0, overrided, 2, toIgnore.length); + return overrided; + } + + @Override + protected FloreStatement initStatement() throws ReflectiveOperationException { + final FloreStatement data = super.initStatement(); + if (uiPhysio.getValue() instanceof PhysionomyFlore) { + ((FloreStatement) data).setPhysionomy(uiPhysio.getValue().getCode()); + } + return data; + } + + /* + * UI LISTENERS + */ + private void physionomyChanged(final ObservableValue obs, final PhysionomyFlore oldPhysio, final PhysionomyFlore newPhysio) { + final String newCode = newPhysio == null ? null : newPhysio.getCode(); + if (uiStatementTable == null || uiStatementTable.getItems() == null) + return; + + for (int i = 0; i < uiStatementTable.getItems().size(); i++) { + uiStatementTable.getItems().get(i).physionomyProperty().set(newCode); + } + } + + @Override + protected void itemsChanged(final ObservableValue obs, final List oldItems, final List newItems) { + super.itemsChanged(obs, oldItems, newItems); + if (newItems != null && !newItems.isEmpty()) { + uiPhysio.setValue(RhomeoCore.getByCode(PhysionomyFlore.class, newItems.get(0).getPhysionomy()).orElse(null)); + } else { + uiPhysio.setValue(null); + } + } + + @Component + public static class Spi implements StatementEditorSpi { + + @Autowired + Session session; + + @Override + public StatementEditor createEditor() { + return session.createPrototype(FXFloreEditor.class); + } + + @Override + public Class getDataType() { + return FloreStatement.class; + } + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/FXOrthopteraEditor.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/FXOrthopteraEditor.java new file mode 100644 index 0000000..b2075f3 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/FXOrthopteraEditor.java @@ -0,0 +1,79 @@ +/** + * 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.fx.edition; + +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.ui.StatementEditor; +import fr.cenra.rhomeo.api.ui.StatementEditorSpi; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.protocol.p05.OrthopteraStatement; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +/** + * + * @author Samuel Andrés (Geomatys) + */ +@Component +@Scope("prototype") +public class FXOrthopteraEditor extends AbstractCustomStatementEditor { + + public FXOrthopteraEditor() { + super(OrthopteraStatement.class); + Rhomeo.loadFXML(this, FXFloreEditor.class); + } + + @Component + public static class Spi implements StatementEditorSpi { + + @Autowired + Session session; + + @Override + public StatementEditor createEditor() { + return session.createPrototype(FXOrthopteraEditor.class); + } + + @Override + public Class getDataType() { + return OrthopteraStatement.class; + } + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/FXP07Editor.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/FXP07Editor.java new file mode 100644 index 0000000..0c25113 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/FXP07Editor.java @@ -0,0 +1,87 @@ +/** + * 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.fx.edition; + +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.ui.StatementEditor; +import fr.cenra.rhomeo.api.ui.StatementEditorSpi; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.protocol.p07.P07Statement; +import java.util.Arrays; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +/** + * + * @author Alexis Manin (Geomatys) + */ +@Component +@Scope("prototype") +public class FXP07Editor extends AbstractCustomStatementEditor { + + public FXP07Editor() { + super(P07Statement.class); + Rhomeo.loadFXML(this, FXFloreEditor.class); + } + + @Override + protected void init() { + super.init(); + if (uiStatementTable != null) + uiStatementTable.sortColumns(Arrays.asList("cd_nom", "number")); + } + + @Component + public static class Spi implements StatementEditorSpi { + + @Autowired + Session session; + + @Override + public StatementEditor createEditor() { + return session.createPrototype(FXP07Editor.class); + } + + @Override + public Class getDataType() { + return P07Statement.class; + } + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/FXTrackingPointTable.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/FXTrackingPointTable.java new file mode 100644 index 0000000..a6c9e03 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/FXTrackingPointTable.java @@ -0,0 +1,207 @@ +/** + * 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.fx.edition; + +import fr.cenra.rhomeo.api.data.Protocol; +import fr.cenra.rhomeo.api.data.Statement; +import fr.cenra.rhomeo.api.ui.FilterTable; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.protocol.p01.P01; +import java.time.LocalDate; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.function.Predicate; +import javafx.beans.binding.Bindings; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.value.ObservableValue; +import javafx.collections.FXCollections; +import javafx.collections.ListChangeListener; +import javafx.collections.transformation.FilteredList; +import javafx.scene.control.TableCell; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.util.Callback; + +/** + * A simple table whose aim is to display tracking point information. + * @author Alexis Manin (Geomatys) + */ +public class FXTrackingPointTable extends FilterTable { + + private static final Callback, TableCell> DATE_CELL_FACTORY = FXTrackingPointTable::createDateCell; + + private final Session session; + private final TableColumn nbColumn; + + private final FilteredList dataset; + + public FXTrackingPointTable(final Session session) { + this.session = session; + final TableColumn nameColumn = new TableColumn("Nom"); + nameColumn.setCellValueFactory(input -> new SimpleStringProperty(input.getValue().getName())); + + final TableColumn dateColumn = new TableColumn("Date"); + dateColumn.setCellValueFactory(input -> (ObservableValue) new SimpleObjectProperty<>(input.getValue().getDate())); + dateColumn.setCellFactory(DATE_CELL_FACTORY); + + // HACK for column name (we should not do it that way, but time...) + String nbTitle = "Nombre"; + if (session.getDataContext() != null && session.getDataContext().getProtocol() != null) { + final Protocol p = session.getDataContext().getProtocol(); + if (p instanceof P01) + nbTitle = "Nombre d'horizons"; + else + nbTitle = "Nombre d'observations"; + } + nbColumn = new TableColumn(nbTitle); + nbColumn.setCellValueFactory(this::getSubsetSize); + + getColumns().addAll(nameColumn, dateColumn, nbColumn); + setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + + setItems(FXCollections.observableArrayList()); + + dataset = session.getDataset().getItems().filtered(null); // Prepare a filtered list to allow user setting filters. + dataset.addListener(this::datasetChanged); + addFilters(dataset); + } + + @Override + public Predicate getPreFilter() { + return dataset.getPredicate(); + } + + @Override + public void setPreFilter(final Predicate filter) { + dataset.setPredicate(filter); + } + + @Override + public ObjectProperty> preFilterProperty() { + return dataset.predicateProperty(); + } + + private ObservableValue getSubsetSize(final TableColumn.CellDataFeatures cellFeature) { + // If given value and current dataset are not null, we set column value as tracking point subset size. + if (cellFeature.getValue() != null && session != null && session.getDataset() != null) { + return (ObservableValue) Bindings.size(dataset.filtered(cellFeature.getValue())); + } else { + return new SimpleObjectProperty<>(null); + } + } + + /** + * Every time session dataset changes, we update list of available groups. + * @param c Changes which occurred on surveyed data. + */ + private void datasetChanged(final ListChangeListener.Change c) { + while (c.next()) { + if (c.wasUpdated()) { + removeObsolete(); + addFilters(c.getList().subList(c.getFrom(), c.getTo())); + } else { + if (c.wasRemoved()) { + removeObsolete(); + } + + addFilters(c.getAddedSubList()); + } + } + } + + /** + * Delete from table all useless entries. I.e all entries which don't have + * any statement associated anymore, and not being currently edited. + */ + private void removeObsolete() { + /* HACK : To find obsolete groups, we just browse count column, and + * delete matching items for each count equal to 0. + */ + final Iterator it = getItems().iterator(); + Integer nb; + ByNameAndDateFilter current; + while (it.hasNext()) { + current = it.next(); + // Even if the current group is empty, we don't delete + // it if user is working with it. + if (current.equals(getSelectionModel().getSelectedItem())) + continue; + nb = nbColumn.getCellData(current); + if (nb == null || nb == 0) + it.remove(); + } + } + + /** + * Add filters matching given data name/date pairs. + * @param dataset Data which will serve to build list of filters to add. + */ + private void addFilters(final List dataset) { + if (dataset == null || dataset.isEmpty()) + return; + + final HashSet set = new HashSet<>(); + for (final Statement st : dataset) { + set.add(new ByNameAndDateFilter(st.getTrackingPoint(), st.getDate())); + } + + synchronized (this) { + set.removeAll(getItems()); // Ensure no doublon is added. + getItems().addAll(set); + } + } + + private static TableCell createDateCell(final TableColumn column) { + return new TableCell() { + @Override + protected void updateItem(LocalDate item, boolean empty) { + super.updateItem(item, empty); + if (empty) + setText(null); + else if (item == null) + setText(" - "); + else + setText(item.toString()); + } + }; + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/ObjectTable.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/ObjectTable.java new file mode 100644 index 0000000..c1bdeb7 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/ObjectTable.java @@ -0,0 +1,192 @@ +/** + * 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.fx.edition; + +import fr.cenra.rhomeo.api.InternationalResource; +import fr.cenra.rhomeo.core.RhomeoCore; +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.MethodDescriptor; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import org.apache.sis.util.ArgumentChecks; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class ObjectTable extends TableView { + + private final Class dataType; + private final BeanInfo beanInfo; + + /** + * Create a new table to expose data type properties. + * + * @param objectType Type of row item objects. + * @param blackList A set of properties to ignore when building table columns. + * + * @throws IntrospectionException + */ + public ObjectTable(final Class objectType, String... blackList) throws IntrospectionException { + ArgumentChecks.ensureNonNull("Data type", objectType); + dataType = objectType; + beanInfo = Introspector.getBeanInfo(objectType, Object.class); + + final Set toIgnore; + if (blackList == null || blackList.length <= 0) { + toIgnore = Collections.EMPTY_SET; + } else { + toIgnore = new HashSet(Arrays.asList(blackList)); + } + + // Index methods by name to find them easily + final MethodDescriptor[] mds = beanInfo.getMethodDescriptors(); + final Map methods = new HashMap<>(mds.length); + for (final MethodDescriptor md : mds) { + methods.put(md.getName(), md.getMethod()); + } + + final boolean bundleAvailable = InternationalResource.class.isAssignableFrom(dataType); + boolean editable = false; + for (final PropertyDescriptor desc : beanInfo.getPropertyDescriptors()) { + if (toIgnore.contains(desc.getName())) + continue; + + try { + if (bundleAvailable) { + try { + desc.setDisplayName(InternationalResource.getResourceString((Class) dataType, desc.getName(), "label")); + desc.setShortDescription(InternationalResource.getResourceString((Class) dataType, desc.getName(), "tooltip")); + } catch (Exception e) { + RhomeoCore.LOGGER.log(Level.FINE, "No bundle available for property ".concat(desc.getName()), e); + } + } + final PropertyColumn col = new PropertyColumn<>(desc, methods.get(desc.getName().concat("Property"))); + if (col.isEditable()) + editable = true; + getColumns().add(col); + } catch (IllegalArgumentException e) { + RhomeoCore.LOGGER.log(Level.WARNING, "Cannot create a table column for property ".concat(desc.getName()), e); + } + } + + setEditable(editable); + setColumnResizePolicy(TableView.UNCONSTRAINED_RESIZE_POLICY); + } + + /** + * Try to sort table columns according to the names given in input list. Names + * in input list must be a property name, or (only for columns not working with object properties) + * the text of the column. Order in the list will define the order of the columns. + * + * @param orderedNames Order to apply on this table columns. + */ + public void sortColumns(final String... orderedNames) { + if (orderedNames == null || orderedNames.length < 1) + return; + sortColumns(Arrays.asList(orderedNames)); + } + + public void sortColumns(final List orderedNames) { + if (orderedNames == null || orderedNames.isEmpty()) + return; + + getColumns().sort((TableColumn o1, TableColumn o2) -> { + final String firstName, secondName; + if (o1 instanceof PropertyColumn) { + firstName = ((PropertyColumn)o1).descriptor.getName(); + } else { + firstName = o1.getText(); + } + if (o2 instanceof PropertyColumn) { + secondName = ((PropertyColumn)o2).descriptor.getName(); + } else { + secondName = o2.getText(); + } + + final int firstOccur = orderedNames.indexOf(firstName); + final int secondOccur = orderedNames.indexOf(secondName); + // Second property not in the given list. No change in ordering. + if (secondOccur < 0) + return -1; + // First property not found. Moved to the back. + else if (firstOccur < 0) + return 1; + else + return orderedNames.indexOf(firstName) - orderedNames.indexOf(secondName); + }); + } + + public Class getDataType() { + return dataType; + } + + public void focusOn(T item, String propertyName) { + final int rowIndex = getItems().indexOf(item); + if (rowIndex >= 0) { + if (propertyName == null || (propertyName = propertyName.trim()).isEmpty()) { + getSelectionModel().select(item);// No property given. Select row. + } else { + // Try to find the column of the property, to focus / edit queried cell. + for (final TableColumn col : getColumns()) { + if (col instanceof PropertyColumn && ((PropertyColumn) col).descriptor.getName().equals(propertyName)) { + if (col.isEditable()) { + edit(rowIndex, col); + } else { + getFocusModel().focus(rowIndex, col); + } + return; + } + } + } + } + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/P01Editor.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/P01Editor.java new file mode 100644 index 0000000..e086e1a --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/P01Editor.java @@ -0,0 +1,104 @@ +/** + * 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.fx.edition; + +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.ui.StatementEditor; +import fr.cenra.rhomeo.api.ui.StatementEditorSpi; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.protocol.p01.PedologyStatement; +import java.util.ResourceBundle; +import javafx.event.ActionEvent; +import javafx.scene.control.Alert; +import javafx.scene.control.ButtonType; +import javafx.scene.control.TableView; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +/** + * + * @author Alexis Manin (Geomatys) + */ +@Component +@Scope("prototype") +public class P01Editor extends AbstractCustomStatementEditor { + + public P01Editor() { + super(PedologyStatement.class); + Rhomeo.loadFXML(this, P01Editor.class); + } + + @Override + protected void init() { + super.init(); + if (uiStatementTable != null) { + uiStatementTable.setMinHeight(30); + uiStatementTable.setMaxSize(Double.MAX_VALUE, USE_COMPUTED_SIZE); + uiStatementTable.setColumnResizePolicy(TableView.UNCONSTRAINED_RESIZE_POLICY); + uiStatementTable.sortColumns("numberH", "depth", "limits", "color", "value", "chroma", "texture", "structure", "rawElements", "roots", "stains", "abundance", "size", "shape", "humidity", "compactness", "plasticity", "adhesiveness", "friability", "alterationMo", "vonPost"); + } + } + + @Override + protected void deleteStatements(ActionEvent evt) { + final Alert alert = new Alert(Alert.AlertType.CONFIRMATION, ResourceBundle.getBundle(P01Editor.class.getCanonicalName()).getString("statement.delete.confirm"), ButtonType.NO, ButtonType.YES); + alert.setResizable(true); + if (ButtonType.YES.equals(alert.showAndWait().orElse(ButtonType.NO))) { + super.deleteStatements(evt); + } + } + + @Component + public static class Spi implements StatementEditorSpi { + + @Autowired + Session session; + + @Override + public StatementEditor createEditor() { + return session.createPrototype(P01Editor.class); + } + + @Override + public Class getDataType() { + return PedologyStatement.class; + } + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/P04Editor.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/P04Editor.java new file mode 100644 index 0000000..a13b3d3 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/P04Editor.java @@ -0,0 +1,222 @@ +/** + * 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.fx.edition; + +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.data.Dataset; +import fr.cenra.rhomeo.api.data.Statement; +import fr.cenra.rhomeo.api.process.Indicator; +import fr.cenra.rhomeo.api.process.ProcessContext; +import fr.cenra.rhomeo.api.result.Index; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.WorkflowStep; +import static fr.cenra.rhomeo.fx.edition.FXDatasetPane.setProcessContext; +import fr.cenra.rhomeo.protocol.p04.I04; +import fr.cenra.rhomeo.protocol.p04.I07; +import fr.cenra.rhomeo.protocol.p04.P04Statement; +import java.beans.IntrospectionException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.logging.Level; +import javafx.beans.binding.Bindings; +import javafx.beans.binding.DoubleBinding; +import javafx.concurrent.Task; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.control.Alert; +import javafx.scene.control.Button; +import javafx.scene.control.TableView; +import javafx.scene.layout.BorderPane; +import javax.validation.ConstraintViolation; +import javax.validation.Validator; +import org.apache.sis.util.ArgumentChecks; +import org.geotoolkit.gui.javafx.util.TaskManager; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class P04Editor extends BorderPane { + + @FXML + private Button uiFinalize; + + @FXML + private BorderPane uiTableContainer; + + @FXML + private Button uiDelete; + + private final Session session; + + private final StatementTable table; + DoubleBinding sizeBinding = null; + + public P04Editor(final Session session) throws IntrospectionException { + ArgumentChecks.ensureNonNull("Session", session); + this.session = session; + Rhomeo.loadFXML(this); + table = new StatementTable<>(P04Statement.class, "trackingPoint", "date", "remarks"); + table.sortColumns("year", "habitat", "humine", "acids", "pt", "cot"); + table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + uiTableContainer.setCenter(table); + if (session.getDataset() != null) { + table.setItems(session.getDataset().getItems()); + table.setFixedCellSize(32); + sizeBinding = Bindings.createDoubleBinding(() -> { + final int elementNb = table.getItems().size() < 1? 1 : table.getItems().size(); + return table.getFixedCellSize() * elementNb + 30; // Header size is not counted in element numbers, so we add a hard-coded size for it. + }, table.getItems(), table.fixedCellSizeProperty()); + table.prefHeightProperty().bind(sizeBinding); + } + + uiDelete.disableProperty().bind(table.getSelectionModel().selectedItemProperty().isNull()); + uiFinalize.disableProperty().bind(Bindings.isEmpty(table.getItems())); + } + + @FXML + void addStatement(ActionEvent event) throws ReflectiveOperationException { + session.getDataset().getItems().add(session.getDataContext().getProtocol().getDataType().newInstance()); + } + + @FXML + void deleteSelection(ActionEvent event) { + // Defensive copy + final Collection selectedItems = new ArrayList<>(table.getSelectionModel().getSelectedItems()); + // Delete strict reference, because if the user has added multiple new + // objects in the table, they could be equal. + if (!selectedItems.isEmpty()) { + session.getDataset().getItems().removeIf(item -> { + for (final Statement selected : selectedItems) { + if (selected == item) + return true; + } + return false; + }); + } + } + + @FXML + void validate(ActionEvent event) { + final Validator validator = session.getBean(Validator.class); + final Set> result = validator.validate(session.getDataset()); + if (result != null && !result.isEmpty()) { + final StringBuilder builder = new StringBuilder("La saisie n'est pas valide : "); + int index; + for (final ConstraintViolation cv : result) { + builder.append(System.lineSeparator()).append(" - "); + index = -1; + final Object leafBean = cv.getLeafBean(); + for (int i = 0 ; i < table.getItems().size() ; i++) { + if (leafBean == table.getItems().get(i)) { + index = i; + break; + } + } + + if (index >= 0) { + builder.append("Ligne ").append(index + 1).append(" : "); + } + builder.append(cv.getMessage()); + } + Rhomeo.showAlert(Alert.AlertType.WARNING, builder.toString()); + return; + } + + // Get P04 indicators + Indicator i04 = null; + Indicator i07 = null; + for (final Indicator i : session.getIndicators()) { + if (I04.NAME.equals(i.getName())) { + i04 = i; + if (i07 != null) + break; + } else if (I07.NAME.equals(i.getName())) { + i07 = i; + if (i04 != null) + break; + } + } + + // Ask indicators to convert seized data into indices. + final List processes = new ArrayList<>(); + if (i04 != null) { + i04.createProcesses(new ProcessContext(session.getDataset(), session.getDataContext())).forEach(p -> { + TaskManager.INSTANCE.submit(p); + processes.add(p); + }); + } + + if (i07 != null) { + i07.createProcesses(new ProcessContext(session.getDataset(), session.getDataContext())).forEach(p -> { + TaskManager.INSTANCE.submit(p); + processes.add(p); + }); + } + + // Aggregate / sort results. + final Task> t = new TaskManager.MockTask("Traitement des résultats...", () -> { + Set indices = new HashSet<>(); + for (final fr.cenra.rhomeo.api.process.Process p : processes) { + try { + indices.addAll(p.get()); + } catch (Exception ex) { + Rhomeo.LOGGER.log(Level.WARNING, "A process failed", ex); + } + } + + return indices; + }); + + // Proceed to finalization. + t.setOnSucceeded((evt) -> { + session.setResults(t.getValue()); + session.requestWorkflowStep(WorkflowStep.FINALIZATION); + }); + + t.setOnFailed((evt) -> Rhomeo.showAlert(Alert.AlertType.WARNING, "Une erreur s'est produite. Impossible de procéder à la finalisation.")); + + TaskManager.INSTANCE.submit(t); + + setProcessContext(session); + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/P04EditorSpi.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/P04EditorSpi.java new file mode 100644 index 0000000..25d7cca --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/P04EditorSpi.java @@ -0,0 +1,109 @@ +/** + * 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.fx.edition; + +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.data.Protocol; +import fr.cenra.rhomeo.api.ui.ProtocolEditorSpi; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.WorkflowStep; +import fr.cenra.rhomeo.protocol.p04.P04; +import java.beans.IntrospectionException; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.logging.Level; +import javafx.scene.Node; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +/** + * + * @author Alexis Manin (Geomatys) + */ +@Component +public class P04EditorSpi implements ProtocolEditorSpi { + + @Autowired + @Qualifier(P04.NAME) + Protocol p04; + + @Autowired + Session session; + + final Set toIgnore; + + private P04EditorSpi() { + final HashSet steps = new HashSet<>(2); + steps.add(WorkflowStep.PROCESS); + steps.add(WorkflowStep.RESULT); + toIgnore = Collections.unmodifiableSet(steps); + } + + @Override + public Protocol getProtocol() { + return p04; + } + + @Override + public Node getEditor(WorkflowStep step) { + Node result = null; + switch (step) { + case DATASET: { + try { + result = new P04Editor(session); + } catch (IntrospectionException ex) { + Rhomeo.LOGGER.log(Level.WARNING, "Cannot initialize edition panel for P04", ex); + } + } + break; + case PROCESS: + case RESULT: + throw new IllegalStateException("Queried step is invalid for this protocol wizard !"); + } + + return result; + } + + @Override + public Set getStepsToIgnore() { + return toIgnore; + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/P06Editor.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/P06Editor.java new file mode 100644 index 0000000..a4df888 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/P06Editor.java @@ -0,0 +1,161 @@ +/** + * 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.fx.edition; + +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.ui.StatementEditor; +import fr.cenra.rhomeo.api.ui.StatementEditorSpi; +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.protocol.p06.Habitat; +import fr.cenra.rhomeo.protocol.p06.OdonataStatement; +import java.util.Arrays; +import java.util.List; +import javafx.beans.value.ObservableValue; +import javafx.collections.FXCollections; +import javafx.fxml.FXML; +import javafx.scene.control.ComboBox; +import javafx.util.StringConverter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +/** + * + * @author Alexis Manin (Geomatys) + */ +@Component +@Scope("prototype") +public class P06Editor extends AbstractCustomStatementEditor { + + @FXML + private ComboBox uiHabitat; + + public P06Editor() { + super(OdonataStatement.class); + Rhomeo.loadFXML(this, P06Editor.class); + + Rhomeo.initComboBox(uiHabitat, FXCollections.observableList(Arrays.asList(Habitat.values()))); + uiHabitat.valueProperty().addListener(this::habitatChanged); + uiHabitat.setConverter(new StringConverter() { + @Override + public String toString(Habitat object) { + if (object == null) + return null; + return new StringBuilder(object.getCode()).append(" - ").append(object.getValue()).toString(); + } + + @Override + public Habitat fromString(String string) { + if (string == null || (string = string.trim()).isEmpty()) { + return null; + } + + return RhomeoCore.getByCode(Habitat.class, string.split("\\s")[0]).orElse(null); + } + }); + } + + @Override + protected void init(){ + super.init(); + if (uiStatementTable != null) + uiStatementTable.sortColumns(Arrays.asList("cd_nom", "behavior")); + } + + @Override + protected String[] getFieldsToIgnore() { + String[] fieldsToIgnore = super.getFieldsToIgnore(); + fieldsToIgnore = Arrays.copyOf(fieldsToIgnore, fieldsToIgnore.length +1); + fieldsToIgnore[fieldsToIgnore.length -1] = "habitat"; + return fieldsToIgnore; + } + + + @Override + protected OdonataStatement initStatement() throws ReflectiveOperationException { + final OdonataStatement data = super.initStatement(); + if (uiHabitat.getValue() instanceof Habitat) { + data.setHabitat(uiHabitat.getValue().getCode()); + } + + return data; + } + + /* + * UI LISTENERS + */ + + private void habitatChanged(final ObservableValue obs, final Habitat oldPhysio, final Habitat newPhysio) { + final String newCode = newPhysio == null? null : newPhysio.getCode(); + if (uiStatementTable == null || uiStatementTable.getItems() == null) + return; + for (int i = 0 ; i < uiStatementTable.getItems().size() ; i++) { + uiStatementTable.getItems().get(i).habitatProperty().set(newCode); + } + } + + @Override + protected void itemsChanged(final ObservableValue obs, final List oldItems, final List newItems) { + super.itemsChanged(obs, oldItems, newItems); + + if (newItems == null || newItems.isEmpty()) { + uiHabitat.setValue(null); + } else { + uiHabitat.setValue(RhomeoCore.getByCode(Habitat.class, newItems.get(0).getHabitat()).orElse(null)); + } + } + + @Component + public static class Spi implements StatementEditorSpi { + + @Autowired + Session session; + + @Override + public StatementEditor createEditor() { + return session.createPrototype(P06Editor.class); + } + + @Override + public Class getDataType() { + return OdonataStatement.class; + } + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/PropertyColumn.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/PropertyColumn.java new file mode 100644 index 0000000..1bf19cf --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/PropertyColumn.java @@ -0,0 +1,728 @@ +/** + * 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.fx.edition; + +import com.vividsolutions.jts.geom.Geometry; +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.Version; +import fr.cenra.rhomeo.api.annotations.RefersTo; +import fr.cenra.rhomeo.api.data.Reference; +import fr.cenra.rhomeo.api.data.Warning; +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.data.reference.Taxref; +import fr.cenra.rhomeo.core.util.RelationResolver; +import java.beans.PropertyDescriptor; +import java.lang.ref.WeakReference; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Function; +import java.util.logging.Level; +import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.beans.value.WritableValue; +import javafx.collections.MapChangeListener; +import javafx.event.EventHandler; +import javafx.scene.Node; +import javafx.scene.control.ComboBox; +import javafx.scene.control.Label; +import javafx.scene.control.TableCell; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TablePosition; +import javafx.scene.control.TableView; +import javafx.scene.control.Tooltip; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; +import javafx.scene.input.MouseEvent; +import javafx.scene.layout.Region; +import javafx.util.StringConverter; +import javax.validation.ConstraintViolation; +import javax.validation.Validator; +import org.apache.sis.parameter.ParameterBuilder; +import org.apache.sis.util.ArgumentChecks; +import org.apache.sis.util.Numbers; +import org.geotoolkit.font.FontAwesomeIcons; +import org.geotoolkit.gui.javafx.parameter.FXValueEditor; +import org.geotoolkit.gui.javafx.parameter.FXValueEditorSpi; +import org.geotoolkit.gui.javafx.util.ComboBoxCompletion; +import org.opengis.parameter.ParameterDescriptor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +/** + * A column whose aim is to display and offer edition capabilities on a specific + * POJO property. The display / edition capabilities are computed using reflection. + * + * @author Alexis Manin (Geomatys) + * @param Type of object found in a row of the parent table. + */ +@Component +@Scope("prototype") +public class PropertyColumn extends TableColumn { + + static final KeyHandler KEY_HANDLER = new KeyHandler(); + + static final StringConverter BASIC_CONVERTER = new BasicConverter(); + + @Autowired + private Validator validator; + + @Autowired + RelationResolver resolver; + + /** + * Descriptor of the property to manage in the column (property extracted + * from a row item). + */ + final PropertyDescriptor descriptor; + /** + * A boolean indicating if {@link #observableGetter} implements {@link WritableValue} + * interface. + */ + final boolean isWritableValue; + /** + * A method extracted from input {@link PropertyDescriptor} to write target + * property. + */ + final Method writeMethod; + /** + * A method extracted from input {@link PropertyDescriptor} to read target + * property. + */ + final Method readMethod; + /** + * A method with no parameter, whose aim is to send back an observable + * object on target property. + */ + final Method observableGetter; + /** + * An annotation extracted from getters to know if the property to manage + * is referring to another object. + */ + final RefersTo referent; + + public final SimpleObjectProperty editorProperty = new SimpleObjectProperty<>(); + + // Hack for issue #75 + final boolean isSpecies; + + /** + * A weak bound to the converter used for transformation of column values + * in text. We use weak reference here mainly because of application + * {@link Reference} which are loaded asynchronously (user can change used + * version, etc.). Also, it avoid to keep a (possibly) consequent memory + * chunk when not needed. + */ + private WeakReference textConverterRef; + + public PropertyColumn(final PropertyDescriptor desc, final Method observableGetter) { + super(); + ArgumentChecks.ensureNonNull("Property descriptor", desc); + Session.getInstance().injectDependencies(this); + descriptor = desc; + writeMethod = desc.getWriteMethod(); + readMethod = desc.getReadMethod(); + this.observableGetter = observableGetter; + /* + * Analyze given parameters to determine how to handle cell content. + */ + boolean tmpIsProperty = false; + boolean isObservableValue = false; + if (observableGetter != null) { + Class observableType = observableGetter.getReturnType(); + if (WritableValue.class.isAssignableFrom(observableType)) { + tmpIsProperty = true; + } else if (ObservableValue.class.isAssignableFrom(observableType)) { + isObservableValue = true; + } + } + + isWritableValue = tmpIsProperty; + + if (isWritableValue || isObservableValue) { + setCellValueFactory((param) -> { + try { + return (ObservableValue) observableGetter.invoke(param.getValue()); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { + RhomeoCore.LOGGER.log(Level.WARNING, "Cannot acces observable property ".concat(desc.getName()), ex); + return null; + } + }); + + } else if (readMethod != null) { + readMethod.setAccessible(true); + setCellValueFactory((param) -> { + try { + return new SimpleObjectProperty<>(readMethod.invoke(param.getValue())); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { + RhomeoCore.LOGGER.log(Level.WARNING, "Cannot acces property ".concat(desc.getName()), ex); + return null; + } + }); + + } else { + throw new IllegalArgumentException("Cannot extract values from given property descriptor !"); + } + + RefersTo tmpReferent = null; + if (readMethod != null) { + tmpReferent = readMethod.getAnnotation(RefersTo.class); + } + + if (tmpReferent == null && observableGetter != null) { + tmpReferent = observableGetter.getAnnotation(RefersTo.class); + } + referent = tmpReferent; + + // Hack #75 + isSpecies = referent == null? false : referent.property().equals(Taxref.ATT_CD_NOM); + + /* When editing a property pointing on a reference, we listen on data + * context changes to update choice list when user change the version + * used. + */ + if (referent != null && Reference.class.isAssignableFrom(referent.type())) { + try { + Session.getInstance().getDataContext().getReferences().addListener((MapChangeListener.Change, ? extends Version> change) -> { + if (referent.type().equals(change.getKey())) { + initEditor(); + } + }); + } catch (Exception e) { + Rhomeo.LOGGER.log(Level.FINE, "Cannot listen on data context changes.", e); + } + } + + initEditor(); + + setCellFactory(this::createPropertyCell); + + editableProperty().bind(editorProperty.isNotNull()); + setText(desc.getDisplayName()); + + String remarks = desc.getShortDescription(); + if (remarks != null && !remarks.equals(desc.getDisplayName()) && !(remarks = remarks.trim()).isEmpty()) { + final Label label = new Label(FontAwesomeIcons.ICON_INFO_CIRCLE); + label.setTooltip(new Tooltip(remarks)); + label.setStyle("-fx-font-family: FontAwesome; -fx-font-size:16;"); + setGraphic(label); + } + + // # 86 : Compare species using their name + if (isSpecies) { + setComparator((o1, o2) -> { + if (o1 == o2) // both null or same reference + return 0; + else if (o1 == null) + return 1; + else if (o2 == null) + return -1; + else if (o1.equals(o2)) + return 0; + + final StringConverter converter = getOrCreateTextConverter(); + final String s1 = converter.toString(o1); + final String s2 = converter.toString(o2); + if (s1 == s2) // both null or same reference + return 0; + else if (s1 == null) + return 1; + else if (s2 == null) + return -1; + + return s1.compareTo(s2); + }); + } + } + + private void initEditor() { + /* If there is writing possibility, we try to setup an editor for the + * column cells. + */ + if (isWritableValue || writeMethod != null) { + Set possibleValues = null; + if (referent != null) { + try { + possibleValues = resolver.getPossibleValues(referent); + } catch (Exception ex) { + RhomeoCore.LOGGER.log(Level.WARNING, "Cannot load choice list for property ".concat(descriptor.getName()), ex); + } + } + + final ParameterDescriptor parameterDescriptor; + final ParameterBuilder builder = new ParameterBuilder().addName(descriptor.getName()).setRequired(false); + if (possibleValues != null) { + parameterDescriptor = builder.createEnumerated((Class) Numbers.primitiveToWrapper(descriptor.getPropertyType()), possibleValues.toArray(), null); + } else { + parameterDescriptor = builder.create(descriptor.getPropertyType(), null); + } + + Optional editor = FXValueEditorSpi.findEditor(parameterDescriptor); + if (editor.isPresent()) { + // If given editor is a combo box, we activate auto-completion on it. + final FXValueEditor tmpEditor = editor.get(); + Optional optCombo = Rhomeo.findComboBox(tmpEditor.getComponent()); + if (optCombo.isPresent()) { + ComboBox cBox = optCombo.get(); + // See ComboBoxListViewSkin + cBox.getProperties().put("comboBoxRowsToMeasureWidth", 7); + setConverter(cBox); + try { + cBox.setEditable(true); + } catch (RuntimeException e) { + // A runtime exception is launched if the editable property is already bound + // Just log and let the property bound and handled by something else. + Rhomeo.LOGGER.log(Level.FINE, e.getLocalizedMessage(), e); + } + ComboBoxCompletion.autocomplete(cBox); + // HACK : Force auto-completion to reset when starting edition. + cBox.focusedProperty().addListener((obs, oldVal, newVal) -> { + if (newVal) + cBox.fireEvent(new KeyEvent(KeyEvent.KEY_RELEASED, "", "", KeyCode.UNDEFINED, false, false, false, false)); + }); + } else { + Rhomeo.prepareSpinners(tmpEditor.getComponent()); + } + editorProperty.set(tmpEditor); + } + } + } + + private PropertyCell createPropertyCell(TableColumn column) { + return new PropertyCell(); + } + + public PropertyDescriptor getTarget() { + return descriptor; + } + + private void setConverter(ComboBox cBox) { + final StringConverter baseConverter = getOrCreateTextConverter(); + final StringConverter converter = new StringConverter() { + @Override + public String toString(Object object) { + return baseConverter.toString(object); + } + + @Override + public Object fromString(String string) { + if (string == null || string.isEmpty()) + return null; + final Object firstGuess = baseConverter.fromString(string); + if (firstGuess == null) { + for (final Object o : cBox.getItems()) { + if (Objects.equals(string, o.toString())) + return o; + } + } + + return null; + } + }; + + cBox.setConverter(converter); + } + + /** + * Create a converter for the elements of this column. + * @return A converter to display this column elements as text. Never null. + */ + private StringConverter getOrCreateTextConverter() { + StringConverter converter = textConverterRef == null? null : textConverterRef.get(); + if (converter != null) + return converter; + + if (referent != null) { + try { + final Set targets = resolver.getTargetObjects(referent); + final Function extractor = RelationResolver.acquireExtractor(referent); + final HashMap refMap = new HashMap<>(targets.size()); + for (final Object o : targets) { + refMap.put(extractor.apply(o), o.toString()); + } + + converter = new StringConverter() { + @Override + public String toString(Object object) { + if (object == null || (isSpecies && object.equals(0))) + return null; + final String str = refMap.get(object); + if (str != null) + return str; + return BASIC_CONVERTER.toString(object); + } + + @Override + public Object fromString(String string) { + if (string == null || string.isEmpty()) + return null; + + for (final Map.Entry entry : refMap.entrySet()) { + if (string.equals(entry.getValue())) { + return entry.getKey(); + } + } + + return BASIC_CONVERTER.fromString(string); + } + }; + } catch (Exception e) { + Rhomeo.LOGGER.log(Level.FINE, "Cannot tune combobox cells.", e); + } + } + + if (converter == null) { + return BASIC_CONVERTER; + } else { + textConverterRef = new WeakReference<>(converter); + return converter; + } + } + + /** + * A cell for rendering and edition of a property. + */ + private class PropertyCell extends AutoCommitableTableCell { + + /** + * A boolean to know if we're in edition state or not. We store a local + * variable here, because when calling {@link TableCell#startEdit() }, + * the edition flag is updated AFTER item update. If we do not want to + * update the view twice on state change, we have to locally store edition + * state, then calling super.startEdit(). + */ + boolean edition = false; + + EventHandler enteredOnError; + + final ChangeListener focusListener = this::focusChanged; + + @Override + public void cancelEdit() { + edition = false; + super.cancelEdit(); + updateItem(getTableColumn().getCellData(getTableRow().getIndex()), false); + removeKeyHandling(); + } + + @Override + public void commitEdit() { + commitEdit(editorProperty.get().valueProperty().getValue()); + } + + @Override + public void commitEdit(Object newValue) { + if (isWritableValue) { + WritableValue property = (WritableValue) getTableColumn().getCellObservableValue(getTableRow().getIndex()); + property.setValue(newValue); + } else { + try { + writeMethod.invoke(getTableRow().getItem(), newValue); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { + RhomeoCore.LOGGER.log(Level.WARNING, "Cannot commit value !", ex); + } + } + + edition = false; + super.commitEdit(newValue); + removeKeyHandling(); + editorProperty.get().getComponent().removeEventHandler(KeyEvent.KEY_RELEASED, KEY_HANDLER); + } + + @Override + public void startEdit() { + edition = true; // Set to true for view update. + super.startEdit(); + if (!(edition = isEditing())) + return; + + final FXValueEditor editor = editorProperty.get(); + if (editor == null || + !(isWritableValue || writeMethod != null)) { + throw new IllegalStateException("Cannot start edition on not editable cell."); + } + + // Init editor value from cell content. + editor.valueProperty().setValue(getItem()); + + addKeyHandling(); + } + + @Override + protected void updateItem(Object item, boolean empty) { + super.updateItem(item, empty); + + if (edition && !empty) { + setText(null); + Node node = editorProperty.get().getComponent(); + if (node instanceof Region) { + final Region r = (Region) node; + r.setMinSize(0, 0); + r.prefWidthProperty().bind(prefWidthProperty()); + r.prefHeightProperty().bind(prefHeightProperty()); + } + setGraphic(node); + Optional opt = Rhomeo.findComboBox(node); + if (opt.isPresent()) { + node = opt.get(); + } + + node.requestFocus(); + node.focusedProperty().addListener(focusListener); + + } else { + removeGraphic(); + if (empty) { + setText(null); + } else { + setText(getOrCreateTextConverter().toString(item)); + } + } + + checkValue(item, empty); + } + + private void focusChanged(final ObservableValue obs, final Boolean oldValue, final boolean newValue) { + if (edition && !newValue) { + commitEdit(); + } + } + + /** + * Remove the graphic attached to the cell, freeing its previously bound + * properties in the same time. + */ + private void removeGraphic() { + Node graphic = getGraphic(); + if (graphic != null) { + if (graphic instanceof Region) { + final Region r = (Region) graphic; + r.prefWidthProperty().unbind(); + r.prefHeightProperty().unbind(); + } + + Optional opt = Rhomeo.findComboBox(graphic); + if (opt.isPresent()) { + graphic = opt.get(); + } + graphic.focusedProperty().removeListener(focusListener); + } + setGraphic(null); + } + + public void checkValue(final Object value, final boolean isEmpty) { + final Object rowItem; + if (isEmpty || getTableRow() == null) { + rowItem = null; + } else { + rowItem = getTableRow().getItem(); + } + + final Set result; + if (rowItem == null) { // Empty cell + result = Collections.EMPTY_SET; + } else { + result = validator.validateValue((Class) rowItem.getClass(), + PropertyColumn.this.descriptor.getName(), + value + ); + } + + if (!result.isEmpty()) { + int warningNumber = 0; + for (final ConstraintViolation cv : result) { + if (cv.getConstraintDescriptor().getPayload().contains(Warning.class)) + warningNumber++; + } + + if (warningNumber >= result.size()) { + if (!getStyleClass().contains(Rhomeo.CSS_WARNING_FIELD)) { + getStyleClass().add(Rhomeo.CSS_WARNING_FIELD); + } + } else if (!getStyleClass().contains(Rhomeo.CSS_ERROR_FIELD)) { + getStyleClass().add(Rhomeo.CSS_ERROR_FIELD); + } + + // Activate a tootltip to give user information about what happens. + createErrorTooltip(result).ifPresent(tip -> setTooltip(tip)); + } else { + setTooltip(null); + getStyleClass().removeAll(Rhomeo.CSS_ERROR_FIELD, Rhomeo.CSS_WARNING_FIELD); + } + } + + /** + * Create a tooltip listing error message of input violations. + * @param errors Errors to display. + * @return An empty optional if input list was null or empty. A tooltip + * with input error messages otherwise. + */ + private Optional createErrorTooltip(final Collection errors) { + if (errors == null || errors.isEmpty()) + return Optional.empty(); + final String text; + if (errors.size() == 1) { + text = errors.iterator().next().getMessage(); + } else { + final Iterator it = errors.iterator(); + final StringBuilder builder = new StringBuilder("∙ "); + if (it.hasNext()) + builder.append(it.next().getMessage()); + while (it.hasNext()) { + builder.append(System.lineSeparator()).append("∙ ").append(it.next().getMessage()); + } + text = builder.toString(); + } + + final Tooltip tip = new Tooltip(text); + tip.getStyleClass().add("info-popup"); + + return Optional.of(tip); + } + + /** + * Set the {@link #KEY_HANDLER} to listen on key events on the given + * cell. The event listener is meant to listen for actions on a cell + * being in edition mode. + * + * Note : If the handler was already listening on another cell, its + * unregistered before setting input cell. + * + * @param target The table cell to activate Key event handling on. + */ + private void addKeyHandling() { + if (KEY_HANDLER.target != null) { + removeKeyHandling(); + } + + KEY_HANDLER.target = this; + addEventHandler(KeyEvent.KEY_RELEASED, KEY_HANDLER); + addEventFilter(KeyEvent.ANY, KEY_HANDLER); + editorProperty.get().getComponent().addEventHandler(KeyEvent.KEY_RELEASED, KEY_HANDLER); + } + + /** + * Set the {@link #KEY_HANDLER} to stop listening on given cell. + * + * @param target The cell to deactivate key event handling for. + */ + private void removeKeyHandling() { + if (KEY_HANDLER != null && KEY_HANDLER.target != null) { + KEY_HANDLER.target.removeEventHandler(KeyEvent.KEY_RELEASED, KEY_HANDLER); + KEY_HANDLER.target.removeEventFilter(KeyEvent.ANY, KEY_HANDLER); + editorProperty.get().getComponent().removeEventHandler(KeyEvent.KEY_RELEASED, KEY_HANDLER); + KEY_HANDLER.target = null; + } + } + } + + /** + * Listens on keyboard key release on a given table cell. Default listeners are : + * - ENTER : commit edit + * - TAB : commit edit then edit next column. If no more column is available, + * start editing first column of the next row. + * - ESC : cancel edit. + */ + static class KeyHandler implements EventHandler { + + AutoCommitableTableCell target; + + @Override + public void handle(KeyEvent evt) { + if (target == null) + return; + + if (KeyEvent.KEY_RELEASED.equals(evt.getEventType())) { + switch (evt.getCode()) { + case ENTER: + target.commitEdit(); + evt.consume(); + break; + case TAB: + final TableView tableView = target.getTableView(); + TablePosition currentCell = tableView.getEditingCell(); + if (currentCell == null) + currentCell = new TablePosition(tableView, 0, null); + target.commitEdit(); + Rhomeo.editNextCell(currentCell); + evt.consume(); + break; + case ESCAPE: + target.cancelEdit(); + evt.consume(); + } + } else { + // Filter events + switch (evt.getCode()) { + case TAB: + evt.consume(); + } + } + } + } + + private static class BasicConverter extends StringConverter { + + @Override + public String toString(Object object) { + if (object instanceof Geometry) { + return "Objet trop complexe pour affichage"; + } else if (object != null && Numbers.isFloat(object.getClass())) { + return RhomeoCore.SECOND_DECIMAL_FORMAT.format(object); + } else { + return String.valueOf(object); + } + } + + @Override + public Object fromString(String string) { + return null; + } + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/StatementTable.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/StatementTable.java new file mode 100644 index 0000000..f82b719 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/edition/StatementTable.java @@ -0,0 +1,60 @@ +/** + * 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.fx.edition; + +import fr.cenra.rhomeo.api.data.Statement; +import java.beans.IntrospectionException; +import javafx.collections.transformation.SortedList; + +/** + * + * @author Alexis Manin (Geomatys) + * @param Type of row items. + */ +public class StatementTable extends ObjectTable { + + public StatementTable(Class objectType, String... blackList) throws IntrospectionException { + super(objectType, blackList); + itemsProperty().addListener((obs, oldValue, newValue) -> { + if (newValue instanceof SortedList) { + ((SortedList)newValue).comparatorProperty().bind(comparatorProperty()); + } + }); + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/p08/FXGeoReferentialTable.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/p08/FXGeoReferentialTable.java new file mode 100644 index 0000000..a5852bf --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/p08/FXGeoReferentialTable.java @@ -0,0 +1,282 @@ + +/** + * 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.fx.p08; + +import fr.cenra.rhomeo.api.data.Site; +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.data.reference.GeoReferential; +import fr.cenra.rhomeo.core.data.reference.GeoReferentials; +import java.util.ArrayList; +import java.util.StringJoiner; +import java.util.logging.Level; +import javafx.application.Platform; +import javafx.beans.property.SimpleIntegerProperty; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.concurrent.Task; +import javafx.event.ActionEvent; +import javafx.event.Event; +import javafx.event.EventHandler; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.control.Alert; +import javafx.scene.control.Button; +import javafx.scene.control.ButtonType; +import javafx.scene.control.CheckBox; +import javafx.scene.control.Label; +import javafx.scene.control.ProgressIndicator; +import javafx.scene.control.TableCell; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableRow; +import javafx.scene.control.TableView; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.layout.HBox; +import javafx.scene.layout.VBox; +import org.geotoolkit.gui.javafx.util.FXTableView; +import org.geotoolkit.gui.javafx.util.TaskManager; + +/** + * Table to download referential data for a site. + * + * @author Johann Sorel (Geomatys) + */ +public class FXGeoReferentialTable extends VBox { + + private static final Image CHECKED = new Image("/fr/cenra/rhomeo/fx/p08/u74.png"); + + private final GeoReferentials geoRef; + private final Site site; + private final TableView table = new FXTableView<>(); + private final Button downloadButton = new Button("Télécharger"); + private final ProgressIndicator progress = new ProgressIndicator(); + private final String[] requiredTypes; + + final TableColumn colAvailable; + + public FXGeoReferentialTable(GeoReferentials geoRef,Site site, String ... requieredTypes){ + this.geoRef = geoRef; + this.site = site; + this.requiredTypes = requieredTypes; + + progress.setProgress(-1); + progress.setVisible(false); + progress.setPrefSize(32, 32); + progress.setMinSize(32, 32); + + downloadButton.getStyleClass().add("create-button"); + downloadButton.setStyle("-fx-text-fill: #FFFFFF;"); + downloadButton.managedProperty().bind(downloadButton.visibleProperty()); + downloadButton.setPadding(new Insets(5, 20, 5, 20)); + final HBox box = new HBox(progress,downloadButton); + box.setPadding(new Insets(5, 5, 5, 5)); + box.setAlignment(Pos.CENTER_RIGHT); + getChildren().addAll(table, box); + + //table structure + final TableColumn colAnnees = new TableColumn<>("Années disponibles"); + colAvailable = new TableColumn<>("Années téléchargées sur le poste"); + final TableColumn colDownload = new TableColumn<>("Années à télécharger"); + colAnnees.setCellValueFactory(param -> new SimpleIntegerProperty(param.getValue().getYear()).asObject()); + colAvailable.setCellValueFactory((TableColumn.CellDataFeatures param) -> param.getValue().completed(requiredTypes)); + colAvailable.setCellFactory((TableColumn param) -> new AvailableCell()); + colDownload.setCellValueFactory((TableColumn.CellDataFeatures param) -> param.getValue().toDownloadProperty()); + colDownload.setCellFactory((TableColumn param) -> new DownloadCell()); + + table.getColumns().addAll(colAnnees, colAvailable, colDownload); + table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + + downloadButton.setOnAction(this::downloadRef); + + updateRefTable(); + } + + private void updateRefTable(){ + final Task> update = new Task>() { + @Override + protected ObservableList call() throws Exception { + updateTitle("Mise à jour des références"); + final ObservableList referentials = geoRef.getReferentials(site); + //remove referentials which don't have all required data + for (int i = referentials.size() - 1; i >= 0; i--) { + if (!referentials.get(i).areAvailable(requiredTypes)) { + referentials.remove(i); + } + } + return referentials; + } + }; + + update.setOnSucceeded(evt -> Platform.runLater(() -> { + table.setItems(update.getValue()); + })); + + update.setOnFailed(evt -> Platform.runLater(() -> { + final Throwable ex = evt.getSource().getException(); + table.setPlaceholder(new Label(ex.getLocalizedMessage())); + table.setItems(FXCollections.emptyObservableList()); + RhomeoCore.LOGGER.log(Level.WARNING, ex.getLocalizedMessage(),ex); + })); + + progress.visibleProperty().bind(update.runningProperty()); + TaskManager.INSTANCE.submit(update); + } + + private void downloadRef(ActionEvent event) { + + final Task task = new Task() { + @Override + protected Object call() throws Exception { + int selectedYears = 0; + final ArrayList failedYears = new ArrayList(); + for (GeoReferential ref : table.getItems()) { + if (ref.toDownloadProperty().get()) { + selectedYears++; + updateTitle("Téléchargement ".concat(String.valueOf(ref.getYear()))); + try { + geoRef.downloadReferential(site, ref.getYear()); + } catch (IllegalArgumentException e) { + failedYears.add(ref.getYear()); + } + } + } + + if (selectedYears < 1) { + Platform.runLater(() -> { + final Alert alert = new Alert(Alert.AlertType.WARNING, "Aucune année séléctionnée pour le téléchargement.", ButtonType.CLOSE); + alert.setResizable(true); + alert.show(); + }); + + } else if (!failedYears.isEmpty()) { + final String msg; + if (failedYears.size() < selectedYears) { + final StringJoiner builder = new StringJoiner(", ", "Aucun référentiel n'est disponible pour la zone demandée en ", "."); + failedYears.stream() + .map(year -> String.valueOf(year)) + .forEach(year -> builder.add(year)); + msg = builder.toString(); + } else { + msg = "Aucun référentiel n'est disponible pour les années demandées"; + } + Platform.runLater(() -> { + final Alert alert = new Alert(Alert.AlertType.WARNING, msg, ButtonType.CLOSE); + alert.setResizable(true); + alert.show(); + }); + } + return true; + } + }; + + progress.visibleProperty().bind(task.runningProperty()); + downloadButton.visibleProperty().bind(task.runningProperty().not()); + // TODO : display message on illegal argument exception : no data available. + final EventHandler e = (EventHandler) (Event event1) -> updateRefTable(); + + task.setOnSucceeded(e); + task.setOnFailed(evt -> { + if (evt.getSource().getException() instanceof IllegalArgumentException) { + final Alert alert = new Alert(Alert.AlertType.WARNING, "Aucun référentiel n'est disponible pour la zone demandée en ", ButtonType.CLOSE); + alert.setResizable(true); + alert.show(); + } + e.handle(evt); + }); + task.setOnCancelled(e); + TaskManager.INSTANCE.submit(task); + } + + public ObservableList getItems() { + return table.getItems(); + } + + private static class AvailableCell extends TableCell{ + + public AvailableCell() { + } + + @Override + protected void updateItem(Boolean item, boolean empty) { + super.updateItem(item, empty); + if(Boolean.TRUE.equals(item)){ + setGraphic(new ImageView(CHECKED)); + }else{ + setText(null); + setGraphic(null); + } + } + } + + private class DownloadCell extends TableCell { + + private final CheckBox checkBox = new CheckBox(); + + private DownloadCell() { + setGraphic(checkBox); + + checkBox.setOnAction((ActionEvent event) -> { + TableRow row = tableRowProperty().getValue(); + if (row == null) + return; + final GeoReferential r = (GeoReferential) row.getItem(); + if (r != null) { + r.toDownloadProperty().set(checkBox.isSelected()); + } + }); + } + + @Override + protected void updateItem(Boolean item, boolean empty) { + super.updateItem(item, empty); + + checkBox.setVisible(!empty); + checkBox.setSelected(Boolean.TRUE.equals(item)); + + TableRow row = tableRowProperty().getValue(); + if (row == null) + return; + final GeoReferential r = (GeoReferential) row.getItem(); + if (r != null) { + checkBox.setVisible(!colAvailable.getCellData(r)); + } + } + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/p08/FXP08DatasetPane.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/p08/FXP08DatasetPane.java new file mode 100644 index 0000000..71fe302 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/p08/FXP08DatasetPane.java @@ -0,0 +1,220 @@ + +/** + * 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.fx.p08; + +import com.vividsolutions.jts.geom.Geometry; +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.data.Site; +import fr.cenra.rhomeo.api.process.Indicator; +import fr.cenra.rhomeo.api.process.ProcessContext; +import fr.cenra.rhomeo.core.BeanUtils; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.WorkflowStep; +import fr.cenra.rhomeo.core.data.county.CountyRepository; +import fr.cenra.rhomeo.core.data.reference.GeoReferential; +import fr.cenra.rhomeo.core.data.reference.GeoReferentials; +import fr.cenra.rhomeo.core.util.GeometryUtils; +import fr.cenra.rhomeo.protocol.p08.I12; +import java.awt.Color; +import java.util.List; +import java.util.Optional; +import java.util.logging.Level; +import java.util.stream.Collectors; +import javafx.collections.ObservableList; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.control.Alert; +import javafx.scene.control.Button; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.VBox; +import javax.annotation.PostConstruct; +import org.geotoolkit.data.FeatureStoreUtilities; +import org.geotoolkit.data.bean.BeanFeature; +import org.geotoolkit.display2d.GO2Utilities; +import org.geotoolkit.feature.Feature; +import org.geotoolkit.feature.FeatureBuilder; +import org.geotoolkit.gui.javafx.render2d.FXMapFrame; +import org.geotoolkit.map.FeatureMapLayer; +import org.geotoolkit.map.MapBuilder; +import org.geotoolkit.map.MapContext; +import org.geotoolkit.map.MapItem; +import org.geotoolkit.map.MapLayer; +import org.geotoolkit.style.MutableStyleFactory; +import org.opengis.feature.Property; +import org.opengis.filter.FilterFactory2; +import org.opengis.filter.expression.PropertyName; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +/** + * + * @author Johann Sorel (Geomatys) + */ +@Component +@Scope("prototype") +public class FXP08DatasetPane extends VBox { + + @Autowired + private Session session; + + @Autowired + private GeoReferentials geoRef; + + @Autowired + @Qualifier(I12.NAME) + private Indicator indicator; + + @FXML + private Button next; + + @FXML + private BorderPane tableSpace; + + @Autowired(required = false) + private CountyRepository countyRepository; + + private FXGeoReferentialTable table; + + public FXP08DatasetPane() { + Rhomeo.loadFXML(this); + } + + @PostConstruct + private void postConstruct() { + table = new FXGeoReferentialTable(geoRef, session.getDataContext().getSite(), + GeoReferentials.TYPE_ZONE_HYDRO, + GeoReferentials.TYPE_TACHE_ARTIF, + GeoReferentials.TYPE_TACHE_URBAINE); + tableSpace.setCenter(table); + } + + @FXML + void nextStep(ActionEvent event) { + + //check there is at least one year of data available + int nbAvailable = 0; + final ObservableList items = table.getItems(); + for(GeoReferential ref : items){ + //we need zone hydro,tache artif and tache_urbaine + if(ref.zoneHydroLocal().get() + && ref.tacheArtifLocal().get() + && ref.tacheUrbaineLocal().get()) nbAvailable++; + } + + if (nbAvailable <= 0) { + Rhomeo.showAlert(Alert.AlertType.WARNING, "Impossible de passer à l'étape suivante : Aucun réferentiel téléchargé."); + return; + } + + final ProcessContext ctx = new ProcessContext(session.getDataset(), session.getDataContext()); + ctx.getIndicators().add(indicator); + session.setProcessContext(ctx); + + if (!session.requestWorkflowStep(WorkflowStep.PROCESS)) { + Rhomeo.showAlert(Alert.AlertType.WARNING, "Impossible de passer à l'étape suivante. Veuillez vérifier votre lot de données."); + } + } + + @FXML + private void showMap() throws Exception { + final Site currentSite = session.getDataContext().getSite(); + // Should not be null when called here + if (currentSite == null) { + throw new IllegalArgumentException("Currently selected site was null here, but shouldn't be"); + } + + // If counties are available, we display them on the map. + final MapContext context = MapBuilder.createContext(); + final MutableStyleFactory sf = GO2Utilities.STYLE_FACTORY; + + if (countyRepository != null) { + try { + context.layers().add(MapBuilder.createFeatureLayer(countyRepository.getFeatures(), sf.style(sf.lineSymbolizer()) + )); + } catch (Exception e) { + Rhomeo.LOGGER.log(Level.WARNING, "Cannot show county layer", e); + } + } + + final BeanFeature feature = new BeanFeature(currentSite, BeanUtils.createMapping(Site.class, null)); + final MapLayer layer = MapBuilder.createFeatureLayer(FeatureStoreUtilities.collection(feature), sf.style(sf.polygonSymbolizer(null, sf.fill(Color.red), null))); + layer.setName("Site"); + context.layers().add(layer); + context.setAreaOfInterest(layer.getBounds()); + + Geometry buffer = GeometryUtils.computeBuffer(currentSite.getGeometry()); + final FeatureBuilder fb = new FeatureBuilder(feature.getType()); + for (final Property p : feature.getProperties()) { + if (p.getValue() instanceof Geometry) + fb.setPropertyValue(p.getName(), buffer); + else + fb.setPropertyValue(p.getName(), p.getValue()); + } + final Feature bufferFeature = fb.buildFeature("buffer"); + final FeatureMapLayer bufferLayer = MapBuilder.createFeatureLayer(FeatureStoreUtilities.collection(bufferFeature)); + bufferLayer.setName("Buffer"); + context.layers().add(1, bufferLayer); + + final FilterFactory2 ff = GO2Utilities.FILTER_FACTORY; + final PropertyName geomProp = ff.property("geom"); + + MapItem zoneHydro = geoRef.getWFSLayers(Optional.of(ff.intersects(geomProp, ff.literal(buffer))), GeoReferentials.TYPE_ZONE_HYDRO); + zoneHydro = zoneHydro.items().get(0); + MapItem wfsLayers = geoRef.getWFSLayers(Optional.of(ff.bbox(null, ((MapLayer)zoneHydro).getBounds())), GeoReferentials.TYPE_TACHE_ARTIF, GeoReferentials.TYPE_TACHE_URBAINE, GeoReferentials.TYPE_RPG); + wfsLayers.setName("BBox filtered"); + context.items().add(0, wfsLayers); + + final List geomCollection = ((FeatureMapLayer)zoneHydro).getCollection().stream() + .map(feat -> feat.getDefaultGeometryProperty().getValue()) + .filter(geom -> geom instanceof Geometry) + .map(geom -> (Geometry) geom) + .collect(Collectors.toList()); + Geometry filterGeom = GO2Utilities.JTS_FACTORY.createGeometryCollection(geomCollection.toArray(new Geometry[geomCollection.size()])).union(); + wfsLayers = geoRef.getWFSLayers(Optional.of(ff.intersects(geomProp, ff.literal(filterGeom))), GeoReferentials.TYPE_TACHE_ARTIF, GeoReferentials.TYPE_TACHE_URBAINE, GeoReferentials.TYPE_RPG); + wfsLayers.setName("Polygon filtered"); + context.items().add(1, wfsLayers); + + context.items().add(0, zoneHydro); + + FXMapFrame.show(context); + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/p08/FXP08ProcessPane.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/p08/FXP08ProcessPane.java new file mode 100644 index 0000000..b7111e9 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/p08/FXP08ProcessPane.java @@ -0,0 +1,310 @@ + +/** + * 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.fx.p08; + +import com.vividsolutions.jts.geom.Geometry; +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.data.Site; +import fr.cenra.rhomeo.api.process.Indicator; +import fr.cenra.rhomeo.api.result.Index; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.WorkflowStep; +import fr.cenra.rhomeo.core.util.ExportUtils; +import fr.cenra.rhomeo.core.util.GeometryUtils; +import fr.cenra.rhomeo.protocol.p08.I12; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import javafx.collections.ObservableList; +import javafx.concurrent.Task; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.control.Alert; +import javafx.scene.control.Button; +import javafx.scene.control.CheckBox; +import javafx.scene.layout.HBox; +import javafx.scene.layout.VBox; +import javafx.stage.FileChooser; +import javax.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; +import fr.cenra.rhomeo.api.process.Process; +import fr.cenra.rhomeo.fx.p09.FXP09ProcessPane; +import fr.cenra.rhomeo.core.data.reference.GeoReferential; +import fr.cenra.rhomeo.core.data.reference.GeoReferentials; +import fr.cenra.rhomeo.protocol.p08.I12Process; +import java.nio.ByteBuffer; +import java.nio.IntBuffer; +import java.util.BitSet; +import java.util.Optional; +import java.util.prefs.Preferences; +import javafx.application.Platform; +import javafx.beans.property.SimpleObjectProperty; +import javafx.scene.control.ChoiceDialog; +import org.geotoolkit.gui.javafx.util.TaskManager; +import org.geotoolkit.internal.GeotkFX; + +/** + * + * @author Johann Sorel (Geomatys) + */ +@Component +@Scope("prototype") +public class FXP08ProcessPane extends VBox { + + @Autowired + private Session session; + + @Autowired + private GeoReferentials geoRef; + + @Autowired + @Qualifier(I12.NAME) + private Indicator indicator; + + @FXML + private Button next; + + @FXML + private Button uiExport; + + @FXML + private HBox yearBoxes; + + private final List checkBoxes = new ArrayList<>(); + + private final SimpleObjectProperty>> globalTask = new SimpleObjectProperty<>(); + + private BitSet activatedYears; + + private final Preferences prefs; + + public FXP08ProcessPane(){ + Rhomeo.loadFXML(this); + prefs = Preferences.userNodeForPackage(FXP08ProcessPane.class); + } + + @PostConstruct + private void postConstruct() { + //liste available referential state for this site + final ObservableList refs; + try { + refs = geoRef.getLocalReferentials(session.getDataContext().getSite()) + .filtered(ref -> ref.hasLocalTypes( + GeoReferentials.TYPE_ZONE_HYDRO, + GeoReferentials.TYPE_TACHE_ARTIF, + GeoReferentials.TYPE_TACHE_URBAINE) + ) + .sorted(); + } catch (IllegalArgumentException | IOException ex) { + // If we cannot load georeferentials, it's no use to go further. + GeotkFX.newExceptionDialog("Impossible de déterminer la liste des réferentiels disponibles. La lecture sur le système a échouée.", ex).show(); + session.requestWorkflowStep(WorkflowStep.DATASET); + return; + } + + final ByteBuffer yearsAsBytes = ByteBuffer.wrap(new byte[refs.size() * (Integer.SIZE / Byte.SIZE)]); + final IntBuffer years = yearsAsBytes.asIntBuffer(); + for (final GeoReferential ref : refs) { + years.put(ref.getYear()); + } + years.position(0); + + /* Restore selection state from serialized bitset if possible. To + * determine if restoration is possible, we ensure there's data stored + * in preferences, and also that they match current edited site / years. + * Otherwise, we set a new bitset, with default selection on types 17 + * and 18. + * We do the same with years, except that by default, they're all selected. + */ + final String siteName = session.getDataContext().getSite().getName(); + final boolean restore = prefs.get(FXP09ProcessPane.SITE_NAME, "").equals(siteName) + && ByteBuffer.wrap(prefs.getByteArray(FXP09ProcessPane.AVAILABLE_YEARS, new byte[0])).asIntBuffer().equals(years); + + final byte[] yearSelection; + if (restore && (yearSelection = prefs.getByteArray(FXP09ProcessPane.YEAR_SELECTION, null)) != null) { + activatedYears = BitSet.valueOf(yearSelection); + } else { + activatedYears = new BitSet(refs.size()); + activatedYears.set(0, activatedYears.length()); + } + + // A new session is starting. We initialize preferences for it. + if (!restore) { + prefs.put(FXP09ProcessPane.SITE_NAME, siteName); + prefs.putByteArray(FXP09ProcessPane.AVAILABLE_YEARS, yearsAsBytes.array()); + } + + for (GeoReferential ref : refs) { + final CheckBox check = new CheckBox(String.valueOf(ref.getYear())); + final int index = checkBoxes.size(); + check.setSelected(activatedYears.get(index)); + check.selectedProperty().addListener((obs, oldValue, newValue) -> { + yearSelectionChanged(index, newValue == null? false : newValue); + }); + yearBoxes.getChildren().add(check); + checkBoxes.add(check); + } + } + + private void yearSelectionChanged(final int index, final boolean value) { + activatedYears.set(index, value); + prefs.putByteArray(FXP09ProcessPane.YEAR_SELECTION, activatedYears.toByteArray()); + } + + @FXML + void exportGeometries(ActionEvent event) { + final Site site = session.getDataContext().getSite(); + final FileChooser.ExtensionFilter zipFilter = new FileChooser.ExtensionFilter("Archive zip", "*.zip"); + final File outputFile = Rhomeo.askOutputFilePopup(site.getName()+".zip", this, zipFilter); + + if (outputFile == null) { + return; + } + + int tmpSelectedYear = Integer.MIN_VALUE; + for(final CheckBox c : checkBoxes) { + if (c.isSelected()) { + tmpSelectedYear = Math.max(tmpSelectedYear, Integer.parseInt(c.getText())); + } + } + + final int selectedYear = tmpSelectedYear; + + final ChoiceDialog dialog = new ChoiceDialog<>(ExportUtils.ExportType.GJSON, ExportUtils.ExportType.values()); + dialog.setTitle("Format d'export"); + dialog.setHeaderText("Choisissez un format de sortie"); + dialog.setResizable(true); + dialog.showAndWait().ifPresent(type -> { + Task t = TaskManager.INSTANCE.submit("Export", () -> { + final Geometry buffer = GeometryUtils.computeBuffer(site.getGeometry()); + final Optional territory; + if (selectedYear > Integer.MIN_VALUE) { + territory = geoRef.getLocalReferential(site, selectedYear).unionIntersecting(GeoReferentials.TYPE_ZONE_HYDRO, site.getGeometry()); + } else { + territory = Optional.empty(); + } + ExportUtils.exportSiteAndBuffer(outputFile, site, buffer, territory, type); + return true; + }); + uiExport.disableProperty().unbind(); + uiExport.disableProperty().bind(t.runningProperty()); + }); + } + + @FXML + void nextStep(ActionEvent event) { + + //check there is at least one year of data available + int nbAvailable = 0; + for(CheckBox c : checkBoxes){ + if(c.isSelected()) nbAvailable++; + } + + if (nbAvailable==0) { + Rhomeo.showAlert(Alert.AlertType.WARNING, "Impossible de passer à l'étape suivante : veuillez sélectionner une année."); + return; + } + + final Computer computer = new Computer(); + globalTask.set(computer); + + computer.stateProperty().addListener(obs -> { + if (computer.isDone()) { + setDisable(false); + switch (computer.getState()) { + case FAILED: + Rhomeo.showAlert(Alert.AlertType.ERROR, "process-failed"); + break; + case SUCCEEDED: + session.setResults(computer.getValue()); + globalTask.set(null); + session.requestWorkflowStep(WorkflowStep.RESULT); + break; + } + } + }); + + TaskManager.INSTANCE.submit(computer); + + } + + + private class Computer extends Task> { + + private final List processes = new ArrayList<>(); + + @Override + protected Set call() throws Exception { + processes.addAll(indicator.createProcesses(session.getProcessContext())); + final I12Process process = (I12Process) processes.get(0); + + //configure selected years + for(CheckBox c : checkBoxes){ + if(c.isSelected())process.getYears().add(Integer.valueOf(c.getText())); + } + + updateProgress(-1, -1); + updateTitle("I12"); + + Platform.runLater(() -> { + process.titleProperty().addListener((obs) -> updateTitle(process.getTitle())); + process.messageProperty().addListener((obs) -> updateTitle(process.getMessage())); + process.workDoneProperty().addListener((obs) -> updateProgress(process.getWorkDone(), process.getTotalWork())); + }); + + process.run(); + return (Set) process.get(); + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + for (final Process p : processes) { + p.cancel(true); + } + return super.cancel(mayInterruptIfRunning); + } + } + +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/p08/P08ProtocolEditorSpi.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/p08/P08ProtocolEditorSpi.java new file mode 100644 index 0000000..897eb6c --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/p08/P08ProtocolEditorSpi.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.fx.p08; + +import fr.cenra.rhomeo.api.data.Protocol; +import fr.cenra.rhomeo.api.ui.ProtocolEditorSpi; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.WorkflowStep; +import fr.cenra.rhomeo.protocol.p08.P08; +import java.util.Collections; +import java.util.Set; +import javafx.scene.Node; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +/** + * Protocol 08 editor spi. + * + * @author Johann Sorel (Geomatys) + */ +@Component +public class P08ProtocolEditorSpi implements ProtocolEditorSpi{ + + @Autowired + private Session session; + + @Autowired + @Qualifier(P08.NAME) + private Protocol protocol; + + @Override + public Protocol getProtocol() { + return protocol; + } + + @Override + public Node getEditor(WorkflowStep step) { + switch(step){ + case DATASET : return session.getBean(FXP08DatasetPane.class); + case PROCESS : return session.getBean(FXP08ProcessPane.class); + default : return null; + } + } + + @Override + public Set getStepsToIgnore() { + return Collections.EMPTY_SET; + } + +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/p09/FXP09DatasetPane.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/p09/FXP09DatasetPane.java new file mode 100644 index 0000000..961f722 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/p09/FXP09DatasetPane.java @@ -0,0 +1,125 @@ + +/** + * 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.fx.p09; + +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.process.Indicator; +import fr.cenra.rhomeo.api.process.ProcessContext; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.WorkflowStep; +import fr.cenra.rhomeo.fx.p08.FXGeoReferentialTable; +import fr.cenra.rhomeo.core.data.reference.GeoReferential; +import fr.cenra.rhomeo.core.data.reference.GeoReferentials; +import fr.cenra.rhomeo.protocol.p09.I13; +import javafx.collections.ObservableList; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.control.Alert; +import javafx.scene.control.Button; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.VBox; +import javax.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +/** + * + * @author Johann Sorel (Geomatys) + */ +@Component +@Scope("prototype") +public class FXP09DatasetPane extends VBox { + + @Autowired + private Session session; + @Autowired + private GeoReferentials geoRef; + + @Autowired + @Qualifier(I13.NAME) + private Indicator indicator; + + @FXML + private Button next; + @FXML + private BorderPane tableSpace; + + private FXGeoReferentialTable table; + + public FXP09DatasetPane() { + Rhomeo.loadFXML(this); + } + + @PostConstruct + private void postConstruct(){ + table = new FXGeoReferentialTable(geoRef, session.getDataContext().getSite(), + GeoReferentials.TYPE_ZONE_HYDRO, + GeoReferentials.TYPE_RPG); + tableSpace.setCenter(table); + } + + @FXML + void nextStep(ActionEvent event) { + + //check there is at least one year of data available + int nbAvailable = 0; + final ObservableList items = table.getItems(); + for(GeoReferential ref : items){ + //we need zone hydro,tache artif and tache_urbaine + if(ref.zoneHydroLocal().get() + && ref.rpgLocal().get()) nbAvailable++; + } + + if (nbAvailable==0) { + Rhomeo.showAlert(Alert.AlertType.WARNING, "Impossible de passer à l'étape suivante : la saisie n'est pas valide."); + return; + } + + final ProcessContext ctx = new ProcessContext(session.getDataset(), session.getDataContext()); + ctx.getIndicators().add(indicator); + session.setProcessContext(ctx); + + if (!session.requestWorkflowStep(WorkflowStep.PROCESS)) { + Rhomeo.showAlert(Alert.AlertType.WARNING, "Impossible de passer à l'étape suivante. Veuillez vérifier votre lot de données."); + } + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/p09/FXP09ProcessPane.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/p09/FXP09ProcessPane.java new file mode 100644 index 0000000..9390672 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/p09/FXP09ProcessPane.java @@ -0,0 +1,383 @@ + +/** + * 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.fx.p09; + +import com.vividsolutions.jts.geom.Geometry; +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.data.Site; +import fr.cenra.rhomeo.api.process.Indicator; +import fr.cenra.rhomeo.api.result.Index; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.WorkflowStep; +import fr.cenra.rhomeo.core.data.reference.GeoReferential; +import fr.cenra.rhomeo.core.data.reference.GeoReferentials; +import fr.cenra.rhomeo.core.util.GeometryUtils; +import fr.cenra.rhomeo.protocol.p09.I13; +import fr.cenra.rhomeo.protocol.p09.I13Process; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import javafx.beans.property.SimpleObjectProperty; +import javafx.collections.ObservableList; +import javafx.concurrent.Task; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.control.Alert; +import javafx.scene.control.Button; +import javafx.scene.control.CheckBox; +import javafx.scene.layout.HBox; +import javafx.scene.layout.VBox; +import javafx.stage.FileChooser; +import javax.annotation.PostConstruct; +import org.geotoolkit.gui.javafx.util.TaskManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; +import fr.cenra.rhomeo.api.process.Process; +import fr.cenra.rhomeo.core.util.ExportUtils; +import java.nio.ByteBuffer; +import java.nio.IntBuffer; +import java.util.BitSet; +import java.util.Optional; +import java.util.prefs.Preferences; +import javafx.application.Platform; +import javafx.scene.control.ChoiceDialog; +import javafx.scene.layout.GridPane; +import org.geotoolkit.internal.GeotkFX; + +/** + * + * @author Johann Sorel (Geomatys) + */ +@Component +@Scope("prototype") +public class FXP09ProcessPane extends VBox { + + public static final String SITE_NAME = "site_name"; + public static final String AVAILABLE_YEARS = "available_years"; + private static final String TYPE_SELECTION = "type_selection"; + public static final String YEAR_SELECTION = "year_selection"; + + private static final String[] TYPES = new String[]{ + null, + "01 - Blé tendre", + "02 - Maïs grain et ensilage", + "03 - Orge", + "04 - Autres céréales", + "05 - Colza", + "06 - Tournesol", + "07 - Autres oleagineux", + "08 - Protéagineux", + "09 - Plantes à fibres", + "10 - Semences", + "11 - Gel (surfaces gelées sans production)", + "12 - Gel industriel", + "13 - Autres gels", + "14 - Riz", + "15 - Légumineuses à grains", + "16 - Fourrage", + "17 - Estives landes", + "18 - Prairies permanentes", + "19 - Prairies temporaires", + "20 - Vergers", + "21 - Vignes", + "22 - Fruits à coque", + "23 - Oliviers", + "24 - Autres cultures industrielles", + "25 - Légumes-fleurs", + "26 - Canne à sucre", + "27 - Arboriculture", + "28 - Divers" + }; + + @Autowired + private Session session; + @Autowired + private GeoReferentials geoRef; + @Autowired + @Qualifier(I13.NAME) + private Indicator indicator; + + @FXML + private Button next; + + @FXML + private Button uiExport; + + @FXML + private HBox yearBoxes; + @FXML + private GridPane typeBoxes; + + private final List yearCheckBoxes = new ArrayList<>(); + private final List typeCheckBoxes = new ArrayList<>(); + + private final SimpleObjectProperty>> globalTask = new SimpleObjectProperty<>(); + + private BitSet activatedYears; + private BitSet activatedTypes; + + private final Preferences prefs; + + public FXP09ProcessPane() { + Rhomeo.loadFXML(this); + prefs = Preferences.userNodeForPackage(FXP09ProcessPane.class); + } + + @PostConstruct + private void postConstruct() { + + //liste available referential state for this site + final ObservableList refs; + try { + refs = geoRef.getLocalReferentials(session.getDataContext().getSite()) + .filtered(ref -> ref.hasLocalTypes(GeoReferentials.TYPE_ZONE_HYDRO, GeoReferentials.TYPE_RPG)) + .sorted(); + } catch (IllegalArgumentException | IOException ex) { + // If we cannot load georeferentials, it's no use to go further. + GeotkFX.newExceptionDialog("Impossible de déterminer la liste des réferentiels disponibles. La lecture sur le système a échouée.", ex).show(); + session.requestWorkflowStep(WorkflowStep.DATASET); + return; + } + + final ByteBuffer yearsAsBytes = ByteBuffer.wrap(new byte[refs.size() * (Integer.SIZE / Byte.SIZE)]); + final IntBuffer years = yearsAsBytes.asIntBuffer(); + for (final GeoReferential ref : refs) { + years.put(ref.getYear()); + } + years.position(0); + + /* Restore selection state from serialized bitset if possible. To + * determine if restoration is possible, we ensure there's data stored + * in preferences, and also that they match current edited site / years. + * Otherwise, we set a new bitset, with default selection on types 17 + * and 18. + * We do the same with years, except that by default, they're all selected. + */ + final String siteName = session.getDataContext().getSite().getName(); + final boolean restore = prefs.get(SITE_NAME, "").equals(siteName) + && ByteBuffer.wrap(prefs.getByteArray(AVAILABLE_YEARS, new byte[0])).asIntBuffer().equals(years); + + final byte[] yearSelection; + if (restore && (yearSelection = prefs.getByteArray(YEAR_SELECTION, null)) != null) { + activatedYears = BitSet.valueOf(yearSelection); + } else { + activatedYears = new BitSet(refs.size()); + activatedYears.set(0, activatedYears.length()); + } + + final byte[] typeSelection; + if (restore && (typeSelection = prefs.getByteArray(TYPE_SELECTION, null)) != null) { + activatedTypes = BitSet.valueOf(typeSelection); + } else { + activatedTypes = new BitSet(TYPES.length); + activatedTypes.set(17, true); + activatedTypes.set(18, true); + activatedTypes.set(19, true); + } + + // A new session is starting. We initialize preferences for it. + if (!restore) { + prefs.put(SITE_NAME, siteName); + prefs.putByteArray(AVAILABLE_YEARS, yearsAsBytes.array()); + } + + // Init UI. For checkboxes, each time selection change, we update preferences. + for (GeoReferential ref : refs) { + final CheckBox check = new CheckBox(String.valueOf(ref.getYear())); + final int index = yearCheckBoxes.size(); + check.setSelected(activatedYears.get(index)); + check.selectedProperty().addListener((obs, oldValue, newValue) -> { + yearSelectionChanged(index, newValue == null? false : newValue); + }); + yearBoxes.getChildren().add(check); + yearCheckBoxes.add(check); + } + + double best = 0; + typeCheckBoxes.add(null); + for(int i=1;i<29;i++){ + final CheckBox box = new CheckBox(TYPES[i]); + box.setSelected(activatedTypes.get(i)); + typeCheckBoxes.add(box); + GridPane.setColumnIndex(box, (i-1)%4); + GridPane.setRowIndex(box, ((i-1)-((i-1)%4))); + typeBoxes.getChildren().add(box); + best = Math.max(best, box.getWidth()); + final int index = i; + box.selectedProperty().addListener((obs, oldValue, newValue) -> { + boxSelectionChanged(index, newValue == null? false : newValue); + }); + } + } + + private void yearSelectionChanged(final int index, final boolean value) { + activatedYears.set(index, value); + prefs.putByteArray(YEAR_SELECTION, activatedYears.toByteArray()); + } + + private void boxSelectionChanged(final int index, final boolean value) { + activatedTypes.set(index, value); + prefs.putByteArray(TYPE_SELECTION, activatedTypes.toByteArray()); + } + + @FXML + void exportGeometries(ActionEvent event) { + final Site site = session.getDataContext().getSite(); + final FileChooser.ExtensionFilter zipFilter = new FileChooser.ExtensionFilter("Archive zip", "*.zip"); + final File outputFile = Rhomeo.askOutputFilePopup(site.getName()+".zip", this, zipFilter); + + if (outputFile == null) { + return; + } + + int tmpSelectedYear = Integer.MIN_VALUE; + for(final CheckBox c : yearCheckBoxes) { + if (c.isSelected()) { + tmpSelectedYear = Math.max(tmpSelectedYear, Integer.parseInt(c.getText())); + } + } + + final int selectedYear = tmpSelectedYear; + + final ChoiceDialog dialog = new ChoiceDialog<>(ExportUtils.ExportType.GJSON, ExportUtils.ExportType.values()); + dialog.setTitle("Format d'export"); + dialog.setHeaderText("Choisissez un format de sortie"); + dialog.setResizable(true); + dialog.showAndWait().ifPresent(type -> { + Task t = TaskManager.INSTANCE.submit("Export", () -> { + final Geometry buffer = GeometryUtils.computeBuffer(site.getGeometry()); + final Optional territory; + if (selectedYear > Integer.MIN_VALUE) { + territory = geoRef.getLocalReferential(site, selectedYear).unionIntersecting(GeoReferentials.TYPE_ZONE_HYDRO, site.getGeometry()); + } else { + territory = Optional.empty(); + } + ExportUtils.exportSiteAndBuffer(outputFile, site, buffer, territory, type); + return true; + }); + uiExport.disableProperty().unbind(); + uiExport.disableProperty().bind(t.runningProperty()); + }); + } + + @FXML + void nextStep(ActionEvent event) { + + //check there is at least one year of data available + int nbAvailable = 0; + for(CheckBox c : yearCheckBoxes){ + if(c.isSelected()) nbAvailable++; + } + + if (nbAvailable==0) { + Rhomeo.showAlert(Alert.AlertType.WARNING, "Impossible de passer à l'étape suivante : veuillez sélectionner une année."); + return; + } + + final Computer computer = new Computer(); + globalTask.set(computer); + + computer.stateProperty().addListener(obs -> { + if (computer.isDone()) { + setDisable(false); + switch (computer.getState()) { + case FAILED: + Rhomeo.showAlert(Alert.AlertType.ERROR, "process-failed"); + break; + case SUCCEEDED: + session.setResults(computer.getValue()); + globalTask.set(null); + session.requestWorkflowStep(WorkflowStep.RESULT); + break; + } + } + }); + + TaskManager.INSTANCE.submit(computer); + } + + + private class Computer extends Task> { + + private final List processes = new ArrayList<>(); + + @Override + protected Set call() throws Exception { + processes.addAll(indicator.createProcesses(session.getProcessContext())); + final I13Process process = (I13Process) processes.get(0); + + //configure selected years + for(CheckBox c : yearCheckBoxes){ + if(c.isSelected())process.getYears().add(Integer.valueOf(c.getText())); + } + //configure excluded types + for(int i=1;i<29;i++){ + if(typeCheckBoxes.get(i).isSelected()){ + process.getNoCount().add(i); + } + } + + updateProgress(-1, -1); + updateTitle("I13"); + + Platform.runLater(() -> { + process.titleProperty().addListener((obs) -> updateTitle(process.getTitle())); + process.messageProperty().addListener((obs) -> updateTitle(process.getMessage())); + process.workDoneProperty().addListener((obs) -> updateProgress(process.getWorkDone(), process.getTotalWork())); + }); + + process.run(); + return (Set) process.get(); + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + for (final Process p : processes) { + p.cancel(true); + } + return super.cancel(mayInterruptIfRunning); + } + } + +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/p09/P09ProtocolEditorSpi.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/p09/P09ProtocolEditorSpi.java new file mode 100644 index 0000000..797a60d --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/p09/P09ProtocolEditorSpi.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.fx.p09; + +import fr.cenra.rhomeo.api.data.Protocol; +import fr.cenra.rhomeo.api.ui.ProtocolEditorSpi; +import fr.cenra.rhomeo.core.Session; +import fr.cenra.rhomeo.core.WorkflowStep; +import fr.cenra.rhomeo.protocol.p09.P09; +import java.util.Collections; +import java.util.Set; +import javafx.scene.Node; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +/** + * Protocol 09 editor spi. + * + * @author Johann Sorel (Geomatys) + */ +@Component +public class P09ProtocolEditorSpi implements ProtocolEditorSpi{ + + @Autowired + private Session session; + + @Autowired + @Qualifier(P09.NAME) + private Protocol protocol; + + @Override + public Protocol getProtocol() { + return protocol; + } + + @Override + public Node getEditor(WorkflowStep step) { + switch(step){ + case DATASET : return session.getBean(FXP09DatasetPane.class); + case PROCESS : return session.getBean(FXP09ProcessPane.class); + default : return null; + } + } + + @Override + public Set getStepsToIgnore() { + return Collections.EMPTY_SET; + } + +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/validation/ConstraintViolationListCell.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/validation/ConstraintViolationListCell.java new file mode 100644 index 0000000..1ee7077 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/validation/ConstraintViolationListCell.java @@ -0,0 +1,83 @@ +/** + * 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.fx.validation; + + +import fr.cenra.rhomeo.api.InternationalResource; +import fr.cenra.rhomeo.core.RhomeoCore; +import java.util.Iterator; +import java.util.logging.Level; +import javafx.scene.control.ListCell; +import javax.validation.ConstraintViolation; +import javax.validation.Path; + + +/** + * A simple cell which render a constraint violation message in cell text. + * @author Alexis Manin (Geomatys) + */ +public class ConstraintViolationListCell extends ListCell { + + @Override + protected void updateItem(ConstraintViolation item, boolean empty) { + super.updateItem(item, empty); + + if (empty || item == null) { + setText(null); + } else { + final StringBuilder msgBuilder = new StringBuilder(); + if (item.getLeafBean() instanceof InternationalResource) { + final Iterator it = item.getPropertyPath().iterator(); + String pName = null; + while (it.hasNext()) + pName = it.next().getName(); + if (pName != null) { + try { + msgBuilder.append(InternationalResource.getResourceString((Class)item.getLeafBean().getClass(), pName, "label")) + .append(" : "); + } catch (Exception e) { + RhomeoCore.LOGGER.log(Level.FINE, "Cannot find resource ".concat(pName), e); + } + } + } + + setText(msgBuilder.append(item.getMessage()).toString()); + } + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/fx/validation/FXValidationPane.java b/desktop/src/main/java/fr/cenra/rhomeo/fx/validation/FXValidationPane.java new file mode 100644 index 0000000..91f18ae --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/fx/validation/FXValidationPane.java @@ -0,0 +1,259 @@ +/** + * 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.fx.validation; + +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.data.Dataset; +import fr.cenra.rhomeo.api.data.Warning; +import fr.cenra.rhomeo.core.Session; +import java.util.HashSet; +import java.util.ResourceBundle; +import java.util.Set; +import javafx.beans.binding.Bindings; +import javafx.beans.binding.BooleanBinding; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.geometry.Insets; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.Hyperlink; +import javafx.scene.control.Label; +import javafx.scene.control.ListView; +import javafx.scene.control.ProgressIndicator; +import javafx.scene.layout.StackPane; +import javafx.stage.Modality; +import javafx.stage.Stage; +import javafx.stage.StageStyle; +import javafx.util.Callback; +import javax.annotation.PostConstruct; +import javax.validation.ConstraintViolation; +import javax.validation.Validator; +import org.geotoolkit.font.FontAwesomeIcons; +import org.geotoolkit.gui.javafx.util.TaskManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +/** + * + * @author Alexis Manin (Geomatys) + */ +@Component +@Scope("prototype") +public class FXValidationPane extends StackPane { + + @Autowired + private Session session; + + @Autowired + private Validator validator; + + @FXML + private Label uiStateIcon; + + @FXML + private Label uiStateLabel; + + @FXML + private Button uiValidate; + + @FXML + private Hyperlink uiErrorContainer; + + @FXML + private Hyperlink uiWarningContainer; + + @FXML + private ProgressIndicator uiProgress; + + private final ListView uiErrorList; + private final ListView uiWarningList; + + private final ObservableList errors; + private final ObservableList warnings; + + private final BooleanBinding noError; + + private Stage errorStage; + private Stage warningStage; + + public FXValidationPane() { + super(); + Rhomeo.loadFXML(this, FXValidationPane.class); + errors = FXCollections.observableArrayList(); + warnings = FXCollections.observableArrayList(); + uiErrorList = new ListView<>(errors); + uiErrorList.setMaxHeight(200); + final Insets insets = new Insets(4); + uiErrorList.setPadding(insets); + uiWarningList = new ListView<>(warnings); + uiWarningList.setPadding(insets); + uiWarningList.setMaxHeight(200); + + final Callback factory = (list) -> new ConstraintViolationListCell(); + uiErrorList.setCellFactory(factory); + uiWarningList.setCellFactory(factory); + + // Update display on error detection + noError = Bindings.isEmpty(errors); + uiErrorContainer.visibleProperty().bind(noError.not()); + uiErrorContainer.managedProperty().bind(uiErrorContainer.visibleProperty()); + final BooleanBinding noWarning = Bindings.isEmpty(warnings); + uiWarningContainer.visibleProperty().bind(noWarning.not()); + uiWarningContainer.managedProperty().bind(uiWarningContainer.visibleProperty()); + noError.addListener((obs) -> { + if (session.getDataset().getItems().isEmpty()) { + uiStateIcon.setText(null); + uiStateLabel.setText(null); + } else if (noError.get()) { + uiStateIcon.setText(FontAwesomeIcons.ICON_CHECK); + uiStateIcon.setStyle("-fx-font-family: FontAwesome; -fx-font-size: 24; -fx-text-fill:#9CB35B"); + uiStateLabel.setText(ResourceBundle.getBundle(FXValidationPane.class.getCanonicalName()).getString("dataset.valid")); + } else { + uiStateIcon.setText(FontAwesomeIcons.ICON_TIMES); + uiStateIcon.setStyle("-fx-font-family: FontAwesome; -fx-font-size: 24; -fx-text-fill:#D85F70"); + uiStateLabel.setText(ResourceBundle.getBundle(FXValidationPane.class.getCanonicalName()).getString("dataset.invalid")); + } + }); + } + + @PostConstruct + private void init() { + uiValidate.disableProperty().bind(Bindings.isEmpty(session.getDataset().getItems())); + } + + @FXML + void validate(ActionEvent event) { + TaskManager.INSTANCE.submit("Validation du lot de données", () -> { + Rhomeo.fxRun(false, () -> { + setDisable(true); + uiProgress.setVisible(true); + }); + try { + Set> violations = validator.validate(session.getDataset()); + + final HashSet tmpErrors = new HashSet(); + final HashSet tmpWarnings = new HashSet(); + for (final ConstraintViolation violation : violations) { + if (findWarning(violation)) { + tmpWarnings.add(violation); + } else { + tmpErrors.add(violation); + } + } + + Rhomeo.fxRun(false, () -> { + errors.setAll(tmpErrors); + warnings.setAll(tmpWarnings); + uiStateLabel.setVisible(true); + noError.invalidate(); + }); + } finally { + Rhomeo.fxRun(false, () -> { + setDisable(false); + uiProgress.setVisible(false); + }); + } + }); + } + + private static boolean findWarning(final ConstraintViolation violation) { + for (final Object p : violation.getConstraintDescriptor().getPayload()) { + if (p == Warning.class) { + return true; + } + } + + return false; + } + + public ListView getErrorList() { + return uiErrorList; + } + + public ListView getWarningList() { + return uiWarningList; + } + + /** + * Empty this panel content. + */ + public void reset() { + warnings.clear(); + errors.clear(); + noError.invalidate(); + } + + @FXML + private void showWarnings(final ActionEvent e) { + if (warningStage == null) { + warningStage = createErrorStage("Avertissements", uiWarningList); + } + + warningStage.show(); + warningStage.requestFocus(); + } + + @FXML + private void showErrors(final ActionEvent e) { + if (errorStage == null) { + errorStage = createErrorStage("Erreurs", uiErrorList); + } + + errorStage.show(); + errorStage.requestFocus(); + } + + private Stage createErrorStage(final String title, final ListView errors) { + final Stage s = new Stage(StageStyle.UNIFIED); + if (title != null) + s.setTitle(title); + s.initModality(Modality.NONE); + if (getScene() != null) + s.initOwner(getScene().getWindow()); + + final Scene scene = new Scene(errors); + s.setScene(scene); + s.setAlwaysOnTop(false); + s.sizeToScene(); + return s; + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/preferences/FXFTPConfiguration.java b/desktop/src/main/java/fr/cenra/rhomeo/preferences/FXFTPConfiguration.java new file mode 100644 index 0000000..ca0801d --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/preferences/FXFTPConfiguration.java @@ -0,0 +1,232 @@ +/** + * 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.preferences; + +import fr.cenra.rhomeo.Rhomeo; +import fr.cenra.rhomeo.api.preferences.PreferenceGroup; +import fr.cenra.rhomeo.api.ui.PreferencePane; +import fr.cenra.rhomeo.core.RhomeoCore; +import fr.cenra.rhomeo.core.preferences.ftp.FTPAccess; +import fr.cenra.rhomeo.core.preferences.ftp.FTPPreferences; +import java.security.GeneralSecurityException; +import java.util.Arrays; +import java.util.logging.Level; +import javafx.application.Platform; +import javafx.beans.value.ObservableValue; +import javafx.collections.FXCollections; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.Node; +import javafx.scene.control.Alert; +import javafx.scene.control.Button; +import javafx.scene.control.ComboBox; +import javafx.scene.control.PasswordField; +import javafx.scene.control.Spinner; +import javafx.scene.control.SpinnerValueFactory; +import javafx.scene.control.TextField; +import javafx.scene.layout.BorderPane; +import javafx.util.StringConverter; +import org.geotoolkit.gui.javafx.util.TaskManager; +import org.geotoolkit.internal.GeotkFX; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +/** + * + * @author Alexis Manin (Geomatys) + */ +@Component +@Scope("prototype") +public class FXFTPConfiguration extends BorderPane implements PreferencePane { + + @FXML + private ComboBox uiAccess; + + @Autowired + FTPPreferences prefs; + + @FXML + private TextField uiURL; + + @FXML + private Spinner uiPort; + + @FXML + private TextField uiDir; + + @FXML + private TextField uiLogin; + + @FXML + private PasswordField uiPassword; + + @FXML + private Button uiTest; + + private FTPAccess access; + + public FXFTPConfiguration() { + Rhomeo.loadFXML(this); + uiPort.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(0, 65535, 21, 1)); + Rhomeo.initComboBox(uiAccess, FXCollections.observableArrayList(Arrays.asList(FTPPreferences.ACCESS_POINTS.values()))); + uiAccess.setEditable(false); + uiAccess.setConverter(new StringConverter() { + @Override + public String toString(FTPPreferences.ACCESS_POINTS object) { + if (object == null) + return null; + return object.getTitle(); + } + + @Override + public FTPPreferences.ACCESS_POINTS fromString(String string) { + if (string == null) + return null; + for (final FTPPreferences.ACCESS_POINTS ap : FTPPreferences.ACCESS_POINTS.values()) { + if (string.equals(ap)) + return ap; + } + + return null; + } + }); + + uiAccess.valueProperty().addListener(this::accessChanged); + } + + @FXML + void cancel(ActionEvent event) { + if (access == null) + clearForm(); + else + fillFromAcccess(); + } + + @FXML + void checkConnection(ActionEvent event) { + final String adress = uiURL.getText(); + if (adress == null || adress.isEmpty()) { + Rhomeo.showAlert(Alert.AlertType.WARNING, "Impossible de tester la connexion si le champs d'adresse est vide !"); + } + + final int port = uiPort.getValue(); + final String workDir = uiDir.getText(); + final String login = uiLogin.getText(); + final String pw = uiPassword.getText(); + + final TaskManager.MockTask t = new TaskManager.MockTask(() -> FTPAccess.createClient(adress, port, workDir, login, pw)); + + t.setOnSucceeded((evt) -> Platform.runLater(() -> { + if (t.getValue() != null) { + Rhomeo.showAlert(Alert.AlertType.INFORMATION, "Connexion établie avec succès !"); + } else { + Rhomeo.showAlert(Alert.AlertType.WARNING, "Aucune réponse du serveur !"); + } + })); + + t.setOnFailed(evt -> Platform.runLater(() -> GeotkFX.newExceptionDialog("Impossible de se connecter au service FTP", t.getException()).show())); + + t.runningProperty().addListener((obs, oldValue, newValue) -> uiTest.setDisable(newValue)); + TaskManager.INSTANCE.submit("Test de connexion", t); + } + + private void accessChanged(final ObservableValue obs, FTPPreferences.ACCESS_POINTS oldAccess, FTPPreferences.ACCESS_POINTS newAccess) { + if (newAccess == null) { + access = null; + clearForm(); + + } else { + access = prefs.getAccess(newAccess); + fillFromAcccess(); + } + } + + private void clearForm() { + uiDir.clear(); + uiLogin.clear(); + uiPassword.clear(); + uiPort.getValueFactory().setValue(21); + uiURL.clear(); + } + + private void fillFromAcccess() { + uiDir.setText(access.getWorkingDir()); + uiLogin.setText(access.getLogin()); + try { + uiPassword.setText(access.getPassword()); + } catch (GeneralSecurityException ex) { + RhomeoCore.LOGGER.log(Level.WARNING, "Cannot read password for FTP access", ex); + Rhomeo.showAlert(Alert.AlertType.ERROR, "Impossible de lire le mot de passe enregistré"); + } + uiPort.getValueFactory().setValue(access.getPort()); + uiURL.setText(access.getAdress()); + } + + private void fillAccess() { + if (access == null) + return; + + access.setPort(uiPort.getValue()); + access.setAdress(uiURL.getText()); + access.setWorkingDir(uiDir.getText()); + access.setLogin(uiLogin.getText()); + try { + access.setPassword(uiPassword.getText()); + } catch (GeneralSecurityException ex) { + RhomeoCore.LOGGER.log(Level.WARNING, "Cannot write password for FTP access", ex); + GeotkFX.newExceptionDialog("Impossible d'enregistrer le mot de passe", ex).show(); + } + } + + @Override + public PreferenceGroup getPreferenceGroup() { + return prefs; + } + + @Override + public Node getEditor() { + return this; + } + + @Override + public void save() { + fillAccess(); + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/preferences/csv/CSVKey.java b/desktop/src/main/java/fr/cenra/rhomeo/preferences/csv/CSVKey.java new file mode 100644 index 0000000..614f0de --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/preferences/csv/CSVKey.java @@ -0,0 +1,77 @@ +/** + * 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.preferences.csv; + +import fr.cenra.rhomeo.api.preferences.InternationalPreferenceKey; +import org.apache.sis.util.ArgumentChecks; + +/** + * + * @author Alexis Manin (Geomatys) + */ +public class CSVKey implements InternationalPreferenceKey { + + private final String keyId; + private final String defaultValue; + + public CSVKey(final String netKey) { + this(netKey, null); + } + + public CSVKey(final String netKey, final String defaultValue) { + ArgumentChecks.ensureNonNull("Key", netKey); + this.keyId = netKey; + this.defaultValue = defaultValue; + } + + @Override + public String name() { + return keyId; + } + + @Override + public String getKey() { + return keyId; + } + + @Override + public String getDefaultValue() { + return defaultValue; + } +} diff --git a/desktop/src/main/java/fr/cenra/rhomeo/preferences/csv/CSVPreferences.java b/desktop/src/main/java/fr/cenra/rhomeo/preferences/csv/CSVPreferences.java new file mode 100644 index 0000000..0ea3185 --- /dev/null +++ b/desktop/src/main/java/fr/cenra/rhomeo/preferences/csv/CSVPreferences.java @@ -0,0 +1,74 @@ +/** + * 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.preferences.csv; + +import fr.cenra.rhomeo.api.preferences.UserPackagePreferenceGroup; +import fr.cenra.rhomeo.core.CSVMapper; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.springframework.stereotype.Component; + +/** + * Display preferences of encoding and other CSV formatting parameters. This is + * needed for dataset import/export. + * + * @author Alexis Manin (Geomatys) + */ +@Component +public class CSVPreferences extends UserPackagePreferenceGroup { + + public static final CSVKey CHARSET_KEY = new CSVKey("charset", StandardCharsets.UTF_8.name()); + public static final CSVKey SEPARATOR_KEY = new CSVKey("separator", String.valueOf(CSVMapper.DEFAULT_SEPARATOR)); + + private static final List KEYS = Collections.unmodifiableList(Arrays.asList(new CSVKey[] { + CHARSET_KEY, SEPARATOR_KEY + })); + + @Override + public List getKeys() { + return KEYS; + } + + @Override + public int getPriority() { + return 3; + } +} diff --git a/desktop/src/main/java/org/geotoolkit/gui/javafx/parameter/FXDateEditor.java b/desktop/src/main/java/org/geotoolkit/gui/javafx/parameter/FXDateEditor.java new file mode 100644 index 0000000..bd41148 --- /dev/null +++ b/desktop/src/main/java/org/geotoolkit/gui/javafx/parameter/FXDateEditor.java @@ -0,0 +1,109 @@ +/* + * Geotoolkit - An Open Source Java GIS Toolkit + * http://www.geotoolkit.org + * + * (C) 2015, Geomatys + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package org.geotoolkit.gui.javafx.parameter; + +import java.sql.Timestamp; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.Date; +import javafx.beans.property.Property; +import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.value.ObservableValue; +import javafx.scene.Node; +import javafx.scene.control.DatePicker; +import org.apache.sis.util.UnconvertibleObjectException; + +/** + * COPIED FROM GEOTOOLKIT 4.0.0-M0082. Aim is to simplify edition. + * + * @author Alexis Manin (Geomatys) + */ +public class FXDateEditor extends FXValueEditor { + + static final Class[] SUPPORTED_CLASSES = new Class[]{Date.class, LocalDate.class, LocalDateTime.class}; + + private final SimpleObjectProperty dateProperty = new SimpleObjectProperty(); + private final DatePicker editor = new DatePicker(); + + public FXDateEditor(final Spi spi) { + super(spi); + + dateProperty.addListener((ObservableValue observable, Object oldValue, Object newValue) -> { + if (editor.valueProperty().isBound()) + return; // Do not throw exception, because user has set editor property as a target for one of his own property. + + if (newValue == null) + editor.valueProperty().set(null); + else if (newValue instanceof LocalDateTime) + editor.valueProperty().set(((LocalDateTime)newValue).toLocalDate()); + else if (newValue instanceof LocalDate) + editor.valueProperty().set((LocalDate)newValue); + else if (newValue instanceof Date) { + editor.valueProperty().set(new Timestamp(((Date)newValue).getTime()).toLocalDateTime().toLocalDate()); + } else throw new UnconvertibleObjectException("Cannot convert from "+newValue.getClass() + " to "+LocalDate.class); + }); + + editor.valueProperty().addListener((ObservableValue observable, LocalDate oldValue, LocalDate newValue) -> { + if (dateProperty.isBound()) + return; // Do not throw exception, because user has set exposed property as a target for one of his own property. + + if (newValue == null) { + dateProperty.set(null); + } else { + Class valueClass = getValueClass(); + if (valueClass == null) + dateProperty.set(newValue); // TODO : throw an exception ? editor has not been configured, but user already started to work with it. + else if (LocalDateTime.class.isAssignableFrom(valueClass)) + dateProperty.set(newValue.atStartOfDay()); + else if (LocalDate.class.isAssignableFrom(valueClass)) + dateProperty.set(newValue); + else if (Date.class.isAssignableFrom(valueClass)) + dateProperty.set(Timestamp.valueOf(newValue.atStartOfDay())); + } + }); + } + + @Override + public Property valueProperty() { + return dateProperty; + } + + @Override + public Node getComponent() { + return editor; + } + + /** + * SPI + */ + public static final class Spi extends FXValueEditorSpi { + + @Override + public boolean canHandle(Class binding) { + for (final Class c : SUPPORTED_CLASSES) { + if (c.isAssignableFrom(binding)) + return true; + } + return false; + } + + @Override + public FXValueEditor createEditor() { + return new FXDateEditor(this); + } + } +} diff --git a/desktop/src/main/java/org/geotoolkit/gui/javafx/util/ProgressMonitor.java b/desktop/src/main/java/org/geotoolkit/gui/javafx/util/ProgressMonitor.java new file mode 100644 index 0000000..57dfe8f --- /dev/null +++ b/desktop/src/main/java/org/geotoolkit/gui/javafx/util/ProgressMonitor.java @@ -0,0 +1,388 @@ +package org.geotoolkit.gui.javafx.util; + +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.ResourceBundle; +import java.util.Set; +import java.util.function.Predicate; +import javafx.application.Platform; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleListProperty; +import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.value.ObservableValue; +import javafx.collections.ListChangeListener; +import javafx.collections.ObservableList; +import javafx.concurrent.Task; +import javafx.event.ActionEvent; +import javafx.geometry.Insets; +import javafx.scene.Node; +import javafx.scene.control.Button; +import javafx.scene.control.CustomMenuItem; +import javafx.scene.control.Dialog; +import javafx.scene.control.Label; +import javafx.scene.control.MenuButton; +import javafx.scene.control.MenuItem; +import javafx.scene.control.ProgressBar; +import javafx.scene.control.SeparatorMenuItem; +import javafx.scene.control.Tooltip; +import javafx.scene.layout.Background; +import javafx.scene.layout.Border; +import javafx.scene.layout.HBox; +import javafx.scene.text.Font; +import org.apache.sis.util.ArgumentChecks; +import org.geotoolkit.font.FontAwesomeIcons; +import org.geotoolkit.internal.GeotkFX; + +/** + * A JavaFX component which display progress and encountered errors for all tasks + * submitted on a specific task manager. + * + * The last submitted task is displayed in an Hbox. To see other running tasks + * and tasks in error, there's two {@link MenuButton}. Each display custom menu + * items containing information about a task. + * + * The {@link ProgressMonitor} is skinnable using a css stylesheet and the specific + * following css classes: + * {@link ProgressMonitor.CURRENT_TASK_CSS_CLASS} + * {@link ProgressMonitor.CURRENT_TASK_GRAPHIC_CSS_CLASS} + * {@link ProgressMonitor.ERROR_TASK_CSS_CLASS} + * {@link ProgressMonitor.ERROR_TASK_GRAPHIC_CSS_CLASS} + * {@link ProgressMonitor.PROGRESS_MONITOR_CSS_CLASS} + * {@link ProgressMonitor.CANCEL_BUTTON_CSS_CLASS} + * {@link ProgressMonitor.TASK_PROGRESS_CSS_CLASS} + * {@link ProgressMonitor.TASK_PROGRESS_GRAPHIC_CSS_CLASS} + * {@link ProgressMonitor.MENU_ITEM_CSS_CLASS} + * {@link ProgressMonitor.CLEAR_MENU_ITEM_CSS_CLASS} + * + * + * {@link ProgressMonitor} labels can be parametrized using {@link ResourceBundle} + * properties defined by {@link ProgressMonitor.ResourceKey}. + * + * @author Alexis Manin (Geomatys) + */ +public class ProgressMonitor extends HBox { + + private static String ICON_LABEL_FONT_FAMILY = "-fx-font-family: FontAwesome Regular;"; + + /** + * The css classes associated to the {@link ProgressMonitor} nodes. + */ + public static final String CURRENT_TASK_CSS_CLASS="geotk-progressMonitor-runningTasks"; + public static final String CURRENT_TASK_GRAPHIC_CSS_CLASS="geotk-progressMonitor-runningTasks-graphic"; + public static final String ERROR_TASK_CSS_CLASS="geotk-progressMonitor-tasksInError"; + public static final String ERROR_TASK_GRAPHIC_CSS_CLASS="geotk-progressMonitor-tasksInError-graphic"; + public static final String PROGRESS_MONITOR_CSS_CLASS="geotk-progressMonitor"; + public static final String CANCEL_BUTTON_CSS_CLASS="geotk-progressMonitor-cancelButton"; + public static final String TASK_PROGRESS_CSS_CLASS="geotk-progressMonitor-taskProgress"; + public static final String TASK_PROGRESS_GRAPHIC_CSS_CLASS="geotk-progressMonitor-taskProgress-graphic"; + public static final String MENU_ITEM_CSS_CLASS="geotk-progressMonitor-menuItem"; + public static final String CLEAR_MENU_ITEM_CSS_CLASS="geotk-progressMonitor-clearMenuItem"; + + private TaskProgress lastTask; + + private final MenuButton runningTasks; + private final MenuButton tasksInError; + + private final TaskManager taskRegistry; + + static { + // Load Font Awesome. + final Font font = FXUtilities.FONTAWESOME; + } + + /** + * The base constructor of progress monitors. + * + * @param registry The {@link TaskManager} followed by this progress monitor. + */ + public ProgressMonitor(final TaskManager registry) { + ArgumentChecks.ensureNonNull("Input task registry", registry); + + taskRegistry = registry; + + final Label runningIcon = new Label(FontAwesomeIcons.ICON_GEARS_ALIAS); + runningIcon.setStyle(ICON_LABEL_FONT_FAMILY); + runningIcon.getStyleClass().add(CURRENT_TASK_GRAPHIC_CSS_CLASS); + runningTasks = new MenuButton(GeotkFX.getString(ProgressMonitor.class, "currentTasksLabel"), runningIcon); + final Label errorIcon = new Label(FontAwesomeIcons.ICON_EXCLAMATION_CIRCLE); + errorIcon.setStyle(ICON_LABEL_FONT_FAMILY); + errorIcon.getStyleClass().add(ERROR_TASK_GRAPHIC_CSS_CLASS); + tasksInError = new MenuButton(GeotkFX.getString(ProgressMonitor.class, "errorTasksLabel"), errorIcon); + + final Tooltip runninTasksTooltip = new Tooltip(GeotkFX.getString(ProgressMonitor.class, "currentTasksTooltip")); + runningTasks.setTooltip(runninTasksTooltip); + final Tooltip tasksInErrorTooltip = new Tooltip(GeotkFX.getString(ProgressMonitor.class, "errorTasksTooltip")); + tasksInError.setTooltip(tasksInErrorTooltip); + + final SimpleListProperty runningTasksProp = new SimpleListProperty(taskRegistry.getSubmittedTasks()); + final SimpleListProperty failedTasksProp = new SimpleListProperty(taskRegistry.getTasksInError()); + + // Hide list of tasks if there's no information available. + runningTasks.visibleProperty().bind(runningTasksProp.sizeProperty().greaterThan(1)); + tasksInError.visibleProperty().bind(failedTasksProp.emptyProperty().not()); + + // Display number of tasks on menu button. + runningTasks.textProperty().bind(runningTasksProp.sizeProperty().asString()); + tasksInError.textProperty().bind(failedTasksProp.sizeProperty().asString()); + + // Set default visible task the last one submitted. + lastTask = new TaskProgress(); + lastTask.taskProperty().bind(runningTasksProp.valueAt(runningTasksProp.sizeProperty().subtract(1))); + + // Do not reserve size for hidden components. + runningTasks.managedProperty().bind(runningTasks.visibleProperty()); + tasksInError.managedProperty().bind(tasksInError.visibleProperty()); + lastTask.managedProperty().bind(lastTask.visibleProperty()); + + initTasks(); + + getChildren().addAll(lastTask, runningTasks, tasksInError); + minWidthProperty().bind(prefWidthProperty()); + prefWidthProperty().set(USE_COMPUTED_SIZE); + + getStyleClass().add(PROGRESS_MONITOR_CSS_CLASS); + runningTasks.getStyleClass().add(CURRENT_TASK_CSS_CLASS); + tasksInError.getStyleClass().add(ERROR_TASK_CSS_CLASS); + } + + /** + * Fill panel with currently submitted tasks. Add listeners on + * {@link TaskManager} to be aware of new events. + */ + private void initTasks() { + + final MenuItem clearErrorItem = new MenuItem(GeotkFX.getString(ProgressMonitor.class, "cleanErrorList")); + clearErrorItem.setOnAction(evt -> taskRegistry.getTasksInError().clear()); + + final Label icon = new Label(FontAwesomeIcons.ICON_TRASH_O); + icon.setStyle(ICON_LABEL_FONT_FAMILY); + clearErrorItem.setGraphic(icon); + + clearErrorItem.getStyleClass().add(CLEAR_MENU_ITEM_CSS_CLASS); + + tasksInError.getItems().add(clearErrorItem); + tasksInError.getItems().add(new SeparatorMenuItem()); + + // Listen on current running tasks + final ObservableList tmpSubmittedTasks = taskRegistry.getSubmittedTasks(); + tmpSubmittedTasks.addListener((ListChangeListener.Change c) -> { + + final Set toAdd = new HashSet<>(); + final Set toRemove = new HashSet<>(); + storeChanges(c, toAdd, toRemove); + + Platform.runLater(() -> { + for (final Task task : toAdd) { + final CustomMenuItem item = new CustomMenuItem(new TaskProgress(task)); + item.setHideOnClick(false); + runningTasks.getItems().add(item); + } + // remove Ended tasks + runningTasks.getItems().removeIf(new GetItemsForTask(toRemove)); + }); + }); + + // Check failed tasks. + final ObservableList tmpTasksInError = taskRegistry.getTasksInError(); + tmpTasksInError.addListener((ListChangeListener.Change c) -> { + final Set toAdd = new HashSet<>(); + final Set toRemove = new HashSet<>(); + storeChanges(c, toAdd, toRemove); + + Platform.runLater(() -> { + for (final Task task : toAdd) { + tasksInError.getItems().add(new ErrorMenuItem(task)); + } + // remove Ended tasks + tasksInError.getItems().removeIf(new GetItemsForTask(toRemove)); + }); + }); + + final Runnable initPanel = () -> { + final int nbSubmitted = tmpSubmittedTasks.size(); + // do not add last task to our menu, it will be used on main display. + for (int i = 0; i < nbSubmitted; i++) { + final CustomMenuItem item = new CustomMenuItem(new TaskProgress(tmpSubmittedTasks.get(i))); + item.setHideOnClick(false); + runningTasks.getItems().add(item); + } + + for (final Task t : tmpTasksInError) { + tasksInError.getItems().add(new ErrorMenuItem(t)); + } + }; + + if (Platform.isFxApplicationThread()) { + initPanel.run(); + } else { + Platform.runLater(initPanel); + } + } + + /** + * Store all objects depicted by a {@link ListChangeListener} into given + * collections. + * + * @param c The {@link ListChangeListener.Change} containing list content delta. + * @param added The collection to store new added objects into. + * @param removed Add removed objects in it. + */ + private static void storeChanges(final ListChangeListener.Change c, final Collection added, final Collection removed) { + while (c.next()) { + final List addedSubList = c.getAddedSubList(); + final List removeSubList = c.getRemoved(); + + if (addedSubList != null && !addedSubList.isEmpty()) { + added.addAll(addedSubList); + } + + final Iterator it = removeSubList.iterator(); + while (it.hasNext()) { + final Task current = it.next(); + if (!added.remove(current)) { + removed.add(current); + } + } + } + } + + /** + * The node giving information about a specific task. Allow to see title, + * description and current progress, as to cancel the task. + */ + private static class TaskProgress extends HBox { + + private final Label title = new Label(); + private final Tooltip description = new Tooltip(); + private final ProgressBar progress = new ProgressBar(); + private final Button cancelButton; + + private final ObjectProperty taskProperty = new SimpleObjectProperty<>(); + + TaskProgress() { + this(null); + } + + TaskProgress(final Task t) { + final Label icon = new Label(FontAwesomeIcons.ICON_BAN); + icon.setStyle(ICON_LABEL_FONT_FAMILY); + icon.getStyleClass().add(TASK_PROGRESS_GRAPHIC_CSS_CLASS); + cancelButton = new Button("", icon); + + taskProperty.addListener((ObservableValue observable, Task oldValue, Task newValue) -> { + if (Platform.isFxApplicationThread()) { + taskUpdated(); + } else { + Platform.runLater(()->taskUpdated()); + } + }); + + taskProperty.set(t); + + getChildren().addAll(title, progress, cancelButton); + + getStyleClass().add(TASK_PROGRESS_CSS_CLASS); + cancelButton.getStyleClass().add(CANCEL_BUTTON_CSS_CLASS); + } + + public ObjectProperty taskProperty() { + return taskProperty; + } + + public Task getTask() { + return taskProperty.get(); + } + + public synchronized void taskUpdated() { + title.textProperty().unbind(); + progress.progressProperty().unbind(); + description.textProperty().unbind(); + + cancelButton.setOnAction(null); + + final Task t =taskProperty.get(); + if (t != null) { + title.textProperty().bind(t.titleProperty()); + description.textProperty().bind(t.messageProperty()); + progress.progressProperty().bind(t.progressProperty()); + cancelButton.setOnAction((ActionEvent e) -> t.cancel()); + setVisible(true); + } else { + setVisible(false); + } + } + } + + /** + * A simple menu items for failed tasks. Display an exception Dialog when clicked. + */ + private class ErrorMenuItem extends MenuItem { + + final Task failedTask; + + ErrorMenuItem(final Task failedTask) { + ArgumentChecks.ensureNonNull("task in error", failedTask); + + this.failedTask = failedTask; + // No need for binding here. Task failed, its state should not change anymore. + String title = failedTask.getTitle(); + if (title == null || title.isEmpty()) + title = GeotkFX.getString(ProgressMonitor.class, "anonymOperation"); + setText(LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm"))+" - "+title); + + final Label icon = new Label(FontAwesomeIcons.ICON_TRASH_O); + icon.setStyle(ICON_LABEL_FONT_FAMILY); + + final Button deleteButton = new Button("", icon); + deleteButton.setBorder(Border.EMPTY); + deleteButton.setPadding(Insets.EMPTY); + deleteButton.setBackground(Background.EMPTY); + deleteButton.setOnAction(e -> { + taskRegistry.getTasksInError().remove(failedTask); + e.consume(); + }); + setGraphic(deleteButton); + + final Dialog d = GeotkFX.newExceptionDialog(failedTask.getMessage(), failedTask.getException()); + d.setResizable(true); + + setOnAction((ActionEvent ae) -> d.show()); + + getStyleClass().add(MENU_ITEM_CSS_CLASS); + } + + public Task getTask() { + return failedTask; + } + } + + /** + * A simple {@link Predicate} which return current monitor progress bars + * which are focused on one of the given tasks. + */ + private static class GetItemsForTask implements Predicate { + + private final Collection tasks; + + GetItemsForTask(final Collection taskFilter) { + ArgumentChecks.ensureNonNull("Input filter tasks", taskFilter); + tasks = taskFilter; + } + + @Override + public boolean test(MenuItem item) { + if (item instanceof CustomMenuItem) { + final Node content = ((CustomMenuItem) item).getContent(); + return (content instanceof TaskProgress + && tasks.contains(((TaskProgress) content).getTask())); + } else if (item instanceof ErrorMenuItem) { + return tasks.contains(((ErrorMenuItem) item).getTask()); + } + return false; + } + } +} diff --git a/desktop/src/main/resources/fr/cenra/rhomeo/ProgressMonitor.css b/desktop/src/main/resources/fr/cenra/rhomeo/ProgressMonitor.css new file mode 100644 index 0000000..0a26436 --- /dev/null +++ b/desktop/src/main/resources/fr/cenra/rhomeo/ProgressMonitor.css @@ -0,0 +1,58 @@ +.geotk-progressMonitor-cancelButton { + -fx-background-color: transparent; +} + +/*Override default css*/ +.label { + -fx-text-fill: #ffffff; +} + +.geotk-progressMonitor-tasksInError > .arrow-button, .geotk-progressMonitor-runningTasks > .arrow-button { + -fx-padding: 0; +} + +.geotk-progressMonitor-tasksInError > .arrow-button > .arrow, .geotk-progressMonitor-runningTasks > .arrow-button > .arrow { + -fx-padding: 0; +} + +.geotk-progressMonitor-tasksInError, .geotk-progressMonitor-runningTasks { + -fx-background-color: transparent; + -fx-border-style: none; + -fx-border-width: 2; +} + +.geotk-progressMonitor-tasksInError { + -fx-text-fill: green; +} + +.geotk-progressMonitor-clearMenuItem .label { + -fx-font-size: 14px; +} + +.geotk-progressMonitor-menuItem .label { + -fx-font-size: 12px; +} + +.geotk-progressMonitor { + -fx-spacing: 10; + -fx-alignment: center; + -fx-font-size: 15px; + -fx-background-color: transparent; +} + +.geotk-progressMonitor-taskProgress{ + -fx-spacing: 5; + -fx-alignment: center; +} + +.geotk-progressMonitor-runningTasks-graphic{ + -fx-text-fill: aquamarine; +} + +.geotk-progressMonitor-tasksInError-graphic{ + -fx-text-fill: #aa0000; +} + +.geotk-progressMonitor-taskProgress-graphic{ + -fx-text-fill: #aa0000; +} \ No newline at end of file diff --git a/desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDashboardMenuPane.fxml b/desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDashboardMenuPane.fxml new file mode 100644 index 0000000..95cd730 --- /dev/null +++ b/desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDashboardMenuPane.fxml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + + + + + + + + +
+
+
diff --git a/desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDashboardMenuPane.properties b/desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDashboardMenuPane.properties new file mode 100644 index 0000000..a6e03ce --- /dev/null +++ b/desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDashboardMenuPane.properties @@ -0,0 +1,32 @@ +site=SITE +new-site=Nouveau site +import-site=Importer un site +site-protocol=SITE ET PROTOCOLE +protocoles=PROTOCOLES +create-site=Cr\u00e9er le site +cancel=Annuler +save=Enregistrer +sites-info-title=INFORMATIONS SUR LE SITE +info-site=Site * +referent-site=R\u00e9f\u00e9rent +contour-site=Contour * +departement-site=D\u00e9partement * +structure-site=Structure +type-zh-site=Type ZH * +zb-odo-site=ZB odo +zb-ortho-site=ZB ortho +import-contour=Importer un contour de site +view-contour=Visualiser +cleanProgressMonitorList=Vider la liste +downloadShape=Format .shp +downloadKml=Format .kml + +download-selected-site-tooltip=T\u00e9l\u00e9charger le site s\u00e9lectionn\u00e9 +delete-selected-site-tooltip=Supprimer le site s\u00e9lectionn\u00e9 +edit-selected-site-tooltip=Edition / Lecture simple pour le site s\u00e9lectionn\u00e9 +view-info-site-tooltip=Afficher / Masquer les informations du site s\u00e9lectionn\u00e9 + +alert-site-deleted=La suppression du site \"{0}\" supprimera \u00e9galement ses donn\u00e9es associ\u00e9es. Etes-vous s\u00fbr ? +alert-site-download=L'extension du fichier de sortie doit \u00eatre .shp, .zip ou .kml. +alert-site-createOrUpdate=Un site est d\u00e9j\u00e0 pr\u00e9sent portant le nom \"{0}\". Veuillez saisir un nouveau nom. +unsaved-modification=Les modifications non sauvegard\u00e9es seront perdues. Etes-vous s\u00fbr de vouloir continuer ? diff --git a/desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDashboardPane.fxml b/desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDashboardPane.fxml new file mode 100644 index 0000000..ca4b16b --- /dev/null +++ b/desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDashboardPane.fxml @@ -0,0 +1,43 @@ + + + + + + + + + + +
+ + + + + + + + +
+
diff --git a/desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDashboardPane.properties b/desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDashboardPane.properties new file mode 100644 index 0000000..e953f81 --- /dev/null +++ b/desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDashboardPane.properties @@ -0,0 +1,5 @@ +title-table=TABLEAU DE BORD +publish=Publier les r\u00e9sultats +export=Exporter les r\u00e9sultats +year=Ann\u00e9e +publish-title=Publication des r\u00e9sultats sur le serveur diff --git a/desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDefaultPreferenceGroupPane.css b/desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDefaultPreferenceGroupPane.css new file mode 100644 index 0000000..78eca06 --- /dev/null +++ b/desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDefaultPreferenceGroupPane.css @@ -0,0 +1,5 @@ +.pane { + -fx-padding: 15; + -fx-hgap: 10; + -fx-vgap: 10; +} diff --git a/desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDefaultProcessingPane.fxml b/desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDefaultProcessingPane.fxml new file mode 100644 index 0000000..0cab345 --- /dev/null +++ b/desktop/src/main/resources/fr/cenra/rhomeo/fx/FXDefaultProcessingPane.fxml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + diff --git a/desktop/src/main/resources/fr/cenra/rhomeo/fx/FXRhomeoWizard.properties b/desktop/src/main/resources/fr/cenra/rhomeo/fx/FXRhomeoWizard.properties new file mode 100644 index 0000000..1067e2a --- /dev/null +++ b/desktop/src/main/resources/fr/cenra/rhomeo/fx/FXRhomeoWizard.properties @@ -0,0 +1,7 @@ +site=Site : +refUsed=R\u00e9f\u00e9rentiels utilis\u00e9s +stopProcess=Arr\u00eater le processus +step1=Lot de donn\u00e9es +step2=Indicateurs +step3=R\u00e9sultats +step4=Finalisation \ No newline at end of file diff --git a/desktop/src/main/resources/fr/cenra/rhomeo/fx/FXSplashScreen.fxml b/desktop/src/main/resources/fr/cenra/rhomeo/fx/FXSplashScreen.fxml new file mode 100644 index 0000000..933d5c8 --- /dev/null +++ b/desktop/src/main/resources/fr/cenra/rhomeo/fx/FXSplashScreen.fxml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/desktop/src/main/resources/fr/cenra/rhomeo/fx/Typologie_Habitats.pdf b/desktop/src/main/resources/fr/cenra/rhomeo/fx/Typologie_Habitats.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8ca49fcd930b5fa87c7533254166ea2e86eea421 GIT binary patch literal 429068 zcma&ObyS?ovNsF_4;tJDmmq_?ySv-q?(Xg`!QGt%cXubayE_C6_Ga&U&bsIQ)_(8( z=8svc=jrL{uIgV^b#>K4t{@^t$4JkLNWQx_J%%Jc7~RSJUk3C7Pck^juxIK z#sEeJ82}3tCy0#K_LrM8Uw(#_115VLNLV8(Sv;D}#cgiLr%|vz;S=k%^Cw zLCnJ1*~F1S%-X=&G*

ER69x)$0$Es?nb}2vY|KD* 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 D5J~;F literal 0 HcmV?d00001 diff --git a/desktop/src/main/resources/fr/cenra/rhomeo/fx/edition/CSVConfigurationPane.fxml b/desktop/src/main/resources/fr/cenra/rhomeo/fx/edition/CSVConfigurationPane.fxml new file mode 100644 index 0000000..1c60cd8 --- /dev/null +++ b/desktop/src/main/resources/fr/cenra/rhomeo/fx/edition/CSVConfigurationPane.fxml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +