diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..1151b0d
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.project b/.project
new file mode 100644
index 0000000..cc814fd
--- /dev/null
+++ b/.project
@@ -0,0 +1,42 @@
+
+
+ social-mail-servlet
+
+
+
+
+
+ org.eclipse.wst.jsdt.core.javascriptValidator
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.wst.common.project.facet.core.builder
+
+
+
+
+ org.eclipse.wst.validation.validationbuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jem.workbench.JavaEMFNature
+ org.eclipse.wst.common.modulecore.ModuleCoreNature
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+ org.eclipse.wst.common.project.facet.core.nature
+ org.eclipse.wst.jsdt.core.jsNature
+
+
diff --git a/.settings/.jsdtscope b/.settings/.jsdtscope
new file mode 100644
index 0000000..b72a6a4
--- /dev/null
+++ b/.settings/.jsdtscope
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..db32697
--- /dev/null
+++ b/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+encoding//src/main/resources=UTF-8
+encoding/=UTF-8
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..443e085
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
+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.7
diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component
new file mode 100644
index 0000000..7bedda1
--- /dev/null
+++ b/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 0000000..4045d87
--- /dev/null
+++ b/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.settings/org.eclipse.wst.jsdt.ui.superType.container b/.settings/org.eclipse.wst.jsdt.ui.superType.container
new file mode 100644
index 0000000..3bd5d0a
--- /dev/null
+++ b/.settings/org.eclipse.wst.jsdt.ui.superType.container
@@ -0,0 +1 @@
+org.eclipse.wst.jsdt.launching.baseBrowserLibrary
\ No newline at end of file
diff --git a/.settings/org.eclipse.wst.jsdt.ui.superType.name b/.settings/org.eclipse.wst.jsdt.ui.superType.name
new file mode 100644
index 0000000..05bd71b
--- /dev/null
+++ b/.settings/org.eclipse.wst.jsdt.ui.superType.name
@@ -0,0 +1 @@
+Window
\ No newline at end of file
diff --git a/.settings/org.eclipse.wst.validation.prefs b/.settings/org.eclipse.wst.validation.prefs
new file mode 100644
index 0000000..04cad8c
--- /dev/null
+++ b/.settings/org.eclipse.wst.validation.prefs
@@ -0,0 +1,2 @@
+disabled=06target
+eclipse.preferences.version=1
diff --git a/distro/INSTALL b/distro/INSTALL
new file mode 100644
index 0000000..139597f
--- /dev/null
+++ b/distro/INSTALL
@@ -0,0 +1,2 @@
+
+
diff --git a/distro/LICENSE b/distro/LICENSE
new file mode 100644
index 0000000..cdb5851
--- /dev/null
+++ b/distro/LICENSE
@@ -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.
+
diff --git a/distro/MAINTAINERS b/distro/MAINTAINERS
new file mode 100644
index 0000000..680cebb
--- /dev/null
+++ b/distro/MAINTAINERS
@@ -0,0 +1,6 @@
+Mantainers
+-------
+
+* Massimiliano Assante (massimiliano.assante@isti.cnr.it), CNR Pisa,
+ Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo".
+
diff --git a/distro/README b/distro/README
new file mode 100644
index 0000000..3b378a6
--- /dev/null
+++ b/distro/README
@@ -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
+------------------------
+
+
+
+Description
+-----------
+Social Mail Servlet
+
+Download information
+--------------------
+Source code is available from SVN:
+https://svn.d4science.research-infrastructures.eu/gcube/trunk/portal/social-mail-servlet
+
+Binaries can be downloaded from:
+http://www.gcube-system.org/
+
+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.
diff --git a/distro/changelog.xml b/distro/changelog.xml
new file mode 100644
index 0000000..48a2030
--- /dev/null
+++ b/distro/changelog.xml
@@ -0,0 +1,5 @@
+
+
+ First Release
+
+
diff --git a/distro/descriptor.xml b/distro/descriptor.xml
new file mode 100644
index 0000000..4efc827
--- /dev/null
+++ b/distro/descriptor.xml
@@ -0,0 +1,48 @@
+
+ servicearchive
+
+ tar.gz
+
+ /
+
+
+ ${distroDirectory}
+ /
+ true
+
+ README
+ LICENSE
+ INSTALL
+ MAINTAINERS
+ changelog.xml
+
+ 755
+ true
+
+
+ target/apidocs
+ /${artifactId}/doc/api
+ true
+ 755
+
+
+
+
+
+ ./
+ true
+
+
+
+ /${artifactId}
+
+
+
+ /${artifactId}
+ true
+
+
+
\ No newline at end of file
diff --git a/distro/profile.xml b/distro/profile.xml
new file mode 100644
index 0000000..4dda0b9
--- /dev/null
+++ b/distro/profile.xml
@@ -0,0 +1,25 @@
+
+
+
+ Library
+
+ ${description}
+ Portal
+ ${artifactId}
+ 1.0.0
+
+
+ ${artifactId}
+ ${version}
+
+ ${groupId}
+ ${artifactId}
+ ${version}
+
+
+ ${build.finalName}.war
+
+
+
+
+
diff --git a/distro/svnpath.txt b/distro/svnpath.txt
new file mode 100644
index 0000000..edacb04
--- /dev/null
+++ b/distro/svnpath.txt
@@ -0,0 +1 @@
+${scm.url}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..756fde0
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,200 @@
+
+
+ maven-parent
+ org.gcube.tools
+ 1.0.0
+
+
+
+ 4.0.0
+ org.gcube.portal
+ social-mail-servlet
+ war
+ 1.0.0-SNAPSHOT
+ social-mail-servlet Maven Webapp
+ This component read periodically email replies from user wanting to reply to a post via email
+
+ 1.7
+ 6.0.6
+ ${project.basedir}/distro
+ ${project.build.directory}/${project.build.finalName}
+ distro
+
+ UTF-8
+ UTF-8
+
+
+
+
+ http://svn.d4science.research-infrastructures.eu/gcube/trunk/portal/${project.artifactId}
+
+
+
+
+ org.gcube.distribution
+ maven-portal-bom
+ LATEST
+ pom
+ import
+
+
+
+
+
+ org.gcube.common.portal
+ portal-manager
+
+
+ org.gcube.portal
+ custom-portal-handler
+ provided
+
+
+ org.gcube.applicationsupportlayer
+ aslcore
+ provided
+
+
+ org.gcube.applicationsupportlayer
+ aslsocial
+ provided
+
+
+ org.gcube.portal
+ social-networking-library
+ provided
+
+
+ com.google
+ gwt-jsonmaker
+
+
+ org.gcube.dvos
+ usermanagement-core
+
+
+ org.gcube.resources.discovery
+ ic-client
+
+
+ org.gcube.core
+ common-encryption
+ provided
+
+
+ com.sun.mail
+ javax.mail
+ provided
+
+
+ com.liferay.portal
+ portal-service
+ provided
+
+
+ javax.portlet
+ portlet-api
+ provided
+
+
+ javax.servlet
+ servlet-api
+ 2.3
+ provided
+
+
+ javax.servlet.jsp
+ jsp-api
+ 2.0
+ provided
+
+
+ org.slf4j
+ slf4j-api
+ provided
+
+
+ junit
+ junit
+ 3.8.1
+ test
+
+
+
+ social-mail-servlet
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+ 2.1.1
+
+
+ compile
+
+ exploded
+
+
+
+
+ ${webappDirectory}
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 2.3.2
+
+
+ 1.7
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 2.2
+
+
+ ${distroDirectory}/descriptor.xml
+
+
+
+
+ servicearchive
+ install
+
+ single
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+ 2.5
+
+
+ copy-profile
+ install
+
+ copy-resources
+
+
+ target
+
+
+ ${distroDirectory}
+ true
+
+ profile.xml
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/org/gcube/portal/socialmail/MailReader.java b/src/main/java/org/gcube/portal/socialmail/MailReader.java
new file mode 100644
index 0000000..6d27a5f
--- /dev/null
+++ b/src/main/java/org/gcube/portal/socialmail/MailReader.java
@@ -0,0 +1,102 @@
+package org.gcube.portal.socialmail;
+
+import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
+import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.gcube.common.encryption.StringEncrypter;
+import org.gcube.common.portal.PortalContext;
+import org.gcube.common.resources.gcore.ServiceEndpoint;
+import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
+import org.gcube.common.scope.api.ScopeProvider;
+import org.gcube.portal.databook.server.DBCassandraAstyanaxImpl;
+import org.gcube.portal.databook.server.DatabookStore;
+import org.gcube.resources.discovery.client.api.DiscoveryClient;
+import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+@SuppressWarnings("serial")
+public class MailReader extends HttpServlet {
+
+ private static final Logger _log = LoggerFactory.getLogger(MailReader.class);
+ private static final int MINUTES_DELAY = 1;
+
+ private final static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
+
+ private static DatabookStore store;
+
+ private static String portalName;
+ private static String host;
+ private static String user;
+ private static String password;
+
+ public void init() {
+ store = new DBCassandraAstyanaxImpl();
+ portalName = PortalContext.getPortalInstanceName();
+
+ PortalContext context = PortalContext.getConfiguration();
+ String scope = "/" + context.getInfrastructureName();
+ ScopeProvider.instance.set(scope);
+
+ SimpleQuery query = queryFor(ServiceEndpoint.class);
+ query.addCondition("$resource/Profile/Category/text() eq 'Portal'");
+ query.addCondition("$resource/Profile/Name/text() eq '" + portalName + "'");
+
+ DiscoveryClient client = clientFor(ServiceEndpoint.class);
+
+ List list = client.submit(query);
+ if (list == null || list.isEmpty()) {
+ _log.error("Could not find any Service endpoint registred in the infrastructure for this portal: " + portalName);
+ }
+ else if (list.size() > 1) {
+ _log.warn("Found more than one Service endpoint registred in the infrastructure for this portal: " + portalName);
+ }
+ else {
+ for (ServiceEndpoint res : list) {
+ AccessPoint found = res.profile().accessPoints().iterator().next();
+ host = found.address();
+ user = found.username();
+ String encrPassword = found.password();
+
+ try {
+ password = StringEncrypter.getEncrypter().decrypt( encrPassword);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+
+ scheduler.scheduleAtFixedRate(new PeriodicTask(store, portalName, host, user, password), 0, MINUTES_DELAY, TimeUnit.MINUTES);
+
+ String toReturn = "Check Notification Email Started ... ";
+ response.setContentType("text/html");
+ response.getWriter().write(toReturn);
+ }
+
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}
+
+ public static void main(String[] args) {
+ new MailReader().init();
+ System.out.println("Scheduling periodic task ... ");
+ //System.out.println(host + user + password);
+ scheduler.scheduleAtFixedRate(new PeriodicTask(store, portalName, host, user, password), 0, MINUTES_DELAY, TimeUnit.MINUTES);
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/gcube/portal/socialmail/PeriodicTask.java b/src/main/java/org/gcube/portal/socialmail/PeriodicTask.java
new file mode 100644
index 0000000..b044a22
--- /dev/null
+++ b/src/main/java/org/gcube/portal/socialmail/PeriodicTask.java
@@ -0,0 +1,233 @@
+package org.gcube.portal.socialmail;
+
+import java.security.GeneralSecurityException;
+import java.util.Date;
+import java.util.Properties;
+import java.util.UUID;
+
+import javax.mail.Address;
+import javax.mail.BodyPart;
+import javax.mail.Flags;
+import javax.mail.Folder;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Multipart;
+import javax.mail.NoSuchProviderException;
+import javax.mail.Session;
+import javax.mail.Store;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage.RecipientType;
+
+import org.gcube.application.framework.core.session.ASLSession;
+import org.gcube.application.framework.core.session.SessionManager;
+import org.gcube.application.framework.core.util.GenderType;
+import org.gcube.applicationsupportlayer.social.mailing.EmailPlugin;
+import org.gcube.common.portal.PortalContext;
+import org.gcube.portal.custom.communitymanager.OrganizationsUtil;
+import org.gcube.portal.databook.server.DatabookStore;
+import org.gcube.portal.databook.shared.Comment;
+import org.gcube.portal.databook.shared.ex.FeedIDNotFoundException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.liferay.portal.kernel.exception.PortalException;
+import com.liferay.portal.kernel.exception.SystemException;
+import com.liferay.portal.model.User;
+import com.liferay.portal.service.UserLocalServiceUtil;
+import com.sun.mail.util.MailSSLSocketFactory;
+
+/**
+ *
+ * @author Massimiliano Assante, CNR-ISTI
+ *
+ */
+public class PeriodicTask implements Runnable {
+ private static final Logger _log = LoggerFactory.getLogger(PeriodicTask.class);
+
+ private DatabookStore socialStore;
+ private String host;
+ private String mailserver_username;
+ private String password;
+ private String portalName;
+
+ public PeriodicTask(DatabookStore store, String portalName, String host, String mailserver_username, String password) {
+ super();
+ this.socialStore = store;
+ this.portalName = portalName;
+ this.host = host;
+ this.mailserver_username = mailserver_username;
+ this.password = password;
+ }
+
+
+ @Override
+ public void run() {
+ //check("pop.isti.cnr.it", "social.post", "kof9044+");
+ check(portalName, host, mailserver_username, password);
+
+ }
+ /**
+ * @return a fake session usuful for Notifications
+ */
+ private ASLSession getFakeASLSession(String emailAddress) {
+ String sessionID = UUID.randomUUID().toString();
+ PortalContext context = PortalContext.getConfiguration();
+ String scope = "/" + context.getInfrastructureName();
+
+ String username = "";
+ long companyId;
+ try {
+ companyId = OrganizationsUtil.getCompany().getCompanyId();
+ User user = UserLocalServiceUtil.getUserByEmailAddress(companyId, emailAddress);
+ username = user.getScreenName();
+ SessionManager.getInstance().getASLSession(sessionID, username).setScope(scope);
+
+ //add the social information needed by apps
+ String fullName = user.getFirstName() + " " + user.getLastName();
+ String email = user.getEmailAddress();
+ String thumbnailURL = "/image/user_male_portrait?img_id="+user.getPortraitId();
+ boolean isMale = user.isMale();
+
+ SessionManager.getInstance().getASLSession(sessionID, username).setUserFullName(fullName);
+ SessionManager.getInstance().getASLSession(sessionID, username).setUserEmailAddress(email);
+ SessionManager.getInstance().getASLSession(sessionID, username).setUserAvatarId(thumbnailURL);
+ SessionManager.getInstance().getASLSession(sessionID, username).setUserGender(isMale? GenderType.MALE : GenderType.FEMALE);
+
+ } catch (PortalException | SystemException e) {
+ e.printStackTrace();
+ }
+
+
+ return SessionManager.getInstance().getASLSession(sessionID, username);
+ }
+
+ public void check(String portalName, String host, String user, String password) {
+ try {
+ MailSSLSocketFactory sf = null;
+ try {
+ sf = new MailSSLSocketFactory();
+ }
+ catch (GeneralSecurityException e) {
+ e.printStackTrace();
+ }
+ sf.setTrustAllHosts(true);
+
+ Properties pop3Props = new Properties();
+ pop3Props.setProperty("mail.pop3.ssl.enable", "true");
+ pop3Props.setProperty("mail.protocol.ssl.trust", host);
+ pop3Props.put("mail.pop3s.ssl.socketFactory", sf);
+ pop3Props.setProperty("mail.pop3s.port", "995");
+
+
+ Session emailSession = Session.getDefaultInstance(pop3Props);
+ //emailSession.setDebug(true);
+
+ //create the POP3 socialStore object and connect with the pop server
+ Store store = emailSession.getStore("pop3s");
+
+ store.connect(host, user, password);
+
+ //create the folder object and open it
+ Folder emailFolder = store.getFolder("INBOX");
+ emailFolder.open(Folder.READ_WRITE);
+
+ // retrieve the messages from the folder in an array and print it
+ Message[] messages = emailFolder.getMessages();
+ _log.debug("Found " + messages.length + " new messages ...");
+
+ for (int i = 0, n = messages.length; i < n; i++) {
+ Message message = messages[i];
+ _log.debug("--------------- FOUND EMAIL ------------------");
+ String subject = message.getSubject();
+ _log.debug("Parsing email of " + message.getFrom()[0] + " with subject: " + subject);
+
+ String feedId = extractFeedId(message);
+ String commentText = extractText(portalName, feedId, message);
+
+ String escapedCommentText = Utils.escapeHtmlAndTransformUrl(commentText);
+
+
+ Address[] froms = message.getFrom();
+ String emailAddress = froms == null ? null : ((InternetAddress) froms[0]).getAddress();
+
+ ASLSession fakeSession = getFakeASLSession(emailAddress);
+
+ Comment comment = new Comment(UUID.randomUUID().toString(), fakeSession.getUsername(),
+ new Date(), feedId, escapedCommentText, fakeSession.getUserFullName(), fakeSession.getUserAvatarId());
+
+ _log.debug("Parsed and escapedCommentText =>" + escapedCommentText);
+ boolean commentCommitResult = false;
+ try {
+ if (socialStore.addComment(comment))
+ commentCommitResult = true;
+ } catch (FeedIDNotFoundException e) {
+ _log.error("Related post not found for this comment " + e.getMessage());
+ e.printStackTrace();
+ }
+ if (commentCommitResult) { //the notify
+ _log.info("Now the NOTIFICATION SHOULD START!!!!!");
+ }
+
+
+ message.setFlag(Flags.Flag.DELETED, true);
+ System.out.println("Marked DELETE for message: " + subject);
+ }
+
+ //close the socialStore and folder objects
+ emailFolder.close(true);
+ store.close();
+
+ } catch (NoSuchProviderException e) {
+ e.printStackTrace();
+ } catch (MessagingException e) {
+ e.printStackTrace();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private String extractFeedId(Message message) throws MessagingException {
+ Address[] emails = message.getRecipients(RecipientType.TO);
+ String toParse = emails[0].toString();
+ int plus = toParse.indexOf('+');
+ int at = toParse.indexOf('@');
+ if (plus == -1)
+ return null;
+ return toParse.substring(plus+1, at);
+ }
+
+ private String extractText(String portalName, String subjectId, Message message) throws Exception {
+ Address[] emails = message.getRecipients(RecipientType.TO);
+ Object messageContent = message.getContent();
+ String toParse = null;
+ // Check if content is pure text/html or in parts
+ if (messageContent instanceof Multipart) {
+ _log.debug("Found Multipart Message, getting text part");
+ Multipart multipart = (Multipart) messageContent;
+ BodyPart part = multipart.getBodyPart(0);
+ part.toString();
+ toParse = part.getContent().toString();
+ }
+ else {
+ _log.debug("Found g text/plain Message, getting text");
+ toParse = messageContent.toString();
+ }
+
+ String[] lines = toParse.split(System.getProperty("line.separator"));
+ int until = -1;
+ for (int i = 0; i < lines.length; i++) {
+ if (lines[i].contains(EmailPlugin.WRITE_ABOVE_TO_REPLY)) {
+ until = i;
+ break;
+ }
+ }
+ String toReturn = "";
+ for (int i = 0; i < until; i++) {
+ if (! ( lines[i].contains(portalName) || lines[i].contains(subjectId) || (lines[i].startsWith("> ") && lines[i].trim().length() < 2)) ) {
+ toReturn += lines[i];
+ }
+ }
+ return toReturn;
+
+ }
+}
diff --git a/src/main/java/org/gcube/portal/socialmail/Utils.java b/src/main/java/org/gcube/portal/socialmail/Utils.java
new file mode 100644
index 0000000..36dee71
--- /dev/null
+++ b/src/main/java/org/gcube/portal/socialmail/Utils.java
@@ -0,0 +1,83 @@
+package org.gcube.portal.socialmail;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Utils {
+ private static final Logger _log = LoggerFactory.getLogger(Utils.class);
+ /**
+ * 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
+ */
+ protected static String escapeHtmlAndTransformUrl(String html) {
+ if (html == null) {
+ return null;
+ }
+ String toReturn = html.replaceAll("&", "&").replaceAll("<", "<")
+ .replaceAll(">", ">");
+
+ // replace all the line breaks by
+ toReturn = toReturn.replaceAll("(\r\n|\n)","
");
+ //transfrom the URL in a clickable URL
+ toReturn = transformUrls(toReturn);
+ // then replace all the double spaces by the html version
+ toReturn = toReturn.replaceAll("\\s\\s"," ");
+ return toReturn;
+ }
+ /**
+ * utility 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
+ */
+ protected static 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++) {
+ String toCheck = getHttpToken(parts[i]);
+ if (toCheck != null) {
+ try {
+ URL url = new URL(toCheck);
+ if (i == 0 && parts.length == 1) //then he shared just a link
+ return sb.append("shared ").append("a link.").append(" ").toString();
+ // If possible then replace with anchor...
+ sb.append("").append(url).append(" ");
+ } 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();
+ }
+ /**
+ * check the tokens of a pasted text and see if there's any http link in it
+ * @param item a text token
+ * @return the actual http link
+ */
+ private static String getHttpToken(String item) {
+ if (item.startsWith("http") || item.startsWith("www") || item.startsWith("(www") || item.startsWith("(http")) {
+ if (item.startsWith("("))
+ item = item.substring(1, item.length());
+ if (item.endsWith(".") || item.endsWith(")")) { //sometimes people write the url and close the phrase with a .
+ item = item.substring(0, item.length()-1);
+ }
+ item = item.startsWith("www") ? "http://"+item : item;
+ //System.out.println("getHttpToken returns -> " + item);
+ return item;
+ }
+ return null;
+ }
+}
diff --git a/src/main/resources/clientlog4j.properties b/src/main/resources/clientlog4j.properties
new file mode 100644
index 0000000..574c7b1
--- /dev/null
+++ b/src/main/resources/clientlog4j.properties
@@ -0,0 +1,13 @@
+log4j.rootLogger=DEBUG, A1
+log4j.appender.A1=org.apache.log4j.ConsoleAppender
+log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+
+# Print the date in ISO 8601 format
+log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
+
+# Print only messages of level TRACE or above in the package org.gcube
+log4j.logger.org.gcube=TRACE
+log4j.logger.org.gcube.application.framework.core.session=INFO
+log4j.logger.com.netflix.astyanax.connectionpool=ERROR
+log4j.logger.org.gcube.portal.databook.server.DBCassandraAstyanaxImpl=TRACE
+log4j.logger.org.gcube.common=ERROR
\ No newline at end of file
diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..0dbac63
--- /dev/null
+++ b/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,17 @@
+
+
+
+ Email Comments Reader Webapp
+
+
+ read-mail
+ org.gcube.portal.socialmail.MailReader
+
+
+ read-mail
+ /read-mail
+
+
+
diff --git a/src/main/webapp/index.jsp b/src/main/webapp/index.jsp
new file mode 100644
index 0000000..04fa808
--- /dev/null
+++ b/src/main/webapp/index.jsp
@@ -0,0 +1,5 @@
+
+
+Hello From Mail Reader Scheduler service!
+
+