package org.gcube.portlets.user.wswidget; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Scanner; import javax.portlet.PortletException; import javax.portlet.PortletSession; import javax.portlet.ResourceRequest; import javax.portlet.ResourceResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.gcube.common.authorization.library.provider.AccessTokenProvider; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.common.storagehub.client.StreamDescriptor; import org.gcube.common.storagehub.client.dsl.FileContainer; import org.gcube.common.storagehub.client.dsl.ItemContainer; import org.gcube.common.storagehub.client.dsl.StorageHubClient; import org.gcube.common.storagehub.client.plugins.AbstractPlugin; import org.gcube.common.storagehub.client.proxies.WorkspaceManagerClient; import org.gcube.common.storagehub.model.exceptions.StorageHubException; import org.gcube.common.storagehub.model.items.ExternalLink; import org.gcube.common.storagehub.model.items.ExternalURL; import org.gcube.common.storagehub.model.items.Item; import org.gcube.oidc.rest.JWTToken; import org.gcube.portal.oidc.lr62.JWTTokenUtil; import org.gcube.portal.oidc.lr62.OIDCUmaUtil; import org.gcube.portlets.user.wswidget.shared.AuthorizedUser; import org.gcube.portlets.user.wswidget.shared.Breadcrumb; import org.gcube.portlets.user.wswidget.shared.WSItem; import org.gcube.vomanagement.usermanagement.model.GCubeUser; import com.liferay.portal.kernel.exception.PortalException; import com.liferay.portal.kernel.exception.SystemException; import com.liferay.portal.kernel.json.JSONArray; import com.liferay.portal.kernel.json.JSONFactoryUtil; import com.liferay.portal.kernel.json.JSONObject; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.servlet.ServletResponseUtil; import com.liferay.portal.kernel.util.ParamUtil; import com.liferay.portal.service.GroupLocalServiceUtil; import com.liferay.portal.util.PortalUtil; import com.liferay.util.bridges.mvc.MVCPortlet; /** * Portlet implementation class WorkspaceWidget */ public class WorkspaceWidget extends MVCPortlet { private static com.liferay.portal.kernel.log.Log _log = LogFactoryUtil.getLog(WorkspaceWidget.class); public static String BREADCRUMB_ATTR = "BREADCRUMB_ATTR_name"; public final static int LIMIT = 5; public final static String ITEM_URL_TYPE = "nthl:externalUrl"; /** * all the AJAX calls are served by this method, to discriminate the operation we use the parameters: * - when fileToDownloadId parameters is not empty the request is for a file download * - when */ @Override public void serveResource(ResourceRequest resourceRequest, ResourceResponse resourceResponse) throws IOException, PortletException { String fileToDownloadId = ParamUtil.getString(resourceRequest, "fileToDownloadId", null); //check if is a file download if (fileToDownloadId != null) { setAuthorizationToken(resourceRequest); String currentContext = Utils.getCurrentContext(resourceRequest); ScopeProvider.instance.set(currentContext); HttpServletRequest httpReq = PortalUtil.getHttpServletRequest(resourceRequest); long userId; try { userId = PortalUtil.getUser(resourceRequest).getUserId(); JWTToken umaToken = OIDCUmaUtil.getUMAToken(httpReq, userId, currentContext); AccessTokenProvider.instance.set(JWTTokenUtil.getAccessTokenString(umaToken)); } catch (Exception e1) { e1.printStackTrace(); } String selectedItemId = fileToDownloadId.split("=")[1]; StorageHubClient client = new StorageHubClient(); FileContainer fileContainer = null; StreamDescriptor streamDescr = null; Item item = null; HttpServletResponse httpRes = PortalUtil.getHttpServletResponse(resourceResponse); try { ItemContainer itemContainer = client.open(selectedItemId).asItem(); item = itemContainer.get(); if (item instanceof ExternalLink) { //if is a type URL we open directly the link (StorageHub Created it) ExternalLink extLink = (ExternalLink) item; httpRes.sendRedirect(extLink.getValue().toString()); } else { fileContainer = client.open(selectedItemId).asFile(); streamDescr = fileContainer.download(selectedItemId); _log.info("*** DONE fileContainer.download for itemid=" +selectedItemId); } if (item instanceof ExternalURL) { //if is a type URL we open directly the link (HL Created it) Scanner sc = new Scanner( streamDescr.getStream()); String text = sc.useDelimiter("\\A").next(); sc.close(); streamDescr.getStream().close(); httpRes.sendRedirect(text); } } catch (StorageHubException e) { e.printStackTrace(); } if (! (item instanceof ExternalURL || item instanceof ExternalLink)) { ServletResponseUtil.sendFile(httpReq,httpRes, streamDescr.getFileName(), streamDescr.getStream(), "application/download"); streamDescr.getStream().close(); } } //the user is browsing the workspace or asking for recents else { String cmd = ParamUtil.getString(resourceRequest, "cmd", ""); String selectedItemId = "root"; String selectedItemName = ""; System.out.println("****\n\n\n*** String cmd2 ="+cmd); if (cmd != null && cmd.split("_selectedName").length > 1) { String[] splits = cmd.split("_selectedName"); selectedItemId = splits[0].split("=")[1]; selectedItemName= splits[1].split("=")[1]; } int start = ParamUtil.getInteger(resourceRequest, "start"); int length = ParamUtil.getInteger(resourceRequest, "length"); int draw = ParamUtil.getInteger(resourceRequest, "draw"); listItems(resourceRequest, resourceResponse, selectedItemId, selectedItemName, start, length, draw); } } private void listItems(ResourceRequest request, ResourceResponse resourceResponse, String itemId, String itemName, int start, int offset, int draw) { try { AuthorizedUser authUser = setAuthorizationToken(request); List itemsList = new ArrayList<>(); Breadcrumb toSet = null; WSItem clicked = null; int count = 0; if (itemId.compareTo("root") == 0) { //here we have to check if is a VRE, in that case the content of the VRE Folder is the root long groupId = PortalUtil.getScopeGroupId(request); if (GroupLocalServiceUtil.getParentGroups(groupId).isEmpty()) { //is in Site / RootVO itemId = getRootItem(request).getId(); itemsList = StorageHubServiceUtil.getRootChildren(authUser, start, offset); toSet = new Breadcrumb(itemId, Utils.getCurrentUser(request).getFirstName()+"\'s home"); request.getPortletSession().setAttribute(BREADCRUMB_ATTR, toSet, PortletSession.APPLICATION_SCOPE); } else { //is in a VRE WorkspaceManagerClient wsclient = AbstractPlugin.workspace().build(); itemId = wsclient.getVreFolder("hl:accounting").getId(); itemsList = StorageHubServiceUtil.getItemChildren(authUser, itemId, itemId, start, offset); String groupName = GroupLocalServiceUtil.getGroup(groupId).getName(); groupName = groupName.replace("_", " "); groupName = (groupName.length() > 20) ? groupName.substring(0, 19) + " ..." : groupName; toSet = new Breadcrumb(itemId, groupName); request.getPortletSession().setAttribute(BREADCRUMB_ATTR, toSet, PortletSession.APPLICATION_SCOPE); } count = StorageHubServiceUtil.getItemChildrenCount(request, itemId); } else if (itemId.compareTo("recents") == 0) { //is in a VRE and asking for recents files itemsList = StorageHubServiceUtil.getRecentItems(authUser); count = offset; toSet = (Breadcrumb) request.getPortletSession().getAttribute(BREADCRUMB_ATTR, PortletSession.APPLICATION_SCOPE); toSet.setChild(new Breadcrumb("", "Top 10 Recent")); request.getPortletSession().setAttribute(BREADCRUMB_ATTR, toSet, PortletSession.APPLICATION_SCOPE); } else { _log.debug("non root"); itemsList = StorageHubServiceUtil.getItemChildren(authUser, itemId, itemId, start, offset); toSet = (Breadcrumb) request.getPortletSession().getAttribute(BREADCRUMB_ATTR, PortletSession.APPLICATION_SCOPE); clicked = new WSItem(itemId, itemName, true); computeBreadcrumb(clicked, toSet); count = StorageHubServiceUtil.getItemChildrenCount(request, itemId); } JSONObject tableData = buildJSONResponse(itemsList, start, offset, draw, count, request); ServletResponseUtil.write(PortalUtil.getHttpServletResponse(resourceResponse),tableData.toString()); } catch (Exception e) { e.printStackTrace(); } } /** * computes the breadcrumb * @param toReturn * @param toCompute */ public void computeBreadcrumb(WSItem toReturn, Breadcrumb toCompute) { boolean found = false; while (toCompute.hasChild()) { if (toReturn.getId().equals(toCompute.getId())) { //in case the user click on the breadcrumb toCompute.setChild(null); found = true; break; } else { toCompute = toCompute.getChild(); } } if (!found) { if (toReturn.getName().equals(Utils.SPECIAL_FOLDERS_NAME)) //in case the user clicked on the VRE Folders toReturn.setName(Utils.VRE_FOLDERS_LABEL); if (! toReturn.getId().equals(toCompute.getId())) toCompute.setChild(new Breadcrumb(toReturn.getId(), toReturn.getName())); } } private static String constructBreadcrumbHTML(Breadcrumb toSet, ResourceRequest request) { StringBuilder sb = new StringBuilder(""); return sb.toString(); } /** * this method construct the breadcrumb server side, the resaulting code is added in the client DOM (once returned) * @param toSet * @return */ private static String getHREFJavascriptCall(Breadcrumb toSet, boolean hideVreFoldersDiv) { String escapedItemName = toSet.getName().replaceAll("\"", "\\\"").replaceAll("'", "\\\\'"); StringBuilder sb = new StringBuilder ("") .append(toSet.getName()).append(""); return sb.toString(); } /** * * @param itemsList * @param start * @param offset * @param draw * @param count * @param request * @return the JSON response to the client */ private JSONObject buildJSONResponse(List itemsList, int start, int offset, int draw, int count, ResourceRequest request){ JSONArray usersJsonArray = JSONFactoryUtil.createJSONArray(); JSONObject jsonUser = null; for (WSItem item : itemsList) { JSONArray nameAndIconArray = JSONFactoryUtil.createJSONArray(); JSONObject nameAndIconObject = JSONFactoryUtil.createJSONObject(); nameAndIconObject.put("Icon", item.getIconURL()); nameAndIconObject.put("IconColor", item.getIconColor()); nameAndIconObject.put("Name", item.getName()); nameAndIconObject.put("Id", item.getId()); nameAndIconObject.put("isFolder", item.isFolder() || item.isSharedFolder() || item.isSpecialFolder()); nameAndIconArray.put(nameAndIconObject); jsonUser = JSONFactoryUtil.createJSONObject(); //we need to pass a JSON here as String without String stringfiedJsonArray = nameAndIconArray.toString(); jsonUser.put("Id",item.getId()); jsonUser.put("Name", stringfiedJsonArray.substring(1, stringfiedJsonArray.length()-1)); //without square brackets so that it is parsable in the client jsonUser.put("Owner",item.getOwner()); jsonUser.put("LastModified", item.getLastUpdated().getTime()); jsonUser.put("isFolder", item.isFolder() || item.isSharedFolder() || item.isSpecialFolder()); usersJsonArray.put(jsonUser); } JSONObject tableData = JSONFactoryUtil.createJSONObject(); tableData.put("mytabledata", usersJsonArray); Breadcrumb bcBegin = (Breadcrumb) request.getPortletSession().getAttribute(BREADCRUMB_ATTR, PortletSession.APPLICATION_SCOPE); tableData.put("breadcrumb", constructBreadcrumbHTML(bcBegin, request)); tableData.put("draw", draw); tableData.put("recordsTotal", count); tableData.put("recordsFiltered", count); _log.debug("tableData:"+tableData.toString()); return tableData; } private static WSItem getRootItem(ResourceRequest request) { WorkspaceManagerClient client = AbstractPlugin.workspace().build(); Item itemRoot = client.getWorkspace("hl:accounting"); WSItem root = new WSItem(itemRoot.getId(), Utils.HOME_LABEL, true); root.setIsRoot(true); root.setFolder(true); return root; } /** * set the authorization token in Thread local and return the current {@link AuthorizedUser} instance * @param request * @return */ private AuthorizedUser setAuthorizationToken(ResourceRequest request) { GCubeUser currentUser = Utils.getCurrentUser(request); return new AuthorizedUser(currentUser); } }