Start adding support for Metadata formats

git-svn-id: http://svn.d4science-ii.research-infrastructures.eu/gcube/trunk/portlets/widgets/ckan-metadata-publisher-widget@129020 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Costantino Perciante 2016-06-08 16:31:54 +00:00
parent 60ecb288d6
commit 1a2cf0db7b
17 changed files with 479 additions and 582 deletions

View File

@ -93,14 +93,10 @@
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId> <artifactId>slf4j-log4j12</artifactId>
<version>1.6.4</version>
<scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId> <artifactId>slf4j-api</artifactId>
<version>1.6.4</version>
<scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.gcube.common.portal</groupId> <groupId>org.gcube.common.portal</groupId>
@ -176,6 +172,11 @@
<artifactId>gcube-widgets</artifactId> <artifactId>gcube-widgets</artifactId>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>net.htmlparser.jericho</groupId>
<artifactId>jericho-html</artifactId>
<version>3.3</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -1,6 +1,6 @@
package org.gcube.portlets.widgets.ckandatapublisherwidget.client; package org.gcube.portlets.widgets.ckandatapublisherwidget.client;
import org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.EditMetadataForm; import org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.CreateDatasetForm;
import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.RootPanel;
@ -24,7 +24,7 @@ public class CKanMetadataPublisher implements EntryPoint {
String idFolderWorkspace = "8b67fc1f-940d-4512-b783-105fba11c270"; String idFolderWorkspace = "8b67fc1f-940d-4512-b783-105fba11c270";
String owner = "costantino.perciante"; String owner = "costantino.perciante";
RootPanel.get("ckan-metadata-publisher-div").add(new EditMetadataForm(owner)); RootPanel.get("ckan-metadata-publisher-div").add(new CreateDatasetForm(owner));
} }
} }

View File

@ -32,17 +32,26 @@ public interface CKanPublisherService extends RemoteService {
/** /**
* Try to create such dataset starting from the information contained into the toCreate bean. * Try to create such dataset starting from the information contained into the toCreate bean.
* @param toCreate * @param toCreate
* @param isWorkspaceRequest if the call comes from the workspace
* @return the identifier of the created dataset or null on error * @return the identifier of the created dataset or null on error
*/ */
String createCKanDataset(DatasetMetadataBean toCreate); String createCKanDataset(DatasetMetadataBean toCreate, boolean isWorkspaceRequest);
/** /**
* Add this resource to the dataset whose id is datasetId * Add this resource to the dataset whose id is datasetId
* @param resource * @param resource
* @param datasetId * @param datasetId
* @param owner of the dataset * @param owner of the dataset
* @param callback
*/ */
boolean addResourceToDataset(ResourceBean resource, String datasetId, String owner); ResourceBean addResourceToDataset(ResourceBean resource, String datasetId, String owner);
/**
* Delete this resource from the dataset with id datasetId
* @param resource
* @param datasetId
* @param owner of the dataset
* @return <b>true</b> on success, false otherwise
*/
boolean deleteResourceFromDataset(ResourceBean resource, String owner);
} }

View File

@ -31,9 +31,10 @@ public interface CKanPublisherServiceAsync {
/** /**
* Try to create such dataset starting from the information contained into the toCreate bean. * Try to create such dataset starting from the information contained into the toCreate bean.
* @param toCreate * @param toCreate
* @param isWorkspaceRequest if the call comes from the workspace
* @return <b>true</b> on success, <b>false</b> otherwise * @return <b>true</b> on success, <b>false</b> otherwise
*/ */
void createCKanDataset(DatasetMetadataBean toCreate, void createCKanDataset(DatasetMetadataBean toCreate, boolean isWorkspaceRequest,
AsyncCallback<String> callback); AsyncCallback<String> callback);
/** /**
@ -44,6 +45,15 @@ public interface CKanPublisherServiceAsync {
* @param callback * @param callback
*/ */
void addResourceToDataset(ResourceBean resource, String datasetId, String owner, void addResourceToDataset(ResourceBean resource, String datasetId, String owner,
AsyncCallback<Boolean> callback); AsyncCallback<ResourceBean> callback);
/**
* Delete this resource from the dataset with id datasetId
* @param resource
* @param owner of the dataset
* @return <b>true</b> on success, false otherwise
*/
void deleteResourceFromDataset(ResourceBean resource,
String owner, AsyncCallback<Boolean> callback);
} }

View File

@ -0,0 +1,34 @@
package org.gcube.portlets.widgets.ckandatapublisherwidget.client.events;
import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.ResourceBean;
import com.google.gwt.event.shared.GwtEvent;
/**
* Deleted resource event.
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/
public class DeleteResourceEvent extends GwtEvent<DeleteResourceEventHandler> {
public static Type<DeleteResourceEventHandler> TYPE = new Type<DeleteResourceEventHandler>();
private ResourceBean resource;
public DeleteResourceEvent(ResourceBean resource) {
this.resource = resource;
}
public ResourceBean getResource() {
return resource;
}
@Override
public Type<DeleteResourceEventHandler> getAssociatedType() {
return TYPE;
}
@Override
protected void dispatch(DeleteResourceEventHandler handler) {
handler.onDeletedResource(this);
}
}

View File

@ -0,0 +1,11 @@
package org.gcube.portlets.widgets.ckandatapublisherwidget.client.events;
import com.google.gwt.event.shared.EventHandler;
/**
* The delete event handler
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/
public interface DeleteResourceEventHandler extends EventHandler{
void onDeletedResource(DeleteResourceEvent deleteResourceEvent);
}

View File

@ -36,10 +36,10 @@ public class AddResourceToDataset extends Composite{
// bus to alert the dataset form about this new resource // bus to alert the dataset form about this new resource
private HandlerManager eventBus; private HandlerManager eventBus;
// the dataset id // the dataset id
private String datasetId; private String datasetId;
// the owner // the owner
private String owner; private String owner;
@ -57,10 +57,10 @@ public class AddResourceToDataset extends Composite{
// save bus // save bus
this.eventBus = eventBus; this.eventBus = eventBus;
// save dataset id (it is needed when we will add resources) // save dataset id (it is needed when we will add resources)
this.datasetId = datasetId; this.datasetId = datasetId;
// the owner of the dataset/files // the owner of the dataset/files
this.owner = owner; this.owner = owner;
} }
@ -71,44 +71,45 @@ public class AddResourceToDataset extends Composite{
infoBlock.setVisible(false); infoBlock.setVisible(false);
// validation // validation
if(resourceUrlTextBox.getText().isEmpty()){ if(resourceUrlTextBox.getText().isEmpty() || resourceNameTextBox.getText().isEmpty()){
infoBlock.setType(AlertType.ERROR); showAlert("Url and name fields cannot be empty", AlertType.ERROR);
infoBlock.setText("URL cannot be empty");
infoBlock.setVisible(true);
return; return;
} }
// remove html tags into description
//String description = convert(resourceDescriptionTextArea.getText()); TODO
// collect data and build up the bean // collect data and build up the bean
final ResourceBean resource = new ResourceBean(resourceUrlTextBox.getText(), resourceNameTextBox.getText(), resourceDescriptionTextArea.getText()); final ResourceBean resource = new ResourceBean(resourceUrlTextBox.getText(), resourceNameTextBox.getText(), resourceDescriptionTextArea.getText());
// disable add button // disable add button
addResourceButton.setEnabled(false); addResourceButton.setEnabled(false);
// try to create // try to create
ckanServices.addResourceToDataset(resource, datasetId, owner, new AsyncCallback<Boolean>() { ckanServices.addResourceToDataset(resource, datasetId, owner, new AsyncCallback<ResourceBean>() {
@Override @Override
public void onSuccess(Boolean result) { public void onSuccess(ResourceBean result) {
if(result){ if(result != null){
showAlert("Resource created correctly", AlertType.SUCCESS); showAlert("Resource created correctly", AlertType.SUCCESS);
eventBus.fireEvent(new AddResourceEvent(resource)); eventBus.fireEvent(new AddResourceEvent(result));
// remove data
resourceUrlTextBox.setText("");
resourceNameTextBox.setText("");
resourceDescriptionTextArea.setText("");
} }
else else
showAlert("Unable to add this resource. Check the url is correct", AlertType.ERROR); showAlert("Unable to add this resource. Check that the url is correct", AlertType.ERROR);
} }
@Override @Override
public void onFailure(Throwable caught) { public void onFailure(Throwable caught) {
showAlert("Unable to add this resource, sorry", AlertType.ERROR); showAlert("Unable to add this resource, sorry", AlertType.ERROR);
} }
}); });
@ -120,7 +121,7 @@ public class AddResourceToDataset extends Composite{
* @param type * @param type
*/ */
protected void showAlert(String text, AlertType type) { protected void showAlert(String text, AlertType type) {
infoBlock.setText(text); infoBlock.setText(text);
infoBlock.setType(type); infoBlock.setType(type);
infoBlock.setVisible(true); infoBlock.setVisible(true);

View File

@ -37,15 +37,6 @@
.add-resource-button { .add-resource-button {
float: right; float: right;
} }
.info-markdown {
width: 95%;
background-color: #ebebeb;
border-bottom: 1px thin;
border-left: 1px thin;
border-right: 1px thin;
padding: 3px;
}
</ui:style> </ui:style>
<g:HTMLPanel> <g:HTMLPanel>
<b:Form type="HORIZONTAL" styleName="{style.form-main-style}" <b:Form type="HORIZONTAL" styleName="{style.form-main-style}"
@ -73,6 +64,7 @@
<b:ControlGroup> <b:ControlGroup>
<b:ControlLabel for="name" title="Resource name"> <b:ControlLabel for="name" title="Resource name">
<font color="red">*</font>
Name: Name:
</b:ControlLabel> </b:ControlLabel>
<b:Controls> <b:Controls>
@ -89,34 +81,16 @@
<b:TextArea alternateSize="LARGE" <b:TextArea alternateSize="LARGE"
placeholder="Some useful notes about data" b:id="description" placeholder="Some useful notes about data" b:id="description"
title="Resource description" ui:field="resourceDescriptionTextArea" /> title="Resource description" ui:field="resourceDescriptionTextArea" />
<b:Paragraph styleName="{style.info-markdown}">
You can use
<b:Popover html="true"
text="__Bold text__ or _italic text_
# title
## secondary title
### etc
* list
* of
* items
http://auto.link.ed/
Please note: HTML tags are stripped out for security reasons"
heading="Markdown short guide">
<b:Button type="LINK">Markdown formatting</b:Button>
</b:Popover>
</b:Paragraph>
</b:Controls> </b:Controls>
</b:ControlGroup> </b:ControlGroup>
<!-- Alert blocks for info/errors --> <!-- Alert blocks for info/errors -->
<b:AlertBlock type="INFO" animation="true" visible="false" <b:AlertBlock type="INFO" animation="true" visible="false" close="false"
ui:field="infoBlock" styleName="{style.block-alert-style}"></b:AlertBlock> ui:field="infoBlock" styleName="{style.block-alert-style}"></b:AlertBlock>
<!-- Add resource button --> <!-- Add resource button -->
<b:Button title="Add resource" ui:field="addResourceButton" >Add</b:Button> <b:Button title="Add resource" ui:field="addResourceButton"
type="PRIMARY">Add</b:Button>
</b:Fieldset> </b:Fieldset>
</b:Form> </b:Form>

View File

@ -3,24 +3,31 @@ package org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.gcube.portlets.widgets.ckandatapublisherwidget.client.CKanPublisherService;
import org.gcube.portlets.widgets.ckandatapublisherwidget.client.CKanPublisherServiceAsync;
import org.gcube.portlets.widgets.ckandatapublisherwidget.client.events.AddResourceEvent; import org.gcube.portlets.widgets.ckandatapublisherwidget.client.events.AddResourceEvent;
import org.gcube.portlets.widgets.ckandatapublisherwidget.client.events.AddResourceEventHandler; import org.gcube.portlets.widgets.ckandatapublisherwidget.client.events.AddResourceEventHandler;
import org.gcube.portlets.widgets.ckandatapublisherwidget.client.events.DeleteResourceEvent;
import org.gcube.portlets.widgets.ckandatapublisherwidget.client.events.DeleteResourceEventHandler;
import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.ResourceBean; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.ResourceBean;
import com.github.gwtbootstrap.client.ui.Accordion;
import com.github.gwtbootstrap.client.ui.AccordionGroup;
import com.github.gwtbootstrap.client.ui.Button; import com.github.gwtbootstrap.client.ui.Button;
import com.github.gwtbootstrap.client.ui.constants.ButtonType; import com.github.gwtbootstrap.client.ui.Paragraph;
import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.HandlerManager; import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget; import com.google.gwt.user.client.ui.Widget;
/** /**
* A summary of the added resources by the user. * A summary of the resources added by the user.
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/ */
public class AddedResourcesSummary extends Composite{ public class AddedResourcesSummary extends Composite{
@ -32,20 +39,29 @@ public class AddedResourcesSummary extends Composite{
UiBinder<Widget, AddedResourcesSummary> { UiBinder<Widget, AddedResourcesSummary> {
} }
//Create a remote service proxy to talk to the server-side ckan service.
private final CKanPublisherServiceAsync ckanServices = GWT.create(CKanPublisherService.class);
// Event bus // Event bus
private HandlerManager eventBus; private HandlerManager eventBus;
// list of added resources // list of added resources (beans)
List<ResourceBean> addedResources; List<ResourceBean> addedResources;
// the owner
private String owner;
@UiField VerticalPanel addResourcesPanel; @UiField VerticalPanel addResourcesPanel;
public AddedResourcesSummary(HandlerManager eventBus) { public AddedResourcesSummary(HandlerManager eventBus, String owner) {
initWidget(uiBinder.createAndBindUi(this)); initWidget(uiBinder.createAndBindUi(this));
// save bus // save bus
this.eventBus = eventBus; this.eventBus = eventBus;
// save owner
this.owner = owner;
// bind on add resource event // bind on add resource event
bind(); bind();
@ -53,6 +69,9 @@ public class AddedResourcesSummary extends Composite{
addedResources = new ArrayList<ResourceBean>(); addedResources = new ArrayList<ResourceBean>();
} }
/**
* Bind on add/delete resource event
*/
private void bind() { private void bind() {
// when a new resource is added // when a new resource is added
@ -64,71 +83,84 @@ public class AddedResourcesSummary extends Composite{
// get the resource // get the resource
final ResourceBean justAddedResource = addResourceEvent.getResource(); final ResourceBean justAddedResource = addResourceEvent.getResource();
// check if a resource with this id already exists // Build an accordion to show resource info
for (ResourceBean resource : addedResources){ Accordion accordion = new Accordion();
AccordionGroup accordionGroup = new AccordionGroup();
accordionGroup.setHeading("- " + justAddedResource.getName());
accordion.add(accordionGroup);
if(resource.getId().equals(justAddedResource.getId())){ // add sub-info such as url and description
Paragraph pUrl = new Paragraph();
pUrl.setText("Url : " + justAddedResource.getUrl());
Paragraph pDescription = new Paragraph();
pDescription.setText("Description : " + justAddedResource.getDescription());
// button to delete the resource
Button deleteButton = new Button();
deleteButton.setText("Delete");
deleteButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
eventBus.fireEvent(new DeleteResourceEvent(justAddedResource));
// clear list and rebuild
rebuildSummary();
return;
} }
} });
Button associatedButton = new Button(); // fill accordion
associatedButton.setType(ButtonType.LINK); accordionGroup.add(pUrl);
associatedButton.setText("-" + justAddedResource.getName()); accordionGroup.add(pDescription);
accordionGroup.add(deleteButton);
// add to the list // add to the list
addedResources.add(justAddedResource); addedResources.add(justAddedResource);
// add to the panel // add to the panel
addResourcesPanel.add(associatedButton); addResourcesPanel.add(accordion);
}
// add handler to swap tab on click });
associatedButton.addClickHandler(new ClickHandler() {
@Override // when the user wants to delete a resource
public void onClick(ClickEvent event) { eventBus.addHandler(DeleteResourceEvent.TYPE, new DeleteResourceEventHandler() {
// TODO show information below this link and swap panel @Override
public void onDeletedResource(DeleteResourceEvent deleteResourceEvent) {
// to delete
ResourceBean toDelete = deleteResourceEvent.getResource();
// find it
for(int i = 0; i < addedResources.size(); i++){
if(addedResources.get(i).getId().equals(toDelete.getId())){
// get the associated widget and remove it
final Widget widget = addResourcesPanel.getWidget(i);
// remote call to remove it from the dataset
ckanServices.deleteResourceFromDataset(toDelete, owner, new AsyncCallback<Boolean>() {
@Override
public void onSuccess(Boolean result) {
if(result)
widget.removeFromParent();
}
@Override
public void onFailure(Throwable caught) {
}
});
break;
} }
}); }
// remove from the list
addedResources.remove(toDelete);
} }
}); });
} }
/**
* Rebuild the summary list
*/
protected void rebuildSummary() {
addResourcesPanel.clear();
for (final ResourceBean resource : addedResources){
Button associatedButton = new Button();
associatedButton.setType(ButtonType.LINK);
associatedButton.setText("-" + resource.getName());
// add to the list
addedResources.add(resource);
// add to the panel
addResourcesPanel.add(associatedButton);
// add handler to swap tab on click
associatedButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
// TODO show information below this link and swap panel
}
});
}
}
} }

View File

@ -1,11 +1,8 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent"> <!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" <ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui"> xmlns:g="urn:import:com.google.gwt.user.client.ui">
<ui:style>
</ui:style>
<g:HTMLPanel> <g:HTMLPanel>
<h2>Added Resources</h2> <h3>Added Resources</h3>
<g:VerticalPanel ui:field="addResourcesPanel"></g:VerticalPanel> <g:VerticalPanel ui:field="addResourcesPanel" width="97%"></g:VerticalPanel>
</g:HTMLPanel> </g:HTMLPanel>
</ui:UiBinder> </ui:UiBinder>

View File

@ -7,6 +7,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import org.gcube.datacatalogue.ckanutillibrary.models.MetaDataBean;
import org.gcube.portlets.user.gcubewidgets.client.elements.Span; import org.gcube.portlets.user.gcubewidgets.client.elements.Span;
import org.gcube.portlets.widgets.ckandatapublisherwidget.client.CKanPublisherService; import org.gcube.portlets.widgets.ckandatapublisherwidget.client.CKanPublisherService;
import org.gcube.portlets.widgets.ckandatapublisherwidget.client.CKanPublisherServiceAsync; import org.gcube.portlets.widgets.ckandatapublisherwidget.client.CKanPublisherServiceAsync;
@ -33,6 +34,8 @@ import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent; import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.shared.HandlerManager; import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.regexp.shared.MatchResult;
import com.google.gwt.regexp.shared.RegExp;
import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.uibinder.client.UiHandler;
@ -47,7 +50,7 @@ import com.google.gwt.user.client.ui.Widget;
* Edit metadata form for ckan dataset. * Edit metadata form for ckan dataset.
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/ */
public class EditMetadataForm extends Composite{ public class CreateDatasetForm extends Composite{
/** /**
* Create a remote service proxy to talk to the server-side ckan service. * Create a remote service proxy to talk to the server-side ckan service.
@ -58,7 +61,7 @@ public class EditMetadataForm extends Composite{
.create(EditMetadataFormUiBinder.class); .create(EditMetadataFormUiBinder.class);
interface EditMetadataFormUiBinder extends interface EditMetadataFormUiBinder extends
UiBinder<Widget, EditMetadataForm> { UiBinder<Widget, CreateDatasetForm> {
} }
@UiField TextBox titleTextBox; @UiField TextBox titleTextBox;
@ -83,12 +86,14 @@ public class EditMetadataForm extends Composite{
@UiField AlertBlock infoBlock; @UiField AlertBlock infoBlock;
@UiField AlertBlock onCreateAlertBlock; @UiField AlertBlock onCreateAlertBlock;
@UiField VerticalPanel resourcesPanel; @UiField VerticalPanel resourcesPanel;
@UiField VerticalPanel metadataPanel;
@UiField ListBox metadataFormatListbox;
// tab panel // tab panel
private TabPanel tabPanel; private TabPanel tabPanel;
// add resource form // add resource form
AddResourceToDataset resourceForm; private AddResourceToDataset resourceForm;
// tags list // tags list
private List<String> tagsList = new ArrayList<String>(); private List<String> tagsList = new ArrayList<String>();
@ -108,11 +113,14 @@ public class EditMetadataForm extends Composite{
// the owner // the owner
private String owner; private String owner;
// workspace request?
private boolean isWorkspaceRequest = false;
/** /**
* Invoked in the most general case * Invoked in the most general case
* @param owner * @param owner
*/ */
public EditMetadataForm(String owner) { public CreateDatasetForm(String owner) {
initWidget(uiBinder.createAndBindUi(this)); initWidget(uiBinder.createAndBindUi(this));
this.owner = owner; this.owner = owner;
@ -144,6 +152,7 @@ public class EditMetadataForm extends Composite{
authorEmailTextbox.setText(bean.getAuthorEmail()); authorEmailTextbox.setText(bean.getAuthorEmail());
maintainerTextbox.setText(bean.getMaintainer()); maintainerTextbox.setText(bean.getMaintainer());
maintainerEmailTextbox.setText(bean.getMaintainerEmail()); maintainerEmailTextbox.setText(bean.getMaintainerEmail());
prepareMetadataList(receivedBean);
// set organizations // set organizations
List<String> organizations = bean.getOrganizationList(); List<String> organizations = bean.getOrganizationList();
@ -206,16 +215,35 @@ public class EditMetadataForm extends Composite{
} }
/**
* Add the items to the listbox and put data into the metadataPanel
* @param receivedBean
*/
protected void prepareMetadataList(DatasetMetadataBean receivedBean) {
List<MetaDataBean> beans = receivedBean.getMetadataList();
for(MetaDataBean metadataBean: beans){
//metadataFormatListbox.addItem(metadataBean.getType().getName());
}
}
/** /**
* Invoked when the workspace is used. * Invoked when the workspace is used.
* @param idFolderWorkspace * @param idFolderWorkspace
* @param owner * @param owner
*/ */
public EditMetadataForm(String idFolderWorkspace, String owner) { public CreateDatasetForm(String idFolderWorkspace, String owner) {
initWidget(uiBinder.createAndBindUi(this)); initWidget(uiBinder.createAndBindUi(this));
this.owner = owner; this.owner = owner;
// workspace request
isWorkspaceRequest = true;
// bind on events // bind on events
bind(); bind();
@ -245,6 +273,7 @@ public class EditMetadataForm extends Composite{
authorEmailTextbox.setText(bean.getAuthorEmail()); authorEmailTextbox.setText(bean.getAuthorEmail());
maintainerTextbox.setText(bean.getMaintainer()); maintainerTextbox.setText(bean.getMaintainer());
maintainerEmailTextbox.setText(bean.getMaintainerEmail()); maintainerEmailTextbox.setText(bean.getMaintainerEmail());
prepareMetadataList(receivedBean);
// set organizations // set organizations
List<String> organizations = bean.getOrganizationList(); List<String> organizations = bean.getOrganizationList();
@ -364,11 +393,16 @@ public class EditMetadataForm extends Composite{
@UiHandler("createButton") @UiHandler("createButton")
void createDatasetEvent(ClickEvent e){ void createDatasetEvent(ClickEvent e){
// validate data TODO // validate data
boolean areDataValid = validateData(); boolean areDataValid = validateData();
// Collect current data and send them to the server // Collect current data and send them to the server
if(areDataValid){ if(!areDataValid){
alertOnCreate("Please check inserted data ", AlertType.ERROR);
}
else{
String title = titleTextBox.getValue(); String title = titleTextBox.getValue();
String description = descriptionTextarea.getText(); String description = descriptionTextarea.getText();
@ -413,10 +447,9 @@ public class EditMetadataForm extends Composite{
createButton.setEnabled(false); createButton.setEnabled(false);
resetButton.setEnabled(false); resetButton.setEnabled(false);
onCreateAlertBlock.setText("Trying to create dataset, please wait"); alertOnCreate("Trying to create dataset, please wait", AlertType.INFO);
onCreateAlertBlock.setVisible(true);
ckanServices.createCKanDataset(receivedBean, new AsyncCallback<String>() { ckanServices.createCKanDataset(receivedBean, isWorkspaceRequest, new AsyncCallback<String>() {
@Override @Override
public void onSuccess(final String datasetId) { public void onSuccess(final String datasetId) {
@ -459,10 +492,10 @@ public class EditMetadataForm extends Composite{
// tab for the added resources // tab for the added resources
Tab addedResources = new Tab(); Tab addedResources = new Tab();
addedResources.add(new AddedResourcesSummary(eventBus)); addedResources.add(new AddedResourcesSummary(eventBus, owner));
addedResources.setHeading("Added Resource"); addedResources.setHeading("Added Resource");
tabPanel.add(addedResources); tabPanel.add(addedResources);
// add tabs to resources panel // add tabs to resources panel
tabPanel.selectTab(0); tabPanel.selectTab(0);
resourcesPanel.add(tabPanel); resourcesPanel.add(tabPanel);
@ -518,14 +551,38 @@ public class EditMetadataForm extends Composite{
/** /**
* Validate data * Validate data
* @return true on success * @return true on success, false otherwise
*/ */
private boolean validateData() { private boolean validateData() {
boolean correct = true;
// TODO if(titleTextBox.getText().isEmpty())
return true; correct = false;
// email reg expression
String regexMail = "\\b[\\w.%-]+@[-.\\w]+\\.[A-Za-z]{2,4}\\b";
correct &= validateByRegExpression(maintainerEmailTextbox.getText(), regexMail);
// name reg expression
String regexName = "^[a-zA-Z\\s]+";
correct &= validateByRegExpression(maintainerTextbox.getText(), regexName);
return correct;
} }
private boolean validateByRegExpression(String textToValidate, String regex){
RegExp pattern = RegExp.compile(regex);
MatchResult matcher = pattern.exec(textToValidate);
GWT.log("Matcher is " + matcher);
return (matcher != null);
}
@UiHandler("resetButton") @UiHandler("resetButton")
void resetFormEvent(ClickEvent e){ void resetFormEvent(ClickEvent e){
@ -533,8 +590,6 @@ public class EditMetadataForm extends Composite{
titleTextBox.setText(""); titleTextBox.setText("");
descriptionTextarea.setText(""); descriptionTextarea.setText("");
versionTextbox.setText(""); versionTextbox.setText("");
authorTextbox.setText("");
authorEmailTextbox.setText("");
maintainerTextbox.setText(""); maintainerTextbox.setText("");
maintainerEmailTextbox.setText(""); maintainerEmailTextbox.setText("");
removeTags(); removeTags();
@ -548,14 +603,14 @@ public class EditMetadataForm extends Composite{
} }
/** /**
* Disable dataset editable fields * Disable dataset editable fields once the dataset has been
* Successfully created.
*/ */
protected void disableDatasetFields() { protected void disableDatasetFields() {
titleTextBox.setEnabled(false); titleTextBox.setEnabled(false);
descriptionTextarea.setEnabled(false); descriptionTextarea.setEnabled(false);
versionTextbox.setEnabled(false); versionTextbox.setEnabled(false);
authorTextbox.setEnabled(false);
authorEmailTextbox.setEnabled(false);
maintainerTextbox.setEnabled(false); maintainerTextbox.setEnabled(false);
maintainerEmailTextbox.setEnabled(false); maintainerEmailTextbox.setEnabled(false);
visibilityListbox.setEnabled(false); visibilityListbox.setEnabled(false);
@ -563,6 +618,17 @@ public class EditMetadataForm extends Composite{
licenseListbox.setEnabled(false); licenseListbox.setEnabled(false);
organizationsListbox.setEnabled(false); organizationsListbox.setEnabled(false);
addCustomFieldButton.setEnabled(false); addCustomFieldButton.setEnabled(false);
// freeze tags
for(int i = 0; i < tagsList.size(); i++){
// get tag widget
ListItem tagWidget = (ListItem)tagsPanel.getWidget(i);
// get the "x" span
tagWidget.getWidget(1).removeFromParent();
}
} }
/** /**
@ -604,19 +670,19 @@ public class EditMetadataForm extends Composite{
final String value = itemBox.getValue(); final String value = itemBox.getValue();
final ListItem displayItem = new ListItem(); final ListItem displayItem = new ListItem();
displayItem.setStyleName("tag-style"); displayItem.setStyleName("tag-style");
Span p = new Span(itemBox.getValue()); Span tagText = new Span(itemBox.getValue());
Span span = new Span("x"); Span tagRemove = new Span("x");
span.setTitle("Remove this tag"); tagRemove.setTitle("Remove this tag");
span.addClickHandler(new ClickHandler() { tagRemove.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent clickEvent) { public void onClick(ClickEvent clickEvent) {
removeListItem(displayItem, value); removeTag(displayItem, value);
} }
}); });
span.setStyleName("tag-style-x"); tagRemove.setStyleName("tag-style-x");
displayItem.add(p); displayItem.add(tagText);
displayItem.add(span); displayItem.add(tagRemove);
itemBox.setValue(""); itemBox.setValue("");
itemBox.setFocus(true); itemBox.setFocus(true);
tagsPanel.add(displayItem); tagsPanel.add(displayItem);
@ -640,7 +706,7 @@ public class EditMetadataForm extends Composite{
span.setTitle("Remove this tag"); span.setTitle("Remove this tag");
span.addClickHandler(new ClickHandler() { span.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent clickEvent) { public void onClick(ClickEvent clickEvent) {
removeListItem(displayItem, tag); removeTag(displayItem, tag);
} }
}); });
@ -655,10 +721,11 @@ public class EditMetadataForm extends Composite{
* Remove a tag from the list * Remove a tag from the list
* @param displayItem * @param displayItem
*/ */
private void removeListItem(ListItem displayItem, String value) { private void removeTag(ListItem displayItem, String value) {
GWT.log("Removing: " + displayItem.getWidget(0).getElement().getInnerHTML(), null);
tagsList.remove(value); tagsList.remove(value);
tagsPanel.remove(displayItem); tagsPanel.remove(displayItem);
} }
/** /**

View File

@ -33,15 +33,6 @@
.tagsPanelStyle { .tagsPanelStyle {
display: inline-block; display: inline-block;
} }
.info-markdown {
width: 95%;
background-color: #ebebeb;
border-bottom: 1px thin;
border-left: 1px thin;
border-right: 1px thin;
padding: 3px;
}
</ui:style> </ui:style>
<g:HTMLPanel> <g:HTMLPanel>
<b:Form type="HORIZONTAL" styleName="{style.form-main-style}" <b:Form type="HORIZONTAL" styleName="{style.form-main-style}"
@ -91,25 +82,6 @@
<b:TextArea placeholder="eg. Some useful notes about the data" <b:TextArea placeholder="eg. Some useful notes about the data"
alternateSize="LARGE" b:id="description" title="Dataset description" alternateSize="LARGE" b:id="description" title="Dataset description"
ui:field="descriptionTextarea"></b:TextArea> ui:field="descriptionTextarea"></b:TextArea>
<b:Paragraph styleName="{style.info-markdown}">
You can use
<b:Popover html="true"
text="__Bold text__ or _italic text_
# title
## secondary title
### etc
* list
* of
* items
http://auto.link.ed/
Please note: HTML tags are stripped out for security reasons"
heading="Markdown formatting short guide">
<b:Button type="LINK">Markdown formatting</b:Button>
</b:Popover>
</b:Paragraph>
</b:Controls> </b:Controls>
</b:ControlGroup> </b:ControlGroup>
@ -188,7 +160,7 @@
</b:ControlLabel> </b:ControlLabel>
<b:Controls> <b:Controls>
<b:TextBox alternateSize="LARGE" placeholder="Joe Bloggs" <b:TextBox alternateSize="LARGE" placeholder="Joe Bloggs"
b:id="author" title="Dataset author" ui:field="authorTextbox" /> enabled="false" b:id="author" title="Dataset author" ui:field="authorTextbox" />
</b:Controls> </b:Controls>
</b:ControlGroup> </b:ControlGroup>
@ -199,7 +171,7 @@
</b:ControlLabel> </b:ControlLabel>
<b:Controls> <b:Controls>
<b:TextBox alternateSize="LARGE" placeholder="joe.bloggs@example.com" <b:TextBox alternateSize="LARGE" placeholder="joe.bloggs@example.com"
b:id="email" title="Dataset author" ui:field="authorEmailTextbox" /> enabled="false" b:id="email" title="Dataset author" ui:field="authorEmailTextbox" />
</b:Controls> </b:Controls>
</b:ControlGroup> </b:ControlGroup>
@ -223,6 +195,20 @@
</b:Controls> </b:Controls>
</b:ControlGroup> </b:ControlGroup>
<b:ControlGroup>
<b:ControlLabel for="metadataFormat" title="Metadata format">Metadata
Format:</b:ControlLabel>
<b:Controls>
<b:ListBox b:id="metadataFormat" alternateSize="LARGE"
title="The metadata format to be used" ui:field="metadataFormatListbox">
</b:ListBox>
</b:Controls>
</b:ControlGroup>
<!-- Here will be placed the metadata formats -->
<g:VerticalPanel ui:field="metadataPanel" visible="false"
width="100%"></g:VerticalPanel>
<!-- Custom fields can be dinamically added --> <!-- Custom fields can be dinamically added -->
<b:ControlGroup ui:field="customFields"> <b:ControlGroup ui:field="customFields">
<b:ControlLabel>Custom Field(s):</b:ControlLabel> <b:ControlLabel>Custom Field(s):</b:ControlLabel>
@ -236,7 +222,8 @@
dataset. dataset.
You have to choose a unique key for the field and a value You have to choose a unique key for the field and a value
for this. You for this. You
can remove them at any time. can remove them at any time until you create the
dataset.
</span> </span>
<b:Button icon="PLUS_SIGN" title="Add Custom Field" <b:Button icon="PLUS_SIGN" title="Add Custom Field"
ui:field="addCustomFieldButton"></b:Button> ui:field="addCustomFieldButton"></b:Button>
@ -261,12 +248,13 @@
<b:AlertBlock type="INFO" close="false" animation="true" <b:AlertBlock type="INFO" close="false" animation="true"
visible="false" ui:field="onCreateAlertBlock" styleName="{style.block-alert-style}"> visible="false" ui:field="onCreateAlertBlock" styleName="{style.block-alert-style}">
</b:AlertBlock> </b:AlertBlock>
<b:Button title="Add resources to the just created dataset" visible="false" <b:Button title="Add resources to the just created dataset"
ui:field="addResourcesButton">Add Resources</b:Button> type="PRIMARY" visible="false" ui:field="addResourcesButton">Add Resources</b:Button>
<!-- Here will be placed the form for the resources --> <!-- Here will be placed the form for the resources -->
<g:VerticalPanel ui:field="resourcesPanel" visible="false" width="100%"></g:VerticalPanel> <g:VerticalPanel ui:field="resourcesPanel" visible="false"
width="100%"></g:VerticalPanel>
<b:Button title="Create dataset" ui:field="createButton" <b:Button title="Create dataset" ui:field="createButton"
type="PRIMARY" block="true">Create</b:Button> type="PRIMARY" block="true">Create</b:Button>

View File

@ -10,6 +10,10 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import net.htmlparser.jericho.Renderer;
import net.htmlparser.jericho.Segment;
import net.htmlparser.jericho.Source;
import org.gcube.common.homelibrary.home.HomeLibrary; import org.gcube.common.homelibrary.home.HomeLibrary;
import org.gcube.common.homelibrary.home.exceptions.InternalErrorException; import org.gcube.common.homelibrary.home.exceptions.InternalErrorException;
import org.gcube.common.homelibrary.home.workspace.Workspace; import org.gcube.common.homelibrary.home.workspace.Workspace;
@ -18,6 +22,7 @@ import org.gcube.common.homelibrary.home.workspace.folder.FolderItem;
import org.gcube.common.homelibrary.home.workspace.folder.items.GCubeItem; import org.gcube.common.homelibrary.home.workspace.folder.items.GCubeItem;
import org.gcube.common.scope.api.ScopeProvider; import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.datacatalogue.ckanutillibrary.CKanUtilsFactory; import org.gcube.datacatalogue.ckanutillibrary.CKanUtilsFactory;
import org.gcube.datacatalogue.ckanutillibrary.models.MetaDataBean;
import org.gcube.portlets.widgets.ckandatapublisherwidget.client.CKanPublisherService; import org.gcube.portlets.widgets.ckandatapublisherwidget.client.CKanPublisherService;
import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.DatasetMetadataBean; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.DatasetMetadataBean;
import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.LicensesBean; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.LicensesBean;
@ -149,6 +154,27 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C
return null; return null;
} }
/**
* Retrieve the list of metadata beans
* @return
*/
private List<MetaDataBean> getMetaDataBeanList(){
logger.debug("Request for metadata beans list");
try{
String currentScope = getCurrentScope();
return CKanUtilsFactory.getInstance().getCkanUtilsForScope(currentScope).getMetadataList();
}catch(Exception e){
logger.error("Unable to retrieve metadata", e);
}
return null;
}
@Override @Override
public LicensesBean getLicenses() { public LicensesBean getLicenses() {
@ -187,7 +213,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C
bean = new DatasetMetadataBean(); bean = new DatasetMetadataBean();
bean.setId(folderId); bean.setId(folderId);
bean.setOwnerFolderInWorkspace(owner); bean.setOwnerIdentifier(owner);
bean.setVersion(1); bean.setVersion(1);
bean.setAuthor(userOwner.getFullname()); bean.setAuthor(userOwner.getFullname());
bean.setAuthorEmail(userOwner.getEmail()); bean.setAuthorEmail(userOwner.getEmail());
@ -195,6 +221,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C
bean.setMaintainerEmail(userOwner.getEmail()); bean.setMaintainerEmail(userOwner.getEmail());
bean.setOrganizationList(getUserOrganizationsList(owner)); bean.setOrganizationList(getUserOrganizationsList(owner));
// if the request comes from the workspace
if(folderId != null && !folderId.isEmpty()){ if(folderId != null && !folderId.isEmpty()){
@ -222,6 +249,11 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C
} }
bean.setResourcesIds(childrenIds); bean.setResourcesIds(childrenIds);
// retrieve the metadata
List<MetaDataBean> metadataBeans = getMetaDataBeanList();
bean.setMetadataList(metadataBeans);
} }
}catch(Exception e){ }catch(Exception e){
@ -241,7 +273,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C
bean.setMaintainer("Costantino Perciante"); bean.setMaintainer("Costantino Perciante");
bean.setMaintainerEmail("costantino.perciante@isti.cnr.it"); bean.setMaintainerEmail("costantino.perciante@isti.cnr.it");
bean.setOrganizationList(getUserOrganizationsList(owner)); bean.setOrganizationList(getUserOrganizationsList(owner));
bean.setOwnerFolderInWorkspace(owner); bean.setOwnerIdentifier(owner);
if(folderId != null && !folderId.isEmpty()){ if(folderId != null && !folderId.isEmpty()){
ScopeProvider.instance.set("/gcube"); ScopeProvider.instance.set("/gcube");
@ -267,6 +299,11 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C
bean.setResourcesIds(childrenIds); bean.setResourcesIds(childrenIds);
} }
// retrieve the metadata
List<MetaDataBean> metadataBeans = getMetaDataBeanList();
bean.setMetadataList(metadataBeans);
}catch(Exception e){ }catch(Exception e){
logger.error("Error while building bean into dev mode", e); logger.error("Error while building bean into dev mode", e);
} }
@ -302,13 +339,13 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C
} }
@Override @Override
public String createCKanDataset(DatasetMetadataBean toCreate) { public String createCKanDataset(DatasetMetadataBean toCreate, boolean isWorkspaceRequest) {
// retrieve ckan's catalog url // retrieve ckan's catalog url
String ckanPortalUrl = getCatalogueUrl(); String ckanPortalUrl = getCatalogueUrl();
// retrieve the owner of the original folder into the workspace // retrieve the owner identifier
String owner = toCreate.getOwnerFolderInWorkspace(); String owner = toCreate.getOwnerIdentifier();
// retrieve the api key for this user // retrieve the api key for this user
String apiKey = getCKANApikeyFromUser(owner); String apiKey = getCKANApikeyFromUser(owner);
@ -335,7 +372,16 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C
dataset.setMaintainer(toCreate.getMaintainer()); dataset.setMaintainer(toCreate.getMaintainer());
dataset.setMaintainerEmail(toCreate.getMaintainerEmail()); dataset.setMaintainerEmail(toCreate.getMaintainerEmail());
dataset.setVersion(String.valueOf(toCreate.getVersion())); dataset.setVersion(String.valueOf(toCreate.getVersion()));
dataset.setNotes(toCreate.getDescription());
// description must be escaped
Source description = new Source(toCreate.getDescription());
Segment htmlSeg = new Segment(description, 0, description.length());
Renderer htmlRend = new Renderer(htmlSeg);
dataset.setNotes(htmlRend.toString());
logger.debug("Description (escaped is ) " + htmlRend.toString());
// visibility TODO
dataset.setOpen(toCreate.getVisibility()); dataset.setOpen(toCreate.getVisibility());
// iterate over the licenses to find the id of the chosen one // iterate over the licenses to find the id of the chosen one
@ -374,7 +420,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C
} }
// check if we need to add the resources // check if we need to add the resources
if(toCreate.isAddResources()){ if(toCreate.isAddResources() && isWorkspaceRequest){
logger.debug("We need to add resources to the dataset"); logger.debug("We need to add resources to the dataset");
@ -384,7 +430,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C
Workspace ws = HomeLibrary Workspace ws = HomeLibrary
.getHomeManagerFactory() .getHomeManagerFactory()
.getHomeManager() .getHomeManager()
.getHome(toCreate.getOwnerFolderInWorkspace()).getWorkspace(); .getHome(toCreate.getOwnerIdentifier()).getWorkspace();
List<CkanResource> resources = new ArrayList<CkanResource>(); List<CkanResource> resources = new ArrayList<CkanResource>();
@ -420,8 +466,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C
}catch(Exception e){ }catch(Exception e){
// try to update // try to update
logger.error("Error while creating the dataset, probably it already exists. Trying to update it..", e); logger.error("Error while creating the dataset, probably it already exists.", e);
res = client.updateDataset(dataset);
} }
@ -459,7 +504,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C
HttpURLConnection.setFollowRedirects(true); HttpURLConnection.setFollowRedirects(true);
HttpURLConnection con = (HttpURLConnection) new URL(URLName).openConnection(); HttpURLConnection con = (HttpURLConnection) new URL(URLName).openConnection();
con.setRequestMethod("HEAD"); con.setRequestMethod("HEAD");
logger.info("Return code is " + con.getResponseCode()); logger.debug("Return code is " + con.getResponseCode());
return (con.getResponseCode() == HttpURLConnection.HTTP_OK); return (con.getResponseCode() == HttpURLConnection.HTTP_OK);
} }
catch (Exception e) { catch (Exception e) {
@ -469,45 +514,81 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C
} }
@Override @Override
public boolean addResourceToDataset(ResourceBean resourceBean, String datasetId, String owner) { public ResourceBean addResourceToDataset(ResourceBean resourceBean, String datasetId, String owner) {
logger.info("Incoming request for creating new resource for dataset with id " + datasetId); logger.debug("Incoming request for creating new resource for dataset with id " + datasetId);
logger.info("Owner is " + owner + " and resource is " + resourceBean); logger.debug("Owner is " + owner + " and resource is " + resourceBean);
// of course, if it exists // of course, if it exists
if(exists(resourceBean.getUrl())){ if(exists(resourceBean.getUrl())){
try{ try{
// retrieve ckan's catalog url // retrieve ckan's catalog url
String ckanPortalUrl = getCatalogueUrl(); String ckanPortalUrl = getCatalogueUrl();
// retrieve the api key for this user // retrieve the api key for this user
String apiKey = getCKANApikeyFromUser(owner); String apiKey = getCKANApikeyFromUser(owner);
CkanResource resource = new CkanResource(ckanPortalUrl, datasetId); CkanResource resource = new CkanResource(ckanPortalUrl, datasetId);
resource.setName(resourceBean.getName()); resource.setName(resourceBean.getName());
resource.setDescription(resourceBean.getDescription());
resource.setUrl(resourceBean.getUrl()); // escape description
resource.setOwner(owner); Source description = new Source(resourceBean.getDescription());
Segment htmlSeg = new Segment(description, 0, description.length());
// Checked client Renderer htmlRend = new Renderer(htmlSeg);
CheckedCkanClient client = new CheckedCkanClient(ckanPortalUrl, apiKey);
CkanResource createdRes = client.createResource(resource); resource.setDescription(htmlRend.toString());
resource.setUrl(resourceBean.getUrl());
if(createdRes != null){ resource.setOwner(owner);
logger.info("Resource " + createdRes.getName() + " is now available"); // Checked client
return true; CheckedCkanClient client = new CheckedCkanClient(ckanPortalUrl, apiKey);
CkanResource createdRes = client.createResource(resource);
}
if(createdRes != null){
logger.debug("Resource " + createdRes.getName() + " is now available");
// set its id and turn it to the client
resourceBean.setId(createdRes.getId());
return resourceBean;
}
}catch(Exception e){ }catch(Exception e){
logger.error("Unable to create new resource", e); logger.error("Unable to create new resource", e);
} }
} }
logger.info("No resource created"); logger.debug("No resource created");
return null;
}
@Override
public boolean deleteResourceFromDataset(ResourceBean resource,
String owner) {
logger.debug("Request for deleting resource " + resource);
try{
// retrieve ckan's catalog url
String ckanPortalUrl = getCatalogueUrl();
// retrieve the api key for this user
String apiKey = getCKANApikeyFromUser(owner);
// Checked client
CheckedCkanClient client = new CheckedCkanClient(ckanPortalUrl, apiKey);
client.deleteResource(resource.getId());
return true;
}catch(Exception e){
logger.error("Unable to delete such resource", e);
}
return false; return false;
} }
} }

View File

@ -4,6 +4,8 @@ import java.io.Serializable;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.gcube.datacatalogue.ckanutillibrary.models.MetaDataBean;
/** /**
* This bean will contain during ckan metadata creation the following information * This bean will contain during ckan metadata creation the following information
* (related to the workspace folder that represents a dataset) * (related to the workspace folder that represents a dataset)
@ -19,6 +21,7 @@ import java.util.Map;
* <li> custom fields -> gcube items <key, value> couple * <li> custom fields -> gcube items <key, value> couple
* <li> organizationsList -> list of organizations to which the user belong (and in which * <li> organizationsList -> list of organizations to which the user belong (and in which
* he wants to publish) * he wants to publish)
* <li> list of metadata, that is custom fields per vre
* </ul> * </ul>
* @author Costantino Perciante at ISTI-CNR * @author Costantino Perciante at ISTI-CNR
* (costantino.perciante@isti.cnr.it) * (costantino.perciante@isti.cnr.it)
@ -39,11 +42,12 @@ public class DatasetMetadataBean implements Serializable {
private String authorEmail; // folder's email owner private String authorEmail; // folder's email owner
private String maintainer; private String maintainer;
private String maintainerEmail; private String maintainerEmail;
private String ownerFolderInWorkspace; // owner of the folder into the workspace private String ownerIdentifier; // owner of the folder into the workspace (e.g., andrea.rossi)
private List<String> organizationList; // list of organization in which the user is present and could create the dataset private List<String> organizationList; // list of organization in which the user is present and could create the dataset
private String selectedOrganization; private String selectedOrganization;
private List<String> resourcesIds; // in case of workspace, this is the list of children's ids private List<String> resourcesIds; // in case of workspace, this is the list of children's ids
private boolean addResources; // if true, add these files as resources to the dataset private boolean addResources; // if true, add these files as resources to the dataset
private List<MetaDataBean> metadataList;
public DatasetMetadataBean(){ public DatasetMetadataBean(){
super(); super();
@ -63,17 +67,21 @@ public class DatasetMetadataBean implements Serializable {
* @param authorEmail * @param authorEmail
* @param maintainer * @param maintainer
* @param maintainerEmail * @param maintainerEmail
* @param ownerFolderInWorkspace * @param ownerIdentifier
* @param organizationList * @param organizationList
* @param selectedOrganization * @param selectedOrganization
* @param resourcesIds
* @param addResources
* @param metadataList
*/ */
public DatasetMetadataBean(String id, String title, String description, public DatasetMetadataBean(String id, String title, String description,
Map<String, String> customFields, List<String> tags, Map<String, String> customFields, List<String> tags,
String license, boolean visibility, String license, boolean visibility, String source, long version,
String source, long version, String author, String authorEmail, String author, String authorEmail, String maintainer,
String maintainer, String maintainerEmail, String maintainerEmail, String ownerIdentifier,
String ownerFolderInWorkspace, List<String> organizationList, List<String> organizationList, String selectedOrganization,
String selectedOrganization) { List<String> resourcesIds, boolean addResources,
List<MetaDataBean> metadataList) {
super(); super();
this.id = id; this.id = id;
this.title = title; this.title = title;
@ -88,9 +96,20 @@ public class DatasetMetadataBean implements Serializable {
this.authorEmail = authorEmail; this.authorEmail = authorEmail;
this.maintainer = maintainer; this.maintainer = maintainer;
this.maintainerEmail = maintainerEmail; this.maintainerEmail = maintainerEmail;
this.ownerFolderInWorkspace = ownerFolderInWorkspace; this.ownerIdentifier = ownerIdentifier;
this.organizationList = organizationList; this.organizationList = organizationList;
this.selectedOrganization = selectedOrganization; this.selectedOrganization = selectedOrganization;
this.resourcesIds = resourcesIds;
this.addResources = addResources;
this.metadataList = metadataList;
}
public List<MetaDataBean> getMetadataList() {
return metadataList;
}
public void setMetadataList(List<MetaDataBean> metadataList) {
this.metadataList = metadataList;
} }
public String getId() { public String getId() {
@ -101,12 +120,12 @@ public class DatasetMetadataBean implements Serializable {
this.id = id; this.id = id;
} }
public void setOwnerFolderInWorkspace(String ownerFolderInWorkspace) { public String getOwnerIdentifier() {
this.ownerFolderInWorkspace = ownerFolderInWorkspace; return ownerIdentifier;
} }
public String getOwnerFolderInWorkspace(){ public void setOwnerIdentifier(String ownerIdentifier) {
return ownerFolderInWorkspace; this.ownerIdentifier = ownerIdentifier;
} }
public String getTitle() { public String getTitle() {
@ -242,14 +261,14 @@ public class DatasetMetadataBean implements Serializable {
return "DatasetMetadataBean [id=" + id + ", title=" + title return "DatasetMetadataBean [id=" + id + ", title=" + title
+ ", description=" + description + ", customFields=" + ", description=" + description + ", customFields="
+ customFields + ", tags=" + tags + ", license=" + license + customFields + ", tags=" + tags + ", license=" + license
+ ", visibility=" + visibility + ", visibility=" + visibility + ", source=" + source
+ ", source=" + source + ", version=" + version + ", author=" + ", version=" + version + ", author=" + author
+ author + ", authorEmail=" + authorEmail + ", maintainer=" + ", authorEmail=" + authorEmail + ", maintainer=" + maintainer
+ maintainer + ", maintainerEmail=" + maintainerEmail + ", maintainerEmail=" + maintainerEmail + ", ownerIdentifier="
+ ", ownerFolderInWorkspace=" + ownerFolderInWorkspace + ownerIdentifier + ", organizationList=" + organizationList
+ ", organizationList=" + organizationList
+ ", selectedOrganization=" + selectedOrganization + ", selectedOrganization=" + selectedOrganization
+ ", resourcesIds=" + resourcesIds + ", addResources=" + ", resourcesIds=" + resourcesIds + ", addResources="
+ addResources + "]"; + addResources + ", metadataList=" + metadataList + "]";
} }
} }

View File

@ -10,7 +10,7 @@
<set-property name="bootstrap.responsiveDesign" value="true" /> <set-property name="bootstrap.responsiveDesign" value="true" />
<inherits name='org.gcube.portlets.user.gcubewidgets.WidgetFactory' /> <inherits name='org.gcube.portlets.user.gcubewidgets.WidgetFactory' />
<!-- Specify the app entry point class. --> <!-- Specify the app entry point class. -->
<entry-point <entry-point
class='org.gcube.portlets.widgets.ckandatapublisherwidget.client.CKanMetadataPublisher' /> class='org.gcube.portlets.widgets.ckandatapublisherwidget.client.CKanMetadataPublisher' />

View File

@ -5,8 +5,6 @@
<link type="text/css" rel="stylesheet" href="CKanMetadataPublisher.css"> <link type="text/css" rel="stylesheet" href="CKanMetadataPublisher.css">
<script type="text/javascript" <script type="text/javascript"
src="CKanMetadataPublisher/CKanMetadataPublisher.nocache.js"></script> src="CKanMetadataPublisher/CKanMetadataPublisher.nocache.js"></script>
<script type="text/javascript"
src="/js/showdown.js"></script>
</head> </head>
<body> <body>

View File

@ -1,325 +0,0 @@
/**
* Created by Tivie on 06-01-2015.
*/
// Private properties
var showdown = {},
parsers = {},
extensions = {},
globalOptions = getDefaultOpts(true),
flavor = {
github: {
omitExtraWLInCodeBlocks: true,
prefixHeaderId: 'user-content-',
simplifiedAutoLink: true,
literalMidWordUnderscores: true,
strikethrough: true,
tables: true,
tablesHeaderId: true,
ghCodeBlocks: true,
tasklists: true
},
vanilla: getDefaultOpts(true)
};
/**
* helper namespace
* @type {{}}
*/
showdown.helper = {};
/**
* TODO LEGACY SUPPORT CODE
* @type {{}}
*/
showdown.extensions = {};
/**
* Set a global option
* @static
* @param {string} key
* @param {*} value
* @returns {showdown}
*/
showdown.setOption = function (key, value) {
'use strict';
globalOptions[key] = value;
return this;
};
/**
* Get a global option
* @static
* @param {string} key
* @returns {*}
*/
showdown.getOption = function (key) {
'use strict';
return globalOptions[key];
};
/**
* Get the global options
* @static
* @returns {{}}
*/
showdown.getOptions = function () {
'use strict';
return globalOptions;
};
/**
* Reset global options to the default values
* @static
*/
showdown.resetOptions = function () {
'use strict';
globalOptions = getDefaultOpts(true);
};
/**
* Set the flavor showdown should use as default
* @param {string} name
*/
showdown.setFlavor = function (name) {
'use strict';
if (flavor.hasOwnProperty(name)) {
var preset = flavor[name];
for (var option in preset) {
if (preset.hasOwnProperty(option)) {
globalOptions[option] = preset[option];
}
}
}
};
/**
* Get the default options
* @static
* @param {boolean} [simple=true]
* @returns {{}}
*/
showdown.getDefaultOptions = function (simple) {
'use strict';
return getDefaultOpts(simple);
};
/**
* Get or set a subParser
*
* subParser(name) - Get a registered subParser
* subParser(name, func) - Register a subParser
* @static
* @param {string} name
* @param {function} [func]
* @returns {*}
*/
showdown.subParser = function (name, func) {
'use strict';
if (showdown.helper.isString(name)) {
if (typeof func !== 'undefined') {
parsers[name] = func;
} else {
if (parsers.hasOwnProperty(name)) {
return parsers[name];
} else {
throw Error('SubParser named ' + name + ' not registered!');
}
}
}
};
/**
* Gets or registers an extension
* @static
* @param {string} name
* @param {object|function=} ext
* @returns {*}
*/
showdown.extension = function (name, ext) {
'use strict';
if (!showdown.helper.isString(name)) {
throw Error('Extension \'name\' must be a string');
}
name = showdown.helper.stdExtName(name);
// Getter
if (showdown.helper.isUndefined(ext)) {
if (!extensions.hasOwnProperty(name)) {
throw Error('Extension named ' + name + ' is not registered!');
}
return extensions[name];
// Setter
} else {
// Expand extension if it's wrapped in a function
if (typeof ext === 'function') {
ext = ext();
}
// Ensure extension is an array
if (!showdown.helper.isArray(ext)) {
ext = [ext];
}
var validExtension = validate(ext, name);
if (validExtension.valid) {
extensions[name] = ext;
} else {
throw Error(validExtension.error);
}
}
};
/**
* Gets all extensions registered
* @returns {{}}
*/
showdown.getAllExtensions = function () {
'use strict';
return extensions;
};
/**
* Remove an extension
* @param {string} name
*/
showdown.removeExtension = function (name) {
'use strict';
delete extensions[name];
};
/**
* Removes all extensions
*/
showdown.resetExtensions = function () {
'use strict';
extensions = {};
};
/**
* Validate extension
* @param {array} extension
* @param {string} name
* @returns {{valid: boolean, error: string}}
*/
function validate(extension, name) {
'use strict';
var errMsg = (name) ? 'Error in ' + name + ' extension->' : 'Error in unnamed extension',
ret = {
valid: true,
error: ''
};
if (!showdown.helper.isArray(extension)) {
extension = [extension];
}
for (var i = 0; i < extension.length; ++i) {
var baseMsg = errMsg + ' sub-extension ' + i + ': ',
ext = extension[i];
if (typeof ext !== 'object') {
ret.valid = false;
ret.error = baseMsg + 'must be an object, but ' + typeof ext + ' given';
return ret;
}
if (!showdown.helper.isString(ext.type)) {
ret.valid = false;
ret.error = baseMsg + 'property "type" must be a string, but ' + typeof ext.type + ' given';
return ret;
}
var type = ext.type = ext.type.toLowerCase();
// normalize extension type
if (type === 'language') {
type = ext.type = 'lang';
}
if (type === 'html') {
type = ext.type = 'output';
}
if (type !== 'lang' && type !== 'output' && type !== 'listener') {
ret.valid = false;
ret.error = baseMsg + 'type ' + type + ' is not recognized. Valid values: "lang/language", "output/html" or "listener"';
return ret;
}
if (type === 'listener') {
if (showdown.helper.isUndefined(ext.listeners)) {
ret.valid = false;
ret.error = baseMsg + '. Extensions of type "listener" must have a property called "listeners"';
return ret;
}
} else {
if (showdown.helper.isUndefined(ext.filter) && showdown.helper.isUndefined(ext.regex)) {
ret.valid = false;
ret.error = baseMsg + type + ' extensions must define either a "regex" property or a "filter" method';
return ret;
}
}
if (ext.listeners) {
if (typeof ext.listeners !== 'object') {
ret.valid = false;
ret.error = baseMsg + '"listeners" property must be an object but ' + typeof ext.listeners + ' given';
return ret;
}
for (var ln in ext.listeners) {
if (ext.listeners.hasOwnProperty(ln)) {
if (typeof ext.listeners[ln] !== 'function') {
ret.valid = false;
ret.error = baseMsg + '"listeners" property must be an hash of [event name]: [callback]. listeners.' + ln +
' must be a function but ' + typeof ext.listeners[ln] + ' given';
return ret;
}
}
}
}
if (ext.filter) {
if (typeof ext.filter !== 'function') {
ret.valid = false;
ret.error = baseMsg + '"filter" must be a function, but ' + typeof ext.filter + ' given';
return ret;
}
} else if (ext.regex) {
if (showdown.helper.isString(ext.regex)) {
ext.regex = new RegExp(ext.regex, 'g');
}
if (!ext.regex instanceof RegExp) {
ret.valid = false;
ret.error = baseMsg + '"regex" property must either be a string or a RegExp object, but ' + typeof ext.regex + ' given';
return ret;
}
if (showdown.helper.isUndefined(ext.replace)) {
ret.valid = false;
ret.error = baseMsg + '"regex" extensions must implement a replace string or function';
return ret;
}
}
}
return ret;
}
/**
* Validate extension
* @param {object} ext
* @returns {boolean}
*/
showdown.validateExtension = function (ext) {
'use strict';
var validateExtension = validate(ext, null);
if (!validateExtension.valid) {
console.warn(validateExtension.error);
return false;
}
return true;
};