diff --git a/pom.xml b/pom.xml
index a3bd99a..17b1ac2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -20,7 +20,6 @@
1.61.6
-
UTF-8UTF-8
@@ -150,5 +149,16 @@
usermanagement-core1.3.0-SNAPSHOT
+
+ log4j
+ log4j
+ 1.2.6
+
+
+ commons-net
+ commons-net
+ 2.0
+ ftp
+
diff --git a/src/main/java/org/gcube/applicationsupportlayer/social/ApplicationNewsManager.java b/src/main/java/org/gcube/applicationsupportlayer/social/ApplicationNewsManager.java
index 611c83d..a676af1 100644
--- a/src/main/java/org/gcube/applicationsupportlayer/social/ApplicationNewsManager.java
+++ b/src/main/java/org/gcube/applicationsupportlayer/social/ApplicationNewsManager.java
@@ -1,21 +1,28 @@
package org.gcube.applicationsupportlayer.social;
+import java.io.BufferedInputStream;
+import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
import java.util.UUID;
-import javax.servlet.http.HttpServlet;
-
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.net.ftp.FTP;
+import org.apache.commons.net.ftp.FTPClient;
import org.gcube.application.framework.core.session.ASLSession;
import org.gcube.applicationsupportlayer.social.ex.ApplicationProfileNotFoundException;
import org.gcube.applicationsupportlayer.social.imageType.ImageType;
import org.gcube.common.core.contexts.GHNContext;
+import org.gcube.common.core.informationsystem.client.AtomicCondition;
import org.gcube.common.core.informationsystem.client.ISClient;
import org.gcube.common.core.informationsystem.client.XMLResult;
import org.gcube.common.core.informationsystem.client.queries.GCUBEGenericQuery;
+import org.gcube.common.core.informationsystem.client.queries.GCUBERuntimeResourceQuery;
+import org.gcube.common.core.resources.GCUBERuntimeResource;
import org.gcube.common.core.scope.GCUBEScope;
-import org.gcube.portal.databook.shared.Application;
+import org.gcube.common.core.utils.logging.GCUBEClientLog;
+import org.gcube.portal.databook.shared.ApplicationProfile;
import org.gcube.portal.databook.shared.Feed;
import org.gcube.portal.databook.shared.FeedType;
import org.gcube.portal.databook.shared.PrivacyLevel;
@@ -26,68 +33,79 @@ import org.gcube.portal.databook.shared.PrivacyLevel;
* @author Massimiliano Assante, ISTI-CNR
* @version 0.1 Dec 2012
*
- * use to share updates from within your application, the update will be published in the Users News Feed belonging to the VRE your application runs into
+ * use to share updates from within your applicationProfile, the update will be published in the Users News Feed belonging to the VRE your applicationProfile runs into
*/
public class ApplicationNewsManager extends SocialPortalBridge implements NewsManager {
+ static GCUBEClientLog _log = new GCUBEClientLog(ApplicationNewsManager.class);
+ private ApplicationProfile applicationProfile;
+
+ /**
+ * the FTP Server RuntimeResource coordinates
+ */
+ private static String RUNTIME_RESOURCE_NAME = "SocialPortalStorage";
+ private static String CATEGORY_NAME = "FTPServer";
- private Application application;
/**
*
* @param aslSession the ASLSession instance
- * @param applicationClass your servlet class name will be used ad unique identifier for your application
+ * @param portletClassName your servlet class name will be used ad unique identifier for your applicationProfile
*/
public ApplicationNewsManager(ASLSession session, String portletClassName) {
super(session);
- this.application = getProfileFromInfrastrucure(portletClassName);
+ this.applicationProfile = getProfileFromInfrastrucure(portletClassName);
}
+
+ public ApplicationProfile getApplicationProfile() {
+ return applicationProfile;
+ }
/**
- * this method looks up the application profile among the ones available in the infrastructure
- * @param applicationClass
- * @return the application profile
+ * this method looks up the applicationProfile profile among the ones available in the infrastructure
+ * @param portletClassName your servlet class name will be used ad unique identifier for your applicationProfile
+ * @return the applicationProfile profile
*/
- private Application getProfileFromInfrastrucure(String portletClassName) {
+ private ApplicationProfile getProfileFromInfrastrucure(String portletClassName) {
try {
- Application toReturn = new Application();
+ ApplicationProfile toReturn = new ApplicationProfile();
ISClient client = GHNContext.getImplementation(ISClient.class);
GCUBEGenericQuery query = client.getQuery(GCUBEGenericQuery.class);
-
-
+
+
query.setExpression("for $profile in collection('/db/Profiles/GenericResource')//Resource " +
"where $profile/Profile/SecondaryType/string() eq 'ApplicationProfile' and $profile/Profile/Body/AppId/string() " +
" eq '" + portletClassName + "'" +
"return $profile");
-
+
GCUBEScope scope = aslSession.getScope();
-
+
List appProfile = client.execute(query, scope.getInfrastructure());
if (appProfile == null || appProfile.size() == 0)
- throw new ApplicationProfileNotFoundException("Your application is not registered in the infrastructure");
+ throw new ApplicationProfileNotFoundException("Your applicationProfile is not registered in the infrastructure");
else {
XMLResult node = appProfile.get(0);
List currValue = null;
- currValue = node.evaluate("/Resource/Profile/Name/text()");
+ currValue = node.evaluate("/Resource/Profile/Name/text()");
if (currValue != null && currValue.size() > 0) {
toReturn.setName(currValue.get(0));
}
- else throw new ApplicationProfileNotFoundException("Your application NAME was not found in the profile");
-
+ else throw new ApplicationProfileNotFoundException("Your applicationProfile NAME was not found in the profile");
+
currValue = node.evaluate("/Resource/Profile/Description/text()");
if (currValue != null && currValue.size() > 0) {
toReturn.setDescription(currValue.get(0));
}
else _log.warn("No Description exists for " + toReturn.getName());
-
+
currValue = node.evaluate("/Resource/Profile/Body/AppId/text()");
if (currValue != null && currValue.size() > 0) {
toReturn.setKey(currValue.get(0));
}
- else throw new ApplicationProfileNotFoundException("Your application ID n was not found in the profile, consider adding element in ");
-
+ else throw new ApplicationProfileNotFoundException("Your applicationProfile ID n was not found in the profile, consider adding element in ");
+
currValue = node.evaluate("/Resource/Profile/Body/ThumbnailURL/text()");
if (currValue != null && currValue.size() > 0) {
toReturn.setImageUrl(currValue.get(0));
}
- else throw new ApplicationProfileNotFoundException("Your application Image Url was not found in the profile, consider adding element in ");
+ else throw new ApplicationProfileNotFoundException("Your applicationProfile Image Url was not found in the profile, consider adding element in ");
currValue = node.evaluate("/Resource/Profile/Body/EndPoint/Scope/text()");
if (currValue != null && currValue.size() > 0) {
List scopes = currValue;
@@ -101,14 +119,14 @@ public class ApplicationNewsManager extends SocialPortalBridge implements NewsMa
}
}
if (! foundUrl)
- throw new ApplicationProfileNotFoundException("Your application URL was not found in the profile for Scope: " + scope.toString());
+ throw new ApplicationProfileNotFoundException("Your applicationProfile URL was not found in the profile for Scope: " + scope.toString());
}
- else throw new ApplicationProfileNotFoundException("Your application EndPoint was not found in the profile, consider adding element in ");
+ else throw new ApplicationProfileNotFoundException("Your applicationProfile EndPoint was not found in the profile, consider adding element in ");
return toReturn;
}
-
+
} catch (Exception e) {
- _log.error("Error while trying to fetch application profile from the infrastructure");
+ _log.error("Error while trying to fetch applicationProfile profile from the infrastructure");
e.printStackTrace();
return null;
}
@@ -136,10 +154,18 @@ public class ApplicationNewsManager extends SocialPortalBridge implements NewsMa
return getStoreInstance().saveAppFeed(buildFeed(feedText, uriParams, previewTitle, previewDescription, previewThumbnailUrl));
}
/**
- * buid a an Application Feed
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean shareApplicationUpdate(String feedText, String uriParams, String previewTitle, String previewDescription, InputStream previewThumbnailInputStream, ImageType imageExtension) {
+ String httpImageUrl = uploadImageOnFTPServer(previewThumbnailInputStream, imageExtension);
+ return shareApplicationUpdate(feedText, uriParams, previewTitle, previewDescription, httpImageUrl);
+ }
+ /**
+ * buid a an ApplicationProfile Feed
*
* @param description add a description for the update you are sharing
- * @param uriParams the additional parameteres your application needs to open the subject of this update e.g. id=12345&type=foo
+ * @param uriParams the additional parameteres your applicationProfile needs to open the subject of this update e.g. id=12345&type=foo
* @param previewTitle the title to show in the preview
* @param previewDescription the description to show in the preview
* @param previewThumbnailUrl the image url to show in the preview
@@ -147,8 +173,8 @@ public class ApplicationNewsManager extends SocialPortalBridge implements NewsMa
*/
private Feed buildFeed(String description, String uriParams, String previewTitle, String previewDescription, String previewThumbnailUrl) {
String descToAdd = escapeHtml(description);
-
- String uri = application.getUrl();
+
+ String uri = applicationProfile.getUrl();
//add the GET params if necessary
if (uriParams != null && uriParams.compareTo("") != 0)
uri += "?"+uriParams;
@@ -158,27 +184,86 @@ public class ApplicationNewsManager extends SocialPortalBridge implements NewsMa
Feed toReturn = new Feed(
UUID.randomUUID().toString(),
FeedType.PUBLISH,
- application.getKey(),
+ applicationProfile.getKey(),
new Date(),
scope,
uri,
previewThumbnailUrl,
descToAdd,
PrivacyLevel.SINGLE_VRE,
- application.getName(),
+ applicationProfile.getName(),
"no-email",
- application.getImageUrl(),
+ applicationProfile.getImageUrl(),
previewTitle,
previewDescription,
"",
true);
return toReturn;
- }
- @Override
- public boolean shareApplicationUpdate(String feedtext, String uriGETparams,
- String previewTitle, String previewDescription,
- InputStream previewThumbnailInputStream, ImageType imageExtension) {
- // TODO Auto-generated method stub
- return false;
- }
+ }
+ /**
+ *
+ * @param previewThumbnailInputStream .
+ * @param imageExtension .
+ * @return the http url of the image uploaded on the ftp server
+ */
+ private String uploadImageOnFTPServer(InputStream previewThumbnailInputStream, ImageType imageExtension) {
+ FTPClient client = new FTPClient( );
+ InputStream inputStream = previewThumbnailInputStream;
+
+ String ftpUrl = "";
+ String user = "";
+ String pwd = "";
+ String httpBaseURL = "";
+ String fileName = UUID.randomUUID() + imageExtension.toString().toLowerCase();
+ try {
+ GCUBERuntimeResource res = getConfigurationFromIS();
+ ftpUrl = res.getAccessPoints().get(0).getEndpoint();
+ httpBaseURL = res.getHostedOn();
+ user = res.getAccessPoints().get(0).getUsername();
+ pwd = res.getAccessPoints().get(0).getPassword();
+
+ // Connect to the FTP server as anonymous
+ client.connect(ftpUrl);
+ client.login(user, pwd);
+
+ client.setFileType(FTP.BINARY_FILE_TYPE);
+ client.enterLocalPassiveMode();
+
+ BufferedInputStream bis = new BufferedInputStream(inputStream);
+ client.storeFile(fileName, bis);
+ bis.close();
+ client.logout();
+ } catch(IOException ioe) {
+ ioe.printStackTrace();
+ _log.error( "Error communicating with FTP server." );
+ } catch (Exception e) {
+ _log.error( "Probably sth wrong in fetching FTP Server RuntimeResource from IS" );
+ e.printStackTrace();
+ } finally {
+ IOUtils.closeQuietly( inputStream );
+ try {
+ client.disconnect( );
+ } catch (IOException e) {
+ _log.error( "Problem disconnecting from FTP server" );
+ }
+ }
+ StringBuilder sb = new StringBuilder().append(httpBaseURL).append(fileName);
+ _log.info( "Uploaded file FTP server: http url: " + sb );
+ return sb.toString();
+ }
+
+ /**
+ *
+ * @return the runtime resource of the FTP Server node
+ * @throws Exception
+ */
+ private GCUBERuntimeResource getConfigurationFromIS() throws Exception {
+ ISClient client = GHNContext.getImplementation(ISClient.class);
+ GHNContext ctx = GHNContext.getContext();
+ String scope = "/" + (String) ctx.getProperty(GHNContext.INFRASTRUCTURE_NAME, true);
+ GCUBERuntimeResourceQuery query = client.getQuery(GCUBERuntimeResourceQuery.class);
+ query.addAtomicConditions(new AtomicCondition("/Profile/Name", RUNTIME_RESOURCE_NAME));
+ query.addAtomicConditions(new AtomicCondition("/Profile/Category", CATEGORY_NAME));
+ return client.execute(query, GCUBEScope.getScope(scope)).get(0);
+ }
}
diff --git a/target/apidocs/allclasses-frame.html b/target/apidocs/allclasses-frame.html
new file mode 100644
index 0000000..ece1232
--- /dev/null
+++ b/target/apidocs/allclasses-frame.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+All Classes (Social Portal ASL Extension 0.1.0-SNAPSHOT API)
+
+
+
+
+
+
+
+
+
+
+
+All Classes
+
+
+
+This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
+Overview
+
+
+
+The Overview page is the front page of this API document and provides a list of all packages with a summary for each. This page can also contain an overall description of the set of packages.
+
+Package
+
+
+
+Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain four categories:
+
Interfaces (italic)
Classes
Enums
Exceptions
Errors
Annotation Types
+
+
+Class/Interface
+
+
+
+Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:
+
Class inheritance diagram
Direct Subclasses
All Known Subinterfaces
All Known Implementing Classes
Class/interface declaration
Class/interface description
+
+
Nested Class Summary
Field Summary
Constructor Summary
Method Summary
+
+
Field Detail
Constructor Detail
Method Detail
+Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.
+
+
+Annotation Type
+
+
+
+Each annotation type has its own separate page with the following sections:
+
Annotation Type declaration
Annotation Type description
Required Element Summary
Optional Element Summary
Element Detail
+
+
+
+Enum
+
+
+
+Each enum has its own separate page with the following sections:
+
Enum declaration
Enum description
Enum Constant Summary
Enum Constant Detail
+
+
+Use
+
+Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.
+
+Tree (Class Hierarchy)
+
+There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.
+
When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
+
+
+Deprecated API
+
+The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.
+
+Index
+
+The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.
+
+Prev/Next
+These links take you to the next or previous class, interface, package, or related page.
+Frames/No Frames
+These links show and hide the HTML frames. All pages are available with or without frames.
+
+
+Serialized Form
+Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.
+
0.1 Dec 2012
+
+ use to share updates from within your application, the update will be published in the Users News Feed belonging to the VRE your application runs into
+
Author:
+
Massimiliano Assante, ISTI-CNR
+
+
+
+
+
+
+
+
+
+
+Field Summary
+
+
+
+
+
+
Fields inherited from class org.gcube.applicationsupportlayer.social.SocialPortalBridge
shareApplicationUpdate(String feedText,
+ String uriParams)
+
+
+ use to share an update from your application with a reference to the news object
+
+
+
+ boolean
+
shareApplicationUpdate(String feedtext,
+ String uriGETparams,
+ String previewTitle,
+ String previewDescription,
+ InputStream previewThumbnailInputStream,
+ ImageType imageExtension)
+
+
+ use to share an update from your application with a reference to the news object and with a link preview passing its input stream
+
+
+
+ boolean
+
shareApplicationUpdate(String feedText,
+ String uriParams,
+ String previewTitle,
+ String previewDescription,
+ String previewThumbnailUrl)
+
+
+ use to share an update from your application with a reference to the news object and with a link preview
+
+
+
+
+
+
Methods inherited from class org.gcube.applicationsupportlayer.social.SocialPortalBridge
notifyAddedItem(String userIdToNotify,
+ org.gcube.portlets.user.homelibrary.home.workspace.WorkspaceItem newItem)
+
+
+ use to notify a user he got a workspace item new in some of his workspace shared folder
+
+
+
+ boolean
+
notifyCommentReply(String userIdToNotify,
+ org.gcube.portal.databook.shared.Comment comment)
+
+
+ use to notify a user that commented on a feed (Not his) that someone commented too
+
+
+
+ boolean
+
notifyFolderAddedUser(String userIdToNotify,
+ org.gcube.portlets.user.homelibrary.home.workspace.WorkspaceFolder sharedFolder,
+ String newAddedUserId)
+
+
+ use to notify a user that a new user was added in on of his workspace shared folder
+
+
+
+ boolean
+
notifyFolderRemovedUser(String userIdToNotify,
+ org.gcube.portlets.user.homelibrary.home.workspace.WorkspaceFolder sharedFolder,
+ String removedUserId)
+
+
+ use to notify a user that an existing user was removed from one of his workspace shared folder
+
+
+
+ boolean
+
notifyFolderSharing(String userIdToNotify,
+ org.gcube.portlets.user.homelibrary.home.workspace.WorkspaceFolder sharedFolder)
+
+
+ use to notify a user he got a workspace folder shared
+
+
+
+ boolean
+
notifyLikedFeed(String userIdToNotify,
+ org.gcube.portal.databook.shared.Feed likedFeed)
+
+
+ use to notify a user he got one of his feed liked
notifyRemovedItem(String userIdToNotify,
+ org.gcube.portlets.user.homelibrary.home.workspace.WorkspaceItem removedItem)
+
+
+ use to notify a user he got a workspace item deleted from one of his workspace shared folder
+
+
+
+ boolean
+
notifyUpdatedItem(String userIdToNotify,
+ org.gcube.portlets.user.homelibrary.home.workspace.WorkspaceItem updatedItem)
+
+
+ use to notify a user he got a workspace item updated from one of his workspace shared folder
+
+
+
+
+
+
Methods inherited from class org.gcube.applicationsupportlayer.social.SocialPortalBridge
shareApplicationUpdate(String feedtext,
+ String uriGETparams)
+
+
+ use to share an update from your application with a reference to the news object
+
+
+
+ boolean
+
shareApplicationUpdate(String feedtext,
+ String uriGETparams,
+ String previewTitle,
+ String previewDescription,
+ InputStream previewThumbnailInputStream,
+ ImageType imageExtension)
+
+
+ use to share an update from your application with a reference to the news object and with a link preview passing its input stream
+
+
+
+ boolean
+
shareApplicationUpdate(String feedtext,
+ String uriGETparams,
+ String previewTitle,
+ String previewDescription,
+ String previewThumbnailUrl)
+
+
+ use to share an update from your application with a reference to the news object and with a link preview
notifyAddedItem(String userIdToNotify,
+ org.gcube.portlets.user.homelibrary.home.workspace.WorkspaceItem newItem)
+
+
+ use to notify a user he got a workspace item new in some of his workspace shared folder
+
+
+
+ boolean
+
notifyCommentReply(String userIdToNotify,
+ org.gcube.portal.databook.shared.Comment comment)
+
+
+ use to notify a user that commented on a feed (Not his) that someone commented too
+
+
+
+ boolean
+
notifyFolderAddedUser(String userIdToNotify,
+ org.gcube.portlets.user.homelibrary.home.workspace.WorkspaceFolder sharedFolder,
+ String newAddedUserId)
+
+
+ use to notify a user that a new user was added in on of his workspace shared folder
+
+
+
+ boolean
+
notifyFolderRemovedUser(String userIdToNotify,
+ org.gcube.portlets.user.homelibrary.home.workspace.WorkspaceFolder sharedFolder,
+ String removedUserId)
+
+
+ use to notify a user that an existing user was removed from one of his workspace shared folder
+
+
+
+ boolean
+
notifyFolderSharing(String userIdToNotify,
+ org.gcube.portlets.user.homelibrary.home.workspace.WorkspaceFolder sharedFolder)
+
+
+ use to notify a user he got a workspace folder shared
+
+
+
+ boolean
+
notifyLikedFeed(String userIdToNotify,
+ org.gcube.portal.databook.shared.Feed likedFeed)
+
+
+ use to notify a user he got one of his feed liked
notifyRemovedItem(String userIdToNotify,
+ org.gcube.portlets.user.homelibrary.home.workspace.WorkspaceItem removedItem)
+
+
+ use to notify a user he got a workspace item deleted from one of his workspace shared folder
+
+
+
+ boolean
+
notifyUpdatedItem(String userIdToNotify,
+ org.gcube.portlets.user.homelibrary.home.workspace.WorkspaceItem updatedItem)
+
+
+ use to notify a user he got a workspace item updated from one of his workspace shared folder
Returns an array containing the constants of this enum type, in
+the order they are declared. This method may be used to iterate
+over the constants as follows:
+
+for (ImageType c : ImageType.values())
+ System.out.println(c);
+
+
+
+
+
Returns:
an array containing the constants of this enum type, in
+the order they are declared
Returns the enum constant of this type with the specified name.
+The string must match exactly an identifier used to declare an
+enum constant in this type. (Extraneous whitespace characters are
+not permitted.)
+
+
+
Parameters:
name - the name of the enum constant to be returned.
+
NewsManager.shareApplicationUpdate(String feedtext,
+ String uriGETparams,
+ String previewTitle,
+ String previewDescription,
+ InputStream previewThumbnailInputStream,
+ ImageType imageExtension)
+
+
+ use to share an update from your application with a reference to the news object and with a link preview passing its input stream