diff --git a/.classpath b/.classpath index ce7b7f2..510cf3c 100644 --- a/.classpath +++ b/.classpath @@ -6,13 +6,7 @@ - - - - - - - + @@ -25,8 +19,8 @@ - + @@ -34,5 +28,6 @@ + diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component index c52d75d..abaeb86 100644 --- a/.settings/org.eclipse.wst.common.component +++ b/.settings/org.eclipse.wst.common.component @@ -12,7 +12,7 @@ - + diff --git a/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml b/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml new file mode 100644 index 0000000..cc81385 --- /dev/null +++ b/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml index 3f2dd2b..fe92fc5 100644 --- a/.settings/org.eclipse.wst.common.project.facet.core.xml +++ b/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -4,4 +4,5 @@ + diff --git a/CHANGELOG.md b/CHANGELOG.md index 0690ed3..fe29816 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v2.0.0-SNAPSHOT] - 2021-02-11 + +**Enhancements** + +[#19764] Porting ckan-metadata-publisher-widget to catalogue-util-library +[#20680] Ported to SHUB +[#19568] Unify and extend the tags allowed values +[#20828] Revisited title size and format +[#20868] Redesigned the "Manage Resources" user experience +[#21068] Add Resources facility: only HTTPS URLs must be allowed + + ## [v1.6.2] - 2021-02-08 **Bug Fixes** diff --git a/pom.xml b/pom.xml index 9f2564e..0b8b895 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ org.gcube.portlets.widgets ckan-metadata-publisher-widget - 1.6.2 + 2.0.0-SNAPSHOT gCube Ckan metadata publisher widget diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/CKanMetadataPublisher.gwt.xml b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/CKanMetadataPublisher.gwt.xml index b2174ff..55363b4 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/CKanMetadataPublisher.gwt.xml +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/CKanMetadataPublisher.gwt.xml @@ -9,13 +9,14 @@ - + - + + + children = new ArrayList(); + + SelectResourceByWEMainPanel resourcesSelectByWEMainPanel = new SelectResourceByWEMainPanel(r); - // random strings - for (int i = 0; i < 10; i++) { - - ResourceElementBean child = new ResourceElementBean(); - child.setFolder(false); - child.setName("BLUE_ECONOMY_WP6_TECHNO_ECONOMIC_ANALYSIS_MODEL.CITE.PPTX" + i); - child.setEditableName("BLUE_ECONOMY_WP6_TECHNO_ECONOMIC_ANALYSIS_MODEL.CITE.PPTX" + i); - child.setParent(r); - child.setFullPath("/" + "BLUE_ECONOMY_WP6_TECHNO_ECONOMIC_ANALYSIS_MODEL.CITE.PPTX" + + i); - children.add(child); - - } - - r.setChildren(children); - - // create random childs - resourcesTwinPanel = new TwinColumnSelectionMainPanel(r); - m.add(resourcesTwinPanel); + m.add(resourcesSelectByWEMainPanel); m.show(); } diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/TwinColumnSelection/ResourceCellLeft.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/TwinColumnSelection/ResourceCellLeft.java deleted file mode 100644 index 1a9c681..0000000 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/TwinColumnSelection/ResourceCellLeft.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.TwinColumnSelection; - -import org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.icons.Images; -import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.ResourceElementBean; - -import com.google.gwt.cell.client.AbstractCell; -import com.google.gwt.core.client.GWT; -import com.google.gwt.safehtml.shared.SafeHtmlBuilder; -import com.google.gwt.user.client.ui.Image; -/** - * Cell that renders left side panel objects - * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) - */ -public class ResourceCellLeft extends AbstractCell{ - private static final Images image = GWT.create(Images.class); - private static final String tipFile = "Hold down the Control (ctrl) or Command button to select multiple options"; - private static final String tipFolder = "Click on the folder to navigate it"; - - @Override - public void render(com.google.gwt.cell.client.Cell.Context context, - ResourceElementBean value, SafeHtmlBuilder sb) { - - if (value == null || value.isToBeAdded()) { - return; - } - - Image file = new Image(image.fileIcon()); - Image folder = new Image(image.folderIcon()); - file.setWidth("15px"); - file.setHeight("15px"); - folder.setWidth("15px"); - folder.setHeight("15px"); - - String whichTip = value.isFolder() ? tipFolder : tipFile; - sb.appendHtmlConstant("
"); - sb.appendHtmlConstant(""); - sb.appendHtmlConstant(value.isFolder() ? folder.toString() : file.toString()); - sb.appendHtmlConstant(""); - sb.appendHtmlConstant(""); - sb.appendHtmlConstant(""); - sb.appendEscaped(value.getName()); - sb.appendHtmlConstant(""); - sb.appendHtmlConstant(""); - sb.appendHtmlConstant("
"); - } -} diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/TwinColumnSelection/ResourceCellRight.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/TwinColumnSelection/ResourceCellRight.java deleted file mode 100644 index e4f7748..0000000 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/TwinColumnSelection/ResourceCellRight.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.TwinColumnSelection; - -import org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.icons.Images; -import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.ResourceElementBean; - -import com.google.gwt.cell.client.AbstractCell; -import com.google.gwt.cell.client.ValueUpdater; -import com.google.gwt.core.client.GWT; -import com.google.gwt.dom.client.Element; -import com.google.gwt.dom.client.NativeEvent; -import com.google.gwt.safehtml.shared.SafeHtmlBuilder; -import com.google.gwt.user.client.ui.Image; - -/** - * Cell that renders right side panel objects - * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) - */ -public class ResourceCellRight extends AbstractCell{ - - private static final Images image = GWT.create(Images.class); - private static final String tip = "Hold down the Control (CTRL) or Command button to select multiple options. Double click to access " - + "this resource information"; - - public ResourceCellRight() { - super("keydown", "dblclick"); - } - - @Override - public void render(com.google.gwt.cell.client.Cell.Context context, - ResourceElementBean value, SafeHtmlBuilder sb) { - - if (value == null || !value.isToBeAdded() || value.isFolder()) { - return; - } - - Image file = new Image(image.fileIcon()); - file.setWidth("15px"); - file.setHeight("15px"); - - sb.appendHtmlConstant("
"); - sb.appendHtmlConstant(""); - sb.appendHtmlConstant(file.toString()); - sb.appendHtmlConstant(""); - sb.appendHtmlConstant(""); - sb.appendHtmlConstant(""); - sb.appendEscaped(value.getEditableName()); - sb.appendHtmlConstant(""); - sb.appendHtmlConstant(""); - sb.appendHtmlConstant("
"); - } - - @Override - public void onBrowserEvent(com.google.gwt.cell.client.Cell.Context context, - Element parent, ResourceElementBean value, NativeEvent event, - ValueUpdater valueUpdater) { - if(value == null || TwinColumnSelectionMainPanel.isFroozen()) - return; - super.onBrowserEvent(context, parent, value, event, valueUpdater); - ResourceInfoForm info = new ResourceInfoForm(value, valueUpdater); - if(TwinColumnSelectionMainPanel.detailContainer.getWidget() != null) - TwinColumnSelectionMainPanel.detailContainer.clear(); - TwinColumnSelectionMainPanel.detailContainer.add(info); - TwinColumnSelectionMainPanel.detailContainer.setVisible(true); - } -} diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/TwinColumnSelection/ResourceInfoForm.ui.xml b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/TwinColumnSelection/ResourceInfoForm.ui.xml deleted file mode 100644 index c9d29ce..0000000 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/TwinColumnSelection/ResourceInfoForm.ui.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - - .legend-style { - width: 100%; - padding: 10px; - margin-bottom: 0px; - font-size: 14px; - } - - .panel-style { - padding: 5px; - border: 1px solid #bbb; - border-radius: 5px; - height: 400px; - width: 95%; - } - - .labels-style { - color: #999; - } - - .controls-style { - margin-left: 10px !important; - } - - .control-group { - margin-bottom: 0px !important; - } - - - - - - Resource Information - - - - - Name: - - - - - - - - Path: - - - - - - - - Description: - - - - - - - - Format: - - - - - - - - Update - - - - - \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/TwinColumnSelection/ShowMorePagerPanel.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/TwinColumnSelection/ShowMorePagerPanel.java deleted file mode 100644 index 8a8f4cf..0000000 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/TwinColumnSelection/ShowMorePagerPanel.java +++ /dev/null @@ -1,101 +0,0 @@ -package org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.TwinColumnSelection; - -import com.google.gwt.event.dom.client.ScrollEvent; -import com.google.gwt.event.dom.client.ScrollHandler; -import com.google.gwt.user.cellview.client.AbstractPager; -import com.google.gwt.user.client.ui.ScrollPanel; -import com.google.gwt.user.client.ui.Widget; -import com.google.gwt.view.client.HasRows; - -/** - * Basically a scroll panel - * Partially changed from the code at http://samples.gwtproject.org/samples/Showcase/Showcase.html#!CwCellList - * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) - */ -public class ShowMorePagerPanel extends AbstractPager{ - - /** - * The default increment size. - */ - public static final int DEFAULT_INCREMENT = 10; - - /** - * The increment size. - */ - private int incrementSize = DEFAULT_INCREMENT; - - /** - * The last scroll position. - */ - private int lastScrollPos = 0; - - /** - * The scrollable panel. - */ - private final ScrollPanel scrollable = new ScrollPanel(); - - /** - * Construct a new {@link ShowMorePagerPanel}. - */ - public ShowMorePagerPanel() { - initWidget(scrollable); - - // Do not let the scrollable take tab focus. - scrollable.getElement().setTabIndex(-1); - - // Handle scroll events. - scrollable.addScrollHandler(new ScrollHandler() { - public void onScroll(ScrollEvent event) { - // If scrolling up, ignore the event. - int oldScrollPos = lastScrollPos; - lastScrollPos = scrollable.getVerticalScrollPosition(); - if (oldScrollPos >= lastScrollPos) { - return; - } - - HasRows display = getDisplay(); - if (display == null) { - return; - } - int maxScrollTop = scrollable.getWidget().getOffsetHeight() - - scrollable.getOffsetHeight(); - if (lastScrollPos >= maxScrollTop) { - // We are near the end, so increase the page size. - int newPageSize = Math.min( - display.getVisibleRange().getLength() + incrementSize, - display.getRowCount()); - display.setVisibleRange(0, newPageSize); - } - } - }); - } - - /** - * Get the number of rows by which the range is increased when the scrollbar - * reaches the bottom. - * @return the increment size - */ - public int getIncrementSize() { - return incrementSize; - } - - @Override - public void setDisplay(HasRows display) { - assert display instanceof Widget : "display must extend Widget"; - scrollable.setWidget((Widget) display); - super.setDisplay(display); - } - - /** - * Set the number of rows by which the range is increased when the scrollbar - * reaches the bottom. - * @param incrementSize the incremental number of rows - */ - public void setIncrementSize(int incrementSize) { - this.incrementSize = incrementSize; - } - - @Override - protected void onRangeOrRowCountChanged() { - } -} diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/TwinColumnSelection/TwinColumnSelectionMainPanel.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/TwinColumnSelection/TwinColumnSelectionMainPanel.java deleted file mode 100644 index 67b3d9c..0000000 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/TwinColumnSelection/TwinColumnSelectionMainPanel.java +++ /dev/null @@ -1,571 +0,0 @@ -package org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.TwinColumnSelection; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.ResourceElementBean; - -import com.github.gwtbootstrap.client.ui.Breadcrumbs; -import com.github.gwtbootstrap.client.ui.Button; -import com.github.gwtbootstrap.client.ui.FluidContainer; -import com.github.gwtbootstrap.client.ui.NavLink; -import com.google.gwt.cell.client.ValueUpdater; -import com.google.gwt.core.client.GWT; -import com.google.gwt.dom.client.Style.BorderStyle; -import com.google.gwt.dom.client.Style.FontWeight; -import com.google.gwt.dom.client.Style.Unit; -import com.google.gwt.event.dom.client.ClickEvent; -import com.google.gwt.event.dom.client.ClickHandler; -import com.google.gwt.uibinder.client.UiBinder; -import com.google.gwt.uibinder.client.UiField; -import com.google.gwt.user.cellview.client.CellList; -import com.google.gwt.user.cellview.client.HasKeyboardPagingPolicy.KeyboardPagingPolicy; -import com.google.gwt.user.client.ui.Composite; -import com.google.gwt.user.client.ui.SimplePanel; -import com.google.gwt.user.client.ui.VerticalPanel; -import com.google.gwt.user.client.ui.Widget; -import com.google.gwt.view.client.ListDataProvider; -import com.google.gwt.view.client.MultiSelectionModel; -import com.google.gwt.view.client.SelectionChangeEvent; - -/** - * The twin column panels for selection of the files to attach to the catalague product. - * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) - * @author Francesco Mangiacrapa at ISTI-CNR - */ -public class TwinColumnSelectionMainPanel extends Composite{ - - @UiField - VerticalPanel leftContainer; - @UiField - VerticalPanel rightContainer; - @UiField - VerticalPanel buttonsPanel; - @UiField - Button allToRightButton; - @UiField - Button toRightButton; - @UiField - Button toLeftButton; - @UiField - Button allToLeftButton; - // @UiField - // Popover popoverResourceSelection; - // @UiField - // Button resourceInfoButton; - @UiField - Breadcrumbs breadcrumbs; - @UiField - FluidContainer mainContainerResourcesSelection; - // @UiField - // Button getResources; - @UiField - public static SimplePanel detailContainer; - - /** - * The breadcrumb subpath with the linked folder - * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) - */ - private class PathBean{ - NavLink link; - ResourceElementBean resourceFolder; - - PathBean(NavLink link, ResourceElementBean resourceFolder){ - this.link = link; - this.resourceFolder = resourceFolder; - } - } - - private static boolean frozen = false; - private List pathListBeans = new ArrayList(); - private static final String PANEL_BORDER_COLOR = "#8899a6"; - private static final String PANEL_HEIGHT = "400px"; - private ShowMorePagerPanel showMorePanelLeft = new ShowMorePagerPanel(); - private ShowMorePagerPanel showMorePanelRight = new ShowMorePagerPanel(); - private CellList cellListLeft; - private CellList cellListRight; - private ListDataProvider dataProviderLeft = new ListDataProvider(); - private ListDataProvider dataProviderRight = new ListDataProvider(); - private MultiSelectionModel selectionModelRight; - private MultiSelectionModel selectionModelLeft; - private final ResourceElementBean initialBean; - // private final static HTML aboutHeader = new HTML("Resource Manager"); - // private final static HTML aboutBody = new HTML("

Move the files you want to attach to the product on the right panel below." - // + " Please consider that any complex hierarchy structure you may have will be flatten.

"); - - // private static final short PATH_THRESHOLD = 1; // TODO - - private static TwinColumnSelectionMainPanelUiBinder uiBinder = GWT - .create(TwinColumnSelectionMainPanelUiBinder.class); - - interface TwinColumnSelectionMainPanelUiBinder extends - UiBinder { - } - - public TwinColumnSelectionMainPanel(ResourceElementBean initialBean) { - initWidget(uiBinder.createAndBindUi(this)); - frozen = false; - - GWT.log(initialBean.toString()); - - this.initialBean = initialBean; - - buttonsPanel.getElement().getStyle().setMarginTop(50, Unit.PCT); - allToRightButton.getElement().getStyle().setMarginBottom(4, Unit.PX); - toRightButton.getElement().getStyle().setMarginBottom(4, Unit.PX); - toLeftButton.getElement().getStyle().setMarginBottom(4, Unit.PX); - allToLeftButton.getElement().getStyle().setMarginBottom(4, Unit.PX); - - buttonsPanel.getElement().setAttribute("align", "center"); - // popoverResourceSelection.setPlacement(Placement.LEFT); - // popoverResourceSelection.setHeading(aboutHeader.getHTML()); - // popoverResourceSelection.setText(aboutBody.getHTML()); - // resourceInfoButton.getElement().getStyle().setFloat(Float.RIGHT); - // resourceInfoButton.getElement().getStyle().setPaddingRight(0, Unit.PX); - mainContainerResourcesSelection.getElement().getStyle().setPadding(10, Unit.PX); - - breadcrumbs.getElement().getStyle().setBackgroundColor("white"); - breadcrumbs.getElement().getStyle().setFontWeight(FontWeight.BOLD); - breadcrumbs.getElement().getStyle().setMarginLeft(0, Unit.PX); - mainContainerResourcesSelection.getElement().getStyle().setMarginLeft(10, Unit.PX); - mainContainerResourcesSelection.getElement().getStyle().setMarginBottom(20, Unit.PX); - mainContainerResourcesSelection.getElement().getStyle().setMarginTop(0, Unit.PX); - - prepareHandlers(); - initLeftSidePanel(initialBean); - initRightSidePanel(); - } - - /** - * Initialize the left side panel - */ - private void initLeftSidePanel(final ResourceElementBean initialBean) { - - // initialize the left side list - ResourceCellLeft cell = new ResourceCellLeft(); - - // Set a key provider that provides a unique key for each object. - cellListLeft = new CellList(cell, ResourceElementBean.KEY_PROVIDER); - cellListLeft.setKeyboardPagingPolicy(KeyboardPagingPolicy.INCREASE_RANGE); - - // set page size - int size = initialBean.isFolder() ? initialBean.getChildren().size() : 1; - cellListLeft.setPageSize(size); - - // Add a selection model so we can select cells. - selectionModelLeft = new MultiSelectionModel(ResourceElementBean.KEY_PROVIDER); - cellListLeft.setSelectionModel(selectionModelLeft); - - // perform an action on selection - selectionModelLeft.addSelectionChangeHandler(new SelectionChangeEvent.Handler() { - - public void onSelectionChange(SelectionChangeEvent event) { - - if(frozen) - return; - - Iterator selectedObjectsIterator = selectionModelLeft.getSelectedSet().iterator(); - - while (selectedObjectsIterator.hasNext()) { - ResourceElementBean selectedBean = selectedObjectsIterator.next(); - if(selectedBean.isFolder()){ - - // a single folder selected - if(selectionModelLeft.getSelectedSet().size() == 1){ - - // update path - final NavLink navElem = new NavLink(selectedBean.getName()); - navElem.getElement().getStyle().setFontWeight(FontWeight.BOLD); - final PathBean pathBean = new PathBean(navElem, selectedBean); - - navElem.addClickHandler(new ClickHandler() { - - @Override - public void onClick(ClickEvent event) { - - removeStartingFromBreadcrumbs(navElem, pathBean); - GWT.log("Clicked on element " + pathBean.resourceFolder.getName()); - //breadcrumbsUpdater(); - ResourceElementBean folder = pathBean.resourceFolder; - Collections.sort(folder.getChildren()); - dataProviderLeft.setList(folder.getChildren()); - dataProviderLeft.refresh(); - - } - }); - - pathListBeans.add(pathBean); - breadcrumbs.add(navElem); - //breadcrumbsUpdater(); - - Collections.sort(selectedBean.getChildren()); - GWT.log("Children " + selectedBean.getChildren()); - dataProviderLeft.setList(selectedBean.getChildren()); - cellListLeft.setPageSize(selectedBean.getChildren().size()); - dataProviderLeft.refresh(); - } - selectionModelLeft.setSelected(selectedBean, false); - } - } - // enable the buttons that allows to move the objects to the right - enableMoveToRightButtons(selectionModelLeft.getSelectedSet()); - } - }); - - // set the list into the provider - if(initialBean.isFolder()){ - Collections.sort(this.initialBean.getChildren()); - dataProviderLeft.setList(this.initialBean.getChildren()); - }else - dataProviderLeft.setList(Arrays.asList(this.initialBean)); - - // add root to breadcrumb - final NavLink root = new NavLink(initialBean.getName()); - final PathBean pathBean = new PathBean(root, initialBean); - root.getElement().getStyle().setFontWeight(FontWeight.BOLD); - pathListBeans.add(pathBean); - breadcrumbs.add(root); - - root.addClickHandler(new ClickHandler() { - - @Override - public void onClick(ClickEvent event) { - - removeStartingFromBreadcrumbs(root, pathBean); - //breadcrumbsUpdater(); - - // set back the root content list - dataProviderLeft.setList(initialBean.getChildren()); - cellListLeft.setPageSize(initialBean.getChildren().size()); - dataProviderLeft.refresh(); - - } - }); - - // set the cell list into the provider - dataProviderLeft.addDataDisplay(cellListLeft); - - // manage showMorePanelLeft - showMorePanelLeft.setDisplay(cellListLeft); - showMorePanelLeft.setHeight(PANEL_HEIGHT); - showMorePanelLeft.getElement().getStyle().setBorderStyle(BorderStyle.SOLID); - showMorePanelLeft.getElement().getStyle().setBorderWidth(2, Unit.PX); - showMorePanelLeft.getElement().getStyle().setBorderColor(PANEL_BORDER_COLOR); - - // add the list to the leftContainerPanel - leftContainer.add(showMorePanelLeft); - } - - /** - * Update the path - * @param navElem - * @param pathBean - */ - public void removeStartingFromBreadcrumbs(NavLink navElem, PathBean pathBean){ - - // remove data after - Iterator iteratorBreadcrumb = breadcrumbs.iterator(); - Iterator iteratorListPath = pathListBeans.iterator(); - - boolean delete = false; - while(iteratorBreadcrumb.hasNext()){ - Widget current = iteratorBreadcrumb.next(); - - if(delete){ - current.removeFromParent(); - iteratorBreadcrumb.remove(); - } - - if(!delete && navElem.equals(current)) - delete = true; - } - - delete = false; - while(iteratorListPath.hasNext()){ - PathBean current = iteratorListPath.next(); - - if(delete) - iteratorListPath.remove(); - - if(!delete && pathBean.equals(current)) - delete = true; - } - - } - - /** - * Initialize the left side panel - */ - private void initRightSidePanel() { - - // initialize the left side list - ResourceCellRight cell = new ResourceCellRight(); - - // Set a key provider that provides a unique key for each object. - cellListRight = new CellList(cell, ResourceElementBean.KEY_PROVIDER); - cellListRight.setKeyboardPagingPolicy(KeyboardPagingPolicy.INCREASE_RANGE); - cellListRight.setValueUpdater(new ValueUpdater() { - - @Override - public void update(ResourceElementBean value) { - - // just redraw the list - cellListRight.redraw(); - - } - }); - - // Add a selection model so we can select cells. - selectionModelRight = new MultiSelectionModel(ResourceElementBean.KEY_PROVIDER); - cellListRight.setSelectionModel(selectionModelRight); - - // perform an action on selection - selectionModelRight.addSelectionChangeHandler(new SelectionChangeEvent.Handler() { - public void onSelectionChange(SelectionChangeEvent event) { - - if(frozen) - return; - - enableMoveToLeftButtons(selectionModelRight.getSelectedSet()); - } - }); - - // set the cell list into the provider - dataProviderRight.addDataDisplay(cellListRight); - - // manage showMorePanelRight - showMorePanelRight.setDisplay(cellListRight); - showMorePanelRight.setHeight(PANEL_HEIGHT); - showMorePanelRight.getElement().getStyle().setBorderStyle(BorderStyle.SOLID); - showMorePanelRight.getElement().getStyle().setBorderWidth(2, Unit.PX); - showMorePanelRight.getElement().getStyle().setBorderColor(PANEL_BORDER_COLOR); - - // add the list to the leftContainerPanel - rightContainer.add(showMorePanelRight); - - } - - /** - * Enable/disable the buttons to move objects from left to right properly. - * @param setselectedItemsLeft - */ - private void enableMoveToRightButtons(Set setselectedItemsLeft){ - - if(setselectedItemsLeft == null || setselectedItemsLeft.isEmpty()){ - allToRightButton.setEnabled(false); - toRightButton.setEnabled(false); - } - else if(setselectedItemsLeft.size() > 1){ - allToRightButton.setEnabled(true); - toRightButton.setEnabled(false); - } - else{ - allToRightButton.setEnabled(false); - toRightButton.setEnabled(true); - } - } - - /** - * Enable/disable the buttons to move objects from right to left properly. - * @param setselectedItemsRight - */ - private void enableMoveToLeftButtons(Set setselectedItemsRight){ - - if(setselectedItemsRight == null || setselectedItemsRight.isEmpty()){ - allToLeftButton.setEnabled(false); - allToLeftButton.setEnabled(false); - } - else if(setselectedItemsRight.size() > 1){ - allToLeftButton.setEnabled(true); - toLeftButton.setEnabled(false); - } - else{ - allToLeftButton.setEnabled(false); - toLeftButton.setEnabled(true); - } - } - - /** - * Prepare the buttons' handlers - */ - private void prepareHandlers() { - - allToRightButton.addClickHandler(new ClickHandler() { - @Override - public void onClick(ClickEvent event) { - moveToRight(selectionModelLeft.getSelectedSet()); - } - }); - - toRightButton.addClickHandler(new ClickHandler() { - @Override - public void onClick(ClickEvent event) { - moveToRight(selectionModelLeft.getSelectedSet()); - } - }); - - allToLeftButton.addClickHandler(new ClickHandler() { - @Override - public void onClick(ClickEvent event) { - moveToLeft(selectionModelRight.getSelectedSet()); - } - }); - - toLeftButton.addClickHandler(new ClickHandler() { - @Override - public void onClick(ClickEvent event) { - moveToLeft(selectionModelRight.getSelectedSet()); - } - }); - } - - /** - * Move to right elements - * @param set the elements to move - */ - private void moveToRight(Set setSelected){ - - if(setSelected == null || setSelected.isEmpty()) - return; - - Iterator iterator = setSelected.iterator(); - while (iterator.hasNext()) { - ResourceElementBean resourceElementBean = iterator - .next(); - resourceElementBean.setToBeAdded(true); - - int indexRight = dataProviderRight.getList().indexOf(resourceElementBean); - if(indexRight >= 0) - dataProviderRight.getList().set(indexRight, resourceElementBean); - else{ - dataProviderRight.getList().add(resourceElementBean); - Collections.sort(dataProviderRight.getList()); - dataProviderRight.refresh(); - } - - int indexLeft = dataProviderLeft.getList().indexOf(resourceElementBean); - dataProviderLeft.getList().set(indexLeft, resourceElementBean); - } - } - - /** - * Move to left elements - * @param setSelected the elements to move - */ - private void moveToLeft(Set setSelected){ - - if(setSelected == null || setSelected.isEmpty()) - return; - - Iterator iterator = setSelected.iterator(); - while (iterator.hasNext()) { - ResourceElementBean resourceElementBean = iterator.next(); - resourceElementBean.setToBeAdded(false); - } - - Collections.sort(dataProviderLeft.getList()); - dataProviderLeft.refresh(); - dataProviderRight.refresh(); - } - - /** - * Freeze the panel - */ - public void freeze() { - - frozen = true; - - Iterator iteratorOverPath = breadcrumbs.iterator(); - while (iteratorOverPath.hasNext()) { - Widget widget = iteratorOverPath.next(); - if(widget instanceof NavLink) - ((NavLink)widget).setActive(false); - } - - allToRightButton.setEnabled(false); - toRightButton.setEnabled(false); - allToLeftButton.setEnabled(false); - toLeftButton.setEnabled(false); - } - - /** - * Returns the root parent with the children as files to save - * @return the resources to save - */ - public ResourceElementBean getResourcesToPublish(){ - - List current = dataProviderRight.getList(); - - ResourceElementBean toReturn = new ResourceElementBean(); - List children = new ArrayList(); - - for (ResourceElementBean resource : current) { - if(resource.isToBeAdded() && !resource.isFolder()){ // be sure ... - ResourceElementBean beanWithoutChildren = new ResourceElementBean(resource); - beanWithoutChildren.setName(resource.getEditableName()); - children.add(beanWithoutChildren); - } - } - - toReturn.setChildren(children); - return toReturn; - } - - - /** - * @return the freezed - */ - public static boolean isFroozen() { - - return frozen; - } - - // @UiHandler("getResources") - // void getResources(ClickEvent ce){ - // getResourcesToPublish(); - // } - // - // /** - // * Short the current path if needed - // */ - // private void breadcrumbsUpdater(){ - // - // // ignore first and last elem - // boolean reduce = (pathListBeans.size() - 2) > PATH_THRESHOLD; - // - // GWT.log("Is to reduce? " + reduce); - // - // GWT.log("Full size is " + pathListBeans.size()); - // - // if(!reduce){ - // GWT.log("Restore"); - // for(int i = 0; i < pathListBeans.size(); i++){ - // PathBean bean = pathListBeans.get(i); - // GWT.log("Elem is " + bean.resourceFolder); - // bean.link.setText(bean.resourceFolder.getName()); - // bean.link.setVisible(true); - // } - // }else{ - // for(int i = 1; i < pathListBeans.size(); i++){ - // PathBean bean = pathListBeans.get(i); - // - // if(i == (pathListBeans.size() - 1)){ - // bean.link.setText(bean.resourceFolder.getName()); - // bean.link.setVisible(true); - // }else if(i == (pathListBeans.size() - 2)){ - // GWT.log("The last to modify ****" + bean.resourceFolder.getName()); - // bean.link.setText("..."); - // bean.link.setVisible(true); - // }else{ - // bean.link.setText(bean.resourceFolder.getName()); - // bean.link.setVisible(false); - // } - // } - // } - // GWT.log("Updated list is " + pathListBeans.toString()); - // } -} \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/TwinColumnSelection/TwinColumnSelectionMainPanel.ui.xml b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/TwinColumnSelection/TwinColumnSelectionMainPanel.ui.xml deleted file mode 100644 index 0fbe728..0000000 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/TwinColumnSelection/TwinColumnSelectionMainPanel.ui.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file 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 f0b625a..f45be57 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 @@ -1,6 +1,7 @@ package org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.form; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -15,7 +16,6 @@ import org.gcube.portlets.widgets.ckandatapublisherwidget.client.events.CloseCre import org.gcube.portlets.widgets.ckandatapublisherwidget.client.events.CloseCreationFormEventHandler; import org.gcube.portlets.widgets.ckandatapublisherwidget.client.events.DeleteCustomFieldEvent; import org.gcube.portlets.widgets.ckandatapublisherwidget.client.events.DeleteCustomFieldEventHandler; -import org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.TwinColumnSelection.TwinColumnSelectionMainPanel; import org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.metadata.CategoryPanel; import org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.metadata.CustomFieldEntry; import org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.metadata.MetaDataFieldSkeleton; @@ -24,6 +24,8 @@ import org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.resources.Ad import org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.resources.AddedResourcesSummary; import org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.tags.TagsPanel; import org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.utils.InfoIconsLabels; +import org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.utils.WizardCreator; +import org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.workspace.SelectResourceByWEMainPanel; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.DatasetBean; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.OrganizationBean; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.licenses.LicenseBean; @@ -45,6 +47,7 @@ import com.github.gwtbootstrap.client.ui.TextArea; import com.github.gwtbootstrap.client.ui.TextBox; import com.github.gwtbootstrap.client.ui.constants.AlertType; import com.github.gwtbootstrap.client.ui.constants.ControlGroupType; +import com.github.gwtbootstrap.client.ui.constants.ResizeType; import com.github.gwtbootstrap.client.ui.resources.Bootstrap.Tabs; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.SelectElement; @@ -163,11 +166,13 @@ public class CreateDatasetForm extends Composite{ @UiField ControlGroup versionControlGroup; @UiField ControlGroup organizationsGroup; @UiField ControlGroup groupsControlGroup; + + @UiField HTMLPanel wizardCreatorPanel; // Create a remote service proxy to talk to the server-side ckan service. private final CKanPublisherServiceAsync ckanServices = GWT.create(CKanPublisherService.class); - private static final String REGEX_TITLE_PRODUCT_SUBWORD = "[^a-zA-Z0-9_.-]"; + //private static final String REGEX_TITLE_PRODUCT_SUBWORD = "[^a-zA-Z0-9_.-]"; private static final String REGEX_MAIL = "\\b[\\w.%-]+@[-.\\w]+\\.[A-Za-z]{2,4}\\b"; private static final String NONE_PROFILE = "none"; @@ -205,13 +210,18 @@ public class CreateDatasetForm extends Composite{ private boolean isWorkspaceRequest = false; // resource table - private TwinColumnSelectionMainPanel resourcesTwinPanel; + //private TwinColumnSelectionMainPanel resourcesTwinPanel; + + // resource table + private SelectResourceByWEMainPanel resourcesSelectByWEMainPanel; // List of opened popup'ids private List popupOpenedIds = new ArrayList(); // map of organization name title private Map nameTitleOrganizationMap = new HashMap(); + + private WizardCreator wizCreator; /** * Invoked in the most general case @@ -265,6 +275,18 @@ public class CreateDatasetForm extends Composite{ initWidget(uiBinder.createAndBindUi(this)); this.eventBus = eventBus; this.isWorkspaceRequest = isWorkspaceRequest; + + List listOfSteps = null; + if(isWorkspaceRequest) { + listOfSteps = Arrays.asList("Edit Common Metadata","Select Item Resources", "Edit Item Specific Metadata & Publish"); + }else { + listOfSteps = Arrays.asList("Edit Common Metadata", "Edit Item Specific Metadata & Publish"); + } + + this.wizCreator = new WizardCreator(listOfSteps); + wizardCreatorPanel.add(wizCreator); + + this.descriptionTextarea.setResize(ResizeType.VERTICAL); bind(); prepareInfoIcons(); @@ -361,7 +383,8 @@ public class CreateDatasetForm extends Composite{ alertNoResources.setType(AlertType.WARNING); alertNoResources.setVisible(true); }else - resourcesTwinPanel = new TwinColumnSelectionMainPanel(bean.getResourceRoot()); + //resourcesSelectByWEMainPanel = new TwinColumnSelectionMainPanel(bean.getResourceRoot()); + resourcesSelectByWEMainPanel = new SelectResourceByWEMainPanel(bean.getResourceRoot()); } // set organizations @@ -426,6 +449,13 @@ public class CreateDatasetForm extends Composite{ setAlertBlock("An unknow error occurred while retrieving types, sorry", AlertType.ERROR, true); } else{ + + GWT.log("Profile returned are: "+profiles.size()); + if(!GWT.isProdMode()) { + for (MetaDataProfileBean profile : profiles) { + GWT.log("Profile title: "+profile.getTitle() + ", type: "+profile.getType()); + } + } receivedBean.setMetadataList(profiles); prepareMetadataList(receivedBean); @@ -850,13 +880,22 @@ public class CreateDatasetForm extends Composite{ // we need to show the page to handle resources one by one from the workspace formFirstStep.setVisible(false); - formSecondStep.setVisible(!hideManageResources()); - formThirdStep.setVisible(hideManageResources()); + boolean hideManageRes = hideManageResources(); + int stepActive = -1; + if(hideManageRes) { + stepActive = 3; + }else { + stepActive = 2; + } + + formSecondStep.setVisible(!hideManageRes); + formThirdStep.setVisible(hideManageRes); + activeWizardStep(stepActive); // add the resources to the container panel if(workspaceResourcesContainer.getWidget() == null){ workspaceResourcesContainer.getElement().getStyle().setMarginLeft(20, Unit.PX); - workspaceResourcesContainer.add(resourcesTwinPanel); + workspaceResourcesContainer.add(resourcesSelectByWEMainPanel); } }else{ @@ -864,6 +903,7 @@ public class CreateDatasetForm extends Composite{ // this is not a workspace request formFirstStep.setVisible(false); formThirdStep.setVisible(true); + activeWizardStep(2); } @@ -873,6 +913,12 @@ public class CreateDatasetForm extends Composite{ selectedProfile.setText("Selected Type is " + metadataTypeListbox.getSelectedItemText()); } + + private void activeWizardStep(int step) { + if(wizCreator!=null) { + wizCreator.activeStep(step); + } + } @UiHandler("goBackButtonFirstStep") @@ -880,6 +926,7 @@ public class CreateDatasetForm extends Composite{ // swap forms formFirstStep.setVisible(true); + activeWizardStep(1); formSecondStep.setVisible(false); formThirdStep.setVisible(false); @@ -891,11 +938,21 @@ public class CreateDatasetForm extends Composite{ // swap forms if(isWorkspaceRequest){ - formFirstStep.setVisible(hideManageResources()); - formSecondStep.setVisible(!hideManageResources()); + boolean hideManageRes = hideManageResources(); + int stepActive = -1; + if(hideManageRes) { + stepActive = 1; + }else { + stepActive = 2; + } + formFirstStep.setVisible(hideManageRes); + formSecondStep.setVisible(!hideManageRes); + activeWizardStep(stepActive); }else{ + formFirstStep.setVisible(true); formSecondStep.setVisible(false); + activeWizardStep(1); } formThirdStep.setVisible(false); @@ -907,6 +964,7 @@ public class CreateDatasetForm extends Composite{ // swap forms formSecondStep.setVisible(false); formThirdStep.setVisible(true); + activeWizardStep(3); } @@ -1022,8 +1080,12 @@ public class CreateDatasetForm extends Composite{ receivedBean.setSelectedOrganization(chosenOrganization); receivedBean.setGroups(groups); receivedBean.setGroupsForceCreation(groupsToForceCreation); - if(resourcesTwinPanel != null) - receivedBean.setResourceRoot(resourcesTwinPanel.getResourcesToPublish()); + + + if(resourcesSelectByWEMainPanel != null) { + receivedBean.setResourceRoot(resourcesSelectByWEMainPanel.getResourcesToPublish()); + } + receivedBean.setCustomFields(customFieldsMap); // alert @@ -1358,7 +1420,7 @@ public class CreateDatasetForm extends Composite{ } }; - t.schedule(10000); + t.schedule(15000); } } @@ -1381,17 +1443,23 @@ public class CreateDatasetForm extends Composite{ productTitleGroup.setType(ControlGroupType.ERROR); return "Missing title"; } + + if(title.length()<2) { + productTitleGroup.setType(ControlGroupType.ERROR); + return "The field title is too short"; + } // better check for the title - String[] splittedTitle = title.split(" "); + //String[] splittedTitle = title.split(" "); + /* No check, see #20828 for (String word : splittedTitle) { String replaced = word.replaceAll(REGEX_TITLE_PRODUCT_SUBWORD, ""); if(!replaced.equals(word)){ productTitleGroup.setType(ControlGroupType.ERROR); return "Please note not all characters are allowed for the title"; } - } + }*/ // email reg expression String maintainerMail = maintainerEmailTextbox.getText(); @@ -1490,8 +1558,8 @@ public class CreateDatasetForm extends Composite{ } // freeze table of resources - if(resourcesTwinPanel != null) - resourcesTwinPanel.freeze(); + if(resourcesSelectByWEMainPanel != null) + resourcesSelectByWEMainPanel.freeze(); } /** @@ -1568,8 +1636,8 @@ public class CreateDatasetForm extends Composite{ */ private boolean hideManageResources(){ - return receivedBean.getResourceRoot() == null || receivedBean.getResourceRoot().isFolder() && (receivedBean.getResourceRoot().getChildren() == null || - receivedBean.getResourceRoot().getChildren().isEmpty()); + return receivedBean.getResourceRoot() == null || receivedBean.getResourceRoot().isFolder() && (receivedBean.getResourceRoot().getChildrenSize() == null || + receivedBean.getResourceRoot().getChildrenSize()==0); } } \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/form/CreateDatasetForm.ui.xml b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/form/CreateDatasetForm.ui.xml index cf4440a..f047f41 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/form/CreateDatasetForm.ui.xml +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/form/CreateDatasetForm.ui.xml @@ -1,6 +1,7 @@ .form-main-style { @@ -8,16 +9,17 @@ } .fieldset-border-style { - border: 1px groove #444; - -webkit-box-shadow: 0px 0px 0px 0px #000; - box-shadow: 0px 0px 0px 0px #000; - padding: 10px; + border: 1px groove #444 !important; + box-shadow: 0px 0px 0px 0px #000 !important; + padding: 10px !important; + margin: 5px !important; } .legend-style { - width: auto; - padding: 10px; - margin-bottom: 0px; + width: auto !important; + padding: 10px !important; + margin-bottom: 0 !important; + border-bottom: 0 !important; } @external .form-horizontal .input-large; @@ -45,11 +47,14 @@ font-weight: bold; } - .the-margin-left{ + .the-margin-gotoitem { margin-left: 5px; + margin-top: 10px; + margin-bottom: 10px; } + @@ -63,8 +68,9 @@ - + @@ -72,13 +78,15 @@ Title : - + - + @@ -86,18 +94,21 @@ - + Description: - - + @@ -117,7 +128,8 @@ - + @@ -125,7 +137,8 @@ - Selected + Selected License Url: @@ -137,7 +150,8 @@ - Visibility: + Visibility: @@ -148,7 +162,8 @@ - + @@ -161,7 +176,8 @@ to publish the item">Publish in: + width="91%" title="Publish in this organization" + ui:field="organizationsListbox"> @@ -172,8 +188,9 @@ Version: - + @@ -184,13 +201,14 @@ + placeholder="Joe Bloggs" enabled="false" b:id="author" + title="Item author" ui:field="authorTextbox" /> - + @@ -198,7 +216,8 @@ - + * Author Email: @@ -210,7 +229,8 @@ - + @@ -218,18 +238,20 @@ - + Maintainer: - + - + @@ -237,18 +259,21 @@ - + Maintainer Email: - - + - + @@ -256,7 +281,8 @@ - Types: + Types: - + @@ -276,10 +303,11 @@ - Item Groups: + Item Groups: - @@ -287,7 +315,8 @@ - + @@ -301,12 +330,12 @@ - + - Continue + Continue Reset @@ -317,25 +346,22 @@ ui:field="formSecondStep" visible="false"> - Manage Resources + Select Item Resources - - - - - - - - - + + + + + + + + - - - Continue @@ -357,7 +383,8 @@ - + - + @@ -384,18 +412,22 @@ - + - + Go to the Item - + Add Resources + block="true" type="PRIMARY" visible="false" + ui:field="addResourcesButton">Add Resources Create diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/metadata/MetaDataFieldSkeleton.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/metadata/MetaDataFieldSkeleton.java index 5dd231b..3eb43ca 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/metadata/MetaDataFieldSkeleton.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/metadata/MetaDataFieldSkeleton.java @@ -319,8 +319,9 @@ public class MetaDataFieldSkeleton extends Composite{ // get vocabulary fields List vocabulary = field.getVocabulary(); - + GWT.log("Vocabulary: "+field.getFieldName()); for (String term : vocabulary) { + GWT.log("Adding term: "+term); tempListBox.addItem(term); } diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/resources/AddResourceToDataset.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/resources/AddResourceToDataset.java index 5347002..9f64db7 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/resources/AddResourceToDataset.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/resources/AddResourceToDataset.java @@ -7,9 +7,11 @@ import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.ResourceElement 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.TextArea; import com.github.gwtbootstrap.client.ui.TextBox; import com.github.gwtbootstrap.client.ui.constants.AlertType; +import com.github.gwtbootstrap.client.ui.constants.ControlGroupType; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; @@ -53,6 +55,8 @@ public class AddResourceToDataset extends Composite{ @UiField Button addResourceButton; @UiField AlertBlock infoBlock; @UiField Button goToDatasetButton; + @UiField ControlGroup urlControlGroup; + @UiField ControlGroup nameControlGroup; public AddResourceToDataset(HandlerManager eventBus, String datasetId, String datasetOrg, String owner, final String datasetUrl) { initWidget(uiBinder.createAndBindUi(this)); @@ -80,15 +84,33 @@ public class AddResourceToDataset extends Composite{ @UiHandler("addResourceButton") void onAddButtonClick(ClickEvent e){ - + infoBlock.setVisible(false); + urlControlGroup.setType(ControlGroupType.NONE); + nameControlGroup.setType(ControlGroupType.NONE); // validation - if(resourceUrlTextBox.getText().isEmpty() || resourceNameTextBox.getText().isEmpty()){ + if (resourceUrlTextBox.getText().isEmpty()) { - showAlert("Url and name fields cannot be empty", AlertType.ERROR); + showAlert("'URL' field cannot be empty", AlertType.ERROR); + urlControlGroup.setType(ControlGroupType.ERROR); return; + } + // validation + if (resourceNameTextBox.getText().isEmpty() || resourceNameTextBox.getText().isEmpty()) { + + showAlert("'Name' field cannot be empty", AlertType.ERROR); + nameControlGroup.setType(ControlGroupType.ERROR); + return; + } + + //THE URL must be HTTPS, see #21068 + if(!(resourceUrlTextBox.getText().toLowerCase().startsWith("https://"))){ + showAlert("The URL must be HTTPS, so start with \"https://\" (e.g. https://your-resource.com)", AlertType.ERROR); + urlControlGroup.setType(ControlGroupType.ERROR); + return; + } // collect data and build up the bean @@ -163,6 +185,6 @@ public class AddResourceToDataset extends Composite{ } }; - t.schedule(4000); + t.schedule(8000); } } diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/resources/AddResourceToDataset.ui.xml b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/resources/AddResourceToDataset.ui.xml index 41b149b..108e98c 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/resources/AddResourceToDataset.ui.xml +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/resources/AddResourceToDataset.ui.xml @@ -1,6 +1,7 @@ + xmlns:b="urn:import:com.github.gwtbootstrap.client.ui" + xmlns:g="urn:import:com.google.gwt.user.client.ui"> .form-main-style { margin-left: 10px; @@ -57,18 +58,24 @@ - + The URL of the resource you are + publishing (only HTTPS URLs are allowed). If your resource is a file that you own on your + desktop, please upload that file to your workspace and generate a + public URL for that file. + + * URL: - + - + * Name: @@ -80,19 +87,22 @@ - + Description: + title="Resource description" + ui:field="resourceDescriptionTextArea" /> - + tagsList = new ArrayList(); diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/utils/GcubeDialogExtended.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/utils/GcubeDialogExtended.java index 43b0d7b..cdb67e7 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/utils/GcubeDialogExtended.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/utils/GcubeDialogExtended.java @@ -1,7 +1,7 @@ package org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.utils; import org.gcube.portlets.user.gcubewidgets.client.popup.GCubeDialog; -import org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.TwinColumnSelection.ResourceInfoForm; +import org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.workspace.ResourceInfoForm; import com.github.gwtbootstrap.client.ui.Paragraph; import com.google.gwt.core.shared.GWT; diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/utils/InfoIconsLabels.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/utils/InfoIconsLabels.java index b26c2a4..ebe779f 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/utils/InfoIconsLabels.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/utils/InfoIconsLabels.java @@ -26,7 +26,7 @@ public class InfoIconsLabels { public static final String TAGS_INFO_ID_POPUP = "tags-popup-panel-info"; public static final String TAGS_INFO_CAPTION = "Tags"; public static final String TAGS_INFO_TEXT = "Tags are meaningful information that can be associated to the " - + "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 or symbols . (dot) - (hyphen minus) _ (underscore)." + "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\"." + " You must push ENTER for attaching a tag, or use the provided list of predefined tags. In the latter case" @@ -70,8 +70,8 @@ public class InfoIconsLabels { // RESOURCES public static final String RESOURCES_INFO_ID_POPUP = "resouces-popup-panel-info"; public static final String RESOURCES_INFO_CAPTION = "Manage resource items"; - public static final String RESOURCES_INFO_TEXT = "Move the files you want to attach to the item on the right panel below. Double click on the item for changing resource's name or description." - + " Please consider that any complex hierarchy structure you may have will be flatten."; + public static final String RESOURCES_INFO_TEXT = "Select the files you want to attach to the publishing item. Click on 'Pencil' for changing resource's name or description. Click on 'Trash' to remove the resource." + + " You can add others files by using the 'Add files from...' facility: (i) to navigate a folder perform a 'double click' on it; (ii) to choose a file select it and press 'Select'. Please consider that any complex hierarchy structure you may have will be flatten."; // CUSTOM FIELDS public static final String CUSTOM_FIELDS_INFO_ID_POPUP = "custom-fields-popup-panel-info"; @@ -80,7 +80,7 @@ public class InfoIconsLabels { // TITLE public static final String TITLE_INFO_ID_POPUP = "title-popup-panel-info"; - public static final String TITLE_INFO_TEXT = "Item Title must contain only alphanumer characters, dots, underscore or hyphen minus. No others symbols are allowed. Please note that this field will be always visible, despite the item's visibility."; + public static final String TITLE_INFO_TEXT = "The title of the item. Please note that this field will be always visible, despite the item's visibility."; public static final String TITLE_INFO_CAPTION = "Item Title"; // DESCRIPTION diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/utils/WizardCreator.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/utils/WizardCreator.java new file mode 100644 index 0000000..6db7cae --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/utils/WizardCreator.java @@ -0,0 +1,154 @@ +package org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.utils; + +import java.util.ArrayList; +import java.util.List; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.core.client.Scheduler; +import com.google.gwt.core.client.Scheduler.ScheduledCommand; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.HTMLPanel; +import com.google.gwt.user.client.ui.Widget; + +/** + * The Class WizardCreator. + * + * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) + * + * Mar 15, 2021 + */ +public class WizardCreator extends Composite { + + /** The ui binder. */ + private static WizardCreatorUiBinder uiBinder = GWT.create(WizardCreatorUiBinder.class); + + /** + * The Interface WizardCreatorUiBinder. + * + * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) + * + * Mar 15, 2021 + */ + interface WizardCreatorUiBinder extends UiBinder { + } + + /** The title of steps. */ + private List titleOfSteps; + + /** The html steps. */ + private List htmlSteps; + + /** The wizard container. */ + @UiField + HTMLPanel theWizardContainer; + + + /** + * Instantiates a new wizard creator. + * + * @param titleOfSteps the title of steps + */ + public WizardCreator(List titleOfSteps) { + initWidget(uiBinder.createAndBindUi(this)); + this.titleOfSteps = titleOfSteps; + createSteps(); + } + + + /** + * Creates the steps. + */ + private void createSteps() { + + if(titleOfSteps==null) + return; + + int i = 1; + htmlSteps = new ArrayList<>(titleOfSteps.size()); + for (String step : titleOfSteps) { + HTML toHML = createStep(i, step); + htmlSteps.add(toHML); + theWizardContainer.add(toHML); + i++; + } + + + Scheduler.get().scheduleDeferred(new ScheduledCommand() { + @Override + public void execute() { + activeStep(1); + } + }); + } + + /** + * Active step. + * + * @param stepNumber the step number + */ + public void activeStep(int stepNumber) { + disableAllBadge(); + + int index = stepNumber-1; + if(index>=0) { + HTML html = htmlSteps.get(index); + html.getElement().addClassName("current"); +// NodeList spans = html.getElement().getElementsByTagName("span"); +// if(spans!=null && spans.getLength()>0) { +// Element el = spans.getItem(0); +// el.addClassName("badge-inverse"); +// } + } + } + + private void disableAllBadge() { + for (HTML html : htmlSteps) { + html.getElement().removeClassName("current"); +// NodeList spans = html.getElement().getElementsByTagName("span"); +// if(spans!=null && spans.getLength()>0) { +// Element el = spans.getItem(0); +// el.removeClassName("badge-inverse"); +// } + } + + } + + + /** + * Creates the step. + * + * @param stepNumber the step number + * @param stepTitle the step title + * @return the string + */ + private HTML createStep(int stepNumber, String stepTitle) { + + StringBuilder builder = new StringBuilder(); + builder.append(""); + builder.append(stepNumber+"."); + builder.append(""); + builder.append(" "+stepTitle); + + + return new HTML(builder.toString()); + + } + + public static class HTMLNoDiv extends HTML{ + + public static HTML noDiv(String theHtml) { + HTML html = new HTML() { + + }; + + html.setHTML(theHtml); + return html; + } + } + + + +} diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/utils/WizardCreator.ui.xml b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/utils/WizardCreator.ui.xml new file mode 100644 index 0000000..68c8844 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/utils/WizardCreator.ui.xml @@ -0,0 +1,10 @@ + + + + + + + \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/workspace/RemovePublishingResourceEvent.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/workspace/RemovePublishingResourceEvent.java new file mode 100644 index 0000000..c3973e1 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/workspace/RemovePublishingResourceEvent.java @@ -0,0 +1,59 @@ +package org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.workspace; + +import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.ResourceElementBean; + +import com.google.gwt.event.shared.GwtEvent; + +/** + * The Class RemovePublishingResourceEvent. + * + * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) + * + * Mar 9, 2021 + */ +public class RemovePublishingResourceEvent extends GwtEvent { + + /** The type. */ + public static Type TYPE = new Type(); + + /** The resource. */ + private ResourceElementBean resource; + + /** + * Instantiates a new removes the publishing resource event. + * + * @param resource the resource + */ + public RemovePublishingResourceEvent(ResourceElementBean resource) { + this.resource = resource; + } + + /** + * Gets the resource. + * + * @return the resource + */ + public ResourceElementBean getResource() { + return resource; + } + + /** + * Gets the associated type. + * + * @return the associated type + */ + @Override + public Type getAssociatedType() { + return TYPE; + } + + /** + * Dispatch. + * + * @param handler the handler + */ + @Override + protected void dispatch(RemovePublishingResourceEventHandler handler) { + handler.onRemoveResource(this); + } +} diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/workspace/RemovePublishingResourceEventHandler.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/workspace/RemovePublishingResourceEventHandler.java new file mode 100644 index 0000000..93c2031 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/workspace/RemovePublishingResourceEventHandler.java @@ -0,0 +1,22 @@ +package org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.workspace; + +import com.google.gwt.event.shared.EventHandler; + + +// TODO: Auto-generated Javadoc +/** + * The Interface RemovePublishingResourceEventHandler. + * + * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) + * + * Mar 9, 2021 + */ +public interface RemovePublishingResourceEventHandler extends EventHandler { + + /** + * On remove resource. + * + * @param removeResourceEvent the remove resource event + */ + void onRemoveResource(RemovePublishingResourceEvent removeResourceEvent); +} diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/TwinColumnSelection/ResourceInfoForm.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/workspace/ResourceInfoForm.java similarity index 89% rename from src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/TwinColumnSelection/ResourceInfoForm.java rename to src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/workspace/ResourceInfoForm.java index f2205c7..3e35839 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/TwinColumnSelection/ResourceInfoForm.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/workspace/ResourceInfoForm.java @@ -1,4 +1,4 @@ -package org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.TwinColumnSelection; +package org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.workspace; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.ResourceElementBean; @@ -8,7 +8,6 @@ import com.github.gwtbootstrap.client.ui.TextArea; import com.github.gwtbootstrap.client.ui.TextBox; import com.github.gwtbootstrap.client.ui.constants.ControlGroupType; import com.github.gwtbootstrap.client.ui.constants.IconType; -import com.google.gwt.cell.client.ValueUpdater; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Style.Float; import com.google.gwt.dom.client.Style.Unit; @@ -53,11 +52,7 @@ public class ResourceInfoForm extends Composite{ UiBinder { } - public ResourceInfoForm() { - initWidget(uiBinder.createAndBindUi(this)); - } - - public ResourceInfoForm(final ResourceElementBean resource, final ValueUpdater valueUpdater) { + public ResourceInfoForm(final ResourceElementBean resource) { initWidget(uiBinder.createAndBindUi(this)); resourceBean = resource; @@ -80,8 +75,9 @@ public class ResourceInfoForm extends Composite{ if(newName == null || newName.isEmpty()){ showError(controlName); }else{ + resourceBean.setName(newName); resourceBean.setEditableName(newName); - valueUpdater.update(resourceBean); + clearPanel(); } } }); @@ -125,10 +121,6 @@ public class ResourceInfoForm extends Composite{ return resourceDescription.getText(); } - public void setResourceDescription(String resourceDescription) { - this.resourceDescription.setText(resourceDescription); - } - public void removeError(ControlGroup control) { control.setType(ControlGroupType.NONE); } @@ -140,4 +132,8 @@ public class ResourceInfoForm extends Composite{ protected void clearPanel() { this.removeFromParent(); } + + public ResourceElementBean getResourceBean() { + return resourceBean; + } } diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/workspace/ResourceInfoForm.ui.xml b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/workspace/ResourceInfoForm.ui.xml new file mode 100644 index 0000000..98c045c --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/workspace/ResourceInfoForm.ui.xml @@ -0,0 +1,100 @@ + + + + .legend-style { + width: 100%; + padding: 10px; + margin-bottom: 0px; + font-size: 14px; + } + + .panel-style { + padding: 5px; + border: 1px solid #bbb; + border-radius: 5px; + height: 320px; + width: 700px; + margin-bottom: 20px; + } + + .labels-style { + color: #999; + } + + .controls-style { + margin-left: 10px !important; + } + + .control-group { + margin-bottom: 0px !important; + } + + .custom-input input { + width: 350px; + } + + .custom-input textarea { + width: 355px; + } + + + + + + Resource Information + + + + + Name: + + + + + + + + Path: + + + + + + + + Description: + + + + + + + + Format: + + + + + + + + Update + + + + + \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/workspace/SelectResourceByWEMainPanel.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/workspace/SelectResourceByWEMainPanel.java new file mode 100644 index 0000000..36adcbf --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/workspace/SelectResourceByWEMainPanel.java @@ -0,0 +1,305 @@ +package org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.workspace; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.ResourceElementBean; +import org.gcube.portlets.widgets.wsexplorer.client.explore.WorkspaceResourcesEnhancedExplorerPanel; +import org.gcube.portlets.widgets.wsexplorer.client.notification.WorkspaceExplorerSelectNotification.WorskpaceExplorerSelectNotificationListener; +import org.gcube.portlets.widgets.wsexplorer.client.view.grid.ItemsTable.DISPLAY_FIELD; +import org.gcube.portlets.widgets.wsexplorer.shared.Item; + +import com.github.gwtbootstrap.client.ui.AccordionGroup; +import com.github.gwtbootstrap.client.ui.Alert; +import com.github.gwtbootstrap.client.ui.Button; +import com.github.gwtbootstrap.client.ui.Label; +import com.github.gwtbootstrap.client.ui.constants.AlertType; +import com.github.gwtbootstrap.client.ui.constants.LabelType; +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.shared.HandlerManager; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.Timer; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.HTMLPanel; +import com.google.gwt.user.client.ui.VerticalPanel; +import com.google.gwt.user.client.ui.Widget; + +/** + * The Class SelectResourceByWEMainPanel. + * + * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) + * + * Mar 5, 2021 + */ +public class SelectResourceByWEMainPanel extends Composite { + + /** The ui binder. */ + private static SelectResourceByWEMainPanelUiBinder uiBinder = GWT.create(SelectResourceByWEMainPanelUiBinder.class); + + private static boolean frozen = false; + + private final ResourceElementBean initialBean; + + @UiField + VerticalPanel wsContainer; + + @UiField + FlowPanel selectResourcesContainer; + + @UiField + Alert showAlert; + + @UiField + Button buttSelectResource; + + @UiField + AccordionGroup buttPickResources; + + @UiField + HTMLPanel containerPickResources; + + @UiField + Label labelNothing; + + private Item selectedWEItem; + + public final static HandlerManager eventBus = new HandlerManager(null); + + private Map mapSelectedResources = new HashMap(); + + /** + * The Interface SelectResourceByWEMainPanelUiBinder. + * + * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) + * + * Mar 5, 2021 + */ + interface SelectResourceByWEMainPanelUiBinder extends UiBinder { + } + + /** + * Instantiates a new select resource by WE main panel. + */ + public SelectResourceByWEMainPanel(ResourceElementBean initialBean) { + initWidget(uiBinder.createAndBindUi(this)); + SelectResourceByWEMainPanel.frozen = false; + this.initialBean = initialBean; + this.labelNothing.setType(LabelType.INFO); + + try { + + String wsFolderId = null; + + //remove this? + if(initialBean.isFolder()) { + wsFolderId = initialBean.getOriginalIdInWorkspace(); + }else { + //is file + if(initialBean.getParent()!=null) { + wsFolderId = initialBean.getParent().getOriginalIdInWorkspace(); + + } + } + + //wsFolderId = initialBean.getRootIdInWorkspace()!=null?initialBean.getRootIdInWorkspace():wsFolderId; + + //loads the WE only if the root is not null + if(wsFolderId!=null) { + + DISPLAY_FIELD[] displayFields = new DISPLAY_FIELD[] { DISPLAY_FIELD.ICON, DISPLAY_FIELD.NAME, + DISPLAY_FIELD.OWNER, DISPLAY_FIELD.CREATION_DATE}; + + WorkspaceResourcesEnhancedExplorerPanel workspaceExplorerPanel = new WorkspaceResourcesEnhancedExplorerPanel(wsFolderId,false,null, null,false,null,displayFields); + WorskpaceExplorerSelectNotificationListener wsResourceExplorerListener = new WorskpaceExplorerSelectNotificationListener() { + + @Override + public void onSelectedItem(Item item) { + GWT.log("Listener Selected Item " + item); + selectedWEItem = item; + } + + @Override + public void onFailed(Throwable throwable) { + // Log.error(throwable.getLocalizedMessage()); + throwable.printStackTrace(); + } + + + @Override + public void onAborted() { + + } + + @Override + public void onNotValidSelection() { + selectedWEItem = null; + } + }; + + workspaceExplorerPanel.addWorkspaceExplorerSelectNotificationListener(wsResourceExplorerListener); + wsContainer.add(workspaceExplorerPanel); + }else { + containerPickResources.setVisible(false); + } + +// if(rootName!=null) { +// buttPickResources.setHeading("Add files from "+rootName); +// } + + + } catch (Exception e) { + e.printStackTrace(); + } + + if(!initialBean.isFolder()) { + addSelectResource(initialBean.getOriginalIdInWorkspace(), initialBean.getName(),initialBean.getFullPath(), initialBean.isFolder()); + } + + addHandlers(); + + } + + private void addHandlers() { + + buttSelectResource.addClickHandler(new ClickHandler() { + + @Override + public void onClick(ClickEvent event) { + if(selectedWEItem!=null && !selectedWEItem.isFolder()) { + addSelectResource(selectedWEItem.getId(), selectedWEItem.getName(), selectedWEItem.getPath(), selectedWEItem.isFolder()); + } + + } + }); + + eventBus.addHandler(RemovePublishingResourceEvent.TYPE, new RemovePublishingResourceEventHandler() { + + @Override + public void onRemoveResource(RemovePublishingResourceEvent removeResourceEvent) { + if(removeResourceEvent.getResource()!=null) { + removePublishingResource(removeResourceEvent.getResource()); + } + } + + }); + + + } + + + private void removePublishingResource(ResourceElementBean resource) { + + SelectedResourceWidget theRW = mapSelectedResources.get(resource.getOriginalIdInWorkspace()); + if(theRW!=null) { + selectResourcesContainer.remove(theRW); + mapSelectedResources.remove(resource.getOriginalIdInWorkspace()); + } + + showNothingResourceSelected(); + } + + public void addSelectResource(String wsItemId, String name, String path, boolean isFolder) { + + SelectedResourceWidget selWidg = mapSelectedResources.get(wsItemId); + if (selWidg != null) { + showAlertMsg(AlertType.WARNING,"Item '" + name + "' already selected",true); + return; + } + + ResourceElementBean rb = new ResourceElementBean(); + rb.setOriginalIdInWorkspace(wsItemId); + rb.setName(name); + rb.setFullPath(path); + rb.setEditableName(name); + rb.setFolder(isFolder); + selWidg = new SelectedResourceWidget(rb); + + mapSelectedResources.put(wsItemId, selWidg); + selectResourcesContainer.add(selWidg); + + showNothingResourceSelected(); + + } + + private void showNothingResourceSelected() { + if(mapSelectedResources.size()==0) { + labelNothing.setVisible(true); + }else + labelNothing.setVisible(false); + } + + private void showAlertMsg(AlertType type, String txt, boolean autoHide) { + showAlert.setType(type); + showAlert.setText(txt); + showAlert.setVisible(true); + showAlert.setClose(true); + if(autoHide) { + Timer timer = new Timer() { + + @Override + public void run() { + showAlert.setVisible(false); + + } + }; + + timer.schedule(5000); + } + } + + + + public void freeze() { + + GWT.log("called freeze into selected resources"); + frozen = true; + selectResourcesContainer.getElement().setAttribute("disabled", "disabled"); + containerPickResources.getElement().setAttribute("disabled", "disabled"); + //buttPickResources.getElement().getStyle().setProperty("pointer-events","none"); + buttSelectResource.setEnabled(false); + + } + + + /** + * Returns the root parent with the children as files to save + * @return the resources to save + */ + public ResourceElementBean getResourcesToPublish(){ + + ResourceElementBean toReturn = new ResourceElementBean(); + List children = new ArrayList(); + + for (String wsItemId : mapSelectedResources.keySet()) { + SelectedResourceWidget selecWC = mapSelectedResources.get(wsItemId); + ResourceElementBean theResource = selecWC.getResourceBean(); + theResource.setToBeAdded(true); + + if(!theResource.isFolder()){ // be sure ... + children.add(theResource); + } + + } + + toReturn.setToPublish(children); + GWT.log("resources to publish are: "+toReturn.getToPublish()); + return toReturn; + } + + + /** + * @return the freezed + */ + public static boolean isFroozen() { + + return frozen; + } + + +} diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/workspace/SelectResourceByWEMainPanel.ui.xml b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/workspace/SelectResourceByWEMainPanel.ui.xml new file mode 100644 index 0000000..54fb234 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/workspace/SelectResourceByWEMainPanel.ui.xml @@ -0,0 +1,54 @@ + + + + .important { + font-weight: bold; + } + + .custom-header { + margin: 0 !important; + font-size: 18px !important; + color: #222 !important; + } + + .max-height-250 { + max-height: 250px; + overflow-y: auto; + } + + .margin-top-10 { + margin-top: 10px; + } + + .margin-top-30 { + margin-top: 30px; + } + + + + + Selected Items + + + no file selected + + + + + + + + + + Select + + + + \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/workspace/SelectedResourceWidget.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/workspace/SelectedResourceWidget.java new file mode 100644 index 0000000..3835c5a --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/workspace/SelectedResourceWidget.java @@ -0,0 +1,133 @@ +package org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.workspace; + +import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.ResourceElementBean; + +import com.github.gwtbootstrap.client.ui.Button; +import com.github.gwtbootstrap.client.ui.constants.ButtonType; +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.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.HTMLPanel; +import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.Widget; + +/** + * The Class SelectResourceWidget. + * + * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) + * + * Mar 12, 2021 + */ +public class SelectedResourceWidget extends Composite { + + /** The ui binder. */ + private static SelectedResourceWidgetUiBinder uiBinder = GWT.create(SelectedResourceWidgetUiBinder.class); + + /** + * The Interface SelectResourceWidgetUiBinder. + * + * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) + * + * Mar 12, 2021 + */ + interface SelectedResourceWidgetUiBinder extends UiBinder { + } + + /** + * Instantiates a new select resource widget. + */ + public SelectedResourceWidget() { + initWidget(uiBinder.createAndBindUi(this)); + } + + /** The button delete. */ + @UiField + Button buttonDelete; + + /** The button edit. */ + @UiField + Button buttonEdit; + + /** The field name. */ + @UiField + Label fieldName; + + @UiField + Label fieldDescription; + + /** The edit panel. */ + @UiField + HTMLPanel editPanel; + + /** The resource bean. */ + private ResourceElementBean resourceBean; + + /** + * Instantiates a new select resource widget. + * + * @param rb the rb + */ + public SelectedResourceWidget(ResourceElementBean rb) { + initWidget(uiBinder.createAndBindUi(this)); + buttonEdit.setType(ButtonType.LINK); + buttonDelete.setType(ButtonType.LINK); + this.resourceBean = rb; + updateFields(); + addHandlers(); + + } + + private void updateFields() { + this.fieldName.setText(resourceBean.getEditableName()); + + if(resourceBean.getDescription()!=null && !resourceBean.getDescription().isEmpty()) { + this.fieldDescription.setVisible(true); + this.fieldDescription.setText(resourceBean.getDescription()); + }else + this.fieldDescription.setVisible(false); + } + + /** + * Adds the handlers. + */ + private void addHandlers() { + + buttonEdit.addClickHandler(new ClickHandler() { + + @Override + public void onClick(ClickEvent event) { + editPanel.clear(); + ResourceInfoForm resourceInformationInfo = new ResourceInfoForm(resourceBean) { + protected void onUnload() { + super.onUnload(); + updateFields(); + }; + }; + editPanel.add(resourceInformationInfo); + + } + }); + + buttonDelete.addClickHandler(new ClickHandler() { + + @Override + public void onClick(ClickEvent event) { + SelectResourceByWEMainPanel.eventBus.fireEvent(new RemovePublishingResourceEvent(resourceBean)); + } + }); + + } + + /** + * Gets the resource bean. + * + * @return the resource bean + */ + public ResourceElementBean getResourceBean() { + return resourceBean; + } + +} diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/workspace/SelectedResourceWidget.ui.xml b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/workspace/SelectedResourceWidget.ui.xml new file mode 100644 index 0000000..009dec0 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/workspace/SelectedResourceWidget.ui.xml @@ -0,0 +1,57 @@ + + + + .important { + font-weight: bold; + } + + .selected-resources { + + } + + .selected-resources td { + vertical-align: middle !important; + } + + .margin-bottom-8 { + margin-bottom: 8px; + } + + .descr-text { + font-style: italic; + padding-left: 105px; + font-size: 12px; + } + + .title-text { + font-weight: bold; + font-size: 14px; + display: inline; + vertical-align: middle; + color: #222; + } + + .icon-my-style { + font-size: 1.2em; + margin-right: 10px; + margin-left: 10px; + vertical-align: middle; + } + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/public/CKanMetadataPublisher.css b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/public/CKanMetadataPublisher.css index 14475b3..9180b9d 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/public/CKanMetadataPublisher.css +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/public/CKanMetadataPublisher.css @@ -49,4 +49,87 @@ .GeoJson-DialogBox{ width: 100% !important; -} \ No newline at end of file +} + +.accordion-no-border-inner { + border: 1px solid #e5e5e5 !important; + border-radius: 4px !important; + padding: 6px 12px !important; +} + +.accordion-no-border-inner .accordion-inner { + border-top: 0 !important; + padding: 4px 4px !important; +} + +/* WIZARD-CREATOR CLASSES */ +.wizard-creator { + width: 100%; + border-collapse: separate; + display: table; + border-spacing: 5px; +} + +.wizard-creator div { + padding: 10px 12px 10px; + background: #efefef; + position: relative; + /*display: inline-block;*/ + display: table-cell; +} + +.wizard-creator div:before { + width: 0; + height: 0; + border-top: 20px inset transparent; + border-bottom: 20px inset transparent; + border-left: 20px solid #fff; + position: absolute; + content: ""; + top: 0; + left: 0; +} + +.wizard-creator div:after { + width: 0; + height: 0; + border-top: 20px inset transparent; + border-bottom: 20px inset transparent; + border-left: 20px solid #efefef; + position: absolute; + content: ""; + top: 0; + right: -20px; + z-index: 2; +} + +.wizard-creator div:first-child:before, +.wizard-creator div:last-child:after { + border: none; +} + +.wizard-creator div:first-child { + border-radius: 4px 0 0 4px; +} + +.wizard-creator div:last-child { + border-radius: 0 4px 4px 0; +} + + +.wizard-creator .badge-wiz { + margin: 0 5px 0 18px; +} + +.wizard-creator div:first-child .badge { + margin-left: 0; +} + +.wizard-creator .current { + background: #007ACC; + color: #fff; +} + +.wizard-creator .current:after { + border-left-color: #007ACC; +} 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 48d0ed6..c1f3732 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 @@ -5,7 +5,6 @@ import java.util.Arrays; import java.util.Calendar; import java.util.Collections; import java.util.Comparator; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -14,15 +13,18 @@ import java.util.concurrent.ConcurrentHashMap; import javax.servlet.http.HttpSession; -import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogue; -import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueFactory; -import org.gcube.datacatalogue.ckanutillibrary.server.utils.CatalogueUtilMethods; -import org.gcube.datacatalogue.ckanutillibrary.server.utils.SessionCatalogueAttributes; -import org.gcube.datacatalogue.ckanutillibrary.shared.ResourceBean; -import org.gcube.datacatalogue.ckanutillibrary.shared.RolesCkanGroupOrOrg; +import org.gcube.common.portal.PortalContext; +import org.gcube.common.storagehubwrapper.server.StorageHubWrapper; +import org.gcube.common.storagehubwrapper.server.tohl.Workspace; +import org.gcube.datacatalogue.utillibrary.server.DataCatalogue; +import org.gcube.datacatalogue.utillibrary.server.DataCatalogueFactory; +import org.gcube.datacatalogue.utillibrary.server.utils.CatalogueUtilMethods; +import org.gcube.datacatalogue.utillibrary.server.utils.SessionCatalogueAttributes; +import org.gcube.datacatalogue.utillibrary.shared.ResourceBean; +import org.gcube.datacatalogue.utillibrary.shared.RolesCkanGroupOrOrg; +import org.gcube.datacatalogue.utillibrary.shared.jackan.model.CkanGroup; +import org.gcube.datacatalogue.utillibrary.shared.jackan.model.CkanLicense; 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.WritePostCatalogueManagerThread; import org.gcube.portlets.widgets.ckandatapublisherwidget.server.utils.CatalogueRoleManager; import org.gcube.portlets.widgets.ckandatapublisherwidget.server.utils.DiscoverTagsList; import org.gcube.portlets.widgets.ckandatapublisherwidget.server.utils.GenericUtils; @@ -41,15 +43,14 @@ import org.gcube.vomanagement.usermanagement.impl.LiferayGroupManager; import org.gcube.vomanagement.usermanagement.impl.LiferayUserManager; import org.gcube.vomanagement.usermanagement.model.GCubeUser; import org.geojson.GeoJsonObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gwt.user.server.rpc.RemoteServiceServlet; -import com.liferay.portal.kernel.log.Log; -import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.service.UserLocalServiceUtil; -import eu.trentorise.opendata.jackan.model.CkanGroup; -import eu.trentorise.opendata.jackan.model.CkanLicense; + /** * Server side of the data publisher. @@ -61,7 +62,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C // Logger //private static final org.slf4j.Logger logger = LoggerFactory.getLogger(CKANPublisherServicesImpl.class); - private static final Log logger = LogFactoryUtil.getLog(CKANPublisherServicesImpl.class); + private static final Logger logger = LoggerFactory.getLogger(CKANPublisherServicesImpl.class); private static final String ITEM_URL_FIELD = "Item URL"; private static final String SYS_TYPE = "system:type"; private static final String TAGS_VOCABULARY_KEY = "TAGS_VOCABULARY"; @@ -69,10 +70,24 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C // map private ConcurrentHashMap mapOrganizationScope = new ConcurrentHashMap(); + /** - * Retrieve an instance of the library for the scope + * Dev mode set contexts. + */ + private void devModeSetContexts() { + if (!isWithinPortal()) { + logger.info("DETECTED DEV MODE"); + GenericUtils.getCurrentContext(getThreadLocalRequest(), true); + GenericUtils.getCurrentToken(getThreadLocalRequest(), true); + } + + } + + /** + * Retrieve an instance of the library for the scope. + * * @param scope if it is null it is evaluated from the session - * @return + * @return the catalogue */ public DataCatalogue getCatalogue(String scope){ @@ -89,11 +104,13 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C } /** - * Retrieve the list of organizations in which the user can publish (roles ADMIN/EDITOR) - * @param username + * Retrieve the list of organizations in which the user can publish (roles ADMIN/EDITOR). + * + * @param username the username + * @param scope the scope * @return the list of organizations - * @throws GroupRetrievalFault - * @throws UserManagementSystemException + * @throws UserManagementSystemException the user management system exception + * @throws GroupRetrievalFault the group retrieval fault */ private List getUserOrganizationsListAdmin(String username, String scope) throws UserManagementSystemException, GroupRetrievalFault { @@ -119,7 +136,8 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C } /** - * Online or in development mode? + * Online or in development mode?. + * * @return true if you're running into the portal, false if in development */ private boolean isWithinPortal() { @@ -132,11 +150,25 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C return false; } } + + /** + * Gets the workspace from storage hub. + * + * @return the workspace from storage hub + * @throws Exception + * the exception + */ + protected Workspace getWorkspaceFromStorageHub() throws Exception { + GCubeUser user = PortalContext.getConfiguration().getCurrentUser(this.getThreadLocalRequest()); + StorageHubWrapper storageHubWrapper = WorkspaceUtils.getStorageHubWrapper(this.getThreadLocalRequest(), null, user); + return storageHubWrapper.getWorkspace(); + } /** * Find a license id given the license text. - * @param chosenLicense - * @return + * + * @param chosenLicense the chosen license + * @return the string */ private String findLicenseIdByLicense(String chosenLicense) { @@ -146,6 +178,11 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C } + /** + * Gets the licenses. + * + * @return the licenses + */ @Override public List getLicenses() { @@ -154,6 +191,13 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C String scope = GenericUtils.getScopeFromClientUrl(getThreadLocalRequest()); logger.info("Request for CKAN licenses for scope " + scope); String keyPerScope = CatalogueUtilMethods.concatenateSessionKeyScope(SessionCatalogueAttributes.CKAN_LICENSES_KEY, scope); + +// if(!isWithinPortal()){ +// logger.info("DEV MODE returning funny licenses..."); +// List licenses = new ArrayList(); +// licenses.add(new LicenseBean("AFL-3.0", "https://opensource.org/licenses/AFL-3.0")); +// return licenses; +// } List licensesBean = null; if(httpSession.getAttribute(keyPerScope) != null){ @@ -179,7 +223,15 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C return licensesBean; } + + /** + * Gets the dataset bean. + * + * @param folderId the folder id + * @return the dataset bean + * @throws Exception the exception + */ @Override public DatasetBean getDatasetBean(String folderId) throws Exception{ @@ -194,7 +246,6 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C String scope = GenericUtils.getScopeFromClientUrl(getThreadLocalRequest()); logger.debug("Scope recovered from session is " + scope); - logger.debug("Request dataset metadata bean for folder with id " + folderId + " whose owner is " + userName); @@ -218,7 +269,8 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C // if the request comes from the workspace if(folderId != null && !folderId.isEmpty()){ - WorkspaceUtils.handleWorkspaceResources(folderId, userName, bean); + Workspace workspace = getWorkspaceFromStorageHub(); + WorkspaceUtils.toWorkspaceResource(folderId, userName, bean, workspace); } }catch(Exception e){ @@ -237,11 +289,11 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C bean.setVersion(1); String onlyAlphanumeric = "test-creation-blablabla".replaceAll("[^A-Za-z0-9]", ""); bean.setTitle(onlyAlphanumeric + Calendar.getInstance().getTimeInMillis()); - bean.setAuthorName("Costantino"); - bean.setAuthorSurname("Perciante"); - bean.setAuthorEmail("costantino.perciante@isti.cnr.it"); - bean.setMaintainer("Costantino Perciante"); - bean.setMaintainerEmail("costantino.perciante@isti.cnr.it"); + bean.setAuthorName("Francesco"); + bean.setAuthorSurname("Mangiacrapa"); + bean.setAuthorEmail("francesco.mangiacrapa@isti.cnr.it"); + bean.setMaintainer("Francesco Mangiacrapa"); + bean.setMaintainerEmail("francesco.mangiacrapa@isti.cnr.it"); //UPDATED By Francesco String scope = GenericUtils.getCurrentContext(this.getThreadLocalRequest(), false); @@ -252,7 +304,8 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C bean.setOwnerIdentifier(userName); if(folderId != null && !folderId.isEmpty()){ - WorkspaceUtils.handleWorkspaceResources(folderId, userName, bean); + Workspace workspace = getWorkspaceFromStorageHub(); + WorkspaceUtils.toWorkspaceResource(folderId, userName, bean, workspace); } }catch(Exception e){ logger.error("Error while building bean into dev mode", e); @@ -265,9 +318,10 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C } /** - * Discover from the IS the vocabulary of tags for this scope, if present + * Discover from the IS the vocabulary of tags for this scope, if present. + * + * @param context the context * @return a list of tags vocabulary - * @throws Exception */ private List discoverTagsVocabulary(String context){ @@ -286,15 +340,30 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C return vocabulary; } + /** + * Gets the tags for organization. + * + * @param orgName the org name + * @return the tags for organization + * @throws Exception the exception + */ @Override public List getTagsForOrganization(String orgName) throws Exception{ return discoverTagsVocabulary(getScopeFromOrgName(orgName)); } + /** + * Creates the C kan dataset. + * + * @param toCreate the to create + * @return the dataset bean + * @throws Exception the exception + */ @Override public DatasetBean createCKanDataset(DatasetBean toCreate) throws Exception{ try{ + devModeSetContexts(); logger.info("Request for creating a dataset with these information " + toCreate); String userName = GenericUtils.getCurrentUser(getThreadLocalRequest()).getUsername(); String title = toCreate.getTitle(); @@ -319,21 +388,43 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C // get the list of resources and convert to ResourceBean List resources = null; ResourceElementBean resourcesToAdd = toCreate.getResourceRoot(); - - // we need to copy such resource in the .catalogue area of the user's ws + + //converting to resources to be added if(resourcesToAdd != null){ - resources = WorkspaceUtils.copyResourcesToUserCatalogueArea(toCreate.getId(), userName, toCreate); + Workspace workspace = getWorkspaceFromStorageHub(); + resources = WorkspaceUtils.toResources(toCreate, workspace, userName); } 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 (!isWithinPortal()) { + logger.debug("Should be added:"); + for (String key : customFields.keySet()) { + logger.debug("Custom field with key: "+key+", value: "+customFields.get(key)); + } + } + + String datasetId = utils.createCkanDatasetMultipleCustomFields(userName, + title, + null, + organizationNameOrId, + author, + authorMail, + maintainer, + maintainerMail, + version, + description, + licenseId, + listOfTags, + customFields, + resources, + setPublic, + true, + true); + if(datasetId != null){ logger.info("Dataset created!"); @@ -344,44 +435,52 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C toCreate.setSource(datasetUrl); // add also this information as custom field + /** + * TODO NEEDED TO BE CHECK + * + * OLD CODE NOT NEEDED. NOW IT IS PERFORMED BY gCAT Map> addField = new HashMap>(); addField.put(ITEM_URL_FIELD, Arrays.asList(datasetUrl)); utils.patchProductCustomFields(datasetId, userApiKey, addField, false); + + */ + + //TODO SHOULD BE NOTIFIED by gCAT // start a thread that will associate this dataset with the group - if(/*toCreate.getChosenType() != null ||*/ toCreate.getGroups() != null){ - - AssociationToGroupAndNotifyThread threadAssociationToGroup = - new AssociationToGroupAndNotifyThread( - toCreate.getGroups(), - toCreate.getGroupsForceCreation(), - null, //toCreate.getChosenType(), TODO - datasetUrl, - datasetId, - toCreate.getTitle(), - GenericUtils.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(), - GenericUtils.getCurrentUser(getThreadLocalRequest()).getFullname(), - GenericUtils.getCurrentClientUrl(getThreadLocalRequest()) - ); - threadWritePost.start(); +// if(/*toCreate.getChosenType() != null ||*/ toCreate.getGroups() != null){ +// +// AssociationToGroupAndNotifyThread threadAssociationToGroup = +// new AssociationToGroupAndNotifyThread( +// toCreate.getGroups(), +// toCreate.getGroupsForceCreation(), +// null, //toCreate.getChosenType(), TODO +// datasetUrl, +// datasetId, +// toCreate.getTitle(), +// GenericUtils.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(), +// GenericUtils.getCurrentUser(getThreadLocalRequest()).getFullname(), +// GenericUtils.getCurrentClientUrl(getThreadLocalRequest()) +// ); +// threadWritePost.start(); return toCreate; }else{ @@ -390,83 +489,91 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C }catch(Exception e){ logger.error("Error while creating item ", e); - throw new Exception("An error occurred while creating the item " + e.getMessage()); + throw new Exception(e.getMessage()); } return null; } - + + /** + * Adds the resource to dataset. + * + * @param resource the resource + * @param datasetId the dataset id + * @return the resource element bean + * @throws Exception the exception + */ @Override public ResourceElementBean addResourceToDataset(ResourceElementBean resource, String datasetId) throws Exception{ + logger.info("called addResourceToDataset"); + devModeSetContexts(); String username = GenericUtils.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("Owner is " + username + " and resource is " + resource); - if(!isWithinPortal()){ + ResourceBean resourceBean = new ResourceBean( + resource.getUrl(), + resource.getName(), + resource.getDescription(), + null, + username, + datasetId, + null); - logger.warn("Running outside the portal"); + // get the scope in which we should discover the ckan instance given the organization name in which the dataset was created + String scope = getScopeFromOrgName(resource.getOrganizationNameDatasetParent()); + DataCatalogue catalogue = getCatalogue(scope); + String resourceId = catalogue.addResourceToDataset(resourceBean, resource.getOrganizationNameDatasetParent(), username); + + if(resourceId != null){ + logger.info("Resource " + resource.getName() + " is now available"); + // set its id and turn it to the client + resource.setOriginalIdInWorkspace(resourceId); return resource; + } - }else{ - - ResourceBean resourceBean = new ResourceBean( - resource.getUrl(), - resource.getName(), - resource.getDescription(), - null, - username, - datasetId, - null); + logger.debug("No resource created"); + return null; + } + /** + * Delete resource from dataset. + * + * @param resource the resource + * @return true, if successful + * @throws Exception the exception + */ + @Override + public boolean deleteResourceFromDataset(ResourceElementBean resource) throws Exception{ + logger.debug("Request for deleting resource " + resource); + boolean deleted = false; + devModeSetContexts(); + try{ // get the scope in which we should discover the ckan instance given the organization name in which the dataset was created String scope = getScopeFromOrgName(resource.getOrganizationNameDatasetParent()); DataCatalogue catalogue = getCatalogue(scope); - String resourceId = catalogue.addResourceToDataset(resourceBean, catalogue.getApiKeyFromUsername(username)); - - if(resourceId != null){ - logger.debug("Resource " + resource.getName() + " is now available"); - // set its id and turn it to the client - resource.setOriginalIdInWorkspace(resourceId); - return resource; - } - - logger.debug("No resource created"); - return null; - } - } - - @Override - public boolean deleteResourceFromDataset(ResourceElementBean resource) throws Exception{ - - logger.debug("Request for deleting resource " + resource); - boolean deleted = false; - - if(!isWithinPortal()){ - logger.warn("Running outside the portal"); - return deleted; - }else{ - String username = GenericUtils.getCurrentUser(getThreadLocalRequest()).getUsername(); - try{ - // get the scope in which we should discover the ckan instance given the organization name in which the dataset was created - String scope = getScopeFromOrgName(resource.getOrganizationNameDatasetParent()); - DataCatalogue catalogue = getCatalogue(scope); - deleted = catalogue. - deleteResourceFromDataset(resource.getOriginalIdInWorkspace(), catalogue.getApiKeyFromUsername(username)); - if(deleted){ - logger.info("Resource described by " + resource + " deleted"); - }else - 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; + deleted = catalogue.deleteResourceFromDataset(resource.getOriginalIdInWorkspace(),username); + if(deleted){ + logger.info("Resource described by " + resource + " deleted"); + }else + 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; + } + /** + * Gets the profiles. + * + * @param orgName the org name + * @return the profiles + * @throws Exception the exception + */ @Override public List getProfiles(String orgName) throws Exception{ @@ -484,6 +591,14 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C return toReturn; } + /** + * Dataset id already exists. + * + * @param title the title + * @param orgName the org name + * @return true, if successful + * @throws Exception the exception + */ @Override public boolean datasetIdAlreadyExists(String title, String orgName) throws Exception{ if(title == null || title.isEmpty()) @@ -505,18 +620,23 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C */ private String getScopeFromOrgName(String orgName){ - logger.debug("Request for scope related to orgName " + orgName + "[ map that will be used is " + mapOrganizationScope.toString() + " ]"); + logger.info("Request for scope related to orgName " + orgName + " [map that will be used is " + mapOrganizationScope.toString() + "]"); if(orgName == null || orgName.isEmpty()) throw new IllegalArgumentException("orgName cannot be empty or null!"); String toReturn = null; if(isWithinPortal()){ - if(mapOrganizationScope.containsKey(orgName)) + if(mapOrganizationScope.containsKey(orgName)) { toReturn = mapOrganizationScope.get(orgName); - else{ + }else{ try{ String evaluatedScope = GenericUtils.retrieveScopeFromOrganizationName(orgName); + //see #20801 + if(evaluatedScope==null || evaluatedScope.isEmpty()) { + logger.warn("Scope detected for OrganizationName: "+orgName+" is null or empty, skipping filling 'mapOrganizationScope' and returning null"); + return toReturn; + } mapOrganizationScope.put(orgName, evaluatedScope); toReturn = evaluatedScope; }catch(Exception e){ @@ -528,17 +648,26 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C toReturn = GenericUtils.getCurrentContext(this.getThreadLocalRequest(), false); mapOrganizationScope.put(orgName, toReturn); } - logger.debug("Returning scope " + toReturn); + logger.info("Returning scope " + toReturn); return toReturn; } + /** + * Gets the user groups. + * + * @param orgName the org name + * @return the user groups + */ @Override public List getUserGroups(String orgName) { List toReturn = new ArrayList(); if(isWithinPortal()){ - String username = GenericUtils.getCurrentUser(getThreadLocalRequest()).getUsername(); + GCubeUser user = GenericUtils.getCurrentUser(getThreadLocalRequest()); + String username = null; + if(user!=null) + username = user.getUsername(); logger.debug("Request for user " + username + " groups. Organization name is " + orgName); @@ -557,10 +686,9 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C //Fixing Incident #12563 try{ DataCatalogue catalogue = getCatalogue(scope); - String apiKey = catalogue.getApiKeyFromUsername(username); //Fixing Incident #12563 - if(apiKey!=null && !apiKey.isEmpty()){ - Map> mapRoleGroup = catalogue.getUserRoleByGroup(username, apiKey); + if(username!=null && !username.isEmpty()){ + Map> mapRoleGroup = catalogue.getUserRoleByGroup(username); Set>> set = mapRoleGroup.entrySet(); for (Entry> entry : set) { Set> subSet = entry.getValue().entrySet(); @@ -583,6 +711,13 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C } + /** + * Checks if is publisher user. + * + * @param isWorkspaceRequest the is workspace request + * @return true, if is publisher user + * @throws Exception the exception + */ @Override public boolean isPublisherUser(boolean isWorkspaceRequest) throws Exception{ @@ -651,6 +786,13 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C } } + /** + * Checks if is geo JSON valid. + * + * @param geoJson the geo json + * @return true, if is geo JSON valid + * @throws Exception the exception + */ @Override public boolean isGeoJSONValid(String geoJson) throws Exception { try{ 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 3266249..c252731 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 @@ -1,160 +1,161 @@ -package org.gcube.portlets.widgets.ckandatapublisherwidget.server.threads; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; - -import org.gcube.common.portal.mailing.EmailNotification; -import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogue; -import org.gcube.datacatalogue.ckanutillibrary.server.utils.CatalogueUtilMethods; -import org.gcube.datacatalogue.ckanutillibrary.shared.RolesCkanGroupOrOrg; -import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.OrganizationBean; -import org.gcube.vomanagement.usermanagement.UserManager; -import org.gcube.vomanagement.usermanagement.impl.LiferayUserManager; - -import com.liferay.portal.kernel.log.Log; -import com.liferay.portal.kernel.log.LogFactoryUtil; - -import eu.trentorise.opendata.jackan.model.CkanGroup; - -/** - * Associate the dataset to a group and send notifications to group's admins. - * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) - */ -public class AssociationToGroupAndNotifyThread extends Thread { - - //private static final Logger logger = LoggerFactory.getLogger(AssociationToGroupAndNotifyThread.class); - private static final Log logger = LogFactoryUtil.getLog(AssociationToGroupAndNotifyThread.class); - private static final String PRODUCT_ASSOCIATED_TO_GROUP_SUBJECT = "Item $TITLE added to group $GROUP"; - private static final String PRODUCT_ASSOCIATED_TO_GROUP_BODY = "Dear user,
a new item named '$TITLE' has been " - + "just published by $USER_FULLNAME in $GROUP .
" - + "You can find it here $DATASET_URL"; - - private String groupTitle; - private String datasetId; - private String username; - private String datasetTitle; - private String userFullName; - private DataCatalogue catalogue; - // private String organization; - private List groups; - private HttpServletRequest request; - private String datasetUrl; - private List groupsForceCreation; - - /** - * @param list - * @param groupTitle - * @param datasetId - * @param username - * @param catalogue - */ - 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 == null ? new ArrayList() : groups; - this.groupsForceCreation = groupsForceCreation; - this.groupTitle = groupTitle; - this.datasetId = datasetId; - this.username = username; - this.catalogue = catalogue; - // this.organization = organization; - this.datasetTitle = datasetTitle; - this.userFullName = userFullName; - this.datasetUrl = datasetUrl; - } - - @Override - public void run() { - - logger.info("Association thread started to put the dataset with id = "+ datasetId + " into group with title " + groupTitle + " for user " + username); - - // force creation of groups if needed - if(groupsForceCreation != null){ - logger.info("Groups that must be created before association are " + groupsForceCreation); - for (OrganizationBean groupToForce : groupsForceCreation) { - try{ - CkanGroup group = catalogue.createGroup(groupToForce.getName(), groupToForce.getTitle(), ""); - if(group == null) - logger.error("Unable to retrieve or create group with name " + groupToForce); - else - groups.add(new OrganizationBean(group.getTitle(), group.getName(), false, groupToForce.isPropagateUp())); - }catch(Exception e){ - logger.error("Failed to check if a group with this info " + groupToForce + " already exists or can be created"); - } - } - - } - - logger.info("Other groups to which the product should be associate are " + groups); - - if(groups != null) - for (OrganizationBean groupBean : groups) { - boolean putIntoGroup = catalogue.assignDatasetToGroup(groupBean.getName(), datasetId, catalogue.getApiKeyFromUsername(username), groupBean.isPropagateUp()); - logger.info("Was product put into group" + groupBean.getTitle() + "? " + putIntoGroup); - if(putIntoGroup) - notifyGroupAdmins(catalogue, groupBean.getName() ,groupBean.getTitle(), username); - } - - } - - /** - * Send a notification to the group admin(s) about the just added product - * @param username - * @param groupTitle - * @param catalogue - */ - private void notifyGroupAdmins(DataCatalogue catalogue, String groupName, String groupTitle, String username){ - - // get the groups admin - Map> userAndRoles = catalogue.getRolesAndUsersGroup(groupName); - - if(userAndRoles.containsKey(RolesCkanGroupOrOrg.ADMIN)){ - - List admins = userAndRoles.get(RolesCkanGroupOrOrg.ADMIN); - List adminsEmails = new ArrayList(); - - for(int i = 0; i < admins.size(); i++){ - String convertedName = CatalogueUtilMethods.fromCKanUsernameToUsername(admins.get(i)); - admins.set(i, convertedName); - } - - // remove the same user who published the product if he/she is an admin of the group - int indexOfUser = admins.indexOf(username); - if(indexOfUser >= 0) - admins.remove(indexOfUser); - - // further cleaning of the list (for users that are only in ckan... sysadmin for example) - UserManager um = new LiferayUserManager(); - Iterator adminIt = admins.iterator(); - - while (adminIt.hasNext()) { - String admin = (String) adminIt.next(); - try{ - adminsEmails.add(um.getUserByUsername(admin).getEmail()); - }catch(Exception e){ - logger.error("User with username " + admin + " doesn't exist in Liferay"); - adminIt.remove(); - } - } - - logger.info("The list of admins for group " + groupTitle + " is " + admins); - - if(admins.isEmpty()) - return; - - // send the email - EmailNotification mailToSend = new EmailNotification( - adminsEmails, - PRODUCT_ASSOCIATED_TO_GROUP_SUBJECT.replace("$TITLE", datasetTitle).replace("$GROUP", groupTitle), - PRODUCT_ASSOCIATED_TO_GROUP_BODY.replace("$TITLE", datasetTitle).replace("$GROUP", groupTitle).replace("$USER_FULLNAME", userFullName).replace("$DATASET_URL", datasetUrl), - request); - mailToSend.sendEmail(); - - }else - logger.warn("It seems there is no user with role Admin in group " + groupTitle); - } -} +//package org.gcube.portlets.widgets.ckandatapublisherwidget.server.threads; +// +//import java.util.ArrayList; +//import java.util.Iterator; +//import java.util.List; +//import java.util.Map; +// +//import javax.servlet.http.HttpServletRequest; +// +//import org.gcube.common.portal.mailing.EmailNotification; +//import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogue; +//import org.gcube.datacatalogue.ckanutillibrary.server.utils.CatalogueUtilMethods; +//import org.gcube.datacatalogue.ckanutillibrary.shared.RolesCkanGroupOrOrg; +//import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanGroup; +//import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.OrganizationBean; +//import org.gcube.vomanagement.usermanagement.UserManager; +//import org.gcube.vomanagement.usermanagement.impl.LiferayUserManager; +// +//import com.liferay.portal.kernel.log.Log; +//import com.liferay.portal.kernel.log.LogFactoryUtil; +// +// +// +///** +// * Associate the dataset to a group and send notifications to group's admins. +// * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) +// */ +//public class AssociationToGroupAndNotifyThread extends Thread { +// +// //private static final Logger logger = LoggerFactory.getLogger(AssociationToGroupAndNotifyThread.class); +// private static final Log logger = LogFactoryUtil.getLog(AssociationToGroupAndNotifyThread.class); +// private static final String PRODUCT_ASSOCIATED_TO_GROUP_SUBJECT = "Item $TITLE added to group $GROUP"; +// private static final String PRODUCT_ASSOCIATED_TO_GROUP_BODY = "Dear user,
a new item named '$TITLE' has been " +// + "just published by $USER_FULLNAME in $GROUP .
" +// + "You can find it here $DATASET_URL"; +// +// private String groupTitle; +// private String datasetId; +// private String username; +// private String datasetTitle; +// private String userFullName; +// private DataCatalogue catalogue; +// // private String organization; +// private List groups; +// private HttpServletRequest request; +// private String datasetUrl; +// private List groupsForceCreation; +// +// /** +// * @param list +// * @param groupTitle +// * @param datasetId +// * @param username +// * @param catalogue +// */ +// 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 == null ? new ArrayList() : groups; +// this.groupsForceCreation = groupsForceCreation; +// this.groupTitle = groupTitle; +// this.datasetId = datasetId; +// this.username = username; +// this.catalogue = catalogue; +// // this.organization = organization; +// this.datasetTitle = datasetTitle; +// this.userFullName = userFullName; +// this.datasetUrl = datasetUrl; +// } +// +// @Override +// public void run() { +// +// logger.info("Association thread started to put the dataset with id = "+ datasetId + " into group with title " + groupTitle + " for user " + username); +// +// // force creation of groups if needed +// if(groupsForceCreation != null){ +// logger.info("Groups that must be created before association are " + groupsForceCreation); +// for (OrganizationBean groupToForce : groupsForceCreation) { +// try{ +// CkanGroup group = catalogue.createGroup(groupToForce.getName(), groupToForce.getTitle(), ""); +// if(group == null) +// logger.error("Unable to retrieve or create group with name " + groupToForce); +// else +// groups.add(new OrganizationBean(group.getTitle(), group.getName(), false, groupToForce.isPropagateUp())); +// }catch(Exception e){ +// logger.error("Failed to check if a group with this info " + groupToForce + " already exists or can be created"); +// } +// } +// +// } +// +// logger.info("Other groups to which the product should be associate are " + groups); +// +// if(groups != null) +// for (OrganizationBean groupBean : groups) { +// boolean putIntoGroup = catalogue.assignDatasetToGroup(groupBean.getName(), datasetId, groupBean.isPropagateUp()); +// logger.info("Was product put into group" + groupBean.getTitle() + "? " + putIntoGroup); +// if(putIntoGroup) +// notifyGroupAdmins(catalogue, groupBean.getName() ,groupBean.getTitle(), username); +// } +// +// } +// +// /** +// * Send a notification to the group admin(s) about the just added product +// * @param username +// * @param groupTitle +// * @param catalogue +// */ +// private void notifyGroupAdmins(DataCatalogue catalogue, String groupName, String groupTitle, String username){ +// +// // get the groups admin +// Map> userAndRoles = catalogue.getRolesAndUsersGroup(groupName); +// +// if(userAndRoles.containsKey(RolesCkanGroupOrOrg.ADMIN)){ +// +// List admins = userAndRoles.get(RolesCkanGroupOrOrg.ADMIN); +// List adminsEmails = new ArrayList(); +// +// for(int i = 0; i < admins.size(); i++){ +// String convertedName = CatalogueUtilMethods.fromCKanUsernameToUsername(admins.get(i)); +// admins.set(i, convertedName); +// } +// +// // remove the same user who published the product if he/she is an admin of the group +// int indexOfUser = admins.indexOf(username); +// if(indexOfUser >= 0) +// admins.remove(indexOfUser); +// +// // further cleaning of the list (for users that are only in ckan... sysadmin for example) +// UserManager um = new LiferayUserManager(); +// Iterator adminIt = admins.iterator(); +// +// while (adminIt.hasNext()) { +// String admin = (String) adminIt.next(); +// try{ +// adminsEmails.add(um.getUserByUsername(admin).getEmail()); +// }catch(Exception e){ +// logger.error("User with username " + admin + " doesn't exist in Liferay"); +// adminIt.remove(); +// } +// } +// +// logger.info("The list of admins for group " + groupTitle + " is " + admins); +// +// if(admins.isEmpty()) +// return; +// +// // send the email +// EmailNotification mailToSend = new EmailNotification( +// adminsEmails, +// PRODUCT_ASSOCIATED_TO_GROUP_SUBJECT.replace("$TITLE", datasetTitle).replace("$GROUP", groupTitle), +// PRODUCT_ASSOCIATED_TO_GROUP_BODY.replace("$TITLE", datasetTitle).replace("$GROUP", groupTitle).replace("$USER_FULLNAME", userFullName).replace("$DATASET_URL", datasetUrl), +// request); +// mailToSend.sendEmail(); +// +// }else +// logger.warn("It seems there is no user with role Admin in group " + groupTitle); +// } +//} diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/threads/WritePostCatalogueManagerThread.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/threads/WritePostCatalogueManagerThread.java index a98593f..8ab084e 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/threads/WritePostCatalogueManagerThread.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/threads/WritePostCatalogueManagerThread.java @@ -1,325 +1,322 @@ -package org.gcube.portlets.widgets.ckandatapublisherwidget.server.threads; - -import java.io.IOException; -import java.net.HttpURLConnection; -import java.util.List; - -import org.gcube.common.authorization.library.provider.SecurityTokenProvider; -import org.gcube.common.scope.api.ScopeProvider; -import org.gcube.portlets.widgets.ckandatapublisherwidget.server.utils.GCoreEndPointReaderSocial; -import org.gcube.portlets.widgets.ckandatapublisherwidget.server.utils.GenericUtils; -import org.json.simple.JSONObject; -import org.json.simple.parser.JSONParser; - -import com.liferay.portal.kernel.log.Log; -import com.liferay.portal.kernel.log.LogFactoryUtil; - -import eu.trentorise.opendata.jackan.internal.org.apache.http.Header; -import eu.trentorise.opendata.jackan.internal.org.apache.http.HttpEntity; -import eu.trentorise.opendata.jackan.internal.org.apache.http.HttpResponse; -import eu.trentorise.opendata.jackan.internal.org.apache.http.client.ClientProtocolException; -import eu.trentorise.opendata.jackan.internal.org.apache.http.client.methods.HttpPost; -import eu.trentorise.opendata.jackan.internal.org.apache.http.entity.StringEntity; -import eu.trentorise.opendata.jackan.internal.org.apache.http.impl.client.CloseableHttpClient; -import eu.trentorise.opendata.jackan.internal.org.apache.http.impl.client.HttpClientBuilder; -import eu.trentorise.opendata.jackan.internal.org.apache.http.util.EntityUtils; - - -/** - * Let the Product Catalogue Manager write a post in a VRE and alert there is a new product - * @author Costantino Perciante at ISTI-CNR - * (costantino.perciante@isti.cnr.it) - */ -public class WritePostCatalogueManagerThread extends Thread { - - public static final String APPLICATION_ID_CATALOGUE_MANAGER = "org.gcube.datacatalogue.ProductCatalogue"; - private static final String NOTIFICATION_MESSAGE = "Dear members,\n$USER_FULLNAME just published the item '$PRODUCT_TITLE'.\nYou can find it at: $PRODUCT_URL\n"; - private static final String SOCIAL_SERVICE_APPLICATION_TOKEN = "2/tokens/generate-application-token"; - private static final String SOCIAL_SERVICE_WRITE_APPLICATION_POST = "2/posts/write-post-app"; - private static final String MEDIATYPE_JSON = "application/json"; - private static final Log logger = LogFactoryUtil.getLog(WritePostCatalogueManagerThread.class); - private String username; - private String scope; - private String productTitle; - private String productUrl; - private boolean enableNotification; - private List hashtags; - private String userFullName; - private String userCurrentUrl; - - /** - * @param token - * @param scope - * @param productTitle - * @param productUrl - * @param enableNotification - * @param hashtags - * @param userFullName - */ - public WritePostCatalogueManagerThread( - String username, String scope, - String productTitle, String productUrl, boolean enableNotification, - List hashtags, String userFullName, String userCurrentUrl) { - super(); - this.username = username; - this.scope = scope; - this.productTitle = productTitle; - this.productUrl = productUrl; - this.enableNotification = enableNotification; - this.hashtags = hashtags; - this.userFullName = userFullName; - this.userCurrentUrl = userCurrentUrl; - } - - @Override - public void run() { - - try{ - // evaluate user's token for this scope - String token = GenericUtils.tryGetElseCreateToken(username, scope); - - if(token == null){ - logger.warn("Unable to proceed, user's token is not available"); - return; - } - - logger.info("Started request to write application post " - + "for new product created. Scope is " + scope + " and " - + "token is " + token.substring(0, 10) + "****************"); - - // set token and scope - ScopeProvider.instance.set(scope); - SecurityTokenProvider.instance.set(token); - - //see Feature #17577 - /*final String profilePageURL = GCubePortalConstants.PREFIX_GROUP_URL + extractOrgFriendlyURL(userCurrentUrl) + GCubePortalConstants.USER_PROFILE_FRIENDLY_URL; - - userFullName = ""+userFullName+ - " "; - */ - - userFullName = "@"+username; - - // write - writeProductPost( - productTitle, - productUrl, - userFullName, - hashtags, - enableNotification - ); - - }catch(Exception e){ - logger.error("Failed to write the post because of the following error ", e); - }finally{ - SecurityTokenProvider.instance.reset(); - ScopeProvider.instance.reset(); - } - } - - public static String extractOrgFriendlyURL(String portalURL) { - String groupRegEx = "/group/"; - if (portalURL.contains(groupRegEx)) { - String[] splits = portalURL.split(groupRegEx); - String friendlyURL = splits[1]; - if (friendlyURL.contains("/")) { - friendlyURL = friendlyURL.split("/")[0]; - } else { - friendlyURL = friendlyURL.split("\\?")[0].split("\\#")[0]; - } - return "/"+friendlyURL; - } - return null; - } - - /** - * Send notification to vre members about the created product by writing a post. - * @param productName the title of the product - * @param productUrl the url of the product - * @param hashtags a list of product's hashtags - */ - private static void writeProductPost(String productName, String productUrl, String userFullname, List hashtags, boolean enablePostNotification){ - - // discover service endpoint for the social networking library - String currentScope = ScopeProvider.instance.get(); - String tokenUser = SecurityTokenProvider.instance.get(); - - logger.info("Current scope for writeProductPost is " + currentScope + " and token is " + tokenUser.substring(0, 10) + "***************"); - String basePath = new GCoreEndPointReaderSocial(currentScope).getBasePath(); - - if(basePath == null){ - - logger.error("Unable to write a post because there is no social networking service available"); - - }else{ - - // check base path form - basePath = basePath.endsWith("/") ? basePath : basePath + "/"; - - try(CloseableHttpClient client = HttpClientBuilder.create().build();){ - - String pathTokenApp = basePath + SOCIAL_SERVICE_APPLICATION_TOKEN + "?gcube-token=" + tokenUser; - String tokenApp = requireAppToken(client, pathTokenApp); - if(tokenApp != null){ - String pathWritePost = basePath + SOCIAL_SERVICE_WRITE_APPLICATION_POST + "?gcube-token=" + tokenApp; - writePost(client, pathWritePost, productName, productUrl, userFullname, hashtags, enablePostNotification); - } - - }catch(Exception e){ - logger.error("Failed to create a post", e); - } - } - } - - /** - * Require the application token - * @param tokenUser - * @param basePath - * @param client - * @return - */ - private static String requireAppToken(CloseableHttpClient client, String path){ - - String token = null; - try{ - - JSONObject request = new JSONObject(); - request.put("app_id", APPLICATION_ID_CATALOGUE_MANAGER); - HttpResponse response = performRequest(client, path, request.toJSONString()); - - int statusTokenGenerate = response.getStatusLine().getStatusCode(); - - if(statusTokenGenerate == HttpURLConnection.HTTP_CREATED){ - - // extract token - JSONObject obj = getJSONObject(response); - if(((Boolean) obj.get("success"))) - token = (String)obj.get("result"); - else - return null; - - }else if(statusTokenGenerate == HttpURLConnection.HTTP_MOVED_TEMP - || statusTokenGenerate == HttpURLConnection.HTTP_MOVED_PERM - || statusTokenGenerate == HttpURLConnection.HTTP_SEE_OTHER){ - - // re-execute - Header[] locations = response.getHeaders("Location"); - Header lastLocation = locations[locations.length - 1]; - String realLocation = lastLocation.getValue(); - logger.debug("New location is " + realLocation); - token = requireAppToken(client, realLocation); - - }else - return null; - - }catch(Exception e){ - logger.error("Failed to retrieve application token", e); - } - - logger.info("Returning app token " + (token != null ? token.substring(0, 10) + "*************************" : null)); - return token; - } - - /** - * Write post request - * @param client - * @param applicationToken - * @param productName - * @param productUrl - * @param userFullname - * @param hashtags - */ - private static void writePost(CloseableHttpClient client, String path, String productName, String productUrl, String userFullname, List hashtags, - boolean enablePostNotification) { - - try{ - - // replace - String message = NOTIFICATION_MESSAGE.replace("$PRODUCT_TITLE", productName).replace("$PRODUCT_URL", productUrl).replace("$USER_FULLNAME", userFullname); - - if(hashtags != null && !hashtags.isEmpty()) - for (String hashtag : hashtags) { - String modifiedHashtag = hashtag.replaceAll(" ", "_").replace("_+", "_"); - if(modifiedHashtag.endsWith("_")) - modifiedHashtag = modifiedHashtag.substring(0, modifiedHashtag.length() - 1); - message += " #" + modifiedHashtag; // ckan accepts tag with empty spaces, we don't - } - - JSONObject request = new JSONObject(); - request.put("text", message); - request.put("enable_notification", enablePostNotification); - logger.info("The post that is going to be written is ->\n" + request.toJSONString()); - HttpResponse response = performRequest(client, path, request.toJSONString()); - int statusWritePost = response.getStatusLine().getStatusCode(); - - if(statusWritePost == HttpURLConnection.HTTP_CREATED){ - - // extract token - JSONObject obj = getJSONObject(response); - if(((Boolean) obj.get("success"))) - logger.info("Post written"); - else - logger.info("Failed to write the post " + obj.get("message")); - - }else if(statusWritePost == HttpURLConnection.HTTP_MOVED_TEMP - || statusWritePost == HttpURLConnection.HTTP_MOVED_PERM - || statusWritePost == HttpURLConnection.HTTP_SEE_OTHER){ - - // re-execute - Header[] locations = response.getHeaders("Location"); - Header lastLocation = locations[locations.length - 1]; - String realLocation = lastLocation.getValue(); - logger.debug("New location is " + realLocation); - writePost(client, realLocation, productName, productUrl, userFullname, hashtags, enablePostNotification); - - }else - throw new RuntimeException("Failed to write the post "); - - }catch(Exception e){ - logger.error("Failed to write the post ", e); - } - - } - - /** - * Convert the json response to a map - * @param response - * @return - */ - private static JSONObject getJSONObject(HttpResponse response){ - - JSONObject toReturn = null; - HttpEntity entity = response.getEntity(); - - if (entity != null) { - try { - String jsonString = EntityUtils.toString(response.getEntity()); - JSONParser parser = new JSONParser(); - toReturn = (JSONObject)parser.parse(jsonString); - }catch(Exception e){ - logger.error("Failed to read json object", e); - } - } - - logger.debug("Returning " + toReturn.toJSONString()); - return toReturn; - } - - /** - * Perform an http request post request with json entity - * @throws IOException - * @throws ClientProtocolException - */ - private static HttpResponse performRequest(CloseableHttpClient client, String path, String entity) throws ClientProtocolException, IOException{ - - HttpPost request = new HttpPost(path); - StringEntity stringEntity = new StringEntity(entity); - stringEntity.setContentType(MEDIATYPE_JSON); - request.setEntity(stringEntity); - return client.execute(request); - - } - -} \ No newline at end of file +//package org.gcube.portlets.widgets.ckandatapublisherwidget.server.threads; +// +//import java.io.IOException; +//import java.net.HttpURLConnection; +//import java.util.List; +// +//import org.apache.http.HttpEntity; +//import org.apache.http.HttpResponse; +//import org.apache.http.client.ClientProtocolException; +//import org.apache.http.client.methods.HttpPost; +//import org.apache.http.entity.StringEntity; +//import org.apache.http.impl.client.CloseableHttpClient; +//import org.apache.http.impl.client.HttpClientBuilder; +//import org.apache.http.util.EntityUtils; +//import org.gcube.common.authorization.library.provider.SecurityTokenProvider; +//import org.gcube.common.scope.api.ScopeProvider; +//import org.gcube.portlets.widgets.ckandatapublisherwidget.server.utils.GCoreEndPointReaderSocial; +//import org.gcube.portlets.widgets.ckandatapublisherwidget.server.utils.GenericUtils; +// +//import com.google.gwt.json.client.JSONParser; +//import com.liferay.portal.kernel.log.Log; +//import com.liferay.portal.kernel.log.LogFactoryUtil; +// +// +///** +// * Let the Product Catalogue Manager write a post in a VRE and alert there is a new product +// * @author Costantino Perciante at ISTI-CNR +// * (costantino.perciante@isti.cnr.it) +// */ +//public class WritePostCatalogueManagerThread extends Thread { +// +// public static final String APPLICATION_ID_CATALOGUE_MANAGER = "org.gcube.datacatalogue.ProductCatalogue"; +// private static final String NOTIFICATION_MESSAGE = "Dear members,\n$USER_FULLNAME just published the item '$PRODUCT_TITLE'.\nYou can find it at: $PRODUCT_URL\n"; +// private static final String SOCIAL_SERVICE_APPLICATION_TOKEN = "2/tokens/generate-application-token"; +// private static final String SOCIAL_SERVICE_WRITE_APPLICATION_POST = "2/posts/write-post-app"; +// private static final String MEDIATYPE_JSON = "application/json"; +// private static final Log logger = LogFactoryUtil.getLog(WritePostCatalogueManagerThread.class); +// private String username; +// private String scope; +// private String productTitle; +// private String productUrl; +// private boolean enableNotification; +// private List hashtags; +// private String userFullName; +// private String userCurrentUrl; +// +// /** +// * @param token +// * @param scope +// * @param productTitle +// * @param productUrl +// * @param enableNotification +// * @param hashtags +// * @param userFullName +// */ +// public WritePostCatalogueManagerThread( +// String username, String scope, +// String productTitle, String productUrl, boolean enableNotification, +// List hashtags, String userFullName, String userCurrentUrl) { +// super(); +// this.username = username; +// this.scope = scope; +// this.productTitle = productTitle; +// this.productUrl = productUrl; +// this.enableNotification = enableNotification; +// this.hashtags = hashtags; +// this.userFullName = userFullName; +// this.userCurrentUrl = userCurrentUrl; +// } +// +// @Override +// public void run() { +// +// try{ +// // evaluate user's token for this scope +// String token = GenericUtils.tryGetElseCreateToken(username, scope); +// +// if(token == null){ +// logger.warn("Unable to proceed, user's token is not available"); +// return; +// } +// +// logger.info("Started request to write application post " +// + "for new product created. Scope is " + scope + " and " +// + "token is " + token.substring(0, 10) + "****************"); +// +// // set token and scope +// ScopeProvider.instance.set(scope); +// SecurityTokenProvider.instance.set(token); +// +// //see Feature #17577 +// /*final String profilePageURL = GCubePortalConstants.PREFIX_GROUP_URL + extractOrgFriendlyURL(userCurrentUrl) + GCubePortalConstants.USER_PROFILE_FRIENDLY_URL; +// +// userFullName = ""+userFullName+ +// " "; +// */ +// +// userFullName = "@"+username; +// +// // write +// writeProductPost( +// productTitle, +// productUrl, +// userFullName, +// hashtags, +// enableNotification +// ); +// +// }catch(Exception e){ +// logger.error("Failed to write the post because of the following error ", e); +// }finally{ +// SecurityTokenProvider.instance.reset(); +// ScopeProvider.instance.reset(); +// } +// } +// +// public static String extractOrgFriendlyURL(String portalURL) { +// String groupRegEx = "/group/"; +// if (portalURL.contains(groupRegEx)) { +// String[] splits = portalURL.split(groupRegEx); +// String friendlyURL = splits[1]; +// if (friendlyURL.contains("/")) { +// friendlyURL = friendlyURL.split("/")[0]; +// } else { +// friendlyURL = friendlyURL.split("\\?")[0].split("\\#")[0]; +// } +// return "/"+friendlyURL; +// } +// return null; +// } +// +// /** +// * Send notification to vre members about the created product by writing a post. +// * @param productName the title of the product +// * @param productUrl the url of the product +// * @param hashtags a list of product's hashtags +// */ +// private static void writeProductPost(String productName, String productUrl, String userFullname, List hashtags, boolean enablePostNotification){ +// +// // discover service endpoint for the social networking library +// String currentScope = ScopeProvider.instance.get(); +// String tokenUser = SecurityTokenProvider.instance.get(); +// +// logger.info("Current scope for writeProductPost is " + currentScope + " and token is " + tokenUser.substring(0, 10) + "***************"); +// String basePath = new GCoreEndPointReaderSocial(currentScope).getBasePath(); +// +// if(basePath == null){ +// +// logger.error("Unable to write a post because there is no social networking service available"); +// +// }else{ +// +// // check base path form +// basePath = basePath.endsWith("/") ? basePath : basePath + "/"; +// +// try(CloseableHttpClient client = HttpClientBuilder.create().build();){ +// +// String pathTokenApp = basePath + SOCIAL_SERVICE_APPLICATION_TOKEN + "?gcube-token=" + tokenUser; +// String tokenApp = requireAppToken(client, pathTokenApp); +// if(tokenApp != null){ +// String pathWritePost = basePath + SOCIAL_SERVICE_WRITE_APPLICATION_POST + "?gcube-token=" + tokenApp; +// writePost(client, pathWritePost, productName, productUrl, userFullname, hashtags, enablePostNotification); +// } +// +// }catch(Exception e){ +// logger.error("Failed to create a post", e); +// } +// } +// } +// +// /** +// * Require the application token +// * @param tokenUser +// * @param basePath +// * @param client +// * @return +// */ +// private static String requireAppToken(CloseableHttpClient client, String path){ +// +// String token = null; +// try{ +// +// JSONObject request = new JSONObject(); +// request.put("app_id", APPLICATION_ID_CATALOGUE_MANAGER); +// HttpResponse response = performRequest(client, path, request.toJSONString()); +// +// int statusTokenGenerate = response.getStatusLine().getStatusCode(); +// +// if(statusTokenGenerate == HttpURLConnection.HTTP_CREATED){ +// +// // extract token +// JSONObject obj = getJSONObject(response); +// if(((Boolean) obj.get("success"))) +// token = (String)obj.get("result"); +// else +// return null; +// +// }else if(statusTokenGenerate == HttpURLConnection.HTTP_MOVED_TEMP +// || statusTokenGenerate == HttpURLConnection.HTTP_MOVED_PERM +// || statusTokenGenerate == HttpURLConnection.HTTP_SEE_OTHER){ +// +// // re-execute +// Header[] locations = response.getHeaders("Location"); +// Header lastLocation = locations[locations.length - 1]; +// String realLocation = lastLocation.getValue(); +// logger.debug("New location is " + realLocation); +// token = requireAppToken(client, realLocation); +// +// }else +// return null; +// +// }catch(Exception e){ +// logger.error("Failed to retrieve application token", e); +// } +// +// logger.info("Returning app token " + (token != null ? token.substring(0, 10) + "*************************" : null)); +// return token; +// } +// +// /** +// * Write post request +// * @param client +// * @param applicationToken +// * @param productName +// * @param productUrl +// * @param userFullname +// * @param hashtags +// */ +// private static void writePost(CloseableHttpClient client, String path, String productName, String productUrl, String userFullname, List hashtags, +// boolean enablePostNotification) { +// +// try{ +// +// // replace +// String message = NOTIFICATION_MESSAGE.replace("$PRODUCT_TITLE", productName).replace("$PRODUCT_URL", productUrl).replace("$USER_FULLNAME", userFullname); +// +// if(hashtags != null && !hashtags.isEmpty()) +// for (String hashtag : hashtags) { +// String modifiedHashtag = hashtag.replaceAll(" ", "_").replace("_+", "_"); +// if(modifiedHashtag.endsWith("_")) +// modifiedHashtag = modifiedHashtag.substring(0, modifiedHashtag.length() - 1); +// message += " #" + modifiedHashtag; // ckan accepts tag with empty spaces, we don't +// } +// +// JSONObject request = new JSONObject(); +// request.put("text", message); +// request.put("enable_notification", enablePostNotification); +// logger.info("The post that is going to be written is ->\n" + request.toJSONString()); +// HttpResponse response = performRequest(client, path, request.toJSONString()); +// int statusWritePost = response.getStatusLine().getStatusCode(); +// +// if(statusWritePost == HttpURLConnection.HTTP_CREATED){ +// +// // extract token +// JSONObject obj = getJSONObject(response); +// if(((Boolean) obj.get("success"))) +// logger.info("Post written"); +// else +// logger.info("Failed to write the post " + obj.get("message")); +// +// }else if(statusWritePost == HttpURLConnection.HTTP_MOVED_TEMP +// || statusWritePost == HttpURLConnection.HTTP_MOVED_PERM +// || statusWritePost == HttpURLConnection.HTTP_SEE_OTHER){ +// +// // re-execute +// Header[] locations = response.getHeaders("Location"); +// Header lastLocation = locations[locations.length - 1]; +// String realLocation = lastLocation.getValue(); +// logger.debug("New location is " + realLocation); +// writePost(client, realLocation, productName, productUrl, userFullname, hashtags, enablePostNotification); +// +// }else +// throw new RuntimeException("Failed to write the post "); +// +// }catch(Exception e){ +// logger.error("Failed to write the post ", e); +// } +// +// } +// +// /** +// * Convert the json response to a map +// * @param response +// * @return +// */ +// private static JSONObject getJSONObject(HttpResponse response){ +// +// JSONObject toReturn = null; +// HttpEntity entity = response.getEntity(); +// +// if (entity != null) { +// try { +// String jsonString = EntityUtils.toString(response.getEntity()); +// JSONParser parser = new JSONParser(); +// toReturn = (JSONObject)parser.parse(jsonString); +// }catch(Exception e){ +// logger.error("Failed to read json object", e); +// } +// } +// +// logger.debug("Returning " + toReturn.toJSONString()); +// return toReturn; +// } +// +// /** +// * Perform an http request post request with json entity +// * @throws IOException +// * @throws ClientProtocolException +// */ +// private static HttpResponse performRequest(CloseableHttpClient client, String path, String entity) throws ClientProtocolException, IOException{ +// +// HttpPost request = new HttpPost(path); +// StringEntity stringEntity = new StringEntity(entity); +// stringEntity.setContentType(MEDIATYPE_JSON); +// request.setEntity(stringEntity); +// return client.execute(request); +// +// } +// +//} \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/CatalogueRoleManager.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/CatalogueRoleManager.java index 1c1ca35..da8ff78 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/CatalogueRoleManager.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/CatalogueRoleManager.java @@ -4,8 +4,9 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogue; -import org.gcube.datacatalogue.ckanutillibrary.shared.RolesCkanGroupOrOrg; +import org.gcube.datacatalogue.utillibrary.server.DataCatalogue; +import org.gcube.datacatalogue.utillibrary.shared.RolesCkanGroupOrOrg; +import org.gcube.datacatalogue.utillibrary.shared.jackan.model.CkanOrganization; import org.gcube.portlets.widgets.ckandatapublisherwidget.server.CKANPublisherServicesImpl; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.OrganizationBean; import org.gcube.vomanagement.usermanagement.GroupManager; @@ -19,18 +20,17 @@ import org.gcube.vomanagement.usermanagement.impl.LiferayUserManager; import org.gcube.vomanagement.usermanagement.model.GCubeGroup; import org.gcube.vomanagement.usermanagement.model.GCubeRole; import org.gcube.vomanagement.usermanagement.model.GatewayRolesNames; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import com.liferay.portal.kernel.log.Log; -import com.liferay.portal.kernel.log.LogFactoryUtil; -import eu.trentorise.opendata.jackan.model.CkanOrganization; /** * Facilities to check roles into the catalogue. */ public class CatalogueRoleManager { - private static final Log logger = LogFactoryUtil.getLog(CatalogueRoleManager.class); + private static final Logger logger = LoggerFactory.getLogger(CatalogueRoleManager.class); /** * Retrieve the highest ckan role the user has and also retrieve the list of organizations (scopes) in which the user has the ckan-admin or ckan-editor role 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 7dc66f2..c1e6176 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 @@ -10,24 +10,23 @@ 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.datacatalogue.utillibrary.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.slf4j.Logger; +import org.slf4j.LoggerFactory; 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); + private static final Logger logger = LoggerFactory.getLogger(CKANPublisherServicesImpl.class); private final static String APPLICATION_PROFILE_NAME = "Tags"; private final static String QUERY = "for $profile in collection('/db/Profiles/GenericResource')//Resource " + diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/GCoreEndPointReaderSocial.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/GCoreEndPointReaderSocial.java index 17d3454..81c314c 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/GCoreEndPointReaderSocial.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/GCoreEndPointReaderSocial.java @@ -9,9 +9,8 @@ import org.gcube.common.resources.gcore.GCoreEndpoint; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.resources.discovery.client.api.DiscoveryClient; import org.gcube.resources.discovery.client.queries.api.SimpleQuery; - -import com.liferay.portal.kernel.log.Log; -import com.liferay.portal.kernel.log.LogFactoryUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Retrieves the base url of the social-networking service in the scope provided @@ -20,7 +19,7 @@ import com.liferay.portal.kernel.log.LogFactoryUtil; public class GCoreEndPointReaderSocial { private String basePath = null; - private static final Log logger = LogFactoryUtil.getLog(GCoreEndPointReaderSocial.class); + private static final Logger logger = LoggerFactory.getLogger(GCoreEndPointReaderSocial.class); private static final String resource = "jersey-servlet"; private static final String serviceName = "SocialNetworking"; private static final String serviceClass = "Portal"; diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/GenericUtils.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/GenericUtils.java index b3346ca..babf567 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/GenericUtils.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/GenericUtils.java @@ -15,16 +15,15 @@ import org.gcube.common.authorization.library.provider.SecurityTokenProvider; import org.gcube.common.authorization.library.provider.UserInfo; import org.gcube.common.portal.PortalContext; import org.gcube.common.scope.api.ScopeProvider; -import org.gcube.datacatalogue.ckanutillibrary.server.ApplicationProfileScopePerUrlReader; +import org.gcube.datacatalogue.utillibrary.server.ApplicationProfileScopePerUrlReader; import org.gcube.vomanagement.usermanagement.GroupManager; import org.gcube.vomanagement.usermanagement.exception.GroupRetrievalFault; import org.gcube.vomanagement.usermanagement.exception.UserManagementSystemException; import org.gcube.vomanagement.usermanagement.impl.LiferayGroupManager; import org.gcube.vomanagement.usermanagement.model.GCubeGroup; import org.gcube.vomanagement.usermanagement.model.GCubeUser; - -import com.liferay.portal.kernel.log.Log; -import com.liferay.portal.kernel.log.LogFactoryUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Util class with static methods. @@ -35,7 +34,7 @@ public class GenericUtils { // Logger //private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Utils.class); - private static final Log logger = LogFactoryUtil.getLog(GenericUtils.class); + private static final Logger logger = LoggerFactory.getLogger(GenericUtils.class); public static final String GCUBE_REQUEST_URL = "gcube-request-url"; /** @@ -52,13 +51,18 @@ public class GenericUtils { GroupManager gm = new LiferayGroupManager(); List groups = gm.listGroups(); for (GCubeGroup gCubeGroup : groups) { - if(gCubeGroup.getGroupName().equalsIgnoreCase(organizationName)) - return gm.getInfrastructureScope(gCubeGroup.getGroupId()); + if(gCubeGroup.getGroupName().equalsIgnoreCase(organizationName)) { + String theScope = gm.getInfrastructureScope(gCubeGroup.getGroupId()); + logger.info("For organizationName: " + organizationName+" by using "+LiferayGroupManager.class.getSimpleName()+ " got the scope: "+theScope +", returning it"); + return theScope; + } } - + + logger.info("No scope detected for organizationName: " + organizationName +" by using "+LiferayGroupManager.class.getSimpleName()); return null; } + /** * First check to retrieve the token, else create it. * 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 e484f45..1830ebf 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 @@ -10,8 +10,6 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.gcube.common.scope.api.ScopeProvider; -import org.gcube.datacatalogue.ckanutillibrary.server.utils.CatalogueUtilMethods; -import org.gcube.datacatalogue.ckanutillibrary.server.utils.SessionCatalogueAttributes; import org.gcube.datacatalogue.metadatadiscovery.DataCalogueMetadataFormatReader; import org.gcube.datacatalogue.metadatadiscovery.bean.MetadataProfile; import org.gcube.datacatalogue.metadatadiscovery.bean.jaxb.MetadataField; @@ -21,6 +19,8 @@ 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.datacatalogue.utillibrary.server.utils.CatalogueUtilMethods; +import org.gcube.datacatalogue.utillibrary.server.utils.SessionCatalogueAttributes; 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; @@ -28,9 +28,8 @@ import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.metadata.FieldA import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.metadata.MetaDataProfileBean; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.metadata.MetadataFieldWrapper; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.metadata.TaggingGroupingValue; - -import com.liferay.portal.kernel.log.Log; -import com.liferay.portal.kernel.log.LogFactoryUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Metadatadiscovery facility. @@ -38,7 +37,7 @@ import com.liferay.portal.kernel.log.LogFactoryUtil; */ public class MetadataDiscovery { - private static final Log logger = LogFactoryUtil.getLog(MetadataDiscovery.class); + private static final Logger logger = LoggerFactory.getLogger(MetadataDiscovery.class); /** * Returns the names of the metadata profiles in a given context diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/WorkspaceUtils.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/WorkspaceUtils.java index 283ce3e..12a410c 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/WorkspaceUtils.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/WorkspaceUtils.java @@ -1,5 +1,6 @@ package org.gcube.portlets.widgets.ckandatapublisherwidget.server.utils; +import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -8,90 +9,186 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; -import org.gcube.common.homelibary.model.items.type.FolderItemType; -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.WorkspaceFolder; -import org.gcube.common.homelibrary.home.workspace.WorkspaceItem; -import org.gcube.common.homelibrary.home.workspace.catalogue.WorkspaceCatalogue; -import org.gcube.common.homelibrary.home.workspace.folder.FolderItem; -import org.gcube.common.homelibrary.home.workspace.folder.items.ExternalUrl; -import org.gcube.common.homelibrary.home.workspace.folder.items.GCubeItem; -import org.gcube.datacatalogue.ckanutillibrary.server.utils.CatalogueUtilMethods; -import org.gcube.datacatalogue.ckanutillibrary.shared.ResourceBean; +import javax.servlet.http.HttpServletRequest; + +import org.gcube.common.portal.PortalContext; +import org.gcube.common.storagehubwrapper.server.StorageHubWrapper; +import org.gcube.common.storagehubwrapper.server.tohl.Workspace; +import org.gcube.common.storagehubwrapper.shared.tohl.WorkspaceItem; +import org.gcube.common.storagehubwrapper.shared.tohl.impl.URLFile; +import org.gcube.common.storagehubwrapper.shared.tohl.items.FileItem; +import org.gcube.common.storagehubwrapper.shared.tohl.items.GCubeItem; +import org.gcube.common.storagehubwrapper.shared.tohl.items.PropertyMap; +import org.gcube.datacatalogue.utillibrary.shared.ResourceBean; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.DatasetBean; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.ResourceElementBean; +import org.gcube.vomanagement.usermanagement.model.GCubeUser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import com.liferay.portal.kernel.log.Log; -import com.liferay.portal.kernel.log.LogFactoryUtil; +import com.liferay.portal.service.UserLocalServiceUtil; + +/** + * The Class WorkspaceUtils. + * + * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) + * + * Feb 18, 2021 + */ public class WorkspaceUtils { //private static final org.slf4j.Logger logger = LoggerFactory.getLogger(WorkspaceUtils.class); - private static final Log logger = LogFactoryUtil.getLog(WorkspaceUtils.class); + private static final Logger logger = LoggerFactory.getLogger(WorkspaceUtils.class); private static final String RESOURCES_NAME_SEPARATOR = "_"; private static final String STRIP_NOT_ALPHANUMERIC = "[^A-Za-z0-9.-_]"; + /** - * This method receives a folder id within the user's workspace and set the list of resources in the dataset bean to be returned - * @param folderId - * @param owner - * @param bean - * @param userName - * @throws Exception + * Checks if is within portal. + * + * @return true if you're running into the portal, false if in development */ - public static void handleWorkspaceResources(String folderId, String userName, - DatasetBean bean) throws Exception { + public static boolean isWithinPortal() { + try { + UserLocalServiceUtil.getService(); + return true; + } catch (Exception ex) { + logger.trace("Development Mode ON"); + return false; + } + } + + /** + * Gets the storage hub wrapper. + * + * @param request + * the request + * @param scopeGroupId + * the scope group id. If scopeGroupId is null the scope is read + * by using the request else by using the scopeGroupId + * @param user + * the user + * @return the storage hub wrapper + * @throws Exception + * the exception + */ + public static StorageHubWrapper getStorageHubWrapper(final HttpServletRequest request, String scopeGroupId, + GCubeUser user) throws Exception { - // get workspace - Workspace ws = HomeLibrary - .getHomeManagerFactory() - .getHomeManager() - .getHome().getWorkspace(); + if (user == null || user.getUsername().isEmpty()) + throw new Exception("Session expired"); - WorkspaceItem originalFolderOrFile = ws.getItem(folderId); + try { + String scope; + PortalContext pContext = PortalContext.getConfiguration(); + if (isWithinPortal() && scopeGroupId != null) { + scope = pContext.getCurrentScope(scopeGroupId); + logger.debug(scope + " has retrieved by using the scopeGroupId=" + scopeGroupId); + } else + scope = pContext.getCurrentScope(request); + + logger.debug("Getting " + StorageHubWrapper.class.getSimpleName() + " for user: " + user.getUsername() + + " by using the scope: " + scope); + String token = pContext.getCurrentUserToken(scope, user.getUsername()); + return new StorageHubWrapper(scope, token, false, false, true); + } catch (Exception e) { + logger.error("Error during getting storageHub wrapper", e); + throw new Exception("Error on gettig the StorageHub wrapper for userId: " + user); + } + } + + /** + * This method receives an item-id within the user's workspace and setit in the dataset bean to be returned. + * revisited by Francesco + * + * @param wsItemId the ws item id + * @param userName the user name + * @param bean the bean + * @param workspace the workspace + * @throws Exception the exception + */ + public static void toWorkspaceResource(String wsItemId, String userName, + DatasetBean bean, Workspace workspace) throws Exception { + + WorkspaceItem originalFolderOrFile = workspace.getItem(wsItemId); logger.debug("Item retrieved is " + originalFolderOrFile); + + String title = originalFolderOrFile.getTitle() != null && !originalFolderOrFile.getTitle().isEmpty() + ? originalFolderOrFile.getTitle() + : originalFolderOrFile.getName(); + + title = title.replaceAll(STRIP_NOT_ALPHANUMERIC, " "); + bean.setTitle(title); + + ResourceElementBean resourceEB = new ResourceElementBean(); + resourceEB.setOriginalIdInWorkspace(wsItemId); + resourceEB.setName(originalFolderOrFile.getName()); + resourceEB.setDescription(originalFolderOrFile.getDescription()); + resourceEB.setFolder(originalFolderOrFile.isFolder()); + resourceEB.setEditableName(originalFolderOrFile.getName()); + resourceEB.setRootIdInWorkspace(workspace.getRoot().getId()); - if(!originalFolderOrFile.isFolder()){ + //in case of folder + if(originalFolderOrFile.isFolder()) { - ResourceElementBean resource = new ResourceElementBean(); - resource.setDescription(originalFolderOrFile.getDescription()); - resource.setFolder(false); - resource.setEditableName(originalFolderOrFile.getName()); - resource.setName(originalFolderOrFile.getName()); - resource.setOriginalIdInWorkspace(folderId); - bean.setResourceRoot(resource); - bean.setTitle(originalFolderOrFile.getName().replaceAll(STRIP_NOT_ALPHANUMERIC, " ")); - bean.setDescription(originalFolderOrFile.getDescription()); - - }else{ - - String onlyAlphanumericTitle = originalFolderOrFile.getName().replaceAll(STRIP_NOT_ALPHANUMERIC, " "); - bean.setTitle(onlyAlphanumericTitle); - bean.setDescription(originalFolderOrFile.getDescription()); - - // Create the folder in the catalogue + // loading gcube properties Map folderItems = getGcubeItemProperties(originalFolderOrFile); - if(folderItems != null){ + if(folderItems != null && folderItems.size()>0){ // transform this properties Map> tempItems = new HashMap>(folderItems.size()); Iterator> iterator = folderItems.entrySet().iterator(); while (iterator.hasNext()) { - Map.Entry entry = (Map.Entry) iterator - .next(); + Map.Entry entry = (Map.Entry) iterator.next(); tempItems.put(entry.getKey(), Arrays.asList(entry.getValue())); } + //setting properties as custom fields bean.setCustomFields(tempItems); } - - // set them into the bean - bean.setResourceRoot(WorkspaceUtils.getTreeFromFolder(folderId, ws)); + + resourceEB.setChildrenSize(workspace.getChildren(originalFolderOrFile.getId()).size()); + }else { + //it is a file, removing extension + int indexOfDot = title.lastIndexOf("."); + if(indexOfDot>0) { + String suffix = title.substring(indexOfDot, title.length()); + if(suffix.length()>=1 && suffix.length()<=4) { + //I'm considering last .suffix as an file extension so removing it. + title = title.substring(0,indexOfDot); + bean.setTitle(title); + } + } + } + + //Replacing /Home/user.name with "" + String fullPathBase = originalFolderOrFile.getPath(); + logger.debug("Path is: "+fullPathBase); + String prefixNodeWorkspace = String.format("/%s/%s", "Home",userName); + logger.debug("Searching: "+prefixNodeWorkspace); + if(fullPathBase.startsWith(prefixNodeWorkspace)){ + logger.info("Removing from path the prefix: "+prefixNodeWorkspace); + fullPathBase = fullPathBase.replaceFirst(prefixNodeWorkspace, ""); + } + resourceEB.setFullPath(fullPathBase); + + //setting parent id + ResourceElementBean theParent = new ResourceElementBean(); + + if(originalFolderOrFile.getParentId()!=null) { + try { + WorkspaceItem parentItem = workspace.getItem(originalFolderOrFile.getParentId()); + theParent.setOriginalIdInWorkspace(parentItem.getId()); + theParent.setName(parentItem.getName()); + }catch (Exception e) { + logger.warn("Error on loading the parent item with id: "+originalFolderOrFile.getParentId()+" skipping it"); + } } + resourceEB.setParent(theParent); + bean.setResourceRoot(resourceEB); } /** Gets the gcube item properties. @@ -104,143 +201,180 @@ public class WorkspaceUtils { 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)); + Map properties = null; + if(gItem.getPropertyMap()!=null){ + Map map = toSimpleMap(gItem.getPropertyMap()); + if(map!=null) { + 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) { + } catch (Exception e) { logger.error("Error in server getItemProperties: ", e); } } return null; } - + /** - * Returns a tree object - * @param workspaceFolderId - * @param ws - * @return ResourceElementBean a tree object - * @throws Exception + * To simple map. + * + * @param propertyMap the property map + * @return the map */ - public static ResourceElementBean getTreeFromFolder(String workspaceFolderId, Workspace ws) throws Exception{ + public static Map toSimpleMap(PropertyMap propertyMap) { - ResourceElementBean rootElem = new ResourceElementBean(); - String pathSeparator = ws.getPathSeparator(); - WorkspaceItem initialItem = ws.getItem(workspaceFolderId); - String fullPathBase = initialItem.getPath(); - fullPathBase = fullPathBase.endsWith(ws.getPathSeparator()) ? fullPathBase : fullPathBase + ws.getPathSeparator(); - rootElem.setFolder(initialItem.isFolder()); - rootElem.setFullPath(initialItem.getPath().replace(fullPathBase, "")); - rootElem.setName(initialItem.getName()); - rootElem.setOriginalIdInWorkspace(initialItem.getId()); - rootElem.setDescription(initialItem.getDescription()); - extractEditableNameFromPath(rootElem, pathSeparator); + if (propertyMap == null) + return null; - // recursive visiting - if(initialItem.isFolder()) - visit(rootElem, initialItem, fullPathBase, pathSeparator); - - logger.debug("Tree that is going to be returned is " + rootElem); - return rootElem; - } - - /** - * Recursive visit of a workspace item - * @param rootElem - * @param initialItemWS - * @throws InternalErrorException - */ - private static void visit(ResourceElementBean parent, WorkspaceItem initialItemWS, String fullPathBase, String pathSeparator) throws InternalErrorException { - List children = initialItemWS.getChildren(); - ArrayList childrenInTree = new ArrayList(children.size()); - for (WorkspaceItem item : children) { - // logger.debug("Path BEFORE REPLACE is " + item.getPath()); - // logger.debug("Path AFTER REPLACE is " + item.getPath().replace(fullPathBase, "")); - // logger.debug("Name is " + item.getName()); - // logger.debug("id is " + item.getId()); - ResourceElementBean elem = new ResourceElementBean(); - elem.setFolder(item.isFolder()); - elem.setOriginalIdInWorkspace(item.getId()); - elem.setFullPath(item.getPath().replace(fullPathBase, "")); - elem.setParent(parent); - elem.setName(item.getName()); - elem.setDescription(item.getDescription()); - extractEditableNameFromPath(elem, pathSeparator); - childrenInTree.add(elem); - logger.trace("Elem is " + elem); - if(item.isFolder()) - visit(elem, item, fullPathBase, pathSeparator); + try { + Map properties = null; + Map map = propertyMap.getValues(); + + if (map != null) { + properties = new HashMap(map.size()); + for (String key : map.keySet()) { + Object theValue = map.get(key); + properties.put(key, (String) theValue); + } + } + + if(properties!=null) + logger.error("Converted: "+properties.size()+" property/properties"); + + return properties; + } catch (Exception e) { + logger.error("Error on converting a PropertyMap to simple Map: ", e); + return null; } - // add these list as child of the rootElem - parent.setChildren(childrenInTree); } + - /** - * Replaces the "/" char with a custom one and return an editable name for the user - * @param rootElem - * @param pathSeparatorInWs - */ - private static void extractEditableNameFromPath(ResourceElementBean rootElem, String pathSeparatorInWs) { +// /** +// * Returns ResourceElementBean corresponding to workspaceFolderId +// * +// * @param workspaceFolderId the workspace folder id +// * @param workspace the workspace +// * @return ResourceElementBean a tree object +// * @throws Exception the exception +// */ +// public static ResourceElementBean toResourceEBFromFolder(String workspaceFolderId, Workspace workspace) throws Exception{ +// +// ResourceElementBean rootElem = new ResourceElementBean(); +// String pathSeparator = "/"; +// +// //String pathSeparator = ws.getPathSeparator(); +// +// WorkspaceItem initialItem = workspace.getItem(workspaceFolderId); +// String fullPathBase = initialItem.getPath(); +// fullPathBase = fullPathBase.endsWith(pathSeparator) ? fullPathBase : fullPathBase + pathSeparator; +// rootElem.setFolder(initialItem.isFolder()); +// rootElem.setFullPath(initialItem.getPath().replace(fullPathBase, "")); +// rootElem.setName(initialItem.getName()); +// rootElem.setOriginalIdInWorkspace(initialItem.getId()); +// rootElem.setDescription(initialItem.getDescription()); +// extractEditableNameFromPath(rootElem, pathSeparator); +// +// // recursive visiting +//// if(initialItem.isFolder()) +//// visit(rootElem, initialItem, workspace, fullPathBase, pathSeparator); +// +// logger.debug("Tree that is going to be returned is " + rootElem); +// return rootElem; +// } - if(rootElem == null) - return; - - String elemName = rootElem.getName(); - String fullPath = rootElem.getFullPath(); - logger.info("Element original is " + rootElem); - - int lastIndex = rootElem.getFullPath().lastIndexOf(elemName); - fullPath = rootElem.getFullPath().substring(0, lastIndex); - fullPath = fullPath.replaceAll(pathSeparatorInWs, RESOURCES_NAME_SEPARATOR) + elemName; - rootElem.setEditableName(fullPath); - } +// /** +// * Recursive visit of a workspace item. +// * +// * @param parent the parent +// * @param initialItemWS the initial item WS +// * @param workspace the ws +// * @param fullPathBase the full path base +// * @param pathSeparator the path separator +// * @throws Exception the exception +// */ +// private static void visit(ResourceElementBean parent, WorkspaceItem initialItemWS, Workspace workspace, String fullPathBase, String pathSeparator) throws Exception { +// //List children = initialItemWS.getChildren(); +// +// List children = workspace.getChildren(initialItemWS.getId()); +// +// ArrayList childrenInTree = new ArrayList(children.size()); +// for (WorkspaceItem item : children) { +// // logger.debug("Path BEFORE REPLACE is " + item.getPath()); +// // logger.debug("Path AFTER REPLACE is " + item.getPath().replace(fullPathBase, "")); +// // logger.debug("Name is " + item.getName()); +// // logger.debug("id is " + item.getId()); +// ResourceElementBean elem = new ResourceElementBean(); +// elem.setFolder(item.isFolder()); +// elem.setOriginalIdInWorkspace(item.getId()); +// elem.setFullPath(item.getPath().replace(fullPathBase, "")); +// elem.setParent(parent); +// elem.setName(item.getName()); +// elem.setDescription(item.getDescription()); +// extractEditableNameFromPath(elem, pathSeparator); +// childrenInTree.add(elem); +// logger.trace("Elem is " + elem); +// if(item.isFolder()) +// visit(elem, item, workspace, fullPathBase, pathSeparator); +// } +// // add these list as child of the rootElem +// parent.setChildren(childrenInTree); +// } +// /** +// * Replaces the "/" char with a custom one and return an editable name for the user. +// * +// * @param rootElem the root elem +// * @param pathSeparatorInWs the path separator in ws +// */ +// public static void extractEditableNameFromPath(ResourceElementBean rootElem, String pathSeparatorInWs) { +// +// if(rootElem == null) +// return; +// +// String elemName = rootElem.getName(); +// String fullPath = rootElem.getFullPath(); +// logger.info("Element original is " + rootElem); +// +// int lastIndex = rootElem.getFullPath().lastIndexOf(elemName); +// fullPath = rootElem.getFullPath().substring(0, lastIndex); +// fullPath = fullPath.replaceAll(pathSeparatorInWs, RESOURCES_NAME_SEPARATOR) + elemName; +// rootElem.setEditableName(fullPath); +// logger.info("Editable name for resource name: "+rootElem.getName()+", is: " + rootElem.getEditableName()); +// } + + /** * Copy into the .catalogue area folder the checked resources. * There is no difference among a single-file-publish and a folder-publish. - * @param folderId - * @param userName - * @param bean - * @return + * + * @param bean the bean + * @param workspace the workspace + * @param username the username + * @return the list + * @throws Exception the exception */ - public static List copyResourcesToUserCatalogueArea(String folderOrFileId, String userName, DatasetBean bean) throws Exception{ - - logger.debug("Request to copy onto catalogue area...."); + public static List toResources(DatasetBean bean, Workspace workspace, String username) throws Exception{ + logger.debug("Called to Resources...: "); + List resources = new ArrayList(); - WorkspaceItem copiedFolder = null; - WorkspaceCatalogue userCatalogue = null; ResourceElementBean rootResource = bean.getResourceRoot(); - - // into the .catalogue area of the user's workspace - Workspace ws = HomeLibrary - .getHomeManagerFactory() - .getHomeManager() - .getHome() - .getWorkspace(); - - // Retrieve the catalogue of the user - userCatalogue = ws.getCatalogue(); - - // get workspace item (it could be a file or a folder) - WorkspaceItem originalItem = ws.getItem(folderOrFileId); - - // copy the folder in the catalogue if it is a folder, or create a new folder - long referenceTime = System.currentTimeMillis(); - if(originalItem.isFolder()){ - copiedFolder = userCatalogue.addWorkspaceItem(folderOrFileId, userCatalogue.getId()); // add to .catalogue root area - copiedFolder.setDescription(bean.getDescription()); - ((WorkspaceFolder)copiedFolder).rename(CatalogueUtilMethods.fromProductTitleToName(bean.getTitle()) + "_" + referenceTime); - } - else{ - copiedFolder = userCatalogue.createFolder(CatalogueUtilMethods.fromProductTitleToName(bean.getTitle()) + "_" + referenceTime, bean.getDescription()); + + if(rootResource==null) { + logger.info("No resource root, returning empty list of resources"); + return resources; } // retrieve the children - List resourcesToAdd = rootResource.getChildren(); + List resourcesToAdd = rootResource.getToPublish(); + + if(resourcesToAdd==null) { + logger.info("No resource to add, returning empty list of resources"); + return resources; + } // copy only the selected ones for(ResourceElementBean resource : resourcesToAdd){ @@ -250,35 +384,130 @@ public class WorkspaceUtils { logger.debug("Resource to add is " + resource); // ok it is a file, so copy it into the copiedFolder - WorkspaceItem copiedFile = userCatalogue.addWorkspaceItem(resource.getOriginalIdInWorkspace(), copiedFolder.getId()); + WorkspaceItem wsItem = workspace.getItem(resource.getOriginalIdInWorkspace()); + + String mimeType = null; + if(wsItem instanceof FileItem) { + mimeType = ((FileItem)wsItem).getMimeType(); + } - // name and description could have been edited - copiedFile.setDescription(resource.getDescription()); - - // check if it is an external url + // check if it is an URLFile String externalUrl = null; try{ - boolean isExternalUrl = ((FolderItem)copiedFile).getFolderItemType().equals(FolderItemType.EXTERNAL_URL); - externalUrl = isExternalUrl ? ((ExternalUrl)copiedFile).getUrl() : null; + if(wsItem instanceof URLFile) { + URLFile urlFile = (URLFile) wsItem; + externalUrl = urlFile.getValue()!=null?urlFile.getValue().toString():null; + } + }catch(Exception e){ logger.warn("Unable to check if it is an external url file ", e); } + + String resourceURL = externalUrl; + + //it is not a URLFile + if(resourceURL==null) { + //getting public link of file + URL publicLink = workspace.getPublicLinkForFile(resource.getOriginalIdInWorkspace()); + if(publicLink!=null) + resourceURL = publicLink.toString(); + } - resources.add(new ResourceBean( - externalUrl != null ? externalUrl : copiedFile.getPublicLink(true), + resources.add(new ResourceBean(resourceURL, resource.getEditableName(), - copiedFile.getDescription(), - copiedFile.getId(), - userName, + resource.getDescription(), + wsItem.getId(), + username, null, // dataset id, to be set - ((FolderItem)copiedFile).getMimeType())); - - // postpone rename operation - copiedFile.rename(resource.getEditableName()); + mimeType)); } } return resources; } + +// //MOVED TO GCAT +// /** +// * Copy into the .catalogue area folder the checked resources. +// * There is no difference among a single-file-publish and a folder-publish. +// * @param folderId +// * @param userName +// * @param bean +// * @return +// */ +// public static List copyResourcesToUserCatalogueArea(String folderOrFileId, String userName, DatasetBean bean) throws Exception{ +// +// logger.debug("Request to copy onto catalogue area...."); +// List resources = new ArrayList(); +// WorkspaceItem copiedFolder = null; +// WorkspaceCatalogue userCatalogue = null; +// ResourceElementBean rootResource = bean.getResourceRoot(); +// +// // into the .catalogue area of the user's workspace +// Workspace ws = HomeLibrary +// .getHomeManagerFactory() +// .getHomeManager() +// .getHome() +// .getWorkspace(); +// +// // Retrieve the catalogue of the user +// userCatalogue = ws.getCatalogue(); +// +// // get workspace item (it could be a file or a folder) +// WorkspaceItem originalItem = ws.getItem(folderOrFileId); +// +// // copy the folder in the catalogue if it is a folder, or create a new folder +// long referenceTime = System.currentTimeMillis(); +// if(originalItem.isFolder()){ +// copiedFolder = userCatalogue.addWorkspaceItem(folderOrFileId, userCatalogue.getId()); // add to .catalogue root area +// copiedFolder.setDescription(bean.getDescription()); +// ((WorkspaceFolder)copiedFolder).rename(CatalogueUtilMethods.fromProductTitleToName(bean.getTitle()) + "_" + referenceTime); +// } +// else{ +// copiedFolder = userCatalogue.createFolder(CatalogueUtilMethods.fromProductTitleToName(bean.getTitle()) + "_" + referenceTime, bean.getDescription()); +// } +// +// // retrieve the children +// List resourcesToAdd = rootResource.getChildren(); +// +// // copy only the selected ones +// for(ResourceElementBean resource : resourcesToAdd){ +// +// if (resource.isToBeAdded()) { +// +// logger.debug("Resource to add is " + resource); +// +// // ok it is a file, so copy it into the copiedFolder +// WorkspaceItem copiedFile = userCatalogue.addWorkspaceItem(resource.getOriginalIdInWorkspace(), copiedFolder.getId()); +// +// // name and description could have been edited +// copiedFile.setDescription(resource.getDescription()); +// +// // check if it is an external url +// String externalUrl = null; +// try{ +// boolean isExternalUrl = ((FolderItem)copiedFile).getFolderItemType().equals(FolderItemType.EXTERNAL_URL); +// externalUrl = isExternalUrl ? ((ExternalUrl)copiedFile).getUrl() : null; +// }catch(Exception e){ +// logger.warn("Unable to check if it is an external url file ", e); +// } +// +// resources.add(new ResourceBean( +// externalUrl != null ? externalUrl : copiedFile.getPublicLink(true), +// resource.getEditableName(), +// copiedFile.getDescription(), +// copiedFile.getId(), +// userName, +// null, // dataset id, to be set +// ((FolderItem)copiedFile).getMimeType())); +// +// // postpone rename operation +// copiedFile.rename(resource.getEditableName()); +// } +// +// } +// return resources; +// } + } \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/ResourceElementBean.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/ResourceElementBean.java index 064ff1d..6c2cb5a 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/ResourceElementBean.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/ResourceElementBean.java @@ -6,29 +6,64 @@ import java.util.List; import com.google.gwt.view.client.ProvidesKey; +// TODO: Auto-generated Javadoc /** * A resource element bean. Contains part of the logic used into the TwinColumn widget * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + * + * @author revisited by Francesco Mangiacrapa */ public class ResourceElementBean implements Comparable, Serializable{ + /** The Constant serialVersionUID. */ private static final long serialVersionUID = -1230871392599580669L; + + /** The name. */ private String name; + + /** The editable name. */ private String editableName; + + /** The to be added. */ private boolean toBeAdded; + + /** The is folder. */ private boolean isFolder; + + /** The full path. */ private String fullPath; + + /** The original id in workspace. */ private String originalIdInWorkspace; + + private String rootIdInWorkspace; + + /** The mime type. */ private String mimeType; + + /** The url. */ private String url; + + /** The description. */ private String description; + + /** The organization name dataset parent. */ private String organizationNameDatasetParent; // the organization name in which the parent dataset was created + + /** The parent. */ private ResourceElementBean parent; - private List children; + + /** The children size. */ + private Integer childrenSize; + +// /** The to publish. */ + private List toPublish; //Resources that must be published + /** The next id. */ // to generate the GWT identifiers private static int nextId = 0; + /** The identifier GWT. */ // identifier of this instance private int identifierGWT; @@ -43,8 +78,9 @@ public class ResourceElementBean implements Comparable, Ser }; /** - * Copy constructor - * @param another + * Copy constructor. + * + * @param another the another */ public ResourceElementBean(ResourceElementBean another) { this.name = another.name; @@ -59,7 +95,7 @@ public class ResourceElementBean implements Comparable, Ser } /** - * Default constructor + * Default constructor. */ public ResourceElementBean(){ super(); @@ -68,43 +104,47 @@ public class ResourceElementBean implements Comparable, Ser } /** - * @param identifier - * @param parentFolder - * @param name - * @param movedToRight - * @param isFolder + * Instantiates a new resource element bean. + * + * @param parent the parent + * @param name the name + * @param isFolder the is folder + * @param childrenSize the children size + * @param fullPath the full path */ public ResourceElementBean( ResourceElementBean parent, String name, boolean isFolder, - List children, + Integer childrenSize, String fullPath) { this.identifierGWT = nextId; nextId++; this.parent = parent; this.name = name; this.isFolder = isFolder; - this.children = children; + this.childrenSize = childrenSize; this.fullPath = fullPath; } /** - * @param name - * @param toBeAdded - * @param isFolder - * @param parent - * @param children - * @param fullPath - * @param originalIdInWorkspace - * @param mimeType - * @param url - * @param description - * @param organizationNameDatasetParent + * Instantiates a new resource element bean. + * + * @param name the name + * @param toBeAdded the to be added + * @param isFolder the is folder + * @param parent the parent + * @param childrenSize the children size + * @param fullPath the full path + * @param originalIdInWorkspace the original id in workspace + * @param mimeType the mime type + * @param url the url + * @param description the description + * @param organizationNameDatasetParent the organization name dataset parent */ public ResourceElementBean(String name, boolean toBeAdded, boolean isFolder, ResourceElementBean parent, - List children, String fullPath, + Integer childrenSize, String fullPath, String originalIdInWorkspace, String mimeType, String url, String description, String organizationNameDatasetParent) { super(); @@ -114,7 +154,7 @@ public class ResourceElementBean implements Comparable, Ser this.toBeAdded = toBeAdded; this.isFolder = isFolder; this.parent = parent; - this.children = children; + this.childrenSize = childrenSize; this.fullPath = fullPath; this.originalIdInWorkspace = originalIdInWorkspace; this.mimeType = mimeType; @@ -123,103 +163,247 @@ public class ResourceElementBean implements Comparable, Ser this.organizationNameDatasetParent = organizationNameDatasetParent; } + /** + * Gets the parent. + * + * @return the parent + */ public ResourceElementBean getParent() { return parent; } + /** + * Sets the parent. + * + * @param parent the new parent + */ public void setParent(ResourceElementBean parent) { this.parent = parent; } + /** + * Gets the name. + * + * @return the name + */ public String getName() { return name; } + /** + * Sets the name. + * + * @param name the new name + */ public void setName(String name) { this.name = name; } + /** + * Checks if is to be added. + * + * @return true, if is to be added + */ public boolean isToBeAdded() { return toBeAdded; } + /** + * Sets the to be added. + * + * @param toBeAdded the new to be added + */ public void setToBeAdded(boolean toBeAdded) { this.toBeAdded = toBeAdded; } + /** + * Gets the mime type. + * + * @return the mime type + */ public String getMimeType() { return mimeType; } + /** + * Sets the mime type. + * + * @param mimeType the new mime type + */ public void setMimeType(String mimeType) { this.mimeType = mimeType; } + /** + * Gets the url. + * + * @return the url + */ public String getUrl() { return url; } + /** + * Sets the url. + * + * @param url the new url + */ public void setUrl(String url) { this.url = url; } + /** + * Gets the description. + * + * @return the description + */ public String getDescription() { return description; } + /** + * Sets the description. + * + * @param description the new description + */ public void setDescription(String description) { this.description = description; } + /** + * Gets the organization name dataset parent. + * + * @return the organization name dataset parent + */ public String getOrganizationNameDatasetParent() { return organizationNameDatasetParent; } + /** + * Sets the organization name dataset parent. + * + * @param organizationNameDatasetParent the new organization name dataset parent + */ public void setOrganizationNameDatasetParent( String organizationNameDatasetParent) { this.organizationNameDatasetParent = organizationNameDatasetParent; } + /** + * Checks if is folder. + * + * @return true, if is folder + */ public boolean isFolder() { return isFolder; } + /** + * Sets the folder. + * + * @param isFolder the new folder + */ public void setFolder(boolean isFolder) { this.isFolder = isFolder; } - public List getChildren() { - return children; + /** + * Gets the children size. + * + * @return the children size + */ + public Integer getChildrenSize() { + return childrenSize; } - public void setChildren(List children) { - this.children = children; + /** + * Sets the children size. + * + * @param size the new children size + */ + public void setChildrenSize(Integer size) { + this.childrenSize = size; } + /** + * Gets the full path. + * + * @return the full path + */ public String getFullPath() { return fullPath; } + /** + * Sets the full path. + * + * @param fullPath the new full path + */ public void setFullPath(String fullPath) { this.fullPath = fullPath; } + /** + * Gets the original id in workspace. + * + * @return the original id in workspace + */ public String getOriginalIdInWorkspace() { return originalIdInWorkspace; } + /** + * Sets the original id in workspace. + * + * @param originalIdInWorkspace the new original id in workspace + */ public void setOriginalIdInWorkspace(String originalIdInWorkspace) { this.originalIdInWorkspace = originalIdInWorkspace; } + /** + * Gets the editable name. + * + * @return the editable name + */ public String getEditableName() { return editableName; } + /** + * Sets the editable name. + * + * @param newName the new editable name + */ public void setEditableName(String newName) { this.editableName = newName; } + + /** + * Gets the to publish. + * + * @return the to publish + */ + public List getToPublish() { + return toPublish; + } + /** + * Sets the to publish. + * + * @param toPublish the new to publish + */ + public void setToPublish(List toPublish) { + this.toPublish = toPublish; + } + + /** + * Equals. + * + * @param o the o + * @return true, if successful + */ @Override public boolean equals(Object o) { boolean toReturn = false; @@ -230,23 +414,62 @@ public class ResourceElementBean implements Comparable, Ser return toReturn; } + /** + * Compare to. + * + * @param o the o + * @return the int + */ @Override public int compareTo(ResourceElementBean o) { int toReturn = (o == null || o.fullPath == null) ? -1 : -o.fullPath.compareTo(fullPath); return toReturn; } + + + public String getRootIdInWorkspace() { + return rootIdInWorkspace; + } + + public void setRootIdInWorkspace(String rootIdInWorkspace) { + this.rootIdInWorkspace = rootIdInWorkspace; + } @Override public String toString() { - return "ResourceElementBean [identifierGWT=" + identifierGWT - + ", name=" + name + ", editableName=" + editableName - + ", toBeAdded=" + toBeAdded + ", isFolder=" + isFolder - + ", fullPath=" + fullPath + ", originalIdInWorkspace=" - + originalIdInWorkspace + ", mimeType=" + mimeType + ", url=" - + url + ", description=" + description - + ", organizationNameDatasetParent=" - + organizationNameDatasetParent + ", parent=" + parent - + ", children number=" + (children == null ? 0 : children.size()) + "]"; + StringBuilder builder = new StringBuilder(); + builder.append("ResourceElementBean [name="); + builder.append(name); + builder.append(", editableName="); + builder.append(editableName); + builder.append(", toBeAdded="); + builder.append(toBeAdded); + builder.append(", isFolder="); + builder.append(isFolder); + builder.append(", fullPath="); + builder.append(fullPath); + builder.append(", originalIdInWorkspace="); + builder.append(originalIdInWorkspace); + builder.append(", rootIdInWorkspace="); + builder.append(rootIdInWorkspace); + builder.append(", mimeType="); + builder.append(mimeType); + builder.append(", url="); + builder.append(url); + builder.append(", description="); + builder.append(description); + builder.append(", organizationNameDatasetParent="); + builder.append(organizationNameDatasetParent); + builder.append(", childrenSize="); + builder.append(childrenSize); + builder.append(", toPublish="); + builder.append(toPublish); + builder.append("]"); + return builder.toString(); } + + + + } 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 b2174ff..55363b4 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,13 +9,14 @@ - + - + + + org.gcube.portlets.widgets.ckandatapublisherwidget.server.CKANPublisherServicesImpl + + workspaceExplorer + org.gcube.portlets.widgets.wsexplorer.server.WorkspaceExplorerServiceImpl + + ckanpublisherservices /CKanMetadataPublisher/ckanservices + + workspaceExplorer + /CKanMetadataPublisher/WorkspaceExplorerService + + diff --git a/src/test/java/org/gcube/portlets/widgets/ckandatapublisherwidget/TestPublishingWidget.java b/src/test/java/org/gcube/portlets/widgets/ckandatapublisherwidget/TestPublishingWidget.java new file mode 100644 index 0000000..0e85a4e --- /dev/null +++ b/src/test/java/org/gcube/portlets/widgets/ckandatapublisherwidget/TestPublishingWidget.java @@ -0,0 +1,107 @@ +package org.gcube.portlets.widgets.ckandatapublisherwidget; + + +import java.util.Arrays; +import java.util.Calendar; + +import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.common.storagehubwrapper.server.StorageHubWrapper; +import org.gcube.datacatalogue.utillibrary.server.DataCatalogueFactory; +import org.gcube.portlets.widgets.ckandatapublisherwidget.server.utils.WorkspaceUtils; +import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.DatasetBean; +import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.OrganizationBean; +import org.junit.Test; +import org.slf4j.LoggerFactory; + + + +/** + * The Class TestDataCatalogueLib. + * + * @author Francesco Mangiacrapa at ISTI-CNR Pisa (Italy) + * Jun 1, 2020 + */ +public class TestPublishingWidget { + + private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(TestPublishingWidget.class); + + private String scope = "/gcube"; + //private String testUser = "costantino_perciante"; + private String testUser = "francesco.mangiacrapa"; + private String authorizationToken = ""; + + /** + * Before. + * + * @throws Exception the exception + */ + //@Before + public void before() throws Exception{ + } + + /** + * Factory test. + * + * @throws Exception the exception + */ + //@Test + public void factoryTest() throws Exception{ + + DataCatalogueFactory factory = DataCatalogueFactory.getFactory(); + + while(true){ + factory.getUtilsPerScope(scope); + Thread.sleep(60* 1000 * 3); + factory.getUtilsPerScope(scope); + break; + } + + for (int i = 0; i < 5; i++) { + Thread.sleep(1000); + factory.getUtilsPerScope(scope); + } + + } + + //@Test + public void getDatasetBeanTest() throws Exception{ + ScopeProvider.instance.set(scope); + String userName = testUser; + String token = authorizationToken; + + String folderId = "6399daa7-2173-4314-b4f7-2afa24eae8f8"; + DatasetBean bean; + try{ + bean = new DatasetBean(); + bean.setId(folderId); + bean.setDescription("This is a fantastic description"); + bean.setVersion(1); + String onlyAlphanumeric = "test-creation-blablabla".replaceAll("[^A-Za-z0-9]", ""); + bean.setTitle(onlyAlphanumeric + Calendar.getInstance().getTimeInMillis()); + bean.setAuthorName("Francesco"); + bean.setAuthorSurname("Mangiacrapa"); + bean.setAuthorEmail("francesco.mangiacrapa@isti.cnr.it"); + bean.setMaintainer("Francesco Mangiacrapa"); + bean.setMaintainerEmail("francesco.mangiacrapa@isti.cnr.it"); + + //UPDATED By Francesco + String vreName = scope.substring(scope.lastIndexOf("/")+1,scope.length()); + LOG.debug("In dev mode using the scope: "+scope+" and VRE name: "+vreName); + bean.setOrganizationList(Arrays.asList(new OrganizationBean(vreName, vreName.toLowerCase(), true))); + + bean.setOwnerIdentifier(userName); + + if(folderId != null && !folderId.isEmpty()){ + StorageHubWrapper storageHubWrapper = new StorageHubWrapper(scope, token, false, false, true); + WorkspaceUtils.toWorkspaceResource(folderId, userName, bean, storageHubWrapper.getWorkspace()); + } + }catch(Exception e){ + LOG.error("Error while building bean into dev mode", e); + throw new Exception("Error while retrieving basic information " + e.getMessage()); + } + + LOG.info("Got dataset: "+bean); + } + + +} diff --git a/src/test/resources/.gitignore b/src/test/resources/.gitignore new file mode 100644 index 0000000..abcb271 --- /dev/null +++ b/src/test/resources/.gitignore @@ -0,0 +1,3 @@ +/devsec.gcubekey +/gcube.gcubekey +/log4j.properties