package org.gcube.portlets.user.sbdportlets; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.portlet.ActionRequest; import javax.portlet.ActionResponse; import javax.portlet.PortletException; import javax.portlet.ResourceRequest; import javax.portlet.ResourceResponse; import javax.servlet.http.HttpServletRequest; import org.gcube.applicationsupportlayer.social.ApplicationNotificationsManager; import org.gcube.applicationsupportlayer.social.NotificationsManager; import org.gcube.applicationsupportlayer.social.shared.SocialNetworkingSite; import org.gcube.applicationsupportlayer.social.shared.SocialNetworkingUser; import org.gcube.common.authorization.library.provider.SecurityTokenProvider; import org.gcube.common.homelibary.model.items.type.WorkspaceItemType; import org.gcube.common.homelibrary.home.HomeLibrary; import org.gcube.common.homelibrary.home.exceptions.HomeNotFoundException; import org.gcube.common.homelibrary.home.exceptions.InternalErrorException; import org.gcube.common.homelibrary.home.workspace.Workspace; import org.gcube.common.homelibrary.home.workspace.WorkspaceFolder; import org.gcube.common.homelibrary.home.workspace.WorkspaceItem; import org.gcube.common.homelibrary.home.workspace.exceptions.ItemNotFoundException; import org.gcube.common.homelibrary.home.workspace.exceptions.WorkspaceFolderNotFoundException; import org.gcube.common.homelibrary.home.workspace.folder.FolderItem; import org.gcube.common.homelibrary.util.WorkspaceUtil; import org.gcube.common.portal.PortalContext; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.portal.notifications.bean.GenericItemBean; import org.gcube.portal.notifications.thread.MessageNotificationsThread; import org.gcube.vomanagement.usermanagement.impl.LiferayRoleManager; import org.gcube.vomanagement.usermanagement.impl.LiferayUserManager; import org.gcube.vomanagement.usermanagement.model.GCubeUser; import com.liferay.portal.kernel.json.JSONFactoryUtil; import com.liferay.portal.kernel.json.JSONObject; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.servlet.SessionErrors; import com.liferay.portal.kernel.servlet.SessionMessages; import com.liferay.portal.kernel.upload.FileItem; import com.liferay.portal.kernel.upload.UploadPortletRequest; import com.liferay.portal.kernel.util.FileUtil; import com.liferay.portal.kernel.util.ParamUtil; import com.liferay.portal.kernel.util.WebKeys; import com.liferay.portal.model.User; import com.liferay.portal.theme.ThemeDisplay; import com.liferay.portal.util.PortalUtil; import com.liferay.util.bridges.mvc.MVCPortlet; /** * upload method/dataset: UserUpload Admin - Share idea: UserIdea Admin * Portlet implementation class UploadDataset */ public class UploadDataset extends MVCPortlet { private static Log _log = LogFactoryUtil.getLog(UploadDataset.class); private static String UPLOAD_DATASET_ROLE_MANAGER_NAME = "UserUpload-Admin"; private final static String UPLOADED_FILE_ATTR_NAME = "myfile"; //make sure in the jsp there's private final static String RESOURCE_URL_ID = "uploadFiles"; public static final String ATTACHMENT_FOLDER ="_shared attachments"; private LiferayRoleManager roleManager = new LiferayRoleManager(); private LiferayUserManager userManager = new LiferayUserManager(); public void addExperiment(ActionRequest actionRequest, ActionResponse actionResponse) throws IOException, PortletException { try{ User currentUser = (User) actionRequest.getAttribute(WebKeys.USER); ThemeDisplay themeDisplay = (ThemeDisplay) actionRequest.getAttribute(WebKeys.THEME_DISPLAY); long groupId = themeDisplay.getLayout().getGroupId(); String method_name = ParamUtil.getString(actionRequest, "method_name"); String people_institutions = ParamUtil.getString(actionRequest, "people_institutions"); String demo_tutorial = ParamUtil.getString(actionRequest, "demo_tutorial"); String experiment_tags = ParamUtil.getString(actionRequest, "experiment_tags"); String[] attachmentIds = ParamUtil.getParameterValues(actionRequest, "selected-attachment"); for (int i = 0; i < attachmentIds.length; i++) { System.out.println(i+"id="+attachmentIds[i]); } _log.debug("new dataset_name : " + method_name); SessionMessages.add(actionRequest.getPortletSession(), "method-form-success"); long teamId = roleManager.getTeam(groupId, UPLOAD_DATASET_ROLE_MANAGER_NAME).getTeamId(); List theManagers = userManager.listUsersByTeam(teamId); HttpServletRequest request = PortalUtil.getHttpServletRequest(actionRequest); boolean result = sendNotificationToUser( request, groupId, currentUser, theManagers, method_name, people_institutions, demo_tutorial, attachmentIds, experiment_tags); if (result) actionResponse.setRenderParameter("mvcPath", "/html/uploaddataset/view-method-inserted.jsp"); else actionResponse.setRenderParameter("mvcPath", "/html/uploaddataset/view-method-error.jsp"); }catch(Exception e){ SessionErrors.add(actionRequest.getPortletSession(),"view-method-error"); e.printStackTrace(); } } @Override public void serveResource(ResourceRequest resourceRequest, ResourceResponse resourceResponse) throws PortletException, IOException { String resourceID = resourceRequest.getResourceID(); if (resourceID.equals(RESOURCE_URL_ID)) { UploadPortletRequest uploadRequest = PortalUtil.getUploadPortletRequest(resourceRequest); File multipartFile = uploadRequest.getFile(UPLOADED_FILE_ATTR_NAME); FileItem[] items = uploadRequest.getMultipartParameterMap().get(UPLOADED_FILE_ATTR_NAME); String fileName = ""; String contentType = ""; for (int i = 0; i < items.length; i++) { fileName = items[i].getFileName(); contentType = items[i].getContentType(); System.out.println(fileName); System.out.println(contentType); } JSONObject fileObject = JSONFactoryUtil.createJSONObject(); try { Workspace workspace = getWorkspace(uploadRequest); String wsItemId = uploadToUserWorkspace(workspace, fileName, contentType, new ByteArrayInputStream(FileUtil.getBytes(multipartFile))); fileObject.put("itemId", wsItemId); fileObject.put("fileName", fileName); } catch (Exception e) { _log.error("There was an error uploading the file " + fileName, e); } resourceResponse.getWriter().println(fileObject); } else { _log.debug("nothing to do"); } } /** * * @param uploadRequest is the XHR http servlet request * @return * @throws Exception */ private Workspace getWorkspace(UploadPortletRequest uploadRequest ) throws Exception { Workspace workspace; try{ PortalContext pContext = PortalContext.getConfiguration(); ScopeProvider.instance.set(pContext.getCurrentScope(uploadRequest)); workspace = HomeLibrary.getUserWorkspace(pContext.getCurrentUser(uploadRequest).getUsername()); }catch(InternalErrorException | HomeNotFoundException | WorkspaceFolderNotFoundException e){ String msg = "Sorry, an error occurred when retrieving workspace item, Refresh an try again"; _log.error("HL error: ",e); throw new Exception(msg); } return workspace; } private String uploadToUserWorkspace(Workspace ownerWS, String fileName, String mimeType,InputStream fileData) throws Exception { WorkspaceFolder attachment = null; try{ attachment = (WorkspaceFolder) ownerWS.getItemByPath(ownerWS.getRoot().getPath() + "/" + ATTACHMENT_FOLDER); } catch (ItemNotFoundException e) { _log.info(ATTACHMENT_FOLDER + " Workspace Folder does not exists, creating it "); attachment = ownerWS.getRoot().createFolder(ATTACHMENT_FOLDER, "Folder created automatically by the System"); } String itemName = WorkspaceUtil.getUniqueName(fileName, attachment); FolderItem item = WorkspaceUtil.createExternalFile(attachment, itemName, "File created automatically by the System", mimeType, fileData); String toReturn = item.getId(); _log.debug("Uploaded " + item.getName() + " - Returned Workspace id=" +toReturn); return toReturn; } private boolean sendNotificationToUser(HttpServletRequest request, long groupId, User currentUser, List theManagers , String method_name, String people_institutions, String demo_tutorial, String[] attachmentIds, String experiment_tags) throws Exception { String scope = PortalContext.getConfiguration().getCurrentScope(""+groupId); _log.info("sendNotificationToUser Scope: " + scope); String authorizationToken = PortalContext.getConfiguration().getCurrentUserToken(scope, currentUser.getScreenName()); ScopeProvider.instance.set(scope); SecurityTokenProvider.instance.set(authorizationToken); Workspace workspace = HomeLibrary.getUserWorkspace(currentUser.getScreenName()); List recipientIds = new ArrayList(); List recipients = new ArrayList(); for (GCubeUser addressee : theManagers) { recipients.add(new GenericItemBean(addressee.getUsername(), addressee.getUsername(), addressee.getFullname(), "")); recipientIds.add(addressee.getUsername()); } String subject = "A new user uploaded a method or dataset"; StringBuilder sb = new StringBuilder("Hi, the following dataset/method was shared by ").append(currentUser.getFullName()) .append(" (").append(currentUser.getEmailAddress()).append(").") .append("\n\n").append("Dataset/Method name: ").append(method_name).append("\n") .append("\n").append("Involved people and or institutions: ").append(people_institutions).append("\n") .append("\n").append("Demo/Tutorial:\n").append(demo_tutorial).append("\n") .append("\n").append("Keywords (Comma separated): ").append(experiment_tags).append("\n"); List attachmentsList = Arrays.asList(attachmentIds); String body = sb.toString(); try { body += getPublicLinksForAttachs(workspace, attachmentsList); } catch (Exception e) { _log.error("Ops, could not generate publick link for some of the attachments"); } String messageId = workspace.getWorkspaceMessageManager(). sendMessageToPortalLogins(subject, body, attachmentsList, recipientIds); _log.info("Sending upload method message notification to: " + recipientIds.toString()); NotificationsManager nm = new ApplicationNotificationsManager(new SocialNetworkingSite(request), scope, new SocialNetworkingUser( currentUser.getScreenName(), currentUser.getEmailAddress(), currentUser.getFullName(), "")); Thread thread = new Thread(new MessageNotificationsThread(recipients, messageId, subject, body, nm)); thread.start(); return (messageId != null); } /** * * @param workspace * @param listAttachmentsId * @return * @throws ItemNotFoundException * @throws InternalErrorException */ private String getPublicLinksForAttachs(Workspace workspace, List listAttachmentsId) throws ItemNotFoundException, InternalErrorException{ if (listAttachmentsId != null && (!listAttachmentsId.isEmpty()) ) { List attachments = new ArrayList(); for (String itemId : listAttachmentsId) { attachments.add(workspace.getItem(itemId)); } StringBuilder builder = new StringBuilder(); if(attachments!=null && attachments.size() > 0){ builder.append("\n\n\nThe following "); String msg = attachments.size()>1?"files were attached to this message:":"file was attached to this message:"; builder.append(msg+"\n"); for (WorkspaceItem workspaceItem : attachments) { if(workspaceItem.getType().equals(WorkspaceItemType.FOLDER_ITEM)) { FolderItem folderItem = (FolderItem) workspaceItem; String publicLink = ""; String itemName = ""; try { itemName = workspaceItem.getName(); publicLink = folderItem.getPublicLink(true); } catch (InternalErrorException e) { _log.warn("An error occurred when creating public link for attachment, skipping file: " + itemName); return ""; } builder.append(itemName + " ("+publicLink+")"); builder.append("\n"); } } _log.debug("returning public links: "+builder.toString()); return builder.toString(); } else return ""; } else return ""; } }