added ClientScopeHandler to help prevent the back button cache problem in Chrome and Firefox

git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/portlets/user/gcube-widgets@102008 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Massimiliano Assante 2014-12-12 10:31:41 +00:00
parent 737c38d540
commit 51643740d0
14 changed files with 1405 additions and 24 deletions

View File

@ -12,16 +12,17 @@
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes> <attributes>
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>
<attribute name="org.eclipse.jst.component.nondependency" value=""/> <attribute name="org.eclipse.jst.component.nondependency" value=""/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="con" path="com.google.gwt.eclipse.core.GWT_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="war/WEB-INF/classes"/> <classpathentry kind="output" path="war/WEB-INF/classes"/>
</classpath> </classpath>

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,3 @@
#Tue Dec 18 15:14:11 CET 2012
eclipse.preferences.version=1 eclipse.preferences.version=1
entryPointModules= entryPointModules=
filesCopiedToWebInfLib= filesCopiedToWebInfLib=

View File

@ -1,4 +1,7 @@
<ReleaseNotes> <ReleaseNotes>
<Changeset component="org.gcube.portlets.user.gcube-widgets.1-9-0" date="2014-12-13">
<Change>Added Client scope handler, to set the scope from the client and help preventing the browser back button cache problem</Change>
</Changeset>
<Changeset component="org.gcube.portlets.user.gcube-widgets.1-7-0" date="2013-10-21"> <Changeset component="org.gcube.portlets.user.gcube-widgets.1-7-0" date="2013-10-21">
<Change>Ported to GWT 2.5.1</Change> <Change>Ported to GWT 2.5.1</Change>
</Changeset> </Changeset>

44
pom.xml
View File

@ -10,7 +10,7 @@
<groupId>org.gcube.portlets.user</groupId> <groupId>org.gcube.portlets.user</groupId>
<artifactId>gcube-widgets</artifactId> <artifactId>gcube-widgets</artifactId>
<version>1.8.0-SNAPSHOT</version> <version>1.9.0-SNAPSHOT</version>
<name>gCube Widgets Library</name> <name>gCube Widgets Library</name>
<description> <description>
gCube Widgets Library News Widget is a GWT Widget that can be used to uniform the Look and Feel for gCube Portlets using plain GWT.It also provides some out of the box widget to use. gCube Widgets Library News Widget is a GWT Widget that can be used to uniform the Look and Feel for gCube Portlets using plain GWT.It also provides some out of the box widget to use.
@ -32,15 +32,47 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties> </properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.gcube.distribution</groupId>
<artifactId>maven-portal-bom</artifactId>
<version>LATEST</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies> <dependencies>
<!-- Google Web Toolkit (GWT) --> <!-- Google Web Toolkit (GWT) -->
<dependency> <dependency>
<groupId>com.google.gwt</groupId> <groupId>com.google.gwt</groupId>
<artifactId>gwt-user</artifactId> <artifactId>gwt-user</artifactId>
<version>${gwtVersion}</version>
<!-- "provided" so that we don't deploy -->
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>org.gcube.applicationsupportlayer</groupId>
<artifactId>aslcore</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.liferay.portal</groupId>
<artifactId>portal-service</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.gcube.common.portal</groupId>
<artifactId>portal-manager</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>
<resources> <resources>
@ -140,12 +172,12 @@
<executions> <executions>
<execution> <execution>
<goals> <goals>
<!-- <goal>compile</goal> --> <!-- <goal>compile</goal> -->
<!-- <goal>test</goal> --> <!-- <goal>test</goal> -->
</goals> </goals>
</execution> </execution>
</executions> </executions>
<configuration> <configuration>
</configuration> </configuration>
</plugin> </plugin>
</plugins> </plugins>

View File

@ -0,0 +1,13 @@
package org.gcube.portlets.user.gcubewidgets.client;
import org.gcube.portlets.user.gcubewidgets.client.rpc.ScopeService;
import org.gcube.portlets.user.gcubewidgets.client.rpc.ScopeServiceAsync;
import com.google.gwt.core.client.GWT;
public class ClientScopeHelper {
public static ScopeServiceAsync getService() {
return GWT.create(ScopeService.class);
//Window.Location.getHref();
}
}

View File

@ -6,6 +6,8 @@ import com.google.gwt.core.client.EntryPoint;
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.user.client.Command; import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Window.Location;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.Image;
@ -24,8 +26,22 @@ public class WidgetFactory implements EntryPoint {
* This is the entry point method. * This is the entry point method.
*/ */
public void onModuleLoad() { public void onModuleLoad() {
//showSample(); //showSample2();
} }
private void showSample2() {
ClientScopeHelper.getService().setScope(Location.getHref(), new AsyncCallback<Boolean>() {
@Override
public void onSuccess(Boolean result) {
}
@Override
public void onFailure(Throwable caught) {
}
});
}
private void showSample() { private void showSample() {
// //

View File

@ -0,0 +1,12 @@
package org.gcube.portlets.user.gcubewidgets.client.rpc;
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
/**
* The client side stub for the RPC service.
*/
@RemoteServiceRelativePath("scopeService")
public interface ScopeService extends RemoteService {
boolean setScope(String portalURL);
}

View File

@ -0,0 +1,14 @@
package org.gcube.portlets.user.gcubewidgets.client.rpc;
import com.google.gwt.user.client.rpc.AsyncCallback;
/**
* The async counterpart of <code>ScopeService</code>.
*/
public interface ScopeServiceAsync {
void setScope(String portalURL, AsyncCallback<Boolean> callback);
}

View File

@ -0,0 +1,125 @@
package org.gcube.portlets.user.gcubewidgets.server;
import java.util.List;
import javax.servlet.http.HttpSession;
import org.gcube.application.framework.core.session.ASLSession;
import org.gcube.application.framework.core.session.SessionManager;
import org.gcube.common.portal.PortalContext;
import org.gcube.portlets.user.gcubewidgets.client.rpc.ScopeService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.model.Group;
import com.liferay.portal.model.Organization;
import com.liferay.portal.service.GroupLocalServiceUtil;
import com.liferay.portal.service.OrganizationLocalServiceUtil;
@SuppressWarnings("serial")
public class ScopeServiceImpl extends RemoteServiceServlet implements ScopeService {
private static final Logger _log = LoggerFactory.getLogger(ScopeServiceImpl.class);
@Override
public boolean setScope(String portalURL) {
String friendlyURL = extractOrgFriendlyURL(portalURL);
if (friendlyURL == null) //the URL is not a portal URL, we are in devmode.
return true;
else {
try {
List<Group> groups = GroupLocalServiceUtil.getGroups(0, GroupLocalServiceUtil.getGroupsCount());
for (Group g : groups) {
if (g.isOrganization() || g.isCommunity())
if (g.getFriendlyURL().compareTo(friendlyURL) == 0) {
setScope(g);
return true;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
return false;
}
private void setScope(Group currentGroup) throws Exception {
String scopeToSet = buildScope(currentGroup);
getASLSession().setScope(scopeToSet);
}
public static String buildScope(Group currentGroup) throws Exception {
String scopeToSet = "";
Organization curOrg = null;
// the group MUST BE an Organization
if (currentGroup.isOrganization()) {
long organizationId = currentGroup.getClassPK();
curOrg = OrganizationLocalServiceUtil.getOrganization(organizationId);
if (curOrg.isRoot()) {
scopeToSet = "/"+curOrg.getName();
} else if (isVO(curOrg)) {
scopeToSet = "/"+curOrg.getParentOrganization().getName()+"/"+curOrg.getName();
} else { //is a VRE
Organization vo = curOrg.getParentOrganization();
scopeToSet = "/"+vo.getParentOrganization().getName()+"/"+vo.getName()+"/"+curOrg.getName();
}
} else { //
scopeToSet = "PORTAL";
_log.info("Not an organization, scopeToSet set to PORTAL");
}
if (curOrg == null) {
String rootVO = getRootConfigFromGCore();
_log.info("CONTEXT INITIALIZED CORRECTLY From Client, setting rootvo as scope: " + rootVO);
scopeToSet = "/"+rootVO;
}
return scopeToSet;
}
public static boolean isVO(Organization currentOrg) throws PortalException, SystemException {
return (currentOrg.getParentOrganization().getParentOrganization() == null);
}
public static String getRootConfigFromGCore() {
return PortalContext.getConfiguration().getInfrastructureName();
}
public static String extractOrgFriendlyURL(String portalURL) {
String groupRegEx = "/group/";
if (portalURL.contains(groupRegEx)) {
_log.debug("LIFERAY PORTAL DETECTED");
String[] splits = portalURL.split(groupRegEx);
String friendlyURL = splits[1];
if (friendlyURL.contains("/")) {
friendlyURL = friendlyURL.split("/")[0];
} else {
friendlyURL = friendlyURL.split("\\?")[0].split("\\#")[0];
}
_log.trace("extracted friendly url: /" + friendlyURL);
return "/"+friendlyURL;
}
return null;
}
private ASLSession getASLSession() {
HttpSession httpSession = this.getThreadLocalRequest().getSession();
String sessionID = httpSession.getId();
String user = (String) httpSession.getAttribute("username");
if (user == null) {
_log.warn("NO USER FOUND, exiting");
return null;
}
else {
_log.info("Found user=" + user);
}
return SessionManager.getInstance().getASLSession(sessionID, user);
}
}

View File

@ -0,0 +1,2 @@
serviceClass: org.gcube.portlets.user.gcubewidgets.client.rpc.ScopeService
path: 3FEEA6DE1884937257328F4A621F9992.gwt.rpc

View File

@ -4,8 +4,18 @@
"http://java.sun.com/dtd/web-app_2_3.dtd"> "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app> <web-app>
<welcome-file-list> <!-- Servlets -->
<welcome-file>GuidedTour.html</welcome-file> <servlet>
</welcome-file-list> <servlet-name>scopeService</servlet-name>
<servlet-class>org.gcube.portlets.user.gcubewidgets.server.ScopeServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>scopeService</servlet-name>
<url-pattern>/gcubewidgets/scopeService</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>gcubeWidgets.html</welcome-file>
</welcome-file-list>
</web-app> </web-app>

View File

@ -0,0 +1,8 @@
com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException, true, true, true, true, com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException/3936916533, 3936916533
com.google.gwt.user.client.rpc.RpcTokenException, true, true, false, false, com.google.gwt.user.client.rpc.RpcTokenException/2345075298, 2345075298
com.google.gwt.user.client.rpc.XsrfToken, false, false, true, true, com.google.gwt.user.client.rpc.XsrfToken/4254043109, 4254043109
java.lang.Exception, true, false, true, false, java.lang.Exception/1920171873, 1920171873
java.lang.RuntimeException, true, false, true, false, java.lang.RuntimeException/515124647, 515124647
java.lang.String, true, true, true, true, java.lang.String/2004016611, 2004016611
java.lang.Throwable, true, false, true, false, java.lang.Throwable/2953622131, 2953622131
org.gcube.portlets.user.gcubewidgets.client.rpc.ScopeService, false, false, false, false, _, 2480143433

View File

@ -1,11 +1,13 @@
/** /**
* Common CSS for gCube Portlets * Common CSS for gCube Portlets
* *
* Massimiliano Assante, November 2013 */
*/ /****** PANELS STYLES *******/
@import url(old-dialog.css);
@import url(normalize.css); @import url(normalize.css);
/****** PANELS STYLES *******/
/* Use it for your portlet main Panel */ /* Use it for your portlet main Panel */
.gcube_panel { .gcube_panel {
background: #FFFFFF; background: #FFFFFF;
@ -280,13 +282,13 @@
.gcube_DialogBox { .gcube_DialogBox {
z-index: 10001; z-index: 10001;
background: #FFFFFF none repeat-x scroll 0 0; background: #FFFFFF none repeat-x scroll 0 0;
border: 2px solid #CCC; border: 5px solid #CCC;
border-radius: 4px; border-radius: 4px;
-moz-border-radius: 4px; -moz-border-radius: 4px;
-webkit-border-radius: 4px; -webkit-border-radius: 4px;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.80); box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.80);
-moz-box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.80); -moz-box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.80);
-webkit-box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.80); -webkit-box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.80);
} }
.gcube_DialogBox .Caption { .gcube_DialogBox .Caption {