diff --git a/.classpath b/.classpath index b02fd49..1a6a60d 100644 --- a/.classpath +++ b/.classpath @@ -1,6 +1,6 @@ - + @@ -17,20 +17,20 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component index bdc40f7..0190c48 100644 --- a/.settings/org.eclipse.wst.common.component +++ b/.settings/org.eclipse.wst.common.component @@ -5,7 +5,6 @@ - diff --git a/pom.xml b/pom.xml index ee852ba..f5feff9 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ org.gcube.portlets.widgets ckan-metadata-publisher-widget - 1.2.3-SNAPSHOT + 1.3.0-SNAPSHOT gCube Ckan metadata publisher widget @@ -55,6 +55,11 @@ + + + + + com.google.gwt gwt-servlet diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/CKanMetadataPublisher.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/CKanMetadataPublisher.java index f0a3493..bf628be 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/CKanMetadataPublisher.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/CKanMetadataPublisher.java @@ -196,7 +196,7 @@ public class CKanMetadataPublisher implements EntryPoint { for (MetaDataFieldSkeleton field : widgetsList) { String error = field.isFieldValueValid(); if(error != null) - Window.alert(field.getFieldName() + " is not valid. Suggestion: " + error); + Window.alert(field.getFieldNameOriginal() + " is not valid. Suggestion: " + error); else Window.alert("No ERROR: " + field.getFieldCurrentValue()); @@ -222,7 +222,7 @@ public class CKanMetadataPublisher implements EntryPoint { private void startExample() { String idFolderWorkspace = "1fede4e2-5859-4f19-bddb-aec7dd5b632f"; - RootPanel.get("ckan-metadata-publisher-div").add(new CreateDatasetForm(idFolderWorkspace, eventBus)); + RootPanel.get("ckan-metadata-publisher-div").add(new CreateDatasetForm(eventBus)); } diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/CKanPublisherService.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/CKanPublisherService.java index 2693583..f9d42e4 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/CKanPublisherService.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/CKanPublisherService.java @@ -29,14 +29,15 @@ public interface CKanPublisherService extends RemoteService { * Retrieve the list of profiles for a given organization name . * @return a List on success, null on error. */ - List getProfiles(String orgName); + List getProfiles(String orgName) throws Exception; /** * Retrieve a partially filled bean given a folder id/file id and its owner. * @param folderIdOrFileId the id of the folder of file to publish * @return @return a DatasetMetadataBean on success, null on error. + * @throws Exception */ - DatasetBean getDatasetBean(String folderIdOrFileId); + DatasetBean getDatasetBean(String folderIdOrFileId) throws Exception; /** * Try to create such dataset starting from the information contained into the toCreate bean. @@ -57,16 +58,18 @@ public interface CKanPublisherService extends RemoteService { * @param resource * @param datasetId * @return true on success, false otherwise + * @throws Exception */ - boolean deleteResourceFromDataset(ResourceElementBean resource); + boolean deleteResourceFromDataset(ResourceElementBean resource) throws Exception; /** * Given the title the user wants to give to the new product to create, a check is performed * to understand if a dataset with the proposed title (and so the id generated at server side) already exists * @param title * @return true if it exists, false otherwise + * @throws Exception */ - boolean datasetIdAlreadyExists(String title, String orgName); + boolean datasetIdAlreadyExists(String title, String orgName) throws Exception; /** * Retrieve the list of groups the user can choose to associate this product with. @@ -79,15 +82,17 @@ public interface CKanPublisherService extends RemoteService { /** * The method checks if the user is a publisher or he/she doesn't have the rights to publish * @return true if he/she can publish, false otherwise + * @throws Exception */ - boolean isPublisherUser(boolean isWorkspaceRequest); + boolean isPublisherUser(boolean isWorkspaceRequest) throws Exception; /** * Get the list of vocabulary tags for this scope * @param orgName * @return + * @throws Exception */ - List getTagsForOrganization(String orgName); + List getTagsForOrganization(String orgName) throws Exception; /** * Validate a geo json field diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/form/CreateDatasetForm.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/form/CreateDatasetForm.java index 7d235d6..a2a9bd0 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/form/CreateDatasetForm.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/form/CreateDatasetForm.java @@ -294,7 +294,7 @@ public class CreateDatasetForm extends Composite{ @Override public void onFailure(Throwable caught) { - setAlertBlock("Error while retrieving information", AlertType.ERROR, true); + setAlertBlock(caught.getMessage(), AlertType.ERROR, true); } @@ -303,7 +303,7 @@ public class CreateDatasetForm extends Composite{ if(bean == null){ - setAlertBlock("Error while retrieving information", AlertType.ERROR, true); + setAlertBlock("Error while retrieving information.", AlertType.ERROR, true); } else{ @@ -324,12 +324,9 @@ public class CreateDatasetForm extends Composite{ List vocabularyTags = bean.getTagsVocabulary(); // vocabulary list of tags has preemption - if(vocabularyTags != null && !vocabularyTags.isEmpty()){ + tagsPanel.setVocabulary(vocabularyTags); - tagsPanel.setVocabulary(vocabularyTags); - - } - else if(customFieldsMap != null){ + if(customFieldsMap != null){ // get the keys and put them as tags Iterator>> iteratorOverCustomField = customFieldsMap.entrySet().iterator(); @@ -391,19 +388,42 @@ public class CreateDatasetForm extends Composite{ // get the name of the organization from the title final String orgName = nameTitleOrganizationMap.get(organizationsListbox.getSelectedItemText()); + // force tags + setAlertBlock("Checking for tags vocabulary, please wait...", AlertType.INFO, true); + ckanServices.getTagsForOrganization(orgName, new AsyncCallback>() { + + @Override + public void onSuccess(List vocabulary) { + + tagsPanel.setVocabulary(vocabulary); + tagsPanel.setVisible(true); + setAlertBlock("", AlertType.ERROR, false); + } + + @Override + public void onFailure(Throwable arg0) { + + setAlertBlock("Error while checking if a vocabulary of tags is defined in the selected organization.", AlertType.ERROR, true); + tagsPanel.setVocabulary(null); + tagsPanel.setVisible(true); + + } + }); + + // perform remote request of profiles for the selected organization ckanServices.getProfiles(orgName, new AsyncCallback>() { @Override public void onFailure(Throwable caught) { - setAlertBlock("Error while retrieving types, retry later", AlertType.ERROR, true); + setAlertBlock(caught.getMessage(), AlertType.ERROR, true); } @Override public void onSuccess(final List profiles) { if(profiles == null){ - setAlertBlock("Error while retrieving types, retry later", AlertType.ERROR, true); + setAlertBlock("An unknow error occurred while retrieving types, sorry", AlertType.ERROR, true); } else{ @@ -418,7 +438,7 @@ public class CreateDatasetForm extends Composite{ @Override public void onFailure(Throwable caught){ - setAlertBlock("Error while retrieving licenses, try later", AlertType.ERROR, true); + setAlertBlock(caught.getMessage(), AlertType.ERROR, true); } @Override @@ -467,7 +487,7 @@ public class CreateDatasetForm extends Composite{ @Override public void onFailure(Throwable caught) { - setAlertBlock("Error while retrieving groups, try later", AlertType.ERROR, true); + setAlertBlock(caught.getMessage(), AlertType.ERROR, true); } }); @@ -578,6 +598,7 @@ public class CreateDatasetForm extends Composite{ // check also for tags (if for that context there is a vocabulary or not) tagsPanel.setVisible(false); + setAlertBlock("Checking for tags vocabulary, please wait...", AlertType.INFO, true); ckanServices.getTagsForOrganization(orgName, new AsyncCallback>() { @Override @@ -585,12 +606,14 @@ public class CreateDatasetForm extends Composite{ tagsPanel.setVocabulary(vocabulary); tagsPanel.setVisible(true); + setAlertBlock("", AlertType.ERROR, false); } @Override public void onFailure(Throwable arg0) { setAlertBlock("Error while checking if a vocabulary of tags is defined in the selected organization.", AlertType.ERROR, true); + tagsPanel.setVocabulary(null); tagsPanel.setVisible(true); } @@ -685,6 +708,8 @@ public class CreateDatasetForm extends Composite{ List fields = bean.getMetadataFields(); List categories = bean.getCategories(); + GWT.log("There are " + categories.size() + " categories for profile " + bean.getTitle()); + if(categories == null || categories.isEmpty()){ for (MetadataFieldWrapper field : fields) { MetaDataFieldSkeleton fieldWidget; @@ -700,42 +725,45 @@ public class CreateDatasetForm extends Composite{ // create the categories, then parse the fields. Fields do not belonging to a category are put at the end for (CategoryWrapper categoryWrapper : categories) { - CategoryPanel cp = new CategoryPanel(categoryWrapper.getTitle(), categoryWrapper.getDescription()); - List fieldsForThisCategory = categoryWrapper.getFieldsForThisCategory(); - fields.removeAll(fieldsForThisCategory); - - for (MetadataFieldWrapper metadataFieldWrapper : fieldsForThisCategory) { - MetaDataFieldSkeleton fieldWidget; - try { - fieldWidget = new MetaDataFieldSkeleton(metadataFieldWrapper, eventBus); - cp.addField(fieldWidget); - listOfMetadataFields.add(fieldWidget); - } catch (Exception e) { - GWT.log("Unable to build such widget", e); + if(categoryWrapper.getFieldsForThisCategory() != null && categoryWrapper.getFieldsForThisCategory().size() > 0){ + CategoryPanel cp = new CategoryPanel(categoryWrapper.getTitle(), categoryWrapper.getDescription()); + List fieldsForThisCategory = categoryWrapper.getFieldsForThisCategory(); + fields.removeAll(fieldsForThisCategory); + + for (MetadataFieldWrapper metadataFieldWrapper : fieldsForThisCategory) { + MetaDataFieldSkeleton fieldWidget; + try { + fieldWidget = new MetaDataFieldSkeleton(metadataFieldWrapper, eventBus); + cp.addField(fieldWidget); + listOfMetadataFields.add(fieldWidget); + } catch (Exception e) { + GWT.log("Unable to build such widget", e); + } } + metadataFieldsPanel.add(cp); } - - metadataFieldsPanel.add(cp); } - - // add the remaining one at the end of the categories TODO + + // add the remaining one at the end of the categories + CategoryPanel extrasCategory = new CategoryPanel("Other", null); for (MetadataFieldWrapper field : fields) { MetaDataFieldSkeleton fieldWidget; try { fieldWidget = new MetaDataFieldSkeleton(field, eventBus); - metadataFieldsPanel.add(fieldWidget); + extrasCategory.addField(fieldWidget); listOfMetadataFields.add(fieldWidget); } catch (Exception e) { GWT.log("Unable to build such widget", e); } } + metadataFieldsPanel.add(extrasCategory); } - metadataFieldsPanel.setVisible(true); } } } + @UiHandler("addCustomFieldButton") void addCustomFieldEvent(ClickEvent e){ @@ -887,6 +915,7 @@ public class CreateDatasetForm extends Composite{ } List groups = new ArrayList(); + List groupsToForceCreation = new ArrayList(); // get groups, if any int items = groupsListbox.getItemCount(); @@ -902,11 +931,9 @@ public class CreateDatasetForm extends Composite{ // prepare custom fields for (MetaDataFieldSkeleton field : listOfMetadataFields) { - String value = field.getFieldCurrentValue(); - if(!value.isEmpty()){ - String key = field.getFieldName(); + String key = field.getFieldNameQualified(); List valuesForThisField = null; if(customFieldsMap.containsKey(key)) valuesForThisField = customFieldsMap.get(key); @@ -915,34 +942,32 @@ public class CreateDatasetForm extends Composite{ valuesForThisField.add(value); customFieldsMap.put(key, valuesForThisField); - + // get also tag/group if it is the case for this field String tag = field.getTagFromThisField(); if(tag != null) tags.add(tag); - - String groupTitle = field.getGroupTitleFromThisGroup(); - if(groupTitle != null) - groups.add(new OrganizationBean(groupTitle, groupTitle, false)); - - } + String groupTitle = field.getGroupTitleFromThisGroup(); + if(groupTitle != null){ + if(field.isGroupToForce()) + groupsToForceCreation.add(new OrganizationBean(groupTitle, groupTitle, false)); + else + groups.add(new OrganizationBean(groupTitle, groupTitle, false)); + } + } } for(CustomFieldEntry customEntry : customFieldEntriesList){ - String key = customEntry.getKey(); String value = customEntry.getValue(); - if(value != null && !value.isEmpty()){ List valuesForThisField = null; if(customFieldsMap.containsKey(key)) valuesForThisField = customFieldsMap.get(key); else valuesForThisField = new ArrayList(); - valuesForThisField.add(value); - customFieldsMap.put(key, valuesForThisField); } @@ -961,6 +986,7 @@ public class CreateDatasetForm extends Composite{ receivedBean.setTags(new ArrayList(tags)); receivedBean.setSelectedOrganization(chosenOrganization); receivedBean.setGroups(groups); + receivedBean.setGroupsForceCreation(groupsToForceCreation); if(resourcesTwinPanel != null) receivedBean.setResourceRoot(resourcesTwinPanel.getResourcesToPublish()); receivedBean.setCustomFields(customFieldsMap); @@ -1227,7 +1253,7 @@ public class CreateDatasetForm extends Composite{ String error = field.isFieldValueValid(); if(error != null){ field.showError(); - return field.getFieldName() + " is not valid. Suggestion: " + error; + return field.getFieldNameOriginal() + " is not valid. Suggestion: " + error; } } diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/metadata/CategoryPanel.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/metadata/CategoryPanel.java index 3552e69..1df7fed 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/metadata/CategoryPanel.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/metadata/CategoryPanel.java @@ -5,6 +5,7 @@ import java.util.List; import com.github.gwtbootstrap.client.ui.PageHeader; import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.Style.Float; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; @@ -35,8 +36,12 @@ public class CategoryPanel extends Composite{ */ public CategoryPanel(String title, String description) { initWidget(uiBinder.createAndBindUi(this)); + title = title == null ? "" : title; + description = description == null ? "" : description; categoryHeader.setTitle(title); + categoryHeader.setText(title); categoryHeader.setSubtext(description); + categoryHeader.getElement().getStyle().setFloat(Float.LEFT); } /** @@ -47,6 +52,7 @@ public class CategoryPanel extends Composite{ if(fieldsForThisCategory == null){ fieldsForThisCategory = new ArrayList(); fieldWidget.setVisible(true); + fieldsPanel.setVisible(true); } fieldsForThisCategory.add(fieldWidget); fieldsPanel.add(fieldWidget); diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/metadata/CategoryPanel.ui.xml b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/metadata/CategoryPanel.ui.xml index 68e9845..585adfe 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/metadata/CategoryPanel.ui.xml +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/metadata/CategoryPanel.ui.xml @@ -2,7 +2,7 @@ - + vocabularyTags) { + tagsEnterListBox.clear(); + tagsPanel.clear(); + tagsList.clear(); + + GWT.log("Vocabulary of tags is " + vocabularyTags); + if(vocabularyTags == null || vocabularyTags.isEmpty()){ tagsEnterListBox.setVisible(false); tagsPanel.setVisible(true); @@ -83,9 +89,6 @@ public class TagsPanel extends Composite{ tagsEnterTextBox.setVisible(false); tagsEnterListBox.setVisible(true); } - - tagsPanel.clear(); - tagsList.clear(); } /** diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/CKANPublisherServicesImpl.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/CKANPublisherServicesImpl.java index 142ddcd..d36b015 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/CKANPublisherServicesImpl.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/CKANPublisherServicesImpl.java @@ -179,7 +179,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C } @Override - public DatasetBean getDatasetBean(String folderId){ + public DatasetBean getDatasetBean(String folderId) throws Exception{ DatasetBean bean = null; String userName = GenericUtils.getCurrentUser(getThreadLocalRequest()).getUsername(); @@ -220,7 +220,8 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C } }catch(Exception e){ - logger.error("Error while retrieving folder information", e); + logger.error("Error while retrieving bean information", e); + throw new Exception("Error while retrieving basic information " + e.getMessage()); } }else{ @@ -239,8 +240,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C bean.setAuthorEmail("costantino.perciante@isti.cnr.it"); bean.setMaintainer("Costantino Perciante"); bean.setMaintainerEmail("costantino.perciante@isti.cnr.it"); - //bean.setOrganizationList(getUserOrganizationsListAdmin(userName, Utils.getCurrentContext(getThreadLocalRequest(), true))); - bean.setOrganizationList(Arrays.asList(new OrganizationBean("preVRE", "prevre", true))); + bean.setOrganizationList(Arrays.asList(new OrganizationBean("NextNext", "nextnext", true))); bean.setOwnerIdentifier(userName); if(folderId != null && !folderId.isEmpty()){ @@ -248,6 +248,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C } }catch(Exception e){ logger.error("Error while building bean into dev mode", e); + throw new Exception("Error while retrieving basic information " + e.getMessage()); } } @@ -258,8 +259,9 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C /** * Discover from the IS the vocabulary of tags for this scope, if present * @return a list of tags vocabulary + * @throws Exception */ - private List discoverTagsVocabulary(String context) { + private List discoverTagsVocabulary(String context){ logger.debug("Looking for vocabulary of tags in this context " + context); String keyPerVocabulary = UtilMethods.concatenateSessionKeyScope(TAGS_VOCABULARY_KEY, context); @@ -267,7 +269,8 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C List vocabulary = (List) getThreadLocalRequest().getSession().getAttribute(keyPerVocabulary); if(vocabulary == null){ vocabulary = DiscoverTagsList.discoverTagsList(context); - getThreadLocalRequest().getSession().setAttribute(keyPerVocabulary, vocabulary); + if(vocabulary != null) + getThreadLocalRequest().getSession().setAttribute(keyPerVocabulary, vocabulary); } logger.debug("Vocabulary for tags is " + vocabulary); @@ -276,7 +279,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C } @Override - public List getTagsForOrganization(String orgName) { + public List getTagsForOrganization(String orgName) throws Exception{ return discoverTagsVocabulary(getScopeFromOrgName(orgName)); } @@ -343,6 +346,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C AssociationToGroupAndNotifyThread threadAssociationToGroup = new AssociationToGroupAndNotifyThread( toCreate.getGroups(), + toCreate.getGroupsForceCreation(), null, //toCreate.getChosenType(), TODO datasetUrl, datasetId, @@ -377,7 +381,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C }catch(Exception e){ logger.error("Error while creating item ", e); - throw new Exception(e.getMessage()); + throw new Exception("An error occurred while creating the item " + e.getMessage()); } return null; @@ -426,7 +430,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C } @Override - public boolean deleteResourceFromDataset(ResourceElementBean resource) { + public boolean deleteResourceFromDataset(ResourceElementBean resource) throws Exception{ logger.debug("Request for deleting resource " + resource); boolean deleted = false; @@ -449,14 +453,14 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C logger.error("Resource described by " + resource + " NOT deleted"); }catch(Exception e){ logger.error("Error while trying to delete resource described by " + resource, e); + throw new Exception("Error while trying to delete resource." + e.getMessage()); } return deleted; - } } @Override - public List getProfiles(String orgName) { + public List getProfiles(String orgName) throws Exception{ logger.debug("Requested profiles for products into orgName " + orgName); List toReturn = new ArrayList(); @@ -466,23 +470,25 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C toReturn = MetadataDiscovery.getMetadataProfilesList(evaluatedScope, getThreadLocalRequest()); }catch(Exception e){ logger.error("Failed to retrieve profiles for scope coming from organization name " + orgName, e); + throw e; } return toReturn; } @Override - public boolean datasetIdAlreadyExists(String title, String orgName) { + public boolean datasetIdAlreadyExists(String title, String orgName) throws Exception{ if(title == null || title.isEmpty()) return true; // it's an error somehow try{ String scopeFromOrgName = getScopeFromOrgName(orgName); String idFromTitle = UtilMethods.fromProductTitleToName(title); + logger.debug("Evaluating if dataset with id " + title + " in context " + scopeFromOrgName + " already exists"); return getCatalogue(scopeFromOrgName).existProductWithNameOrId(idFromTitle); }catch(Exception e){ logger.error("Unable to check if such a dataset id already exists", e); + throw new Exception("Unable to check if such a dataset id already exists " + e.getMessage()); } - return false; } /** @@ -510,7 +516,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C } } }else{ - toReturn = "/gcube/preprod/preVRE"; + toReturn = "/gcube/devNext/NextNext"; mapOrganizationScope.put(orgName, toReturn); } logger.debug("Returning scope " + toReturn); @@ -560,7 +566,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C @Override - public boolean isPublisherUser(boolean isWorkspaceRequest) { + public boolean isPublisherUser(boolean isWorkspaceRequest) throws Exception{ String username = GenericUtils.getCurrentUser(getThreadLocalRequest()).getUsername(); logger.info("Checking if the user " + username + " can publish or not on the catalogue"); @@ -621,10 +627,8 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C }catch(Exception e){ logger.error("Failed to check the user's role", e); + throw new Exception("Failed to check if you are an Administrator or Editor " + e.getMessage()); } - - // return false - return false; } @Override diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/threads/AssociationToGroupAndNotifyThread.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/threads/AssociationToGroupAndNotifyThread.java index c885322..267124a 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/threads/AssociationToGroupAndNotifyThread.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/threads/AssociationToGroupAndNotifyThread.java @@ -39,10 +39,11 @@ public class AssociationToGroupAndNotifyThread extends Thread { private String datasetTitle; private String userFullName; private DataCatalogue catalogue; - private String organization; + // private String organization; private List groups; private HttpServletRequest request; private String datasetUrl; + private List groupsForceCreation; /** * @param list @@ -51,15 +52,16 @@ public class AssociationToGroupAndNotifyThread extends Thread { * @param username * @param catalogue */ - public AssociationToGroupAndNotifyThread(List groups, String groupTitle, String datasetUrl, String datasetId, String datasetTitle, String userFullName, + public AssociationToGroupAndNotifyThread(List groups, List groupsForceCreation, String groupTitle, String datasetUrl, String datasetId, String datasetTitle, String userFullName, String username, DataCatalogue catalogue, String organization, HttpServletRequest request) { this.request = request; - this.groups = groups; + this.groups = groups == null ? new ArrayList() : groups; + this.groupsForceCreation = groupsForceCreation; this.groupTitle = groupTitle; this.datasetId = datasetId; this.username = username; this.catalogue = catalogue; - this.organization = organization; + // this.organization = organization; this.datasetTitle = datasetTitle; this.userFullName = userFullName; this.datasetUrl = datasetUrl; @@ -70,44 +72,58 @@ public class AssociationToGroupAndNotifyThread extends Thread { logger.info("Association thread started to put the dataset with id = "+ datasetId + " into group with title " + groupTitle + " for user " + username); - if(groupTitle != null){ - try{ + // if(groupTitle != null){ + // try{ + // + // // create the group + // CkanGroup group = catalogue.createGroup(groupTitle, groupTitle, ""); + // + // if(group == null){ + // + // logger.warn("The group doesn't exist! Unable to perform such association"); + // + // }else{ + // + // logger.debug("Group exists, going to add the user " + username + " as its admin..."); + // + // // retrieve the role to be assigned according the one the user has into the organization of the dataset + // RolesCkanGroupOrOrg role = RolesCkanGroupOrOrg.valueOf(catalogue.getRoleOfUserInOrganization(username, organization, catalogue.getApiKeyFromUsername(username)).toUpperCase()); + // + // if(!role.equals(RolesCkanGroupOrOrg.ADMIN)) + // role = RolesCkanGroupOrOrg.MEMBER; // decrease the role to member if it is not an admin + // + // boolean assigned = catalogue.checkRoleIntoGroup(username, groupTitle, role); + // + // if(assigned){ + // + // logger.debug("Admin/editor role was assigned for this group, going to associate the product to the group"); + // boolean putIntoGroup = catalogue.assignDatasetToGroup(groupTitle, datasetId, catalogue.getApiKeyFromUsername(username)); + // logger.info("Was product put into group? " + putIntoGroup); + // + // if(putIntoGroup) + // notifyGroupAdmins(catalogue, group.getName(), group.getTitle(), username); + // + // } + // } + // + // }catch(Exception e){ + // logger.warn("Something went wrong when tried to add the group " + groupTitle, e); + // } + // } - // create the group - CkanGroup group = catalogue.createGroup(groupTitle, groupTitle, ""); - - if(group == null){ - - logger.warn("The group doesn't exist! Unable to perform such association"); - - }else{ - - logger.debug("Group exists, going to add the user " + username + " as its admin..."); - - // retrieve the role to be assigned according the one the user has into the organization of the dataset - RolesCkanGroupOrOrg role = RolesCkanGroupOrOrg.valueOf(catalogue.getRoleOfUserInOrganization(username, organization, catalogue.getApiKeyFromUsername(username)).toUpperCase()); - - if(!role.equals(RolesCkanGroupOrOrg.ADMIN)) - role = RolesCkanGroupOrOrg.MEMBER; // decrease the role to member if it is not an admin - - boolean assigned = catalogue.checkRoleIntoGroup(username, groupTitle, role); - - if(assigned){ - - logger.debug("Admin/editor role was assigned for this group, going to associate the product to the group"); - boolean putIntoGroup = catalogue.assignDatasetToGroup(groupTitle, datasetId, catalogue.getApiKeyFromUsername(username)); - logger.info("Was product put into group? " + putIntoGroup); - - if(putIntoGroup) - notifyGroupAdmins(catalogue, group.getName(), group.getTitle(), username); - - } - } - - }catch(Exception e){ - logger.warn("Something went wrong when tried to add the group " + groupTitle, e); + // force creation of groups if needed + if(groupsForceCreation != null){ + logger.info("Groups that must be created before association are " + groupsForceCreation); + for (OrganizationBean groupToForce : groupsForceCreation) { + CkanGroup group = catalogue.createGroup(groupToForce.getName(), groupToForce.getTitle(), ""); + if(group == null) + logger.warn("Unable to retrieve or create group with name " + group); + else + groups.add(new OrganizationBean(group.getTitle(), group.getName(), false)); } + } + logger.info("Other groups to which the product should be associate are " + groups); if(groups != null) diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/DiscoverTagsList.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/DiscoverTagsList.java index 3ebb2dd..7dc66f2 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/DiscoverTagsList.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/DiscoverTagsList.java @@ -37,8 +37,9 @@ public class DiscoverTagsList { /** * Discover the list of tags vocabulary if needed + * @throws Exception */ - public static List discoverTagsList(String context) { + public static List discoverTagsList(String context){ if(context == null || context.isEmpty()) throw new IllegalArgumentException("Context cannot be empty or null!"); @@ -58,7 +59,6 @@ public class DiscoverTagsList { XPathHelper helper = new XPathHelper(node); List tagsVocabulary = helper.evaluate("/Resource/Profile/Body/tags/tag/text()"); logger.debug("Retrieved tags " + tagsVocabulary); - return tagsVocabulary; } }catch(Exception e){ @@ -66,7 +66,7 @@ public class DiscoverTagsList { }finally{ ScopeProvider.instance.set(currentContext); } - + return null; } diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/MetadataDiscovery.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/MetadataDiscovery.java index 3f3fbb2..123bad7 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/MetadataDiscovery.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/MetadataDiscovery.java @@ -2,6 +2,7 @@ package org.gcube.portlets.widgets.ckandatapublisherwidget.server.utils; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -13,13 +14,13 @@ import org.gcube.datacatalogue.ckanutillibrary.server.utils.SessionCatalogueAttr import org.gcube.datacatalogue.ckanutillibrary.server.utils.UtilMethods; import org.gcube.datacatalogue.metadatadiscovery.DataCalogueMetadataFormatReader; import org.gcube.datacatalogue.metadatadiscovery.bean.MetadataProfile; -import org.gcube.datacatalogue.metadatadiscovery.bean.jaxb.MetadataCategory; import org.gcube.datacatalogue.metadatadiscovery.bean.jaxb.MetadataField; import org.gcube.datacatalogue.metadatadiscovery.bean.jaxb.MetadataFormat; import org.gcube.datacatalogue.metadatadiscovery.bean.jaxb.MetadataGrouping; import org.gcube.datacatalogue.metadatadiscovery.bean.jaxb.MetadataTagging; import org.gcube.datacatalogue.metadatadiscovery.bean.jaxb.MetadataValidator; import org.gcube.datacatalogue.metadatadiscovery.bean.jaxb.MetadataVocabulary; +import org.gcube.datacatalogue.metadatadiscovery.bean.jaxb.NamespaceCategory; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.metadata.CategoryWrapper; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.metadata.DataTypeWrapper; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.metadata.FieldAsGroup; @@ -112,7 +113,7 @@ public class MetadataDiscovery { * @return */ @SuppressWarnings("unchecked") - public static List getMetadataProfilesList(String scope, HttpServletRequest request) { + public static List getMetadataProfilesList(String scope, HttpServletRequest request) throws Exception{ List beans = new ArrayList(); String username = GenericUtils.getCurrentUser(request).getUsername(); @@ -139,23 +140,34 @@ public class MetadataDiscovery { ScopeProvider.instance.set(scopeInWhichDiscover); + // TODO two reset methods could be added to force the reader to read again these information (after a while) DataCalogueMetadataFormatReader reader = new DataCalogueMetadataFormatReader(); + List profiles = reader.getListOfMetadataProfiles(); + logger.debug("Profiles are " + profiles); + + List categories = reader.getListOfNamespaceCategories(); + if(categories == null) + categories = new ArrayList(); + + logger.debug("All Categories are " + categories); for (MetadataProfile profile : profiles) { + + logger.debug("Wrapping profile with name " + profile.getName() + " and type " + profile.getMetadataType()); + MetadataFormat metadata = reader.getMetadataFormatForMetadataProfile(profile); - String type = metadata.getMetadataType(); + String type = metadata.getType(); String title = profile.getName(); - List categories = metadata.getMetadataCategories(); List fields = metadata.getMetadataFields(); - // we need to wrap the list of metadata + // we need to wrap the list of metadata and categories List fieldsWrapper = new ArrayList(fields != null ? fields.size() : 0); - List categoriesWrapper = new ArrayList(categories != null ? categories.size() : 0); - Map idToCategory = new HashMap(categoriesWrapper.size()); + List categoriesWrapper = new ArrayList(categories.size()); + Map idToCategory = new HashMap(categories.size()); // manage the categories - for (MetadataCategory category : categories) { + for (NamespaceCategory category : categories) { CategoryWrapper categoryWrapped = new CategoryWrapper(category.getId(), category.getTitle(), category.getDescription()); categoriesWrapper.add(categoryWrapped); idToCategory.put(category.getId(), categoryWrapped); @@ -173,7 +185,6 @@ public class MetadataDiscovery { wrapperObj.setDefaultValue(metadataField.getDefaultValue()); wrapperObj.setFieldName(metadataField.getFieldName()); wrapperObj.setMandatory(metadataField.getMandatory()); - metadataField.getNamespaceFieldToCategoryReference(); wrapperObj.setNote(metadataField.getNote()); MetadataValidator validator = metadataField.getValidator(); if(validator != null) @@ -201,7 +212,7 @@ public class MetadataDiscovery { if(grouping != null){ FieldAsGroup group = new FieldAsGroup(); - group.setCreate(group.getCreate()); + group.setCreate(grouping.getCreate()); group.setGroupingValue(TaggingGroupingValue.valueOf(grouping.getGroupingValue().toString())); wrapperObj.setAsGroup(group); @@ -209,35 +220,50 @@ public class MetadataDiscovery { // set to which category this field belongs to and vice-versa if(metadataField.getCategoryRef() != null){ - CategoryWrapper ownerCategory = idToCategory.get(metadataField.getCategoryRef()); - wrapperObj.setOwnerCategory(ownerCategory); - - List fieldsPerCategoryN = fieldsPerCategory.get(metadataField.getCategoryRef()); - if(fieldsPerCategoryN == null) - fieldsPerCategoryN = new ArrayList(); - - fieldsPerCategoryN.add(wrapperObj); - fieldsPerCategory.put(metadataField.getCategoryRef(), fieldsPerCategoryN); - - // instead of re-looping on the fieldsPerCategory map later, just set this potentially partial list - ownerCategory.setFieldsForThisCategory(fieldsPerCategoryN); + + if(ownerCategory == null){ + logger.warn("A field with categoryref " + metadataField.getCategoryRef() + " has been found, but" + + " such category is not defined within the namespaces"); + }else{ + + wrapperObj.setOwnerCategory(ownerCategory); + + List fieldsPerCategoryN = fieldsPerCategory.get(metadataField.getCategoryRef()); + if(fieldsPerCategoryN == null) + fieldsPerCategoryN = new ArrayList(); + + fieldsPerCategoryN.add(wrapperObj); + fieldsPerCategory.put(metadataField.getCategoryRef(), fieldsPerCategoryN); + + // instead of re-looping on the fieldsPerCategory map later, just set this potentially partial list + ownerCategory.setFieldsForThisCategory(fieldsPerCategoryN); + } } fieldsWrapper.add(wrapperObj); } - - + + // filter the categories without children here + Iterator categoryToRemoveIT = categoriesWrapper.iterator(); + while (categoryToRemoveIT.hasNext()) { + CategoryWrapper categoryWrapper = (CategoryWrapper) categoryToRemoveIT + .next(); + if(categoryWrapper.getFieldsForThisCategory() == null) + categoryToRemoveIT.remove(); + } + MetaDataProfileBean bean = new MetaDataProfileBean(type, title, fieldsWrapper, categoriesWrapper); beans.add(bean); } - logger.trace("List of beans is " + beans); + logger.debug("List of beans is " + beans); httpSession.setAttribute(keyPerScope, beans); logger.info("List of profiles has been saved into session"); } catch (Exception e) { logger.error("Error while retrieving metadata beans ", e); + throw new Exception("Failed to parse Types: " + e.getMessage()); }finally{ ScopeProvider.instance.set(oldScope); } @@ -246,5 +272,8 @@ public class MetadataDiscovery { return beans; } + // public static void main(String[] args) throws Exception { + // MetadataDiscovery.getMetadataProfilesList("/gcube/devsec/devVRE", null); + // } } diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/DatasetBean.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/DatasetBean.java index d29690f..bf14fae 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/DatasetBean.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/DatasetBean.java @@ -36,6 +36,7 @@ public class DatasetBean implements Serializable { private List tagsVocabulary; // when available private Map> customFields; private List groups; + private List groupsForceCreation; public DatasetBean(){ super(); @@ -278,22 +279,57 @@ public class DatasetBean implements Serializable { this.tagsVocabulary = tagsVocabulary; } + public List getGroupsForceCreation() { + return groupsForceCreation; + } + + public void setGroupsForceCreation(List groupsForceCreation) { + this.groupsForceCreation = groupsForceCreation; + } + @Override public String toString() { - return "DatasetMetadataBean [id=" + id + ", title=" + title - + ", description=" + description + ", license=" + license - + ", source=" + source + ", authorName=" + authorName - + ", authorSurname=" + authorSurname + ", authorFullName=" - + authorFullName + ", authorEmail=" + authorEmail - + ", maintainer=" + maintainer + ", maintainerEmail=" - + maintainerEmail + ", ownerIdentifier=" + ownerIdentifier - + ", chosenType=" + chosenType + ", selectedOrganization=" - + selectedOrganization + ", version=" + version - + ", visible=" + visible + ", organizationList=" - + organizationList + ", resourceRoot=" + resourceRoot - + ", metadataList=" + metadataList + ", tags=" + tags - + ", tagsVocabulary=" + tagsVocabulary + ", customFields=" - + customFields + ", groups=" + groups + "]"; + return "DatasetBean [" + + (id != null ? "id=" + id + ", " : "") + + (title != null ? "title=" + title + ", " : "") + + (description != null ? "description=" + description + ", " + : "") + + (license != null ? "license=" + license + ", " : "") + + (source != null ? "source=" + source + ", " : "") + + (authorName != null ? "authorName=" + authorName + ", " : "") + + (authorSurname != null ? "authorSurname=" + authorSurname + + ", " : "") + + (authorFullName != null ? "authorFullName=" + authorFullName + + ", " : "") + + (authorEmail != null ? "authorEmail=" + authorEmail + ", " + : "") + + (maintainer != null ? "maintainer=" + maintainer + ", " : "") + + (maintainerEmail != null ? "maintainerEmail=" + + maintainerEmail + ", " : "") + + (ownerIdentifier != null ? "ownerIdentifier=" + + ownerIdentifier + ", " : "") + + (chosenType != null ? "chosenType=" + chosenType + ", " : "") + + (selectedOrganization != null ? "selectedOrganization=" + + selectedOrganization + ", " : "") + + "version=" + + version + + ", visible=" + + visible + + ", " + + (organizationList != null ? "organizationList=" + + organizationList + ", " : "") + + (resourceRoot != null ? "resourceRoot=" + resourceRoot + ", " + : "") + + (metadataList != null ? "metadataList=" + metadataList + ", " + : "") + + (tags != null ? "tags=" + tags + ", " : "") + + (tagsVocabulary != null ? "tagsVocabulary=" + tagsVocabulary + + ", " : "") + + (customFields != null ? "customFields=" + customFields + ", " + : "") + + (groups != null ? "groups=" + groups + ", " : "") + + (groupsForceCreation != null ? "groupsForceCreation=" + + groupsForceCreation : "") + "]"; } } \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/metadata/CategoryWrapper.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/metadata/CategoryWrapper.java index 00c8fff..d82cb5e 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/metadata/CategoryWrapper.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/metadata/CategoryWrapper.java @@ -62,17 +62,14 @@ public class CategoryWrapper implements Serializable{ @Override public String toString() { - final int maxLen = 10; - return "CategoryWrapper [id=" - + id - + ", title=" - + title - + ", description=" - + description - + ", fieldsForThisCategory=" - + (fieldsForThisCategory != null ? fieldsForThisCategory - .subList(0, - Math.min(fieldsForThisCategory.size(), maxLen)) - : null) + "]"; + return "CategoryWrapper [" + + (id != null ? "id=" + id + ", " : "") + + (title != null ? "title=" + title + ", " : "") + + (description != null ? "description=" + description + ", " + : "") + + (fieldsForThisCategory != null ? "fieldsForThisCategory=" + + fieldsForThisCategory.size() : "") + "]"; } + + } diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/metadata/MetadataFieldWrapper.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/metadata/MetadataFieldWrapper.java index 8707490..db67788 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/metadata/MetadataFieldWrapper.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/metadata/MetadataFieldWrapper.java @@ -227,25 +227,24 @@ public class MetadataFieldWrapper implements Serializable{ @Override public String toString() { - final int maxLen = 10; - return "MetadataFieldWrapper [fieldName=" - + fieldName - + ", fieldNameFromCategory=" - + fieldNameFromCategory - + ", mandatory=" - + mandatory - + ", type=" - + type - + ", defaultValue=" - + defaultValue - + ", note=" - + note - + ", vocabulary=" - + (vocabulary != null ? vocabulary.subList(0, - Math.min(vocabulary.size(), maxLen)) : null) - + ", multiSelection=" + multiSelection + ", validator=" - + validator + ", ownerCategory=" + ownerCategory + ", asGroup=" - + asGroup + ", asTag=" + asTag + "]"; + return "MetadataFieldWrapper [" + + (fieldName != null ? "fieldName=" + fieldName + ", " : "") + + (fieldNameFromCategory != null ? "fieldNameFromCategory=" + + fieldNameFromCategory + ", " : "") + + (mandatory != null ? "mandatory=" + mandatory + ", " : "") + + (type != null ? "type=" + type + ", " : "") + + (defaultValue != null ? "defaultValue=" + defaultValue + ", " + : "") + + (note != null ? "note=" + note + ", " : "") + + (vocabulary != null ? "vocabulary=" + vocabulary + ", " : "") + + "multiSelection=" + + multiSelection + + ", " + + (validator != null ? "validator=" + validator + ", " : "") + + (ownerCategory != null ? "ownerCategory=" + ownerCategory.getId() + + ", " : "") + + (asGroup != null ? "asGroup=" + asGroup + ", " : "") + + (asTag != null ? "asTag=" + asTag : "") + "]"; } }