in progess

This commit is contained in:
Francesco Mangiacrapa 2024-02-08 14:09:56 +01:00
parent bff3a41207
commit 87a4211301
8 changed files with 2743 additions and 111 deletions

View File

@ -13,91 +13,141 @@ import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
/**
* CKAN publisher services.
* @author Costantino Perciante at ISTI-CNR
* (costantino.perciante@isti.cnr.it)
*
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/
@RemoteServiceRelativePath("ckanservices")
public interface CKanPublisherService extends RemoteService {
/**
* Retrieve the list of licenses to show to the user.
*
* @return a LicenseBean on success, <b>null</b> on error.
*/
List<LicenseBean> getLicenses();
/**
* Retrieve the list of profiles for a given organization name .
*
* @param orgName the org name
* @return a List<MetaDataProfileBean> on success, <b>null</b> on error.
* @throws Exception the exception
*/
List<MetaDataProfileBean> getProfiles(String orgName) throws Exception;
/**
* Retrieve a partially filled bean given a folder id/file id and its owner.
*
* @param folderIdOrFileId the id of the folder of file to publish
* @return @return a DatasetMetadataBean on success, <b>null</b> on error.
* @throws Exception
* @throws Exception the exception
*/
DatasetBean getDatasetBean(String folderIdOrFileId) throws Exception;
/**
* Try to create such dataset starting from the information contained into the toCreate bean.
* @param toCreate
* Try to create such dataset starting from the information contained into the
* toCreate bean.
*
* @param toCreate the to create
* @return the sent bean filled with the needed information
* @throws Exception the exception
*/
DatasetBean createCKanDataset(DatasetBean toCreate) throws Exception;
/**
* Add this resource to the dataset whose id is datasetId
* @param resource
* @param datasetId
* Add this resource to the dataset whose id is datasetId.
*
* @param resource the resource
* @param datasetId the dataset id
* @return the resource element bean
* @throws Exception the exception
*/
ResourceElementBean addResourceToDataset(ResourceElementBean resource, String datasetId) throws Exception;
/**
* Delete this resource from the dataset with id datasetId
* @param resource
* @param datasetId
* Delete this resource from the dataset with id datasetId.
*
* @param resource the resource
* @return <b>true</b> on success, false otherwise
* @throws Exception
* @throws Exception the exception
*/
boolean deleteResourceFromDataset(ResourceElementBean resource) throws Exception;
/**
* Given the title the user wants to give to the new product to create, a check is performed
* to understand if a dataset with the proposed title (and so the id generated at server side) already exists
* @param title
* Given the title the user wants to give to the new product to create, a check
* is performed to understand if a dataset with the proposed title (and so the
* id generated at server side) already exists.
*
* @param title the title
* @param orgName the org name
* @return true if it exists, false otherwise
* @throws Exception
* @throws Exception the exception
*/
boolean datasetIdAlreadyExists(String title, String orgName) throws Exception;
/**
* Retrieve the list of groups the user can choose to associate this product with.
* @param orgName retrieve the groups in the context linked to this name. If null, returns
* the one in the current context.
* Retrieve the list of groups the user can choose to associate this product
* with.
*
* @param orgName retrieve the groups in the context linked to this name. If
* null, returns the one in the current context.
* @return a list of groups' beans
*/
List<OrganizationBean> getUserGroups(String orgName);
/**
* The method checks if the user is a publisher or he/she doesn't have the rights to publish
* The method checks if the user is a publisher or he/she doesn't have the
* rights to publish.
*
* @return true if he/she can publish, false otherwise
* @throws Exception
* @throws Exception the exception
*/
boolean isPublisherUser(boolean isWorkspaceRequest) throws Exception;
boolean isPublisherUser() throws Exception;
/**
* Get the list of vocabulary tags for this scope
* @param orgName
* @return
* @throws Exception
* Get the list of vocabulary tags for this scope.
*
* @param orgName the org name
* @return the tags for organization
* @throws Exception the exception
*/
List<String> getTagsForOrganization(String orgName) throws Exception;
/**
* Validate a geo json field
* @param json
* @return
* Validate a geo json field.
*
* @param json the json
* @return true, if is geo JSON valid
* @throws Exception the exception
*/
boolean isGeoJSONValid(String json) throws Exception;
/**
* Checks if is owner or admin user.
*
* @param datasetIdOrName the dataset id or name
* @return true, if is owner or admin user
* @throws Exception the exception
*/
boolean isPublisherOwnerOrAdminUser(String datasetIdOrName) throws Exception;
/**
* Gets the dataset bean for update.
*
* @param itemID the item ID
* @return the dataset bean for update
* @throws Exception the exception
*/
DatasetBean getDatasetBeanForUpdate(String itemID) throws Exception;
/**
* Gets the profile for update.
*
* @param orgName the org name
* @param datasetType the dataset type
* @param datasedIdOrName the datased id or name
* @return the profile for update
* @throws Exception the exception
*/
List<MetaDataProfileBean> getProfileForUpdate(String orgName, String datasetType, String datasedIdOrName) throws Exception;
}

View File

@ -12,97 +12,147 @@ import com.google.gwt.user.client.rpc.AsyncCallback;
/**
* CKAN publisher services RPC.
*
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/
public interface CKanPublisherServiceAsync {
/**
* Retrieve the list of licenses to show to the user.
*
* @param callback the callback
* @return a LicenseBean on success, <b>null</b> on error.
*/
void getLicenses(AsyncCallback<List<LicenseBean>> callback);
/**
* Retrieve a partially filled bean given a folder id/file id and its owner.
*
* @param folderIdOrFileId the id of the folder of file to publish
* @param callback the callback
* @return @return a DatasetMetadataBean on success, <b>null</b> on error.
*/
void getDatasetBean(String folderIdOrFileId,
AsyncCallback<DatasetBean> callback);
void getDatasetBean(String folderIdOrFileId, AsyncCallback<DatasetBean> callback);
/**
* Try to create such dataset starting from the information contained into the toCreate bean.
* @param toCreate
* Try to create such dataset starting from the information contained into the
* toCreate bean.
*
* @param toCreate the to create
* @param callback the callback
* @return the sent bean full filled with the needed information
*/
void createCKanDataset(DatasetBean toCreate,
AsyncCallback<DatasetBean> callback);
void createCKanDataset(DatasetBean toCreate, AsyncCallback<DatasetBean> callback);
/**
* Add this resource to the dataset whose id is datasetId
* @param resource
* @param datasetId
* @param callback
* Add this resource to the dataset whose id is datasetId.
*
* @param resource the resource
* @param datasetId the dataset id
* @param callback the callback
*/
void addResourceToDataset(ResourceElementBean resource, String datasetId,
AsyncCallback<ResourceElementBean> callback);
/**
* Delete this resource from the dataset with id datasetId
* @param resource
* Delete this resource from the dataset with id datasetId.
*
* @param resource the resource
* @param callback the callback
* @return <b>true</b> on success, false otherwise
*/
void deleteResourceFromDataset(ResourceElementBean resource, AsyncCallback<Boolean> callback);
/**
* Retrieve the list of profiles for a given organization name .
*
* @param orgName the org name
* @param callback the callback
* @return a List<MetaDataProfileBean> on success, <b>null</b> on error.
*/
void getProfiles(String orgName, AsyncCallback<List<MetaDataProfileBean>> callback);
/**
* Given the title the user wants to give to the new product to create, a check is performed
* to understand if a dataset with the proposed title (and so the id generated at server side) already exists
* @param title
* Given the title the user wants to give to the new product to create, a check
* is performed to understand if a dataset with the proposed title (and so the
* id generated at server side) already exists.
*
* @param title the title
* @param orgName the org name
* @param callback the callback
* @return true if it exists, false otherwise
*/
void datasetIdAlreadyExists(String title, String orgName, AsyncCallback<Boolean> callback);
// /**
// * Return a tree object representing the whole folder hierarchy
// * @param folderId
// * @return ResourceElementBean
// */
// void getTreeFolder(String folderId,
// AsyncCallback<ResourceElementBean> callback);
// /**
// * Return a tree object representing the whole folder hierarchy
// * @param folderId
// * @return ResourceElementBean
// */
// void getTreeFolder(String folderId,
// AsyncCallback<ResourceElementBean> callback);
/**
* Retrieve the list of groups the user can choose to associate this product with.
* @param orgName retrieve the groups in the context linked to this name. If null, returns
* the one in the current context.
* Retrieve the list of groups the user can choose to associate this product
* with.
*
* @param orgName retrieve the groups in the context linked to this name. If
* null, returns the one in the current context.
* @param callback the callback
* @return a list of groups' beans
*/
void getUserGroups(String orgName, AsyncCallback<List<OrganizationBean>> callback);
/**
* The method checks if the user is a publisher or he/she doesn't have the rights to publish
* @return true if he/she can publish, false otherwise
* Checks if is publisher user.
*
* @param callback the callback
*/
void isPublisherUser(boolean isWorkspaceRequest,
AsyncCallback<Boolean> callback);
void isPublisherUser(AsyncCallback<Boolean> callback);
/**
* Get the list of vocabulary tags for this scope
* @param orgName
* @return
* Get the list of vocabulary tags for this scope.
*
* @param orgName the org name
* @param callback the callback
* @return the tags for organization
*/
void getTagsForOrganization(String orgName,
AsyncCallback<List<String>> callback);
void getTagsForOrganization(String orgName, AsyncCallback<List<String>> callback);
/**
* Validate a geo json field
* @param json
* @return
* Validate a geo json field.
*
* @param json the json
* @param callback the callback
*/
void isGeoJSONValid(String json, AsyncCallback<Boolean> callback);
/**
* Checks if is owner or admin user.
*
* @param datasetIdOrName the dataset id or name
* @param callback the callback
* @return true, if is owner or admin user
*/
void isPublisherOwnerOrAdminUser(String datasetIdOrName, AsyncCallback<Boolean> callback);
/**
* Gets the dataset bean.
*
* @param itemID the item ID
* @return the dataset bean
* @throws Exception the exception
*/
void getDatasetBeanForUpdate(String itemID, AsyncCallback<DatasetBean> callback);
/**
* Gets the profile for update.
*
* @param orgName the org name
* @param datasetType the dataset type
* @param datasedIdOrName the datased id or name
* @param callaback the callaback
* @return the profile for update
*/
void getProfileForUpdate(String orgName, String datasetType, String datasedIdOrName, AsyncCallback<List<MetaDataProfileBean>> callaback);
}

View File

@ -402,7 +402,7 @@ public class CreateDatasetForm extends Composite {
// check if the user has publishing rights
setAlertBlock("Checking your permissions, please wait...", AlertType.INFO, true);
ckanServices.isPublisherUser(isWorkspaceRequest, new AsyncCallback<Boolean>() {
ckanServices.isPublisherUser(new AsyncCallback<Boolean>() {
@Override
public void onSuccess(Boolean result) {

View File

@ -0,0 +1,442 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:b="urn:import:com.github.gwtbootstrap.client.ui"
xmlns:m="urn:import:org.gcube.portlets.widgets.mpformbuilder.client.ui.tags">
<ui:style>
.form-main-style {
margin-left: 10px;
}
.fieldset-border-style {
border: 1px groove #444 !important;
box-shadow: 0px 0px 0px 0px #000 !important;
padding: 10px !important;
margin: 5px !important;
}
.legend-style {
width: auto !important;
padding: 10px !important;
margin-bottom: 0 !important;
border-bottom: 0 !important;
}
@external .form-horizontal .input-large;
.form-horizontal .input-large .input-prepend {
width: 95%;
}
.block-alert-style {
margin-top: 10px;
padding: 10px;
margin-bottom: 10px;
}
.tagsPanelStyle {
display: inline-block;
}
.selected-profile {
font-weight: bold;
}
.label-go-to-product {
display: inline-block;
vertical-align: middle;
font-weight: bold;
}
.the-margin-gotoitem {
margin-left: 5px;
margin-top: 10px;
margin-bottom: 10px;
}
</ui:style>
<g:HTMLPanel ui:field="createDatasetMainPanel">
<g:HTMLPanel ui:field="wizardCreatorPanel"></g:HTMLPanel>
<b:Form type="HORIZONTAL" styleName="{style.form-main-style}"
ui:field="formFirstStep" visible="true">
<b:Fieldset styleName="{style.fieldset-border-style}">
<b:Legend styleName="{style.legend-style}">
Insert Item Information
<small>
<span style="color:red;">*</span>
is required
</small>
</b:Legend>
<!-- Alert blocks for info/errors -->
<b:AlertBlock type="INFO" close="false"
animation="true" visible="false" ui:field="infoBlock"
styleName="{style.block-alert-style}"></b:AlertBlock>
<b:ControlGroup ui:field="productTitleGroup">
<b:ControlLabel for="title" title="Item title">
<font color="red">*</font>
Title :
</b:ControlLabel>
<b:Controls>
<b:TextBox alternateSize="LARGE"
placeholder="Item title" width="90%" b:id="title"
title="Item title" ui:field="titleTextBox" />
<span style="float:right; width:5%; color: #aaaaaa;">
<b:Popover ui:field="popoverTitle" html="true"
animation="true" placement="LEFT">
<g:FocusPanel ui:field="focusPanelTitle">
<b:Icon type="INFO_SIGN" size="TWO_TIMES"
ui:field="infoIconTitle" />
</g:FocusPanel>
</b:Popover>
</span>
</b:Controls>
</b:ControlGroup>
<b:ControlGroup>
<b:ControlLabel for="description"
title="Item description">
Description:
</b:ControlLabel>
<b:Controls>
<b:TextArea
placeholder="eg. Some useful notes about the item" width="90%"
alternateSize="LARGE" b:id="description" title="Item description"
ui:field="descriptionTextarea"></b:TextArea>
<span style="float:right; width:5%; color: #aaaaaa;">
<b:Popover ui:field="popoverDescription" html="true"
animation="true" placement="LEFT">
<g:FocusPanel ui:field="focusPanelDescription">
<b:Icon type="INFO_SIGN" size="TWO_TIMES"
ui:field="infoIconDescription" />
</g:FocusPanel>
</b:Popover>
</span>
</b:Controls>
</b:ControlGroup>
<!-- TAGS Panel -->
<m:TagsPanel ui:field="tagsPanel"></m:TagsPanel>
<b:ControlGroup>
<b:ControlLabel for="licenses" title="License">License:</b:ControlLabel>
<b:Controls>
<b:ListBox b:id="licenses" title="Item license"
width="91%" ui:field="licenseListbox">
</b:ListBox>
<span style="float:right; width:5%; color: #aaaaaa;">
<b:Popover ui:field="popoverLicenses" html="true"
animation="true" placement="LEFT">
<g:FocusPanel ui:field="focusPanelLicenses">
<b:Icon type="INFO_SIGN" size="TWO_TIMES"
ui:field="infoIconLicenses" />
</g:FocusPanel>
</b:Popover>
</span>
</b:Controls>
</b:ControlGroup>
<b:ControlGroup>
<b:ControlLabel for="licenseUrl"
title="Selected License'url">Selected
License Url:</b:ControlLabel>
<b:Controls>
<b:Paragraph ui:field="unavailableUrl" visible="true">
<b>Unavailable</b>
</b:Paragraph>
<g:Anchor ui:field="licenseUrlAnchor" target="_blank"
visible="false"></g:Anchor>
</b:Controls>
</b:ControlGroup>
<b:ControlGroup>
<b:ControlLabel for="visibility"
title="Visibility of the item">Visibility:</b:ControlLabel>
<b:Controls>
<b:ListBox b:id="visibility" title="Item visibility"
width="91%" ui:field="visibilityListbox">
<g:item title="restricted">Restricted</g:item>
<g:item enabled="true" title="public">Public</g:item>
</b:ListBox>
<span style="float:right; width:5%; color: #aaaaaa;">
<b:Popover ui:field="popoverVisibility" html="true"
animation="true" placement="LEFT">
<g:FocusPanel ui:field="focusPanelVisibility">
<b:Icon type="INFO_SIGN" size="TWO_TIMES"
ui:field="infoIconVisibility" />
</g:FocusPanel>
</b:Popover>
</span>
</b:Controls>
</b:ControlGroup>
<b:ControlGroup ui:field="organizationsGroup">
<b:ControlLabel for="organization"
title="Select the organizations in which you want
to publish the item">Publish in:</b:ControlLabel>
<b:Controls>
<b:ListBox b:id="organization" alternateSize="LARGE"
width="91%" title="Publish in this organization"
ui:field="organizationsListbox">
</b:ListBox>
</b:Controls>
</b:ControlGroup>
<b:ControlGroup ui:field="versionControlGroup">
<b:ControlLabel for="version"
title="Item version expressed as positive integer number">
Version:
</b:ControlLabel>
<b:Controls>
<b:TextBox alternateSize="LARGE" placeholder="1.0"
b:id="version" width="90%" title="Item version"
ui:field="versionTextbox" />
</b:Controls>
</b:ControlGroup>
<b:ControlGroup>
<b:ControlLabel for="author" title="Item author">
<font color="red">*</font>
Author:
</b:ControlLabel>
<b:Controls>
<b:TextBox alternateSize="LARGE" width="90%"
placeholder="Joe Bloggs" enabled="false" b:id="author"
title="Item author" ui:field="authorTextbox" />
<span style="float:right; width:5%; color: #aaaaaa;">
<b:Popover ui:field="popoverAuthor" html="true"
animation="true" placement="LEFT">
<g:FocusPanel ui:field="focusPanelAuthor">
<b:Icon type="INFO_SIGN" size="TWO_TIMES"
ui:field="infoIconAuthor" />
</g:FocusPanel>
</b:Popover>
</span>
</b:Controls>
</b:ControlGroup>
<b:ControlGroup ui:field="authorEmailControlGroup">
<b:ControlLabel for="email"
title="Item author's email">
<font color="red">*</font>
Author Email:
</b:ControlLabel>
<b:Controls>
<b:TextBox alternateSize="LARGE" width="90%"
placeholder="joe.bloggs@example.com" enabled="false" b:id="email"
title="Item author" ui:field="authorEmailTextbox" />
<span style="float:right; width:5%; color: #aaaaaa;">
<b:Popover ui:field="popoverAuthorEmail" html="true"
animation="true" placement="LEFT">
<g:FocusPanel ui:field="focusPanelAuthorEmail">
<b:Icon type="INFO_SIGN" size="TWO_TIMES"
ui:field="infoIconAuthorEmail" />
</g:FocusPanel>
</b:Popover>
</span>
</b:Controls>
</b:ControlGroup>
<b:ControlGroup>
<b:ControlLabel for="maintainer"
title="Item maintainer">
Maintainer:
</b:ControlLabel>
<b:Controls>
<b:TextBox alternateSize="LARGE"
placeholder="Joe Bloggs" width="90%" b:id="maintainer"
title="Item maintainer" ui:field="maintainerTextbox" />
<span style="float:right; width:5%; color: #aaaaaa;">
<b:Popover ui:field="popoverMaintainer" html="true"
animation="true" placement="LEFT">
<g:FocusPanel ui:field="focusPanelMaintainer">
<b:Icon type="INFO_SIGN" size="TWO_TIMES"
ui:field="infoIconMaintainer" />
</g:FocusPanel>
</b:Popover>
</span>
</b:Controls>
</b:ControlGroup>
<b:ControlGroup ui:field="maintainerControlGroup">
<b:ControlLabel for="emailMaintaner"
title="Item author's email">
Maintainer Email:
</b:ControlLabel>
<b:Controls>
<b:TextBox alternateSize="LARGE"
placeholder="maintainer@example.com" width="90%"
b:id="emailMaintaner" title="Item author"
ui:field="maintainerEmailTextbox" />
<span style="float:right; width:5%; color: #aaaaaa;">
<b:Popover ui:field="popoverMaintainerEmail"
html="true" animation="true" placement="LEFT">
<g:FocusPanel ui:field="focusPanelMaintainerEmail">
<b:Icon type="INFO_SIGN" size="TWO_TIMES"
ui:field="infoIconMaintainerEmail" />
</g:FocusPanel>
</b:Popover>
</span>
</b:Controls>
</b:ControlGroup>
<b:ControlGroup ui:field="metadataTypesControlGroup">
<b:ControlLabel for="metadataTypes"
title="Item profile types">Types:</b:ControlLabel>
<b:Controls>
<b:ListBox b:id="metadataTypes" alternateSize="LARGE"
width="91%" title="The item type to be used"
ui:field="metadataTypeListbox">
<g:item enabled="true" title="None">none</g:item>
</b:ListBox>
<span style="float:right; width:5%; color: #aaaaaa;">
<b:Popover ui:field="popoverTypes" html="true"
animation="true" placement="LEFT">
<g:FocusPanel ui:field="focusPanelTypes">
<b:Icon type="INFO_SIGN" size="TWO_TIMES"
ui:field="infoIconTypes" />
</g:FocusPanel>
</b:Popover>
</span>
</b:Controls>
</b:ControlGroup>
<b:ControlGroup ui:field="groupsControlGroup"
visible="false">
<b:ControlLabel for="groups"
title="The groups for this item">Item Groups:</b:ControlLabel>
<b:Controls>
<b:ListBox b:id="groups" alternateSize="LARGE"
width="91%" multipleSelect="true"
title="The groups for this item (Hold CTRL or Command button for multiple selection)"
ui:field="groupsListbox">
</b:ListBox>
<span style="float:right; width:5%; color: #aaaaaa;">
<b:Popover ui:field="popoverGroups" html="true"
animation="true" placement="LEFT">
<g:FocusPanel ui:field="focusPanelGroups">
<b:Icon type="INFO_SIGN" size="TWO_TIMES"
ui:field="infoIconGroups" />
</g:FocusPanel>
</b:Popover>
</span>
</b:Controls>
</b:ControlGroup>
<!-- Alert block on continue -->
<b:AlertBlock animation="true" visible="false"
ui:field="alertNoResources"
text="Please note that the item you are going to publish will not have resources.">
</b:AlertBlock>
<!-- Alert block on continue -->
<b:AlertBlock type="INFO" close="false"
animation="true" visible="false" ui:field="onContinueAlertBlock">
</b:AlertBlock>
<b:Button title="Continue" ui:field="continueButton"
type="PRIMARY" block="true">Continue</b:Button>
<b:Button title="Reset" ui:field="resetButton" block="true">Reset</b:Button>
</b:Fieldset>
</b:Form>
<b:Form type="HORIZONTAL" styleName="{style.form-main-style}"
ui:field="formSecondStep" visible="false">
<b:Fieldset styleName="{style.fieldset-border-style}">
<b:Legend styleName="{style.legend-style}">
Select Item Resources
</b:Legend>
<b:ControlGroup>
<span style="float:right; width:5%; color: #aaaaaa;">
<b:Popover ui:field="popoverResources" html="true"
animation="true" placement="LEFT">
<g:FocusPanel ui:field="focusPanelResources">
<b:Icon type="INFO_SIGN" size="TWO_TIMES"
ui:field="infoIconResources" />
</g:FocusPanel>
</b:Popover>
</span>
<g:SimplePanel ui:field="workspaceResourcesContainer"
width="95%" visible="true"></g:SimplePanel>
</b:ControlGroup>
<b:Button title="Continue" ui:field="continueThirdStep"
type="PRIMARY" block="true">Continue</b:Button>
<b:Button title="Go Back" ui:field="goBackButtonFirstStep"
block="true">Go
Back</b:Button>
</b:Fieldset>
</b:Form>
<b:Form type="HORIZONTAL" styleName="{style.form-main-style}"
ui:field="formThirdStep" visible="false">
<b:Fieldset styleName="{style.fieldset-border-style}">
<b:Legend styleName="{style.legend-style}">
Insert Item Profile Information
<small>
<span style="color:red;">*</span>
is required
</small>
</b:Legend>
<b:Paragraph ui:field="selectedProfile"
styleName="{style.selected-profile}"></b:Paragraph>
<!-- Here will be placed the metadata fields formats -->
<g:VerticalPanel ui:field="metadataFieldsPanel"
visible="false" width="100%"></g:VerticalPanel>
<!-- Custom fields can be dinamically added -->
<b:ControlGroup ui:field="customFields">
<b:ControlLabel>Custom Field(s):</b:ControlLabel>
</b:ControlGroup>
<b:ControlGroup>
<b:Controls>
<span style="float:right; width:5%; color: #aaaaaa;">
<b:Popover ui:field="popoverCustomFields" html="true"
animation="true" placement="LEFT">
<g:FocusPanel ui:field="focusPanelCustomFields">
<b:Icon type="INFO_SIGN" size="TWO_TIMES"
ui:field="infoIconCustomFields" />
</g:FocusPanel>
</b:Popover>
</span>
<b:Button icon="PLUS_SIGN" title="Add Custom Field"
ui:field="addCustomFieldButton"></b:Button>
</b:Controls>
</b:ControlGroup>
<!-- Alert block on create -->
<b:AlertBlock type="INFO" close="false"
animation="true" visible="false" ui:field="onCreateAlertBlock"
styleName="{style.block-alert-style}">
</b:AlertBlock>
<g:HorizontalPanel
ui:field="goToDatasetButtonPanel" visible="false">
<g:Label>Go to the Item</g:Label>
<b:Button title="Go to the Item"
ui:field="goToDatasetButton" type="LINK" visible="false"
styleName="{style.the-margin-gotoitem}"></b:Button>
</g:HorizontalPanel>
<b:Button title="Add resources to the just created item"
block="true" type="PRIMARY" visible="false"
ui:field="addResourcesButton">Add Resources</b:Button>
<b:Button title="Create Item" ui:field="createButton"
type="PRIMARY" block="true">Create</b:Button>
<b:Button title="Go Back" ui:field="goBackButtonSecondStep"
block="true">Go
Back</b:Button>
</b:Fieldset>
</b:Form>
</g:HTMLPanel>
</ui:UiBinder>

View File

@ -10,6 +10,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import javax.servlet.http.HttpSession;
@ -22,8 +23,12 @@ 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.CkanDataset;
import org.gcube.datacatalogue.utillibrary.shared.jackan.model.CkanGroup;
import org.gcube.datacatalogue.utillibrary.shared.jackan.model.CkanLicense;
import org.gcube.datacatalogue.utillibrary.shared.jackan.model.CkanOrganization;
import org.gcube.datacatalogue.utillibrary.shared.jackan.model.CkanResource;
import org.gcube.datacatalogue.utillibrary.shared.jackan.model.CkanTag;
import org.gcube.portlets.widgets.ckandatapublisherwidget.client.CKanPublisherService;
import org.gcube.portlets.widgets.ckandatapublisherwidget.server.utils.CatalogueRoleManager;
import org.gcube.portlets.widgets.ckandatapublisherwidget.server.utils.DiscoverTagsList;
@ -35,6 +40,7 @@ import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.OrganizationBea
import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.ResourceElementBean;
import org.gcube.portlets.widgets.mpformbuilder.shared.license.LicenseBean;
import org.gcube.portlets.widgets.mpformbuilder.shared.metadata.MetaDataProfileBean;
import org.gcube.portlets.widgets.mpformbuilder.shared.metadata.MetadataFieldWrapper;
import org.gcube.vomanagement.usermanagement.GroupManager;
import org.gcube.vomanagement.usermanagement.UserManager;
import org.gcube.vomanagement.usermanagement.exception.GroupRetrievalFault;
@ -241,7 +247,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C
DatasetBean bean = null;
String userName = GenericUtils.getCurrentUser(getThreadLocalRequest()).getUsername();
logger.info("DatasetBean request for " + folderId + " and " + userName);
logger.info("DatasetBean request for folderId " + folderId + " and " + userName);
if (isWithinPortal()) {
try {
@ -320,6 +326,133 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C
return bean;
}
/**
* Gets the dataset bean for update.
*
* @param datasetIdOrName the dataset id or name
* @return the dataset bean for update
* @throws Exception the exception
*/
@Override
public DatasetBean getDatasetBeanForUpdate(String datasetIdOrName) throws Exception {
DatasetBean bean = null;
String userName = GenericUtils.getCurrentUser(getThreadLocalRequest()).getUsername();
logger.info("DatasetBeanForUpdate request for " + datasetIdOrName + " and " + userName);
String scopePerCurrentUrl = GenericUtils.getScopeFromClientUrl(getThreadLocalRequest());
DataCatalogue utils = getCatalogue(scopePerCurrentUrl);
CkanDataset dataset = utils.getDataset(datasetIdOrName, userName);
if (dataset == null) {
// the user cannot read the item, so he/she is not the owner nor the admin
throw new Exception("Dataset with id " + datasetIdOrName + " not found for user " + userName);
}
logger.debug("Building bean");
bean = new DatasetBean();
bean.setId(datasetIdOrName);
bean.setTitle(dataset.getTitle());
bean.setDescription(dataset.getNotes());
bean.setLicense(dataset.getLicenseTitle());
bean.setVisibile(dataset.isPriv());
long version = 1;
try {
version = Long.parseLong(dataset.getVersion());
} catch (Exception e) {
// TODO: handle exception
}
bean.setVersion(version);
bean.setOwnerIdentifier(dataset.getCreatorUserId());
bean.setAuthorFullName(dataset.getAuthor());
bean.setAuthorEmail(dataset.getAuthorEmail());
bean.setMaintainer(dataset.getMaintainer());
bean.setMaintainerEmail(dataset.getMaintainerEmail());
CkanOrganization ckanOrganization = dataset.getOrganization();
// UPDATED By Francesco
// String vreName = scope.substring(scope.lastIndexOf("/") + 1, scope.length());
// logger.debug("In dev mode using the scope: " + scope + " and VRE name: " + vreName);
bean.setOrganizationList(
Arrays.asList(new OrganizationBean(ckanOrganization.getTitle(), ckanOrganization.getName(), true)));
List<CkanTag> listDatasetTags = dataset.getTags();
if(logger.isDebugEnabled()) {
logger.debug("List tags from CKAN are: ");
for (CkanTag ckanTag : listDatasetTags) {
logger.debug("ckanTag: "+ckanTag.getDisplayName());
logger.debug("ckanTag: "+ckanTag.getName());
}
}
// selected tags into Dataset
if (listDatasetTags != null) {
List<String> listTags = dataset.getTags().stream().map(t -> t.getName()).collect(Collectors.toList());
logger.info("setTags: {}",listTags);
bean.setTags(listTags);
}
// Vocabulary Tags from Generi Resources
bean.setTagsVocabulary(discoverTagsVocabulary(scopePerCurrentUrl));
// By default setting the root folder ID for updating the Resources on the
// client-side
// TODO LOAD THE WORKSPACE ROOT
/*
* Workspace workspace = getWorkspaceFromStorageHub();
* WorkspaceUtils.toWorkspaceResource(workspace.getRoot().getId(), userName,
* bean, workspace);
*/
// Settings the CKAN resources
List<CkanResource> resources = dataset.getResources();
if (resources != null) {
List<ResourceElementBean> list = new ArrayList<ResourceElementBean>(resources.size());
for (CkanResource ckanResource : resources) {
ResourceElementBean reb = toResourceBean(ckanResource);
list.add(reb);
}
bean.setResources(list);
}
// Settings the dataset type
Map<String, String> extras = dataset.getExtrasAsHashMap();
if (extras != null) {
String theDatasetType = extras.get(SYS_TYPE);
bean.setChosenType(theDatasetType);
}
logger.debug("Returning bean " + bean);
logger.info("Returning the bean for dataset title {} and type {}" + bean.getTitle(), bean.getChosenType());
return bean;
}
/**
* To resource bean.
*
* @param ckanResource the ckan resource
*/
public ResourceElementBean toResourceBean(CkanResource ckanResource) {
ResourceElementBean reb = new ResourceElementBean();
reb.setName(ckanResource.getName());
reb.setDescription(ckanResource.getDescription());
reb.setEditableName(ckanResource.getName());
reb.setUrl(ckanResource.getUrl());
reb.setMimeType(ckanResource.getMimetype());
return reb;
}
/**
* Discover from the IS the vocabulary of tags for this scope, if present.
*
@ -548,6 +681,72 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C
return toReturn;
}
/**
* Gets the profile for update.
*
* @param orgName the org name
* @param datasetType the dataset type
* @param datasedIdOrName the datased id or name
* @return the profile for update
* @throws Exception the exception
*/
@Override
public List<MetaDataProfileBean> getProfileForUpdate(String orgName, String datasetType, String datasedIdOrName)
throws Exception {
logger.info("Called getProfileForUpdate for orgName {} and dataset type {} ", orgName, datasetType);
logger.debug("Requested profiles for products into orgName " + orgName);
List<MetaDataProfileBean> toRead = new ArrayList<MetaDataProfileBean>();
List<MetaDataProfileBean> toReturn = new ArrayList<MetaDataProfileBean>();
try {
String evaluatedScope = getScopeFromOrgName(orgName);
logger.debug("Evaluated scope is " + evaluatedScope);
toRead = MetadataDiscovery.getMetadataProfilesList(evaluatedScope, getThreadLocalRequest());
for (MetaDataProfileBean metaDataProfileBean : toRead) {
logger.debug("Comparing profile {} with datasetType {}", metaDataProfileBean.getType(), datasetType);
if (metaDataProfileBean.getType().compareTo(datasetType) == 0) {
logger.info("Profile found {}", metaDataProfileBean.getType());
toReturn.add(metaDataProfileBean);
}
}
} catch (Exception e) {
logger.error("Failed to retrieve profiles for scope coming from organization name " + orgName, e);
throw e;
}
HttpSession httpSession = this.getThreadLocalRequest().getSession();
// retrieve scope per current portlet url
String scopePerCurrentUrl = GenericUtils.getScopeFromClientUrl(getThreadLocalRequest());
String username = GenericUtils.getCurrentUser(getThreadLocalRequest()).getUsername();
DataCatalogue utils = getCatalogue(scopePerCurrentUrl);
CkanDataset dataset = utils.getDataset(datasedIdOrName, username);
if (toReturn.isEmpty())
throw new Exception("No Profile found for dataset type: " + datasetType);
// Settings current values in the profile found
MetaDataProfileBean profileBean = toReturn.get(0);
logger.trace("The profile is {}", profileBean);
Map<String, String> extras = dataset.getExtrasAsHashMap();
logger.trace("Current extras are {}", extras);
for (MetadataFieldWrapper metadataFieldWrapper : profileBean.getMetadataFields()) {
String fieldName = metadataFieldWrapper.getFieldName();
logger.trace("Searching field name {} in the profile", fieldName);
String currValueOfExtraField = extras.get(metadataFieldWrapper.getFieldName());
logger.trace("Current value found is {} for field name {}", currValueOfExtraField, fieldName);
metadataFieldWrapper.setCurrentValues(currValueOfExtraField);
}
if (logger.isDebugEnabled()) {
logger.debug("Returning filled profile {}", profileBean.getType());
logger.debug("with MetadataFields {}", profileBean.getMetadataFields());
}
logger.info("returing the filled profile {}", profileBean.getType());
return Arrays.asList(profileBean);
}
/**
* Dataset id already exists.
*
@ -575,7 +774,10 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C
/**
* The method tries to retrieve the scope related to the organization using the
* map first, if no match is found, it retrieves such information by using
* liferay
* liferay.
*
* @param orgName the org name
* @return the scope from org name
*/
private String getScopeFromOrgName(String orgName) {
@ -679,12 +881,11 @@ 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 {
public boolean isPublisherUser() throws Exception {
String username = GenericUtils.getCurrentUser(getThreadLocalRequest()).getUsername();
logger.info("Checking if the user " + username + " can publish or not on the catalogue");
@ -759,6 +960,60 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C
}
}
/**
* Checks if is publisher owner or admin user.
*
* @param datasetIdOrName the dataset id or name
* @return true, if is publisher owner or admin user
* @throws Exception the exception
*/
@Override
public boolean isPublisherOwnerOrAdminUser(String datasetIdOrName) throws Exception {
String username = GenericUtils.getCurrentUser(getThreadLocalRequest()).getUsername();
logger.info("Checking if the user " + username + " can publish or not on the catalogue");
boolean isPublisher = isPublisherUser();
if (isPublisher) {
RolesCkanGroupOrOrg role = null;
String scopePerCurrentUrl = GenericUtils.getScopeFromClientUrl(getThreadLocalRequest());
if (!isWithinPortal()) {
role = RolesCkanGroupOrOrg.EDITOR;
logger.warn("OUT FROM PORTAL SETTING HARD-CODED ROLE " + role);
} else {
String keyPerScopeRole = CatalogueUtilMethods
.concatenateSessionKeyScope(SessionCatalogueAttributes.CKAN_HIGHEST_ROLE, scopePerCurrentUrl);
HttpSession httpSession = this.getThreadLocalRequest().getSession();
role = (RolesCkanGroupOrOrg) httpSession.getAttribute(keyPerScopeRole);
}
// if the user is an EDITOT he/she must be also the owner of the dataset
if (role.equals(RolesCkanGroupOrOrg.EDITOR)) {
logger.info("The user {} is an {}", username, RolesCkanGroupOrOrg.EDITOR);
String loggedUserEmail = GenericUtils.getCurrentUser(getThreadLocalRequest()).getEmail();
logger.debug("Logged user email: {} ", loggedUserEmail);
DataCatalogue utils = getCatalogue(scopePerCurrentUrl);
CkanDataset dataset = utils.getDataset(datasetIdOrName, username);
String datasetOwnerEmail = dataset.getAuthorEmail();
logger.debug("Dataset Owner email: {} ", datasetOwnerEmail);
if (loggedUserEmail != null && datasetOwnerEmail != null
&& datasetOwnerEmail.compareTo(loggedUserEmail) == 0) {
logger.info("The user {} is owner of the dataset id {}, returning isOwnerOrAdminUser true ",
username, dataset.getId());
return true;
}
} else if (role.equals(RolesCkanGroupOrOrg.ADMIN)) {
logger.info("The user {} is an {}", username, RolesCkanGroupOrOrg.ADMIN);
return true;
}
}
logger.info("The user {} does not have the rights to update the dataset with id {}", username, datasetIdOrName);
return false;
}
/**
* Checks if is geo JSON valid.
*

View File

@ -9,7 +9,9 @@ import org.gcube.portlets.widgets.mpformbuilder.shared.metadata.MetaDataProfileB
import com.google.gwt.user.client.rpc.IsSerializable;
/**
* This bean will contain during ckan metadata creation information related to the future build.
* This bean will contain during ckan metadata creation information related to
* the future build.
*
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/
@SuppressWarnings("serial")
@ -31,20 +33,25 @@ public class DatasetBean implements Serializable, IsSerializable {
private String selectedOrganization;
private long version; // version 1, 2 ...
private boolean visible; // Private (false) or Public(true)
private List<OrganizationBean> organizationList; // list of organization in which the user is present and could create the dataset
private ResourceElementBean resourceRoot; // in case of workspace, this is the directory root or the single file information
private List<OrganizationBean> organizationList; // list of organization in which the user is present and could
// create the dataset
private ResourceElementBean resourceRoot; // in case of workspace, this is the directory root or the single file
// information
private List<MetaDataProfileBean> metadataList;
private List<String> tags; // on retrieve, they are the keys of the product
private List<String> tagsVocabulary; // when available
private Map<String, List<String>> customFields;
private List<OrganizationBean> groups;
private List<OrganizationBean> groupsForceCreation;
private List<ResourceElementBean> resources;
public DatasetBean(){
public DatasetBean() {
super();
}
/** Create a metadata bean object.
/**
* Create a metadata bean object.
*
* @param id
* @param title
* @param description
@ -65,13 +72,10 @@ public class DatasetBean implements Serializable, IsSerializable {
* @param addResources
* @param metadataList
*/
public DatasetBean(String id, String title, String description,
Map<String, List<String>> customFields, List<String> tags,
String license, boolean visible, String source, long version,
String authorName, String authorSurname, String authorEmail, String maintainer,
String maintainerEmail, String ownerIdentifier,
List<OrganizationBean> organizationList, String selectedOrganization,
ResourceElementBean resourceRoot,
public DatasetBean(String id, String title, String description, Map<String, List<String>> customFields,
List<String> tags, String license, boolean visible, String source, long version, String authorName,
String authorSurname, String authorEmail, String maintainer, String maintainerEmail, String ownerIdentifier,
List<OrganizationBean> organizationList, String selectedOrganization, ResourceElementBean resourceRoot,
List<MetaDataProfileBean> metadataList, List<OrganizationBean> groups, List<String> tagsVocabulary) {
super();
this.id = id;
@ -289,6 +293,14 @@ public class DatasetBean implements Serializable, IsSerializable {
this.groupsForceCreation = groupsForceCreation;
}
public void setResources(List<ResourceElementBean> resources) {
this.resources = resources;
}
public List<ResourceElementBean> getCkanResources() {
return resources;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();

View File

@ -1,31 +1,31 @@
package org.gcube.portlets.widgets.ckandatapublisherwidget;
import java.util.Arrays;
import java.util.Calendar;
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.common.storagehubwrapper.server.StorageHubWrapper;
import org.gcube.datacatalogue.utillibrary.server.DataCatalogueFactory;
import org.gcube.datacatalogue.utillibrary.server.DataCatalogueImpl;
import org.gcube.datacatalogue.utillibrary.shared.jackan.model.CkanDataset;
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
* @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 = "costantino_perciante";
private String testUser = "francesco.mangiacrapa";
private String authorizationToken = "";
@ -34,23 +34,50 @@ public class TestPublishingWidget {
*
* @throws Exception the exception
*/
//@Before
public void before() throws Exception{
// @Before
public void before() throws Exception {
}
@Test
public void getDataset() {
try {
scope = "/d4science.research-infrastructures.eu/D4OS/Blue-Cloud2026Project";
authorizationToken = "8c3ce374-5482-422d-9542-97b1b9360747-843339462"; //Blue-Cloud2026Project
ScopeProvider.instance.set(scope);
SecurityTokenProvider.instance.set(authorizationToken);
String datasetId = "blue-cloud_2026_-_a_federated_european_fair_and_open_research_ecosystem_for_oceans_seas_coastal_and";
DataCatalogueFactory factory = DataCatalogueFactory.getFactory();
DataCatalogueImpl utils = factory.getUtilsPerScope(scope);
CkanDataset dataset = utils.getDataset(datasetId, testUser);
System.out.println("Dataset: "+dataset);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Factory test.
*
* @throws Exception the exception
*/
//@Test
public void factoryTest() throws Exception{
// @Test
public void factoryTest() throws Exception {
DataCatalogueFactory factory = DataCatalogueFactory.getFactory();
while(true){
while (true) {
factory.getUtilsPerScope(scope);
Thread.sleep(60* 1000 * 3);
Thread.sleep(60 * 1000 * 3);
factory.getUtilsPerScope(scope);
break;
}
@ -61,16 +88,16 @@ public class TestPublishingWidget {
}
}
//@Test
public void getDatasetBeanTest() throws Exception{
// @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{
try {
bean = new DatasetBean();
bean.setId(folderId);
bean.setDescription("This is a fantastic description");
@ -83,24 +110,23 @@ public class TestPublishingWidget {
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);
// 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()){
if (folderId != null && !folderId.isEmpty()) {
StorageHubWrapper storageHubWrapper = new StorageHubWrapper(scope, token, false, false, true);
WorkspaceUtils.toWorkspaceResource(folderId, userName, bean, storageHubWrapper.getWorkspace());
}
}catch(Exception e){
} 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);
LOG.info("Got dataset: " + bean);
}
}