diff --git a/sdi-plugins/CHANGELOG.md b/sdi-plugins/CHANGELOG.md index 50923a1..02c468e 100644 --- a/sdi-plugins/CHANGELOG.md +++ b/sdi-plugins/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog for org.gcube.application.cms.sdi-plugins +## [v1.1.3-SNAPSHOT] +- Added apply regex business logic [#26322] + ## [v1.1.2] - Using parent version range [#25572] diff --git a/sdi-plugins/pom.xml b/sdi-plugins/pom.xml index dd43608..b5ca10a 100644 --- a/sdi-plugins/pom.xml +++ b/sdi-plugins/pom.xml @@ -5,7 +5,7 @@ 4.0.0 sdi-plugins - 1.1.2 + 1.1.3-SNAPSHOT gCube CMS - SDI Plugins diff --git a/sdi-plugins/src/main/java/org/gcube/application/cms/sdi/model/ApplyRegex.java b/sdi-plugins/src/main/java/org/gcube/application/cms/sdi/model/ApplyRegex.java new file mode 100644 index 0000000..5fd28a0 --- /dev/null +++ b/sdi-plugins/src/main/java/org/gcube/application/cms/sdi/model/ApplyRegex.java @@ -0,0 +1,40 @@ +package org.gcube.application.cms.sdi.model; + +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + + + +/** + * The Class ApplyRegex. + * + * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it + * + * Dec 21, 2023 + * + * e.g. + * { + * "apply_regex": + * { "type": "replaceAll", + * "regex": "(\\s)?\\([\\s\\S]*", + * "replacement": "" + * } + * } + */ +@Data +@Slf4j +public class ApplyRegex { + + /** + * The Enum REGEX_TYPES. + * + * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it + * + * Dec 21, 2023 + */ + public static enum REGEX_TYPES {replaceAll, replaceFirst, find} + String type; + String regex; + String replacement = ""; + +} diff --git a/sdi-plugins/src/main/java/org/gcube/application/cms/sdi/model/MappingObject.java b/sdi-plugins/src/main/java/org/gcube/application/cms/sdi/model/MappingObject.java index 6d39512..52712f4 100644 --- a/sdi-plugins/src/main/java/org/gcube/application/cms/sdi/model/MappingObject.java +++ b/sdi-plugins/src/main/java/org/gcube/application/cms/sdi/model/MappingObject.java @@ -9,6 +9,8 @@ import org.gcube.application.cms.serialization.Serialization; import org.gcube.application.geoportal.common.model.useCaseDescriptor.HandlerDeclaration; import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; +import com.fasterxml.jackson.annotation.JsonProperty; + import lombok.Data; import lombok.extern.slf4j.Slf4j; @@ -18,7 +20,11 @@ public class MappingObject { private String name; private String type; private String path; - + //Added by Francesco M. + //Here we can pass a regex to manage the value that must be added to index + @JsonProperty("apply_regex") + private ApplyRegex applyRegex; + public void validate() throws InvalidProfileException { if (name == null) throw new InvalidProfileException("Invalid mapping " + this + " : name is null"); if (type == null) throw new InvalidProfileException("Invalid mapping " + this + " : type is null"); diff --git a/sdi-plugins/src/main/java/org/gcube/application/cms/sdi/plugins/SDIIndexerPlugin.java b/sdi-plugins/src/main/java/org/gcube/application/cms/sdi/plugins/SDIIndexerPlugin.java index a8cdf3b..05f8af2 100644 --- a/sdi-plugins/src/main/java/org/gcube/application/cms/sdi/plugins/SDIIndexerPlugin.java +++ b/sdi-plugins/src/main/java/org/gcube/application/cms/sdi/plugins/SDIIndexerPlugin.java @@ -5,6 +5,8 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.bson.Document; import org.gcube.application.cms.plugins.IndexerPluginInterface; @@ -26,6 +28,8 @@ import org.gcube.application.cms.sdi.engine.bboxes.BBOXByCoordinatePaths; import org.gcube.application.cms.sdi.engine.bboxes.BBOXEvaluator; import org.gcube.application.cms.sdi.engine.bboxes.BBOXPathScanner; import org.gcube.application.cms.sdi.faults.SDIInteractionException; +import org.gcube.application.cms.sdi.model.ApplyRegex; +import org.gcube.application.cms.sdi.model.ApplyRegex.REGEX_TYPES; import org.gcube.application.cms.sdi.model.MappingObject; import org.gcube.application.cms.serialization.Serialization; import org.gcube.application.geoportal.common.model.JSONPathWrapper; @@ -50,14 +54,14 @@ import com.vdurmont.semver4j.Semver; import lombok.extern.slf4j.Slf4j; - /** * The Class SDIIndexerPlugin. * * @author created by Fabio Sinibaldi - * @author new architect and maintainer - Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it + * @author new architect and maintainer - Francesco Mangiacrapa at ISTI-CNR + * francesco.mangiacrapa@isti.cnr.it * - * Apr 28, 2023 + * Apr 28, 2023 */ @Slf4j public class SDIIndexerPlugin extends SDIAbstractPlugin implements IndexerPluginInterface { @@ -141,7 +145,7 @@ public class SDIIndexerPlugin extends SDIAbstractPlugin implements IndexerPlugin centroidDoc.put(DBConstants.Defaults.PROJECT_ID, project.getId()); centroidDoc.put(DBConstants.Defaults.DISPLAYED, true); - //*********** Added by Francesco. Creating Gis Viewer Link as public or private + // *********** Added by Francesco. Creating Gis Viewer Link as public or private Boolean isInternalIndex = null; try { isInternalIndex = requestArguments.getBoolean(IndexConstants.INDEX_PARAMETER_FLAGINTERNALINDEX); @@ -173,41 +177,44 @@ public class SDIIndexerPlugin extends SDIAbstractPlugin implements IndexerPlugin log.error("Error on creating the Geoportal GisViewer link for project id {}", project.getId(), e); } } - - // ********************** Updated by Francesco, see #25056, Calculating Spatial Reference as Centroid Object - //**** EVALUATE POSITION + + // ********************** Updated by Francesco, see #25056, Calculating Spatial + // Reference as Centroid Object + // **** EVALUATE POSITION log.debug("indexing UseCaseDescriptor {} : Evaluating Centroid... ", useCaseDescriptor.getId()); SpatialReference reference = null; List refs = project .getIdentificationReferenceByType(SpatialReference.SPATIAL_REFERENCE_TYPE); - + GCubeSDILayer.BBOX bbox = null; if (!refs.isEmpty()) { // Use existing Reference try { reference = Serialization.convert(refs.get(0), SpatialReference.class); - + log.debug("Using already defined spatial reference " + reference); - + GeoJsonObject object = Serialization.convert(reference.getGeoJson(), GeoJsonObject.class); - + bbox = GCubeSDILayer.BBOX.fromGeoJSON(object.getBbox()); - + log.info("Found declared BBOX {} ", bbox); Double pointX = (bbox.getMaxX() + bbox.getMinX()) / 2; Double pointY = (bbox.getMaxY() + bbox.getMinY()) / 2; String wkt = String.format("POINT (%1$f %2$f) ", pointX, pointY); - + centroidDoc.put("geom", wkt); - //No overriding SpatialReference in the IndexDocumentReport, using the existing one. - }catch (Exception e) { + // No overriding SpatialReference in the IndexDocumentReport, using the existing + // one. + } catch (Exception e) { log.info("The defined spatial reference is wrong or empty: " + reference); } } - - //Calculating and overriding the SpatialReference (the Centroid JSON) in the IndexDocumentReport. - if(bbox==null) { + + // Calculating and overriding the SpatialReference (the Centroid JSON) in the + // IndexDocumentReport. + if (bbox == null) { log.info("No bbox defined in the current spatial reference going to calculate it..."); // unable to use current Spatial reference, try evaluating it log.debug("UseCaseDescriptor {} : Getting evaluation paths from useCaseDescriptor.. ", @@ -275,6 +282,9 @@ public class SDIIndexerPlugin extends SDIAbstractPlugin implements IndexerPlugin b.deleteCharAt(b.length() - 1); toSetValue = b.toString(); } + // Added by Francesco M. #26322 + toSetValue = toSetValueByApplyRegex(m, toSetValue); + log.trace("Setting {} = {} in centroid doc ", m.getName(), toSetValue); centroidDoc.put(m.getName(), toSetValue); } @@ -311,6 +321,43 @@ public class SDIIndexerPlugin extends SDIAbstractPlugin implements IndexerPlugin } } + // Added by Francesco M. #26322 + public static Object toSetValueByApplyRegex(MappingObject m, Object toSetValue) { + + ApplyRegex applyRegex = m.getApplyRegex(); + + if (applyRegex != null) { + try { + String valueString = toSetValue==null?"":toSetValue.toString(); + String type = applyRegex.getType(); + REGEX_TYPES theRegexType = ApplyRegex.REGEX_TYPES.valueOf(type); + Pattern p = Pattern.compile(applyRegex.getRegex()); + Matcher matcher = p.matcher(valueString); + switch (theRegexType) { + case find: + while (matcher.find()) { + toSetValue += matcher.group(); + } + break; + case replaceFirst: + toSetValue = matcher.replaceFirst(applyRegex.getReplacement()); + break; + case replaceAll: + toSetValue = matcher.replaceFirst(applyRegex.getReplacement()); + break; + + default: + break; + } + } catch (Exception e) { + log.warn("Error on applying replaceAll by regex {} on field {} = {} in centroid doc ", applyRegex, + m.getName(), toSetValue, e); + } + } + + return toSetValue; + } + /** * Gets the mappings. * @@ -338,13 +385,14 @@ public class SDIIndexerPlugin extends SDIAbstractPlugin implements IndexerPlugin try { PostgisIndexer indexer = getIndexer(request.getUseCaseDescriptor(), request.getCallParameters()); indexer.removeByFieldValue(PostgisIndexer.StandardFields.PROJECT_ID, request.getDocument().getId()); - - //***** Added by Francesco, see #25056 - //Replacing the "old" centroid if any. Creating an empty SpatialReference + + // ***** Added by Francesco, see #25056 + // Replacing the "old" centroid if any. Creating an empty SpatialReference SpatialReference reference = new SpatialReference(new Document()); - log.info("DeIndexer project {}, Setting Spatial Reference empty {} ", request.getDocument().getId(), Serialization.write(reference)); + log.info("DeIndexer project {}, Setting Spatial Reference empty {} ", request.getDocument().getId(), + Serialization.write(reference)); report.addIdentificationReference(reference); - + } catch (SDIInteractionException e) { log.error("Unable to index " + request, e); report.setStatus(Report.Status.ERROR); @@ -379,11 +427,11 @@ public class SDIIndexerPlugin extends SDIAbstractPlugin implements IndexerPlugin /** * Gets the indexer. * - * @param ucd the ucd + * @param ucd the ucd * @param params the params * @return the indexer - * @throws ConfigurationException the configuration exception - * @throws SQLException the SQL exception + * @throws ConfigurationException the configuration exception + * @throws SQLException the SQL exception * @throws InvalidProfileException the invalid profile exception * @throws SDIInteractionException the SDI interaction exception */ diff --git a/sdi-plugins/src/test/java/org/gcube/application/cms/sdi/LayerCreationTest.java b/sdi-plugins/src/test/java/org/gcube/application/cms/sdi/LayerCreationTest.java index e07ddb8..7196355 100644 --- a/sdi-plugins/src/test/java/org/gcube/application/cms/sdi/LayerCreationTest.java +++ b/sdi-plugins/src/test/java/org/gcube/application/cms/sdi/LayerCreationTest.java @@ -23,12 +23,11 @@ import org.gcube.application.geoportal.common.utils.tests.GCubeTest; import org.junit.Test; public class LayerCreationTest extends BasicTests { - - + @Test public void testCreateIndexLayer() throws SDIInteractionException, ConfigurationException, SQLException, InvalidProfileException { assumeTrue(GCubeTest.isTestInfrastructureEnabled()); - UseCaseDescriptor ucd = TestProfiles.profiles.get("sdi-tests"); + UseCaseDescriptor ucd = TestProfiles.profiles.get("concessioni"); DatabaseConnection db = ImplementationProvider.get().getProvidedObjectByClass(ISInterface.class). queryForDatabase("Database","postgis", "GNA_DB","Concessioni"); diff --git a/sdi-plugins/src/test/java/org/gcube/application/cms/sdi/MappingObjectRegexTest.java b/sdi-plugins/src/test/java/org/gcube/application/cms/sdi/MappingObjectRegexTest.java new file mode 100644 index 0000000..95cabc1 --- /dev/null +++ b/sdi-plugins/src/test/java/org/gcube/application/cms/sdi/MappingObjectRegexTest.java @@ -0,0 +1,50 @@ +package org.gcube.application.cms.sdi; + +import static org.junit.Assume.assumeTrue; + +import java.sql.SQLException; +import java.util.List; +import java.util.stream.Collectors; + +import org.gcube.application.cms.plugins.faults.InvalidProfileException; +import org.gcube.application.cms.sdi.engine.PostgisTable; +import org.gcube.application.cms.sdi.faults.SDIInteractionException; +import org.gcube.application.cms.sdi.model.MappingObject; +import org.gcube.application.cms.sdi.plugins.SDIIndexerPlugin; +import org.gcube.application.cms.tests.TestProfiles; +import org.gcube.application.geoportal.common.model.rest.ConfigurationException; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; +import org.gcube.application.geoportal.common.utils.tests.GCubeTest; +import org.junit.Test; + +public class MappingObjectRegexTest { + + String test = "paleolitico inferiore (da 2.000.000 a.C. al 200.000 a.C.)"; + + @Test + public void testApplyRegex() throws SDIInteractionException, ConfigurationException, SQLException, + InvalidProfileException, InterruptedException { + assumeTrue(GCubeTest.isTestInfrastructureEnabled()); + UseCaseDescriptor ucd = TestProfiles.profiles.get("profiledConcessioni"); + + System.out.println("ucd: " + ucd); + + List mappingObjects = MappingObject.getMappingsFromUCD(ucd, Constants.INDEXER_PLUGIN_ID); + + String toPrint = mappingObjects.stream().map(mo -> String.valueOf(mo)).collect(Collectors.joining("\n")); + + System.out.println(toPrint); + + for (MappingObject mappingObject : mappingObjects) { + Object toSetValue = SDIIndexerPlugin.toSetValueByApplyRegex(mappingObject, test); + System.out.println("MappingObject '" + mappingObject.getName() + "' toSetValue is: " + toSetValue); + } + + List fields = PostgisTable.Field.fromMappings(mappingObjects); + + for (PostgisTable.Field field : fields) { + System.out.println(field); + } + } + +} diff --git a/sdi-plugins/src/test/java/org/gcube/application/cms/sdi/MappingsFromUCDTest.java b/sdi-plugins/src/test/java/org/gcube/application/cms/sdi/MappingsFromUCDTest.java new file mode 100644 index 0000000..ab5ff8b --- /dev/null +++ b/sdi-plugins/src/test/java/org/gcube/application/cms/sdi/MappingsFromUCDTest.java @@ -0,0 +1,43 @@ +package org.gcube.application.cms.sdi; + +import static org.junit.Assume.assumeTrue; + +import java.sql.SQLException; +import java.util.List; +import java.util.stream.Collectors; + +import org.gcube.application.cms.plugins.faults.InvalidProfileException; +import org.gcube.application.cms.sdi.engine.PostgisTable; +import org.gcube.application.cms.sdi.faults.SDIInteractionException; +import org.gcube.application.cms.sdi.model.MappingObject; +import org.gcube.application.cms.tests.TestProfiles; +import org.gcube.application.cms.tests.model.BasicTests; +import org.gcube.application.geoportal.common.model.rest.ConfigurationException; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; +import org.gcube.application.geoportal.common.utils.tests.GCubeTest; +import org.junit.Test; + +public class MappingsFromUCDTest extends BasicTests { + + @Test + public void testReadMappingsFromUCD() + throws SDIInteractionException, ConfigurationException, SQLException, InvalidProfileException { + assumeTrue(GCubeTest.isTestInfrastructureEnabled()); + UseCaseDescriptor ucd = TestProfiles.profiles.get("profiledConcessioni"); + + System.out.println("ucd: " + ucd); + + List mappingObjects = MappingObject.getMappingsFromUCD(ucd, Constants.INDEXER_PLUGIN_ID); + + String toPrint = mappingObjects.stream().map(mo -> String.valueOf(mo)).collect(Collectors.joining("\n")); + + System.out.println(toPrint); + + List fields = PostgisTable.Field.fromMappings(mappingObjects); + + for (PostgisTable.Field field : fields) { + System.out.println(field); + } + } + +}