added temporary code for vocabulary of tags

git-svn-id: http://svn.d4science-ii.research-infrastructures.eu/gcube/trunk/portlets/widgets/ckan-metadata-publisher-widget@146590 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Costantino Perciante 2017-04-05 16:42:07 +00:00
parent 800a2417b4
commit 7d5e7a4978
11 changed files with 365 additions and 196 deletions

View File

@ -93,6 +93,11 @@
<artifactId>portal-manager</artifactId> <artifactId>portal-manager</artifactId>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>org.gcube.data-catalogue</groupId>
<artifactId>gcubedatacatalogue-metadata-discovery</artifactId>
<version>[2.0.0-SNAPSHOT, 3.0.0-SNAPSHOT)</version>
</dependency>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>

View File

@ -43,14 +43,14 @@ public interface CKanPublisherService extends RemoteService {
* @param toCreate * @param toCreate
* @return the sent bean filled with the needed information * @return the sent bean filled with the needed information
*/ */
DatasetMetadataBean createCKanDataset(DatasetMetadataBean toCreate); DatasetMetadataBean createCKanDataset(DatasetMetadataBean toCreate) throws Exception;
/** /**
* Add this resource to the dataset whose id is datasetId * Add this resource to the dataset whose id is datasetId
* @param resource * @param resource
* @param datasetId * @param datasetId
*/ */
ResourceElementBean addResourceToDataset(ResourceElementBean resource, String datasetId); ResourceElementBean addResourceToDataset(ResourceElementBean resource, String datasetId) throws Exception;
/** /**
* Delete this resource from the dataset with id datasetId * Delete this resource from the dataset with id datasetId

View File

@ -98,7 +98,7 @@ public class CreateDatasetForm extends Composite{
@UiField AlertBlock onContinueAlertBlock; @UiField AlertBlock onContinueAlertBlock;
@UiField AlertBlock onCreateAlertBlock; @UiField AlertBlock onCreateAlertBlock;
@UiField VerticalPanel metadataFieldsPanel; @UiField VerticalPanel metadataFieldsPanel;
@UiField ListBox metadataProfilesFormatListbox; @UiField ListBox metadataTypeListbox;
@UiField Form formFirstStep; @UiField Form formFirstStep;
@UiField Form formSecondStep; @UiField Form formSecondStep;
@UiField Form formThirdStep; @UiField Form formThirdStep;
@ -132,9 +132,9 @@ public class CreateDatasetForm extends Composite{
@UiField Icon infoIconAuthorEmail; @UiField Icon infoIconAuthorEmail;
@UiField FocusPanel focusPanelAuthorEmail; @UiField FocusPanel focusPanelAuthorEmail;
@UiField Popover popoverAuthorEmail; @UiField Popover popoverAuthorEmail;
@UiField Icon infoIconProfiles; @UiField Icon infoIconTypes;
@UiField FocusPanel focusPanelProfiles; @UiField FocusPanel focusPanelTypes;
@UiField Popover popoverProfiles; @UiField Popover popoverTypes;
@UiField Icon infoIconMaintainer; @UiField Icon infoIconMaintainer;
@UiField FocusPanel focusPanelMaintainer; @UiField FocusPanel focusPanelMaintainer;
@UiField Popover popoverMaintainer; @UiField Popover popoverMaintainer;
@ -153,7 +153,7 @@ public class CreateDatasetForm extends Composite{
@UiField Icon infoIconDescription; @UiField Icon infoIconDescription;
@UiField Popover popoverDescription; @UiField Popover popoverDescription;
@UiField FocusPanel focusPanelDescription; @UiField FocusPanel focusPanelDescription;
@UiField ControlGroup metadataProfilesControlGroup; @UiField ControlGroup metadataTypesControlGroup;
@UiField ControlGroup productTitleGroup; @UiField ControlGroup productTitleGroup;
@UiField ControlGroup maintainerControlGroup; @UiField ControlGroup maintainerControlGroup;
@UiField ControlGroup versionControlGroup; @UiField ControlGroup versionControlGroup;
@ -168,9 +168,9 @@ public class CreateDatasetForm extends Composite{
private static final String NONE_PROFILE = "none"; private static final String NONE_PROFILE = "none";
// error/info messages // error/info messages
protected static final String ERROR_PRODUCT_CREATION = "There was an error while trying to publish your item, sorry.. Retry later"; protected static final String ERROR_PRODUCT_CREATION = "There was an error while trying to publish your item.";
protected static final String PRODUCT_CREATED_OK = "Item correctly published!"; protected static final String PRODUCT_CREATED_OK = "Item correctly published!";
private static final String TRYING_TO_CREATE_PRODUCT = "Trying to publish the item, please wait"; private static final String TRYING_TO_CREATE_PRODUCT = "Trying to publish the item, please wait...";
protected static final String MISSING_PUBLISH_RIGHTS = "It seems you are not authorized to publish on catalogue. Request it to the VRE manager or the portal administrator."; protected static final String MISSING_PUBLISH_RIGHTS = "It seems you are not authorized to publish on catalogue. Request it to the VRE manager or the portal administrator.";
// tab panel // tab panel
@ -267,6 +267,9 @@ public class CreateDatasetForm extends Composite{
// disable continue button // disable continue button
continueButton.setEnabled(false); continueButton.setEnabled(false);
resetButton.setEnabled(false); resetButton.setEnabled(false);
// hide tags panel TODO
tagsPanel.setVisible(false);
// check if the user has publishing rights // check if the user has publishing rights
setAlertBlock("Checking your permissions, please wait...", AlertType.INFO, true); setAlertBlock("Checking your permissions, please wait...", AlertType.INFO, true);
@ -314,10 +317,18 @@ public class CreateDatasetForm extends Composite{
// retrieve custom fields // retrieve custom fields
Map<String, List<String>> customFieldsMap = bean.getCustomFields(); Map<String, List<String>> customFieldsMap = bean.getCustomFields();
List<String> vocabularyTags = bean.getTagsVocabulary();
// TODO vocabulary list of tags has preemption
if(vocabularyTags != null && !vocabularyTags.isEmpty()){
tagsPanel.setVocabulary(vocabularyTags);
}
else if(customFieldsMap != null){
if(customFieldsMap != null){ // get the keys and put them as tags
// get the keys and put them as tags
Iterator<Entry<String, List<String>>> iteratorOverCustomField = customFieldsMap.entrySet().iterator(); Iterator<Entry<String, List<String>>> iteratorOverCustomField = customFieldsMap.entrySet().iterator();
while (iteratorOverCustomField.hasNext()) { while (iteratorOverCustomField.hasNext()) {
@ -337,6 +348,9 @@ public class CreateDatasetForm extends Composite{
} }
} }
} }
// set it as visible anyway
tagsPanel.setVisible(true);
if(isWorkspaceRequest){ if(isWorkspaceRequest){
// if there are not resources, for now just checked it ( and hide so that the step will be skipped) // if there are not resources, for now just checked it ( and hide so that the step will be skipped)
@ -369,7 +383,7 @@ public class CreateDatasetForm extends Composite{
}); });
// try to retrieve the profiles // try to retrieve the profiles
setAlertBlock("Retrieving profiles, please wait...", AlertType.INFO, true); setAlertBlock("Retrieving types, please wait...", AlertType.INFO, true);
// get the name of the organization from the title // get the name of the organization from the title
final String orgName = nameTitleOrganizationMap.get(organizationsListbox.getSelectedItemText()); final String orgName = nameTitleOrganizationMap.get(organizationsListbox.getSelectedItemText());
@ -379,21 +393,21 @@ public class CreateDatasetForm extends Composite{
@Override @Override
public void onFailure(Throwable caught) { public void onFailure(Throwable caught) {
setAlertBlock("Error while retrieving profiles, retry later", AlertType.ERROR, true); setAlertBlock("Error while retrieving types, retry later", AlertType.ERROR, true);
} }
@Override @Override
public void onSuccess(final List<MetaDataProfileBean> profiles) { public void onSuccess(final List<MetaDataProfileBean> profiles) {
if(profiles == null){ if(profiles == null){
setAlertBlock("Error while retrieving profiles, retry later", AlertType.ERROR, true); setAlertBlock("Error while retrieving types, retry later", AlertType.ERROR, true);
} }
else{ else{
receivedBean.setMetadataList(profiles); receivedBean.setMetadataListTypes(profiles);
prepareMetadataList(receivedBean); prepareMetadataList(receivedBean);
organizationsListbox.setEnabled(true); organizationsListbox.setEnabled(true);
metadataProfilesFormatListbox.setEnabled(true); metadataTypeListbox.setEnabled(true);
// try to retrieve the licenses // try to retrieve the licenses
setAlertBlock("Retrieving licenses, please wait...", AlertType.INFO, true); setAlertBlock("Retrieving licenses, please wait...", AlertType.INFO, true);
@ -494,25 +508,25 @@ public class CreateDatasetForm extends Composite{
private void organizationsListboxChangeHandlerBody() { private void organizationsListboxChangeHandlerBody() {
// remove any other product profiles // remove any other product profiles
metadataProfilesFormatListbox.clear(); metadataTypeListbox.clear();
// add "none" item again // add "none" item again
metadataProfilesFormatListbox.addItem(NONE_PROFILE); metadataTypeListbox.addItem(NONE_PROFILE);
// select "none" // select "none"
metadataProfilesFormatListbox.setSelectedIndex(0); metadataTypeListbox.setSelectedIndex(0);
// get the name of the organization from the title // get the name of the organization from the title
String selectedOrganizationTitle = organizationsListbox.getSelectedItemText(); String selectedOrganizationTitle = organizationsListbox.getSelectedItemText();
final String orgName = nameTitleOrganizationMap.get(selectedOrganizationTitle); final String orgName = nameTitleOrganizationMap.get(selectedOrganizationTitle);
// try to retrieve the profiles // try to retrieve the profiles
setAlertBlock("Retrieving profiles, please wait...", AlertType.INFO, true); setAlertBlock("Retrieving types, please wait...", AlertType.INFO, true);
// disable the list of organizations name so that the user doesn't change it again // disable the list of organizations name so that the user doesn't change it again
// also disable the profiles and the list of groups // also disable the profiles and the list of groups
organizationsListbox.setEnabled(false); organizationsListbox.setEnabled(false);
metadataProfilesFormatListbox.setEnabled(false); metadataTypeListbox.setEnabled(false);
groupsListbox.clear(); groupsListbox.clear();
groupsControlGroup.setVisible(false); groupsControlGroup.setVisible(false);
@ -524,10 +538,10 @@ public class CreateDatasetForm extends Composite{
if(profiles != null){ if(profiles != null){
receivedBean.setMetadataList(profiles); receivedBean.setMetadataListTypes(profiles);
prepareMetadataList(receivedBean); prepareMetadataList(receivedBean);
organizationsListbox.setEnabled(true); organizationsListbox.setEnabled(true);
metadataProfilesFormatListbox.setEnabled(true); metadataTypeListbox.setEnabled(true);
// try to retrieve the licenses // try to retrieve the licenses
setAlertBlock("Retrieving groups, please wait...", AlertType.INFO, true); setAlertBlock("Retrieving groups, please wait...", AlertType.INFO, true);
@ -564,14 +578,14 @@ public class CreateDatasetForm extends Composite{
}); });
}else }else
setAlertBlock("Error while retrieving profiles, sorry", AlertType.ERROR, true); setAlertBlock("Error while retrieving types, sorry", AlertType.ERROR, true);
} }
@Override @Override
public void onFailure(Throwable caught) { public void onFailure(Throwable caught) {
setAlertBlock("Error while retrieving profiles, sorry", AlertType.ERROR, true); setAlertBlock("Error while retrieving types, sorry", AlertType.ERROR, true);
} }
}); });
@ -584,27 +598,27 @@ public class CreateDatasetForm extends Composite{
*/ */
private void prepareMetadataList(final DatasetMetadataBean receivedBean) { private void prepareMetadataList(final DatasetMetadataBean receivedBean) {
List<MetaDataProfileBean> profiles = receivedBean.getMetadataList(); List<MetaDataProfileBean> profiles = receivedBean.getMetadataListTypes();
if(profiles != null && !profiles.isEmpty()){ if(profiles != null && !profiles.isEmpty()){
for(MetaDataProfileBean metadataBean: profiles){ for(MetaDataProfileBean metadataBean: profiles){
metadataProfilesFormatListbox.addItem(metadataBean.getType().getName()); metadataTypeListbox.addItem(metadataBean.getType().getName());
// add handler on select // add handler on select
metadataProfilesFormatListbox.addChangeHandler(new ChangeHandler() { metadataTypeListbox.addChangeHandler(new ChangeHandler() {
@Override @Override
public void onChange(ChangeEvent event) { public void onChange(ChangeEvent event) {
String selectedItemText = metadataProfilesFormatListbox.getSelectedItemText(); String selectedItemText = metadataTypeListbox.getSelectedItemText();
if(selectedItemText.equals(NONE_PROFILE)){ if(selectedItemText.equals(NONE_PROFILE)){
metadataFieldsPanel.clear(); metadataFieldsPanel.clear();
metadataFieldsPanel.setVisible(false); metadataFieldsPanel.setVisible(false);
receivedBean.setChosenProfile(null); receivedBean.setChosenType(null);
}else{ }else{
receivedBean.setChosenProfile(selectedItemText); receivedBean.setChosenType(selectedItemText);
metadataFieldsPanel.clear(); metadataFieldsPanel.clear();
addFields(selectedItemText); addFields(selectedItemText);
} }
@ -628,13 +642,13 @@ public class CreateDatasetForm extends Composite{
} }
} }
metadataProfilesControlGroup.setVisible(true); metadataTypesControlGroup.setVisible(true);
}else{ }else{
// just hide this listbox // just hide this listbox
metadataProfilesControlGroup.setVisible(false); metadataTypesControlGroup.setVisible(false);
metadataFieldsPanel.clear(); metadataFieldsPanel.clear();
listOfMetadataFields.clear(); listOfMetadataFields.clear();
receivedBean.setChosenProfile(null); receivedBean.setChosenType(null);
} }
} }
@ -644,7 +658,7 @@ public class CreateDatasetForm extends Composite{
*/ */
protected void addFields(String selectedItem) { protected void addFields(String selectedItem) {
for(MetaDataProfileBean bean: receivedBean.getMetadataList()){ for(MetaDataProfileBean bean: receivedBean.getMetadataListTypes()){
if(bean.getType().getName().equals(selectedItem)){ if(bean.getType().getName().equals(selectedItem)){
@ -744,10 +758,10 @@ public class CreateDatasetForm extends Composite{
} }
if(metadataProfilesFormatListbox.getSelectedItemText().equals(NONE_PROFILE)) if(metadataTypeListbox.getSelectedItemText().equals(NONE_PROFILE))
selectedProfile.setText(""); selectedProfile.setText("");
else else
selectedProfile.setText("Selected Profile is " + metadataProfilesFormatListbox.getSelectedItemText()); selectedProfile.setText("Selected Type is " + metadataTypeListbox.getSelectedItemText());
} }
@ -986,6 +1000,7 @@ public class CreateDatasetForm extends Composite{
} }
}else{ }else{
alertOnCreate(ERROR_PRODUCT_CREATION, AlertType.ERROR, true); alertOnCreate(ERROR_PRODUCT_CREATION, AlertType.ERROR, true);
} }
@ -993,7 +1008,7 @@ public class CreateDatasetForm extends Composite{
@Override @Override
public void onFailure(Throwable caught) { public void onFailure(Throwable caught) {
alertOnCreate(ERROR_PRODUCT_CREATION, AlertType.ERROR, true); alertOnCreate(ERROR_PRODUCT_CREATION + " Error message is : " + caught.getMessage(), AlertType.ERROR, true);
} }
}); });
} }
@ -1073,14 +1088,14 @@ public class CreateDatasetForm extends Composite{
popupOpenedIds popupOpenedIds
); );
// profiles // profiles (or types)
InfoIconsLabels.preparePopupPanelAndPopover( InfoIconsLabels.preparePopupPanelAndPopover(
InfoIconsLabels.PROFILES_INFO_ID_POPUP, InfoIconsLabels.PROFILES_INFO_ID_POPUP,
InfoIconsLabels.PROFILES_INFO_TEXT, InfoIconsLabels.PROFILES_INFO_TEXT,
InfoIconsLabels.PROFILES_INFO_CAPTION, InfoIconsLabels.PROFILES_INFO_CAPTION,
infoIconProfiles, infoIconTypes,
popoverProfiles, popoverTypes,
focusPanelProfiles, focusPanelTypes,
popupOpenedIds popupOpenedIds
); );
@ -1225,7 +1240,7 @@ public class CreateDatasetForm extends Composite{
productTitleGroup.setType(ControlGroupType.NONE); productTitleGroup.setType(ControlGroupType.NONE);
maintainerControlGroup.setType(ControlGroupType.NONE); maintainerControlGroup.setType(ControlGroupType.NONE);
versionControlGroup.setType(ControlGroupType.NONE); versionControlGroup.setType(ControlGroupType.NONE);
metadataProfilesControlGroup.setType(ControlGroupType.NONE); metadataTypesControlGroup.setType(ControlGroupType.NONE);
organizationsGroup.setType(ControlGroupType.NONE); organizationsGroup.setType(ControlGroupType.NONE);
tagsPanel.setGroupPanelType(ControlGroupType.NONE); tagsPanel.setGroupPanelType(ControlGroupType.NONE);
@ -1265,8 +1280,8 @@ public class CreateDatasetForm extends Composite{
// check if metadata profile is different from none and its mandatory fields have been fulfilled // check if metadata profile is different from none and its mandatory fields have been fulfilled
if(checkSelectedMetaDataProfile()){ if(checkSelectedMetaDataProfile()){
metadataProfilesControlGroup.setType(ControlGroupType.ERROR); metadataTypesControlGroup.setType(ControlGroupType.ERROR);
return "You must select a metadata profile different frome none"; return "You must select a Type different frome none";
} }
if(organizationsListbox.getSelectedItemText() == null){ if(organizationsListbox.getSelectedItemText() == null){
@ -1288,7 +1303,7 @@ public class CreateDatasetForm extends Composite{
* @return * @return
*/ */
private boolean checkSelectedMetaDataProfile() { private boolean checkSelectedMetaDataProfile() {
return metadataProfilesFormatListbox.getSelectedItemText().equals(NONE_PROFILE) && (metadataProfilesFormatListbox.getItemCount() != 1); return metadataTypeListbox.getSelectedItemText().equals(NONE_PROFILE) && (metadataTypeListbox.getItemCount() != 1);
} }
@UiHandler("resetButton") @UiHandler("resetButton")
@ -1329,7 +1344,7 @@ public class CreateDatasetForm extends Composite{
licenseListbox.setEnabled(false); licenseListbox.setEnabled(false);
organizationsListbox.setEnabled(false); organizationsListbox.setEnabled(false);
addCustomFieldButton.setEnabled(false); addCustomFieldButton.setEnabled(false);
metadataProfilesFormatListbox.setEnabled(false); metadataTypeListbox.setEnabled(false);
groupsListbox.setEnabled(false); groupsListbox.setEnabled(false);
for(CustomFieldEntry ce: customFieldEntriesList) for(CustomFieldEntry ce: customFieldEntriesList)

View File

@ -251,20 +251,19 @@
</b:Controls> </b:Controls>
</b:ControlGroup> </b:ControlGroup>
<b:ControlGroup ui:field="metadataProfilesControlGroup"> <b:ControlGroup ui:field="metadataTypesControlGroup">
<b:ControlLabel for="metadataProfilesFormat" title="Item profile formats">Item <b:ControlLabel for="metadataTypes" title="Item profile types">Types:</b:ControlLabel>
Profile:</b:ControlLabel>
<b:Controls> <b:Controls>
<b:ListBox b:id="metadataProfilesFormat" alternateSize="LARGE" <b:ListBox b:id="metadataTypes" alternateSize="LARGE"
width="91%" title="The item profile format to be used" width="91%" title="The item type to be used"
ui:field="metadataProfilesFormatListbox"> ui:field="metadataTypeListbox">
<g:item enabled="true" title="None">none</g:item> <g:item enabled="true" title="None">none</g:item>
</b:ListBox> </b:ListBox>
<span style="float:right; width:5%; color: #aaaaaa;"> <span style="float:right; width:5%; color: #aaaaaa;">
<b:Popover ui:field="popoverProfiles" html="true" <b:Popover ui:field="popoverTypes" html="true"
animation="true" placement="LEFT"> animation="true" placement="LEFT">
<g:FocusPanel ui:field="focusPanelProfiles"> <g:FocusPanel ui:field="focusPanelTypes">
<b:Icon type="INFO_SIGN" size="TWO_TIMES" ui:field="infoIconProfiles" /> <b:Icon type="INFO_SIGN" size="TWO_TIMES" ui:field="infoIconTypes" />
</g:FocusPanel> </g:FocusPanel>
</b:Popover> </b:Popover>
</span> </span>

View File

@ -133,7 +133,7 @@ public class AddResourceToDataset extends Composite{
@Override @Override
public void onFailure(Throwable caught) { public void onFailure(Throwable caught) {
showAlert("Unable to add this resource, sorry", AlertType.ERROR); showAlert("Unable to add this resource, sorry. Error is: " + caught.getMessage(), AlertType.ERROR);
} }
}); });

View File

@ -8,6 +8,7 @@ import org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.utils.InfoIc
import com.github.gwtbootstrap.client.ui.ControlGroup; import com.github.gwtbootstrap.client.ui.ControlGroup;
import com.github.gwtbootstrap.client.ui.Icon; import com.github.gwtbootstrap.client.ui.Icon;
import com.github.gwtbootstrap.client.ui.ListBox;
import com.github.gwtbootstrap.client.ui.Popover; import com.github.gwtbootstrap.client.ui.Popover;
import com.github.gwtbootstrap.client.ui.TextBox; import com.github.gwtbootstrap.client.ui.TextBox;
import com.github.gwtbootstrap.client.ui.base.ListItem; import com.github.gwtbootstrap.client.ui.base.ListItem;
@ -39,7 +40,8 @@ public class TagsPanel extends Composite{
@UiField FocusPanel focusPanelTags; @UiField FocusPanel focusPanelTags;
@UiField Popover popoverTags; @UiField Popover popoverTags;
@UiField ControlGroup tagsInsertGroup; @UiField ControlGroup tagsInsertGroup;
@UiField ListBox tagsEnterListBox;
// regular expression for tags // regular expression for tags
private static final String REGEX_TAG = "^[a-zA-Z0-9]*$"; private static final String REGEX_TAG = "^[a-zA-Z0-9]*$";
@ -47,8 +49,35 @@ public class TagsPanel extends Composite{
// tags list // tags list
private List<String> tagsList = new ArrayList<String>(); private List<String> tagsList = new ArrayList<String>();
private List<String> vocabulary;
public TagsPanel() { public TagsPanel() {
initWidget(uiBinder.createAndBindUi(this)); initWidget(uiBinder.createAndBindUi(this));
tagsEnterListBox.setVisible(true);
}
/**
* Since we have a controlled vocabulary, we swap to a listbox with multiple selection
* @param vocabularyTags
*/
public void setVocabulary(List<String> vocabularyTags) {
if(vocabularyTags == null || vocabularyTags.isEmpty()){
tagsEnterListBox.setVisible(false);
tagsPanel.setVisible(true);
tagsEnterTextBox.setVisible(true);
}else{
for (String vocabularyTag : vocabularyTags) {
tagsEnterListBox.addItem(vocabularyTag, vocabularyTag);
}
vocabulary = vocabularyTags;
tagsPanel.setVisible(false);
tagsEnterTextBox.setVisible(false);
tagsEnterListBox.setVisible(true);
}
} }
/** /**
@ -197,7 +226,19 @@ public class TagsPanel extends Composite{
* @return * @return
*/ */
public List<String> getTags() { public List<String> getTags() {
return tagsList;
if(vocabulary == null){
return tagsList;
}else{
List<String> selected = new ArrayList<String>();
for(int i = 0; i < tagsEnterListBox.getItemCount(); i++){
if(tagsEnterListBox.isItemSelected(i))
selected.add(tagsEnterListBox.getItemText(i));
}
return selected;
}
} }
/** /**
@ -206,6 +247,7 @@ public class TagsPanel extends Composite{
public void freeze() { public void freeze() {
tagsEnterTextBox.setEnabled(false); tagsEnterTextBox.setEnabled(false);
tagsEnterListBox.setEnabled(false);
for(int i = 0; i < tagsList.size(); i++){ for(int i = 0; i < tagsList.size(); i++){
// get tag widget // get tag widget
@ -223,8 +265,8 @@ public class TagsPanel extends Composite{
* @param none * @param none
*/ */
public void setGroupPanelType(ControlGroupType type) { public void setGroupPanelType(ControlGroupType type) {
tagsInsertGroup.setType(type); tagsInsertGroup.setType(type);
} }
} }

View File

@ -12,9 +12,11 @@
<font color="red">*</font> <font color="red">*</font>
Tags: Tags:
</b:ControlLabel> </b:ControlLabel>
<b:Controls> <b:Controls ui:field="controlAsTextBox">
<b:TextBox width="90%" placeholder="Enter one or more tag for the item" <b:TextBox width="90%" placeholder="Enter one or more tag for the item"
b:id="tags" ui:field="tagsEnterTextBox" /> b:id="tags" ui:field="tagsEnterTextBox" />
<b:ListBox width="91%" title="HOLD CTRL or CMD for multiple selection"
b:id="tags" ui:field="tagsEnterListBox" multipleSelect="true"/>
<span style="float:right; width:5%; color: #aaaaaa;"> <span style="float:right; width:5%; color: #aaaaaa;">
<b:Popover ui:field="popoverTags" html="true" animation="true" <b:Popover ui:field="popoverTags" html="true" animation="true"
placement="LEFT"> placement="LEFT">
@ -25,7 +27,6 @@
</span> </span>
</b:Controls> </b:Controls>
</b:ControlGroup> </b:ControlGroup>
<b:ControlGroup> <b:ControlGroup>
<b:Controls> <b:Controls>
<g:FlowPanel ui:field="tagsPanel" styleName="{style.tagsPanelStyle}"></g:FlowPanel> <g:FlowPanel ui:field="tagsPanel" styleName="{style.tagsPanelStyle}"></g:FlowPanel>

View File

@ -29,7 +29,8 @@ public class InfoIconsLabels {
+ "item and by means of them it can be retrieved. A tag can contain only alphanumeric characters. " + "item and by means of them it can be retrieved. A tag can contain only alphanumeric characters. "
+ "If the tag is composed by a single word it must have a size of at least two characters." + "If the tag is composed by a single word it must have a size of at least two characters."
+ "Examples of good tags: \"This is a sample tag\", \"tagY\". Example of bad tag: \"c\"." + "Examples of good tags: \"This is a sample tag\", \"tagY\". Example of bad tag: \"c\"."
+ " You must push ENTER for attaching a tag."; + " You must push ENTER for attaching a tag, or use the provided list of predefined tags. In the latter case"
+ " hold down the CTRL or CMD button to select multiple options.";
// LICENSES // LICENSES
public static final String LICENSES_INFO_ID_POPUP = "licenses-popup-panel-info"; public static final String LICENSES_INFO_ID_POPUP = "licenses-popup-panel-info";
@ -63,8 +64,8 @@ public class InfoIconsLabels {
// PROFILES // PROFILES
public static final String PROFILES_INFO_ID_POPUP = "product-profiles-popup-panel-info"; public static final String PROFILES_INFO_ID_POPUP = "product-profiles-popup-panel-info";
public static final String PROFILES_INFO_CAPTION = "Item Profiles"; public static final String PROFILES_INFO_CAPTION = "Item Types";
public static final String PROFILES_INFO_TEXT = "Select a profile, different from none, for your item among the ones available"; public static final String PROFILES_INFO_TEXT = "Select a type, different from none, for your item among the ones available";
// RESOURCES // RESOURCES
public static final String RESOURCES_INFO_ID_POPUP = "resouces-popup-panel-info"; public static final String RESOURCES_INFO_ID_POPUP = "resouces-popup-panel-info";

View File

@ -21,6 +21,7 @@ import org.gcube.datacatalogue.ckanutillibrary.shared.RolesCkanGroupOrOrg;
import org.gcube.portlets.widgets.ckandatapublisherwidget.client.CKanPublisherService; import org.gcube.portlets.widgets.ckandatapublisherwidget.client.CKanPublisherService;
import org.gcube.portlets.widgets.ckandatapublisherwidget.server.threads.AssociationToGroupAndNotifyThread; import org.gcube.portlets.widgets.ckandatapublisherwidget.server.threads.AssociationToGroupAndNotifyThread;
import org.gcube.portlets.widgets.ckandatapublisherwidget.server.threads.WritePostCatalogueManagerThread; import org.gcube.portlets.widgets.ckandatapublisherwidget.server.threads.WritePostCatalogueManagerThread;
import org.gcube.portlets.widgets.ckandatapublisherwidget.server.utils.DiscoverTagsList;
import org.gcube.portlets.widgets.ckandatapublisherwidget.server.utils.Utils; import org.gcube.portlets.widgets.ckandatapublisherwidget.server.utils.Utils;
import org.gcube.portlets.widgets.ckandatapublisherwidget.server.utils.WorkspaceUtils; import org.gcube.portlets.widgets.ckandatapublisherwidget.server.utils.WorkspaceUtils;
import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.DatasetMetadataBean; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.DatasetMetadataBean;
@ -202,6 +203,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C
bean.setMaintainer(userOwner.getFullname()); bean.setMaintainer(userOwner.getFullname());
bean.setMaintainerEmail(userOwner.getEmail()); bean.setMaintainerEmail(userOwner.getEmail());
bean.setOrganizationList(getUserOrganizationsListAdmin(userName, scope)); bean.setOrganizationList(getUserOrganizationsListAdmin(userName, scope));
bean.setTagsVocabulary(discoverTagsVocabulary(scope));
// if the request comes from the workspace // if the request comes from the workspace
if(folderId != null && !folderId.isEmpty()){ if(folderId != null && !folderId.isEmpty()){
@ -244,106 +246,124 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C
return bean; return bean;
} }
/**
* Discover from the IS the vocabulary of tags for this scope, if present
* @return a list of tags vocabulary
*/
private List<String> discoverTagsVocabulary(String context) {
String keyPerVocabulary = UtilMethods.concatenateSessionKeyScope("TAGS_VOCABULARY", context); // TODO REMOVE
List<String> vocabulary = (List<String>) getThreadLocalRequest().getSession().getAttribute(keyPerVocabulary);
if(vocabulary != null){
vocabulary = new DiscoverTagsList(context).getTagsVocabulary();
getThreadLocalRequest().getSession().setAttribute(keyPerVocabulary, vocabulary);
}
return vocabulary;
}
@Override @Override
public DatasetMetadataBean createCKanDataset(DatasetMetadataBean toCreate) { public DatasetMetadataBean createCKanDataset(DatasetMetadataBean toCreate) throws Exception{
logger.debug("Request for creating a dataset with these information " + toCreate); logger.debug("Request for creating a dataset with these information " + toCreate);
String userName = Utils.getCurrentUser(getThreadLocalRequest()).getUsername(); String userName = Utils.getCurrentUser(getThreadLocalRequest()).getUsername();
try{ String title = toCreate.getTitle();
String organizationNameOrId = toCreate.getSelectedOrganization();
String author = toCreate.getAuthorFullName();
String authorMail = toCreate.getAuthorEmail();
String maintainer = toCreate.getMaintainer();
String maintainerMail = toCreate.getMaintainerEmail();
long version = toCreate.getVersion();
String description = toCreate.getDescription();
String chosenLicense = toCreate.getLicense();
String licenseId = findLicenseIdByLicense(chosenLicense);
List<String> listOfTags = toCreate.getTags();
Map<String, List<String>> customFields = toCreate.getCustomFields();
String title = toCreate.getTitle(); // add Type for custom fields
String organizationNameOrId = toCreate.getSelectedOrganization(); if(toCreate.getChosenType() != null)
String author = toCreate.getAuthorFullName(); customFields.put("Type", Arrays.asList(toCreate.getChosenType()));
String authorMail = toCreate.getAuthorEmail();
String maintainer = toCreate.getMaintainer();
String maintainerMail = toCreate.getMaintainerEmail();
long version = toCreate.getVersion();
String description = toCreate.getDescription();
String chosenLicense = toCreate.getLicense();
String licenseId = findLicenseIdByLicense(chosenLicense);
List<String> listOfTags = toCreate.getTags();
Map<String, List<String>> customFields = toCreate.getCustomFields();
boolean setPublic = toCreate.getVisibility();
// get the list of resources and convert to ResourceBean boolean setPublic = toCreate.getVisibility();
List<ResourceBean> resources = null;
ResourceElementBean resourcesToAdd = toCreate.getResourceRoot();
// we need to copy such resource in the .catalogue area of the user's ws // get the list of resources and convert to ResourceBean
if(resourcesToAdd != null){ List<ResourceBean> resources = null;
resources = WorkspaceUtils.copyResourcesToUserCatalogueArea(toCreate.getId(), userName, toCreate); ResourceElementBean resourcesToAdd = toCreate.getResourceRoot();
}
logger.debug("The user wants to publish in organization with name " + organizationNameOrId); // we need to copy such resource in the .catalogue area of the user's ws
String scope = getScopeFromOrgName(organizationNameOrId); if(resourcesToAdd != null){
DataCatalogue utils = getCatalogue(scope); resources = WorkspaceUtils.copyResourcesToUserCatalogueArea(toCreate.getId(), userName, toCreate);
String userApiKey = utils.getApiKeyFromUsername(userName);
String datasetId = utils.createCKanDatasetMultipleCustomFields
(userApiKey, title, null, organizationNameOrId, author, authorMail, maintainer,
maintainerMail, version, description, licenseId, listOfTags, customFields, resources, setPublic);
if(datasetId != null){
logger.info("Dataset created!");
toCreate.setId(datasetId);
// retrieve the url
String datasetUrl = utils.getUnencryptedUrlFromDatasetIdOrName(datasetId);
toCreate.setSource(datasetUrl);
// add also this information as custom field
Map<String, List<String>> addField = new HashMap<String, List<String>>();
addField.put(ITEM_URL_FIELD, Arrays.asList(datasetUrl));
utils.patchProductCustomFields(datasetId, userApiKey, addField);
// start a thread that will associate this dataset with the group
if(toCreate.getChosenProfile() != null || toCreate.getGroups() != null){
AssociationToGroupAndNotifyThread threadAssociationToGroup =
new AssociationToGroupAndNotifyThread(
toCreate.getGroups(),
toCreate.getChosenProfile(),
datasetUrl,
datasetId,
toCreate.getTitle(),
Utils.getCurrentUser(getThreadLocalRequest()).getFullname(),
userName,
utils,
organizationNameOrId,
getThreadLocalRequest()
);
threadAssociationToGroup.start();
}
// launch notification thread
WritePostCatalogueManagerThread threadWritePost =
new WritePostCatalogueManagerThread(
userName,
scope,
toCreate.getTitle(),
datasetUrl,
false, // send notification to other people
toCreate.getTags(),
Utils.getCurrentUser(getThreadLocalRequest()).getFullname()
);
threadWritePost.start();
return toCreate;
}else{
logger.error("Failed to create the dataset");
}
}catch(Exception e){
logger.error("Unable to create the dataset", e);
} }
logger.debug("The user wants to publish in organization with name " + organizationNameOrId);
String scope = getScopeFromOrgName(organizationNameOrId);
DataCatalogue utils = getCatalogue(scope);
String userApiKey = utils.getApiKeyFromUsername(userName);
String datasetId = utils.createCKanDatasetMultipleCustomFields
(userApiKey, title, null, organizationNameOrId, author, authorMail, maintainer,
maintainerMail, version, description, licenseId, listOfTags, customFields, resources, setPublic);
if(datasetId != null){
logger.info("Dataset created!");
toCreate.setId(datasetId);
// retrieve the url
String datasetUrl = utils.getUnencryptedUrlFromDatasetIdOrName(datasetId);
toCreate.setSource(datasetUrl);
// add also this information as custom field
Map<String, List<String>> addField = new HashMap<String, List<String>>();
addField.put(ITEM_URL_FIELD, Arrays.asList(datasetUrl));
utils.patchProductCustomFields(datasetId, userApiKey, addField);
// start a thread that will associate this dataset with the group
if(/*toCreate.getChosenType() != null ||*/ toCreate.getGroups() != null){
AssociationToGroupAndNotifyThread threadAssociationToGroup =
new AssociationToGroupAndNotifyThread(
toCreate.getGroups(),
null, //toCreate.getChosenType(), TODO
datasetUrl,
datasetId,
toCreate.getTitle(),
Utils.getCurrentUser(getThreadLocalRequest()).getFullname(),
userName,
utils,
organizationNameOrId,
getThreadLocalRequest()
);
threadAssociationToGroup.start();
}
// launch notification thread
WritePostCatalogueManagerThread threadWritePost =
new WritePostCatalogueManagerThread(
userName,
scope,
toCreate.getTitle(),
datasetUrl,
false, // send notification to other people
toCreate.getTags(),
Utils.getCurrentUser(getThreadLocalRequest()).getFullname()
);
threadWritePost.start();
return toCreate;
}else{
logger.error("Failed to create the dataset");
}
return null; return null;
} }
@Override @Override
public ResourceElementBean addResourceToDataset(ResourceElementBean resource, String datasetId) { public ResourceElementBean addResourceToDataset(ResourceElementBean resource, String datasetId) throws Exception{
String username = Utils.getCurrentUser(getThreadLocalRequest()).getUsername(); String username = Utils.getCurrentUser(getThreadLocalRequest()).getUsername();
logger.debug("Incoming request for creating new resource for dataset with id " + datasetId + " and organization name of the dataset is " + resource.getOrganizationNameDatasetParent()); logger.debug("Incoming request for creating new resource for dataset with id " + datasetId + " and organization name of the dataset is " + resource.getOrganizationNameDatasetParent());
@ -356,29 +376,26 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C
}else{ }else{
try{
ResourceBean resourceBean = new ResourceBean(
resource.getUrl(),
resource.getName(),
resource.getDescription(),
null,
username,
datasetId,
null);
// get the scope in which we should discover the ckan instance given the organization name in which the dataset was created ResourceBean resourceBean = new ResourceBean(
String scope = getScopeFromOrgName(resource.getOrganizationNameDatasetParent()); resource.getUrl(),
DataCatalogue catalogue = getCatalogue(scope); resource.getName(),
String resourceId = catalogue.addResourceToDataset(resourceBean, catalogue.getApiKeyFromUsername(username)); resource.getDescription(),
null,
username,
datasetId,
null);
if(resourceId != null){ // get the scope in which we should discover the ckan instance given the organization name in which the dataset was created
logger.debug("Resource " + resource.getName() + " is now available"); String scope = getScopeFromOrgName(resource.getOrganizationNameDatasetParent());
// set its id and turn it to the client DataCatalogue catalogue = getCatalogue(scope);
resource.setOriginalIdInWorkspace(resourceId); String resourceId = catalogue.addResourceToDataset(resourceBean, catalogue.getApiKeyFromUsername(username));
return resource;
} if(resourceId != null){
}catch(Exception e){ logger.debug("Resource " + resource.getName() + " is now available");
logger.error("Unable to create new resource", e); // set its id and turn it to the client
resource.setOriginalIdInWorkspace(resourceId);
return resource;
} }
logger.debug("No resource created"); logger.debug("No resource created");

View File

@ -0,0 +1,79 @@
package org.gcube.portlets.widgets.ckandatapublisherwidget.server.utils;
import static org.gcube.resources.discovery.icclient.ICFactory.client;
import java.io.StringReader;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.gcube.common.resources.gcore.utils.XPathHelper;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.datacatalogue.ckanutillibrary.shared.ex.ApplicationProfileNotFoundException;
import org.gcube.portlets.widgets.ckandatapublisherwidget.server.CKANPublisherServicesImpl;
import org.gcube.resources.discovery.client.api.DiscoveryClient;
import org.gcube.resources.discovery.client.queries.api.Query;
import org.gcube.resources.discovery.client.queries.impl.QueryBox;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
/**
* Discover in a given context if there is a Generic Resource containing the list of tags to be used
* within the widget
* @author Costantino Perciante at ISTI-CNR
* (costantino.perciante@isti.cnr.it)
*
*/
public class DiscoverTagsList {
private static final Log logger = LogFactoryUtil.getLog(CKANPublisherServicesImpl.class);
List<String> tagsVocabulary;
private final static String APPLICATION_PROFILE_NAME = "Tags";
private final static String QUERY = "for $profile in collection('/db/Profiles/GenericResource')//Resource " +
"where $profile/Profile/SecondaryType/string() eq 'DataCatalogueMetadataTags' and $profile/Profile/Name/string() " +
" eq '" + APPLICATION_PROFILE_NAME + "'" +
"return $profile";
/**
* Discover the list of tags vocabulary if needed
*/
public DiscoverTagsList(String context) {
String currentContext = ScopeProvider.instance.get();
ScopeProvider.instance.set(context);
try{
Query q = new QueryBox(QUERY);
DiscoveryClient<String> client = client();
List<String> appProfile = client.submit(q);
if (appProfile == null || appProfile.size() == 0)
throw new ApplicationProfileNotFoundException("Your applicationProfile is not registered in the infrastructure");
else{
String elem = appProfile.get(0);
DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Node node = docBuilder.parse(new InputSource(new StringReader(elem))).getDocumentElement();
XPathHelper helper = new XPathHelper(node);
tagsVocabulary = helper.evaluate("/Resource/Profile/Body/tags/tag/text()");
logger.trace("Retrieved tags " + tagsVocabulary);
}
}catch(Exception e){
logger.warn("Failed to retrieve this information " + e.getMessage());
}finally{
ScopeProvider.instance.set(currentContext);
}
}
public List<String> getTagsVocabulary() {
return tagsVocabulary;
}
}

View File

@ -23,14 +23,15 @@ public class DatasetMetadataBean implements Serializable {
private String maintainer; private String maintainer;
private String maintainerEmail; private String maintainerEmail;
private String ownerIdentifier; // owner of the folder into the workspace (e.g., andrea.rossi) private String ownerIdentifier; // owner of the folder into the workspace (e.g., andrea.rossi)
private String chosenProfile; // the name of the MetaDataProfile chosen private String chosenType; // the name of the MetaDataType chosen
private String selectedOrganization; private String selectedOrganization;
private long version; // version 1, 2 ... private long version; // version 1, 2 ...
private boolean visibility; // Private (false) or Public(true) private boolean visibility; // Private (false) or Public(true)
private List<OrganizationBean> organizationList; // list of organization in which the user is present and could create the dataset private List<OrganizationBean> organizationList; // list of organization in which the user is present and could create the dataset
private ResourceElementBean resourceRoot; // in case of workspace, this is the directory root or the single file information private ResourceElementBean resourceRoot; // in case of workspace, this is the directory root or the single file information
private List<MetaDataProfileBean> metadataList; private List<MetaDataProfileBean> metadataListTypes;
private List<String> tags; // on retrieve, they are the keys of the product private List<String> tags; // on retrieve, they are the keys of the product
private List<String> tagsVocabulary; // when available
private Map<String, List<String>> customFields; private Map<String, List<String>> customFields;
private List<GroupBean> groups; private List<GroupBean> groups;
@ -66,7 +67,7 @@ public class DatasetMetadataBean implements Serializable {
String maintainerEmail, String ownerIdentifier, String maintainerEmail, String ownerIdentifier,
List<OrganizationBean> organizationList, String selectedOrganization, List<OrganizationBean> organizationList, String selectedOrganization,
ResourceElementBean resourceRoot, ResourceElementBean resourceRoot,
List<MetaDataProfileBean> metadataList, List<GroupBean> groups) { List<MetaDataProfileBean> metadataList, List<GroupBean> groups, List<String> tagsVocabulary) {
super(); super();
this.id = id; this.id = id;
this.title = title; this.title = title;
@ -86,16 +87,25 @@ public class DatasetMetadataBean implements Serializable {
this.organizationList = organizationList; this.organizationList = organizationList;
this.selectedOrganization = selectedOrganization; this.selectedOrganization = selectedOrganization;
this.resourceRoot = resourceRoot; this.resourceRoot = resourceRoot;
this.metadataList = metadataList; this.metadataListTypes = metadataList;
this.groups = groups; this.groups = groups;
this.tagsVocabulary = tagsVocabulary;
} }
public List<MetaDataProfileBean> getMetadataList() { public String getChosenType() {
return metadataList; return chosenType;
} }
public void setMetadataList(List<MetaDataProfileBean> metadataList) { public void setChosenType(String chosenType) {
this.metadataList = metadataList; this.chosenType = chosenType;
}
public List<MetaDataProfileBean> getMetadataListTypes() {
return metadataListTypes;
}
public void setMetadataListTypes(List<MetaDataProfileBean> metadataListTypes) {
this.metadataListTypes = metadataListTypes;
} }
public String getId() { public String getId() {
@ -250,14 +260,6 @@ public class DatasetMetadataBean implements Serializable {
this.authorFullName = authorFullName; this.authorFullName = authorFullName;
} }
public String getChosenProfile() {
return chosenProfile;
}
public void setChosenProfile(String chosenProfile) {
this.chosenProfile = chosenProfile;
}
public List<GroupBean> getGroups() { public List<GroupBean> getGroups() {
return groups; return groups;
} }
@ -266,6 +268,14 @@ public class DatasetMetadataBean implements Serializable {
this.groups = groups; this.groups = groups;
} }
public List<String> getTagsVocabulary() {
return tagsVocabulary;
}
public void setTagsVocabulary(List<String> tagsVocabulary) {
this.tagsVocabulary = tagsVocabulary;
}
@Override @Override
public String toString() { public String toString() {
return "DatasetMetadataBean [id=" + id + ", title=" + title return "DatasetMetadataBean [id=" + id + ", title=" + title
@ -275,13 +285,13 @@ public class DatasetMetadataBean implements Serializable {
+ authorFullName + ", authorEmail=" + authorEmail + authorFullName + ", authorEmail=" + authorEmail
+ ", maintainer=" + maintainer + ", maintainerEmail=" + ", maintainer=" + maintainer + ", maintainerEmail="
+ maintainerEmail + ", ownerIdentifier=" + ownerIdentifier + maintainerEmail + ", ownerIdentifier=" + ownerIdentifier
+ ", chosenProfile=" + chosenProfile + ", chosenType=" + chosenType + ", selectedOrganization="
+ ", selectedOrganization=" + selectedOrganization + selectedOrganization + ", version=" + version
+ ", version=" + version + ", visibility=" + visibility + ", visibility=" + visibility + ", organizationList="
+ ", organizationList=" + organizationList + ", resourceRoot=" + organizationList + ", resourceRoot=" + resourceRoot
+ resourceRoot + ", metadataList=" + metadataList + ", tags=" + ", metadataListTypes=" + metadataListTypes + ", tags=" + tags
+ tags + ", customFields=" + customFields + ", groups=" + ", tagsVocabulary=" + tagsVocabulary + ", customFields="
+ groups + "]"; + customFields + ", groups=" + groups + "]";
} }
} }