Fixing group and tag generation on Item Validator

git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-publishing/gcat@177319 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Luca Frosini 2019-02-27 13:09:44 +00:00
parent 10201a9cea
commit f90b768b39
5 changed files with 37 additions and 54 deletions

View File

@ -2,7 +2,7 @@
<!DOCTYPE xml> <!DOCTYPE xml>
<ReleaseNotes> <ReleaseNotes>
<Changeset component="org.gcube.data-publishing.gcat.1-2-0" date="${buildDate}"> <Changeset component="org.gcube.data-publishing.gcat.1-2-0" date="${buildDate}">
<Change></Change> <Change>Saparated REST class for Profile management from the logic which effectively manage profile on IS</Change>
</Changeset> </Changeset>
<Changeset component="org.gcube.data-publishing.gcat.1-1-0" date="2019-02-26"> <Changeset component="org.gcube.data-publishing.gcat.1-1-0" date="2019-02-26">
<Change>Added Item URL via URI Resolver in extras field #13309</Change> <Change>Added Item URL via URI Resolver in extras field #13309</Change>

View File

@ -1,6 +1,6 @@
package org.gcube.gcat.oldutils; package org.gcube.gcat.oldutils;
import org.json.simple.JSONObject; import com.fasterxml.jackson.databind.JsonNode;
/** /**
* A custom field bean. It also stores index of the category and of the metadata field associated. * A custom field bean. It also stores index of the category and of the metadata field associated.
@ -42,9 +42,9 @@ public class CustomField implements Comparable<CustomField> {
} }
public CustomField(JSONObject object) { public CustomField(JsonNode object) {
super(); super();
init((String) object.get("key"), (String) object.get("value"), -1, -1); init(object.get("key").asText(), object.get("value").asText(), -1, -1);
} }
/** /**

View File

@ -28,14 +28,13 @@ import org.gcube.gcat.persistence.ckan.CKANUtility;
import org.gcube.gcat.profile.MetadataUtility; import org.gcube.gcat.profile.MetadataUtility;
import org.gcube.gcat.social.SocialService; import org.gcube.gcat.social.SocialService;
import org.geojson.GeoJsonObject; import org.geojson.GeoJsonObject;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import eu.trentorise.opendata.jackan.model.CkanGroup; import eu.trentorise.opendata.jackan.model.CkanGroup;
@ -44,7 +43,6 @@ import eu.trentorise.opendata.jackan.model.CkanGroup;
* @author Costantino Perciante (ISTI - CNR) * @author Costantino Perciante (ISTI - CNR)
* @author Luca Frosini (ISTI - CNR) * @author Luca Frosini (ISTI - CNR)
*/ */
@SuppressWarnings({"rawtypes", "unchecked"})
public class Validator { public class Validator {
private static final Logger logger = LoggerFactory.getLogger(Validator.class); private static final Logger logger = LoggerFactory.getLogger(Validator.class);
@ -52,22 +50,6 @@ public class Validator {
private static final SimpleDateFormat DATE_SIMPLE = new SimpleDateFormat("yyyy-MM-dd"); private static final SimpleDateFormat DATE_SIMPLE = new SimpleDateFormat("yyyy-MM-dd");
private static final SimpleDateFormat DATE_HOUR_MINUTES = new SimpleDateFormat("yyyy-MM-dd HH:mm"); private static final SimpleDateFormat DATE_HOUR_MINUTES = new SimpleDateFormat("yyyy-MM-dd HH:mm");
private static JSONObject getJSONObject(String json) {
JSONParser parser = new JSONParser();
JSONObject jsonObject;
try {
jsonObject = (JSONObject) parser.parse(json);
} catch(ParseException e) {
throw new BadRequestException(e.getMessage());
}
return jsonObject;
}
public static void validateAgainstProfile(String json) throws Exception {
JSONObject jsonObject = getJSONObject(json);
validateAgainstProfile(jsonObject);
}
/** /**
* This method validate the incoming json dataset wrt a metadata profile * This method validate the incoming json dataset wrt a metadata profile
* @param json * @param json
@ -76,30 +58,31 @@ public class Validator {
* @return * @return
* @throws Exception * @throws Exception
*/ */
public static void validateAgainstProfile(JSONObject obj) throws Exception { public static ObjectNode validateAgainstProfile(ObjectMapper mapper, ObjectNode objectNode) throws Exception {
JSONArray extrasArrayOriginal = (JSONArray) obj.get(CKANPackage.EXTRAS_KEY);
JSONArray groupsArrayOriginal = (JSONArray) obj.get(CKANPackage.GROUPS_KEY);
JSONArray tagsArrayOriginal = (JSONArray) obj.get(CKANPackage.TAGS_KEY);
if(extrasArrayOriginal == null || extrasArrayOriginal.isEmpty()) { ArrayNode extrasArrayOriginal = (ArrayNode) objectNode.get(CKANPackage.EXTRAS_KEY);
ArrayNode groupsArrayOriginal = (ArrayNode) objectNode.get(CKANPackage.GROUPS_KEY);
ArrayNode tagsArrayOriginal = (ArrayNode) objectNode.get(CKANPackage.TAGS_KEY);
if(extrasArrayOriginal == null || extrasArrayOriginal.size()==0) {
throw new BadRequestException("'extras' field is missing in context where metadata profile(s) are defined!"); throw new BadRequestException("'extras' field is missing in context where metadata profile(s) are defined!");
} }
if(groupsArrayOriginal == null) { if(groupsArrayOriginal == null) {
groupsArrayOriginal = new JSONArray(); groupsArrayOriginal = mapper.createArrayNode();
} }
if(tagsArrayOriginal == null) { if(tagsArrayOriginal == null) {
tagsArrayOriginal = new JSONArray(); tagsArrayOriginal = mapper.createArrayNode();
} }
// get the metadata profile specifying the type // get the metadata profile specifying the type
CustomField metadataTypeCF = null; CustomField metadataTypeCF = null;
List<CustomField> customFields = new ArrayList<CustomField>(extrasArrayOriginal.size()); List<CustomField> customFields = new ArrayList<CustomField>(extrasArrayOriginal.size());
Iterator iterator = extrasArrayOriginal.iterator(); Iterator<JsonNode> iterator = extrasArrayOriginal.iterator();
while(iterator.hasNext()) { while(iterator.hasNext()) {
JSONObject object = (JSONObject) iterator.next(); JsonNode object = iterator.next();
CustomField cf = new CustomField(object); CustomField cf = new CustomField(object);
if(cf.getKey().equals(CKANPackage.EXTRAS_KEY_VALUE_SYSTEM_TYPE)) { if(cf.getKey().equals(CKANPackage.EXTRAS_KEY_VALUE_SYSTEM_TYPE)) {
metadataTypeCF = cf; metadataTypeCF = cf;
@ -124,13 +107,13 @@ public class Validator {
+ profileName + profileName
+ "') specified as custom field doesn't match any of the profiles defined in this context!"); + "') specified as custom field doesn't match any of the profiles defined in this context!");
} else { } else {
JSONArray extrasArrayUpdated = null; ArrayNode extrasArrayUpdated = null;
List<MetadataField> metadataFields = profile.getMetadataFields(); List<MetadataField> metadataFields = profile.getMetadataFields();
if(metadataFields == null || metadataFields.isEmpty()) { if(metadataFields == null || metadataFields.isEmpty()) {
extrasArrayUpdated = extrasArrayOriginal; extrasArrayUpdated = extrasArrayOriginal;
} else { } else {
extrasArrayUpdated = new JSONArray(); extrasArrayUpdated = mapper.createArrayNode();
List<NamespaceCategory> categories = metadataUtility.getNamespaceCategories(); List<NamespaceCategory> categories = metadataUtility.getNamespaceCategories();
logger.debug("Retrieved namespaces are {}", categories); logger.debug("Retrieved namespaces are {}", categories);
@ -164,7 +147,7 @@ public class Validator {
List<CustomField> validCFs = validateAgainstMetadataField(metadataIndex, categoryIdIndex, List<CustomField> validCFs = validateAgainstMetadataField(metadataIndex, categoryIdIndex,
customFields, tagsArrayOriginal, groupsArrayOriginal, metadataField, categories, customFields, tagsArrayOriginal, groupsArrayOriginal, metadataField, categories,
fieldsMandatoryLowerBoundMap, fieldsMandatoryUpperBoundMap, numberFieldsMandatorySameKeyMap, fieldsMandatoryLowerBoundMap, fieldsMandatoryUpperBoundMap, numberFieldsMandatorySameKeyMap,
groupsToCreateAfterValidation); groupsToCreateAfterValidation, mapper);
validatedCustomFields.addAll(validCFs); validatedCustomFields.addAll(validCFs);
metadataIndex++; metadataIndex++;
@ -191,7 +174,7 @@ public class Validator {
} }
// if there are no tags, throw an exception // if there are no tags, throw an exception
if(tagsArrayOriginal.isEmpty()) { if(tagsArrayOriginal.size()==0) {
throw new BadRequestException("Please define at least one tag for this item!"); throw new BadRequestException("Please define at least one tag for this item!");
} }
@ -206,14 +189,14 @@ public class Validator {
// convert back to json // convert back to json
for(CustomField customField : validatedCustomFields) { for(CustomField customField : validatedCustomFields) {
JSONObject jsonObj = new JSONObject(); ObjectNode jsonObj = mapper.createObjectNode();
jsonObj.put(CKANPackage.EXTRAS_KEY_KEY, customField.getQualifiedKey()); jsonObj.put(CKANPackage.EXTRAS_KEY_KEY, customField.getQualifiedKey());
jsonObj.put(CKANPackage.EXTRAS_VALUE_KEY, customField.getValue()); jsonObj.put(CKANPackage.EXTRAS_VALUE_KEY, customField.getValue());
extrasArrayUpdated.add(jsonObj); extrasArrayUpdated.add(jsonObj);
} }
// add metadata type field as last element // add metadata type field as last element
JSONObject metadataTypeJSON = new JSONObject(); ObjectNode metadataTypeJSON = mapper.createObjectNode();
metadataTypeJSON.put(CKANPackage.EXTRAS_KEY_KEY, metadataTypeCF.getKey()); metadataTypeJSON.put(CKANPackage.EXTRAS_KEY_KEY, metadataTypeCF.getKey());
metadataTypeJSON.put(CKANPackage.EXTRAS_VALUE_KEY, metadataTypeCF.getValue()); metadataTypeJSON.put(CKANPackage.EXTRAS_VALUE_KEY, metadataTypeCF.getValue());
extrasArrayUpdated.add(metadataTypeJSON); extrasArrayUpdated.add(metadataTypeJSON);
@ -228,10 +211,11 @@ public class Validator {
} }
} }
obj.put(CKANPackage.TAGS_KEY, tagsArrayOriginal); objectNode.replace(CKANPackage.TAGS_KEY, tagsArrayOriginal);
obj.put(CKANPackage.GROUPS_KEY, groupsArrayOriginal); objectNode.replace(CKANPackage.GROUPS_KEY, groupsArrayOriginal);
obj.put(CKANPackage.EXTRAS_KEY, extrasArrayUpdated); objectNode.replace(CKANPackage.EXTRAS_KEY, extrasArrayUpdated);
return objectNode;
} }
} }
@ -262,10 +246,10 @@ public class Validator {
* @throws Exception * @throws Exception
*/ */
private static List<CustomField> validateAgainstMetadataField(int metadataIndex, int categoryIndex, private static List<CustomField> validateAgainstMetadataField(int metadataIndex, int categoryIndex,
List<CustomField> customFields, JSONArray tagsArrayOriginal, JSONArray groupsArrayOriginal, List<CustomField> customFields, ArrayNode tagsArrayOriginal, ArrayNode groupsArrayOriginal,
MetadataField metadataField, List<NamespaceCategory> categories, MetadataField metadataField, List<NamespaceCategory> categories,
Map<String,Integer> fieldsMandatoryLowerBoundMap, Map<String,Integer> fieldsMandatoryUpperBoundMap, Map<String,Integer> fieldsMandatoryLowerBoundMap, Map<String,Integer> fieldsMandatoryUpperBoundMap,
Map<String,Integer> numberFieldsMandatorySameKeyMap, List<String> groupToCreate) throws Exception { Map<String,Integer> numberFieldsMandatorySameKeyMap, List<String> groupToCreate, ObjectMapper mapper) throws Exception {
List<CustomField> toReturn = new ArrayList<CustomField>(); List<CustomField> toReturn = new ArrayList<CustomField>();
String metadataFieldName = metadataField.getCategoryFieldQName(); // get the qualified one, if any String metadataFieldName = metadataField.getCategoryFieldQName(); // get the qualified one, if any
@ -279,8 +263,8 @@ public class Validator {
fieldsFoundWithThisKey++; fieldsFoundWithThisKey++;
cf.setIndexCategory(categoryIndex); cf.setIndexCategory(categoryIndex);
cf.setIndexMetadataField(metadataIndex); cf.setIndexMetadataField(metadataIndex);
checkAsGroup(cf, metadataField, groupsArrayOriginal, groupToCreate); checkAsGroup(cf, metadataField, groupsArrayOriginal, groupToCreate, mapper);
checkAsTag(cf, metadataField, tagsArrayOriginal); checkAsTag(cf, metadataField, tagsArrayOriginal, mapper);
toReturn.add(cf); toReturn.add(cf);
iterator.remove(); iterator.remove();
} }
@ -331,7 +315,7 @@ public class Validator {
* @param tagsArrayOriginal * @param tagsArrayOriginal
*/ */
private static void checkAsTag(CustomField fieldToValidate, MetadataField metadataField, private static void checkAsTag(CustomField fieldToValidate, MetadataField metadataField,
JSONArray tagsArrayOriginal) { ArrayNode tagsArrayOriginal, ObjectMapper mapper) {
MetadataTagging tagging = metadataField.getTagging(); MetadataTagging tagging = metadataField.getTagging();
if(tagging != null) { if(tagging != null) {
@ -357,7 +341,7 @@ public class Validator {
tag = tag.substring(0, MAX_TAG_CHARS > tag.length() ? tag.length() : MAX_TAG_CHARS); tag = tag.substring(0, MAX_TAG_CHARS > tag.length() ? tag.length() : MAX_TAG_CHARS);
logger.debug("Tag is " + tag); logger.debug("Tag is " + tag);
JSONObject tagJSON = new JSONObject(); ObjectNode tagJSON = mapper.createObjectNode();
tagJSON.put("name", tag); tagJSON.put("name", tag);
tagJSON.put("display_name", tag); tagJSON.put("display_name", tag);
tagsArrayOriginal.add(tagJSON); tagsArrayOriginal.add(tagJSON);
@ -375,7 +359,7 @@ public class Validator {
* @throws Exception * @throws Exception
*/ */
private static void checkAsGroup(CustomField fieldToValidate, MetadataField metadataField, private static void checkAsGroup(CustomField fieldToValidate, MetadataField metadataField,
JSONArray groupsArrayOriginal, List<String> groupToCreate) throws Exception { ArrayNode groupsArrayOriginal, List<String> groupToCreate, ObjectMapper mapper) throws Exception {
logger.debug("Custom field is " + fieldToValidate); logger.debug("Custom field is " + fieldToValidate);
logger.debug("MetadataField field is " + metadataField); logger.debug("MetadataField field is " + metadataField);
@ -407,13 +391,13 @@ public class Validator {
for(String title : groupNames) { for(String title : groupNames) {
logger.debug("Adding group to which add this item " + CatalogueUtilMethods.fromGroupTitleToName(title)); logger.debug("Adding group to which add this item " + CatalogueUtilMethods.fromGroupTitleToName(title));
JSONObject group = new JSONObject(); ObjectNode group = mapper.createObjectNode();
group.put("name", CatalogueUtilMethods.fromGroupTitleToName(title)); group.put("name", CatalogueUtilMethods.fromGroupTitleToName(title));
if(propagateUp) { if(propagateUp) {
List<String> parents = Validator List<String> parents = Validator
.getGroupHierarchyNames(CatalogueUtilMethods.fromGroupTitleToName(title)); .getGroupHierarchyNames(CatalogueUtilMethods.fromGroupTitleToName(title));
for(String parent : parents) { for(String parent : parents) {
JSONObject groupP = new JSONObject(); ObjectNode groupP = mapper.createObjectNode();
groupP.put("name", parent); groupP.put("name", parent);
groupsArrayOriginal.add(groupP); groupsArrayOriginal.add(groupP);
} }

View File

@ -200,7 +200,7 @@ public class CKANPackage extends CKAN {
// Validating against profiles if any // Validating against profiles if any
MetadataUtility metadataUtility = MetadataUtility.getInstance(); MetadataUtility metadataUtility = MetadataUtility.getInstance();
if(!metadataUtility.getMetadataProfiles().isEmpty()) { if(!metadataUtility.getMetadataProfiles().isEmpty()) {
Validator.validateAgainstProfile(getAsString(objectNode)); objectNode = Validator.validateAgainstProfile(mapper, objectNode);
} }
return objectNode; return objectNode;

View File

@ -129,7 +129,6 @@ public class CKANPackageTest extends ContextTest {
@Test @Test
public void create() throws Exception { public void create() throws Exception {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
createPackage(mapper); createPackage(mapper);
} }