added support for ticket #7207

git-svn-id: http://svn.d4science-ii.research-infrastructures.eu/gcube/trunk/portlets/widgets/ckan-metadata-publisher-widget@144145 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Costantino Perciante 2017-02-22 16:40:16 +00:00
parent ffe9c462e0
commit f7d30e099a
7 changed files with 120 additions and 95 deletions

View File

@ -32,11 +32,11 @@ public interface CKanPublisherService extends RemoteService {
List<MetaDataProfileBean> getProfiles(String orgName);
/**
* Retrieve a partially filled bean given a folder id and its owner.
* @param folderId
* 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.
*/
DatasetMetadataBean getDatasetBean(String folderId);
DatasetMetadataBean getDatasetBean(String folderIdOrFileId);
/**
* Try to create such dataset starting from the information contained into the toCreate bean.

View File

@ -23,11 +23,11 @@ public interface CKanPublisherServiceAsync {
void getLicenses(AsyncCallback<LicensesBean> callback);
/**
* Retrieve a partially filled bean given a folder id and its owner.
* @param folderId
* 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.
*/
void getDatasetBean(String folderId,
void getDatasetBean(String folderIdOrFileId,
AsyncCallback<DatasetMetadataBean> callback);
/**

View File

@ -222,8 +222,8 @@ public class CreateDatasetForm extends Composite{
* @param idFolderWorkspace
* @param eventBus the event bus
*/
public CreateDatasetForm(String idFolderWorkspace, HandlerManager eventBus) {
createDatasetFormBody(true, idFolderWorkspace, eventBus);
public CreateDatasetForm(String idFolderOrFileWorkspace, HandlerManager eventBus) {
createDatasetFormBody(true, idFolderOrFileWorkspace, eventBus);
}
/**
@ -256,7 +256,7 @@ public class CreateDatasetForm extends Composite{
* @param owner
* @param eventBus
*/
private void createDatasetFormBody(final boolean isWorkspaceRequest, final String idFolderWorkspace, final HandlerManager eventBus){
private void createDatasetFormBody(final boolean isWorkspaceRequest, final String idFolderOrFileWorkspace, final HandlerManager eventBus){
initWidget(uiBinder.createAndBindUi(this));
this.eventBus = eventBus;
@ -282,7 +282,7 @@ public class CreateDatasetForm extends Composite{
setAlertBlock("Retrieving information, please wait...", AlertType.INFO, true);
// get back the licenses and the metadata information
ckanServices.getDatasetBean(idFolderWorkspace, new AsyncCallback<DatasetMetadataBean>() {
ckanServices.getDatasetBean(idFolderOrFileWorkspace, new AsyncCallback<DatasetMetadataBean>() {
@Override
public void onFailure(Throwable caught) {
@ -339,16 +339,12 @@ public class CreateDatasetForm extends Composite{
}
if(isWorkspaceRequest){
boolean showAlertMissingResources = bean.getResources() == null || bean.getResources().isEmpty() || bean.getResources().get(0).getChildren() == null ||
bean.getResources().get(0).getChildren().isEmpty();
// if there are not resources, for now just checked it ( and hide so that the step will be skipped)
if(showAlertMissingResources){
if(hideManageResources()){
alertNoResources.setType(AlertType.WARNING);
alertNoResources.setVisible(true);
}else
resourcesTwinPanel = new TwinColumnSelectionMainPanel(bean.getResources().get(0));
resourcesTwinPanel = new TwinColumnSelectionMainPanel(bean.getResourceRoot());
}
// set organizations
@ -731,9 +727,8 @@ public class CreateDatasetForm extends Composite{
// we need to show the page to handle resources one by one from the workspace
formFirstStep.setVisible(false);
boolean hideManageResources = receivedBean.getResources() == null || receivedBean.getResources().isEmpty();
formSecondStep.setVisible(!hideManageResources);
formThirdStep.setVisible(hideManageResources);
formSecondStep.setVisible(!hideManageResources());
formThirdStep.setVisible(hideManageResources());
// add the resources to the container panel
if(workspaceResourcesContainer.getWidget() == null){
@ -773,9 +768,8 @@ public class CreateDatasetForm extends Composite{
// swap forms
if(isWorkspaceRequest){
boolean resourcesPresent = receivedBean.getResources() != null && receivedBean.getResources().size() > 0 ? true : false;
formFirstStep.setVisible(!resourcesPresent);
formSecondStep.setVisible(resourcesPresent);
formFirstStep.setVisible(hideManageResources());
formSecondStep.setVisible(!hideManageResources());
}else{
formFirstStep.setVisible(true);
formSecondStep.setVisible(false);
@ -853,7 +847,7 @@ public class CreateDatasetForm extends Composite{
receivedBean.setSelectedOrganization(chosenOrganization);
receivedBean.setGroups(groups);
if(resourcesTwinPanel != null)
receivedBean.setResources(resourcesTwinPanel.getResourcesToPublish());
receivedBean.setResourceRoot(resourcesTwinPanel.getResourcesToPublish());
Map<String, List<String>> customFieldsMap = new HashMap<String, List<String>>();
@ -1122,7 +1116,7 @@ public class CreateDatasetForm extends Composite{
focusPanelTitle,
popupOpenedIds
);
// description
InfoIconsLabels.preparePopupPanelAndPopover(
InfoIconsLabels.DESCRIPTION_INFO_ID_POPUP,
@ -1279,7 +1273,7 @@ public class CreateDatasetForm extends Composite{
organizationsGroup.setType(ControlGroupType.ERROR);
return "You must select an organization in which you want to publish";
}
// at least one tag..
if(tagsPanel.getTags().isEmpty()){
tagsPanel.setGroupPanelType(ControlGroupType.ERROR);
@ -1425,4 +1419,15 @@ public class CreateDatasetForm extends Composite{
groupsControlGroup.setVisible(true);
}
/**
* Check if resource(s) are missing
* @return
*/
private boolean hideManageResources(){
return receivedBean.getResourceRoot() == null || (receivedBean.getResourceRoot().isFolder() && (receivedBean.getResourceRoot().getChildren() == null ||
receivedBean.getResourceRoot().getChildren().isEmpty()));
}
}

View File

@ -1,6 +1,7 @@
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;
@ -145,8 +146,11 @@ public class TwinColumnSelectionMainPanel extends Composite{
// Set a key provider that provides a unique key for each object.
cellListLeft = new CellList<ResourceElementBean>(cell, ResourceElementBean.KEY_PROVIDER);
cellListLeft.setPageSize(initialBean.getChildren().size());
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>(ResourceElementBean.KEY_PROVIDER);
@ -207,8 +211,11 @@ public class TwinColumnSelectionMainPanel extends Composite{
});
// set the list into the provider
Collections.sort(this.initialBean.getChildren());
dataProviderLeft.setList(this.initialBean.getChildren());
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());
@ -478,20 +485,25 @@ public class TwinColumnSelectionMainPanel extends Composite{
}
/**
* Returns the list of files to save
* Returns the root parent with the children as files to save
* @return the resources to save
*/
public List<ResourceElementBean> getResourcesToPublish(){
public ResourceElementBean getResourcesToPublish(){
List<ResourceElementBean> current = dataProviderRight.getList();
List<ResourceElementBean> toReturn = new ArrayList<ResourceElementBean>();
ResourceElementBean toReturn = new ResourceElementBean();
List<ResourceElementBean> children = new ArrayList<ResourceElementBean>();
for (ResourceElementBean resource : current) {
if(resource.isToBeAdded() && !resource.isFolder()){ // be sure ...
ResourceElementBean beanWithoutChildren = new ResourceElementBean(resource);
beanWithoutChildren.setName(resource.getEditableName());
toReturn.add(beanWithoutChildren);
children.add(beanWithoutChildren);
}
}
toReturn.setChildren(children);
return toReturn;
}

View File

@ -264,10 +264,10 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C
// get the list of resources and convert to ResourceBean
List<ResourceBean> resources = null;
List<ResourceElementBean> resourcesToAdd = toCreate.getResources();
ResourceElementBean resourcesToAdd = toCreate.getResourceRoot();
// we need to copy such resource in the .catalogue area of the user's ws
if(resourcesToAdd != null && !resourcesToAdd.isEmpty()){
if(resourcesToAdd != null){
resources = WorkspaceUtils.copyResourcesToUserCatalogueArea(toCreate.getId(), userName, toCreate);
}
@ -521,7 +521,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C
logger.warn("OUT FROM PORTAL DETECTED RETURNING TRUE");
return false;
}
try{
HttpSession httpSession = this.getThreadLocalRequest().getSession();
@ -570,7 +570,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C
logger.info("Does the user have the right to publish on the catalogue? " + role);
return !role.equals(RolesCkanGroupOrOrg.MEMBER);
}catch(Exception e){
logger.error("Failed to check the user's role", e);
}

View File

@ -31,21 +31,22 @@ public class WorkspaceUtils {
private static final String RESOURCES_NAME_SEPARATOR = "_";
/**
* Copy into the .catalogue area folder the checked resources
* 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<ResourceBean> copyResourcesToUserCatalogueArea(String folderId, String userName, DatasetMetadataBean bean) throws Exception{
public static List<ResourceBean> copyResourcesToUserCatalogueArea(String folderOrFileId, String userName, DatasetMetadataBean bean) throws Exception{
logger.debug("Request to copy onto catalogue area....");
List<ResourceBean> resources = new ArrayList<ResourceBean>();
WorkspaceItem copiedFolder = null;
WorkspaceCatalogue userCatalogue = null;
List<ResourceElementBean> resourcesToAdd = bean.getResources();
ResourceElementBean rootResource = bean.getResourceRoot();
// in to the .catalogue area of the user's workspace
// into the .catalogue area of the user's workspace
Workspace ws = HomeLibrary
.getHomeManagerFactory()
.getHomeManager()
@ -55,16 +56,25 @@ public class WorkspaceUtils {
// Retrieve the catalogue of the user
userCatalogue = ws.getCatalogue();
// Create the folder in the catalogue
copiedFolder = userCatalogue.addWorkspaceItem(folderId, userCatalogue.getId()); // add to .catalogue root area
// get workspace item (it could be a file or a folder)
WorkspaceItem originalItem = ws.getItem(folderOrFileId);
// change description for the folder
copiedFolder.setDescription(bean.getDescription());
// 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());
}
else{
copiedFolder = userCatalogue.createFolder(UtilMethods.fromProductTitleToName(bean.getTitle()) + "_" + referenceTime, bean.getDescription());
}
// change name of the copied folder to match the title (append the timestamp to avoid ties)
long referenceTime = System.currentTimeMillis();
((WorkspaceFolder)copiedFolder).rename(UtilMethods.fromProductTitleToName(bean.getTitle()) + "_" + referenceTime);
// retrieve the children
List<ResourceElementBean> resourcesToAdd = rootResource.getChildren();
// copy only the selected ones
for(ResourceElementBean resource : resourcesToAdd){
@ -90,6 +100,7 @@ public class WorkspaceUtils {
// postpone rename operation
copiedFile.rename(resource.getName() + "_" + referenceTime);
}
}
return resources;
}
@ -111,33 +122,45 @@ public class WorkspaceUtils {
.getHomeManager()
.getHome().getWorkspace();
WorkspaceItem originalFolder = ws.getItem(folderId);
WorkspaceItem originalFolderOrFile = ws.getItem(folderId);
// set some info
String onlyAlphanumericTitle = originalFolder.getName().replaceAll("[^A-Za-z0-9.-_]", " "); // that is, remove characters different than the ones inside
// since it will (likely) be the name of the product
bean.setTitle(onlyAlphanumericTitle);
bean.setDescription(originalFolder.getDescription());
if(!originalFolderOrFile.isFolder()){
// Create the folder in the catalogue
Map<String, String> folderItems = Utils.getGcubeItemProperties(originalFolder);
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("[^A-Za-z0-9.-_]", " "));
bean.setDescription(originalFolderOrFile.getDescription());
if(folderItems != null){
// transform this properties
Map<String, List<String>> tempItems = new HashMap<String, List<String>>(folderItems.size());
}else{
Iterator<Entry<String, String>> iterator = folderItems.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<java.lang.String, java.lang.String> entry = (Map.Entry<java.lang.String, java.lang.String>) iterator
.next();
tempItems.put(entry.getKey(), Arrays.asList(entry.getValue()));
String onlyAlphanumericTitle = originalFolderOrFile.getName().replaceAll("[^A-Za-z0-9.-_]", " "); // that is, remove characters different than the ones inside
bean.setTitle(onlyAlphanumericTitle);
bean.setDescription(originalFolderOrFile.getDescription());
// Create the folder in the catalogue
Map<String, String> folderItems = Utils.getGcubeItemProperties(originalFolderOrFile);
if(folderItems != null){
// transform this properties
Map<String, List<String>> tempItems = new HashMap<String, List<String>>(folderItems.size());
Iterator<Entry<String, String>> iterator = folderItems.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<java.lang.String, java.lang.String> entry = (Map.Entry<java.lang.String, java.lang.String>) iterator
.next();
tempItems.put(entry.getKey(), Arrays.asList(entry.getValue()));
}
bean.setCustomFields(tempItems);
}
bean.setCustomFields(tempItems);
}
// set them into the bean
bean.setResources(Arrays.asList(WorkspaceUtils.getTreeFromFolder(folderId, ws)));
// set them into the bean
bean.setResourceRoot(WorkspaceUtils.getTreeFromFolder(folderId, ws));
}
}
@ -216,4 +239,4 @@ public class WorkspaceUtils {
rootElem.setEditableName(fullPath);
}
}
}

View File

@ -5,23 +5,7 @@ import java.util.List;
import java.util.Map;
/**
* This bean will contain during ckan metadata creation the following information
* (related to the workspace folder that represents a dataset)
* <ul>
* <li> id -> the id that will be assigned by ckan
* <li> Title -> folder's name
* <li> Description -> folders' description
* <li> tags -> folder's custom fields keys' names
* <li> visibility -> as chosen by the creator (visible = true, not visible = false)
* <li> source -> url of the folder within the workspace
* <li> version -> during creation it is going to be 1.0
* <li> author, maintainer -> folder's owner
* <li> custom fields -> gcube items <key, value> couple
* <li> organizationsList -> list of organizations to which the user belong (and in which
* he wants to publish)
* <li> list of metadata, that is custom fields per vre
* <li> the name of the chosen profile used
* </ul>
* 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")
@ -44,7 +28,7 @@ public class DatasetMetadataBean implements Serializable {
private long version; // version 1, 2 ...
private boolean visibility; // Private (false) or Public(true)
private List<OrganizationBean> organizationList; // list of organization in which the user is present and could create the dataset
private List<ResourceElementBean> resources; // in case of workspace, this is the list of children of the folder
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 custom fields
private Map<String, List<String>> customFields;
@ -81,7 +65,7 @@ public class DatasetMetadataBean implements Serializable {
String authorName, String authorSurname, String authorEmail, String maintainer,
String maintainerEmail, String ownerIdentifier,
List<OrganizationBean> organizationList, String selectedOrganization,
List<ResourceElementBean> resources,
ResourceElementBean resourceRoot,
List<MetaDataProfileBean> metadataList, List<GroupBean> groups) {
super();
this.id = id;
@ -101,7 +85,7 @@ public class DatasetMetadataBean implements Serializable {
this.ownerIdentifier = ownerIdentifier;
this.organizationList = organizationList;
this.selectedOrganization = selectedOrganization;
this.resources = resources;
this.resourceRoot = resourceRoot;
this.metadataList = metadataList;
this.groups = groups;
}
@ -250,12 +234,12 @@ public class DatasetMetadataBean implements Serializable {
this.selectedOrganization = selectedOrganization;
}
public List<ResourceElementBean> getResources() {
return resources;
public ResourceElementBean getResourceRoot() {
return resourceRoot;
}
public void setResources(List<ResourceElementBean> resources) {
this.resources = resources;
public void setResourceRoot(ResourceElementBean resourceRoot) {
this.resourceRoot = resourceRoot;
}
public String getAuthorFullName() {
@ -294,9 +278,10 @@ public class DatasetMetadataBean implements Serializable {
+ ", chosenProfile=" + chosenProfile
+ ", selectedOrganization=" + selectedOrganization
+ ", version=" + version + ", visibility=" + visibility
+ ", organizationList=" + organizationList + ", resources="
+ resources + ", metadataList=" + metadataList + ", tags="
+ ", organizationList=" + organizationList + ", resourceRoot="
+ resourceRoot + ", metadataList=" + metadataList + ", tags="
+ tags + ", customFields=" + customFields + ", groups="
+ groups + "]";
}
}
}