diff --git a/pom.xml b/pom.xml index 471f4bc..b1fe8d5 100644 --- a/pom.xml +++ b/pom.xml @@ -128,6 +128,44 @@ [2.0.0-SNAPSHOT, 3.0.0-SNAPSHOT) provided + + org.gcube.common + home-library + provided + + + asm-all + asm + + + + + org.gcube.common + home-library-jcr + provided + + + org.gcube.dvos + usermanagement-core + [2.0.0-SNAPSHOT, 3.0.0-SNAPSHOT) + provided + + + org.gcube.core + common-scope-maps + runtime + + + + org.gcube.portlets.user + workspace-tree-widget + [6.0.0-SNAPSHOT, 7.0.0-SNAPSHOT) + + + org.gcube.portlets.user + gcube-widgets + provided + 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 15ab355..f9305c7 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 @@ -22,7 +22,9 @@ public class CKanMetadataPublisher implements EntryPoint { private void startExample() { - RootPanel.get("ckan-metadata-publisher-div").add(new EditMetadataForm()); + String idFolderWorkspace = "06bc1ca7-bf1b-4797-b0a4-cb8a55a9c189"; + String owner = "costantino.perciante"; + RootPanel.get("ckan-metadata-publisher-div").add(new EditMetadataForm(idFolderWorkspace, owner)); } } 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 41f8a5d..77da28b 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 @@ -1,5 +1,6 @@ package org.gcube.portlets.widgets.ckandatapublisherwidget.client; +import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.DatasetMetadataBean; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.LicensesBean; import com.google.gwt.user.client.rpc.RemoteService; @@ -14,5 +15,6 @@ import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; public interface CKanPublisherService extends RemoteService { LicensesBean getLicenses(); + DatasetMetadataBean getDatasetBean(String folderId, String owner); } diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/CKanPublisherServiceAsync.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/CKanPublisherServiceAsync.java index fa6c08c..2d58bdd 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/CKanPublisherServiceAsync.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/CKanPublisherServiceAsync.java @@ -1,5 +1,6 @@ package org.gcube.portlets.widgets.ckandatapublisherwidget.client; +import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.DatasetMetadataBean; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.LicensesBean; import com.google.gwt.user.client.rpc.AsyncCallback; @@ -13,4 +14,7 @@ public interface CKanPublisherServiceAsync { void getLicenses(AsyncCallback callback); + void getDatasetBean(String folderId, String owner, + AsyncCallback callback); + } diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/events/DeleteCustomFieldEvent.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/events/DeleteCustomFieldEvent.java new file mode 100644 index 0000000..4374ac1 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/events/DeleteCustomFieldEvent.java @@ -0,0 +1,29 @@ +package org.gcube.portlets.widgets.ckandatapublisherwidget.client.events; +import org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.CustomFieldEntry; + +import com.google.gwt.event.shared.GwtEvent; + + +public class DeleteCustomFieldEvent extends GwtEvent { + public static Type TYPE = new Type(); + + private CustomFieldEntry removedEntry; + + public DeleteCustomFieldEvent(CustomFieldEntry removedEntry) { + this.removedEntry = removedEntry; + } + + public CustomFieldEntry getRemovedEntry() { + return removedEntry; + } + + @Override + public Type getAssociatedType() { + return TYPE; + } + + @Override + protected void dispatch(DeleteCustomFieldEventHandler handler) { + handler.onRemoveEntry(this); + } +} diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/events/DeleteCustomFieldEventHandler.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/events/DeleteCustomFieldEventHandler.java new file mode 100644 index 0000000..6cfb050 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/events/DeleteCustomFieldEventHandler.java @@ -0,0 +1,7 @@ +package org.gcube.portlets.widgets.ckandatapublisherwidget.client.events; + +import com.google.gwt.event.shared.EventHandler; + +public interface DeleteCustomFieldEventHandler extends EventHandler { + void onRemoveEntry(DeleteCustomFieldEvent event); +} diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/CustomFieldEntry.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/CustomFieldEntry.java index 878305c..4280746 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/CustomFieldEntry.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/CustomFieldEntry.java @@ -1,9 +1,16 @@ package org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui; +import org.gcube.portlets.widgets.ckandatapublisherwidget.client.events.DeleteCustomFieldEvent; + +import com.github.gwtbootstrap.client.ui.Button; +import com.github.gwtbootstrap.client.ui.InputAddOn; import com.github.gwtbootstrap.client.ui.TextBox; import com.google.gwt.core.client.GWT; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.shared.HandlerManager; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; @@ -15,31 +22,61 @@ public class CustomFieldEntry extends Composite { interface CustomFieldEntryUiBinder extends UiBinder { } - - @UiField TextBox keyField; - @UiField TextBox valueField; - - public CustomFieldEntry() { + + @UiField InputAddOn keyFieldPrepend; + @UiField InputAddOn valueFieldPrepend; + @UiField Button removeCustomField; + + // event bus + private HandlerManager eventBus; + + public CustomFieldEntry(HandlerManager eventBus) { initWidget(uiBinder.createAndBindUi(this)); + this.eventBus = eventBus; } /** - * Get current key value - * @return string + * Check if it has been added by the user during form creation or comes from the workspace + * @return */ - public String getCurrentKey(){ - - return keyField.getText(); - + private boolean isCreatedCustomField(){ + + return valueFieldPrepend.isAttached(); + } /** - * Get current value value - * @return string + * Retrieve the key value + * @return */ - public String getCurrentValue(){ + public String getKey(){ - return valueField.getText(); + if(isCreatedCustomField()) + return ((TextBox)keyFieldPrepend.getWidget(1)).getValue(); + else + return valueFieldPrepend.get } + + /** + * Retrieve the value + * @return + */ + public String getValue(){ + + if(isCreatedCustomField()) + return ((TextBox)valueFieldPrepend.getWidget(1)).getValue(); + else + return valueFieldPrepend.getWidgetIndex(1).get + + } + + @UiHandler("removeCustomField") + void onRemoveCustomField(ClickEvent e){ + + // fire event + eventBus.fireEvent(new DeleteCustomFieldEvent(this)); + + } + } diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/CustomFieldEntry.ui.xml b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/CustomFieldEntry.ui.xml index 3729e76..780c41a 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/CustomFieldEntry.ui.xml +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/CustomFieldEntry.ui.xml @@ -2,11 +2,12 @@ - - + + - - + + + \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/EditMetadataForm.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/EditMetadataForm.java index 8f8c278..dc7296a 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/EditMetadataForm.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/EditMetadataForm.java @@ -1,24 +1,41 @@ package org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import org.gcube.portlets.widgets.ckandatapublisherwidget.client.CKanPublisherService; import org.gcube.portlets.widgets.ckandatapublisherwidget.client.CKanPublisherServiceAsync; +import org.gcube.portlets.widgets.ckandatapublisherwidget.client.events.DeleteCustomFieldEvent; +import org.gcube.portlets.widgets.ckandatapublisherwidget.client.events.DeleteCustomFieldEventHandler; +import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.DatasetMetadataBean; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.LicensesBean; +import org.gcube.portlets.widgets.workspacesharingwidget.client.view.sharing.multisuggest.Span; +import com.github.gwtbootstrap.client.ui.AlertBlock; import com.github.gwtbootstrap.client.ui.Button; import com.github.gwtbootstrap.client.ui.ControlGroup; +import com.github.gwtbootstrap.client.ui.Label; import com.github.gwtbootstrap.client.ui.ListBox; import com.github.gwtbootstrap.client.ui.TextArea; import com.github.gwtbootstrap.client.ui.TextBox; +import com.github.gwtbootstrap.client.ui.base.ListItem; +import com.github.gwtbootstrap.client.ui.constants.AlertType; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.event.dom.client.KeyCodes; +import com.google.gwt.event.dom.client.KeyDownEvent; +import com.google.gwt.event.shared.HandlerManager; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Widget; /** @@ -26,7 +43,7 @@ import com.google.gwt.user.client.ui.Widget; * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) */ public class EditMetadataForm extends Composite{ - + /** * Create a remote service proxy to talk to the server-side ckan service. */ @@ -40,13 +57,12 @@ public class EditMetadataForm extends Composite{ } @UiField TextBox titleTextBox; - @UiField TextBox urlTextbox; @UiField TextArea descriptionTextarea; - @UiField TextBox tagsTextbox; + @UiField TextBox tagsEnterTextBox; + @UiField FlowPanel tagsPanel; @UiField ListBox licenseListbox; @UiField ListBox visibilityListbox; @UiField ListBox searchableListbox; - @UiField TextBox sourceTextbox; @UiField TextBox versionTextbox; @UiField TextBox authorTextbox; @UiField TextBox authorEmailTextbox; @@ -56,52 +72,160 @@ public class EditMetadataForm extends Composite{ @UiField Button addCustomFieldButton; @UiField Button createButton; @UiField Button resetButton; - + @UiField AlertBlock infoBlock; + + // tags list + private List tagsList = new ArrayList(); + // the licenses private LicensesBean licenseBean; + // event bus + private final HandlerManager eventBus = new HandlerManager(null); + // added custom field entries List customFieldEntries = new ArrayList(); + + // dataset metadata bean + private DatasetMetadataBean receivedBean; - public EditMetadataForm() { + public EditMetadataForm(String idFolderWorkspace, String owner) { initWidget(uiBinder.createAndBindUi(this)); + + // bind on events + bind(); - // get back the licenses - ckanServices.getLicenses(new AsyncCallback() { - + // set info block + setAlertBlock("Retrieving information, please wait...", AlertType.INFO, true); + + // disable create button + createButton.setEnabled(false); + + // get back the licenses and the metadata information from the workspace + ckanServices.getDatasetBean(idFolderWorkspace, owner, new AsyncCallback() { + @Override - public void onSuccess(LicensesBean result) { - - if(result != null && !result.getLicenses().isEmpty()){ + public void onSuccess(DatasetMetadataBean bean) { + + if(bean != null){ - licenseBean = result; - - // fill the listbox - for(String license: licenseBean.getLicenses()){ - - licenseListbox.addItem(license); - + // save it + receivedBean = bean; + + // fill the form + titleTextBox.setText(bean.getTitle()); + descriptionTextarea.setText(bean.getDescription()); + versionTextbox.setText(String.valueOf(bean.getVersion())); + authorTextbox.setText(bean.getAuthor()); + authorEmailTextbox.setText(bean.getAuthorEmail()); + maintainerTextbox.setText(bean.getMaintainer()); + maintainerEmailTextbox.setText(bean.getMaintainerEmail()); + + // retrieve custom fields + Map customFieldsMap = bean.getCustomFields(); + + if(customFields != null){ + + // get the keys and put them as tags + Iterator> iteratorOverCustomField = customFieldsMap.entrySet().iterator(); + + while (iteratorOverCustomField.hasNext()) { + Map.Entry entry = (Map.Entry) iteratorOverCustomField + .next(); + + // these are fixed key, variable value custom fields + CustomFieldEntry toAdd = new CustomFieldEntry(eventBus); + + // remove the first appendbox + toAdd.valueFieldPrepend.removeFromParent(); + toAdd.keyFieldPrepend.setPrependText(entry.getKey() + ":"); + ((TextBox)toAdd.keyFieldPrepend.getWidget(1)).setText(entry.getValue()); + + customFieldEntries.add(toAdd); + customFields.add(toAdd); + + final ListItem item = new ListItem(); + Label label = new Label(entry.getKey()); + item.add(label); + + } } - - }else - { - // TODO + + // try to retrieve the licenses + setAlertBlock("Retrieving licenses, please wait...", AlertType.INFO, true); + ckanServices.getLicenses(new AsyncCallback() { + + @Override + public void onSuccess(LicensesBean lBean) { + + if(lBean != null && !lBean.getLicenses().isEmpty()){ + + licenseBean = lBean; + + // fill the listbox + for(String license: licenseBean.getLicenses()){ + + licenseListbox.addItem(license); + + } + + // everything went ok + setAlertBlock("", AlertType.ERROR, false); + createButton.setEnabled(true); + + }else{ + setAlertBlock("Error while retrieving licenses, try to refresh the page", AlertType.ERROR, true); + } + } + + @Override + public void onFailure(Throwable caught) { + + setAlertBlock("Error while retrieving licenses, try to refresh the page", AlertType.ERROR, true); + + } + }); + + }else{ + + setAlertBlock("Error while retrieving information, try to refresh the page", AlertType.ERROR, true); } + } - + @Override public void onFailure(Throwable caught) { - - // TODO - + + setAlertBlock("Error while retrieving information, try to refresh the page", AlertType.ERROR, true); + } }); + + } + + /** + * Bind on events + */ + private void bind() { + + // when a custom field is removed, remove it from the list + eventBus.addHandler(DeleteCustomFieldEvent.TYPE, new DeleteCustomFieldEventHandler() { + + @Override + public void onRemoveEntry(DeleteCustomFieldEvent event) { + + customFieldEntries.remove(event.getRemovedEntry()); + customFields.remove(event.getRemovedEntry()); + + } + }); + } @UiHandler("addCustomFieldButton") void addCustomFieldEvent(ClickEvent e){ - CustomFieldEntry toAdd = new CustomFieldEntry(); + CustomFieldEntry toAdd = new CustomFieldEntry(eventBus); customFieldEntries.add(toAdd); customFields.add(toAdd); @@ -109,9 +233,63 @@ public class EditMetadataForm extends Composite{ @UiHandler("createButton") void createDatasetEvent(ClickEvent e){ + + // validate data TODO + boolean areDataValid = validateData(); - // TODO + // Collect current data and send them to the server + if(areDataValid){ + + String title = titleTextBox.getValue(); + String description = descriptionTextarea.getText(); + String selectedLicense = licenseListbox.getSelectedItemText(); + String visibility = visibilityListbox.getValue(); + String searchable = searchableListbox.getValue(); + long version = Long.valueOf(versionTextbox.getValue()); + String author = authorTextbox.getValue(); + String authorEmail = authorEmailTextbox.getValue(); + String maintainer = maintainerTextbox.getValue(); + String maintainerEmail = maintainerEmailTextbox.getValue(); + + // fill the bean + receivedBean.setAuthor(author); + receivedBean.setAuthorEmail(authorEmail); + receivedBean.setDescription(description); + receivedBean.setLicense(selectedLicense); + receivedBean.setMaintainer(maintainer); + receivedBean.setMaintainerEmail(maintainerEmail); + receivedBean.setVersion(version); + receivedBean.setVisibility(visibility.equals("Public")); + receivedBean.setTitle(title); + receivedBean.setSearchable(searchable.equals("Yes")); + receivedBean.setTags(tagsList); + + Map customFieldsMap = new HashMap(); + + // prepare custom fields + for(CustomFieldEntry customEntry : customFieldEntries){ + + String key = customEntry.getKey(); + String value = customEntry.getValue(); + customFieldsMap.put(key, value); + } + + receivedBean.setCustomFields(customFieldsMap); + + // TODO invoke remote service + } + + + } + + /** + * Validate data + * @return true on success + */ + private boolean validateData() { + // TODO Auto-generated method stub + return true; } @UiHandler("resetButton") @@ -119,21 +297,99 @@ public class EditMetadataForm extends Composite{ // reset main fields titleTextBox.setText(""); - urlTextbox.setText(""); descriptionTextarea.setText(""); - tagsTextbox.setText(""); - sourceTextbox.setText(""); versionTextbox.setText(""); authorTextbox.setText(""); authorEmailTextbox.setText(""); maintainerTextbox.setText(""); maintainerEmailTextbox.setText(""); + removeTags(); // delete custom fields for (CustomFieldEntry customField : customFieldEntries) { customField.removeFromParent(); } customFieldEntries.clear(); - + + } + + /** + * change alert block behavior. + * @param textToShow + * @param type + * @param visible + */ + private void setAlertBlock(String textToShow, AlertType type, boolean visible){ + + infoBlock.setText(textToShow); + infoBlock.setType(type); + infoBlock.setVisible(visible); + + } + + @UiHandler("tagsEnterTextBox") + void onAddTag(KeyDownEvent event){ + + if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) { + if (!"".equals(tagsEnterTextBox.getValue().trim())) { + + addTagElement(tagsEnterTextBox); + + } + } + } + + /** + * Add the tag as an element + */ + private void addTagElement(TextBox itemBox){ + + if (itemBox.getValue() != null && !"".equals(itemBox.getValue().trim())) { + + if(tagsList.contains(itemBox.getValue())) + return; + + final String value = itemBox.getValue(); + final ListItem displayItem = new ListItem(); + displayItem.setStyleName("tag-style"); + Span p = new Span(itemBox.getValue()); + + Span span = new Span("x"); + span.setTitle("Remove this tag"); + span.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent clickEvent) { + removeListItem(displayItem, value); + } + }); + + span.setStyleName("tag-style-x"); + displayItem.add(p); + displayItem.add(span); + itemBox.setValue(""); + itemBox.setFocus(true); + tagsPanel.add(displayItem); + tagsList.add(value); + } + } + + + /** + * Remove a tag from the list + * @param displayItem + */ + private void removeListItem(ListItem displayItem, String value) { + GWT.log("Removing: " + displayItem.getWidget(0).getElement().getInnerHTML(), null); + tagsList.remove(value); + tagsPanel.remove(displayItem); + } + + /** + * Remove all inserted tags + */ + private void removeTags(){ + + tagsList.clear(); + tagsPanel.clear(); + } } diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/EditMetadataForm.ui.xml b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/EditMetadataForm.ui.xml index 765c8f5..066cda4 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/EditMetadataForm.ui.xml +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/EditMetadataForm.ui.xml @@ -28,6 +28,11 @@ .block-alert-style { margin-top: 10px; padding: 10px; + margin-bottom: 10px; + } + + .tagsPanelStyle { + display: inline-block; } @@ -37,9 +42,16 @@ Insert Dataset Metadata - * is required + + * + is required + + + + * @@ -52,16 +64,16 @@ - - - * - URL: - - - - - + + + + + + + + + + @@ -74,14 +86,21 @@ + + Tags: - + + + + + + + @@ -104,7 +123,7 @@ - Private + Private Public @@ -120,8 +139,8 @@ - true - false + Yes + No @@ -132,16 +151,16 @@ - - - Source: - - - - - + + + + + + + + + + @@ -155,6 +174,7 @@ + * Author: @@ -165,6 +185,7 @@ + * Author Email: @@ -195,19 +216,19 @@ - Custom Field: - - - - - - - - + Custom Field(s): + + + Custom fields are customable metadata that will be added to the + dataset. + You have to choose a unique key for the field and a value + for this. You + can remove them at any time. + @@ -218,11 +239,6 @@ type="PRIMARY" block="true">Create Reset - - - 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 364754f..d881c32 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 @@ -1,20 +1,32 @@ package org.gcube.portlets.widgets.ckandatapublisherwidget.server; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.gcube.application.framework.core.session.ASLSession; import org.gcube.application.framework.core.session.SessionManager; +import org.gcube.common.homelibrary.home.HomeLibrary; +import org.gcube.common.homelibrary.home.exceptions.InternalErrorException; +import org.gcube.common.homelibrary.home.workspace.Workspace; +import org.gcube.common.homelibrary.home.workspace.WorkspaceItem; +import org.gcube.common.homelibrary.home.workspace.folder.items.GCubeItem; +import org.gcube.common.scope.api.ScopeProvider; import org.gcube.portal.custom.scopemanager.scopehelper.ScopeHelper; import org.gcube.portlets.widgets.ckandatapublisherwidget.client.CKanPublisherService; +import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.DatasetMetadataBean; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.LicensesBean; +import org.gcube.vomanagement.usermanagement.UserManager; +import org.gcube.vomanagement.usermanagement.impl.LiferayUserManager; +import org.gcube.vomanagement.usermanagement.model.GCubeUser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.gwt.user.server.rpc.RemoteServiceServlet; import com.liferay.portal.service.UserLocalServiceUtil; -import eu.trentorise.opendata.jackan.CkanClient; +import eu.trentorise.opendata.jackan.CheckedCkanClient; import eu.trentorise.opendata.jackan.model.CkanLicense; /** @@ -24,9 +36,6 @@ import eu.trentorise.opendata.jackan.model.CkanLicense; @SuppressWarnings("serial") public class CKANPublisherServicesImpl extends RemoteServiceServlet implements CKanPublisherService{ - public static final String HOSTNAME_CKAN = "https://ckan-d-d4s.d4science.org/"; - public static final String API_KEY = "803ada7f-2080-493f-8a99-3e593e880d94"; - // Logger private static final Logger logger = LoggerFactory.getLogger(CKANPublisherServicesImpl.class); @@ -46,6 +55,28 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C return user; } + /** + * Retrieve the ckan portal url by querying the IS + * @return + */ + private String getCKANUrlFromIS(){ + + // TODO + return "https://ckan-d-d4s.d4science.org/"; + + } + + /** + * Retrieve the API_KEY of the current user + * @return + */ + private String getCKANApikeyFromUser(String username){ + + // TODO + return "803ada7f-2080-493f-8a99-3e593e880d94"; + + } + /** * the current ASLSession * @return the session @@ -86,12 +117,16 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C logger.debug("Request for CKAN licenses"); + // get the url and the api key of the user + String ckanPortalUrl = getCKANUrlFromIS(); + String apiKey = getCKANApikeyFromUser(""); // TODO + List result = new ArrayList(); - CkanClient cc = new CkanClient(HOSTNAME_CKAN); + CheckedCkanClient checkedClient = new CheckedCkanClient(ckanPortalUrl, apiKey); //retrieve the list of available licenses - List licenses = cc.getLicenseList(); + List licenses = checkedClient.getLicenseList(); for (CkanLicense ckanLicense : licenses) { result.add(ckanLicense.getTitle()); @@ -101,4 +136,99 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C return new LicensesBean(result); } + @Override + public DatasetMetadataBean getDatasetBean(String folderId, String owner){ + + DatasetMetadataBean bean = null; + ScopeProvider.instance.set("/gcube/devsec/devVRE"); + + if(isWithinPortal()){ + try{ + + logger.debug("Request dataset metadata bean for folder with id " + folderId + + " whose owner is " + owner); + + Workspace ws = HomeLibrary + .getHomeManagerFactory() + .getHomeManager() + .getHome(owner).getWorkspace(); + + WorkspaceItem retrievedItem = ws.getItem(folderId); + + // get usermanager (liferay) + UserManager liferUserManager = new LiferayUserManager(); + GCubeUser userOwner = liferUserManager.getUserByUsername(owner); + + // build bean + logger.debug("Building bean"); + bean = new DatasetMetadataBean(); + + bean.setId(folderId); + bean.setDescription(retrievedItem.getDescription()); + bean.setVersion(1); + bean.setTitle(retrievedItem.getName()); + bean.setAuthor(userOwner.getFullname()); + bean.setAuthorEmail(userOwner.getEmail()); + bean.setMaintainer(userOwner.getFullname()); + bean.setMaintainerEmail(userOwner.getEmail()); + bean.setSource(retrievedItem.getPublicLink(true)); + + // retrieve gcube items of the folder + Map folderItems = getGcubeItemProperties(retrievedItem); + bean.setCustomFields(folderItems); + + }catch(Exception e){ + logger.error("Error while retrieving folder information", e); + } + }else{ + + bean = new DatasetMetadataBean(); + bean.setId(folderId); + bean.setDescription("This is a fantastic description"); + bean.setVersion(1); + bean.setTitle("Dataset name"); + bean.setAuthor("Costantino Perciante"); + bean.setAuthorEmail("costantino.perciante@isti.cnr.it"); + bean.setMaintainer("Costantino Perciante"); + bean.setMaintainerEmail("costantino.perciante@isti.cnr.it"); + bean.setSource("https://dev.d4science.org/group/data-e-infrastructure-gateway/workspace"); + + // retrieve gcube items of the folder + Map folderItems = new HashMap(); + folderItems.put("tag1", "asds"); + folderItems.put("tag2", "asdsdaxcxcs"); + folderItems.put("tag3", "asasdads"); + bean.setCustomFields(folderItems); + + } + + return bean; + } + + /** Gets the gcube item properties. + * + * @param item the item + * @return the gcube item properties + */ + private Map getGcubeItemProperties(WorkspaceItem item) { + + if(item instanceof GCubeItem){ + GCubeItem gItem = (GCubeItem) item; + try { + if(gItem.getProperties()!=null){ + Map map = gItem.getProperties().getProperties(); + HashMap properties = new HashMap(map.size()); //TO PREVENT GWT SERIALIZATION ERROR + for (String key : map.keySet()) + properties.put(key, map.get(key)); + + return properties; + } + } catch (InternalErrorException e) { + logger.error("Error in server getItemProperties: ", e); + return null; + } + } + return null; + } + } diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/DatasetMetadataBean.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/DatasetMetadataBean.java new file mode 100644 index 0000000..ca49a79 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/DatasetMetadataBean.java @@ -0,0 +1,204 @@ +package org.gcube.portlets.widgets.ckandatapublisherwidget.shared; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * This bean will contain during ckan metadata creation the following information + * (related to the workspace folder that represents a dataset) + *
    + *
  • id -> the id of the workspace folder + *
  • Title -> folder's name + *
  • Description -> folders' description + *
  • tags -> folder's custom fields keys' names + *
  • visibility -> as chosen by the creator (visible = true, not visible = false) + *
  • searchable -> as chosen by the creator + *
  • source -> url of the folder within the workspace + *
  • version -> during creation it is going to be 1.0 + *
  • author, maintainer -> folder's owner + *
  • custom fields -> gcube items couple + *
+ * @author Costantino Perciante at ISTI-CNR + * (costantino.perciante@isti.cnr.it) + */ +@SuppressWarnings("serial") +public class DatasetMetadataBean implements Serializable { + + private String id; + private String title; + private String description; + private Map customFields; + List tags; // on retrieve, they are the keys of the custom fields + private String license; // chosen by the user + private boolean visibility; // Private (false) or Public(true) + private boolean searchable; // true or false + private String source; // url of the folder in the workspace + private long version; // version 1, 2 ... + private String author; // folder's owner + private String authorEmail; // folder's email owner + private String maintainer; + private String maintainerEmail; + + public DatasetMetadataBean(){ + super(); + } + + /** Create a metadata bean object. + * @param id + * @param title + * @param description + * @param tags + * @param license + * @param visibility + * @param searchable + * @param source + * @param version + * @param author + * @param authorEmail + * @param maintainer + * @param maintainerEmail + */ + public DatasetMetadataBean(String id, String title, String description, + Map customFields, String license, boolean visibility, + boolean searchable, String source, long version, String author, + String authorEmail, String maintainer, String maintainerEmail) { + super(); + this.id = id; + this.title = title; + this.description = description; + this.customFields = customFields; + this.license = license; + this.visibility = visibility; + this.searchable = searchable; + this.source = source; + this.version = version; + this.author = author; + this.authorEmail = authorEmail; + this.maintainer = maintainer; + this.maintainerEmail = maintainerEmail; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Map getCustomFields() { + return customFields; + } + + public void setCustomFields(Map customFields) { + this.customFields = customFields; + } + + public List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags = tags; + } + + public String getLicense() { + return license; + } + + public void setLicense(String license) { + this.license = license; + } + + public boolean getVisibility() { + return visibility; + } + + public void setVisibility(boolean visibility) { + this.visibility = visibility; + } + + public boolean isSearchable() { + return searchable; + } + + public void setSearchable(boolean searchable) { + this.searchable = searchable; + } + + public String getSource() { + return source; + } + + public void setSource(String source) { + this.source = source; + } + + public long getVersion() { + return version; + } + + public void setVersion(long version) { + this.version = version; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getAuthorEmail() { + return authorEmail; + } + + public void setAuthorEmail(String authorEmail) { + this.authorEmail = authorEmail; + } + + public String getMaintainer() { + return maintainer; + } + + public void setMaintainer(String maintainer) { + this.maintainer = maintainer; + } + + public String getMaintainerEmail() { + return maintainerEmail; + } + + public void setMaintainerEmail(String maintainerEmail) { + this.maintainerEmail = maintainerEmail; + } + + @Override + public String toString() { + return "DatasetMetadataBean [id=" + id + ", title=" + title + + ", description=" + description + ", customFields=" + + customFields + ", tags=" + tags + ", license=" + license + + ", visibility=" + visibility + ", searchable=" + searchable + + ", source=" + source + ", version=" + version + ", author=" + + author + ", authorEmail=" + authorEmail + ", maintainer=" + + maintainer + ", maintainerEmail=" + maintainerEmail + "]"; + } +} diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/LicensesBean.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/LicensesBean.java index ad281dc..738892f 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/LicensesBean.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/LicensesBean.java @@ -12,9 +12,6 @@ public class LicensesBean implements Serializable{ List licenses; - /** - * - */ public LicensesBean() { super(); } diff --git a/src/main/resources/org/gcube/portlets/widgets/ckandatapublisherwidget/CKanMetadataPublisher.gwt.xml b/src/main/resources/org/gcube/portlets/widgets/ckandatapublisherwidget/CKanMetadataPublisher.gwt.xml index cd2dda6..afb8ec1 100644 --- a/src/main/resources/org/gcube/portlets/widgets/ckandatapublisherwidget/CKanMetadataPublisher.gwt.xml +++ b/src/main/resources/org/gcube/portlets/widgets/ckandatapublisherwidget/CKanMetadataPublisher.gwt.xml @@ -9,6 +9,9 @@ + + + diff --git a/src/main/webapp/CKanMetadataPublisher.css b/src/main/webapp/CKanMetadataPublisher.css index 7aca7ac..c7d9e35 100644 --- a/src/main/webapp/CKanMetadataPublisher.css +++ b/src/main/webapp/CKanMetadataPublisher.css @@ -1,34 +1,24 @@ -/** Add css rules here for your application. */ - - -/** Example rules used by the template application (remove for your app) */ -h1 { - font-size: 2em; - font-weight: bold; - color: #777777; - margin: 40px 0px 70px; - text-align: center; +.tag-style { + color: #3a87ad; + background-color: #d9edf7; + border: 2px solid; + border-color: #bce8f1; + padding: 5px; + display: inline; + margin: 2px; + overflow: hidden; + height: auto !important; + font-size: 11px; + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + float: left; + font-size: 15px; } -.sendButton { - display: block; - font-size: 16pt; -} - -/** Most GWT widgets already have a style name defined */ -.gwt-DialogBox { - width: 400px; -} - -.dialogVPanel { - margin: 5px; -} - -.serverResponseLabelError { - color: red; -} - -/** Set ids using widget.getElement().setId("idOfElement") */ -#closeButton { - margin: 15px 6px 6px; -} +.tag-style-x { + color: #a6b3cf !important; + margin-left: 5px !important; + font-weight: bold !important; + cursor: pointer !important; +} \ No newline at end of file diff --git a/src/test/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/Tests.java b/src/test/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/Tests.java new file mode 100644 index 0000000..eb8c520 --- /dev/null +++ b/src/test/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/Tests.java @@ -0,0 +1,67 @@ +package org.gcube.portlets.widgets.ckandatapublisherwidget.client; + +import java.util.ArrayList; +import java.util.List; + +import org.gcube.common.homelibrary.home.exceptions.HomeNotFoundException; +import org.gcube.common.homelibrary.home.exceptions.InternalErrorException; +import org.gcube.common.homelibrary.home.exceptions.UserNotFoundException; +import org.gcube.common.homelibrary.home.workspace.exceptions.WorkspaceFolderNotFoundException; + +import eu.trentorise.opendata.jackan.CheckedCkanClient; +import eu.trentorise.opendata.jackan.CkanClient; +import eu.trentorise.opendata.jackan.model.CkanUser; + +public class Tests { + + //@Test + public static void test() throws WorkspaceFolderNotFoundException, InternalErrorException, HomeNotFoundException, UserNotFoundException { + + // String username ="costantino.perciante"; + // ScopeProvider.instance.set("/gcube/devsec/devVRE"); + // + // Workspace ws = HomeLibrary + // .getHomeManagerFactory() + // .getHomeManager() + // .getHome(username).getWorkspace(); + // + // System.out.println("Created workspace reference"); + // + // WorkspaceFolder rootFolder = ws.getRoot(); + // System.out.println("Root folder has id " + rootFolder.getId()); + // + // List children = rootFolder.getChildren(); + // + // for (WorkspaceItem workspaceItem : children) { + // System.out.println("Children with name " + workspaceItem.getName() + " and id " + workspaceItem.getId()); + // } + + + // get the url and the api key of the user + String ckanPortalUrl = "https://ckan-d-d4s.d4science.org/"; + String apiKey = "803ada7f-2080-493f-8a99-3e593e880d94"; + + List result = new ArrayList(); + + CheckedCkanClient checkedClient = new CheckedCkanClient(ckanPortalUrl, apiKey); + CkanClient client = new CkanClient(ckanPortalUrl); + + List list = client.getUserList(); + for (CkanUser ckanUser : list) { + + System.out.println("User -> " + ckanUser.getId() + " with fullname " + ckanUser.getFullname() + " and name " + ckanUser.getName() + " password " + ckanUser.getPassword()); + + } + } + + public static void main(String[] args) { +// try { +// test(); +// } catch (WorkspaceFolderNotFoundException | InternalErrorException +// | HomeNotFoundException | UserNotFoundException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } + } + +}