ready to release
git-svn-id: https://svn.research-infrastructures.eu/d4science/gcube/trunk/portlets/user/share-updates@68368 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
parent
1c16bf7897
commit
e041f7c313
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/share-updates-0.1.0-SNAPSHOT/WEB-INF/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" path="target/generated-sources/gwt"/>
|
||||
<classpathentry including="**/*.java" kind="src" output="src/main/webapp/WEB-INF/classes" path="src/main/resources"/>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry including="**/*.java" kind="src" output="target/test-classes" path="src/test/resources"/>
|
||||
<classpathentry kind="con" path="com.google.gwt.eclipse.core.GWT_CONTAINER"/>
|
||||
<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/share-updates-0.1.0-SNAPSHOT/WEB-INF/classes"/>
|
||||
</classpath>
|
|
@ -0,0 +1,59 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>share-updates</name>
|
||||
<comment>share-updates project</comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.common.project.facet.core.builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.validation.validationbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.maven.ide.eclipse.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.google.gdt.eclipse.core.webAppProjectValidator</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.google.gwt.eclipse.core.gwtProjectValidator</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
|
||||
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
|
||||
<nature>org.maven.ide.eclipse.maven2Nature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
|
||||
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
|
||||
<nature>com.google.gwt.eclipse.core.gwtNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src/main/webapp" />
|
||||
<classpathentry kind="con"
|
||||
path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER" />
|
||||
<classpathentry kind="con"
|
||||
path="org.eclipse.wst.jsdt.launching.WebProject">
|
||||
<attributes>
|
||||
<attribute name="hide" value="true" />
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con"
|
||||
path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary" />
|
||||
<classpathentry kind="output" path="" />
|
||||
</classpath>
|
|
@ -0,0 +1,3 @@
|
|||
#Thu Jun 16 10:18:26 CEST 2011
|
||||
eclipse.preferences.version=1
|
||||
filesCopiedToWebInfLib=
|
|
@ -0,0 +1,6 @@
|
|||
#Sat Jan 26 18:07:22 CET 2013
|
||||
eclipse.preferences.version=1
|
||||
jarsExcludedFromWebInfLib=
|
||||
lastWarOutDir=/Users/massi/Documents/workspace/share-updates/target/share-updates-0.1.0-SNAPSHOT
|
||||
warSrcDir=src/main/webapp
|
||||
warSrcDirIsOutput=false
|
|
@ -0,0 +1,5 @@
|
|||
#Thu Jun 16 11:14:17 CEST 2011
|
||||
eclipse.preferences.version=1
|
||||
entryPointModules=
|
||||
filesCopiedToWebInfLib=gwt-servlet.jar
|
||||
gwtCompileSettings=PGd3dC1jb21waWxlLXNldHRpbmdzPjxsb2ctbGV2ZWw+SU5GTzwvbG9nLWxldmVsPjxvdXRwdXQtc3R5bGU+T0JGVVNDQVRFRDwvb3V0cHV0LXN0eWxlPjxleHRyYS1hcmdzPjwhW0NEQVRBWy13YXIgc3JjL21haW4vd2ViYXBwXV0+PC9leHRyYS1hcmdzPjx2bS1hcmdzPjwhW0NEQVRBWy1YbXg1MTJtXV0+PC92bS1hcmdzPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLmNvbXBhbnkuU29tZU1vZHVsZTwvZW50cnktcG9pbnQtbW9kdWxlPjwvZ3d0LWNvbXBpbGUtc2V0dGluZ3M+
|
|
@ -0,0 +1,7 @@
|
|||
#Sat Jan 26 18:07:22 CET 2013
|
||||
eclipse.preferences.version=1
|
||||
encoding//src/main/java=UTF-8
|
||||
encoding//src/main/resources=UTF-8
|
||||
encoding//src/test/java=UTF-8
|
||||
encoding//src/test/resources=UTF-8
|
||||
encoding/<project>=UTF-8
|
|
@ -0,0 +1,9 @@
|
|||
#Thu Sep 02 10:42:20 CEST 2010
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
|
||||
org.eclipse.jdt.core.compiler.compliance=1.5
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.5
|
|
@ -0,0 +1,5 @@
|
|||
#Sat Jan 26 18:07:21 CET 2013
|
||||
activeProfiles=
|
||||
eclipse.preferences.version=1
|
||||
resolveWorkspaceProjects=true
|
||||
version=1
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project-modules id="moduleCoreId" project-version="1.5.0">
|
||||
<wb-module deploy-name="${module}">
|
||||
<wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
|
||||
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
|
||||
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
|
||||
<wb-resource deploy-path="/WEB-INF/classes" source-path="/target/generated-sources/gwt"/>
|
||||
<property name="java-output-path" value="/${module}/target/www/WEB-INF/classes"/>
|
||||
<property name="context-root" value="share-updates"/>
|
||||
</wb-module>
|
||||
</project-modules>
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<faceted-project>
|
||||
<fixed facet="wst.jsdt.web" />
|
||||
<installed facet="java" version="1.5" />
|
||||
<installed facet="jst.web" version="2.3" />
|
||||
<installed facet="wst.jsdt.web" version="1.0" />
|
||||
</faceted-project>
|
|
@ -0,0 +1 @@
|
|||
org.eclipse.wst.jsdt.launching.baseBrowserLibrary
|
|
@ -0,0 +1,9 @@
|
|||
#Thu Sep 02 10:42:12 CEST 2010
|
||||
activeProfiles=
|
||||
eclipse.preferences.version=1
|
||||
fullBuildGoals=process-test-resources
|
||||
includeModules=false
|
||||
resolveWorkspaceProjects=true
|
||||
resourceFilterGoals=process-resources resources\:testResources
|
||||
skipCompilerPlugin=true
|
||||
version=1
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="com.google.gwt.eclipse.core.launch.gwtJUnit">
|
||||
<stringAttribute key="com.google.gwt.eclipse.core.LOG_LEVEL" value="INFO"/>
|
||||
<booleanAttribute key="com.google.gwt.eclipse.core.NOT_HEADLESS" value="false"/>
|
||||
<stringAttribute key="com.google.gwt.eclipse.core.OUT_DIR" value="www-test"/>
|
||||
<booleanAttribute key="com.google.gwt.eclipse.core.STANDARDS_MODE" value="false"/>
|
||||
<stringAttribute key="com.google.gwt.eclipse.core.STYLE" value="OBFUSCATED"/>
|
||||
<stringAttribute key="com.google.gwt.eclipse.core.WEB_MODE" value="false"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/share-updates/src/test/java/org/gcube/portlets/user/shareupdates/client/GwtTestShareUpdates.java"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="1"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value=""/>
|
||||
<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
|
||||
<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gdt.eclipse.maven.mavenClasspathProvider"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.gcube.portlets.user.shareupdates.client.GwtTestShareUpdates"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="share-updates"/>
|
||||
</launchConfiguration>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="com.google.gwt.eclipse.core.launch.gwtJUnit">
|
||||
<stringAttribute key="com.google.gwt.eclipse.core.LOG_LEVEL" value="INFO"/>
|
||||
<booleanAttribute key="com.google.gwt.eclipse.core.NOT_HEADLESS" value="false"/>
|
||||
<stringAttribute key="com.google.gwt.eclipse.core.OUT_DIR" value="www-test"/>
|
||||
<booleanAttribute key="com.google.gwt.eclipse.core.STANDARDS_MODE" value="false"/>
|
||||
<stringAttribute key="com.google.gwt.eclipse.core.STYLE" value="OBFUSCATED"/>
|
||||
<stringAttribute key="com.google.gwt.eclipse.core.WEB_MODE" value="true"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/share-updates/src/test/java/org/gcube/portlets/user/shareupdates/client/GwtTestShareUpdates.java"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="1"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value=""/>
|
||||
<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
|
||||
<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gdt.eclipse.maven.mavenClasspathProvider"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.gcube.portlets.user.shareupdates.client.GwtTestShareUpdates"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="share-updates"/>
|
||||
</launchConfiguration>
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
gCube System - License
|
||||
------------------------------------------------------------
|
||||
|
||||
The gCube/gCore software is licensed as Free Open Source software conveying to the EUPL (http://ec.europa.eu/idabc/eupl).
|
||||
The software and documentation is provided by its authors/distributors "as is" and no expressed or
|
||||
implied warranty is given for its use, quality or fitness for a particular case.
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
Mantainers
|
||||
-------
|
||||
|
||||
* Massimiliano Assante (massimiliano.assante@isti.cnr.it), CNR Pisa,
|
||||
Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo".
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
The gCube System - Social Library
|
||||
------------------------------------------------------------
|
||||
|
||||
This work is partially funded by the European Commission in the
|
||||
context of the iMarine project (www.i-marine.eu), under the 1st call of FP7 IST priority.
|
||||
|
||||
Authors
|
||||
-------
|
||||
Massimiliano Assante
|
||||
*
|
||||
Version and Release Date
|
||||
------------------------
|
||||
Jan 2013
|
||||
|
||||
|
||||
Description
|
||||
-----------
|
||||
Social networking Library
|
||||
|
||||
Download information
|
||||
--------------------
|
||||
Source code is available from SVN:
|
||||
https://svn.d4science.research-infrastructures.eu/gcube/trunk/portlets/user/share-updates
|
||||
|
||||
Binaries can be downloaded from:
|
||||
http://maven.research-infrastructures.eu/nexus/index.html#welcome
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
Documentation is available on-line from the Projects Documentation Wiki:
|
||||
|
||||
Licensing
|
||||
---------
|
||||
|
||||
This software is licensed under the terms you may find in the file named "LICENSE" in this directory.
|
|
@ -0,0 +1,6 @@
|
|||
<ReleaseNotes>
|
||||
<Changeset component="org.gcube.portlets.user.shareupdates.0-1-0"
|
||||
date="2013-01-13">
|
||||
<Change>First Release</Change>
|
||||
</Changeset>
|
||||
</ReleaseNotes>
|
|
@ -0,0 +1,48 @@
|
|||
<assembly
|
||||
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
|
||||
<id>servicearchive</id>
|
||||
<formats>
|
||||
<format>tar.gz</format>
|
||||
</formats>
|
||||
<baseDirectory>/</baseDirectory>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>${distroDirectory}</directory>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<useDefaultExcludes>true</useDefaultExcludes>
|
||||
<includes>
|
||||
<include>README</include>
|
||||
<include>LICENSE</include>
|
||||
<include>INSTALL</include>
|
||||
<include>MAINTAINERS</include>
|
||||
<include>changelog.xml</include>
|
||||
</includes>
|
||||
<fileMode>755</fileMode>
|
||||
<filtered>true</filtered>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>target/apidocs</directory>
|
||||
<outputDirectory>/${artifactId}/doc/api</outputDirectory>
|
||||
<useDefaultExcludes>true</useDefaultExcludes>
|
||||
<fileMode>755</fileMode>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
<files>
|
||||
<file>
|
||||
<source>${distroDirectory}/profile.xml</source>
|
||||
<outputDirectory>./</outputDirectory>
|
||||
<filtered>true</filtered>
|
||||
</file>
|
||||
<file>
|
||||
<source>target/${build.finalName}.war</source>
|
||||
<outputDirectory>/${artifactId}</outputDirectory>
|
||||
</file>
|
||||
<file>
|
||||
<source>${distroDirectory}/svnpath.txt</source>
|
||||
<outputDirectory>/${artifactId}</outputDirectory>
|
||||
<filtered>true</filtered>
|
||||
</file>
|
||||
</files>
|
||||
</assembly>
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Resource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<ID></ID>
|
||||
<Type>Service</Type>
|
||||
<Profile>
|
||||
<Description>${description}</Description>
|
||||
<Class>PortletUser</Class>
|
||||
<Name>${artifactId}</Name>
|
||||
<Version>${version}</Version>
|
||||
<Packages>
|
||||
<Software>
|
||||
<Name>${artifactId}</Name>
|
||||
<Version>${version}</Version>
|
||||
<MavenCoordinates>
|
||||
<groupId>${groupId}</groupId>
|
||||
<artifactId>${artifactId}</artifactId>
|
||||
<version>${version}</version>
|
||||
</MavenCoordinates>
|
||||
<Files>
|
||||
<File>target/${build.finalName}.war</File>
|
||||
</Files>
|
||||
</Software>
|
||||
</Packages>
|
||||
</Profile>
|
||||
</Resource>
|
|
@ -0,0 +1 @@
|
|||
${scm.url}
|
|
@ -0,0 +1,281 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>maven-parent</artifactId>
|
||||
<groupId>org.gcube.tools</groupId>
|
||||
<version>1.0.0</version>
|
||||
<relativePath />
|
||||
</parent>
|
||||
|
||||
<groupId>org.gcube.portlets.user</groupId>
|
||||
<artifactId>share-updates</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
|
||||
<name>gCube Share Updates Portlet</name>
|
||||
<description>
|
||||
gCube Share Updates for exchanging updates with other users of VREs.
|
||||
</description>
|
||||
<scm>
|
||||
<connection>scm:svn:http://svn.d4science.research-infrastructures.eu/gcube/trunk/portlets/user/${project.artifactId}</connection>
|
||||
<developerConnection>scm:https://svn.d4science.research-infrastructures.eu/gcube/trunk/portlets/user/${project.artifactId}</developerConnection>
|
||||
<url>http://svn.d4science.research-infrastructures.eu/gcube/trunk/portlets/user/${project.artifactId}</url>
|
||||
</scm>
|
||||
<properties>
|
||||
<!-- Convenience property to set the GWT version -->
|
||||
<gwtVersion>2.4.0</gwtVersion>
|
||||
<distroDirectory>distro</distroDirectory>
|
||||
<!-- GWT needs at least java 1.6 -->
|
||||
<maven.compiler.source>1.6</maven.compiler.source>
|
||||
<maven.compiler.target>1.6</maven.compiler.target>
|
||||
<webappDirectory>${project.build.directory}/${project.build.finalName}</webappDirectory>
|
||||
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- This dependency is needed and is need on TOP to use GWT UI BInder
|
||||
without old Xerces version of gCore complaining -->
|
||||
<dependency>
|
||||
<groupId>xerces</groupId>
|
||||
<artifactId>xercesImpl</artifactId>
|
||||
<version>2.9.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.gwt</groupId>
|
||||
<artifactId>gwt-user</artifactId>
|
||||
<version>${gwtVersion}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.gwt</groupId>
|
||||
<artifactId>gwt-servlet</artifactId>
|
||||
<version>${gwtVersion}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<version>1.6.4</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.6.4</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sencha.gxt</groupId>
|
||||
<artifactId>gxt</artifactId>
|
||||
<version>2.2.5</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-validator</groupId>
|
||||
<artifactId>commons-validator</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.portal</groupId>
|
||||
<artifactId>social-networking-library</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.core</groupId>
|
||||
<artifactId>gcf</artifactId>
|
||||
<version>[1.4.0,1.6.0]</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.portlets.user</groupId>
|
||||
<artifactId>gcube-widgets</artifactId>
|
||||
<version>1.4.0-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.portal</groupId>
|
||||
<artifactId>custom-portal-handler</artifactId>
|
||||
<version>1.2.0-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.applicationsupportlayer</groupId>
|
||||
<artifactId>aslcore</artifactId>
|
||||
<version>3.2.0-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google</groupId>
|
||||
<artifactId>gwt-jsonmaker</artifactId>
|
||||
<version>1.2.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.htmlparser</groupId>
|
||||
<artifactId>htmllexer</artifactId>
|
||||
<version>2.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.htmlparser</groupId>
|
||||
<artifactId>htmlparser</artifactId>
|
||||
<version>2.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.htmlcleaner</groupId>
|
||||
<artifactId>htmlcleaner</artifactId>
|
||||
<version>2.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sf.jtidy</groupId>
|
||||
<artifactId>jtidy</artifactId>
|
||||
<version>r938</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.eliasbalasis</groupId>
|
||||
<artifactId>tibcopagebus4gwt</artifactId>
|
||||
<version>1.2.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.liferay.portal</groupId>
|
||||
<artifactId>portal-service</artifactId>
|
||||
<version>6.0.6</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.portlet</groupId>
|
||||
<artifactId>portlet-api</artifactId>
|
||||
<version>2.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.7</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
<version>1.0.0.GA</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
<version>1.0.0.GA</version>
|
||||
<classifier>sources</classifier>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<!-- Generate compiled stuff in the folder used for developing mode -->
|
||||
<outputDirectory>${webappDirectory}/WEB-INF/classes</outputDirectory>
|
||||
|
||||
<plugins>
|
||||
|
||||
<!-- GWT Maven Plugin -->
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>gwt-maven-plugin</artifactId>
|
||||
<version>2.4.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
<!-- <goal>test</goal> -->
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<!-- Plugin configuration. There are many available options, see gwt-maven-plugin
|
||||
documentation at codehaus.org -->
|
||||
<configuration>
|
||||
<runTarget>Messages.html</runTarget>
|
||||
<hostedWebapp>${webappDirectory}</hostedWebapp>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!-- Copy static web files before executing gwt:run -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>2.1.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>exploded</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<webappDirectory>${webappDirectory}</webappDirectory>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>2.3.2</version>
|
||||
<configuration>
|
||||
<source>1.5</source>
|
||||
<target>1.5</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- SA Plugin -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>2.2</version>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>${distroDirectory}/descriptor.xml</descriptor>
|
||||
</descriptors>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>servicearchive</id>
|
||||
<phase>install</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>2.5</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-profile</id>
|
||||
<phase>install</phase>
|
||||
<goals>
|
||||
<goal>copy-resources</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>target</outputDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>${distroDirectory}</directory>
|
||||
<filtering>true</filtering>
|
||||
<includes>
|
||||
<include>profile.xml</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,22 @@
|
|||
package org.gcube.portlets.user.shareupdates.client;
|
||||
|
||||
import org.gcube.portal.databook.shared.ClientFeed;
|
||||
import org.gcube.portal.databook.shared.FeedType;
|
||||
import org.gcube.portal.databook.shared.PrivacyLevel;
|
||||
import org.gcube.portal.databook.shared.UserInfo;
|
||||
import org.gcube.portlets.user.shareupdates.shared.LinkPreview;
|
||||
|
||||
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("shareupdateServlet")
|
||||
public interface ShareUpdateService extends RemoteService {
|
||||
ClientFeed share(String feedText, FeedType type, PrivacyLevel pLevel, String vreName, String linkTitle, String linkDesc, String url, String urlThumbnail, String host);
|
||||
|
||||
UserInfo getUserInfo();
|
||||
|
||||
LinkPreview checkLink(String linkToCheck);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package org.gcube.portlets.user.shareupdates.client;
|
||||
|
||||
import org.gcube.portal.databook.shared.ClientFeed;
|
||||
import org.gcube.portal.databook.shared.FeedType;
|
||||
import org.gcube.portal.databook.shared.PrivacyLevel;
|
||||
import org.gcube.portal.databook.shared.UserInfo;
|
||||
import org.gcube.portlets.user.shareupdates.shared.LinkPreview;
|
||||
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
|
||||
/**
|
||||
* The async counterpart of <code>ShareUpdateService</code>.
|
||||
*/
|
||||
public interface ShareUpdateServiceAsync {
|
||||
void share(String feedText, FeedType type, PrivacyLevel pLevel,
|
||||
String vreName, String linkTitle, String linkDesc, String url,
|
||||
String urlThumbnail, String host, AsyncCallback<ClientFeed> callback);
|
||||
void getUserInfo(AsyncCallback<UserInfo> callback);
|
||||
void checkLink(String linkToCheck, AsyncCallback<LinkPreview> callback);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package org.gcube.portlets.user.shareupdates.client;
|
||||
|
||||
import org.gcube.portlets.user.shareupdates.client.form.ShareUpdateForm;
|
||||
|
||||
import com.google.gwt.core.client.EntryPoint;
|
||||
import com.google.gwt.user.client.ui.RootPanel;
|
||||
|
||||
/**
|
||||
* Entry point classes define <code>onModuleLoad()</code>.
|
||||
*/
|
||||
public class ShareUpdates implements EntryPoint {
|
||||
|
||||
/**
|
||||
* This is the entry point method.
|
||||
*/
|
||||
public void onModuleLoad() {
|
||||
RootPanel.get("shareUpdateDiv").add(new ShareUpdateForm());
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
package org.gcube.portlets.user.shareupdates.client.form;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.ClickHandler;
|
||||
import com.google.gwt.uibinder.client.UiHandler;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.HTML;
|
||||
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
|
||||
import com.google.gwt.user.client.ui.HorizontalPanel;
|
||||
import com.google.gwt.user.client.ui.Image;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
|
||||
public class ImageSwitcher extends Composite{
|
||||
|
||||
private ArrayList<String> imageUrls;
|
||||
private VerticalPanel mainPanel = new VerticalPanel();
|
||||
private HorizontalPanel controlPanel = new HorizontalPanel();
|
||||
private Image image = new Image();
|
||||
private HTML prev = new HTML(" << ");
|
||||
private HTML label = new HTML("1 of 1");
|
||||
private HTML next = new HTML(" >> ");
|
||||
private int currentIndex = 0;
|
||||
|
||||
public ImageSwitcher() {
|
||||
super();
|
||||
image.setWidth("80px");
|
||||
mainPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
|
||||
mainPanel.setPixelSize(100, 100);
|
||||
mainPanel.add(image);
|
||||
|
||||
controlPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
|
||||
controlPanel.add(prev);
|
||||
controlPanel.add(label);
|
||||
controlPanel.add(next);
|
||||
|
||||
mainPanel.add(controlPanel);
|
||||
|
||||
prev.setStyleName("small-text-arrow");
|
||||
label.setStyleName("small-text");
|
||||
next.setStyleName("small-text-arrow");
|
||||
|
||||
|
||||
initWidget(mainPanel);
|
||||
|
||||
next.addClickHandler(new ClickHandler() {
|
||||
public void onClick(ClickEvent event) {
|
||||
if (imageUrls != null && currentIndex < imageUrls.size()) {
|
||||
currentIndex++;
|
||||
image.setUrl(imageUrls.get(currentIndex));
|
||||
label.setHTML((currentIndex+1)+" of " + imageUrls.size());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
prev.addClickHandler(new ClickHandler() {
|
||||
public void onClick(ClickEvent event) {
|
||||
if (imageUrls != null && currentIndex > 0) {
|
||||
currentIndex--;
|
||||
image.setUrl(imageUrls.get(currentIndex));
|
||||
label.setHTML((currentIndex+1)+" of " + imageUrls.size());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected void setImages(ArrayList<String> imageUrls) {
|
||||
this.imageUrls = imageUrls;
|
||||
if (imageUrls.size() == 0) {
|
||||
mainPanel.remove(controlPanel);
|
||||
return;
|
||||
}
|
||||
image.setUrl(imageUrls.get(0));
|
||||
GWT.log("images no. " + imageUrls.size());
|
||||
if (imageUrls.size() < 2) {
|
||||
prev.setVisible(false);
|
||||
next.setVisible(false);
|
||||
} else {
|
||||
enableSwitch(imageUrls);
|
||||
}
|
||||
}
|
||||
|
||||
private void enableSwitch(ArrayList<String> imageUrls) {
|
||||
label.setHTML("1 of " + imageUrls.size());
|
||||
currentIndex = 0;
|
||||
}
|
||||
|
||||
protected String getSelectedImageURL() {
|
||||
return image.getUrl();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package org.gcube.portlets.user.shareupdates.client.form;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
|
||||
public class LinkLoader extends Composite {
|
||||
|
||||
private static LinkLoaderUiBinder uiBinder = GWT
|
||||
.create(LinkLoaderUiBinder.class);
|
||||
|
||||
interface LinkLoaderUiBinder extends UiBinder<Widget, LinkLoader> {
|
||||
}
|
||||
|
||||
public LinkLoader() {
|
||||
initWidget(uiBinder.createAndBindUi(this));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<!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">
|
||||
|
||||
<g:HTMLPanel>
|
||||
<div style="width:600px; height:25px; text-align:center; margin-left: 5px;" class="image-loader"></div>
|
||||
</g:HTMLPanel>
|
||||
</ui:UiBinder>
|
|
@ -0,0 +1,11 @@
|
|||
package org.gcube.portlets.user.shareupdates.client.form;
|
||||
|
||||
import com.google.gwt.user.client.ui.SimplePanel;
|
||||
/**
|
||||
*
|
||||
* @author massi
|
||||
*
|
||||
*/
|
||||
public class LinkPlaceholder extends SimplePanel {
|
||||
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
package org.gcube.portlets.user.shareupdates.client.form;
|
||||
|
||||
import org.gcube.portlets.user.shareupdates.shared.LinkPreview;
|
||||
|
||||
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.ui.CheckBox;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.HTML;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
|
||||
public class LinkPreviewer extends Composite {
|
||||
|
||||
private static LinkPreviewUiBinder uiBinder = GWT
|
||||
.create(LinkPreviewUiBinder.class);
|
||||
|
||||
interface LinkPreviewUiBinder extends UiBinder<Widget, LinkPreviewer> {
|
||||
}
|
||||
|
||||
private ShareUpdateForm parent;
|
||||
|
||||
private LinkPreview toShow;
|
||||
|
||||
public LinkPreviewer(ShareUpdateForm parent, LinkPreview toShow) {
|
||||
initWidget(uiBinder.createAndBindUi(this));
|
||||
closeImage.setStyleName("su-closeImage");
|
||||
closeImage.setTitle("Cancel");
|
||||
this.parent = parent;
|
||||
this.toShow = toShow;
|
||||
|
||||
titleArea.setHTML("<a class=\"link\" target=\"_blank\" href=\"" + toShow.getUrl() + "\">"+toShow.getTitle()+"</a> <span style=\"color: #333;\"> - " + toShow.getHost() + "</span>");
|
||||
String url = toShow.getUrl();
|
||||
urlText.setHTML((url.length() > 80) ? url.substring(0, 80)+"..." : url);
|
||||
String desc = toShow.getDescription();
|
||||
descText.setHTML((desc.length() > 256) ? desc.substring(0, 256)+"..." : desc);
|
||||
switcher.setImages(toShow.getImageUrls());
|
||||
}
|
||||
|
||||
@UiField HTML closeImage;
|
||||
@UiField ImageSwitcher switcher;
|
||||
|
||||
@UiField
|
||||
HTML titleArea;
|
||||
@UiField
|
||||
HTML urlText;
|
||||
@UiField
|
||||
HTML descText;
|
||||
@UiField
|
||||
CheckBox hideCheckBox;
|
||||
|
||||
public ImageSwitcher getSwitcher() {
|
||||
return switcher;
|
||||
}
|
||||
|
||||
@UiHandler("closeImage")
|
||||
void onDeleteFeedClick(ClickEvent e) {
|
||||
parent.cancelPreview();
|
||||
}
|
||||
|
||||
@UiHandler("hideCheckBox")
|
||||
void onClick(ClickEvent e) {
|
||||
descText.setVisible(!hideCheckBox.getValue());
|
||||
}
|
||||
|
||||
public String getLinkTitle() {
|
||||
return toShow.getTitle();
|
||||
}
|
||||
public String getLinkDescription() {
|
||||
return hideCheckBox.getValue() ? "" : toShow.getDescription();
|
||||
}
|
||||
public String getUrl() {
|
||||
return toShow.getUrl();
|
||||
}
|
||||
public String getHost() {
|
||||
return toShow.getHost();
|
||||
}
|
||||
public String getUrlThumbnail() {
|
||||
return switcher.getSelectedImageURL();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<!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:m="urn:import:org.gcube.portlets.user.shareupdates.client.form">
|
||||
<ui:style>
|
||||
.important {
|
||||
font-weight: bold;
|
||||
}
|
||||
</ui:style>
|
||||
<g:HTMLPanel>
|
||||
<table class="link-previewer">
|
||||
<tr>
|
||||
<td width="60px;" align="middle">
|
||||
<m:ImageSwitcher ui:field="switcher"></m:ImageSwitcher>
|
||||
</td>
|
||||
<td width="100%" valign="TOP">
|
||||
<div class="link-title">
|
||||
<g:HTML styleName="" ui:field="titleArea" />
|
||||
</div>
|
||||
<div class="link-url">
|
||||
<g:HTML styleName="" ui:field="urlText" />
|
||||
</div>
|
||||
<div class="link-desc">
|
||||
<g:HTML styleName="" ui:field="descText" />
|
||||
<div class="hide-description">
|
||||
<g:CheckBox ui:field="hideCheckBox">Hide Description</g:CheckBox>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td valign="top" class="linkpreview-bgcolor">
|
||||
<g:HTML height="15px" width="15px" ui:field="closeImage"></g:HTML>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</g:HTMLPanel>
|
||||
</ui:UiBinder>
|
|
@ -0,0 +1,66 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.gcube.portlets.user.shareupdates.client.form;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.Element;
|
||||
import com.google.gwt.user.client.Event;
|
||||
import com.google.gwt.user.client.Timer;
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.google.gwt.user.client.ui.TextArea;
|
||||
|
||||
/**
|
||||
* @author massi
|
||||
*
|
||||
*/
|
||||
public class MyTextArea extends TextArea {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public MyTextArea() {
|
||||
sinkEvents(Event.ONPASTE);
|
||||
sinkEvents(Event.ONCONTEXTMENU);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param element
|
||||
*/
|
||||
public MyTextArea(Element element) {
|
||||
super(element);
|
||||
}
|
||||
|
||||
/**
|
||||
* paste event overridden
|
||||
*/
|
||||
public void onBrowserEvent(Event event) {
|
||||
super.onBrowserEvent(event);
|
||||
switch (event.getTypeInt()) {
|
||||
case Event.ONPASTE: {
|
||||
final String before = getText();
|
||||
GWT.log("BEFORE:" + before);
|
||||
Timer t = new Timer() {
|
||||
@Override
|
||||
public void run() {
|
||||
String toCheck = getText().replaceAll(before, "");
|
||||
ShareUpdateForm.get().checkLink(toCheck);
|
||||
}
|
||||
};
|
||||
t.schedule(100);
|
||||
break;
|
||||
}
|
||||
case Event.ONCONTEXTMENU: {
|
||||
removeSampleText();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
protected void removeSampleText() {
|
||||
if (getText().equals(ShareUpdateForm.SHARE_UPDATE_TEXT) || getText().equals(ShareUpdateForm.ERROR_UPDATE_TEXT) ) {
|
||||
setText("");
|
||||
addStyleName("dark-color");
|
||||
removeStyleName("error");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,295 @@
|
|||
package org.gcube.portlets.user.shareupdates.client.form;
|
||||
|
||||
import net.eliasbalasis.tibcopagebus4gwt.client.PageBusAdapter;
|
||||
import net.eliasbalasis.tibcopagebus4gwt.client.PageBusAdapterException;
|
||||
|
||||
import org.gcube.portal.databook.shared.ClientFeed;
|
||||
import org.gcube.portal.databook.shared.ClientFeed.ClientFeedJsonizer;
|
||||
import org.gcube.portal.databook.shared.FeedType;
|
||||
import org.gcube.portal.databook.shared.PrivacyLevel;
|
||||
import org.gcube.portal.databook.shared.UserInfo;
|
||||
import org.gcube.portlets.user.shareupdates.client.ShareUpdateService;
|
||||
import org.gcube.portlets.user.shareupdates.client.ShareUpdateServiceAsync;
|
||||
import org.gcube.portlets.user.shareupdates.shared.LinkPreview;
|
||||
import org.jsonmaker.gwt.client.Jsonizer;
|
||||
|
||||
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.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.ui.Button;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.Image;
|
||||
import com.google.gwt.user.client.ui.ListBox;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
/**
|
||||
*
|
||||
* @author Massimiliano Assante
|
||||
* @version 1.2 Nov 2012
|
||||
*
|
||||
*/
|
||||
public class ShareUpdateForm extends Composite {
|
||||
/**
|
||||
* Create a remote service proxy to talk to the server-side Greeting service.
|
||||
*/
|
||||
private final ShareUpdateServiceAsync shareupdateService = GWT
|
||||
.create(ShareUpdateService.class);
|
||||
|
||||
final PageBusAdapter pageBusAdapter = new PageBusAdapter();
|
||||
protected final static String SHARE_UPDATE_TEXT = "Share an update or paste a link";
|
||||
protected final static String ERROR_UPDATE_TEXT = "Looks like empty to me!";
|
||||
private final static String LISTBOX_LEVEL = " - ";
|
||||
|
||||
public static final String loading = GWT.getModuleBaseURL() + "../images/avatarLoader.gif";
|
||||
public static final String avatar_default = GWT.getModuleBaseURL() + "../images/Avatar_default.png";
|
||||
|
||||
private static ShareUpdateFormUiBinder uiBinder = GWT
|
||||
.create(ShareUpdateFormUiBinder.class);
|
||||
|
||||
private LinkPreviewer myLinkPreviewer;
|
||||
|
||||
interface ShareUpdateFormUiBinder extends UiBinder<Widget, ShareUpdateForm> {
|
||||
}
|
||||
|
||||
private static ShareUpdateForm singleton;
|
||||
|
||||
public static ShareUpdateForm get() {
|
||||
return singleton;
|
||||
}
|
||||
|
||||
|
||||
UserInfo myUserInfo;
|
||||
|
||||
public ShareUpdateForm() {
|
||||
initWidget(uiBinder.createAndBindUi(this));
|
||||
singleton = this;
|
||||
|
||||
avatarImage.setUrl(loading);
|
||||
shareTextArea.setText(SHARE_UPDATE_TEXT);
|
||||
shareupdateService.getUserInfo(new AsyncCallback<UserInfo>() {
|
||||
public void onFailure(Throwable caught) {
|
||||
avatarImage.setSize("60px", "60px");
|
||||
avatarImage.setUrl(avatar_default);
|
||||
}
|
||||
|
||||
public void onSuccess(UserInfo user) {
|
||||
myUserInfo = user;
|
||||
avatarImage.getElement().getParentElement().setAttribute("href", user.getAccountURL());
|
||||
avatarImage.setSize("60px", "60px");
|
||||
avatarImage.setUrl(user.getAvatarId());
|
||||
if (myUserInfo.getOwnVREs().size() > 1){
|
||||
privacyLevel.addItem("My VREs", PrivacyLevel.VRES.toString());
|
||||
for (String vreId : myUserInfo.getOwnVREs().keySet())
|
||||
privacyLevel.addItem(LISTBOX_LEVEL + myUserInfo.getOwnVREs().get(vreId), vreId);
|
||||
}
|
||||
else if (myUserInfo.getOwnVREs().size() == 1)
|
||||
for (String vreId : myUserInfo.getOwnVREs().keySet())
|
||||
privacyLevel.addItem(LISTBOX_LEVEL + myUserInfo.getOwnVREs().get(vreId), vreId);
|
||||
privacyLevel.addItem("My Connections", PrivacyLevel.CONNECTION.toString());
|
||||
if (user.isAdmin())
|
||||
privacyLevel.addItem("Anyone", PrivacyLevel.PORTAL.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
@UiField
|
||||
LinkPlaceholder preview;
|
||||
|
||||
@UiField
|
||||
Button submitButton;
|
||||
|
||||
@UiField
|
||||
Image avatarImage;
|
||||
|
||||
@UiField MyTextArea shareTextArea;
|
||||
|
||||
@UiField ListBox privacyLevel = new ListBox(false);
|
||||
|
||||
@UiHandler("shareTextArea")
|
||||
void onShareUpdateClick(ClickEvent e) {
|
||||
shareTextArea.removeSampleText();
|
||||
}
|
||||
|
||||
@UiHandler("submitButton")
|
||||
void onClick(ClickEvent e) {
|
||||
shareupdateService.getUserInfo(new AsyncCallback<UserInfo>() {
|
||||
public void onFailure(Throwable caught) {
|
||||
Window.alert("Ops! we encountered some problems delivering your message, server is not responding, please try again in a short while.");
|
||||
}
|
||||
public void onSuccess(UserInfo result) {
|
||||
if (result.getUsername().equals("test.user")) {
|
||||
Window.alert("Your session has expired, please log out and login again");
|
||||
return;
|
||||
}
|
||||
myUserInfo = result;
|
||||
String toShare = shareTextArea.getText().trim();
|
||||
if (toShare.equals(SHARE_UPDATE_TEXT) || toShare.equals(ERROR_UPDATE_TEXT) || toShare.equals("")) {
|
||||
shareTextArea.addStyleName("error");
|
||||
shareTextArea.setText(ERROR_UPDATE_TEXT);
|
||||
return;
|
||||
}
|
||||
//then you can post
|
||||
postTweet(toShare);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param textToPost
|
||||
*/
|
||||
private void postTweet(String textToPost) {
|
||||
String toShare = escapeHtml(textToPost);
|
||||
if (! checkTextLength(toShare)) {
|
||||
Window.alert("We found a single word containing more than 50 chars and it's not a link, is it meaningful?");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
submitButton.setEnabled(false);
|
||||
shareTextArea.setEnabled(false);
|
||||
|
||||
String vreId = "";
|
||||
if (getPrivacyLevel() == PrivacyLevel.SINGLE_VRE) {
|
||||
vreId = privacyLevel.getValue(privacyLevel.getSelectedIndex());
|
||||
}
|
||||
|
||||
String linkTitle = "";
|
||||
String linkDescription = "";
|
||||
String linkUrl = "";
|
||||
String linkUrlThumbnail = "";
|
||||
String linkHost = "";
|
||||
|
||||
if (myLinkPreviewer != null) {
|
||||
linkTitle = myLinkPreviewer.getLinkTitle();
|
||||
linkDescription = myLinkPreviewer.getLinkDescription();
|
||||
linkUrl = myLinkPreviewer.getUrl();
|
||||
linkUrlThumbnail = myLinkPreviewer.getUrlThumbnail();
|
||||
linkHost = myLinkPreviewer.getHost();
|
||||
}
|
||||
shareupdateService.share(toShare, FeedType.TWEET, getPrivacyLevel(), vreId, linkTitle, linkDescription, linkUrl, linkUrlThumbnail, linkHost, new AsyncCallback<ClientFeed>() {
|
||||
public void onFailure(Throwable caught) {
|
||||
submitButton.setEnabled(true);
|
||||
shareTextArea.setEnabled(true);
|
||||
shareTextArea.setText(SHARE_UPDATE_TEXT);
|
||||
preview.clear();
|
||||
myLinkPreviewer = null;
|
||||
}
|
||||
|
||||
public void onSuccess(ClientFeed feed) {
|
||||
submitButton.setEnabled(true);
|
||||
shareTextArea.setEnabled(true);
|
||||
shareTextArea.setText(SHARE_UPDATE_TEXT);
|
||||
preview.clear();
|
||||
myLinkPreviewer = null;
|
||||
if (feed == null)
|
||||
Window.alert("Ops! we encountered some problems delivering your message, please try again in a short while.");
|
||||
else {
|
||||
// publish a message with the refresh notification
|
||||
try {
|
||||
pageBusAdapter.PageBusPublish("org.gcube.portal.databook.shared", feed, (Jsonizer)GWT.create(ClientFeedJsonizer.class));
|
||||
} catch (PageBusAdapterException ex) {
|
||||
GWT.log(ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private PrivacyLevel getPrivacyLevel() {
|
||||
String selected = privacyLevel.getValue(privacyLevel.getSelectedIndex());
|
||||
if (selected.compareTo(PrivacyLevel.CONNECTION.toString()) == 0)
|
||||
return PrivacyLevel.CONNECTION;
|
||||
else if (selected.compareTo(PrivacyLevel.VRES.toString()) == 0)
|
||||
return PrivacyLevel.VRES;
|
||||
else if (selected.compareTo(PrivacyLevel.PRIVATE.toString()) == 0)
|
||||
return PrivacyLevel.PRIVATE;
|
||||
else if (selected.compareTo(PrivacyLevel.PORTAL.toString()) == 0)
|
||||
return PrivacyLevel.PORTAL;
|
||||
else
|
||||
return PrivacyLevel.SINGLE_VRE;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Escape an html string. Escaping data received from the client helps to
|
||||
* prevent cross-site script vulnerabilities.
|
||||
*
|
||||
* @param html the html string to escape
|
||||
* @return the escaped string
|
||||
*/
|
||||
private String escapeHtml(String html) {
|
||||
if (html == null) {
|
||||
return null;
|
||||
}
|
||||
return html.replaceAll("&", "&").replaceAll("<", "<")
|
||||
.replaceAll(">", ">");
|
||||
}
|
||||
/**
|
||||
* called when pasting a possible link
|
||||
* @param linkToCheck
|
||||
*/
|
||||
protected void checkLink(String textToCheck) {
|
||||
if (myLinkPreviewer == null) {
|
||||
String [] parts = textToCheck.split("\\s");
|
||||
// Attempt to convert each item into an URL.
|
||||
for( String item : parts ) {
|
||||
if (item.startsWith("http")) {
|
||||
preview.add(new LinkLoader());
|
||||
//GWT.log("It's http link:" + linkToCheck);
|
||||
shareupdateService.checkLink(textToCheck, new AsyncCallback<LinkPreview>() {
|
||||
public void onFailure(Throwable caught) {
|
||||
preview.clear();
|
||||
}
|
||||
|
||||
public void onSuccess(LinkPreview result) {
|
||||
preview.clear();
|
||||
if (result != null)
|
||||
addPreview(result);
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
Window.alert("You cannot post two links, please remove the previous one first.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* called when pasting. it tries to avoid pasting long non spaced strings
|
||||
* @param linkToCheck
|
||||
*/
|
||||
private boolean checkTextLength(String textToCheck) {
|
||||
|
||||
String [] parts = textToCheck.split("\\s");
|
||||
// check the length of tokens
|
||||
for( String item : parts ) {
|
||||
if (! item.startsWith("http")) { //url are accepted as they can be trunked
|
||||
if (item.length() > 50) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* add the link preview in the view
|
||||
* @param result
|
||||
*/
|
||||
private void addPreview(LinkPreview result) {
|
||||
myLinkPreviewer = new LinkPreviewer(this, result);
|
||||
preview.add(myLinkPreviewer);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected void cancelPreview() {
|
||||
preview.clear();
|
||||
myLinkPreviewer = null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
<!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:m="urn:import:org.gcube.portlets.user.shareupdates.client.form">
|
||||
<ui:style>
|
||||
.important {
|
||||
font-weight: bold;
|
||||
}
|
||||
</ui:style>
|
||||
<g:HTMLPanel>
|
||||
<table class="shareContainer">
|
||||
<tr>
|
||||
<td width="60px;" align="middle">
|
||||
<a href="">
|
||||
<g:Image title="Edit Profile Picture" styleName="member-photo"
|
||||
url="" ui:field="avatarImage" width="60" height="60" />
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<div class="shareContainer-in">
|
||||
<m:MyTextArea styleName="post-message" ui:field="shareTextArea" />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<m:LinkPlaceholder ui:field="preview"></m:LinkPlaceholder>
|
||||
<table class="toolsContainer">
|
||||
<tr>
|
||||
|
||||
<td valign="middle" width="50%">
|
||||
<div style="text-align: left; padding-top: 2px; color: #777;">
|
||||
privacy level:
|
||||
<g:ListBox styleName="wizardListbox" ui:field="privacyLevel" />
|
||||
</div>
|
||||
</td>
|
||||
<td valign="middle"></td>
|
||||
<td valign="middle">
|
||||
<div class="buttonDiv">
|
||||
<!-- <g:Button styleName="wizardButton" ui:field="attachButton" -->
|
||||
<!-- text="Attach a Link" /> -->
|
||||
<g:Button ui:field="submitButton" width="90px" text="Share" />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</g:HTMLPanel>
|
||||
</ui:UiBinder>
|
|
@ -0,0 +1,564 @@
|
|||
package org.gcube.portlets.user.shareupdates.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
import org.apache.commons.validator.routines.UrlValidator;
|
||||
import org.gcube.application.framework.core.session.ASLSession;
|
||||
import org.gcube.application.framework.core.session.SessionManager;
|
||||
import org.gcube.common.core.utils.logging.GCUBEClientLog;
|
||||
import org.gcube.portal.custom.communitymanager.OrganizationsUtil;
|
||||
import org.gcube.portal.custom.scopemanager.scopehelper.ScopeHelper;
|
||||
import org.gcube.portal.databook.server.DBCassandraAstyanaxImpl;
|
||||
import org.gcube.portal.databook.server.DatabookStore;
|
||||
import org.gcube.portal.databook.shared.ClientFeed;
|
||||
import org.gcube.portal.databook.shared.Feed;
|
||||
import org.gcube.portal.databook.shared.FeedType;
|
||||
import org.gcube.portal.databook.shared.PrivacyLevel;
|
||||
import org.gcube.portal.databook.shared.UserInfo;
|
||||
import org.gcube.portal.databook.shared.ex.FeedIDNotFoundException;
|
||||
import org.gcube.portlets.user.shareupdates.client.ShareUpdateService;
|
||||
import org.gcube.portlets.user.shareupdates.server.metaseeker.MetaSeeker;
|
||||
import org.gcube.portlets.user.shareupdates.server.opengraph.OpenGraph;
|
||||
import org.gcube.portlets.user.shareupdates.shared.LinkPreview;
|
||||
import org.gcube.vomanagement.usermanagement.GroupManager;
|
||||
import org.gcube.vomanagement.usermanagement.impl.liferay.LiferayGroupManager;
|
||||
import org.gcube.vomanagement.usermanagement.model.GroupModel;
|
||||
import org.htmlparser.beans.StringBean;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.w3c.tidy.Tidy;
|
||||
|
||||
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.kernel.util.WebKeys;
|
||||
import com.liferay.portal.model.Organization;
|
||||
import com.liferay.portal.model.Role;
|
||||
import com.liferay.portal.model.User;
|
||||
import com.liferay.portal.model.UserModel;
|
||||
import com.liferay.portal.service.OrganizationLocalServiceUtil;
|
||||
import com.liferay.portal.service.UserLocalServiceUtil;
|
||||
import com.liferay.portal.theme.ThemeDisplay;
|
||||
import com.sun.net.ssl.HttpsURLConnection;
|
||||
|
||||
/**
|
||||
* The server side implementation of the RPC service.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class ShareUpdateServiceImpl extends RemoteServiceServlet implements ShareUpdateService {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final String ADMIN_ROLE = "Administrator";
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static GCUBEClientLog _log = new GCUBEClientLog(ShareUpdateServiceImpl.class);
|
||||
/**
|
||||
* The store interface
|
||||
*/
|
||||
private DatabookStore store;
|
||||
/**
|
||||
* used for debugging in eclipse
|
||||
*/
|
||||
private boolean withinPortal = false;
|
||||
/**
|
||||
* connect to cassandra at startup
|
||||
*/
|
||||
public void init() {
|
||||
store = new DBCassandraAstyanaxImpl();
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
store.closeConnection();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* the current ASLSession
|
||||
* @return the session
|
||||
*/
|
||||
private ASLSession getASLSession() {
|
||||
String sessionID = this.getThreadLocalRequest().getSession().getId();
|
||||
String user = (String) this.getThreadLocalRequest().getSession().getAttribute(ScopeHelper.USERNAME_ATTRIBUTE);
|
||||
if (user == null) {
|
||||
_log.warn("USER IS NULL setting test.user and Running OUTSIDE PORTAL");
|
||||
user = "test.user";
|
||||
//user = "massimiliano.assante";
|
||||
withinPortal = false;
|
||||
}
|
||||
else {
|
||||
withinPortal = true;
|
||||
}
|
||||
System.out.println("SessionID = " + sessionID);
|
||||
return SessionManager.getInstance().getASLSession(sessionID, user);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public ClientFeed share(String feedText, FeedType feedType, PrivacyLevel pLevel, String vreId, String linkTitle,
|
||||
String linkDesc, String url, String urlThumbnail, String host) {
|
||||
|
||||
String escapedFeedText = escapeHtml(feedText);
|
||||
String username = getASLSession().getUsername();
|
||||
String email = username+"@isti.cnr.it";
|
||||
String fullName = username+" FULL";
|
||||
String thumbnailURL = "images/Avatar_default.png";
|
||||
|
||||
if (withinPortal) {
|
||||
try {
|
||||
UserInfo user = getUserFromSession();
|
||||
email = user.getEmailaddress();
|
||||
fullName = user.getFullName();
|
||||
thumbnailURL = user.getAvatarId();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
Feed toShare = new Feed(UUID.randomUUID().toString(), feedType, username, new Date(),
|
||||
"", url, urlThumbnail, transformUrls(escapedFeedText), pLevel, fullName, email, thumbnailURL, linkTitle, linkDesc, host);
|
||||
|
||||
_log.trace("Attempting to save Feed with text: " + escapedFeedText + " Level: " + pLevel);
|
||||
boolean result = store.saveUserFeed(toShare);
|
||||
|
||||
//need to put the feed into VRES Timeline too
|
||||
if (pLevel == PrivacyLevel.VRES) {
|
||||
_log.trace("PrivacyLevel was set to VRES attempting to write onto User's VRES Timelines");
|
||||
for (GroupModel vre : getUserVREs(username)) {
|
||||
String vreScope = getScopeByOrganizationId(vre.getGroupId());
|
||||
_log.trace("Attempting to write onto " + vreScope);
|
||||
try {
|
||||
store.saveFeedToVRETimeline(toShare.getKey(), vreScope);
|
||||
} catch (FeedIDNotFoundException e) {
|
||||
_log.error("Error writing onto VRES Time Line" + vreScope);
|
||||
} //save the feed
|
||||
_log.trace("Success writing onto " + vreScope);
|
||||
}
|
||||
|
||||
} //share on a single VRE Timeline
|
||||
//receives a VreId(groupId) get the scope from the groupId
|
||||
else if (pLevel == PrivacyLevel.SINGLE_VRE && vreId != null && vreId.compareTo("") != 0) {
|
||||
String vreScope = getScopeByOrganizationId(vreId);
|
||||
_log.trace("Attempting to write onto " + vreScope);
|
||||
try {
|
||||
store.saveFeedToVRETimeline(toShare.getKey(), vreScope);
|
||||
} catch (FeedIDNotFoundException e) {
|
||||
_log.error("Error writing onto VRES Time Line" + vreScope);
|
||||
} //save the feed
|
||||
_log.trace("Success writing onto " + vreScope);
|
||||
}
|
||||
if (!result) return null;
|
||||
|
||||
ClientFeed cf = new ClientFeed(toShare.getKey(), toShare.getType().toString(), username, toShare.getUri(),
|
||||
replaceAmpersand(toShare.getDescription()), fullName, email, thumbnailURL, toShare.getLinkTitle(), toShare.getLinkDescription(),
|
||||
toShare.getUriThumbnail(), toShare.getLinkHost());
|
||||
return cf;
|
||||
}
|
||||
|
||||
private UserInfo getUserFromSession() {
|
||||
return (UserInfo) getASLSession().getAttribute(UserInfo.USER_INFO_ATTR);
|
||||
}
|
||||
|
||||
private void setUserInSession(UserInfo user) {
|
||||
getASLSession().setAttribute(UserInfo.USER_INFO_ATTR, user);
|
||||
}
|
||||
private String replaceAmpersand(String toReplace) {
|
||||
String toReturn = toReplace.replaceAll("&", "&");
|
||||
return toReturn;
|
||||
}
|
||||
/**
|
||||
* utilty method that convert a url ina text in a clickable url by the browser
|
||||
* and if the user has just pasted a link, converts the link in: shared a link
|
||||
* @param feedText
|
||||
* @return the text with the clickable url in it
|
||||
*/
|
||||
public String transformUrls(String feedText) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
// separate input by spaces ( URLs have no spaces )
|
||||
String [] parts = feedText.split("\\s");
|
||||
// Attempt to convert each item into an URL.
|
||||
for (int i = 0; i < parts.length; i++) {
|
||||
if (parts[i].startsWith("http")) {
|
||||
try {
|
||||
URL url = new URL(parts[i]);
|
||||
if (i == 0 && parts.length == 1) //then he shared just a link
|
||||
return sb.append("<span style=\"color:gray; font-size:12px;\">shared </span><a class=\"link\" href=\"").append(url).append("\" target=\"_blank\">").append("a link.").append("</a> ").toString();
|
||||
// If possible then replace with anchor...
|
||||
sb.append("<a class=\"link\" style=\"font-size:14px;\" href=\"").append(url).append("\" target=\"_blank\">").append(url).append("</a> ");
|
||||
} catch (MalformedURLException e) {
|
||||
// If there was an URL then it's not valid
|
||||
_log.error("MalformedURLException returning... ");
|
||||
return feedText;
|
||||
}
|
||||
} else {
|
||||
sb.append(parts[i]);
|
||||
sb.append(" ");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
|
||||
}
|
||||
|
||||
public UserInfo getUserInfo() {
|
||||
try {
|
||||
|
||||
String username = getASLSession().getUsername();
|
||||
String email = username+"@isti.cnr.it";
|
||||
String fullName = username+" FULL";
|
||||
String thumbnailURL = "images/Avatar_default.png";
|
||||
|
||||
if (withinPortal) {
|
||||
getUserVREs(username);
|
||||
UserModel user = UserLocalServiceUtil.getUserByScreenName(OrganizationsUtil.getCompany().getCompanyId(), username);
|
||||
thumbnailURL = "/image/user_male_portrait?img_id="+user.getPortraitId();
|
||||
fullName = user.getFirstName() + " " + user.getLastName();
|
||||
email = user.getEmailAddress();
|
||||
ThemeDisplay themeDisplay = (ThemeDisplay) this.getThreadLocalRequest().getSession().getAttribute(WebKeys.THEME_DISPLAY);
|
||||
String accountURL = themeDisplay.getURLMyAccount().toString();
|
||||
HashMap<String, String> vreNames = getUserVreNames(username);
|
||||
UserInfo toReturn = new UserInfo(username, fullName, thumbnailURL, user.getEmailAddress(), accountURL, true, isAdmin(), vreNames);
|
||||
setUserInSession(toReturn);
|
||||
return toReturn;
|
||||
}
|
||||
else {
|
||||
_log.info("Returning test USER");
|
||||
HashMap<String, String> fakeVreNames = new HashMap<String, String>();
|
||||
fakeVreNames.put("1","devVRE");
|
||||
// fakeVreNames.put("2", "devNext");
|
||||
return new UserInfo(getASLSession().getUsername(), fullName, thumbnailURL, email, "fakeAccountUrl", true, false, fakeVreNames);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new UserInfo();
|
||||
}
|
||||
/**
|
||||
* return the id as key and the names as value of the vre a user is subscribed to
|
||||
* @param username
|
||||
* @return the id as key and the names as value of the vre a user is subscribed to
|
||||
*/
|
||||
private HashMap<String, String> getUserVreNames(String username) {
|
||||
HashMap<String, String> toReturn = new HashMap<String, String>();
|
||||
for (GroupModel vre : getUserVREs(username)) {
|
||||
toReturn.put(vre.getGroupId(), vre.getGroupName());
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
/**
|
||||
* tell if the user is a portal administrator or not
|
||||
* @param username
|
||||
* @return true if is admin
|
||||
* @throws SystemException
|
||||
* @throws PortalException
|
||||
*/
|
||||
private boolean isAdmin() throws PortalException, SystemException {
|
||||
User currUser = OrganizationsUtil.validateUser(getASLSession().getUsername());
|
||||
List<Organization> organizations = OrganizationLocalServiceUtil.getOrganizations(0, OrganizationLocalServiceUtil.getOrganizationsCount());
|
||||
Organization rootOrganization = null;
|
||||
for (Organization organization : organizations) {
|
||||
if (organization.getName().equals(OrganizationsUtil.getRootOrganizationName() ) ) {
|
||||
rootOrganization = organization;
|
||||
break;
|
||||
}
|
||||
}
|
||||
try {
|
||||
_log.trace("root: " + rootOrganization.getName() );
|
||||
return (hasRole(ADMIN_ROLE, rootOrganization.getName(), currUser));
|
||||
}
|
||||
catch (NullPointerException e) {
|
||||
_log.error("Cannot find root organziation, please check gcube-data.properties file in $CATALINA_HOME/conf folder");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param rolename
|
||||
* @param organizationName
|
||||
* @param user
|
||||
* @return
|
||||
* @throws SystemException
|
||||
*/
|
||||
private boolean hasRole(String rolename, String organizationName, User user) throws SystemException {
|
||||
for (Role role : user.getRoles())
|
||||
if (role.getName().compareTo(rolename) == 0 )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
private ArrayList<GroupModel> getUserVREs(String username) {
|
||||
ArrayList<GroupModel> toReturn = new ArrayList<GroupModel>();
|
||||
User currUser;
|
||||
try {
|
||||
GroupManager gm = new LiferayGroupManager();
|
||||
currUser = OrganizationsUtil.validateUser(username);
|
||||
for (Organization org : currUser.getOrganizations())
|
||||
if (gm.isVRE(org.getOrganizationId()+"")) {
|
||||
GroupModel toAdd = gm.getGroup(""+org.getOrganizationId());
|
||||
toReturn.add(toAdd);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
_log.error("Failed reading User VREs for : " + username);
|
||||
e.printStackTrace();
|
||||
return toReturn;
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
private String getScopeByOrganizationId(String vreid) {
|
||||
GroupManager gm = new LiferayGroupManager();
|
||||
try {
|
||||
return gm.getScope(vreid);
|
||||
} catch (Exception e) {
|
||||
_log.error("Could not find a scope for this VREid: " + vreid);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Escape an html string. Escaping data received from the client helps to
|
||||
* prevent cross-site script vulnerabilities.
|
||||
*
|
||||
* @param html the html string to escape
|
||||
* @return the escaped string
|
||||
*/
|
||||
private String escapeHtml(String html) {
|
||||
if (html == null) {
|
||||
return null;
|
||||
}
|
||||
return html.replaceAll("&", "&").replaceAll("<", "<")
|
||||
.replaceAll(">", ">");
|
||||
}
|
||||
|
||||
/**
|
||||
* utilty method that extract an url ina text
|
||||
* @param feedText
|
||||
* @return the text with the clickable url in it
|
||||
*/
|
||||
public String extractURL(String feedText) {
|
||||
// separate input by spaces ( URLs have no spaces )
|
||||
String [] parts = feedText.split("\\s");
|
||||
// Attempt to convert each item into an URL.
|
||||
for( String item : parts ) {
|
||||
if (item.startsWith("http")) {
|
||||
try {
|
||||
new URL(item);
|
||||
return item;
|
||||
} catch (MalformedURLException e) {
|
||||
// If there was an URL then it's not valid
|
||||
_log.error("MalformedURLException returning... ");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* tries the following in the indicated order for Populating the Link preview
|
||||
* Open Graph protocol
|
||||
* Meta "title" and "description" tags
|
||||
* Best guess from page content (not recommended)
|
||||
*
|
||||
* Schema.org microdata <-- This is still a TODO
|
||||
*/
|
||||
public LinkPreview checkLink(String linkToCheck) {
|
||||
LinkPreview toReturn = null;
|
||||
_log.info("to check " + linkToCheck);
|
||||
//look for a url in text
|
||||
linkToCheck = extractURL(linkToCheck);
|
||||
if (linkToCheck == null)
|
||||
return null; //no url
|
||||
|
||||
String[] schemes = {"http","https"};
|
||||
UrlValidator urlValidator = new UrlValidator(schemes);
|
||||
if (! urlValidator.isValid(linkToCheck)) {
|
||||
_log.warn("url is NOT valid, returning nothing");
|
||||
return null;
|
||||
}
|
||||
_log.debug("url is valid");
|
||||
|
||||
URL pageURL;
|
||||
URLConnection siteConnection = null;
|
||||
try {
|
||||
pageURL = new URL(linkToCheck);
|
||||
if (pageURL.getProtocol().equalsIgnoreCase("https")) {
|
||||
System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
|
||||
java.security.Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
|
||||
trustAllHTTPSConnections();
|
||||
siteConnection = (HttpsURLConnection) pageURL.openConnection();
|
||||
}
|
||||
else
|
||||
siteConnection = (HttpURLConnection) pageURL.openConnection();
|
||||
} catch (MalformedURLException e) {
|
||||
_log.error("url is not valid");
|
||||
return null;
|
||||
} catch (IOException e) {
|
||||
_log.error("url is not reachable");
|
||||
return null;
|
||||
}
|
||||
String title;
|
||||
String description;
|
||||
ArrayList<String> imageUrls = new ArrayList<String>();
|
||||
//get the host from the url
|
||||
String host = pageURL.getHost().replaceAll("www.", "");
|
||||
|
||||
//try openGraph First
|
||||
OpenGraph ogLink = null;
|
||||
try {
|
||||
ogLink = new OpenGraph(linkToCheck, true, siteConnection);
|
||||
if (ogLink == null || ogLink.getContent("title") == null) {
|
||||
//there is no OpenGraph for this link
|
||||
_log.info("No OpenGraph Found, going Best guess from page content") ;
|
||||
toReturn = getInfoFromHTML(pageURL, linkToCheck, host);
|
||||
} else {
|
||||
//there is OpenGraph
|
||||
title = ogLink.getContent("title");
|
||||
description = (ogLink.getContent("description") != null) ? ogLink.getContent("description") : "";
|
||||
description = ((description.length() > 256) ? description.substring(0, 256)+"..." : description);
|
||||
//look for the imagem ask the guesser if not present
|
||||
if (ogLink.getContent("image") != null)
|
||||
imageUrls.add(ogLink.getContent("image"));
|
||||
else {
|
||||
ArrayList<String> images = getImagesFromHTML(pageURL);
|
||||
if (! images.isEmpty())
|
||||
imageUrls = images;
|
||||
}
|
||||
toReturn = new LinkPreview(title, description, linkToCheck, host, imageUrls);
|
||||
return toReturn;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
/**
|
||||
* get all the image urls from an HTML page up to 15
|
||||
* @param pageURL the url
|
||||
* @return a list of image url
|
||||
* @throws IOException
|
||||
*/
|
||||
private ArrayList<String> getImagesFromHTML(URL pageURL) throws IOException {
|
||||
ArrayList<String> toReturn = new ArrayList<String>();
|
||||
InputStream input = pageURL.openStream();
|
||||
try {
|
||||
Document document = new Tidy().parseDOM(input, null);
|
||||
NodeList imgs = document.getElementsByTagName("img");
|
||||
int upTo = (imgs.getLength() > 15) ? 15 : imgs.getLength();
|
||||
for (int i = 0; i < upTo; i++) {
|
||||
System.out.println(i);
|
||||
toReturn.add(imgs.item(i).getAttributes().getNamedItem("src").getNodeValue());
|
||||
}
|
||||
}catch (NullPointerException e) {
|
||||
_log.error("Error parsing HTML for images, malformed HTML returning what I found so far ... ");
|
||||
return toReturn;
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* to use when OpenGraph is not available, Tries Metadata first, then Best guess from page content
|
||||
* @param pageUrl
|
||||
* @param link
|
||||
* @param host
|
||||
* @return a LinPreview object instance filled with the extracted information
|
||||
* @throws IOException
|
||||
*/
|
||||
private LinkPreview getInfoFromHTML(URL pageUrl, String link, String host) throws Exception {
|
||||
LinkPreview toReturn = null;
|
||||
String title = "";
|
||||
String description = "";
|
||||
|
||||
InputStream input = pageUrl.openStream();
|
||||
Document document = new Tidy().parseDOM(input, null);
|
||||
NodeList titles = document.getElementsByTagName("title");
|
||||
if (titles != null && titles.getLength()>0) {
|
||||
if (titles.item(0).getFirstChild() == null || titles.item(0).getFirstChild().getNodeValue() == null) {
|
||||
_log.error("[MANUAL-PARSE] Something wrong with the title element, returning ... ");
|
||||
return toReturn;
|
||||
}
|
||||
title = titles.item(0).getFirstChild().getNodeValue();
|
||||
MetaSeeker ms = null;
|
||||
try {
|
||||
ms = new MetaSeeker(link);
|
||||
} catch(Exception e) {
|
||||
_log.error("[MANUAL-PARSE] Something wrong with the meta seeker returning ... ");
|
||||
return toReturn;
|
||||
}
|
||||
//try the metadata, otherwise ask the guesser
|
||||
description = (ms.getContent("description") != null && ! ms.getContent("description").isEmpty()) ? ms.getContent("description") : createDescriptionFromContent(link);
|
||||
|
||||
ArrayList<String> images = new ArrayList<String>();
|
||||
NodeList imgs = document.getElementsByTagName("img");
|
||||
int upTo = (imgs.getLength() > 15) ? 15 : imgs.getLength();
|
||||
for (int i = 0; i < upTo; i++) {
|
||||
String imageUrl = imgs.item(i).getAttributes().getNamedItem("src").getNodeValue();
|
||||
if (imageUrl.startsWith("/"))
|
||||
imageUrl = pageUrl.getProtocol()+"://"+pageUrl.getHost()+imageUrl;
|
||||
images.add(imageUrl);
|
||||
}
|
||||
toReturn = new LinkPreview(title, description, link, host, images);
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
/**
|
||||
* generate the description parsing the content (Best Guess)
|
||||
* @param link the link to check
|
||||
* @return the description guessed
|
||||
*/
|
||||
private String createDescriptionFromContent(String link) {
|
||||
StringBean sb = new StringBean();
|
||||
sb.setURL(link);
|
||||
sb.setLinks(false);
|
||||
String description = sb.getStrings();
|
||||
description = ((description.length() > 256) ? description.substring(0, 256)+"..." : description);
|
||||
return description;
|
||||
}
|
||||
/**
|
||||
* this method handles the non trusted https connections
|
||||
*/
|
||||
private void trustAllHTTPSConnections() {
|
||||
// Create a trust manager that does not validate certificate chains
|
||||
TrustManager[] trustAllCerts = new TrustManager[]{
|
||||
new X509TrustManager() {
|
||||
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void checkClientTrusted(
|
||||
java.security.cert.X509Certificate[] certs, String authType) {
|
||||
}
|
||||
|
||||
public void checkServerTrusted(
|
||||
java.security.cert.X509Certificate[] certs, String authType) {
|
||||
}
|
||||
}
|
||||
};
|
||||
try {
|
||||
SSLContext sc = SSLContext.getInstance("SSL");
|
||||
sc.init(null, trustAllCerts, new java.security.SecureRandom());
|
||||
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error" + e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package org.gcube.portlets.user.shareupdates.server.metaseeker;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* Represents OpenGraph enabled meta data for a specific document
|
||||
* @author Callum Jones
|
||||
*/
|
||||
public class MetaElement
|
||||
{
|
||||
private String property;
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* Construct the representation of an element
|
||||
* @param property The property key
|
||||
* @param content The content or value of this element
|
||||
*/
|
||||
public MetaElement(String property, String content)
|
||||
{
|
||||
this.property = property;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the content string of the element
|
||||
*/
|
||||
public String getContent()
|
||||
{
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the property of the element
|
||||
*/
|
||||
public String getProperty()
|
||||
{
|
||||
return property;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,211 @@
|
|||
package org.gcube.portlets.user.shareupdates.server.metaseeker;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Hashtable;
|
||||
|
||||
import org.htmlcleaner.HtmlCleaner;
|
||||
import org.htmlcleaner.TagNode;
|
||||
|
||||
/**
|
||||
* @author Massimiliano Assante ISTI-CNR
|
||||
* @version 1.0 Nov 2012
|
||||
*
|
||||
* This class parses the meta elements in the head of an html page and constructs a hashmap with the content attr value associated to the attr name
|
||||
* e.g.
|
||||
* <meta name="description" content="my description">
|
||||
*
|
||||
* ex. #getContent("description") returns 'my description'
|
||||
*
|
||||
*/
|
||||
public class MetaSeeker
|
||||
{
|
||||
private String pageUrl;
|
||||
|
||||
private Hashtable<String, ArrayList<MetaElement>> metaAttributes;
|
||||
private String baseType;
|
||||
private boolean isImported; // determine if the object is a new incarnation or representation of a web page
|
||||
private boolean hasChanged; // track if object has been changed
|
||||
|
||||
public final static String[] REQUIRED_META = new String[]{"title", "type", "image", "url" };
|
||||
|
||||
public final static Hashtable<String, String[]> BASE_TYPES = new Hashtable<String, String[]>();
|
||||
static
|
||||
{
|
||||
BASE_TYPES.put("activity", new String[] {"activity", "sport"});
|
||||
BASE_TYPES.put("business", new String[] {"bar", "company", "cafe", "hotel", "restaurant"});
|
||||
BASE_TYPES.put("group", new String[] {"cause", "sports_league", "sports_team"});
|
||||
BASE_TYPES.put("organization", new String[] {"band", "government", "non_profit", "school", "university"});
|
||||
BASE_TYPES.put("person", new String[] {"actor", "athlete", "author", "director", "musician", "politician", "profile", "public_figure"});
|
||||
BASE_TYPES.put("place", new String[] {"city", "country", "landmark", "state_province"});
|
||||
BASE_TYPES.put("product", new String[] {"album", "book", "drink", "food", "game", "movie", "product", "song", "tv_show"});
|
||||
BASE_TYPES.put("website", new String[] {"blog", "website", "article"});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an open graph representation for generating your own Open Graph object
|
||||
*/
|
||||
public MetaSeeker() {
|
||||
metaAttributes = new Hashtable<String, ArrayList<MetaElement>>();
|
||||
hasChanged = false;
|
||||
isImported = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the metas representation from a web site
|
||||
* @param url The address to the web page to fetch the meta
|
||||
* @throws java.io.IOException If a network error occurs, the HTML parser will throw an IO Exception
|
||||
*/
|
||||
public MetaSeeker(String url) throws java.io.IOException, Exception {
|
||||
this();
|
||||
isImported = true;
|
||||
// download the (X)HTML content, but only up to the closing head tag. We do not want to waste resources parsing irrelevant content
|
||||
URL httpURL = new URL(url);
|
||||
BufferedReader dis = new BufferedReader(new InputStreamReader(httpURL.openStream()));
|
||||
String inputLine;
|
||||
StringBuffer headContents = new StringBuffer();
|
||||
|
||||
// Loop through each line, looking for the closing head element
|
||||
while ((inputLine = dis.readLine()) != null) {
|
||||
if (inputLine.contains("</head>")) {
|
||||
inputLine = inputLine.substring(0, inputLine.indexOf("</head>") + 7);
|
||||
inputLine = inputLine.concat("<body></body></html>");
|
||||
headContents.append(inputLine + "\r\n");
|
||||
break;
|
||||
}
|
||||
headContents.append(inputLine + "\r\n");
|
||||
}
|
||||
|
||||
String headContentsStr = headContents.toString();
|
||||
HtmlCleaner cleaner = new HtmlCleaner();
|
||||
// parse the string HTML
|
||||
TagNode pageData = cleaner.clean(headContentsStr);
|
||||
// open only the meta tags
|
||||
TagNode[] metaData = pageData.getElementsByName("meta", true);
|
||||
System.out.println("meta length " + metaData.length);
|
||||
for (TagNode metaElement : metaData) {
|
||||
String target = null;
|
||||
System.out.println("meta " + metaElement.toString());
|
||||
if (metaElement.hasAttribute("name")) {
|
||||
target = "name";
|
||||
setProperty(metaElement.getAttributeByName(target), metaElement.getAttributeByName("content"));
|
||||
}
|
||||
}
|
||||
pageUrl = httpURL.toExternalForm();
|
||||
}
|
||||
/**
|
||||
* Get the basic type of the Open graph page as per the specification
|
||||
* @return Base type as defined by specification, null otherwise
|
||||
*/
|
||||
public String getBaseType()
|
||||
{
|
||||
return baseType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a value of a given Open Graph property
|
||||
* @param property The Open graph property key
|
||||
* @return Returns the value of the first property defined, null otherwise
|
||||
*/
|
||||
public String getContent(String property)
|
||||
{
|
||||
if (metaAttributes.containsKey(property) && metaAttributes.get(property).size() > 0)
|
||||
return metaAttributes.get(property).get(0).getContent();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the defined properties of the Open Graph object
|
||||
* @return An array of all currently defined properties
|
||||
*/
|
||||
public MetaElement[] getProperties()
|
||||
{
|
||||
ArrayList<MetaElement> allElements = new ArrayList<MetaElement>();
|
||||
for (ArrayList<MetaElement> collection : metaAttributes.values())
|
||||
allElements.addAll(collection);
|
||||
|
||||
return (MetaElement[]) allElements.toArray(new MetaElement[allElements.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the defined properties of the Open Graph object
|
||||
* @param property The property to focus on
|
||||
* @return An array of all currently defined properties
|
||||
*/
|
||||
public MetaElement[] getProperties(String property)
|
||||
{
|
||||
if (metaAttributes.containsKey(property))
|
||||
{
|
||||
ArrayList target = metaAttributes.get(property);
|
||||
return (MetaElement[]) target.toArray(new MetaElement[target.size()]);
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the original URL the Open Graph page was obtained from
|
||||
* @return The address to the Open Graph object page
|
||||
*/
|
||||
public String getOriginalUrl()
|
||||
{
|
||||
return pageUrl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the meta property to a specific value
|
||||
* @param property The meta where XXXX is the property you wish to set
|
||||
* @param content The value or contents of the property to be set
|
||||
*/
|
||||
public void setProperty(String property, String content)
|
||||
{
|
||||
|
||||
MetaElement element = new MetaElement(property, content);
|
||||
if (!metaAttributes.containsKey(property))
|
||||
metaAttributes.put(property, new ArrayList<MetaElement>());
|
||||
|
||||
metaAttributes.get(property).add(element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removed a defined property
|
||||
* @param property The og:XXXX where XXXX is the property you wish to remove
|
||||
*/
|
||||
public void removeProperty(String property)
|
||||
{
|
||||
metaAttributes.remove(property);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the underlying HashTable
|
||||
* @return The underlying structure as a Hashtable
|
||||
*/
|
||||
public Hashtable<String, ArrayList<MetaElement>> exposeTable() {
|
||||
return metaAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the Open Graph object was initially a representation of a web page
|
||||
* @return True if the object is from a web page, false otherwise
|
||||
*/
|
||||
public boolean isFromWeb()
|
||||
{
|
||||
return isImported;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the object has been modified by setters/deleters.
|
||||
* This is only relevant if this object initially represented a web page
|
||||
* @return True True if the object has been modified, false otherwise
|
||||
*/
|
||||
public boolean hasChanged()
|
||||
{
|
||||
return hasChanged;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package org.gcube.portlets.user.shareupdates.server.opengraph;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* Represents OpenGraph enabled meta data for a specific document
|
||||
* @author Callum Jones
|
||||
*/
|
||||
public class MetaElement
|
||||
{
|
||||
private OpenGraphNamespace namespace; //either "og" an NS specific
|
||||
private String property;
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* Construct the representation of an element
|
||||
* @param namespace The namespace the element belongs to
|
||||
* @param property The property key
|
||||
* @param content The content or value of this element
|
||||
*/
|
||||
public MetaElement(OpenGraphNamespace namespace, String property, String content)
|
||||
{
|
||||
this.namespace = namespace;
|
||||
this.property = property;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the content string of the element
|
||||
*/
|
||||
public String getContent()
|
||||
{
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the OpenGraph namespace
|
||||
*/
|
||||
public OpenGraphNamespace getNamespace()
|
||||
{
|
||||
return namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the property of the element
|
||||
*/
|
||||
public String getProperty()
|
||||
{
|
||||
return property;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,378 @@
|
|||
package org.gcube.portlets.user.shareupdates.server.opengraph;
|
||||
|
||||
import org.htmlcleaner.HtmlCleaner;
|
||||
import org.htmlcleaner.TagNode;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Hashtable;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* A Java object representation of an Open Graph enabled webpage.
|
||||
* A simplified layer over a Hastable.
|
||||
*
|
||||
* @author Callum Jones
|
||||
*/
|
||||
public class OpenGraph
|
||||
{
|
||||
private String pageUrl;
|
||||
private ArrayList<OpenGraphNamespace> pageNamespaces;
|
||||
private Hashtable<String, ArrayList<MetaElement>> metaAttributes;
|
||||
private String baseType;
|
||||
private boolean isImported; // determine if the object is a new incarnation or representation of a web page
|
||||
private boolean hasChanged; // track if object has been changed
|
||||
|
||||
public final static String[] REQUIRED_META = new String[]{"title", "type", "image", "url" };
|
||||
|
||||
public final static Hashtable<String, String[]> BASE_TYPES = new Hashtable<String, String[]>();
|
||||
static
|
||||
{
|
||||
BASE_TYPES.put("activity", new String[] {"activity", "sport"});
|
||||
BASE_TYPES.put("business", new String[] {"bar", "company", "cafe", "hotel", "restaurant"});
|
||||
BASE_TYPES.put("group", new String[] {"cause", "sports_league", "sports_team"});
|
||||
BASE_TYPES.put("organization", new String[] {"band", "government", "non_profit", "school", "university"});
|
||||
BASE_TYPES.put("person", new String[] {"actor", "athlete", "author", "director", "musician", "politician", "profile", "public_figure"});
|
||||
BASE_TYPES.put("place", new String[] {"city", "country", "landmark", "state_province"});
|
||||
BASE_TYPES.put("product", new String[] {"album", "book", "drink", "food", "game", "movie", "product", "song", "tv_show"});
|
||||
BASE_TYPES.put("website", new String[] {"blog", "website", "article"});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an open graph representation for generating your own Open Graph object
|
||||
*/
|
||||
public OpenGraph()
|
||||
{
|
||||
pageNamespaces = new ArrayList<OpenGraphNamespace>();
|
||||
metaAttributes = new Hashtable<String, ArrayList<MetaElement>>();
|
||||
hasChanged = false;
|
||||
isImported = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the open graph representation from a web site
|
||||
* @param url The address to the web page to fetch Open Graph data
|
||||
* @param ignoreSpecErrors Set this option to true if you don't wish to have an exception throw if the page does not conform to the basic 4 attributes
|
||||
* @throws java.io.IOException If a network error occurs, the HTML parser will throw an IO Exception
|
||||
* @throws java.lang.Exception A generic exception is throw if the specific page fails to conform to the basic Open Graph standard as define by the constant REQUIRED_META
|
||||
*/
|
||||
public OpenGraph(String url, boolean ignoreSpecErrors, URLConnection siteConnection) throws java.io.IOException, Exception {
|
||||
this();
|
||||
isImported = true;
|
||||
|
||||
|
||||
// download the (X)HTML content, but only up to the closing head tag. We do not want to waste resources parsing irrelevant content
|
||||
Charset charset = getConnectionCharset(siteConnection);
|
||||
BufferedReader dis = new BufferedReader(new InputStreamReader(siteConnection.getInputStream(), charset));
|
||||
String inputLine;
|
||||
StringBuffer headContents = new StringBuffer();
|
||||
|
||||
// Loop through each line, looking for the closing head element
|
||||
while ((inputLine = dis.readLine()) != null)
|
||||
{
|
||||
if (inputLine.contains("</head>"))
|
||||
{
|
||||
inputLine = inputLine.substring(0, inputLine.indexOf("</head>") + 7);
|
||||
inputLine = inputLine.concat("<body></body></html>");
|
||||
headContents.append(inputLine + "\r\n");
|
||||
break;
|
||||
}
|
||||
headContents.append(inputLine + "\r\n");
|
||||
}
|
||||
|
||||
String headContentsStr = headContents.toString();
|
||||
HtmlCleaner cleaner = new HtmlCleaner();
|
||||
// parse the string HTML
|
||||
TagNode pageData = cleaner.clean(headContentsStr);
|
||||
|
||||
// read in the declared namespaces
|
||||
boolean hasOGspec = false;
|
||||
TagNode headElement = pageData.findElementByName("head", true);
|
||||
if (headElement.hasAttribute("prefix"))
|
||||
{
|
||||
String namespaceData = headElement.getAttributeByName("prefix");
|
||||
Pattern pattern = Pattern.compile("(([A-Za-z0-9_]+):\\s+(http:\\/\\/ogp.me\\/ns(\\/\\w+)*#))\\s*");
|
||||
Matcher matcher = pattern.matcher(namespaceData);
|
||||
while (matcher.find())
|
||||
{
|
||||
String prefix = matcher.group(2);
|
||||
String documentURI = matcher.group(3);
|
||||
pageNamespaces.add(new OpenGraphNamespace(prefix, documentURI));
|
||||
if (prefix.equals("og"))
|
||||
hasOGspec = true;
|
||||
}
|
||||
}
|
||||
|
||||
// some pages do not include the new OG spec
|
||||
// this fixes compatibility
|
||||
if (!hasOGspec)
|
||||
pageNamespaces.add(new OpenGraphNamespace("og", "http:// ogp.me/ns#"));
|
||||
|
||||
// open only the meta tags
|
||||
TagNode[] metaData = pageData.getElementsByName("meta", true);
|
||||
for (TagNode metaElement : metaData)
|
||||
{
|
||||
for (OpenGraphNamespace namespace : pageNamespaces)
|
||||
{
|
||||
String target = null;
|
||||
if (metaElement.hasAttribute("property"))
|
||||
target = "property";
|
||||
else if (metaElement.hasAttribute("name"))
|
||||
target = "name";
|
||||
|
||||
if (target != null && metaElement.getAttributeByName(target).startsWith(namespace.getPrefix() + ":"))
|
||||
{
|
||||
setProperty(namespace, metaElement.getAttributeByName(target), metaElement.getAttributeByName("content"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that page conforms to Open Graph protocol
|
||||
*/
|
||||
if (!ignoreSpecErrors)
|
||||
{
|
||||
for (String req : REQUIRED_META)
|
||||
{
|
||||
if (!metaAttributes.containsKey(req))
|
||||
throw new Exception("Does not conform to Open Graph protocol");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Has conformed, now determine basic sub type.
|
||||
*/
|
||||
baseType = null;
|
||||
String currentType = getContent("type");
|
||||
// read the original page url
|
||||
URL realURL = siteConnection.getURL();
|
||||
pageUrl = realURL.toExternalForm();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the charset for specified connection.
|
||||
* Content Type header is parsed to get the charset name.
|
||||
*
|
||||
* @param connection the connection.
|
||||
* @return the Charset object for response charset name;
|
||||
* if it's not found then the default charset.
|
||||
*/
|
||||
private static Charset getConnectionCharset(URLConnection connection)
|
||||
{
|
||||
String contentType = connection.getContentType();
|
||||
if (contentType != null && contentType.length() > 0)
|
||||
{
|
||||
contentType = contentType.toLowerCase();
|
||||
String charsetName = extractCharsetName(contentType);
|
||||
if (charsetName != null && charsetName.length() > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Charset.forName(charsetName);
|
||||
}
|
||||
catch (Exception e) {
|
||||
// specified charset is not found,
|
||||
// skip it to return the default one
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return the default charset
|
||||
return Charset.defaultCharset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the charset name form the content type string.
|
||||
* Content type string is received from Content-Type header.
|
||||
*
|
||||
* @param contentType the content type string, must be not null.
|
||||
* @return the found charset name or null if not found.
|
||||
*/
|
||||
private static String extractCharsetName(String contentType)
|
||||
{
|
||||
// split onto media types
|
||||
final String[] mediaTypes = contentType.split(":");
|
||||
if (mediaTypes.length > 0)
|
||||
{
|
||||
// use only the first one, and split it on parameters
|
||||
final String[] params = mediaTypes[0].split(";");
|
||||
|
||||
// find the charset parameter and return it's value
|
||||
for (String each : params)
|
||||
{
|
||||
each = each.trim();
|
||||
if (each.startsWith("charset="))
|
||||
{
|
||||
// return the charset name
|
||||
return each.substring(8).trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the basic type of the Open graph page as per the specification
|
||||
* @return Base type as defined by specification, null otherwise
|
||||
*/
|
||||
public String getBaseType()
|
||||
{
|
||||
return baseType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a value of a given Open Graph property
|
||||
* @param property The Open graph property key
|
||||
* @return Returns the value of the first property defined, null otherwise
|
||||
*/
|
||||
public String getContent(String property)
|
||||
{
|
||||
if (metaAttributes.containsKey(property) && metaAttributes.get(property).size() > 0)
|
||||
return metaAttributes.get(property).get(0).getContent();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the defined properties of the Open Graph object
|
||||
* @return An array of all currently defined properties
|
||||
*/
|
||||
public MetaElement[] getProperties()
|
||||
{
|
||||
ArrayList<MetaElement> allElements = new ArrayList<MetaElement>();
|
||||
for (ArrayList<MetaElement> collection : metaAttributes.values())
|
||||
allElements.addAll(collection);
|
||||
|
||||
return (MetaElement[]) allElements.toArray(new MetaElement[allElements.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the defined properties of the Open Graph object
|
||||
* @param property The property to focus on
|
||||
* @return An array of all currently defined properties
|
||||
*/
|
||||
public MetaElement[] getProperties(String property)
|
||||
{
|
||||
if (metaAttributes.containsKey(property))
|
||||
{
|
||||
ArrayList target = metaAttributes.get(property);
|
||||
return (MetaElement[]) target.toArray(new MetaElement[target.size()]);
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the original URL the Open Graph page was obtained from
|
||||
* @return The address to the Open Graph object page
|
||||
*/
|
||||
public String getOriginalUrl()
|
||||
{
|
||||
return pageUrl;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the HTML representation of the Open Graph data.
|
||||
* @return An array of meta elements as Strings
|
||||
*/
|
||||
public String[] toHTML()
|
||||
{
|
||||
// allocate the array
|
||||
ArrayList<String> returnHTML = new ArrayList<String>();
|
||||
|
||||
int index = 0; // keep track of the index to insert into
|
||||
for (ArrayList<MetaElement> elements : metaAttributes.values())
|
||||
{
|
||||
for (MetaElement element : elements)
|
||||
returnHTML.add("<meta property=\"" + element.getNamespace() + ":" +
|
||||
element.getProperty() + "\" content=\"" + element.getContent() + "\" />");
|
||||
}
|
||||
|
||||
// return the array
|
||||
return (String[]) returnHTML.toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the XHTML representation of the Open Graph data.
|
||||
* @return An array of meta elements as Strings
|
||||
*/
|
||||
public String[] toXHTML()
|
||||
{
|
||||
// allocate the array
|
||||
ArrayList<String> returnHTML = new ArrayList<String>();
|
||||
|
||||
int index = 0; // keep track of the index to insert into
|
||||
for (ArrayList<MetaElement> elements : metaAttributes.values())
|
||||
{
|
||||
for (MetaElement element : elements)
|
||||
returnHTML.add("<meta name=\"" + element.getNamespace().getPrefix() + ":" +
|
||||
element.getProperty() + "\" content=\"" + element.getContent() + "\" />");
|
||||
}
|
||||
|
||||
// return the array
|
||||
return (String[]) returnHTML.toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Open Graph property to a specific value
|
||||
* @param namespace The OpenGraph namespace the content belongs to
|
||||
* @param property The og:XXXX where XXXX is the property you wish to set
|
||||
* @param content The value or contents of the property to be set
|
||||
*/
|
||||
public void setProperty(OpenGraphNamespace namespace, String property, String content)
|
||||
{
|
||||
if (!pageNamespaces.contains(namespace))
|
||||
pageNamespaces.add(namespace);
|
||||
|
||||
property = property.replaceAll(namespace.getPrefix() + ":", "");
|
||||
MetaElement element = new MetaElement(namespace, property, content);
|
||||
if (!metaAttributes.containsKey(property))
|
||||
metaAttributes.put(property, new ArrayList<MetaElement>());
|
||||
|
||||
metaAttributes.get(property).add(element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removed a defined property
|
||||
* @param property The og:XXXX where XXXX is the property you wish to remove
|
||||
*/
|
||||
public void removeProperty(String property)
|
||||
{
|
||||
metaAttributes.remove(property);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the underlying HashTable
|
||||
* @return The underlying structure as a Hashtable
|
||||
*/
|
||||
public Hashtable<String, ArrayList<MetaElement>> exposeTable() {
|
||||
return metaAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the Open Graph object was initially a representation of a web page
|
||||
* @return True if the object is from a web page, false otherwise
|
||||
*/
|
||||
public boolean isFromWeb()
|
||||
{
|
||||
return isImported;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the object has been modified by setters/deleters.
|
||||
* This is only relevant if this object initially represented a web page
|
||||
* @return True True if the object has been modified, false otherwise
|
||||
*/
|
||||
public boolean hasChanged()
|
||||
{
|
||||
return hasChanged;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package org.gcube.portlets.user.shareupdates.server.opengraph;
|
||||
|
||||
/**
|
||||
* Represents an OpenGraph namespace
|
||||
* @author Callum Jones
|
||||
*/
|
||||
public class OpenGraphNamespace
|
||||
{
|
||||
private String prefix;
|
||||
private String schemaURI;
|
||||
|
||||
/**
|
||||
* Construct a namespace
|
||||
* @param prefix The OpenGraph assigned namespace prefix such as og or og_appname
|
||||
* @param schemaURI The URL for the OpenGraph schema
|
||||
*/
|
||||
public OpenGraphNamespace(String prefix, String schemaURI)
|
||||
{
|
||||
this.prefix = prefix;
|
||||
this.schemaURI = schemaURI;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fetch the prefix used for the namespace
|
||||
*/
|
||||
public String getPrefix()
|
||||
{
|
||||
return prefix;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fetch the address for the schema reference
|
||||
*/
|
||||
public String getSchemaURI()
|
||||
{
|
||||
return schemaURI;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
package org.gcube.portlets.user.shareupdates.server.portlet;
|
||||
|
||||
import javax.portlet.GenericPortlet;
|
||||
import javax.portlet.ActionRequest;
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.ActionResponse;
|
||||
import javax.portlet.RenderResponse;
|
||||
import javax.portlet.PortletException;
|
||||
import java.io.IOException;
|
||||
import javax.portlet.PortletRequestDispatcher;
|
||||
|
||||
import org.gcube.portal.custom.scopemanager.scopehelper.ScopeHelper;
|
||||
|
||||
/**
|
||||
* WfTemplatesPortlet Portlet Class
|
||||
*
|
||||
* @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it
|
||||
* @version May 2011 (0.1)
|
||||
*/
|
||||
public class ShareUpdatesPortlet extends GenericPortlet {
|
||||
public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException {
|
||||
response.setContentType("text/html");
|
||||
ScopeHelper.setContext(request);
|
||||
PortletRequestDispatcher dispatcher = getPortletContext().getRequestDispatcher("/WEB-INF/jsp/ShareUpdates_view.jsp");
|
||||
dispatcher.include(request, response);
|
||||
}
|
||||
|
||||
public void processAction(ActionRequest request, ActionResponse response)
|
||||
throws PortletException, IOException {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package org.gcube.portlets.user.shareupdates.shared;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* FieldVerifier validates that the name the user enters is valid.
|
||||
* </p>
|
||||
* <p>
|
||||
* This class is in the <code>shared</code> packing because we use it in both
|
||||
* the client code and on the server. On the client, we verify that the name is
|
||||
* valid before sending an RPC request so the user doesn't have to wait for a
|
||||
* network round trip to get feedback. On the server, we verify that the name is
|
||||
* correct to ensure that the input is correct regardless of where the RPC
|
||||
* originates.
|
||||
* </p>
|
||||
* <p>
|
||||
* When creating a class that is used on both the client and the server, be sure
|
||||
* that all code is translatable and does not use native JavaScript. Code that
|
||||
* is note translatable (such as code that interacts with a database or the file
|
||||
* system) cannot be compiled into client side JavaScript. Code that uses native
|
||||
* JavaScript (such as Widgets) cannot be run on the server.
|
||||
* </p>
|
||||
*/
|
||||
public class FieldVerifier {
|
||||
|
||||
/**
|
||||
* Verifies that the specified name is valid for our service.
|
||||
*
|
||||
* In this example, we only require that the name is at least four
|
||||
* characters. In your application, you can use more complex checks to ensure
|
||||
* that usernames, passwords, email addresses, URLs, and other fields have the
|
||||
* proper syntax.
|
||||
*
|
||||
* @param name the name to validate
|
||||
* @return true if valid, false if invalid
|
||||
*/
|
||||
public static boolean isValidName(String name) {
|
||||
if (name == null) {
|
||||
return false;
|
||||
}
|
||||
return name.length() > 3;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package org.gcube.portlets.user.shareupdates.shared;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class LinkPreview implements Serializable {
|
||||
|
||||
private String title;
|
||||
private String description;
|
||||
private String url;
|
||||
private String host;
|
||||
private ArrayList<String> imageUrls;
|
||||
|
||||
|
||||
public LinkPreview() {
|
||||
super();
|
||||
}
|
||||
|
||||
public LinkPreview(String title, String description, String url,
|
||||
String host, ArrayList<String> imageUrls) {
|
||||
super();
|
||||
this.title = title;
|
||||
this.description = description;
|
||||
this.url = url;
|
||||
this.host = host;
|
||||
this.imageUrls = imageUrls;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public void setHost(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param title
|
||||
*/
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
public ArrayList<String> getImageUrls() {
|
||||
return imageUrls;
|
||||
}
|
||||
public void setImageUrls(ArrayList<String> imageUrls) {
|
||||
this.imageUrls = imageUrls;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LinkPreview [title=" + title + ", description=" + description
|
||||
+ ", url=" + url + ", host=" + host + ", imageUrls="
|
||||
+ imageUrls + "]";
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module rename-to='shareupdates'>
|
||||
<!-- Inherit the core Web Toolkit stuff. -->
|
||||
<inherits name='com.google.gwt.user.User' />
|
||||
|
||||
<inherits name="net.eliasbalasis.tibcopagebus4gwt.tibcopagebus4gwt" />
|
||||
<inherits name="org.jsonmaker.gwt.Gwt_jsonmaker" />
|
||||
|
||||
<!-- inherits GCUBE Widgets -->
|
||||
<inherits name='org.gcube.portlets.user.gcubewidgets.WidgetFactory' />
|
||||
|
||||
<inherits
|
||||
name="net.eliasbalasis.tibcopagebus4gwt.testsubscriber.TestSubscriber" />
|
||||
|
||||
<!-- To Comment out -->
|
||||
<!-- <set-property name="user.agent" value="gecko1_8" /> -->
|
||||
|
||||
<!-- Other module inherits -->
|
||||
|
||||
<inherits name='org.gcube.portal.databook.GCubeSocialNetworking' />
|
||||
|
||||
<!-- Specify the app entry point class. -->
|
||||
<entry-point class='org.gcube.portlets.user.shareupdates.client.ShareUpdates' />
|
||||
|
||||
<!-- Specify the paths for translatable code -->
|
||||
<source path='client' />
|
||||
<source path='shared' />
|
||||
|
||||
</module>
|
|
@ -0,0 +1,174 @@
|
|||
.buttonDiv {
|
||||
text-align: right;
|
||||
padding-top: 2px;
|
||||
}
|
||||
.member-photo {
|
||||
display: block;
|
||||
padding: 2px;
|
||||
border: 1px solid #E6E6E6;
|
||||
}
|
||||
|
||||
.link-previewer {
|
||||
width: 600px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
font-family: 'lucida grande', tahoma, verdana, arial, sans-serif;
|
||||
background-clip: border-box;
|
||||
background-color: #FBFBFB;
|
||||
background-image: none;
|
||||
border-color: #D7D7D7;
|
||||
}
|
||||
|
||||
.hide-description {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.hide-description span label{
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.linkpreview-bgcolor {
|
||||
background-color: #FBFBFB;
|
||||
}
|
||||
|
||||
.link-title {
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
line-height: 15px;
|
||||
width: 465px;
|
||||
}
|
||||
|
||||
.link-url {
|
||||
color: #666;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.link-desc {
|
||||
padding-top: 5px;
|
||||
color: #333;
|
||||
font-size: 10px;
|
||||
width: 465px;
|
||||
}
|
||||
|
||||
.image-loader {
|
||||
background: #FFF url(images/avatarLoader.gif) no-repeat;
|
||||
}
|
||||
|
||||
.su-closeImage {
|
||||
background: url(images/close.png) 0px 0px no-repeat;
|
||||
height: 15px;
|
||||
width: 15px;
|
||||
}
|
||||
|
||||
.su-closeImage:hover {
|
||||
background: url(images/close.png) 0px -16px no-repeat;
|
||||
cursor: pointer;
|
||||
cursor: hand;
|
||||
}
|
||||
|
||||
.su-closeImage:active {
|
||||
background: url(images/close.png) 0px -32px no-repeat;
|
||||
}
|
||||
|
||||
.small-text {
|
||||
font-family: 'lucida grande', tahoma, verdana, arial, sans-serif;
|
||||
font-size: 9px;
|
||||
}
|
||||
|
||||
.small-text-arrow {
|
||||
font-family: 'lucida grande', tahoma, verdana, arial, sans-serif;
|
||||
font-size: 9px;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.small-text-arrow:hover {
|
||||
color: blue;
|
||||
cursor: pointer;
|
||||
cursor: hand;
|
||||
}
|
||||
|
||||
a.link,a.link:active,a.link:visited {
|
||||
font-family: 'Lucida Grande', Verdana, 'Bitstream Vera Sans', Arial,
|
||||
sans-serif;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
cursor: hand;
|
||||
text-decoration: none;
|
||||
color: #3B5998;
|
||||
}
|
||||
|
||||
a.link:hover {
|
||||
opacity: 0.8;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.shareContainer {
|
||||
width: 600px;
|
||||
background-clip: border-box;
|
||||
background-image: none;
|
||||
background-origin: padding-box;
|
||||
padding-bottom: 3px;
|
||||
}
|
||||
|
||||
.shareContainer-in {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.post-message {
|
||||
height: 54px;
|
||||
color: #999;
|
||||
font-family: 'Lucida Grande', Verdana, 'Bitstream Vera Sans', Arial,
|
||||
sans-serif;
|
||||
font-size: 13px;
|
||||
padding: 4px 2px;
|
||||
width: 99%;
|
||||
border-color: #999;
|
||||
border-width: 1px;
|
||||
-moz-border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
letter-spacing: normal;
|
||||
}
|
||||
|
||||
.dark-color {
|
||||
color: #333;
|
||||
background-color: #FFF;
|
||||
transition: background .25s ease-in-out;
|
||||
-moz-transition: background .25s ease-in-out;
|
||||
-webkit-transition: background .25s ease-in-out;
|
||||
}
|
||||
|
||||
.toolsContainer {
|
||||
padding-top: 3px;
|
||||
width: 600px;
|
||||
background-image: none;
|
||||
border-top-color: #DADADA;
|
||||
border-top-style: solid;
|
||||
border-top-width: 1px;
|
||||
}
|
||||
|
||||
.wizardListbox {
|
||||
height: 19px;
|
||||
width: 110px;
|
||||
background: #F2F2F2 url(images/white-grad.png) repeat-x scroll left top;
|
||||
border-color: #BBB;
|
||||
color: #464646;
|
||||
font-size: 10px;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
cursor: pointer;
|
||||
cursor: hand;
|
||||
padding-bottom: 3px;
|
||||
-moz-border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: #FFF;
|
||||
background-color: pink;
|
||||
transition: background .45s ease-in-out;
|
||||
-moz-transition: background .45s ease-in-out;
|
||||
-webkit-transition: background .45s ease-in-out;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<!doctype html>
|
||||
<!-- The DOCTYPE declaration above will set the -->
|
||||
<!-- browser's rendering engine into -->
|
||||
<!-- "Standards Mode". Replacing this declaration -->
|
||||
<!-- with a "Quirks Mode" doctype may lead to some -->
|
||||
<!-- differences in layout. -->
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
|
||||
<!-- -->
|
||||
<!-- Consider inlining CSS to reduce the number of requested files -->
|
||||
<!-- -->
|
||||
<link type="text/css" rel="stylesheet" href="ShareUpdates.css">
|
||||
|
||||
<script type="text/javascript" language="javascript" src="shareupdates/shareupdates.nocache.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="shareUpdateDiv"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,19 @@
|
|||
<%@page contentType="text/html"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
|
||||
<%-- Uncomment below lines to add portlet taglibs to jsp
|
||||
<%@ page import="javax.portlet.*"%>
|
||||
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet"%>
|
||||
|
||||
<portlet:defineObjects />
|
||||
--%>
|
||||
|
||||
<script type="text/javascript">
|
||||
if(window.parent.PageBus) {
|
||||
window.PageBus = window.parent.PageBus;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" language="javascript"
|
||||
src='<%=request.getContextPath()%>/shareupdates/shareupdates.nocache.js'></script>
|
||||
<div id="shareUpdateDiv"></div>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE display PUBLIC "-//Liferay//DTD Display 6.0.0//EN" "http://www.liferay.com/dtd/liferay-display_6_0_0.dtd">
|
||||
|
||||
<display>
|
||||
<category name="gCube Social Apps">
|
||||
<portlet id="ShareUpdates" />
|
||||
</category>
|
||||
</display>
|
|
@ -0,0 +1,9 @@
|
|||
name=ShareUpdates
|
||||
module-group-id=liferay
|
||||
module-incremental-version=1
|
||||
tags=
|
||||
short-description=
|
||||
change-log=
|
||||
page-url=http://www.liferay.com
|
||||
author=Liferay, Inc.
|
||||
licenses=LGPL
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE liferay-portlet-app PUBLIC "-//Liferay//DTD Portlet Application 5.2.0//EN" "http://www.liferay.com/dtd/liferay-portlet-app_6_0_0.dtd">
|
||||
|
||||
<liferay-portlet-app>
|
||||
<portlet>
|
||||
<portlet-name>ShareUpdates</portlet-name>
|
||||
<layout-cacheable>false</layout-cacheable>
|
||||
<instanceable>false</instanceable>
|
||||
<ajaxable>false</ajaxable>
|
||||
<header-portlet-css>/ShareUpdates.css</header-portlet-css>
|
||||
<header-portlet-javascript>/js/pagebus.js</header-portlet-javascript>
|
||||
</portlet>
|
||||
<role-mapper>
|
||||
<role-name>administrator</role-name>
|
||||
<role-link>Administrator</role-link>
|
||||
</role-mapper>
|
||||
<role-mapper>
|
||||
<role-name>guest</role-name>
|
||||
<role-link>Guest</role-link>
|
||||
</role-mapper>
|
||||
<role-mapper>
|
||||
<role-name>power-user</role-name>
|
||||
<role-link>Power User</role-link>
|
||||
</role-mapper>
|
||||
<role-mapper>
|
||||
<role-name>user</role-name>
|
||||
<role-link>User</role-link>
|
||||
</role-mapper>
|
||||
</liferay-portlet-app>
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<portlet-app
|
||||
version="2.0"
|
||||
xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
|
||||
>
|
||||
<portlet>
|
||||
<portlet-name>ShareUpdates</portlet-name>
|
||||
<display-name>ShareUpdates</display-name>
|
||||
<portlet-class>org.gcube.portlets.user.shareupdates.server.portlet.ShareUpdatesPortlet</portlet-class>
|
||||
<init-param>
|
||||
<name>view-jsp</name>
|
||||
<value>/view.jsp</value>
|
||||
</init-param>
|
||||
<expiration-cache>0</expiration-cache>
|
||||
<supports>
|
||||
<mime-type>text/html</mime-type>
|
||||
</supports>
|
||||
<portlet-info>
|
||||
<title>Share updates</title>
|
||||
<short-title>Share</short-title>
|
||||
<keywords>Share Updates</keywords>
|
||||
</portlet-info>
|
||||
<security-role-ref>
|
||||
<role-name>administrator</role-name>
|
||||
</security-role-ref>
|
||||
</portlet>
|
||||
</portlet-app>
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
|
||||
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
|
||||
version="2.5"
|
||||
xmlns="http://java.sun.com/xml/ns/javaee">
|
||||
|
||||
<!-- Servlets -->
|
||||
<servlet>
|
||||
<servlet-name>shareupdateServlet</servlet-name>
|
||||
<servlet-class>org.gcube.portlets.user.shareupdates.server.ShareUpdateServiceImpl</servlet-class>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>shareupdateServlet</servlet-name>
|
||||
<url-pattern>/shareupdates/shareupdateServlet</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Default page to serve -->
|
||||
<welcome-file-list>
|
||||
<welcome-file>ShareUpdates.html</welcome-file>
|
||||
</welcome-file-list>
|
||||
|
||||
</web-app>
|
Binary file not shown.
After Width: | Height: | Size: 997 B |
Binary file not shown.
After Width: | Height: | Size: 5.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 316 B |
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
After Width: | Height: | Size: 210 B |
|
@ -0,0 +1,182 @@
|
|||
/**
|
||||
* Copyright (c) 2006-2007, TIBCO Software Inc.
|
||||
* Use, modification, and distribution subject to terms of license.
|
||||
*
|
||||
* TIBCO(R) PageBus 1.1.0
|
||||
*/
|
||||
|
||||
if(typeof window.PageBus == 'undefined') {
|
||||
|
||||
PageBus = {
|
||||
version: "1.1.0",
|
||||
S: {c:{},s:[]},
|
||||
X: 0,
|
||||
P: 0,
|
||||
U: [],
|
||||
H: "undefined"
|
||||
};
|
||||
|
||||
PageBus.subscribe = function(name, scope, callback, subscriberData)
|
||||
{
|
||||
if(name == null)
|
||||
this._badName();
|
||||
if(scope == null)
|
||||
scope = window;
|
||||
var path = name.split(".");
|
||||
var sub = { f: callback, d: subscriberData, i: this.X++, p: path, w: scope };
|
||||
for(var i = 0; i < path.length; i++) {
|
||||
if((path[i].indexOf("*") != -1) && (path[i] != "*") && (path[i] != "**"))
|
||||
this._badName();
|
||||
}
|
||||
this._subscribe(this.S, path, 0, sub);
|
||||
return sub;
|
||||
}
|
||||
|
||||
PageBus.publish = function (name, message)
|
||||
{
|
||||
if((name == null) || (name.indexOf("*") != -1))
|
||||
this._badName();
|
||||
var path = name.split(".");
|
||||
if(this.P > 100)
|
||||
this._throw("StackOverflow");
|
||||
try {
|
||||
this.P++;
|
||||
this._publish(this.S, path, 0, name, message);
|
||||
}
|
||||
catch(err) {
|
||||
this.P--;
|
||||
throw err;
|
||||
}
|
||||
try {
|
||||
this.P--;
|
||||
if((this.U.length > 0) && (this.P == 0)) {
|
||||
for(var i = 0; i < this.U.length; i++)
|
||||
this.unsubscribe(this.U[i]);
|
||||
this.U = [];
|
||||
}
|
||||
}
|
||||
catch(err) {
|
||||
// All unsubscribe exceptions should already have
|
||||
// been handled when unsubscribe was called in the
|
||||
// publish callback. This is a repeat appearance
|
||||
// of this exception. Discard it.
|
||||
}
|
||||
}
|
||||
|
||||
PageBus.unsubscribe = function(sub)
|
||||
{
|
||||
this._unsubscribe(this.S, sub.p, 0, sub.i);
|
||||
}
|
||||
|
||||
/*
|
||||
* @private @jsxobf-clobber
|
||||
*/
|
||||
PageBus._throw = function(n)
|
||||
{
|
||||
throw new Error("PageBus." + n);
|
||||
}
|
||||
|
||||
/*
|
||||
* @private @jsxobf-clobber
|
||||
*/
|
||||
PageBus._badName = function(n)
|
||||
{
|
||||
this._throw("BadName");
|
||||
}
|
||||
|
||||
/*
|
||||
* @private @jsxobf-clobber
|
||||
*/
|
||||
PageBus._subscribe = function(tree, path, index, sub)
|
||||
{
|
||||
var tok = path[index];
|
||||
if(tok == "")
|
||||
this._badName();
|
||||
if(index == path.length)
|
||||
tree.s.push(sub);
|
||||
else {
|
||||
if(typeof tree.c == this.H)
|
||||
tree.c = {};
|
||||
if(typeof tree.c[tok] == this.H) {
|
||||
try {
|
||||
tree.c[tok] = { c: {}, s: [] };
|
||||
this._subscribe(tree.c[tok], path, index + 1, sub);
|
||||
}
|
||||
catch(err) {
|
||||
delete tree.c[tok];
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
else
|
||||
this._subscribe( tree.c[tok], path, index + 1, sub );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @private @jsxobf-clobber
|
||||
*/
|
||||
PageBus._publish = function(tree, path, index, name, msg) {
|
||||
if(path[index] == "")
|
||||
this._badName();
|
||||
if(typeof tree != this.H) {
|
||||
if(index < path.length) {
|
||||
this._publish(tree.c[path[index]], path, index + 1, name, msg);
|
||||
this._publish(tree.c["*"], path, index + 1, name, msg);
|
||||
this._call(tree.c["**"], name, msg);
|
||||
}
|
||||
else
|
||||
this._call(tree, name, msg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @private @jsxobf-clobber
|
||||
*/
|
||||
PageBus._call = function(node, name, msg) {
|
||||
if(typeof node != this.H) {
|
||||
var callbacks = node.s;
|
||||
var max = callbacks.length;
|
||||
for(var i = 0; i < max; i++)
|
||||
if(callbacks[i].f != null)
|
||||
callbacks[i].f.apply(callbacks[i].w, [name, msg, callbacks[i].d]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @jsxobf-clobber
|
||||
*/
|
||||
PageBus._unsubscribe = function(tree, path, index, sid) {
|
||||
if(typeof tree != this.H) {
|
||||
if(index < path.length) {
|
||||
var childNode = tree.c[path[index]];
|
||||
this._unsubscribe(childNode, path, index + 1, sid);
|
||||
if(childNode.s.length == 0) {
|
||||
for(var x in childNode.c) // not empty. We're done.
|
||||
return;
|
||||
delete tree.c[path[index]]; // if we got here, c is empty
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
var callbacks = tree.s;
|
||||
var max = callbacks.length;
|
||||
for(var i = 0; i < max; i++) {
|
||||
if(sid == callbacks[i].i) {
|
||||
if(this.P > 0) {
|
||||
if(callbacks[i].f == null)
|
||||
this._throw("BadParameter");
|
||||
callbacks[i].f = null;
|
||||
this.U.push(callbacks[i]);
|
||||
}
|
||||
else
|
||||
callbacks.splice(i, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Not found. Fall through
|
||||
}
|
||||
}
|
||||
this._throw("BadParameter");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package org.gcube.portlets.user.shareupdates.client;
|
||||
|
||||
import com.google.gwt.junit.client.GWTTestCase;
|
||||
|
||||
/**
|
||||
* GWT JUnit <b>integration</b> tests must extend GWTTestCase.
|
||||
* Using <code>"GwtTest*"</code> naming pattern exclude them from running with
|
||||
* surefire during the test phase.
|
||||
*
|
||||
* If you run the tests using the Maven command line, you will have to
|
||||
* navigate with your browser to a specific url given by Maven.
|
||||
* See http://mojo.codehaus.org/gwt-maven-plugin/user-guide/testing.html
|
||||
* for details.
|
||||
*/
|
||||
public class GwtTestShareUpdates extends GWTTestCase {
|
||||
|
||||
/**
|
||||
* Must refer to a valid module that sources this class.
|
||||
*/
|
||||
public String getModuleName() {
|
||||
return "org.gcube.portlets.user.shareupdates.ShareUpdatesJUnit";
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the FieldVerifier.
|
||||
*/
|
||||
public void testFieldVerifier() {
|
||||
}
|
||||
|
||||
/**
|
||||
* This test will send a request to the server using the greetServer method in
|
||||
* GreetingService and verify the response.
|
||||
*/
|
||||
public void testGreetingService() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module>
|
||||
<!-- Inherit our applications main module. -->
|
||||
<inherits name='org.gcube.portlets.user.shareupdates.ShareUpdates' />
|
||||
|
||||
</module>
|
Loading…
Reference in New Issue