almost finished: implemented client side and improved server side code

git-svn-id: http://svn.d4science-ii.research-infrastructures.eu/gcube/trunk/portlets/widgets/catalogue-sharing-widget@146508 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Costantino Perciante 2017-04-01 10:11:21 +00:00
parent abcabd68ba
commit 6d75e2931f
8 changed files with 273 additions and 123 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry including="**/*.java" kind="src" output="${webappDirectory}/WEB-INF/classes" path="src/main/java">
<classpathentry kind="src" output="${webappDirectory}/WEB-INF/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
@ -44,10 +44,11 @@
</classpathentry>
<classpathentry kind="lib" path="/home/costantino/Downloads/gwt-2.7.0/validation-api-1.0.0.GA-sources.jar"/>
<classpathentry kind="lib" path="/home/costantino/Downloads/gwt-2.7.0/validation-api-1.0.0.GA.jar" sourcepath="/home/costantino/Downloads/gwt-2.7.0/validation-api-1.0.0.GA-sources.jar"/>
<classpathentry excluding="**" kind="src" output="${webappDirectory}/WEB-INF/classes" path="src/main/resources">
<classpathentry kind="src" output="${webappDirectory}/WEB-INF/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="com.google.gwt.eclipse.core.GWT_CONTAINER"/>
<classpathentry kind="output" path="${webappDirectory}/WEB-INF/classes"/>
</classpath>

11
pom.xml
View File

@ -60,6 +60,12 @@
<artifactId>gwt-user</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.gcube.dvos</groupId>
<artifactId>usermanagement-core</artifactId>
<version>[2.0.0-SNAPSHOT,)</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.gcube.core</groupId>
<artifactId>common-scope-maps</artifactId>
@ -87,6 +93,11 @@
<version>[1.0.0-SNAPSHOT,2.0.0-SNAPSHOT)</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.github.gwtbootstrap</groupId>
<artifactId>gwt-bootstrap</artifactId>
<version>2.3.2.0</version>
</dependency>
<dependency>
<groupId>org.gcube.common.portal</groupId>
<artifactId>portal-manager</artifactId>

View File

@ -1,48 +1,93 @@
package org.gcube.portlets_widgets.catalogue_sharing_widget.client;
import org.gcube.portlets_widgets.catalogue_sharing_widget.shared.ItemUrls;
import com.github.gwtbootstrap.client.ui.AlertBlock;
import com.github.gwtbootstrap.client.ui.Form;
import com.github.gwtbootstrap.client.ui.Well;
import com.github.gwtbootstrap.client.ui.base.TextBox;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.Widget;
public class ShareCatalogueWidget extends Composite implements HasText {
public class ShareCatalogueWidget extends Composite {
private static ShareCatalogueWidgetUiBinder uiBinder = GWT
.create(ShareCatalogueWidgetUiBinder.class);
interface ShareCatalogueWidgetUiBinder extends
UiBinder<Widget, ShareCatalogueWidget> {
UiBinder<Widget, ShareCatalogueWidget> {
}
public ShareCatalogueWidget() {
initWidget(uiBinder.createAndBindUi(this));
}
public static final ShareServicesAsync ckanServices = GWT.create(ShareServices.class);
public static final String SERVICE_UNAVAILABLE = "The service is currently unavailable, retry later";
@UiField
Button button;
Well loadingIcon;
public ShareCatalogueWidget(String firstName) {
@UiField
AlertBlock errorBlock;
@UiField
Form formWithInformation;
@UiField
TextBox itemShortUrl;
@UiField
TextBox itemTitle;
@UiField
TextBox itemName;
@UiField
TextBox itemLongUrl;
public ShareCatalogueWidget(String itemUUID) {
initWidget(uiBinder.createAndBindUi(this));
button.setText(firstName);
ckanServices.getPackageUrl(itemUUID, new AsyncCallback<ItemUrls>() {
@Override
public void onSuccess(ItemUrls result) {
if(result == null){
onError(null);
}else{
loadingIcon.setVisible(false);
formWithInformation.setVisible(true);
itemShortUrl.setText(result.getShortUrl() == null ? "" : result.getShortUrl());
itemLongUrl.setText(result.getUrl() == null ? "" : result.getUrl());
itemTitle.setText(result.getProductTitle() == null ? "" : result.getProductTitle());
itemName.setText(result.getProductName() == null ? "" : result.getProductName());
}
}
@Override
public void onFailure(Throwable caught) {
onError(caught.getMessage());
}
});
}
@UiHandler("button")
void onClick(ClickEvent e) {
Window.alert("Hello!");
}
private void onError(String msg) {
public void setText(String text) {
button.setText(text);
}
loadingIcon.setVisible(false);
formWithInformation.setVisible(false);
errorBlock.setText(SERVICE_UNAVAILABLE + (msg == null ? "" : "(" + msg + ")"));
errorBlock.setVisible(true);
public String getText() {
return button.getText();
}
}

View File

@ -1,10 +1,53 @@
<!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:g="urn:import:com.google.gwt.user.client.ui" xmlns:b="urn:import:com.github.gwtbootstrap.client.ui">
<g:HTMLPanel>
<b:Modal ui:field="modalShareLink" title="Item's information"
backdrop="STATIC" keyboard="true" animation="true">
<div>
<b:Well size="LARGE" visible="true" ui:field="loadingIcon">
<b:Icon type="COG" size="FOUR_TIMES" aria-hidden="true"
alignment="CENTER" spin="true" />
</b:Well>
<!-- Alert blocks for info/errors -->
<b:AlertBlock type="ERROR" close="false" animation="true"
visible="false" ui:field="errorBlock"></b:AlertBlock>
<b:Form type="VERTICAL" ui:field="formWithInformation"
visible="false">
<b:Fieldset>
<b:ControlGroup>
<b:ControlLabel for="input01">Item's title:</b:ControlLabel>
<b:Controls>
<b:TextBox alternateSize="XLARGE" b:id="input01"
placeholder="Item's title" readOnly="true" ui:field="itemTitle"></b:TextBox>
</b:Controls>
</b:ControlGroup>
<b:ControlGroup>
<b:ControlLabel for="input04">Item's name:</b:ControlLabel>
<b:Controls>
<b:TextBox alternateSize="XLARGE" b:id="input04"
placeholder="Item's title" readOnly="true" ui:field="itemName"></b:TextBox>
</b:Controls>
</b:ControlGroup>
<b:ControlGroup>
<b:ControlLabel for="input02">Item's url:</b:ControlLabel>
<b:Controls>
<b:TextBox alternateSize="XLARGE" b:id="input02"
placeholder="Item's long url" readOnly="true" ui:field="itemLongUrl"></b:TextBox>
</b:Controls>
</b:ControlGroup>
<b:ControlGroup>
<b:ControlLabel for="input03">Item's short url:</b:ControlLabel>
<b:Controls>
<b:TextBox alternateSize="XLARGE" b:id="input03"
placeholder="Item's short url" readOnly="true" ui:field="itemShortUrl"></b:TextBox>
</b:Controls>
</b:ControlGroup>
</b:Fieldset>
</b:Form>
</div>
</b:Modal>
</g:HTMLPanel>
</ui:UiBinder>

View File

@ -0,0 +1,95 @@
package org.gcube.portlets_widgets.catalogue_sharing_widget.server;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.datacatalogue.ckanutillibrary.server.ApplicationProfileScopePerUrlReader;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
public class ServerUtils {
private static final Log logger = LogFactoryUtil.getLog(ServerUtils.class);
public static final String GCUBE_REQUEST_URL = "gcube-request-url";
/**
* Get the scope in which ckan information needs to be discovered from the url
* @param httpServletRequest
* @return
*/
public static String getScopeFromClientUrl(HttpServletRequest httpServletRequest){
if(httpServletRequest == null)
throw new IllegalArgumentException("HttpServletRequest is null!");
String scopeToReturn = null;
try{
String clientUrl = getCurrentClientUrl(httpServletRequest).split("\\?")[0];
logger.debug("Client url is " + clientUrl);
// check if this information is in session, otherwise set it and return
HttpSession session = httpServletRequest.getSession();
if((scopeToReturn = (String) session.getAttribute(clientUrl)) != null){
logger.debug("Scope to return is " + scopeToReturn);
}else{
// ask to the ckan library and set it
scopeToReturn = ApplicationProfileScopePerUrlReader.getScopePerUrl(clientUrl);
logger.debug("Scope to return is " + scopeToReturn);
session.setAttribute(clientUrl, scopeToReturn);
}
}catch(Exception e){
scopeToReturn = getCurrentContext(httpServletRequest, false);
logger.warn("Failed to determine the scope from the client url, returning the current one: " + scopeToReturn);
}
return scopeToReturn;
}
/**
* Retrieve the current scope by using the portal manager
* @param b
* @return a GcubeUser object
*/
public static String getCurrentContext(HttpServletRequest request, boolean setInThread){
if(request == null)
throw new IllegalArgumentException("HttpServletRequest is null!");
PortalContext pContext = PortalContext.getConfiguration();
String context = pContext.getCurrentScope(request);
logger.debug("Returning context " + context);
if(context != null && setInThread)
ScopeProvider.instance.set(context);
return context;
}
/**
* Needed to get the url of the client
* @param httpServletRequest the httpServletRequest object
* @return the instance of the user
* @see the url at client side
*/
public static String getCurrentClientUrl(HttpServletRequest httpServletRequest) {
if(httpServletRequest == null)
throw new IllegalArgumentException("HttpServletRequest is null!");
return httpServletRequest.getHeader(GCUBE_REQUEST_URL);
}
/**
* Needed to get the url of the client
* @param httpServletRequest the httpServletRequest object
* @return the instance of the user
* @see the url at client side
*/
public static String getUserInSession(HttpServletRequest httpServletRequest) {
return PortalContext.getConfiguration().getCurrentUser(httpServletRequest).getUsername();
}
}

View File

@ -1,11 +1,5 @@
package org.gcube.portlets_widgets.catalogue_sharing_widget.server;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.gcube.common.portal.PortalContext;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.datacatalogue.ckanutillibrary.server.ApplicationProfileScopePerUrlReader;
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogue;
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueFactory;
import org.gcube.portlets.user.urlshortener.UrlShortener;
@ -16,11 +10,12 @@ import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import eu.trentorise.opendata.jackan.model.CkanDataset;
public class ShareServicesImpl extends RemoteServiceServlet implements ShareServices{
private static final long serialVersionUID = -2060855544534802987L;
private static final Log logger = LogFactoryUtil.getLog(ShareServicesImpl.class);
public static final String GCUBE_REQUEST_URL = "gcube-request-url";
/**
* Retrieve an instance of the library for the scope
@ -30,7 +25,7 @@ public class ShareServicesImpl extends RemoteServiceServlet implements ShareServ
*/
public DataCatalogue getCatalogue(String scope) throws Exception{
String scopeInWhichDiscover = (scope != null && !scope.isEmpty()) ? scope : getCurrentContext(getThreadLocalRequest(), false);
String scopeInWhichDiscover = (scope != null && !scope.isEmpty()) ? scope : ServerUtils.getCurrentContext(getThreadLocalRequest(), false);
logger.debug("Discovering ckan instance into scope " + scopeInWhichDiscover);
return DataCatalogueFactory.getFactory().getUtilsPerScope(scopeInWhichDiscover);
@ -39,83 +34,23 @@ public class ShareServicesImpl extends RemoteServiceServlet implements ShareServ
@Override
public ItemUrls getPackageUrl(String uuid) throws Exception{
String scopePerCurrentUrl = getScopeFromClientUrl(getThreadLocalRequest());
String scopePerCurrentUrl = ServerUtils.getScopeFromClientUrl(getThreadLocalRequest());
DataCatalogue catalogue = getCatalogue(scopePerCurrentUrl);
CkanDataset dataset = catalogue.getDataset(uuid, catalogue.getApiKeyFromUsername(ServerUtils.getUserInSession(getThreadLocalRequest())));
String longUrl = catalogue.getUnencryptedUrlFromDatasetIdOrName(uuid);
if(longUrl == null || longUrl.isEmpty())
throw new Exception("There was a problem while retrieving the item's url, retry later");
String shortUrl = null;
UrlShortener shortener = new UrlShortener();
if(shortener!=null && shortener.isAvailable())
shortUrl = shortener.shorten(longUrl);
return new ItemUrls(shortUrl, longUrl, uuid);
}
else
logger.warn("Short url not available");
/**
* Get the scope in which ckan information needs to be discovered from the url
* @param httpServletRequest
* @return
*/
public static String getScopeFromClientUrl(HttpServletRequest httpServletRequest){
if(httpServletRequest == null)
throw new IllegalArgumentException("HttpServletRequest is null!");
String scopeToReturn = null;
try{
String clientUrl = getCurrentClientUrl(httpServletRequest).split("\\?")[0];
logger.debug("Client url is " + clientUrl);
// check if this information is in session, otherwise set it and return
HttpSession session = httpServletRequest.getSession();
if((scopeToReturn = (String) session.getAttribute(clientUrl)) != null){
logger.debug("Scope to return is " + scopeToReturn);
}else{
// ask to the ckan library and set it
scopeToReturn = ApplicationProfileScopePerUrlReader.getScopePerUrl(clientUrl);
logger.debug("Scope to return is " + scopeToReturn);
session.setAttribute(clientUrl, scopeToReturn);
}
}catch(Exception e){
scopeToReturn = getCurrentContext(httpServletRequest, false);
logger.warn("Failed to determine the scope from the client url, returning the current one: " + scopeToReturn);
}
return scopeToReturn;
}
/**
* Retrieve the current scope by using the portal manager
* @param b
* @return a GcubeUser object
*/
public static String getCurrentContext(HttpServletRequest request, boolean setInThread){
if(request == null)
throw new IllegalArgumentException("HttpServletRequest is null!");
PortalContext pContext = PortalContext.getConfiguration();
String context = pContext.getCurrentScope(request);
logger.debug("Returning context " + context);
if(context != null && setInThread)
ScopeProvider.instance.set(context);
return context;
}
/**
* Needed to get the url of the client
* @param httpServletRequest the httpServletRequest object
* @return the instance of the user
* @see the url at client side
*/
public static String getCurrentClientUrl(HttpServletRequest httpServletRequest) {
if(httpServletRequest == null)
throw new IllegalArgumentException("HttpServletRequest is null!");
return httpServletRequest.getHeader(GCUBE_REQUEST_URL);
return new ItemUrls(shortUrl, longUrl, uuid, dataset.getName(), dataset.getTitle());
}
}

View File

@ -13,8 +13,8 @@ public class ItemUrls implements Serializable {
private String shortUrl;
private String url;
private String catalogueUUID;
private String productName;
private String productTitle;
/**
*
@ -29,11 +29,13 @@ public class ItemUrls implements Serializable {
* @param url
* @param catalogueUUID
*/
public ItemUrls(String shortUrl, String url, String catalogueUUID) {
public ItemUrls(String shortUrl, String url, String catalogueUUID, String productName, String productTitle) {
super();
this.shortUrl = shortUrl;
this.url = url;
this.catalogueUUID = catalogueUUID;
this.productName = productName;
this.productTitle = productTitle;
}
public String getShortUrl() {
@ -60,9 +62,26 @@ public class ItemUrls implements Serializable {
this.catalogueUUID = catalogueUUID;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public String getProductTitle() {
return productTitle;
}
public void setProductTitle(String productTitle) {
this.productTitle = productTitle;
}
@Override
public String toString() {
return "ItemUrls [shortUrl=" + shortUrl + ", url=" + url
+ ", catalogueUUID=" + catalogueUUID + "]";
+ ", catalogueUUID=" + catalogueUUID + ", productName="
+ productName + ", productTitle=" + productTitle + "]";
}
}

View File

@ -1,22 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<module rename-to='ShareCatalogue'>
<!-- Inherit the core Web Toolkit stuff. -->
<inherits name='com.google.gwt.user.User' />
<!-- Inherit the core Web Toolkit stuff. -->
<inherits name='com.google.gwt.user.User' />
<!-- Inherit the default GWT style sheet. You can change -->
<!-- the theme of your GWT application by uncommenting -->
<!-- any one of the following lines. -->
<inherits name='com.google.gwt.user.theme.standard.Standard' />
<!-- <inherits name='com.google.gwt.user.theme.chrome.Chrome'/> -->
<!-- <inherits name='com.google.gwt.user.theme.dark.Dark'/> -->
<!-- Other module inherits -->
<inherits name="com.github.gwtbootstrap.Bootstrap" />
<!-- Other module inherits -->
<!-- Responsive design -->
<set-property name="bootstrap.responsiveDesign" value="true" />
<inherits name='org.gcube.datacatalogue.ckanutillibrary.CkanUtilLibrary' />
<!-- Specify the app entry point class. -->
<entry-point class='org.gcube.portlets_widgets.catalogue_sharing_widget.client.ShareCatalogue' />
<!-- Other module inherits -->
<!-- Specify the paths for translatable code -->
<source path='client' />
<source path='shared' />
<!-- Specify the app entry point class. -->
<entry-point
class='org.gcube.portlets_widgets.catalogue_sharing_widget.client.ShareCatalogue' />
<!-- Specify the paths for translatable code -->
<source path='client' />
<source path='shared' />
</module>