diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 39d368aad82..dbda173e220 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -38,7 +38,9 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 + with: + show-progress: 'false' - name: Setup Java JDK uses: actions/setup-java@v3.12.0 diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 1e26bb5bf47..1a32f8f6424 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -15,11 +15,12 @@ jobs: - os: ubuntu-22.04 jdk: 11 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: # 500 commits, set to 0 to get all fetch-depth: 500 submodules: 'recursive' + show-progress: 'false' - name: Set up JDK uses: actions/setup-java@v3.12.0 with: @@ -42,11 +43,12 @@ jobs: QA: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: # 500 commits, set to 0 to get all fetch-depth: 500 submodules: 'recursive' + show-progress: 'false' - name: Set up JDK uses: actions/setup-java@v3.12.0 with: diff --git a/.github/workflows/mvn-dep-tree.yml b/.github/workflows/mvn-dep-tree.yml index e1693f5297a..74bd2f9cad7 100644 --- a/.github/workflows/mvn-dep-tree.yml +++ b/.github/workflows/mvn-dep-tree.yml @@ -15,7 +15,9 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 + with: + show-progress: 'false' - name: Setup Java JDK uses: actions/setup-java@v3.12.0 diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index 76c83de388c..33abdc2a46b 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -13,10 +13,11 @@ jobs: # https://github.community/t/how-to-detect-a-pull-request-from-a-fork/18363/4 if: github.event.pull_request.head.repo.fork != true steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis submodules: 'recursive' + show-progress: 'false' - name: Set up JDK 11 uses: actions/setup-java@v3.12.0 with: diff --git a/core/src/main/java/org/fao/geonet/api/tools/i18n/TranslationPackBuilder.java b/core/src/main/java/org/fao/geonet/api/tools/i18n/TranslationPackBuilder.java index f290068098c..8f14052ab05 100644 --- a/core/src/main/java/org/fao/geonet/api/tools/i18n/TranslationPackBuilder.java +++ b/core/src/main/java/org/fao/geonet/api/tools/i18n/TranslationPackBuilder.java @@ -136,12 +136,21 @@ public Map getPack( ); } else if (config[0].equals(TranslationType.standards.name()) && config.length == 4) { - // standards/iso19115-3.2018/codelists/cit:CI_DateTypeCode+... String[] codelistKeys = config[3].split(LIST_SEPARATOR); - translations.putAll( - self.getStandardCodelist( - language, config[1], Arrays.asList(codelistKeys), context) - ); + + if ("labels".equals(config[2])) { + // standards/iso19139/labels/gmd:DQ_AbsoluteExternalPositionalAccuracy+gmd + translations.putAll( + self.getStandardLabel( + language, config[1], Arrays.asList(codelistKeys), context) + ); + } else { + // standards/iso19115-3.2018/codelists/cit:CI_DateTypeCode+... + translations.putAll( + self.getStandardCodelist( + language, config[1], Arrays.asList(codelistKeys), context) + ); + } } else { throw new IllegalArgumentException( String.format( @@ -193,6 +202,28 @@ public Map getStandardCodelist( return translations; } + @Cacheable(value = "translations", + cacheManager = "cacheManager", + key = "{#schema, #language, #label}") + public Map getStandardLabel( + String language, String schema, List label, + ServiceContext context) { + Map translations = new HashMap<>(); + context.setLanguage(language); + + for (String c : label) { + Element e = null; + try { + e = StandardsUtils.getLabel(c, schemaManager, + schema, null, null, null, null, context); + translations.put(c.split(":")[1], e.getChildText("label")); + } catch (Exception exception) { + exception.printStackTrace(); + } + } + return translations; + } + @Cacheable(value = "translations", cacheManager = "cacheManager") public Map getDbTranslation(String language, List type) { Map translations = new HashMap<>(); diff --git a/core/src/main/java/org/fao/geonet/kernel/SchemaManager.java b/core/src/main/java/org/fao/geonet/kernel/SchemaManager.java index 1489c367132..77173317ffa 100644 --- a/core/src/main/java/org/fao/geonet/kernel/SchemaManager.java +++ b/core/src/main/java/org/fao/geonet/kernel/SchemaManager.java @@ -1,29 +1,25 @@ -//============================================================================= -//=== -//=== SchemaManager -//=== -//============================================================================= -//=== Copyright (C) 2001-2011 Food and Agriculture Organization of the -//=== United Nations (FAO-UN), United Nations World Food Programme (WFP) -//=== and United Nations Environment Programme (UNEP) -//=== -//=== This program is free software; you can redistribute it and/or modify -//=== it under the terms of the GNU General Public License as published by -//=== the Free Software Foundation; either version 2 of the License, or (at -//=== your option) any later version. -//=== -//=== This program 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 -//=== General Public License for more details. -//=== -//=== You should have received a copy of the GNU General Public License -//=== along with this program; if not, write to the Free Software -//=== Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -//=== -//=== Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2, -//=== Rome - Italy. email: geonetwork@osgeo.org -//============================================================================== +/* + * Copyright (C) 2001-2023 Food and Agriculture Organization of the + * United Nations (FAO-UN), United Nations World Food Programme (WFP) + * and United Nations Environment Programme (UNEP) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + * Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2, + * Rome - Italy. email: geonetwork@osgeo.org + */ package org.fao.geonet.kernel; @@ -42,6 +38,7 @@ import org.fao.geonet.exceptions.OperationAbortedEx; import org.fao.geonet.exceptions.SchemaMatchConflictException; import org.fao.geonet.kernel.schema.MetadataSchema; +import org.fao.geonet.kernel.schema.MetadataSchemaOperationFilter; import org.fao.geonet.kernel.schema.SchemaLoader; import org.fao.geonet.kernel.schema.SchemaPlugin; import org.fao.geonet.kernel.setting.SettingInfo; @@ -107,8 +104,8 @@ public class SchemaManager { * Active writers count */ private static int activeWriters = 0; - private Map hmSchemas = new HashMap(); - private Map hmSchemasTypenames = new HashMap(); + private Map hmSchemas = new HashMap<>(); + private Map hmSchemasTypenames = new HashMap<>(); private String[] fnames = {"labels.xml", "codelists.xml", "strings.xml"}; private Path schemaPluginsDir; private Path schemaPluginsCat; @@ -271,11 +268,11 @@ public MetadataSchema getSchema(String name) { try { Schema schema = hmSchemas.get(name); - if (schema == null) + if (schema == null) { throw new IllegalArgumentException("Schema not registered : " + name); + } - final MetadataSchema mds = schema.getMetadataSchema(); - return mds; + return schema.getMetadataSchema(); } finally { afterRead(); } @@ -288,7 +285,7 @@ public MetadataSchema getSchema(String name) { */ public Set getDependencies(String name) { - Set dependencies = new HashSet(); + Set dependencies = new HashSet<>(); beforeRead(); try { @@ -541,7 +538,7 @@ public List getConversionElements(String name) throws Exception { try { Schema schema = hmSchemas.get(name); List childs = schema.getConversionElements(); - List dChilds = new ArrayList(); + List dChilds = new ArrayList<>(); for (Element child : childs) { if (child != null) dChilds.add((Element) child.clone()); } @@ -712,40 +709,35 @@ public String autodetectSchema(Element md, String defaultSchema) throws SchemaMa // -- specific test first, then in order of increasing generality, // -- first match wins schema = compareElementsAndAttributes(md, MODE_ATTRIBUTEWITHVALUE); - if (schema != null) { - if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) - Log.debug(Geonet.SCHEMA_MANAGER, " => Found schema " + schema + " using AUTODETECT(attributes) examination"); + if (schema != null && Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) { + Log.debug(Geonet.SCHEMA_MANAGER, " => Found schema " + schema + " using AUTODETECT(attributes) examination"); } if (schema == null) { schema = compareElementsAndAttributes(md, MODE_NEEDLEWITHVALUE); - if (schema != null) { - if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) - Log.debug(Geonet.SCHEMA_MANAGER, " => Found schema " + schema + " using AUTODETECT(elements with value) examination"); + if (schema != null && Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) { + Log.debug(Geonet.SCHEMA_MANAGER, " => Found schema " + schema + " using AUTODETECT(elements with value) examination"); } } if (schema == null) { schema = compareElementsAndAttributes(md, MODE_NEEDLE); - if (schema != null) { - if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) - Log.debug(Geonet.SCHEMA_MANAGER, " => Found schema " + schema + " using AUTODETECT(elements) examination"); + if (schema != null && Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) { + Log.debug(Geonet.SCHEMA_MANAGER, " => Found schema " + schema + " using AUTODETECT(elements) examination"); } } if (schema == null) { schema = compareElementsAndAttributes(md, MODE_ROOT); - if (schema != null) { - if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) - Log.debug(Geonet.SCHEMA_MANAGER, " => Found schema " + schema + " using AUTODETECT(elements with root) examination"); + if (schema != null && Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) { + Log.debug(Geonet.SCHEMA_MANAGER, " => Found schema " + schema + " using AUTODETECT(elements with root) examination"); } } if (schema == null) { schema = compareElementsAndAttributes(md, MODE_NAMESPACE); - if (schema != null) { - if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) - Log.debug(Geonet.SCHEMA_MANAGER, " => Found schema " + schema + " using AUTODETECT(namespaces) examination"); + if (schema != null && Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) { + Log.debug(Geonet.SCHEMA_MANAGER, " => Found schema " + schema + " using AUTODETECT(namespaces) examination"); } } @@ -789,8 +781,9 @@ private String checkNamespace(Element md, String schema) { MetadataSchema mds = getSchema(schema); if (mds != null) { String primeNs = mds.getPrimeNS(); - if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) + if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) { Log.debug(Geonet.SCHEMA_MANAGER, " primeNs " + primeNs + " for schema " + schema); + } if (md.getNamespace().getURI().equals(primeNs)) { result = schema; } else { @@ -800,8 +793,9 @@ private String checkNamespace(Element md, String schema) { Schema sch = hmSchemas.get(schema); List dependsList = sch.getDependElements(); for (Element depends : dependsList) { - if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) + if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) { Log.debug(Geonet.SCHEMA_MANAGER, " checkNamespace for dependency: " + depends.getText()); + } return checkNamespace(md, depends.getText()); } } @@ -869,7 +863,7 @@ private void realDeletePluginSchema(String name, boolean doDependencies) throws if (schema != null) { if (doDependencies) { List dependsOnMe = getSchemasThatDependOnMe(name); - if (dependsOnMe.size() > 0) { + if (!dependsOnMe.isEmpty()) { String errStr = "Cannot remove schema " + name + " because the following schemas list it as a dependency: " + dependsOnMe; Log.error(Geonet.SCHEMA_MANAGER, errStr); throw new OperationAbortedEx(errStr); @@ -959,19 +953,21 @@ private void addSchema(ApplicationContext applicationContext, Path schemaDir, El final String schemaName = schemaDir.getFileName().toString(); Path locBase = schemaDir.resolve("loc"); - Map xfMap = new HashMap(); + Map xfMap = new HashMap<>(); for (String fname : fnames) { Path filePath = path.resolve("loc").resolve(defaultLang).resolve(fname); - if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) + if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) { Log.debug(Geonet.SCHEMA_MANAGER, "Searching for " + filePath); + } if (Files.exists(filePath)) { Element config = new Element("xml"); config.setAttribute("name", schemaName); config.setAttribute("base", locBase.toUri().toString()); config.setAttribute("file", fname); - if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) + if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) { Log.debug(Geonet.SCHEMA_MANAGER, "Adding XmlFile " + Xml.getString(config)); + } XmlFile xf = new XmlFile(config, defaultLang, true); xfMap.put(fname, xf); } else { @@ -1078,8 +1074,9 @@ private Element deleteSchemaFromPluginCatalog(String name, Element root) throws else continue; // skip this if (!uri.getName().equals("uri") || !uri.getNamespace().equals(Namespaces.OASIS_CATALOG)) { - if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) + if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) { Log.debug(Geonet.SCHEMA_MANAGER, "Skipping element " + uri.getQualifiedName() + ":" + uri.getNamespace()); + } continue; } @@ -1113,8 +1110,9 @@ private int getHighestSchemaPluginCatalogId(String name, Element root) throws Ex else continue; // skip this if (!uri.getName().equals("rewriteURI") || !uri.getNamespace().equals(Namespaces.OASIS_CATALOG)) { - if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) + if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) { Log.debug(Geonet.SCHEMA_MANAGER, "Skipping element " + uri.getQualifiedName() + ":" + uri.getNamespace()); + } continue; } @@ -1122,8 +1120,9 @@ private int getHighestSchemaPluginCatalogId(String name, Element root) throws Ex if (uri.getAttributeValue("rewritePrefix").equals(ourUri.toString())) return -1; String nameAttr = uri.getAttributeValue("uriStartString"); - if (nameAttr.startsWith(Geonet.File.METADATA_BLANK)) { - if (nameAttr.compareTo(baseBlank) > 0) baseBlank = nameAttr; + if (nameAttr.startsWith(Geonet.File.METADATA_BLANK) && + nameAttr.compareTo(baseBlank) > 0) { + baseBlank = nameAttr; } } @@ -1318,17 +1317,17 @@ private void processSchema(ApplicationContext applicationContext, Path schemasDi * Check dependencies for all schemas - remove those that fail. */ private void checkDependencies(Element schemaPluginCatRoot) throws Exception { - List removes = new ArrayList(); + List removes = new ArrayList<>(); // process each schema to see whether its dependencies are present - for (String schemaName : hmSchemas.keySet()) { - Schema schema = hmSchemas.get(schemaName); + for (Map.Entry schemaInfo : hmSchemas.entrySet()) { + Schema schema = schemaInfo.getValue(); try { - checkDepends(schemaName, schema.getDependElements()); + checkDepends(schemaInfo.getKey(), schema.getDependElements()); } catch (Exception e) { Log.error(Geonet.SCHEMA_MANAGER, "check dependencies failed: " + e.getMessage()); // add the schema to list for removal - removes.add(schemaName); + removes.add(schemaInfo.getKey()); } } @@ -1341,7 +1340,7 @@ private void checkDependencies(Element schemaPluginCatRoot) throws Exception { } private void checkAppSupported(Element schemaPluginCatRoot) throws Exception { - List removes = new ArrayList(); + List removes = new ArrayList<>(); final SystemInfo systemInfo = ApplicationContextHolder.get().getBean(SystemInfo.class); @@ -1349,17 +1348,17 @@ private void checkAppSupported(Element schemaPluginCatRoot) throws Exception { Version appVersion = Version.parseVersionNumber(version); // process each schema to see whether its dependencies are present - for (String schemaName : hmSchemas.keySet()) { - Schema schema = hmSchemas.get(schemaName); + for (Map.Entry schemaInfo : hmSchemas.entrySet()) { + Schema schema = schemaInfo.getValue(); String minorAppVersionSupported = schema.getMetadataSchema().getAppMinorVersionSupported(); Version schemaMinorAppVersion = Version.parseVersionNumber(minorAppVersionSupported); if (appVersion.compareTo(schemaMinorAppVersion) < 0) { - Log.error(Geonet.SCHEMA_MANAGER, "Schema " + schemaName + + Log.error(Geonet.SCHEMA_MANAGER, "Schema " + schemaInfo.getKey() + " requires min Geonetwork version: " + minorAppVersionSupported + ", current is: " + version + ". Skip load schema."); - removes.add(schemaName); + removes.add(schemaInfo.getKey()); continue; } @@ -1368,10 +1367,10 @@ private void checkAppSupported(Element schemaPluginCatRoot) throws Exception { Version schemaMajorAppVersion = Version.parseVersionNumber(majorAppVersionSupported); if (appVersion.compareTo(schemaMajorAppVersion) > 0) { - Log.error(Geonet.SCHEMA_MANAGER, "Schema " + schemaName + + Log.error(Geonet.SCHEMA_MANAGER, "Schema " + schemaInfo.getKey() + " requires max Geonetwork version: " + majorAppVersionSupported + ", current is: " + version + ". Skip load schema."); - removes.add(schemaName); + removes.add(schemaInfo.getKey()); continue; } } @@ -1396,17 +1395,17 @@ private void checkAppSupported(Element schemaPluginCatRoot) throws Exception { */ public List getSchemasThatDependOnMe(String schemaName) { - List myDepends = new ArrayList(); + List myDepends = new ArrayList<>(); // process each schema to see whether its dependencies are present - for (String schemaNameToTest : hmSchemas.keySet()) { - if (schemaNameToTest.equals(schemaName)) continue; + for (Map.Entry schemaInfoToTest : hmSchemas.entrySet()) { + if (schemaInfoToTest.getKey().equals(schemaName)) continue; - Schema schema = hmSchemas.get(schemaNameToTest); + Schema schema = schemaInfoToTest.getValue(); List dependsList = schema.getDependElements(); for (Element depends : dependsList) { if (depends.getText().equals(schemaName)) { - myDepends.add(schemaNameToTest); + myDepends.add(schemaInfoToTest.getKey()); } } } @@ -1424,7 +1423,7 @@ private void checkDepends(String thisSchema, List dependsList) throws E // process each dependency to see whether it is present for (Element depends : dependsList) { String schema = depends.getText(); - if (schema.length() > 0) { + if (StringUtils.isNotBlank(schema)) { if (!hmSchemas.containsKey(schema)) { throw new IllegalArgumentException("Schema " + thisSchema + " depends on " + schema + ", but that schema is not loaded"); } @@ -1444,7 +1443,7 @@ private List extractDepends(Path xmlIdFile) throws Exception { // get list of depends elements from schema-ident.xml List dependsList = root.getChildren("depends", GEONET_SCHEMA_NS); - if (dependsList.size() == 0) { + if (dependsList.isEmpty()) { dependsList = root.getChildren("depends", GEONET_SCHEMA_PREFIX_NS); } return dependsList; @@ -1502,11 +1501,11 @@ private Map getSchemaIdentMultilingualProperty(Element root, Str * true if schema requires to synch the uuid column schema info with the uuid in the metadata * record (updated on editing or in UFO). */ - private Map> extractOperationFilters(Path xmlIdFile) throws Exception { + private Map extractOperationFilters(Path xmlIdFile) throws Exception { Element root = Xml.loadFile(xmlIdFile); Element filters = root.getChild("filters", GEONET_SCHEMA_NS); - Map> filterRules = - new HashMap>(); + Map filterRules = + new HashMap<>(); if (filters == null) { return filterRules; } else { @@ -1514,11 +1513,14 @@ private Map> extractOperationFilters(Path xmlIdFil if (rule instanceof Element) { Element ruleElement = (Element) rule; String xpath = ruleElement.getAttributeValue("xpath"); + String jsonpath = ruleElement.getAttributeValue("jsonpath"); String ifNotOperation = ruleElement.getAttributeValue("ifNotOperation"); Element markedElement = ruleElement.getChild("keepMarkedElement", GEONET_SCHEMA_NS); + if (StringUtils.isNotBlank(ifNotOperation) && StringUtils.isNotBlank(xpath)) { - filterRules.put(ifNotOperation, Pair.read(xpath, markedElement)); + MetadataSchemaOperationFilter filter = new MetadataSchemaOperationFilter(xpath, jsonpath, ifNotOperation, markedElement); + filterRules.put(ifNotOperation, filter); } } } @@ -1574,11 +1576,12 @@ private List extractConvElements(Path xmlConvFile) throws Exception { if (!Files.exists(xmlConvFile)) { if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) Log.debug(Geonet.SCHEMA_MANAGER, "Schema conversions file not present"); - return new ArrayList(); + return new ArrayList<>(); } else { Element root = Xml.loadFile(xmlConvFile); - if (root.getName() != "conversions") + if (!root.getName().equals("conversions")) { throw new IllegalArgumentException("Schema conversions file " + xmlConvFile + " is invalid, no root element"); + } @SuppressWarnings("unchecked") List result = root.getChildren(); return result; @@ -1609,8 +1612,9 @@ private String compareElementsAndAttributes(Element md, int mode) throws SchemaM Set allSchemas = getSchemas(); List matches = new ArrayList<>(); - if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) + if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) { Log.debug(Geonet.SCHEMA_MANAGER, "Schema autodetection starting on " + md.getName() + " (Namespace: " + md.getNamespace() + ") using mode: " + mode + "..."); + } for (String schemaName : allSchemas) { if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) @@ -1619,8 +1623,9 @@ private String compareElementsAndAttributes(Element md, int mode) throws SchemaM List adElems = schema.getAutodetectElements(); for (Element elem : adElems) { - if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) + if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) { Log.debug(Geonet.SCHEMA_MANAGER, " Checking autodetect element " + Xml.getString(elem) + " with name " + elem.getName()); + } @SuppressWarnings("unchecked") List elemKids = elem.getChildren(); @@ -1629,12 +1634,13 @@ private String compareElementsAndAttributes(Element md, int mode) throws SchemaM Attribute type = elem.getAttribute("type"); // --- try and find the attribute and value in md - if (mode == MODE_ATTRIBUTEWITHVALUE && elem.getName() == "attributes") { + if (mode == MODE_ATTRIBUTEWITHVALUE && elem.getName().equals("attributes")) { @SuppressWarnings("unchecked") List atts = elem.getAttributes(); for (Attribute searchAtt : atts) { - if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) + if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) { Log.debug(Geonet.SCHEMA_MANAGER, " Finding attribute " + searchAtt.toString()); + } if (isMatchingAttributeInMetadata(searchAtt, md)) { match = true; @@ -1649,8 +1655,9 @@ private String compareElementsAndAttributes(Element md, int mode) throws SchemaM @SuppressWarnings("unchecked") List nss = elem.getAdditionalNamespaces(); for (Namespace ns : nss) { - if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) + if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) { Log.debug(Geonet.SCHEMA_MANAGER, " Finding namespace " + ns.toString()); + } if (isMatchingNamespaceInMetadata(ns, md)) { match = true; @@ -1664,8 +1671,9 @@ private String compareElementsAndAttributes(Element md, int mode) throws SchemaM // --- is the kid the same as the root of the md if (mode == MODE_ROOT && type != null && "root".equals(type.getValue())) { - if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) + if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) { Log.debug(Geonet.SCHEMA_MANAGER, " Comparing " + Xml.getString(kid) + " with " + md.getName() + " with namespace " + md.getNamespace() + " : " + (kid.getName().equals(md.getName()) && kid.getNamespace().equals(md.getNamespace()))); + } if (kid.getName().equals(md.getName()) && kid.getNamespace().equals(md.getNamespace())) { match = true; @@ -1675,8 +1683,9 @@ private String compareElementsAndAttributes(Element md, int mode) throws SchemaM } // --- try and find the kid in the md (kid only, not value) } else if (mode == MODE_NEEDLE && type != null && "search".equals(type.getValue())) { - if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) + if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) { Log.debug(Geonet.SCHEMA_MANAGER, " Comparing " + Xml.getString(kid) + " with " + md.getName() + " with namespace " + md.getNamespace() + " : " + (kid.getName().equals(md.getName()) && kid.getNamespace().equals(md.getNamespace()))); + } if (isMatchingElementInMetadata(kid, md, false)) { match = true; @@ -1720,8 +1729,9 @@ private boolean isMatchingAttributeInMetadata(Attribute needle, Element haystack @SuppressWarnings("unchecked") Iterator haystackIterator = haystack.getDescendants(new ElementFilter()); - if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) + if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) { Log.debug(Geonet.SCHEMA_MANAGER, "Matching " + needle.toString()); + } while (haystackIterator.hasNext()) { Element tempElement = haystackIterator.next(); @@ -1742,8 +1752,9 @@ private boolean isMatchingAttributeInMetadata(Attribute needle, Element haystack * @param haystack the XML metadata record we are searching */ private boolean isMatchingNamespaceInMetadata(Namespace needle, Element haystack) { - if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) + if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) { Log.debug(Geonet.SCHEMA_MANAGER, "Matching " + needle.toString()); + } if (checkNamespacesOnElement(needle, haystack)) return true; @@ -1797,8 +1808,9 @@ private boolean isMatchingElementInMetadata(Element needle, Element haystack, bo if (tempElement.getName().equals(needleName) && tempElement.getNamespace().equals(needleNS)) { if (checkValue) { - if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) + if (Log.isDebugEnabled(Geonet.SCHEMA_MANAGER)) { Log.debug(Geonet.SCHEMA_MANAGER, " Searching value for element: " + tempElement.getName()); + } String needleVal = StringUtils.deleteWhitespace(needle.getValue()); String tempVal = StringUtils.deleteWhitespace(tempElement.getValue()); @@ -1923,7 +1935,6 @@ public List getListOfTypeNames() { List listOfTypenames = new ArrayList<>(); while (iterator.hasNext()) { String typeName = iterator.next(); - Namespace ns = hmSchemasTypenames.get(typeName); listOfTypenames.add(typeName); } return listOfTypenames; diff --git a/core/src/main/java/org/fao/geonet/kernel/XmlSerializer.java b/core/src/main/java/org/fao/geonet/kernel/XmlSerializer.java index 4e0840d5a68..762afc9b551 100644 --- a/core/src/main/java/org/fao/geonet/kernel/XmlSerializer.java +++ b/core/src/main/java/org/fao/geonet/kernel/XmlSerializer.java @@ -36,6 +36,7 @@ import org.fao.geonet.kernel.datamanager.IMetadataManager; import org.fao.geonet.kernel.datamanager.IMetadataUtils; import org.fao.geonet.kernel.schema.MetadataSchema; +import org.fao.geonet.kernel.schema.MetadataSchemaOperationFilter; import org.fao.geonet.kernel.setting.SettingManager; import org.fao.geonet.kernel.setting.Settings; import org.fao.geonet.utils.Log; @@ -70,13 +71,13 @@ public static void clearThreadLocal() { } public static void removeFilteredElement(Element metadata, - final Pair xPathAndMarkedElement, + final MetadataSchemaOperationFilter filter, List namespaces) throws JDOMException { // xPathAndMarkedElement seem can be null in some schemas like dublin core - if (xPathAndMarkedElement == null) return; + if (filter == null) return; - String xpath = xPathAndMarkedElement.one(); - Element mark = xPathAndMarkedElement.two(); + String xpath = filter.getXpath(); + Element mark = filter.getMarkedElement(); List nodes = Xml.selectNodes(metadata, xpath, @@ -89,13 +90,13 @@ public static void removeFilteredElement(Element metadata, // Remove attributes @SuppressWarnings("unchecked") - List atts = new ArrayList(element.getAttributes()); + List atts = new ArrayList<>(element.getAttributes()); for (Attribute attribute : atts) { attribute.detach(); } // Insert attributes or children element of the mark - List markAtts = new ArrayList(mark.getAttributes()); + List markAtts = new ArrayList<>(mark.getAttributes()); for (Attribute attribute : markAtts) { element.setAttribute((Attribute) attribute.clone()); } @@ -182,33 +183,42 @@ public Element removeHiddenElements(boolean isIndexingTask, AbstractMetadata met // Check if a filter is defined for this schema // for the editing operation ie. user who can not edit // will not see those elements. - Pair editXpathFilter = mds.getOperationFilter(ReservedOperation.editing); - boolean filterEditOperationElements = editXpathFilter != null; + MetadataSchemaOperationFilter editFilter = mds.getOperationFilter(ReservedOperation.editing); + boolean filterEditOperationElements = editFilter != null; List namespaces = mds.getNamespaces(); if (context != null) { - if (editXpathFilter != null) { + if (editFilter != null) { boolean canEdit = accessManager.canEdit(context, id); if (canEdit) { filterEditOperationElements = false; } } - Pair downloadXpathFilter = mds.getOperationFilter(ReservedOperation.download); - if (downloadXpathFilter != null) { + + MetadataSchemaOperationFilter authenticatedFilter = mds.getOperationFilter("authenticated"); + if (authenticatedFilter != null) { + boolean isAuthenticated = context.getUserSession().isAuthenticated(); + if (!isAuthenticated) { + removeFilteredElement(metadataXml, authenticatedFilter, namespaces); + } + } + + MetadataSchemaOperationFilter downloadFilter = mds.getOperationFilter(ReservedOperation.download); + if (downloadFilter != null) { boolean canDownload = accessManager.canDownload(context, id); if (!canDownload) { - removeFilteredElement(metadataXml, downloadXpathFilter, namespaces); + removeFilteredElement(metadataXml, downloadFilter, namespaces); } } - Pair dynamicXpathFilter = mds.getOperationFilter(ReservedOperation.dynamic); - if (dynamicXpathFilter != null) { + MetadataSchemaOperationFilter dynamicFilter = mds.getOperationFilter(ReservedOperation.dynamic); + if (dynamicFilter != null) { boolean canDynamic = accessManager.canDynamic(context, id); if (!canDynamic) { - removeFilteredElement(metadataXml, dynamicXpathFilter, namespaces); + removeFilteredElement(metadataXml, dynamicFilter, namespaces); } } } if (filterEditOperationElements || (getThreadLocal(false) != null && getThreadLocal(false).forceFilterEditOperation)) { - removeFilteredElement(metadataXml, editXpathFilter, namespaces); + removeFilteredElement(metadataXml, editFilter, namespaces); } } return metadataXml; diff --git a/core/src/main/java/org/fao/geonet/kernel/datamanager/base/BaseMetadataIndexer.java b/core/src/main/java/org/fao/geonet/kernel/datamanager/base/BaseMetadataIndexer.java index e91a3a828f0..ae899ebd1ff 100644 --- a/core/src/main/java/org/fao/geonet/kernel/datamanager/base/BaseMetadataIndexer.java +++ b/core/src/main/java/org/fao/geonet/kernel/datamanager/base/BaseMetadataIndexer.java @@ -409,13 +409,13 @@ public void indexMetadata(final String metadataId, fields.put(IndexFields.DRAFT, "n"); fields.put(IndexFields.INDEXING_ERROR_FIELD, true); fields.put(IndexFields.INDEXING_ERROR_MSG, String.format( - "Schema '%s' is not registerd in this catalog. Install it or remove those records", + "Schema '%s' is not registered in this catalog. Install it or remove those records", schema )); searchManager.index(null, md, indexKey, fields, metadataType, forceRefreshReaders, indexingMode); Log.error(Geonet.DATA_MANAGER, String.format( - "Record %s / Schema '%s' is not registerd in this catalog. Install it or remove those records. Record is indexed indexing error flag.", + "Record %s / Schema '%s' is not registered in this catalog. Install it or remove those records. Record is indexed indexing error flag.", metadataId, schema)); } else { diff --git a/core/src/main/java/org/fao/geonet/kernel/datamanager/base/BaseMetadataUtils.java b/core/src/main/java/org/fao/geonet/kernel/datamanager/base/BaseMetadataUtils.java index 64ad3fc04fb..ad4dde213b4 100644 --- a/core/src/main/java/org/fao/geonet/kernel/datamanager/base/BaseMetadataUtils.java +++ b/core/src/main/java/org/fao/geonet/kernel/datamanager/base/BaseMetadataUtils.java @@ -360,17 +360,20 @@ public String getDefaultUrl(String uuid, String language) { private String buildUrl(String uuid, String language, String url) { if (StringUtils.isNotEmpty(url)) { + String upperCaseUrl = url.toUpperCase(); Map substitutions = new HashMap<>(); substitutions.put("{{UUID}}", uuid); substitutions.put("{{LANG}}", StringUtils.isEmpty(language) ? "" : language); - try { - String resourceId = getResourceIdentifier(uuid); - substitutions.put("{{RESOURCEID}}", StringUtils.isEmpty(resourceId) ? "" : resourceId); - } catch (Exception e) { - // No resource identifier xpath defined in schema + if (upperCaseUrl.contains("{{RESOURCEID}}")) { + try { + String resourceId = getResourceIdentifier(uuid); + substitutions.put("{{RESOURCEID}}", StringUtils.isEmpty(resourceId) ? "" : resourceId); + } catch (Exception e) { + // No resource identifier xpath defined in schema + } } for (Map.Entry s : substitutions.entrySet()) { - if (url.toUpperCase().contains(s.getKey())) { + if (upperCaseUrl.contains(s.getKey())) { url = url.replaceAll("(?i)" + Pattern.quote(s.getKey()), s.getValue()); } } diff --git a/core/src/main/java/org/fao/geonet/kernel/mef/ExportFormat.java b/core/src/main/java/org/fao/geonet/kernel/mef/ExportFormat.java index 5fd16fdb577..02fe7637483 100644 --- a/core/src/main/java/org/fao/geonet/kernel/mef/ExportFormat.java +++ b/core/src/main/java/org/fao/geonet/kernel/mef/ExportFormat.java @@ -31,6 +31,7 @@ import java.util.Set; import org.fao.geonet.GeonetContext; +import org.fao.geonet.constants.Edit; import org.fao.geonet.constants.Geonet; import org.fao.geonet.domain.AbstractMetadata; import org.fao.geonet.domain.Metadata; @@ -72,7 +73,7 @@ public static Iterable> getFormats(ServiceContext context, String outputFileName = entry.getValue(); Path path = metadataSchema.getSchemaDir().resolve(xslFileName); if (Files.isRegularFile(path)) { - String outputData = formatData(metadata, true, path); + String outputData = formatData(context, metadata, true, path); allExports.add(Pair.read(outputFileName, outputData)); } else { // A conversion that does not exist @@ -96,10 +97,9 @@ public static Iterable> getFormats(ServiceContext context, * * @return ByteArrayInputStream */ - public static String formatData(AbstractMetadata metadata, boolean transform, Path stylePath) throws Exception { - String xmlData = metadata.getData(); - - Element md = Xml.loadString(xmlData, false); + public static String formatData(ServiceContext context, AbstractMetadata metadata, boolean transform, Path stylePath) throws Exception { + Element md = context.getBean(DataManager.class).getMetadata(context, metadata.getId() + "", false, false, true); + md.removeChild("info", Edit.NAMESPACE); // Apply a stylesheet transformation when schema is ISO profil if (transform) { diff --git a/core/src/main/java/org/fao/geonet/kernel/schema/MetadataSchema.java b/core/src/main/java/org/fao/geonet/kernel/schema/MetadataSchema.java index d07dccc595c..3f8e038a88d 100644 --- a/core/src/main/java/org/fao/geonet/kernel/schema/MetadataSchema.java +++ b/core/src/main/java/org/fao/geonet/kernel/schema/MetadataSchema.java @@ -1,29 +1,25 @@ -//============================================================================== -//=== -//=== MetadataSchema -//=== -//============================================================================== -//=== Copyright (C) 2001-2007 Food and Agriculture Organization of the -//=== United Nations (FAO-UN), United Nations World Food Programme (WFP) -//=== and United Nations Environment Programme (UNEP) -//=== -//=== This program is free software; you can redistribute it and/or modify -//=== it under the terms of the GNU General Public License as published by -//=== the Free Software Foundation; either version 2 of the License, or (at -//=== your option) any later version. -//=== -//=== This program 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 -//=== General Public License for more details. -//=== -//=== You should have received a copy of the GNU General Public License -//=== along with this program; if not, write to the Free Software -//=== Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -//=== -//=== Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2, -//=== Rome - Italy. email: geonetwork@osgeo.org -//============================================================================== +/* + * Copyright (C) 2001-2023 Food and Agriculture Organization of the + * United Nations (FAO-UN), United Nations World Food Programme (WFP) + * and United Nations Environment Programme (UNEP) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + * Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2, + * Rome - Italy. email: geonetwork@osgeo.org + */ package org.fao.geonet.kernel.schema; @@ -34,9 +30,9 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import org.apache.commons.lang.StringUtils; import org.fao.geonet.api.exception.ResourceNotFoundException; import org.fao.geonet.constants.Geonet; -import org.fao.geonet.domain.Pair; import org.fao.geonet.domain.ReservedOperation; import org.fao.geonet.domain.Schematron; import org.fao.geonet.domain.SchematronCriteria; @@ -82,15 +78,15 @@ public class MetadataSchema { private static final String XSL_FILE_EXTENSION = ".xsl"; private static final String SCH_FILE_EXTENSION = ".sch"; private static final String SCHEMATRON_RULE_FILE_PREFIX = "schematron-rules"; - private Map> hmElements = new HashMap>(); - private Map>> hmRestric = new HashMap>>(); - private Map hmTypes = new HashMap(); - private Map> hmSubs = new HashMap>(); - private Map hmSubsLink = new HashMap(); - private Map hmNameSpaces = new HashMap(); - private Map hmPrefixes = new HashMap(); - private Map> hmOperationFilters = - new HashMap>(); + private Map> hmElements = new HashMap<>(); + private Map>> hmRestric = new HashMap<>(); + private Map hmTypes = new HashMap<>(); + private Map> hmSubs = new HashMap<>(); + private Map hmSubsLink = new HashMap<>(); + private Map hmNameSpaces = new HashMap<>(); + private Map hmPrefixes = new HashMap<>(); + private Map hmOperationFilters = + new HashMap<>(); private String schemaName; private Path schemaDir; private String standardUrl; @@ -294,8 +290,8 @@ void addElement(String name, String type, List alValues, List al // first just add the subs - because these are for global elements we // never have a clash because global elements are all in the same scope // and are thus unique - if (alSubs != null && alSubs.size() > 0) hmSubs.put(name, alSubs); - if (subLink != null && subLink.length() > 0) hmSubsLink.put(name, subLink); + if (alSubs != null && !alSubs.isEmpty()) hmSubs.put(name, alSubs); + if (subLink != null && StringUtils.isNotBlank(subLink)) hmSubsLink.put(name, subLink); List exType = hmElements.get(name); @@ -309,7 +305,8 @@ void addElement(String name, String type, List alValues, List al // it's not there so add a new list } else { - hmElements.put(name, exType = new ArrayList()); + exType = new ArrayList<>(); + hmElements.put(name, exType); } exType.add(type); @@ -323,7 +320,8 @@ void addElement(String name, String type, List alValues, List al // it's not there so add a new list of lists } else { - hmRestric.put(restricName, exValues = new ArrayList>()); + exValues = new ArrayList<>(); + hmRestric.put(restricName, exValues); } exValues.add(alValues); } @@ -361,7 +359,7 @@ public String getNS(String targetNSPrefix) { */ @JsonIgnore public List getNamespaces() { - List list = new ArrayList(hmNameSpaces.size()); + List list = new ArrayList<>(hmNameSpaces.size()); for (Namespace ns : hmNameSpaces.values()) { list.add(ns); } @@ -382,12 +380,12 @@ public String getPrefix(String theNSUri) { //--------------------------------------------------------------------------- @JsonIgnore public List getSchemaNS() { - return new ArrayList(hmPrefixes.values()); + return new ArrayList<>(hmPrefixes.values()); } @JsonProperty(value = "namespaces") public Map getSchemaNSWithPrefix() { - Map mapNs = new HashMap(); + Map mapNs = new HashMap<>(); List schemaNsList = getSchemaNS(); for (Namespace ns : schemaNsList) { @@ -518,7 +516,7 @@ private void setSchematronPriorities() { this.schemaRepo.saveAll(updated); } - public void setOperationFilters(Map> operationFilters) { + public void setOperationFilters(Map operationFilters) { this.hmOperationFilters = operationFilters; } @@ -527,10 +525,14 @@ public void setOperationFilters(Map> operationFilt * * @return The XPath to select element to filter or null */ - public Pair getOperationFilter(ReservedOperation operation) { + public MetadataSchemaOperationFilter getOperationFilter(ReservedOperation operation) { return hmOperationFilters.get(operation.name()); } + public MetadataSchemaOperationFilter getOperationFilter(String operation) { + return hmOperationFilters.get(operation); + } + @JsonIgnore public SchemaPlugin getSchemaPlugin() { return schemaPlugin; diff --git a/core/src/main/java/org/fao/geonet/kernel/schema/MetadataSchemaOperationFilter.java b/core/src/main/java/org/fao/geonet/kernel/schema/MetadataSchemaOperationFilter.java new file mode 100644 index 00000000000..d296b5fa9ee --- /dev/null +++ b/core/src/main/java/org/fao/geonet/kernel/schema/MetadataSchemaOperationFilter.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2001-2023 Food and Agriculture Organization of the + * United Nations (FAO-UN), United Nations World Food Programme (WFP) + * and United Nations Environment Programme (UNEP) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + * Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2, + * Rome - Italy. email: geonetwork@osgeo.org + */ +package org.fao.geonet.kernel.schema; + +import org.jdom.Element; + +public class MetadataSchemaOperationFilter { + private String xpath; + private String jsonpath; + private String ifNotOperation; + private Element markedElement; + + + public MetadataSchemaOperationFilter(String xpath, String jsonpath, String ifNotOperation) { + this(xpath, jsonpath, ifNotOperation, null); + } + + public MetadataSchemaOperationFilter(String xpath, String jsonpath, String ifNotOperation, Element markedElement) { + this.xpath = xpath; + this.jsonpath = jsonpath; + this.ifNotOperation = ifNotOperation; + this.markedElement = markedElement; + + } + + public String getXpath() { + return xpath; + } + + public String getJsonpath() { + return jsonpath; + } + + public String getIfNotOperation() { + return ifNotOperation; + } + + public Element getMarkedElement() { + return markedElement; + } +} diff --git a/core/src/main/java/org/fao/geonet/kernel/search/EsSearchManager.java b/core/src/main/java/org/fao/geonet/kernel/search/EsSearchManager.java index 746b9d8cc16..ca3f4e35f8a 100644 --- a/core/src/main/java/org/fao/geonet/kernel/search/EsSearchManager.java +++ b/core/src/main/java/org/fao/geonet/kernel/search/EsSearchManager.java @@ -563,9 +563,11 @@ private void checkIndexResponse(BulkResponse bulkItemResponses, .add("orderingInstructionsObject") .add("contact") .add("contactForResource") + .add("contactForProcessing") .add("contactForDistribution") .add("OrgForResource") .add("specificationConformance") + .add("processSteps") .add("measure") .add("resourceProviderOrgForResource") .add("resourceVerticalRange") diff --git a/core/src/main/java/org/fao/geonet/resources/ResourceFilter.java b/core/src/main/java/org/fao/geonet/resources/ResourceFilter.java index 238fbd2a813..e00b9e0c2b6 100644 --- a/core/src/main/java/org/fao/geonet/resources/ResourceFilter.java +++ b/core/src/main/java/org/fao/geonet/resources/ResourceFilter.java @@ -102,7 +102,7 @@ public Instance(ServletRequest request, ServletResponse response) throws IOExcep this.nodeId = applicationContext.getBean(NodeInfo.class).getId(); if (!faviconMap.containsKey(nodeId)) { final byte[] defaultImageBytes = defaultImage.one(); - AddFavIcon(nodeId, resources.loadResource(resourcesDir, servletContext, appPath, "images/logos/" + siteId + ".ico", + addFavIcon(nodeId, resources.loadResource(resourcesDir, servletContext, appPath, "images/logos/" + siteId + ".ico", defaultImageBytes, -1)); } @@ -143,7 +143,7 @@ public void execute() throws IOException { if (filename.equals("images/logos/" + siteId + ".ico")) { favicon = resources.loadResource(resourcesDir, servletContext, appPath, "images/logos/" + siteId + ".ico", favicon.one(), favicon.two()); - AddFavIcon(nodeId, favicon); + addFavIcon(nodeId, favicon); httpServletResponse.setContentLength(favicon.one().length); httpServletResponse.addHeader("Cache-Control", "max-age=" + FIVE_DAYS + ", public"); @@ -167,7 +167,7 @@ public void execute() throws IOException { } } - private synchronized void AddFavIcon(String nodeId, Pair favicon) { + private synchronized void addFavIcon(String nodeId, Pair favicon) { if (faviconMap.containsKey(nodeId)) { faviconMap.replace(nodeId, favicon); } else { diff --git a/core/src/test/java/org/fao/geonet/kernel/XmlSerializerIntegrationTest.java b/core/src/test/java/org/fao/geonet/kernel/XmlSerializerIntegrationTest.java index 453098e09a7..b16e898db5a 100644 --- a/core/src/test/java/org/fao/geonet/kernel/XmlSerializerIntegrationTest.java +++ b/core/src/test/java/org/fao/geonet/kernel/XmlSerializerIntegrationTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001-2016 Food and Agriculture Organization of the + * Copyright (C) 2001-2023 Food and Agriculture Organization of the * United Nations (FAO-UN), United Nations World Food Programme (WFP) * and United Nations Environment Programme (UNEP) * @@ -45,6 +45,7 @@ import org.fao.geonet.domain.Pair; import org.fao.geonet.kernel.datamanager.IMetadataManager; import org.fao.geonet.kernel.schema.MetadataSchema; +import org.fao.geonet.kernel.schema.MetadataSchemaOperationFilter; import org.fao.geonet.utils.Xml; import org.jdom.Element; import org.jdom.Namespace; @@ -101,23 +102,31 @@ public class XmlSerializerIntegrationTest extends AbstractCoreIntegrationTest { public void setSchemaFilters(boolean withHeld, boolean keepMarkedElement) { MetadataSchema mds = _dataManager.getSchema(metadata.getDataInfo().getSchemaId()); - Map> filters = new HashMap>(); + Map filters = new HashMap<>(); if (withHeld) { if (keepMarkedElement) { Element mark = new Element("keepMarkedElement"); mark.setAttribute("nilReason", "withheld", Geonet.Namespaces.GCO); - filters.put("editing", - Pair.read(XPATH_WITHHELD, mark)); + + MetadataSchemaOperationFilter editFilter = new MetadataSchemaOperationFilter(XPATH_WITHHELD, "", "editing", mark); + + filters.put(editFilter.getIfNotOperation(), + editFilter); } else { - filters.put("editing", - Pair.read(XPATH_WITHHELD, null)); + MetadataSchemaOperationFilter editFilter = new MetadataSchemaOperationFilter(XPATH_WITHHELD, "", "editing", null); + + filters.put(editFilter.getIfNotOperation(), + editFilter); } } - filters.put("download", - Pair.read(XPATH_DOWNLOAD, null)); - filters.put("dynamic", - Pair.read(XPATH_DYNAMIC, null)); + MetadataSchemaOperationFilter downloadFilter = new MetadataSchemaOperationFilter(XPATH_DOWNLOAD, "", "download", null); + filters.put(downloadFilter.getIfNotOperation(), + downloadFilter); + + MetadataSchemaOperationFilter dynamicFilter = new MetadataSchemaOperationFilter(XPATH_DYNAMIC, "", "dynamic", null); + filters.put(dynamicFilter.getIfNotOperation(), + dynamicFilter); mds.setOperationFilters(filters); } diff --git a/core/src/test/resources/org/fao/geonet/api/Messages.properties b/core/src/test/resources/org/fao/geonet/api/Messages.properties index a248e81b409..7146a6b8f93 100644 --- a/core/src/test/resources/org/fao/geonet/api/Messages.properties +++ b/core/src/test/resources/org/fao/geonet/api/Messages.properties @@ -141,7 +141,7 @@ username.field.required=Username is required password.field.length=Password size should be between {min} and {max} characters password.field.invalid=Password must contain at least 1 uppercase, 1 lowercase, 1 number and 1 symbol. Symbols include: `~!@#$%^&*()-_=+[]{}\\|;:'",.<>/?'); api.exception.forbidden=Access denied -api.exception.forbidden.description=Access is denied. To access, try again with a user containing more priviledges. +api.exception.forbidden.description=Access is denied. To access, try again with a user containing more privileges. api.exception.resourceNotFound=Resource not found api.exception.resourceNotFound.description=Resource could not be located. api.exception.resourceAlreadyExists=Resource already exists diff --git a/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/SearchController.java b/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/SearchController.java index 99ac7c50b37..3002391bbf6 100644 --- a/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/SearchController.java +++ b/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/SearchController.java @@ -571,10 +571,10 @@ private String convertCswFilterToEsQuery(Element xml, String filterVersion) { * 1) gmd-csw-postprocessing.xsl : Postprocessing xsl applied for CSW service when requesting iso (gmd) output * 2) csw-csw-postprocessing.xsl : Postprocessing xsl applied for CSW service when requesting ogc (csw) output * - * For a custom CSW service named csw-inspire + * For a custom sub-portal named inspire * - * 1) gmd-csw-inspire-postprocessing.xsl : Postprocessing xsl applied for custom CSW csw-inspire service when requesting iso output - * 2) csw-csw-inspire-postprocessing.xsl : Postprocessing xsl applied for custom CSW csw-inspire service when requesting ogc (csw) output + * 1) gmd-inspire-postprocessing.xsl : Postprocessing xsl applied for custom inspire sub-portal when requesting iso output + * 2) csw-inspire-postprocessing.xsl : Postprocessing xsl applied for custom inspire sub-portal when requesting ogc (csw) output * * @param context Service context * @param schemaManager schemamanager diff --git a/docs/changes2.1.x.txt b/docs/changes2.1.x.txt index 84a0c41255c..803c1ec16de 100644 --- a/docs/changes2.1.x.txt +++ b/docs/changes2.1.x.txt @@ -769,7 +769,7 @@ === Changes ================================================================================ -- Search for templates is hidden to simple registerd users (only allow from editors up) +- Search for templates is hidden to simple registered users (only allow from editors up) - Moved login info to the righ diff --git a/docs/changes2.2.x.txt b/docs/changes2.2.x.txt index c37ec5f926b..a8b2cd9c720 100644 --- a/docs/changes2.2.x.txt +++ b/docs/changes2.2.x.txt @@ -1098,7 +1098,7 @@ InterMap: === Changes ================================================================================ -- Search for templates is hidden to simple registerd users (only allow from +- Search for templates is hidden to simple registered users (only allow from editors up) - Moved login info to the righ diff --git a/docs/changes3.8.0-0.txt b/docs/changes3.8.0-0.txt index 832c2d67898..f367694b79f 100644 --- a/docs/changes3.8.0-0.txt +++ b/docs/changes3.8.0-0.txt @@ -292,7 +292,7 @@ - Support gmx:Anchor in extract relations xslt process - refactor - Support gmx:Anchor in extract relations xslt process - fix pdf generation from full view, flying saucer trouble with float: left -- in manage record priviledges help groups sorter to sort +- in manage record privileges help groups sorter to sort - Metadata editor - associated panel doesn't remove error red highlight when filling the url in thumbnail mode #3756 - Fix JS build. - Fixes empty owner select in admin's batch process @@ -439,4 +439,4 @@ - fixes #3207, add warning when layer not in capabilities (for wmts and wfs), with option to open service panel to select alternative layer (adding type to warning translation, so it can be used for multiple types). Also fixes bug with url having &. - Updated slf4j dependencies - Updated avalon-framework dependencies -- Updated json-path dependencies \ No newline at end of file +- Updated json-path dependencies diff --git a/inspire-atom/src/main/java/org/fao/geonet/inspireatom/harvester/InspireAtomHarvester.java b/inspire-atom/src/main/java/org/fao/geonet/inspireatom/harvester/InspireAtomHarvester.java index fae1e933e9a..6379dbf6e84 100644 --- a/inspire-atom/src/main/java/org/fao/geonet/inspireatom/harvester/InspireAtomHarvester.java +++ b/inspire-atom/src/main/java/org/fao/geonet/inspireatom/harvester/InspireAtomHarvester.java @@ -298,7 +298,7 @@ private void processDatasetsMetadataFeeds(final ServiceContext context, try { // Find the metadata UUID using the resource identifier gmd:MD_Identifier/gmd:code - metadataUuid = InspireAtomUtil.retrieveDatasetUuidFromIdentifier(ServiceContext.get(), + metadataUuid = InspireAtomUtil.retrieveDatasetUuidFromIdentifier( gc.getBean(EsSearchManager.class), datasetFeedInfo.identifier); String atomUrl = datasetFeedInfo.feedUrl; @@ -376,7 +376,7 @@ private void processDatasetsMetadataFeedsForService(final ServiceContext context String metadataUuid = ""; try { - metadataUuid = InspireAtomUtil.retrieveDatasetUuidFromIdentifier(context, + metadataUuid = InspireAtomUtil.retrieveDatasetUuidFromIdentifier( gc.getBean(EsSearchManager.class), atomDatasetId); String atomDatasetNs = datasetFeedInfo.namespace; diff --git a/inspire-atom/src/main/java/org/fao/geonet/inspireatom/util/InspireAtomUtil.java b/inspire-atom/src/main/java/org/fao/geonet/inspireatom/util/InspireAtomUtil.java index 7a52e12f87b..6c6980b6f8c 100644 --- a/inspire-atom/src/main/java/org/fao/geonet/inspireatom/util/InspireAtomUtil.java +++ b/inspire-atom/src/main/java/org/fao/geonet/inspireatom/util/InspireAtomUtil.java @@ -1,5 +1,5 @@ //============================================================================= -//=== Copyright (C) 2001-2017 Food and Agriculture Organization of the +//=== Copyright (C) 2001-2023 Food and Agriculture Organization of the //=== United Nations (FAO-UN), United Nations World Food Programme (WFP) //=== and United Nations Environment Programme (UNEP) //=== @@ -24,7 +24,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import jeeves.server.ServiceConfig; import jeeves.server.context.ServiceContext; import org.apache.commons.lang.StringUtils; import org.apache.lucene.search.TotalHits; @@ -71,11 +70,6 @@ public class InspireAtomUtil { **/ private static final String EXTRACT_DATASETS = "extract-datasets.xsl"; - /** - * Xslt process to get if a metadata is a service or a dataset. - **/ - private static final String EXTRACT_MD_TYPE = "extract-type.xsl"; - /** * Xslt process to get the atom feed link from the metadata. **/ @@ -116,6 +110,10 @@ public class InspireAtomUtil { **/ public static final String LOCAL_DOWNLOAD_DATASET_URL_SUFFIX = "atom/download/dataset"; + private InspireAtomUtil() { + + } + /** * Issue an http request to retrieve the remote Atom feed document. * @@ -162,7 +160,7 @@ public static void filterDatasetFeedByCrs(final Element feed, final String crs) throws Exception { - List elementsToRemove = new ArrayList(); + List elementsToRemove = new ArrayList<>(); Iterator it = feed.getChildren().iterator(); @@ -190,7 +188,7 @@ public static void filterDatasetFeedByCrs(final Element feed, public static boolean isServiceMetadata(DataManager dm, String schema, Element md) throws Exception { java.nio.file.Path styleSheet = dm.getSchemaDir(schema).resolve("extract-type.xsl"); - Map paramsM = new HashMap(); + Map paramsM = new HashMap<>(); String mdType = Xml.transform(md, styleSheet, paramsM).getText().trim(); return "service".equalsIgnoreCase(mdType); @@ -235,7 +233,7 @@ public static List extractRelatedDatasetsInfoFromServiceFeed(fi java.nio.file.Path defaultStyleSheet = dataManager.getSchemaDir("iso19139").resolve(EXTRACT_DATASETS_FROM_SERVICE_XSLT); - Map params = new HashMap(); + Map params = new HashMap<>(); Element atomIndexFields = Xml.transform(serviceFeed, defaultStyleSheet, params); List datasetsInformation = new ArrayList<>(); @@ -287,7 +285,7 @@ private static Map processAtomFeedsInternal(DataManager dataMana List iso19139Metadata, String type, String atomProtocol) throws Exception { - Map metadataAtomFeeds = new HashMap(); + Map metadataAtomFeeds = new HashMap<>(); for (AbstractMetadata md : iso19139Metadata) { int id = md.getId(); @@ -386,8 +384,7 @@ public static List searchMetadataByTypeAndProtocol(ServiceCont } - public static String retrieveDatasetUuidFromIdentifier(ServiceContext context, - EsSearchManager searchMan, + public static String retrieveDatasetUuidFromIdentifier(EsSearchManager searchMan, String datasetIdCode) { String jsonQuery = "{" + " \"bool\": {" + @@ -515,34 +512,20 @@ private static Path getAtomFeedXSLStylesheet(final String schema, final DataMana .resolve(TRANSFORM_MD_TO_ATOM_FEED); } - public static Element getDatasetFeed(final ServiceContext context, final String spIdentifier, - final String spNamespace, final Map params, String requestedLanguage) throws Exception { + public static Element getMetadataFeedByResourceIdentifier(final ServiceContext context, final String spIdentifier, + final String spNamespace, final Map params, String requestedLanguage) throws Exception { - ServiceConfig config = new ServiceConfig(); EsSearchManager searchMan = context.getBean(EsSearchManager.class); // Search for the dataset identified by spIdentifier AbstractMetadata datasetMd = null; String jsonQuery = "{" + - " \"bool\": {" + - " \"must\": [" + - " {" + - " \"term\": {" + - " \"resourceType\": {" + - " \"value\": \"%s\"" + - " }" + - " }" + - " }, " + - " {" + - " \"term\": {" + - " \"resourceIdentifier.code\": {" + - " \"value\": \"%s\"" + - " }" + - " }" + - " }" + - " ]" + - " }" + + " \"term\": {" + + " \"resourceIdentifier.code\": {" + + " \"value\": \"%s\"" + + " }" + + " }" + "}"; ObjectMapper objectMapper = new ObjectMapper(); IMetadataUtils repo = context.getBean(IMetadataUtils.class); @@ -563,7 +546,7 @@ public static Element getDatasetFeed(final ServiceContext context, final String // searchResult = searcher.present(context, dsLuceneSearchParams.getRootElement(), config); // } // } - JsonNode esJsonQuery = objectMapper.readTree(String.format(jsonQuery, "dataset", spIdentifier)); + JsonNode esJsonQuery = objectMapper.readTree(String.format(jsonQuery, spIdentifier)); final SearchResponse result = searchMan.query( esJsonQuery, @@ -646,9 +629,9 @@ public static Element getDatasetFeed(final ServiceContext context, final String } public static Element prepareOpenSearchDescriptionEltBeforeTransform(final ServiceContext context, - final Map params, final String fileIdentifier, final String schema, - final Element serviceAtomFeed, final String defaultLanguage, - final DataManager dataManager) throws Exception { + final Map params, final String fileIdentifier, + final Element serviceAtomFeed, final String defaultLanguage + ) throws Exception { List keywords = retrieveKeywordsFromFileIdentifier(context, fileIdentifier); Namespace ns = serviceAtomFeed.getNamespace(); @@ -658,7 +641,7 @@ public static Element prepareOpenSearchDescriptionEltBeforeTransform(final Servi response.addContent(new Element("fileId").setText(fileIdentifier)); response.addContent(new Element("title").setText(serviceAtomFeed.getChildText("title", ns))); response.addContent(new Element("subtitle").setText(serviceAtomFeed.getChildText("subtitle", ns))); - List languages = new ArrayList(); + List languages = new ArrayList<>(); languages.add(XslUtil.twoCharLangCode(defaultLanguage)); Iterator linksChildren = (serviceAtomFeed.getChildren("link", ns)).iterator(); while (linksChildren.hasNext()) { @@ -685,7 +668,7 @@ public static Element prepareOpenSearchDescriptionEltBeforeTransform(final Servi response.addContent(datasetsEl); Namespace inspiredlsns = serviceAtomFeed.getNamespace("inspire_dls"); Iterator datasets = (serviceAtomFeed.getChildren("entry", ns)).iterator(); - List fileTypes = new ArrayList(); + List fileTypes = new ArrayList<>(); while (datasets.hasNext()) { Element dataset = datasets.next(); String datasetIdCode = dataset.getChildText("spatial_dataset_identifier_code", inspiredlsns); @@ -693,7 +676,7 @@ public static Element prepareOpenSearchDescriptionEltBeforeTransform(final Servi Element datasetAtomFeed = null; try { - datasetAtomFeed = InspireAtomUtil.getDatasetFeed(context, datasetIdCode, datasetIdNs, params, XslUtil.twoCharLangCode(defaultLanguage)); + datasetAtomFeed = InspireAtomUtil.getMetadataFeedByResourceIdentifier(context, datasetIdCode, datasetIdNs, params, XslUtil.twoCharLangCode(defaultLanguage)); } catch (Exception e) { Log.error(Geonet.ATOM, "No dataset metadata found with uuid:" + fileIdentifier); @@ -708,7 +691,7 @@ public static Element prepareOpenSearchDescriptionEltBeforeTransform(final Servi datasetEl.addContent(new Element("authorName").setText(authorName)); } } - Map downloadsCountByCrs = new HashMap(); + Map downloadsCountByCrs = new HashMap<>(); Iterator entries = (datasetAtomFeed.getChildren("entry", ns)).iterator(); while (entries.hasNext()) { Element entry = entries.next(); @@ -717,7 +700,7 @@ public static Element prepareOpenSearchDescriptionEltBeforeTransform(final Servi String term = category.getAttributeValue("term"); Integer count = downloadsCountByCrs.get(term); if (count == null) { - count = new Integer(0); + count = 0; } downloadsCountByCrs.put(term, count + 1); } @@ -820,15 +803,13 @@ private static Element buildDatasetInfo(final String identifier, final String na public static List retrieveKeywordsFromFileIdentifier(ServiceContext context, String uuid) { EsSearchManager searchManager = context.getBean(EsSearchManager.class); - List keywordsList = new ArrayList(); + List keywordsList = new ArrayList<>(); try { Map document = searchManager.getDocument(uuid); Object tags = document.get("tag"); if (tags instanceof List) { ArrayList> list = (ArrayList) tags; - list.forEach(tag -> { - keywordsList.add(tag.get("default")); - }); + list.forEach(tag -> keywordsList.add(tag.get("default"))); } } catch (Exception ex) { Log.error(Geonet.ATOM, ex.getMessage(), ex); diff --git a/inspire-atom/src/main/java/org/fao/geonet/services/inspireatom/AtomPredefinedFeed.java b/inspire-atom/src/main/java/org/fao/geonet/services/inspireatom/AtomPredefinedFeed.java index 33908bacbcd..f1e0f517eba 100644 --- a/inspire-atom/src/main/java/org/fao/geonet/services/inspireatom/AtomPredefinedFeed.java +++ b/inspire-atom/src/main/java/org/fao/geonet/services/inspireatom/AtomPredefinedFeed.java @@ -139,7 +139,7 @@ public HttpEntity localDatasetDescribe( if (StringUtils.isNotBlank(searchTerms)) { params.put("searchTerms", searchTerms.toLowerCase()); } - Element feed = InspireAtomUtil.getDatasetFeed(context, spIdentifier, spNamespace, params, language); + Element feed = InspireAtomUtil.getMetadataFeedByResourceIdentifier(context, spIdentifier, spNamespace, params, language); return writeOutResponse(Xml.getString(feed), "application", "atom+xml"); } @@ -247,7 +247,7 @@ public HttpEntity localDatasetDownload( if (StringUtils.isNotBlank(searchTerms)) { params.put("searchTerms", searchTerms.toLowerCase()); } - Element feed = InspireAtomUtil.getDatasetFeed(context, spIdentifier, spNamespace, params, language); + Element feed = InspireAtomUtil.getMetadataFeedByResourceIdentifier(context, spIdentifier, spNamespace, params, language); Map crsCounts = new HashMap();; Namespace ns = Namespace.getNamespace("http://www.w3.org/2005/Atom"); if (crs!=null) { @@ -368,7 +368,9 @@ private Element getOpenSearchDescription(ServiceContext context, final String uu String defaultLanguage = dm.extractDefaultLanguage(schema, md); Map params = getDefaultXSLParams(sm, context, XslUtil.twoCharLangCode(defaultLanguage)); - Element inputDoc = InspireAtomUtil.prepareOpenSearchDescriptionEltBeforeTransform(context, params, uuid, schema, InspireAtomUtil.convertDatasetMdToAtom("iso19139", InspireAtomUtil.prepareServiceFeedEltBeforeTransform(schema, md, dm), dm, params), defaultLanguage, dm); + Element inputDoc = InspireAtomUtil.prepareOpenSearchDescriptionEltBeforeTransform(context, params, uuid, + InspireAtomUtil.convertDatasetMdToAtom("iso19139", + InspireAtomUtil.prepareServiceFeedEltBeforeTransform(schema, md, dm), dm, params), defaultLanguage); return InspireAtomUtil.convertServiceMdToOpenSearchDescription(context, inputDoc, params); } diff --git a/pom.xml b/pom.xml index c25d1a430b5..60cd6217400 100644 --- a/pom.xml +++ b/pom.xml @@ -1562,7 +1562,7 @@ yyyy-MM-dd'T'HH'\:'mm'\:'ssZ ${maven.build.timestamp} .. - 1.7.9 + 1.10.1 true 2.7 2.1.1 diff --git a/schemas/dublin-core/src/main/plugin/dublin-core/formatter/xsl-view/view.xsl b/schemas/dublin-core/src/main/plugin/dublin-core/formatter/xsl-view/view.xsl index f4fdfc7c987..d407b47b5eb 100644 --- a/schemas/dublin-core/src/main/plugin/dublin-core/formatter/xsl-view/view.xsl +++ b/schemas/dublin-core/src/main/plugin/dublin-core/formatter/xsl-view/view.xsl @@ -88,11 +88,18 @@ select="(dct:references|dc:relation)[ normalize-space(.) != '' and matches(., '.*(.gif|.png|.jpeg|.jpg)$', 'i')]"/> + + + {$schemaStrings/overview} + src="{.}" + onerror="{$imgOnError}"/> diff --git a/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/convert/fromJsonOpenDataSoft.xsl b/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/convert/fromJsonOpenDataSoft.xsl index c23687e7c04..a0df66ee81d 100644 --- a/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/convert/fromJsonOpenDataSoft.xsl +++ b/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/convert/fromJsonOpenDataSoft.xsl @@ -482,7 +482,7 @@ + select="metas/records_count|dataset/metas/default/records_count"/> csv @@ -496,7 +496,7 @@ - shapefile + shp @@ -562,10 +562,9 @@ + '/exports/', $format, '?use_labels=true')" /> diff --git a/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/formatter/xsl-view/view.xsl b/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/formatter/xsl-view/view.xsl index 013e1d9f416..abb49d93770 100644 --- a/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/formatter/xsl-view/view.xsl +++ b/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/formatter/xsl-view/view.xsl @@ -249,19 +249,27 @@ - - {$schemaStrings/overview} + - -
- - - -
-
+ +
+ {$schemaStrings/overview} + + +
+ + + +
+
+
diff --git a/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/index-fields/index.xsl b/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/index-fields/index.xsl index eec955fbfe7..1d049dd3f24 100644 --- a/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/index-fields/index.xsl +++ b/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/index-fields/index.xsl @@ -1083,6 +1083,9 @@ "descriptionObject": , + + "nilReason": "", + "applicationProfile": "" } @@ -1101,15 +1104,73 @@
- + + + + + + + { + "descriptionObject": + + ,"date": "" + + + ,"source": [ + + { + "descriptionObject": + } + , + + ] + + + + + ,"processor": [ + + + { + "organisationObject": + + ,"individual":"" + + } + , + + ] + + } + + + + + + + + + normalize-space(mdq:measure/*/mdq:nameOfMeasure/gco:CharacterString) != '' + or normalize-space(mdq:measure/*/mdq:measureDescription/gco:CharacterString) != '' + ]"> @@ -1197,6 +1258,9 @@ "descriptionObject": , + + "nilReason": "", + "function":"", "applicationProfile":"", "group": @@ -1348,6 +1412,7 @@ + { @@ -1363,6 +1428,9 @@ "position":"", "phone":"", "address":"" + + ,"nilReason": "" + ,"identifiers":[ diff --git a/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/index-fields/link-utility.xsl b/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/index-fields/link-utility.xsl index c6695bce12f..a2674cc7121 100644 --- a/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/index-fields/link-utility.xsl +++ b/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/index-fields/link-utility.xsl @@ -151,6 +151,9 @@ + + + diff --git a/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/process/onlinesrc-add.xsl b/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/process/onlinesrc-add.xsl index 61ee24404dd..ccdd293aaa6 100644 --- a/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/process/onlinesrc-add.xsl +++ b/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/process/onlinesrc-add.xsl @@ -268,7 +268,7 @@ - + diff --git a/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/schema-ident.xml b/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/schema-ident.xml index a914403c23e..a012a32fbf8 100644 --- a/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/schema-ident.xml +++ b/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/schema-ident.xml @@ -128,13 +128,14 @@ Ce schéma est également composé des normes : --> - diff --git a/schemas/iso19139/src/main/plugin/iso19139/formatter/xsl-view/view.xsl b/schemas/iso19139/src/main/plugin/iso19139/formatter/xsl-view/view.xsl index 9653a658a66..3f13daa000f 100644 --- a/schemas/iso19139/src/main/plugin/iso19139/formatter/xsl-view/view.xsl +++ b/schemas/iso19139/src/main/plugin/iso19139/formatter/xsl-view/view.xsl @@ -223,20 +223,27 @@ - - {$schemaStrings/overview} - - -
- - - -
-
+ + +
+ {$schemaStrings/overview} + + +
+ + + +
+
+
diff --git a/schemas/iso19139/src/main/plugin/iso19139/index-fields/index.xsl b/schemas/iso19139/src/main/plugin/iso19139/index-fields/index.xsl index bbc4c321f47..0f97c538a5e 100644 --- a/schemas/iso19139/src/main/plugin/iso19139/index-fields/index.xsl +++ b/schemas/iso19139/src/main/plugin/iso19139/index-fields/index.xsl @@ -966,13 +966,14 @@ gmd:statement, $allLanguages)"/> - + + select="(gmd:result/gmd:DQ_QuantitativeResult/gmd:valueUnit//(gml:identifier|gml320:identifier))[1]"/> { @@ -995,6 +996,60 @@ + + + + { + "descriptionObject": + + ,"date": "" + + + ,"source": [ + + { + "descriptionObject": + } + , + + ] + + + + + + ,"processor": [ + + { + "organisationObject": + + ,"individual":"" + + } + , + + ] + + } + + + + + + + + +
@@ -1060,6 +1115,9 @@ "descriptionObject": , + + "nilReason": "", + "function":"", "applicationProfile":"", "group": @@ -1207,6 +1265,7 @@ + { @@ -1221,6 +1280,9 @@ "position":"", "phone":"", "address":"" + + ,"nilReason": "" + } diff --git a/schemas/iso19139/src/main/plugin/iso19139/process/onlinesrc-add.xsl b/schemas/iso19139/src/main/plugin/iso19139/process/onlinesrc-add.xsl index dafdcd1590b..6947108375b 100644 --- a/schemas/iso19139/src/main/plugin/iso19139/process/onlinesrc-add.xsl +++ b/schemas/iso19139/src/main/plugin/iso19139/process/onlinesrc-add.xsl @@ -518,7 +518,7 @@ Insert is made in first transferOptions found. - + diff --git a/schemas/iso19139/src/main/plugin/iso19139/schema-ident.xml b/schemas/iso19139/src/main/plugin/iso19139/schema-ident.xml index e1293de0efe..b3bd3bd0bf7 100644 --- a/schemas/iso19139/src/main/plugin/iso19139/schema-ident.xml +++ b/schemas/iso19139/src/main/plugin/iso19139/schema-ident.xml @@ -83,6 +83,7 @@ of data.]]> diff --git a/services/pom.xml b/services/pom.xml index 69cbcbd1196..63a6a9d227a 100644 --- a/services/pom.xml +++ b/services/pom.xml @@ -136,7 +136,6 @@ com.jayway.jsonpath json-path 2.4.0 - test com.jayway.jsonpath diff --git a/services/src/main/java/org/fao/geonet/api/es/EsHTTPProxy.java b/services/src/main/java/org/fao/geonet/api/es/EsHTTPProxy.java index 99b221c8342..5c6b9a156bf 100644 --- a/services/src/main/java/org/fao/geonet/api/es/EsHTTPProxy.java +++ b/services/src/main/java/org/fao/geonet/api/es/EsHTTPProxy.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001-2016 Food and Agriculture Organization of the + * Copyright (C) 2001-2023 Food and Agriculture Organization of the * United Nations (FAO-UN), United Nations World Food Programme (WFP) * and United Nations Environment Programme (UNEP) * @@ -26,12 +26,15 @@ import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.MappingIterator; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.collect.Sets; +import com.jayway.jsonpath.DocumentContext; +import com.jayway.jsonpath.JsonPath; import io.swagger.v3.oas.annotations.Hidden; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.parameters.RequestBody; @@ -43,18 +46,19 @@ import org.fao.geonet.Constants; import org.fao.geonet.NodeInfo; import org.fao.geonet.api.ApiUtils; -import org.fao.geonet.api.records.MetadataApi; import org.fao.geonet.api.records.MetadataUtils; import org.fao.geonet.api.records.model.related.AssociatedRecord; import org.fao.geonet.api.records.model.related.RelatedItemType; -import org.fao.geonet.api.records.model.related.RelatedResponse; import org.fao.geonet.constants.Edit; import org.fao.geonet.constants.Geonet; import org.fao.geonet.domain.*; import org.fao.geonet.index.es.EsRestClient; import org.fao.geonet.kernel.AccessManager; +import org.fao.geonet.kernel.SchemaManager; import org.fao.geonet.kernel.SelectionManager; import org.fao.geonet.kernel.datamanager.IMetadataUtils; +import org.fao.geonet.kernel.schema.MetadataSchema; +import org.fao.geonet.kernel.schema.MetadataSchemaOperationFilter; import org.fao.geonet.kernel.search.EsFilterBuilder; import org.fao.geonet.repository.SourceRepository; import org.slf4j.Logger; @@ -77,7 +81,6 @@ import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.*; -import java.util.stream.Collectors; import java.util.zip.DeflaterInputStream; import java.util.zip.DeflaterOutputStream; import java.util.zip.GZIPInputStream; @@ -129,6 +132,9 @@ public class EsHTTPProxy { @Autowired private EsRestClient client; + @Autowired + private SchemaManager schemaManager; + public EsHTTPProxy() { } @@ -171,7 +177,7 @@ private static void addRelatedTypes(ObjectNode doc, LOGGER.warn("Failed to load related types for {}. Error is: {}", getSourceString(doc, Geonet.IndexFieldNames.UUID), e.getMessage() - ); + ); } doc.putPOJO("related", related); } @@ -274,20 +280,20 @@ private static boolean hasOperation(ObjectNode doc, ReservedGroup group, Reserve @ResponseBody public void search( @RequestParam(defaultValue = SelectionManager.SELECTION_METADATA) - String bucket, + String bucket, @Parameter(description = "Type of related resource. If none, no associated resource returned.", required = false ) @RequestParam(name = "relatedType", defaultValue = "") - RelatedItemType[] relatedTypes, + RelatedItemType[] relatedTypes, @Parameter(hidden = true) - HttpSession httpSession, + HttpSession httpSession, @Parameter(hidden = true) - HttpServletRequest request, + HttpServletRequest request, @Parameter(hidden = true) - HttpServletResponse response, + HttpServletResponse response, @RequestBody(description = "JSON request based on Elasticsearch API.") - String body, + String body, @Parameter(hidden = true) HttpEntity httpEntity) throws Exception { ServiceContext context = ApiUtils.createServiceContext(request); @@ -306,20 +312,20 @@ public void search( @ResponseBody public void msearch( @RequestParam(defaultValue = SelectionManager.SELECTION_METADATA) - String bucket, + String bucket, @Parameter(description = "Type of related resource. If none, no associated resource returned.", required = false ) @RequestParam(name = "relatedType", defaultValue = "") - RelatedItemType[] relatedTypes, + RelatedItemType[] relatedTypes, @Parameter(hidden = true) - HttpSession httpSession, + HttpSession httpSession, @Parameter(hidden = true) - HttpServletRequest request, + HttpServletRequest request, @Parameter(hidden = true) - HttpServletResponse response, + HttpServletResponse response, @RequestBody(description = "JSON request based on Elasticsearch API.") - String body, + String body, @Parameter(hidden = true) HttpEntity httpEntity) throws Exception { ServiceContext context = ApiUtils.createServiceContext(request); @@ -336,25 +342,25 @@ public void msearch( @RequestMapping(value = "/search/records/{endPoint}", method = { RequestMethod.POST, RequestMethod.GET - }) + }) @ResponseStatus(value = HttpStatus.OK) @PreAuthorize("hasAuthority('Administrator')") @ResponseBody public void call( @RequestParam(defaultValue = SelectionManager.SELECTION_METADATA) - String bucket, + String bucket, @Parameter(description = "'_search' for search service.") @PathVariable String endPoint, @Parameter(hidden = true) - HttpSession httpSession, + HttpSession httpSession, @Parameter(hidden = true) - HttpServletRequest request, + HttpServletRequest request, @Parameter(hidden = true) - HttpServletResponse response, + HttpServletResponse response, @RequestBody(description = "JSON request based on Elasticsearch API.") - String body, + String body, @Parameter(hidden = true) - HttpEntity httpEntity) throws Exception { + HttpEntity httpEntity) throws Exception { ServiceContext context = ApiUtils.createServiceContext(request); call(context, httpSession, request, response, endPoint, httpEntity.getBody(), bucket, null); @@ -419,6 +425,7 @@ public void call(ServiceContext context, HttpSession httpSession, HttpServletReq */ private void addRequiredField(ArrayNode source) { source.add("op*"); + source.add(Geonet.IndexFieldNames.SCHEMA); source.add(Geonet.IndexFieldNames.GROUP_OWNER); source.add(Geonet.IndexFieldNames.OWNER); source.add(Geonet.IndexFieldNames.ID); @@ -430,8 +437,8 @@ private void addFilterToQuery(ServiceContext context, // Build filter node String esFilter = buildQueryFilter(context, - "", - esQuery.toString().contains("\"draft\":")); + "", + esQuery.toString().contains("\"draft\":")); JsonNode nodeFilter = objectMapper.readTree(esFilter); JsonNode queryNode = esQuery.get("query"); @@ -639,13 +646,20 @@ private void processResponse(ServiceContext context, HttpSession httpSession, addRelatedTypes(doc, relatedTypes, context); } - // Remove fields with privileges info if (doc.has("_source")) { ObjectNode sourceNode = (ObjectNode) doc.get("_source"); + String metadataSchema = doc.get("_source").get("documentStandard").asText(); + MetadataSchema mds = schemaManager.getSchema(metadataSchema); + + // Apply metadata schema filters to remove non-allowed fields + processMetadataSchemaFilters(context, mds, doc); + + // Remove fields with privileges info for (ReservedOperation o : ReservedOperation.values()) { sourceNode.remove("op" + o.getId()); } + } }); } else { @@ -778,4 +792,96 @@ protected boolean isContentTypeValid(final String contentType) { return false; } + + /** + * Process the metadata schema filters to filter out from the ElasticSearch response + * the elements defined in the metadata schema filters. + * + * It uses a jsonpath to filter the elements, typically is configured with the following jsonpath, to + * filter the ES object elements with an attribute nilReason = 'withheld'. + * + * $.*[?(@.nilReason == 'withheld')] + * + * The metadata index process, has to define this attribute. Any element that requires to be filtered, should be + * defined as an object in ElasticSearch. + * + * Example for contacts: + * + * + * ... + * + * + * + * + * { + * ... + * "address":"" + * + * ,"nilReason": "withheld" + * + * + * @param mds + * @param doc + * @throws JsonProcessingException + */ + private void processMetadataSchemaFilters(ServiceContext context, MetadataSchema mds, ObjectNode doc) throws JsonProcessingException { + if (!doc.has("_source")) { + return; + } + + ObjectMapper mapper = new ObjectMapper(); + ObjectNode sourceNode = (ObjectNode) doc.get("_source"); + + MetadataSchemaOperationFilter authenticatedFilter = mds.getOperationFilter("authenticated"); + + List jsonpathFilters = new ArrayList<>(); + + if (authenticatedFilter != null && !context.getUserSession().isAuthenticated()) { + jsonpathFilters.add(authenticatedFilter.getJsonpath()); + } + + MetadataSchemaOperationFilter editFilter = mds.getOperationFilter(ReservedOperation.editing); + + if (editFilter != null) { + boolean canEdit = doc.get("edit").asBoolean(); + + if (!canEdit) { + jsonpathFilters.add(editFilter.getJsonpath()); + } + } + + MetadataSchemaOperationFilter downloadFilter = mds.getOperationFilter(ReservedOperation.download); + if (downloadFilter != null) { + boolean canDownload = doc.get("download").asBoolean(); + + if (!canDownload) { + jsonpathFilters.add(downloadFilter.getJsonpath()); + } + } + + MetadataSchemaOperationFilter dynamicFilter = mds.getOperationFilter(ReservedOperation.dynamic); + if (dynamicFilter != null) { + boolean canDynamic = doc.get("dynamic").asBoolean(); + + if (!canDynamic) { + jsonpathFilters.add(dynamicFilter.getJsonpath()); + } + } + + JsonNode actualObj = filterResponseElements(mapper, sourceNode, jsonpathFilters); + if (actualObj != null) { + doc.set("_source", actualObj); + } + } + private JsonNode filterResponseElements(ObjectMapper mapper, ObjectNode sourceNode, List jsonPathFilters) throws JsonProcessingException { + DocumentContext jsonContext = JsonPath.parse(sourceNode.toPrettyString()); + + for(String jsonPath : jsonPathFilters) { + if (StringUtils.isNotBlank(jsonPath)) { + jsonContext = jsonContext.delete(jsonPath); + } + } + + return mapper.readTree(jsonContext.jsonString()); + } } diff --git a/services/src/main/java/org/fao/geonet/api/site/SitemapApi.java b/services/src/main/java/org/fao/geonet/api/site/SitemapApi.java index 0f05217a52a..6fe6895459f 100644 --- a/services/src/main/java/org/fao/geonet/api/site/SitemapApi.java +++ b/services/src/main/java/org/fao/geonet/api/site/SitemapApi.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001-2016 Food and Agriculture Organization of the + * Copyright (C) 2001-2023 Food and Agriculture Organization of the * United Nations (FAO-UN), United Nations World Food Programme (WFP) * and United Nations Environment Programme (UNEP) * @@ -28,7 +28,6 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import org.fao.geonet.NodeInfo; -import org.fao.geonet.api.API; import org.fao.geonet.api.ApiParams; import org.fao.geonet.domain.*; import org.fao.geonet.exceptions.SitemapDocumentNotFoundEx; @@ -44,22 +43,23 @@ import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.jpa.domain.Specification; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseStatus; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; import java.nio.file.Path; import java.util.List; import static org.fao.geonet.api.ApiParams.API_CLASS_CATALOG_TAG; -/** - * - */ - @RequestMapping(value = { "/{portal}/api" }) @@ -94,18 +94,21 @@ public class SitemapApi { description = "") @RequestMapping( path = "/robots.txt", - produces = MediaType.TEXT_PLAIN_VALUE, method = RequestMethod.GET) @ResponseStatus(HttpStatus.OK) @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "robots.txt file for SEO.") }) - @ResponseBody - public String getRobotsText() throws Exception { - StringBuffer response = new StringBuffer(); - response.append("sitemap: ").append(settingManager.getNodeURL()).append("api/sitemap").append("\n"); - response.append("sitemap: ").append(settingManager.getNodeURL()).append("api/sitemap?format=rdf"); - return response.toString(); + public void getRobotsText(HttpServletRequest request, HttpServletResponse response) throws IOException { + StringBuilder content = new StringBuilder(256); + String contextPath = request.getContextPath(); + content.append("User-agent: *\n"); + content.append("Disallow: ").append(contextPath).append("/catalog/\n"); + content.append("Disallow: ").append(contextPath).append("/static/\n"); + content.append("Sitemap: ").append(settingManager.getNodeURL()).append("api/sitemap\n"); + content.append("Sitemap: ").append(settingManager.getNodeURL()).append("api/sitemap?format=rdf"); + response.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE); + response.getWriter().append(content); } @io.swagger.v3.oas.annotations.Operation( @@ -113,14 +116,12 @@ public String getRobotsText() throws Exception { description = "") @RequestMapping( path = "/sitemap", - produces = MediaType.APPLICATION_XML_VALUE, method = RequestMethod.GET) @ResponseStatus(HttpStatus.OK) @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Site map.") }) - public @ResponseBody - ResponseEntity getSitemap( + public void getSitemap( @Parameter( description = "Format (xml or html).", required = false @@ -129,7 +130,7 @@ ResponseEntity getSitemap( required = false, defaultValue = FORMAT_HTML ) - String format, + String format, @Parameter( description = "page.", required = false @@ -138,20 +139,20 @@ ResponseEntity getSitemap( required = false, defaultValue = "0" ) - Integer doc, + Integer doc, @Parameter(hidden = true) - HttpServletRequest request + HttpServletResponse response ) throws Exception { if (!(format.equalsIgnoreCase(FORMAT_HTML) || format.equalsIgnoreCase(FORMAT_XML))) { format = FORMAT_HTML; } - Integer allgroup = 1; + int allGroup = 1; Specification spec = Specification.where( OperationAllowedSpecs.hasOperation(ReservedOperation.view)); - spec = spec.and(OperationAllowedSpecs.hasGroupId(allgroup)); + spec = spec.and(OperationAllowedSpecs.hasGroupId(allGroup)); final List list = operationAllowedRepository.findAllIds( spec, @@ -161,10 +162,10 @@ ResponseEntity getSitemap( Sort.Direction.DESC, Metadata_.dataInfo.getName() + "." + MetadataDataInfo_.changeDate.getName()); - long metadatataCount = metadataRepository.count((Specification) MetadataSpecs.hasMetadataIdIn(list)); - long pages = (long) Math.ceil((double) metadatataCount / MAX_ITEMS_PER_PAGE); + long metadataCount = metadataRepository.count((Specification) MetadataSpecs.hasMetadataIdIn(list)); + long pages = (long) Math.ceil((double) metadataCount / MAX_ITEMS_PER_PAGE); - Element result = null; + Element result; if (doc > 0) { // Requesting a sitemap specific document @@ -180,7 +181,7 @@ ResponseEntity getSitemap( } } else { // Request the sitemap (no specific document) - if (metadatataCount <= MAX_ITEMS_PER_PAGE) { + if (metadataCount <= MAX_ITEMS_PER_PAGE) { // Request the full sitemap result = metadataRepository.findUuidsAndChangeDatesAndSchemaId(list); @@ -208,7 +209,7 @@ ResponseEntity getSitemap( root.addContent(requestElt); root.addContent(result); - Element sitemap = Xml.transform(root, xslt); - return new ResponseEntity<>(sitemap, HttpStatus.OK); + response.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE); + Xml.transform(root, xslt, response.getOutputStream()); } } diff --git a/software_development/ECLIPSE.md b/software_development/ECLIPSE.md index 611bba94f74..d82032dbf4d 100644 --- a/software_development/ECLIPSE.md +++ b/software_development/ECLIPSE.md @@ -14,7 +14,7 @@ In order to import the source code, follow instructions below: 2. In new dialog Select **Maven** > **Existing Maven Projects** 3. Press *Next* - ![Import existing projects into Eclipse](../eclipse-import-existing-projects.png) + ![Import existing projects into Eclipse](eclipse-import-existing-projects.png) 4. In **Select root directory** field enter the location of your source code: diff --git a/eclipse-import-existing-projects.png b/software_development/eclipse-import-existing-projects.png similarity index 100% rename from eclipse-import-existing-projects.png rename to software_development/eclipse-import-existing-projects.png diff --git a/web-ui/src/main/resources/catalog/components/admin/harvester/HarvesterDirective.js b/web-ui/src/main/resources/catalog/components/admin/harvester/HarvesterDirective.js index 280dd130619..223dcb65645 100644 --- a/web-ui/src/main/resources/catalog/components/admin/harvester/HarvesterDirective.js +++ b/web-ui/src/main/resources/catalog/components/admin/harvester/HarvesterDirective.js @@ -355,12 +355,12 @@ matches = []; // regex used to determine if a string contains the substring `q` - substrRegex = new RegExp(q, "i"); + substringRegex = new RegExp(q, "i"); // iterate through the pool of strings and for any string that // contains the substring `q`, add it to the `matches` array $.each(strs, function (i, str) { - if (substrRegex.test(str)) { + if (substringRegex.test(str)) { matches.push(str); } }); diff --git a/web-ui/src/main/resources/catalog/components/catalog/CatalogService.js b/web-ui/src/main/resources/catalog/components/catalog/CatalogService.js index e5fe5ed5c55..496b676e9a4 100644 --- a/web-ui/src/main/resources/catalog/components/catalog/CatalogService.js +++ b/web-ui/src/main/resources/catalog/components/catalog/CatalogService.js @@ -369,7 +369,6 @@ lang: "lang?_content_type=json&", removeThumbnail: "md.thumbnail.remove?_content_type=json&", removeOnlinesrc: "resource.del.and.detach", // TODO: CHANGE - suggest: "suggest", selectionLayers: "selection.layers", featureindexproxy: "../../index/features", @@ -710,12 +709,14 @@ var mlObjs = angular.isArray(multilingualObjects) ? multilingualObjects : [multilingualObjects]; - mlObjs.forEach(function (mlObj) { - mlObj.default = - mlObj["lang" + gnLangs.current] || - mlObj.default || - mlObj["lang" + this.mainLanguage]; - }); + mlObjs.forEach( + function (mlObj) { + mlObj.default = + mlObj["lang" + gnLangs.current] || + mlObj.default || + mlObj["lang" + this.mainLanguage]; + }.bind(this) + ); }, translateCodelists: function (index) { var codelists = angular.isArray(index) ? index : [index]; @@ -734,7 +735,7 @@ for (var fieldName in index) { var field = index[fieldName]; if (fieldName.endsWith("Object")) { - this.translateMultilingualObjects(field); + this.translateMultilingualObjects.call(this, field); index[fieldName.replace(/Object$/g, "")] = angular.isArray(field) ? field.map(function (mlObj) { return mlObj.default; @@ -745,16 +746,16 @@ } else if (fieldName === "allKeywords") { Object.keys(field).forEach( function (th) { - this.translateMultilingualObjects(field[th].keywords); + this.translateMultilingualObjects.call(this, field[th].keywords); }.bind(this) ); } else if ( fieldName.match(/th_.*$/) !== null && fieldName.match(/.*(_tree|Number)$/) === null ) { - this.translateMultilingualObjects(field); + this.translateMultilingualObjects.call(this, field); } else if (typeof field === "object") { - this.translateMultingualFields(field); + this.translateMultingualFields.call(this, field); } } }, @@ -786,7 +787,7 @@ return this.valid > -1; }, isOwned: function () { - return this.owner === "true"; + return this.owner === true; }, getOwnerId: function () { return this.ownerId; diff --git a/web-ui/src/main/resources/catalog/components/common/map/mapService.js b/web-ui/src/main/resources/catalog/components/common/map/mapService.js index 1b7ec0cfc62..9caacc5a25b 100644 --- a/web-ui/src/main/resources/catalog/components/common/map/mapService.js +++ b/web-ui/src/main/resources/catalog/components/common/map/mapService.js @@ -926,7 +926,8 @@ imageTile.getImage().src = imageUrl; }); } else { - console.warn("Error loading image for: " + src, r); + // Other HEAD errors, default to OL image src set + imageTile.getImage().src = src; } } ); diff --git a/web-ui/src/main/resources/catalog/components/common/map/print/PrintMapDirective.js b/web-ui/src/main/resources/catalog/components/common/map/print/PrintMapDirective.js index 1c9deec2324..6ea1b5d2a93 100644 --- a/web-ui/src/main/resources/catalog/components/common/map/print/PrintMapDirective.js +++ b/web-ui/src/main/resources/catalog/components/common/map/print/PrintMapDirective.js @@ -224,7 +224,7 @@ var encLegends = []; var attributions = []; var layers = $scope.map.getLayers(); - pdfLegendsToDownload = []; + var pdfLegendsToDownload = []; var sortedZindexLayers = layers.getArray().sort(function (a, b) { return a.getZIndex() > b.getZIndex(); diff --git a/web-ui/src/main/resources/catalog/components/common/ows/OWSService.js b/web-ui/src/main/resources/catalog/components/common/ows/OWSService.js index d70aad5ccae..e9be099ea18 100644 --- a/web-ui/src/main/resources/catalog/components/common/ows/OWSService.js +++ b/web-ui/src/main/resources/catalog/components/common/ows/OWSService.js @@ -357,7 +357,7 @@ getWFSCapabilities: function (url, version) { var defer = $q.defer(); if (url) { - defaultVersion = "1.1.0"; + var defaultVersion = "1.1.0"; version = version || defaultVersion; url = mergeDefaultParams(url, { request: "GetCapabilities", @@ -396,7 +396,7 @@ getWCSCapabilities: function (url, version) { var defer = $q.defer(); if (url) { - defaultVersion = "1.1.0"; + var defaultVersion = "1.1.0"; version = version || defaultVersion; url = mergeDefaultParams(url, { REQUEST: "GetCapabilities", @@ -474,13 +474,13 @@ var layers = capObj.layers || capObj.Layer; // Layer name may be a list of comma separated layers - layerList = layerName.split(","); + var layerList = layerName.split(","); var needles = new Array(layerList.length); layersLoop: for (var j = 0; j < layerList.length; j++) { var name = layerList[j]; //non namespaced lowercase name - nameNoNamespace = this.getNameWithoutNamespace(name).toLowerCase(); + var nameNoNamespace = this.getNameWithoutNamespace(name).toLowerCase(); capabilityLayers: for (var i = 0; i < layers.length; i++) { //Add Info for Requests: diff --git a/web-ui/src/main/resources/catalog/components/common/scrollspy/ScrollSpyDirective.js b/web-ui/src/main/resources/catalog/components/common/scrollspy/ScrollSpyDirective.js index 9a40e0dfef6..3d356896f1c 100644 --- a/web-ui/src/main/resources/catalog/components/common/scrollspy/ScrollSpyDirective.js +++ b/web-ui/src/main/resources/catalog/components/common/scrollspy/ScrollSpyDirective.js @@ -140,7 +140,7 @@ scope.spyElems.pop(); } - rootElement = $("#" + scope.id); + var rootElement = $("#" + scope.id); // Get the number of fieldset above the current element // to compute depth later. diff --git a/web-ui/src/main/resources/catalog/components/edit/FieldsDirective.js b/web-ui/src/main/resources/catalog/components/edit/FieldsDirective.js index deb8646dd5d..89bd0973dcf 100644 --- a/web-ui/src/main/resources/catalog/components/edit/FieldsDirective.js +++ b/web-ui/src/main/resources/catalog/components/edit/FieldsDirective.js @@ -368,7 +368,7 @@ tooltipsMode === "onhover" ? "hover" : isField ? "focus" : "click" }); - if (tooltipsMode === "" || tooltipsMode === "onfocus") { + if (tooltipsMode !== "onhover") { // Remove first the event, to avoid ending with multiple events // every time a new popup is displayed. $(document) diff --git a/web-ui/src/main/resources/catalog/components/edit/directoryentryselector/DirectoryEntrySelector.js b/web-ui/src/main/resources/catalog/components/edit/directoryentryselector/DirectoryEntrySelector.js index 30e2afc2759..a872c3d2a8c 100644 --- a/web-ui/src/main/resources/catalog/components/edit/directoryentryselector/DirectoryEntrySelector.js +++ b/web-ui/src/main/resources/catalog/components/edit/directoryentryselector/DirectoryEntrySelector.js @@ -426,7 +426,7 @@ // $(id).tagsinput('add', keyword); // }); - getRecordsAutocompleter = function (config) { + var getRecordsAutocompleter = function (config) { var recordsAutocompleter = new Bloodhound({ datumTokenizer: Bloodhound.tokenizers.whitespace("title"), queryTokenizer: Bloodhound.tokenizers.whitespace, @@ -469,7 +469,7 @@ recordsAutocompleter.initialize(); return recordsAutocompleter; }; - autocompleter = getRecordsAutocompleter({ max: 10 }); + var autocompleter = getRecordsAutocompleter({ max: 10 }); // Init typeahead field @@ -558,7 +558,7 @@ urls.forEach(function (url, i) { // local://srv/api/registries/entries/af8a36bb-ecea-4880-bf83-26b691e7570e? // transformation=contact-from-iso19139-to-foaf-agent&lang=eng,fre&schema=dcat2 - uuid = url.replace(/.*entries\/(.*)\?.*/, "$1"); + var uuid = url.replace(/.*entries\/(.*)\?.*/, "$1"); $http .post( "../api/search/records/_search", diff --git a/web-ui/src/main/resources/catalog/components/edit/editorhelper/EditorHelperDirective.js b/web-ui/src/main/resources/catalog/components/edit/editorhelper/EditorHelperDirective.js index 5b0f2745a1d..30c9d43ff94 100644 --- a/web-ui/src/main/resources/catalog/components/edit/editorhelper/EditorHelperDirective.js +++ b/web-ui/src/main/resources/catalog/components/edit/editorhelper/EditorHelperDirective.js @@ -137,6 +137,15 @@ // Load the config from the textarea containing the helpers scope.config = angular.fromJson($("#" + scope.ref + "_config")[0].value); + if (scope.mode == "") { + scope.config.defaultSelected = { + "@value": "", + "#text": $translate.instant("recommendedValues"), + disabled: true + }; + } else { + scope.config.defaultSelected = {}; + } // If only one option, convert to an array if (!$.isArray(scope.config.option)) { @@ -146,6 +155,11 @@ scope.config.option = scope.config; } + if (scope.mode == "") { + // Add on top the recommended values option + scope.config.option.unshift(scope.config.defaultSelected); + } + // Add record formats if any scope.isProtocol = attrs.tooltip.indexOf && attrs.tooltip.indexOf("protocol|") !== -1; @@ -180,7 +194,8 @@ } // Set the initial value - scope.config.selected = {}; + scope.config.selected = scope.config.defaultSelected; + scope.config.value = field.type === "number" ? parseFloat(field.value) : field.value; scope.config.layout = diff --git a/web-ui/src/main/resources/catalog/components/edit/editorhelper/partials/editorhelper.html b/web-ui/src/main/resources/catalog/components/edit/editorhelper/partials/editorhelper.html index dfddebdb478..c5c5a43561b 100644 --- a/web-ui/src/main/resources/catalog/components/edit/editorhelper/partials/editorhelper.html +++ b/web-ui/src/main/resources/catalog/components/edit/editorhelper/partials/editorhelper.html @@ -17,7 +17,7 @@ type="radio" data-ng-click="select(o)" name="ignore_{{ref}}" - data-ng-checked="o['@value'] === config.value" + data-ng-checked="o['@value'] == config.value" /> {{o['#text']}} @@ -70,9 +70,7 @@ class="form-control" data-ng-model="config.selected" data-ng-options="o as o['#text'] disable when o.disabled for o in config.option" - > - - + > diff --git a/web-ui/src/main/resources/catalog/components/edit/onlinesrc/OnlineSrcDirective.js b/web-ui/src/main/resources/catalog/components/edit/onlinesrc/OnlineSrcDirective.js index 6817d94a0aa..7ced917fdfc 100644 --- a/web-ui/src/main/resources/catalog/components/edit/onlinesrc/OnlineSrcDirective.js +++ b/web-ui/src/main/resources/catalog/components/edit/onlinesrc/OnlineSrcDirective.js @@ -724,7 +724,7 @@ scope.generateThumbnail = function () { //Added mandatory custom params here to avoid //changing other printing services - jsonSpec = angular.extend(scope.jsonSpec, { + var jsonSpec = angular.extend(scope.jsonSpec, { hasNoTitle: true }); @@ -867,8 +867,6 @@ } else { return DEFAULT_CONFIG; } - - return DEFAULT_CONFIG; } gnOnlinesrc.register("onlinesrc", function (linkToEditOrType) { @@ -2124,7 +2122,7 @@ * Return the index or -1 if not present. */ var findObj = function (md) { - for (i = 0; i < scope.selection.length; ++i) { + for (var i = 0; i < scope.selection.length; ++i) { if (scope.selection[i].md === md) { return i; } @@ -2172,7 +2170,7 @@ */ scope.linkToResource = function () { var uuids = []; - for (i = 0; i < scope.selection.length; ++i) { + for (var i = 0; i < scope.selection.length; ++i) { var obj = scope.selection[i], parameter = obj.md.uuid + diff --git a/web-ui/src/main/resources/catalog/components/edit/onlinesrc/partials/addOnlinesrc.html b/web-ui/src/main/resources/catalog/components/edit/onlinesrc/partials/addOnlinesrc.html index 7b84fd16691..405682e079b 100644 --- a/web-ui/src/main/resources/catalog/components/edit/onlinesrc/partials/addOnlinesrc.html +++ b/web-ui/src/main/resources/catalog/components/edit/onlinesrc/partials/addOnlinesrc.html @@ -395,7 +395,8 @@ /> -
+ + + measureType + measureName + + {{(columnVisibility['name'] ? 'measureDescription' : 'measureName') | translate}} + + measureValue + + + + + {{m.type | translate}} + {{m.name}} + {{m.description}} + + {{m.value}} {{m.unit}} + + + + diff --git a/web-ui/src/main/resources/catalog/components/search/searchfiltertag/SearchFilterTagsDirective.js b/web-ui/src/main/resources/catalog/components/search/searchfiltertag/SearchFilterTagsDirective.js index 7f4fcbd8d35..24fcd9e925f 100644 --- a/web-ui/src/main/resources/catalog/components/search/searchfiltertag/SearchFilterTagsDirective.js +++ b/web-ui/src/main/resources/catalog/components/search/searchfiltertag/SearchFilterTagsDirective.js @@ -269,7 +269,7 @@ }; scope.removeFilter = function (filter) { - removeFacetElement = []; + var removeFacetElement = []; removeFacetElement.push(filter.key); var keys = Object.keys(filter.value); if (angular.isObject(filter.value) && keys[0] != 0) { diff --git a/web-ui/src/main/resources/catalog/components/search/searchmanager/SearchFormDirective.js b/web-ui/src/main/resources/catalog/components/search/searchmanager/SearchFormDirective.js index 79a61720f57..8c34410690f 100644 --- a/web-ui/src/main/resources/catalog/components/search/searchmanager/SearchFormDirective.js +++ b/web-ui/src/main/resources/catalog/components/search/searchmanager/SearchFormDirective.js @@ -122,7 +122,7 @@ }; var cleanSearchParams = function (params) { - for (v in params) { + for (var v in params) { if (v !== "sortOrder" && params[v] == "") { delete params[v]; } diff --git a/web-ui/src/main/resources/catalog/components/thesaurus/ThesaurusDirective.js b/web-ui/src/main/resources/catalog/components/thesaurus/ThesaurusDirective.js index 11330b04ca6..e9f912db0c1 100644 --- a/web-ui/src/main/resources/catalog/components/thesaurus/ThesaurusDirective.js +++ b/web-ui/src/main/resources/catalog/components/thesaurus/ThesaurusDirective.js @@ -806,6 +806,8 @@ // By default, such an attribute is identified in the form by // the parent element id + '_' + attribute name if (angular.isDefined(attrs.thesaurusConceptIdAttribute)) { + var input; + if (scope.templateField) { scope.conceptIdElementName = // In multilingual mode, the ref to the CharacterString is known using the id diff --git a/web-ui/src/main/resources/catalog/components/thesaurus/ThesaurusService.js b/web-ui/src/main/resources/catalog/components/thesaurus/ThesaurusService.js index fae0e4aca34..28030bcfadd 100644 --- a/web-ui/src/main/resources/catalog/components/thesaurus/ThesaurusService.js +++ b/web-ui/src/main/resources/catalog/components/thesaurus/ThesaurusService.js @@ -177,11 +177,11 @@ } if (gnLangs.langs[currentUILang_3char]) { - v = gnLangs.langs[currentUILang_3char]; + var v = gnLangs.langs[currentUILang_3char]; if (!_.includes(result, v)) result.push(v); } if (currentUILang2_3char && gnLangs.langs[currentUILang2_3char]) { - v = gnLangs.langs[currentUILang2_3char]; + var v = gnLangs.langs[currentUILang2_3char]; if (!_.includes(result, v)) result.push(v); } return result; diff --git a/web-ui/src/main/resources/catalog/components/usersearches/UserSearchesService.js b/web-ui/src/main/resources/catalog/components/usersearches/UserSearchesService.js index 428f58115b0..dbfae5132f7 100644 --- a/web-ui/src/main/resources/catalog/components/usersearches/UserSearchesService.js +++ b/web-ui/src/main/resources/catalog/components/usersearches/UserSearchesService.js @@ -33,7 +33,7 @@ this.loadFeaturedUserSearches = function (type, withPortal) { var deferred = $q.defer(), usersearches = $http.get("../api/usersearches/featured?type=" + type); - apiCalls = [usersearches]; + var apiCalls = [usersearches]; if (withPortal) { apiCalls.push($http.get("../api/sources/subportal")); } diff --git a/web-ui/src/main/resources/catalog/components/utility/UtilityDirective.js b/web-ui/src/main/resources/catalog/components/utility/UtilityDirective.js index 8ad4d6483ea..c336b393038 100644 --- a/web-ui/src/main/resources/catalog/components/utility/UtilityDirective.js +++ b/web-ui/src/main/resources/catalog/components/utility/UtilityDirective.js @@ -484,7 +484,7 @@ function setDefault() { var defaultThesaurus = attrs["default"]; - for (t in scope.regionTypes) { + for (var t in scope.regionTypes) { if (scope.regionTypes[t].name === defaultThesaurus) { scope.regionType = scope.regionTypes[t]; return; @@ -729,7 +729,7 @@ link: function (scope, element, attrs) { if (attrs["gnRegionType"]) { gnRegionService.loadList().then(function (data) { - for (i = 0; i < data.length; ++i) { + for (var i = 0; i < data.length; ++i) { if (attrs["gnRegionType"] == data[i].name) { scope.regionType = data[i]; } diff --git a/web-ui/src/main/resources/catalog/components/viewer/draw/DrawDirective.js b/web-ui/src/main/resources/catalog/components/viewer/draw/DrawDirective.js index 34eac7b47f4..c30b16f9f03 100644 --- a/web-ui/src/main/resources/catalog/components/viewer/draw/DrawDirective.js +++ b/web-ui/src/main/resources/catalog/components/viewer/draw/DrawDirective.js @@ -244,7 +244,7 @@ * @param {ol.Feature} feature * @return {Object} serialized style */ - getStyleObjFromFeature = function (feature) { + var getStyleObjFromFeature = function (feature) { var st = feature.get("_style"); var drawType = feature.get("_type"); if (angular.isFunction(st)) { diff --git a/web-ui/src/main/resources/catalog/components/viewer/geometry/GeometryService.js b/web-ui/src/main/resources/catalog/components/viewer/geometry/GeometryService.js index 5e0d1aa8a69..cc7d5059623 100644 --- a/web-ui/src/main/resources/catalog/components/viewer/geometry/GeometryService.js +++ b/web-ui/src/main/resources/catalog/components/viewer/geometry/GeometryService.js @@ -482,7 +482,7 @@ // Do not densify if shape does not appear to be an extent if (geom.getType() !== "Polygon" || inCoords.length > 5) return; for (var i = 0; i < inCoords.length - 1; i++) { - var p0, p1, x0, y0, dX; + var p0, p1, x0, y0, dX, dY; p0 = inCoords[i]; p1 = inCoords[i + 1]; x0 = p0[0]; diff --git a/web-ui/src/main/resources/catalog/components/viewer/gfi/FeaturesLoader.js b/web-ui/src/main/resources/catalog/components/viewer/gfi/FeaturesLoader.js index 52f9949ffed..c9ca61926cf 100644 --- a/web-ui/src/main/resources/catalog/components/viewer/gfi/FeaturesLoader.js +++ b/web-ui/src/main/resources/catalog/components/viewer/gfi/FeaturesLoader.js @@ -210,8 +210,8 @@ var promises = [this.promise, this.dictionary]; return $q.all(promises).then(function (data) { - features = data[0]; - dictionary = data[1]; + var features = data[0]; + var dictionary = data[1]; if (!features || features.length == 0) { return; diff --git a/web-ui/src/main/resources/catalog/components/viewer/layermanager/LayerManagerDirective.js b/web-ui/src/main/resources/catalog/components/viewer/layermanager/LayerManagerDirective.js index 4d02bd7b1d5..11552ccd3dc 100644 --- a/web-ui/src/main/resources/catalog/components/viewer/layermanager/LayerManagerDirective.js +++ b/web-ui/src/main/resources/catalog/components/viewer/layermanager/LayerManagerDirective.js @@ -208,12 +208,12 @@ headers: new Headers(headerDict), responseType: "blob" }; - legendPromise = $http.get(urlGetLegend, requestOptions).then( + var legendPromise = $http.get(urlGetLegend, requestOptions).then( function (response) { var contentType = headers("content-type"); if (contentType.indexOf("image") === 0) { // encode data to base 64 url - fileReader = new FileReader(); + var fileReader = new FileReader(); fileReader.onload = function () { style.LegendURL[0].OnlineResource = fileReader.result; layer.set("legend", fileReader.result); @@ -296,7 +296,7 @@ var dimensionConfig = scope.layer.get(dimension); if (dimensionConfig) { var idx = dimensionConfig.values.length - 1; - for (i = 0; i < dimensionConfig.values.length; i++) { + for (var i = 0; i < dimensionConfig.values.length; i++) { if (dimensionConfig.values[i] === dimensionConfig.default) { idx = i; break; diff --git a/web-ui/src/main/resources/catalog/components/viewer/measure/MeasureDirective.js b/web-ui/src/main/resources/catalog/components/viewer/measure/MeasureDirective.js index b04d0d26118..ceb0209aa35 100644 --- a/web-ui/src/main/resources/catalog/components/viewer/measure/MeasureDirective.js +++ b/web-ui/src/main/resources/catalog/components/viewer/measure/MeasureDirective.js @@ -202,11 +202,11 @@ this.create = function (map, measureObj, scope) { // taken from https://openlayers.org/en/v3.15.0/examples/measure.html - getGeodesicLength = function (geometry) { + var getGeodesicLength = function (geometry) { var sourceProj = map.getView().getProjection(); return formatLength(geometry, sourceProj); }; - getGeodesicArea = function (geometry) { + var getGeodesicArea = function (geometry) { var sourceProj = map.getView().getProjection(); return formatArea(geometry, sourceProj); }; diff --git a/web-ui/src/main/resources/catalog/components/viewer/owscontext/OwsContextService.js b/web-ui/src/main/resources/catalog/components/viewer/owscontext/OwsContextService.js index ebee3668e9f..8538da10cf5 100644 --- a/web-ui/src/main/resources/catalog/components/viewer/owscontext/OwsContextService.js +++ b/web-ui/src/main/resources/catalog/components/viewer/owscontext/OwsContextService.js @@ -236,7 +236,7 @@ layerAttributionArray = []; for (var a = 0; a < layer.vendorExtension.attribution.length; a++) { var attribution = layer.vendorExtension.attribution[a]; - layerAttribution = attribution.title; + var layerAttribution = attribution.title; // If href exist then make the title a link if (attribution.onlineResource && attribution.onlineResource[0].href) { var link = document.createElement("a"); diff --git a/web-ui/src/main/resources/catalog/components/viewer/wfsfilter/WfsFilterDirective.js b/web-ui/src/main/resources/catalog/components/viewer/wfsfilter/WfsFilterDirective.js index e53117490c2..742d41ae97f 100644 --- a/web-ui/src/main/resources/catalog/components/viewer/wfsfilter/WfsFilterDirective.js +++ b/web-ui/src/main/resources/catalog/components/viewer/wfsfilter/WfsFilterDirective.js @@ -592,7 +592,7 @@ scope.featuresInMapExtent = false; - onMoveEnd = function (evt) { + var onMoveEnd = function (evt) { var extent = scope.map.getView().calculateExtent(map.getSize()); var wgsExtent = ol.extent.applyTransform( extent, diff --git a/web-ui/src/main/resources/catalog/components/viewer/wps/WpsService.js b/web-ui/src/main/resources/catalog/components/viewer/wps/WpsService.js index f9780ca4b74..9901d171f66 100644 --- a/web-ui/src/main/resources/catalog/components/viewer/wps/WpsService.js +++ b/web-ui/src/main/resources/catalog/components/viewer/wps/WpsService.js @@ -99,7 +99,7 @@ * requests are cancelled */ this.describeProcess = function (uri, processId, options) { - url = gnOwsCapabilities.mergeDefaultParams(uri, { + var url = gnOwsCapabilities.mergeDefaultParams(uri, { service: "WPS", version: "1.0.0", request: "DescribeProcess", diff --git a/web-ui/src/main/resources/catalog/js/CatController.js b/web-ui/src/main/resources/catalog/js/CatController.js index 9c7aed3185d..1e6d4846fef 100644 --- a/web-ui/src/main/resources/catalog/js/CatController.js +++ b/web-ui/src/main/resources/catalog/js/CatController.js @@ -1367,7 +1367,7 @@ _.set(this.gnCfg, p, o); } if (runAllChecks) { - optionInDefaultConfig = _.get(defaultConfig, p); + var optionInDefaultConfig = _.get(defaultConfig, p); if (optionInDefaultConfig === undefined) { console.warn( "Path " + @@ -1403,7 +1403,7 @@ option = _.get(config, p); if (angular.isObject(option) && Object.keys(option).length === 0) { var key = pathToken.pop(); - parent = _.get(config, pathToken.join(".")); + var parent = _.get(config, pathToken.join(".")); delete parent[key]; } } @@ -1482,7 +1482,7 @@ return angular.isDefined(this.langs[lang]); }, isValidIso2Lang: function (lang) { - for (p in this.langs) { + for (var p in this.langs) { if (this.langs[p] === lang) { return true; } @@ -1493,7 +1493,7 @@ return this.langs[iso3lang] || "en"; }, getIso3Lang: function (iso2lang) { - for (p in this.langs) { + for (var p in this.langs) { if (this.langs[p] === iso2lang) { return p; } @@ -1559,7 +1559,7 @@ // Links for social media $scope.socialMediaLink = $location.absUrl(); - $scope.getPermalink = gnUtilityService.getPermalink; + $scope.getPermalink = gnUtilityService.displayPermalink; $scope.fluidEditorLayout = gnGlobalSettings.gnCfg.mods.editor.fluidEditorLayout; $scope.fluidHeaderLayout = gnGlobalSettings.gnCfg.mods.header.fluidHeaderLayout; $scope.showGNName = gnGlobalSettings.gnCfg.mods.header.showGNName; @@ -1983,7 +1983,7 @@ .then(function (r) { $scope.searchInfo = r.data; var keys = Object.keys(gnGlobalSettings.gnCfg.mods.home.facetConfig); - selectedFacet = keys[0]; + var selectedFacet = keys[0]; for (var i = 0; i < keys.length; i++) { if ( diff --git a/web-ui/src/main/resources/catalog/js/GnFormatterLib.js b/web-ui/src/main/resources/catalog/js/GnFormatterLib.js index 08fc518ead2..417cf38096f 100644 --- a/web-ui/src/main/resources/catalog/js/GnFormatterLib.js +++ b/web-ui/src/main/resources/catalog/js/GnFormatterLib.js @@ -24,7 +24,7 @@ (function () { goog.provide("gn_formatter_lib"); - gnFormatter = {}; + var gnFormatter = {}; gnFormatter.formatterSectionTogglersEventHandler = function (e) { var thisEl = $(e.currentTarget); thisEl.toggleClass("closed"); @@ -198,7 +198,7 @@ }; gnFormatter.toggleTab = function (tabElementId) { - tab = $('.view-outline [id="tab-' + tabElementId + '"] a[rel]'); + var tab = $('.view-outline [id="tab-' + tabElementId + '"] a[rel]'); if (tab.length > 0) { tab.click(); } else { diff --git a/web-ui/src/main/resources/catalog/js/GnLandingPageLib.js b/web-ui/src/main/resources/catalog/js/GnLandingPageLib.js index 6070af83a59..dcef85637e3 100644 --- a/web-ui/src/main/resources/catalog/js/GnLandingPageLib.js +++ b/web-ui/src/main/resources/catalog/js/GnLandingPageLib.js @@ -21,7 +21,7 @@ * Rome - Italy. email: geonetwork@osgeo.org */ (function () { - gnLandingPage = {}; + var gnLandingPage = {}; gnLandingPage.displayLanguage = function (lang, target) { target.parentElement.parentElement.querySelectorAll("li").forEach(function (li) { li.classList.remove("active"); diff --git a/web-ui/src/main/resources/catalog/js/GnSearchModule.js b/web-ui/src/main/resources/catalog/js/GnSearchModule.js index 33d38ceea12..0e8e33f76d8 100644 --- a/web-ui/src/main/resources/catalog/js/GnSearchModule.js +++ b/web-ui/src/main/resources/catalog/js/GnSearchModule.js @@ -24,7 +24,6 @@ (function () { goog.provide("gn_search"); - goog.require("gn_formatter_lib"); goog.require("gn_map_field_directive"); goog.require("gn_field_duration_directive"); goog.require("gn_mdactions"); diff --git a/web-ui/src/main/resources/catalog/js/admin/AdminController.js b/web-ui/src/main/resources/catalog/js/admin/AdminController.js index 2a9580990e1..84429a89889 100644 --- a/web-ui/src/main/resources/catalog/js/admin/AdminController.js +++ b/web-ui/src/main/resources/catalog/js/admin/AdminController.js @@ -81,14 +81,14 @@ ]; var irol = 0; - for (i = 0; i < roles.length; i++) { + for (var i = 0; i < roles.length; i++) { if (rol.toUpperCase() == roles[i].toUpperCase()) { irol = i; } } var iprofile = 0; - for (i = 0; i < roles.length; i++) { + for (var i = 0; i < roles.length; i++) { if (newProfile.toUpperCase() == roles[i].toUpperCase()) { iprofile = i; } diff --git a/web-ui/src/main/resources/catalog/js/admin/AdminMetadataController.js b/web-ui/src/main/resources/catalog/js/admin/AdminMetadataController.js index 68e2597d245..efb701b682a 100644 --- a/web-ui/src/main/resources/catalog/js/admin/AdminMetadataController.js +++ b/web-ui/src/main/resources/catalog/js/admin/AdminMetadataController.js @@ -140,7 +140,7 @@ } } - selectSchema = function (schema) { + var selectSchema = function (schema) { var idx = $scope.selectedSchemas.indexOf(schema); if (idx === -1) { $scope.selectedSchemas.push(schema); @@ -223,7 +223,7 @@ $scope.formatterFiles = []; $scope.metadataId = ""; - loadFormatter = function () { + var loadFormatter = function () { $scope.formatters = []; $http.get("../api/formatters").then( function (response) { @@ -242,7 +242,7 @@ /** * Callback when error uploading file. */ - loadFormatterError = function (e, data) { + var loadFormatterError = function (e, data) { if (data.jqXHR.status === 201) { loadFormatter(); return; diff --git a/web-ui/src/main/resources/catalog/js/admin/HarvestSettingsController.js b/web-ui/src/main/resources/catalog/js/admin/HarvestSettingsController.js index b7544f92efe..95a30bbf36a 100644 --- a/web-ui/src/main/resources/catalog/js/admin/HarvestSettingsController.js +++ b/web-ui/src/main/resources/catalog/js/admin/HarvestSettingsController.js @@ -135,7 +135,7 @@ } } if ($scope.harvesterSelected.bboxFilter) { - s = $scope.harvesterSelected.bboxFilter; + var s = $scope.harvesterSelected.bboxFilter; if ($scope.harvesterSelected.bboxFilter["bbox-xmin"]) { bboxProperties.forEach(function (coordinate) { s[coordinate] = parseFloat(s[coordinate]); @@ -714,8 +714,8 @@ var i = 0; var xmlDoc = $.parseXML(response.data); var $xml = $(xmlDoc); - $sources = $xml.find("uuid"); - $names = $xml.find("name"); + var $sources = $xml.find("uuid"); + var $names = $xml.find("name"); angular.forEach($sources, function (s) { // FIXME: probably some issue on IE ? diff --git a/web-ui/src/main/resources/catalog/js/admin/LogoSettingsController.js b/web-ui/src/main/resources/catalog/js/admin/LogoSettingsController.js index b93b9606a48..751acede84e 100644 --- a/web-ui/src/main/resources/catalog/js/admin/LogoSettingsController.js +++ b/web-ui/src/main/resources/catalog/js/admin/LogoSettingsController.js @@ -45,7 +45,7 @@ /** * Load list of logos */ - loadLogo = function () { + var loadLogo = function () { $scope.logos = []; $http.get("../api/logos").then(function (response) { $scope.logos = response.data; @@ -55,7 +55,7 @@ /** * Callback when error uploading file. */ - loadLogoError = function (e, data) { + var loadLogoError = function (e, data) { if (data.jqXHR.status !== 201) { $rootScope.$broadcast("StatusUpdated", { title: $translate.instant("logoUploadError"), diff --git a/web-ui/src/main/resources/catalog/js/admin/ThesaurusController.js b/web-ui/src/main/resources/catalog/js/admin/ThesaurusController.js index e3c09820d52..2897fa91b07 100644 --- a/web-ui/src/main/resources/catalog/js/admin/ThesaurusController.js +++ b/web-ui/src/main/resources/catalog/js/admin/ThesaurusController.js @@ -179,7 +179,7 @@ /** * Search thesaurus keyword based on filter and max number */ - searchThesaurusKeyword = function () { + var searchThesaurusKeyword = function () { $scope.searching = true; if ($scope.thesaurusSelected) { // list of ui languages; we want the keyword info in all these @@ -445,7 +445,7 @@ * Thesaurus uploaded with success, close the modal, * refresh the list. */ - uploadThesaurusDone = function (data) { + var uploadThesaurusDone = function (data) { $scope.clear($scope.queue); $scope.thesaurusUrl = ""; @@ -463,7 +463,7 @@ /** * Thesaurus uploaded with error, broadcast it. */ - uploadThesaurusError = function (e, data) { + var uploadThesaurusError = function (e, data) { var r = data.jqXHR || data; if (r.status === 201) { uploadThesaurusDone(data); @@ -575,7 +575,7 @@ /** * Search relation for each types for the current keyword */ - searchRelation = function (k) { + var searchRelation = function (k) { $scope.keywordSelectedRelation = {}; $.each(relationTypes, function (index, value) { $http @@ -656,7 +656,7 @@ /** * Build keyword POST body message */ - buildKeywordXML = function (keywordObject) { + var buildKeywordXML = function (keywordObject) { var geoxml = $scope.isPlaceType() ? "" + keywordObject.geo.west + diff --git a/web-ui/src/main/resources/catalog/js/admin/UserGroupController.js b/web-ui/src/main/resources/catalog/js/admin/UserGroupController.js index 81cdfb4df8b..284cdb74616 100644 --- a/web-ui/src/main/resources/catalog/js/admin/UserGroupController.js +++ b/web-ui/src/main/resources/catalog/js/admin/UserGroupController.js @@ -691,10 +691,10 @@ }); }; - var createOrModifyGroupError = function (data) { + var createOrModifyGroupError = function (response) { $rootScope.$broadcast("StatusUpdated", { title: $translate.instant("groupUpdateError"), - error: data, + error: response.data, timeout: 0, type: "danger" }); diff --git a/web-ui/src/main/resources/catalog/js/edit/BatchEditController.js b/web-ui/src/main/resources/catalog/js/edit/BatchEditController.js index 9783dcc5a88..5429167526f 100644 --- a/web-ui/src/main/resources/catalog/js/edit/BatchEditController.js +++ b/web-ui/src/main/resources/catalog/js/edit/BatchEditController.js @@ -311,7 +311,6 @@ field: field, insertMode: insertMode || field.insertMode, xpath: xpath, - condition: condition, value: template && value !== "" ? template.replace("{{value}}", value) : value, isXpath: isXpath || false, condition: condition || "" @@ -454,7 +453,6 @@ $scope.defaultCurrentXpath = { field: "", xpath: "", - condition: "", value: "", insertMode: "gn_add", condition: "" diff --git a/web-ui/src/main/resources/catalog/js/edit/NewMetadataController.js b/web-ui/src/main/resources/catalog/js/edit/NewMetadataController.js index 238337f2d93..9fe7f8ae126 100644 --- a/web-ui/src/main/resources/catalog/js/edit/NewMetadataController.js +++ b/web-ui/src/main/resources/catalog/js/edit/NewMetadataController.js @@ -293,7 +293,7 @@ } else { metadataUuid = getSelectedMdIdentifierTemplate().template; - for (key in $scope.mdIdentifierTemplateTokens) { + for (var key in $scope.mdIdentifierTemplateTokens) { var labelKey = $scope.mdIdentifierTemplateTokens[key].label; metadataUuid = metadataUuid.replace( "{" + labelKey + "}", @@ -359,7 +359,7 @@ $scope.updateMdIdentifierTemplateLabel = function () { $scope.mdIdSelectedTemplateForLabel = getSelectedMdIdentifierTemplate().template; - for (key in $scope.mdIdentifierTemplateTokens) { + for (var key in $scope.mdIdentifierTemplateTokens) { if ($scope.mdIdentifierTemplateTokens[key].value) { var labelKey = $scope.mdIdentifierTemplateTokens[key].label; @@ -402,7 +402,7 @@ var fieldsFilled = true; - for (key in $scope.mdIdentifierTemplateTokens) { + for (var key in $scope.mdIdentifierTemplateTokens) { if (!$scope.mdIdentifierTemplateTokens[key].value) { fieldsFilled = false; break; diff --git a/web-ui/src/main/resources/catalog/locales/ca-core.json b/web-ui/src/main/resources/catalog/locales/ca-core.json index 855eb6f2551..5250d81ca29 100644 --- a/web-ui/src/main/resources/catalog/locales/ca-core.json +++ b/web-ui/src/main/resources/catalog/locales/ca-core.json @@ -506,7 +506,7 @@ "indexingTaskFinished": "Indexing finished, {{total}} records processed", "indexingTaskFinishedWithErrors": "Indexing finished, {{total}} records processed with {{errors}} errors", "indexingTaskCanceled": "Indexing canceled", - "inspireValidationTaskUndefined": "Unknow INSPIRE validation task (abnormal state)", + "inspireValidationTaskUndefined": "Unknown INSPIRE validation task (abnormal state)", "inspireValidationTaskRunning": "INSPIRE validation {{total}} records...", "inspireValidationTaskFinished": "INSPIRE validation finished, {{total}} records processed", "inspireValidationTaskFinishedWithErrors": "INSPIRE validation finished, {{total}} records processed with {{errors}} errors", @@ -515,7 +515,7 @@ "taskProbable": "Probable state", "analyseRecordRunning": "{{total}} records to analyze...", "analyseRecordFinished": "Analyse over, {{total}} records processed", - "analyseRecordFinishedWithErrors": "Analyse over, {{total}} records processed with {{errors}} errorrs", + "analyseRecordFinishedWithErrors": "Analyse over, {{total}} records processed with {{errors}} errors", "testLinkRunning": "{{total}} links to test...", "testLinkFinished": "Testing links over, {{total}} links tested", "mdStatusButton-1": "Submit", @@ -574,4 +574,4 @@ "reviewerNotAllowedPublish": "Reviewer not allowed to publish the metadata", "reviewerNotAllowedUnpublish": "Reviewer not allowed to un-publish the metadata", "reviewerNotAllowedPublishUnpublish": "Reviewer not allowed to publish / un-publish the metadata" -} \ No newline at end of file +} diff --git a/web-ui/src/main/resources/catalog/locales/en-core.json b/web-ui/src/main/resources/catalog/locales/en-core.json index baf9200d321..6321f1ce160 100644 --- a/web-ui/src/main/resources/catalog/locales/en-core.json +++ b/web-ui/src/main/resources/catalog/locales/en-core.json @@ -507,7 +507,7 @@ "indexingTaskFinished": "Indexing finished, {{total}} records processed", "indexingTaskFinishedWithErrors": "Indexing finished, {{total}} records processed with {{errors}} errors", "indexingTaskCanceled": "Indexing canceled", - "inspireValidationTaskUndefined": "Unknow INSPIRE validation task (abnormal state)", + "inspireValidationTaskUndefined": "Unknown INSPIRE validation task (abnormal state)", "inspireValidationTaskRunning": "INSPIRE validation {{total}} records...", "inspireValidationTaskFinished": "INSPIRE validation finished, {{total}} records processed", "inspireValidationTaskFinishedWithErrors": "INSPIRE validation finished, {{total}} records processed with {{errors}} errors", diff --git a/web-ui/src/main/resources/catalog/locales/en-editor.json b/web-ui/src/main/resources/catalog/locales/en-editor.json index 827c0fb3f6e..30f2996010a 100644 --- a/web-ui/src/main/resources/catalog/locales/en-editor.json +++ b/web-ui/src/main/resources/catalog/locales/en-editor.json @@ -44,7 +44,7 @@ "removeField": "Remove this field", "addXpath-help": "Updating records using XPath needs careful definition of the changes. A change is defined by:", "addXpathTitle": "an optional title", - "addXpathXpath": "a mandatory XPath to point to the element(s) to update. XPath may contain a filter expression.", + "addXpathXpath": "a mandatory XPath to point to the element(s) to update. XPath may contain a filter expression.", "addXpathInsertMode": "a type of update", "xpath": "XPath", "xpathValue": "Text or XML value", diff --git a/web-ui/src/main/resources/catalog/locales/en-v4.json b/web-ui/src/main/resources/catalog/locales/en-v4.json index efb3d051c3c..b6a1f9ea04a 100644 --- a/web-ui/src/main/resources/catalog/locales/en-v4.json +++ b/web-ui/src/main/resources/catalog/locales/en-v4.json @@ -335,6 +335,7 @@ "createCollectionFromSelectionAs": "Create collection from selection as", "supplementalInformation": "Supplemental Information", "sourceDescription": "Source description", + "processSteps": "Process steps", "orderingInstructions": "Ordering instructions", "siblingsReverseLinks": "Other resources (other record links)", "focusOnFrom": "Focus on resources from ", @@ -386,6 +387,11 @@ "setServiceConnectPoint": "Add service connect point", "mimeType": "Format", "uploadedResourceAlreadyExistException": "File {{file}} already exist in this record data store. Remove it first.", + "qualityMeasures": "Quality", + "measureType": "Type", + "measureName": "Measure", + "measureDescription": "Description", + "measureValue": "Value", "switchPortals": "Switch to another Portal", "dataPreview": "Discover data", "tableOfContents": "Table of Contents", diff --git a/web-ui/src/main/resources/catalog/locales/fi-core.json b/web-ui/src/main/resources/catalog/locales/fi-core.json index 9ece02067c4..f1f6e871f5f 100644 --- a/web-ui/src/main/resources/catalog/locales/fi-core.json +++ b/web-ui/src/main/resources/catalog/locales/fi-core.json @@ -506,7 +506,7 @@ "indexingTaskFinished": "Indexing finished, {{total}} records processed", "indexingTaskFinishedWithErrors": "Indexing finished, {{total}} records processed with {{errors}} errors", "indexingTaskCanceled": "Indexing canceled", - "inspireValidationTaskUndefined": "Unknow INSPIRE validation task (abnormal state)", + "inspireValidationTaskUndefined": "Unknown INSPIRE validation task (abnormal state)", "inspireValidationTaskRunning": "INSPIRE validation {{total}} records...", "inspireValidationTaskFinished": "INSPIRE validation finished, {{total}} records processed", "inspireValidationTaskFinishedWithErrors": "INSPIRE validation finished, {{total}} records processed with {{errors}} errors", @@ -515,7 +515,7 @@ "taskProbable": "Probable state", "analyseRecordRunning": "{{total}} records to analyze...", "analyseRecordFinished": "Analyse over, {{total}} records processed", - "analyseRecordFinishedWithErrors": "Analyse over, {{total}} records processed with {{errors}} errorrs", + "analyseRecordFinishedWithErrors": "Analyse over, {{total}} records processed with {{errors}} errors", "testLinkRunning": "{{total}} links to test...", "testLinkFinished": "Testing links over, {{total}} links tested", "mdStatusButton-1": "Submit", @@ -574,4 +574,4 @@ "reviewerNotAllowedPublish": "Reviewer not allowed to publish the metadata", "reviewerNotAllowedUnpublish": "Reviewer not allowed to un-publish the metadata", "reviewerNotAllowedPublishUnpublish": "Reviewer not allowed to publish / un-publish the metadata" -} \ No newline at end of file +} diff --git a/web-ui/src/main/resources/catalog/locales/is-core.json b/web-ui/src/main/resources/catalog/locales/is-core.json index 21ddf8da4e0..b44dfd5b00c 100644 --- a/web-ui/src/main/resources/catalog/locales/is-core.json +++ b/web-ui/src/main/resources/catalog/locales/is-core.json @@ -506,7 +506,7 @@ "indexingTaskFinished": "Flokkun lokið, {{total}} færslur unnar ", "indexingTaskFinishedWithErrors": "Flokkun lokið, {{total}} færslur unnar með {{errors}} villum", "indexingTaskCanceled": "Hætt við flokkun", - "inspireValidationTaskUndefined": "Unknow INSPIRE validation task (abnormal state)", + "inspireValidationTaskUndefined": "Unknown INSPIRE validation task (abnormal state)", "inspireValidationTaskRunning": "INSPIRE validation {{total}} records...", "inspireValidationTaskFinished": "INSPIRE validation finished, {{total}} records processed", "inspireValidationTaskFinishedWithErrors": "INSPIRE validation finished, {{total}} records processed with {{errors}} errors", @@ -515,7 +515,7 @@ "taskProbable": "Probable state", "analyseRecordRunning": "{{total}} records to analyze...", "analyseRecordFinished": "Analyse over, {{total}} records processed", - "analyseRecordFinishedWithErrors": "Analyse over, {{total}} records processed with {{errors}} errorrs", + "analyseRecordFinishedWithErrors": "Analyse over, {{total}} records processed with {{errors}} errors", "testLinkRunning": "{{total}} links to test...", "testLinkFinished": "Testing links over, {{total}} links tested", "mdStatusButton-1": "Leggja fram", @@ -574,4 +574,4 @@ "reviewerNotAllowedPublish": "Reviewer not allowed to publish the metadata", "reviewerNotAllowedUnpublish": "Reviewer not allowed to un-publish the metadata", "reviewerNotAllowedPublishUnpublish": "Reviewer not allowed to publish / un-publish the metadata" -} \ No newline at end of file +} diff --git a/web-ui/src/main/resources/catalog/locales/it-core.json b/web-ui/src/main/resources/catalog/locales/it-core.json index e1965ae2ba8..be7c427c766 100644 --- a/web-ui/src/main/resources/catalog/locales/it-core.json +++ b/web-ui/src/main/resources/catalog/locales/it-core.json @@ -506,7 +506,7 @@ "indexingTaskFinished": "Indexing finished, {{total}} records processed", "indexingTaskFinishedWithErrors": "Indexing finished, {{total}} records processed with {{errors}} errors", "indexingTaskCanceled": "Indexing canceled", - "inspireValidationTaskUndefined": "Unknow INSPIRE validation task (abnormal state)", + "inspireValidationTaskUndefined": "Unknown INSPIRE validation task (abnormal state)", "inspireValidationTaskRunning": "INSPIRE validation {{total}} records...", "inspireValidationTaskFinished": "INSPIRE validation finished, {{total}} records processed", "inspireValidationTaskFinishedWithErrors": "INSPIRE validation finished, {{total}} records processed with {{errors}} errors", @@ -515,7 +515,7 @@ "taskProbable": "Probable state", "analyseRecordRunning": "{{total}} records to analyze...", "analyseRecordFinished": "Analyse over, {{total}} records processed", - "analyseRecordFinishedWithErrors": "Analyse over, {{total}} records processed with {{errors}} errorrs", + "analyseRecordFinishedWithErrors": "Analyse over, {{total}} records processed with {{errors}} errors", "testLinkRunning": "{{total}} links to test...", "testLinkFinished": "Testing links over, {{total}} links tested", "mdStatusButton-1": "Submit", @@ -574,4 +574,4 @@ "reviewerNotAllowedPublish": "Reviewer not allowed to publish the metadata", "reviewerNotAllowedUnpublish": "Reviewer not allowed to un-publish the metadata", "reviewerNotAllowedPublishUnpublish": "Reviewer not allowed to publish / un-publish the metadata" -} \ No newline at end of file +} diff --git a/web-ui/src/main/resources/catalog/locales/ko-core.json b/web-ui/src/main/resources/catalog/locales/ko-core.json index b00571a0642..d993a7bf04a 100644 --- a/web-ui/src/main/resources/catalog/locales/ko-core.json +++ b/web-ui/src/main/resources/catalog/locales/ko-core.json @@ -506,7 +506,7 @@ "indexingTaskFinished": "인덱싱 완료, {{total}} 레코드를 처리했습니다", "indexingTaskFinishedWithErrors": "인덱싱 완료, {{errors}} 오류가 발생한 {{total}} 레코드가 처리되었습니다.", "indexingTaskCanceled": "인덱싱 취소됨", - "inspireValidationTaskUndefined": "Unknow INSPIRE validation task (abnormal state)", + "inspireValidationTaskUndefined": "Unknown INSPIRE validation task (abnormal state)", "inspireValidationTaskRunning": "INSPIRE validation {{total}} records...", "inspireValidationTaskFinished": "INSPIRE validation finished, {{total}} records processed", "inspireValidationTaskFinishedWithErrors": "INSPIRE validation finished, {{total}} records processed with {{errors}} errors", @@ -515,7 +515,7 @@ "taskProbable": "Probable state", "analyseRecordRunning": "{{total}} records to analyze...", "analyseRecordFinished": "Analyse over, {{total}} records processed", - "analyseRecordFinishedWithErrors": "Analyse over, {{total}} records processed with {{errors}} errorrs", + "analyseRecordFinishedWithErrors": "Analyse over, {{total}} records processed with {{errors}} errors", "testLinkRunning": "{{total}} links to test...", "testLinkFinished": "Testing links over, {{total}} links tested", "mdStatusButton-1": "Submit", @@ -574,4 +574,4 @@ "reviewerNotAllowedPublish": "Reviewer not allowed to publish the metadata", "reviewerNotAllowedUnpublish": "Reviewer not allowed to un-publish the metadata", "reviewerNotAllowedPublishUnpublish": "Reviewer not allowed to publish / un-publish the metadata" -} \ No newline at end of file +} diff --git a/web-ui/src/main/resources/catalog/locales/pt-core.json b/web-ui/src/main/resources/catalog/locales/pt-core.json index 7611c78b120..cc442e2c02d 100644 --- a/web-ui/src/main/resources/catalog/locales/pt-core.json +++ b/web-ui/src/main/resources/catalog/locales/pt-core.json @@ -506,7 +506,7 @@ "indexingTaskFinished": "A indexação terminou, {{total}} registros processados", "indexingTaskFinishedWithErrors": "A indexação terminou, {{total}} registros processados ​​com erros de {{errors}}", "indexingTaskCanceled": "Indexação cancelada", - "inspireValidationTaskUndefined": "Unknow INSPIRE validation task (abnormal state)", + "inspireValidationTaskUndefined": "Unknown INSPIRE validation task (abnormal state)", "inspireValidationTaskRunning": "INSPIRE validation {{total}} records...", "inspireValidationTaskFinished": "INSPIRE validation finished, {{total}} records processed", "inspireValidationTaskFinishedWithErrors": "INSPIRE validation finished, {{total}} records processed with {{errors}} errors", @@ -515,7 +515,7 @@ "taskProbable": "Probable state", "analyseRecordRunning": "{{total}} records to analyze...", "analyseRecordFinished": "Analyse over, {{total}} records processed", - "analyseRecordFinishedWithErrors": "Analyse over, {{total}} records processed with {{errors}} errorrs", + "analyseRecordFinishedWithErrors": "Analyse over, {{total}} records processed with {{errors}} errors", "testLinkRunning": "{{total}} links to test...", "testLinkFinished": "Testing links over, {{total}} links tested", "mdStatusButton-1": "Enviar", @@ -574,4 +574,4 @@ "reviewerNotAllowedPublish": "Reviewer not allowed to publish the metadata", "reviewerNotAllowedUnpublish": "Reviewer not allowed to un-publish the metadata", "reviewerNotAllowedPublishUnpublish": "Reviewer not allowed to publish / un-publish the metadata" -} \ No newline at end of file +} diff --git a/web-ui/src/main/resources/catalog/locales/ru-core.json b/web-ui/src/main/resources/catalog/locales/ru-core.json index 88561103edd..fc0d9c82448 100644 --- a/web-ui/src/main/resources/catalog/locales/ru-core.json +++ b/web-ui/src/main/resources/catalog/locales/ru-core.json @@ -506,7 +506,7 @@ "indexingTaskFinished": "Indexing finished, {{total}} records processed", "indexingTaskFinishedWithErrors": "Indexing finished, {{total}} records processed with {{errors}} errors", "indexingTaskCanceled": "Indexing canceled", - "inspireValidationTaskUndefined": "Unknow INSPIRE validation task (abnormal state)", + "inspireValidationTaskUndefined": "Unknown INSPIRE validation task (abnormal state)", "inspireValidationTaskRunning": "INSPIRE validation {{total}} records...", "inspireValidationTaskFinished": "INSPIRE validation finished, {{total}} records processed", "inspireValidationTaskFinishedWithErrors": "INSPIRE validation finished, {{total}} records processed with {{errors}} errors", @@ -515,7 +515,7 @@ "taskProbable": "Probable state", "analyseRecordRunning": "{{total}} records to analyze...", "analyseRecordFinished": "Analyse over, {{total}} records processed", - "analyseRecordFinishedWithErrors": "Analyse over, {{total}} records processed with {{errors}} errorrs", + "analyseRecordFinishedWithErrors": "Analyse over, {{total}} records processed with {{errors}} errors", "testLinkRunning": "{{total}} links to test...", "testLinkFinished": "Testing links over, {{total}} links tested", "mdStatusButton-1": "Submit", @@ -574,4 +574,4 @@ "reviewerNotAllowedPublish": "Reviewer not allowed to publish the metadata", "reviewerNotAllowedUnpublish": "Reviewer not allowed to un-publish the metadata", "reviewerNotAllowedPublishUnpublish": "Reviewer not allowed to publish / un-publish the metadata" -} \ No newline at end of file +} diff --git a/web-ui/src/main/resources/catalog/locales/sk-core.json b/web-ui/src/main/resources/catalog/locales/sk-core.json index 5a1c0a4ca9f..c1ed75a554e 100644 --- a/web-ui/src/main/resources/catalog/locales/sk-core.json +++ b/web-ui/src/main/resources/catalog/locales/sk-core.json @@ -506,7 +506,7 @@ "indexingTaskFinished": "Indexing finished, {{total}} records processed", "indexingTaskFinishedWithErrors": "Indexing finished, {{total}} records processed with {{errors}} errors", "indexingTaskCanceled": "Indexing canceled", - "inspireValidationTaskUndefined": "Unknow INSPIRE validation task (abnormal state)", + "inspireValidationTaskUndefined": "Unknown INSPIRE validation task (abnormal state)", "inspireValidationTaskRunning": "INSPIRE validation {{total}} records...", "inspireValidationTaskFinished": "INSPIRE validation finished, {{total}} records processed", "inspireValidationTaskFinishedWithErrors": "INSPIRE validation finished, {{total}} records processed with {{errors}} errors", @@ -515,7 +515,7 @@ "taskProbable": "Probable state", "analyseRecordRunning": "{{total}} records to analyze...", "analyseRecordFinished": "Analyse over, {{total}} records processed", - "analyseRecordFinishedWithErrors": "Analyse over, {{total}} records processed with {{errors}} errorrs", + "analyseRecordFinishedWithErrors": "Analyse over, {{total}} records processed with {{errors}} errors", "testLinkRunning": "{{total}} links to test...", "testLinkFinished": "Testing links over, {{total}} links tested", "mdStatusButton-1": "Submit", @@ -574,4 +574,4 @@ "reviewerNotAllowedPublish": "Reviewer not allowed to publish the metadata", "reviewerNotAllowedUnpublish": "Reviewer not allowed to un-publish the metadata", "reviewerNotAllowedPublishUnpublish": "Reviewer not allowed to publish / un-publish the metadata" -} \ No newline at end of file +} diff --git a/web-ui/src/main/resources/catalog/locales/zh-core.json b/web-ui/src/main/resources/catalog/locales/zh-core.json index ec12a19dd79..f6b259bf10c 100644 --- a/web-ui/src/main/resources/catalog/locales/zh-core.json +++ b/web-ui/src/main/resources/catalog/locales/zh-core.json @@ -506,7 +506,7 @@ "indexingTaskFinished": "索引已完成,已处理{{total}}条记录", "indexingTaskFinishedWithErrors": "索引已完成,{{total}}条记录已处理,{{errors}}条错误", "indexingTaskCanceled": "索引已取消", - "inspireValidationTaskUndefined": "Unknow INSPIRE validation task (abnormal state)", + "inspireValidationTaskUndefined": "Unknown INSPIRE validation task (abnormal state)", "inspireValidationTaskRunning": "INSPIRE validation {{total}} records...", "inspireValidationTaskFinished": "INSPIRE validation finished, {{total}} records processed", "inspireValidationTaskFinishedWithErrors": "INSPIRE validation finished, {{total}} records processed with {{errors}} errors", @@ -515,7 +515,7 @@ "taskProbable": "Probable state", "analyseRecordRunning": "{{total}} records to analyze...", "analyseRecordFinished": "Analyse over, {{total}} records processed", - "analyseRecordFinishedWithErrors": "Analyse over, {{total}} records processed with {{errors}} errorrs", + "analyseRecordFinishedWithErrors": "Analyse over, {{total}} records processed with {{errors}} errors", "testLinkRunning": "{{total}} links to test...", "testLinkFinished": "Testing links over, {{total}} links tested", "mdStatusButton-1": "Submit", @@ -574,4 +574,4 @@ "reviewerNotAllowedPublish": "Reviewer not allowed to publish the metadata", "reviewerNotAllowedUnpublish": "Reviewer not allowed to un-publish the metadata", "reviewerNotAllowedPublishUnpublish": "Reviewer not allowed to publish / un-publish the metadata" -} \ No newline at end of file +} diff --git a/web-ui/src/main/resources/catalog/style/gn_metadata.less b/web-ui/src/main/resources/catalog/style/gn_metadata.less index dbe7dbaf8d8..0753279c0c9 100644 --- a/web-ui/src/main/resources/catalog/style/gn_metadata.less +++ b/web-ui/src/main/resources/catalog/style/gn_metadata.less @@ -665,6 +665,13 @@ ul.container-list { } } +.gn-process-steps { + [data-gn-metadata-contacts] ul, + [gn-metadata-contacts] ul { + grid-template-columns: 1fr; + } +} + @media only screen and (min-width: 550px) { .gallery { display: flex; diff --git a/web-ui/src/main/resources/catalog/style/timeline.less b/web-ui/src/main/resources/catalog/style/timeline.less index e44bdcaa770..14a4c274364 100644 --- a/web-ui/src/main/resources/catalog/style/timeline.less +++ b/web-ui/src/main/resources/catalog/style/timeline.less @@ -10,11 +10,11 @@ .timeline-1-col { :before { - left: 2%; + left: 1%; } li > .timeline-badge { - left: 2%; + left: 1%; } li > .timeline-panel { width: 92%; diff --git a/web-ui/src/main/resources/catalog/templates/editor/top-toolbar.html b/web-ui/src/main/resources/catalog/templates/editor/top-toolbar.html index 01d45e0b8ad..cf663b5b162 100644 --- a/web-ui/src/main/resources/catalog/templates/editor/top-toolbar.html +++ b/web-ui/src/main/resources/catalog/templates/editor/top-toolbar.html @@ -12,8 +12,10 @@

{{gnCurrentEdit.mdTitle | limitTo: 50 }} {{gnCurrentEdit.mdTitle.length > 50 ? '...' : ''}}

- | - {{savedStatus}} +
+ {{savedStatus}}