From bc273ce9cd8b2b1aaa416893f69e75129b411997 Mon Sep 17 00:00:00 2001 From: Mike Conway Date: Fri, 26 Jan 2018 12:15:24 -0500 Subject: [PATCH 1/7] #65 work in progress --- .../metalnx/controller/BrowseController.java | 1051 +++++++++++++++++ .../controller/CollectionController.java | 988 +++------------- .../controller/CollectionInfoController.java | 84 +- .../controller/FileOperationsController.java | 27 +- .../resources/i18n/messages_en.properties | 2 + .../collections/collectionManagement.html | 21 +- .../collections/collectionsBreadCrumb.html | 14 +- .../views/collections/collectionsBrowser.html | 27 +- .../views/rules/rulesManagement.html | 2 +- .../src/main/resources/log4j.properties | 2 +- .../webapp/WEB-INF/applicationContext.xml | 2 + 11 files changed, 1287 insertions(+), 933 deletions(-) create mode 100644 src/emc-metalnx-shared/src/main/java/com/emc/metalnx/controller/BrowseController.java diff --git a/src/emc-metalnx-shared/src/main/java/com/emc/metalnx/controller/BrowseController.java b/src/emc-metalnx-shared/src/main/java/com/emc/metalnx/controller/BrowseController.java new file mode 100644 index 000000000..a872d2f5d --- /dev/null +++ b/src/emc-metalnx-shared/src/main/java/com/emc/metalnx/controller/BrowseController.java @@ -0,0 +1,1051 @@ +/* + * Copyright (c) 2015-2017, Dell EMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.emc.metalnx.controller; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Stack; + +import javax.annotation.PostConstruct; +import javax.servlet.http.HttpServletRequest; + +import org.irods.jargon.core.exception.FileNotFoundException; +import org.irods.jargon.core.exception.JargonException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.SessionAttributes; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; +import org.thymeleaf.util.StringUtils; + +import com.emc.metalnx.controller.utils.LoggedUserUtils; +import com.emc.metalnx.core.domain.entity.DataGridCollectionAndDataObject; +import com.emc.metalnx.core.domain.entity.DataGridGroup; +import com.emc.metalnx.core.domain.entity.DataGridPageContext; +import com.emc.metalnx.core.domain.entity.DataGridResource; +import com.emc.metalnx.core.domain.entity.DataGridUser; +import com.emc.metalnx.core.domain.exceptions.DataGridConnectionRefusedException; +import com.emc.metalnx.core.domain.exceptions.DataGridException; +import com.emc.metalnx.modelattribute.breadcrumb.DataGridBreadcrumb; +import com.emc.metalnx.modelattribute.collection.CollectionOrDataObjectForm; +import com.emc.metalnx.modelattribute.metadatatemplate.MetadataTemplateForm; +import com.emc.metalnx.services.interfaces.CollectionService; +import com.emc.metalnx.services.interfaces.FavoritesService; +import com.emc.metalnx.services.interfaces.GroupBookmarkService; +import com.emc.metalnx.services.interfaces.GroupService; +import com.emc.metalnx.services.interfaces.IRODSServices; +import com.emc.metalnx.services.interfaces.MetadataService; +import com.emc.metalnx.services.interfaces.PermissionsService; +import com.emc.metalnx.services.interfaces.ResourceService; +import com.emc.metalnx.services.interfaces.RuleDeploymentService; +import com.emc.metalnx.services.interfaces.UserBookmarkService; +import com.emc.metalnx.services.interfaces.UserService; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Transitional controller factors out all sub functions of the + * {@link CollectionController} so that this controller can respond to 'deep + * linkable' paths, including from breadcrumbs in the info pages + * + * @author Mike Conway - NIEHS + * + */ +@Controller +@Scope(WebApplicationContext.SCOPE_SESSION) +@SessionAttributes({ "sourcePaths" }) +@RequestMapping(value = "/browse") +public class BrowseController { + + @Autowired + CollectionService cs; + + @Autowired + ResourceService resourceService; + + @Autowired + UserService userService; + + @Autowired + GroupService groupService; + + @Autowired + GroupBookmarkService groupBookmarkService; + + @Autowired + UserBookmarkService userBookmarkService; + + @Autowired + MetadataService metadataService; + + @Autowired + GroupBookmarkController groupBookmarkController; + + @Autowired + PermissionsService permissionsService; + + @Autowired + IRODSServices irodsServices; + + @Autowired + FavoritesService favoritesService; + + @Autowired + LoggedUserUtils loggedUserUtils; + + @Autowired + RuleDeploymentService ruleDeploymentService; + + // parent path of the current directory in the tree view + private String parentPath; + + // path to the current directory in the tree view + private String currentPath; + + // number of pages for current path + private int totalObjsForCurrentPath; + + // number of pages for current search + private int totalObjsForCurrentSearch; + + // Auxiliary structure to manage download, upload, copy and move operations + private List sourcePaths; + + // ui mode that will be shown when the rods user switches mode from admin to + // user and vice-versa + public static final String UI_USER_MODE = "user"; + public static final String UI_ADMIN_MODE = "admin"; + + public static final int MAX_HISTORY_SIZE = 10; + + private boolean cameFromMetadataSearch; + private boolean cameFromFilePropertiesSearch; + private boolean cameFromBookmarks; + + private Stack collectionHistoryBack; + private Stack collectionHistoryForward; + + // variable to save trash path for the logged user + private String userTrashPath = ""; + // saves the trash under the zone + private String zoneTrashPath = ""; + + private static final Logger logger = LoggerFactory.getLogger(CollectionController.class); + + @PostConstruct + public void init() throws DataGridException { + collectionHistoryBack = new Stack(); + collectionHistoryForward = new Stack(); + + cameFromMetadataSearch = false; + cameFromFilePropertiesSearch = false; + cameFromBookmarks = false; + + sourcePaths = new ArrayList<>(); + parentPath = ""; + currentPath = ""; + } + + /** + * Get a list of resources in which an object doesn't have replicas + * + * @param model + * @return list of resources in which an object can be replicated + * @throws DataGridConnectionRefusedException + */ + @RequestMapping(value = "getAvailableRescForPath/") + public String getAvailableRescForPath(final Model model, @RequestParam("isUpload") final boolean isUpload) + throws DataGridConnectionRefusedException { + + Map replicasMap = null; + List resources = resourceService.findFirstLevelResources(); + + if (!isUpload) { + for (String path : sourcePaths) { + replicasMap = cs.listReplicasByResource(path); + for (DataGridResource resc : replicasMap.values()) { + if (resources.contains(resc)) { + resources.remove(resc); + } + } + } + } + model.addAttribute("resources", resources); + return "collections/collectionsResourcesForReplica"; + } + + /** + * Switches an admin from the Rods_Admin UI to the Rods_User UI and vice-versa. + * + * @param model + * @return redirects an admin user from to the new UI view mode (admin view or + * user view) + */ + @RequestMapping(value = "/switchMode/") + @ResponseStatus(value = HttpStatus.OK) + public void switchMode(final Model model, final HttpServletRequest request, + @RequestParam("currentMode") final String currentMode, final RedirectAttributes redirectAttributes) { + + // if the admin is currently seeing the Admin UI, we need to switch it + // over to the USER UI + if (currentMode.equalsIgnoreCase(UI_ADMIN_MODE)) { + request.getSession().setAttribute("uiMode", UI_USER_MODE); + } + // if the admin is currently seeing the User UI, we need to switch it + // over to the ADMIN UI + else if (currentMode.equalsIgnoreCase(UI_USER_MODE)) { + request.getSession().setAttribute("uiMode", UI_ADMIN_MODE); + } + } + + /** + * Responds the getSubdirectories request finding collections and data objects + * that exist underneath a certain path + * + * @param model + * @param path + * path to find all subdirectories and objects + * @return treeView template that renders all nodes of certain path (parent) + * @throws DataGridException + * if Metalnx cannot find collections and objects inside the path + */ + @RequestMapping(value = "/getSubDirectories/", method = RequestMethod.POST) + public String getSubDirectories(final Model model, @RequestParam("path") String path) throws DataGridException { + + logger.info("getSubDirectories()"); + logger.info("model:{}", model); + logger.info("path:{}", path); + + // removes all ocurrences of "/" at the end of the path string + while (path.endsWith("/") && !"/".equals(path)) { + path = path.substring(0, path.lastIndexOf("/")); + } + + logger.info("Get subdirectories of {}", path); + + System.out.println("In GetSubdirectories!!"); + System.out.println("path :: " + path); + + return getCollBrowserView(model, path); + } + + /** + * Goes back in collection historic stack + * + * @param model + * @param steps + * @return treeView template that renders all nodes of certain path (parent) + * @throws DataGridConnectionRefusedException + */ + @RequestMapping(value = "/goBackHistory/", method = RequestMethod.POST) + public String goBackHistory(final Model model, @RequestParam("steps") final int steps) + throws DataGridException, JargonException { + if (collectionHistoryBack.size() < steps || steps < 1) { + model.addAttribute("invalidStepsBackwards", steps); + logger.info("It is not possible to go back {} steps, current stack size is {}", steps, + collectionHistoryBack.size()); + return getCollBrowserView(model, currentPath); + } + + logger.info("Going back {} steps in collection history", steps); + + // pop paths from collectionHistoryBack and push them to + // collectionHistoryForward + while (collectionHistoryForward.size() >= MAX_HISTORY_SIZE) { + collectionHistoryForward.remove(0); + } + collectionHistoryForward.push(currentPath); + for (int i = 0; i < steps - 1; i++) { + String elementHistory = collectionHistoryBack.pop(); + while (collectionHistoryForward.size() >= MAX_HISTORY_SIZE) { + collectionHistoryForward.remove(0); + } + collectionHistoryForward.push(elementHistory); + } + + return getCollBrowserView(model, collectionHistoryBack.pop()); + } + + /** + * Goes forward in collection historic stack + * + * @param model + * @param steps + * @return treeView template that renders all nodes of certain path (parent) + * @throws DataGridConnectionRefusedException + */ + @RequestMapping(value = "/goForwardHistory/", method = RequestMethod.POST) + public String goForwardHistory(final Model model, @RequestParam("steps") final int steps) + throws DataGridException, JargonException { + if (collectionHistoryForward.size() < steps || steps < 1) { + model.addAttribute("invalidStepsForward", steps); + return getCollBrowserView(model, currentPath); + } + + logger.info("Going {} steps forward in collection history", steps); + + // pop paths from collectionHistoryBack and push them to + // collectionHistoryForward + while (collectionHistoryBack.size() >= MAX_HISTORY_SIZE) { + collectionHistoryBack.remove(0); + } + collectionHistoryBack.push(currentPath); + for (int i = 0; i < steps - 1; i++) { + String elementHistory = collectionHistoryForward.pop(); + while (collectionHistoryBack.size() >= MAX_HISTORY_SIZE) { + collectionHistoryBack.remove(0); + } + collectionHistoryBack.push(elementHistory); + } + + return getCollBrowserView(model, collectionHistoryForward.pop()); + } + + /** + * Responds the getSubdirectories request finding collections and data objects + * that exist underneath a certain path + * + * @param model + * @param path + * @return treeView template that renders all nodes of certain path (parent) + * @throws DataGridConnectionRefusedException + */ + @RequestMapping(value = "/getSubDirectoriesOldTree/") + public String getSubDirectoriesOldTree(final Model model, @RequestParam("path") String path) + throws DataGridConnectionRefusedException { + + if (path.isEmpty()) { + path = "/"; + } else { + if (path.endsWith("/") && path.compareTo("/") != 0) { + path = path.substring(0, path.length() - 1); + } + } + + // The line below was modified so that only collection would be retrieved + model.addAttribute("dataGridCollectionAndDataObjectList", cs.getSubCollectionsUnderPath(path)); + + return "collections/oldTreeView :: oldTreeView"; + } + + /** + * Gets checksum, total number of replicas and where each replica lives in the + * data grid for a specific data object + * + * @param model + * @param path + * path to the data object to get checksum and replica information + * @return the template that shows the data object information + * @throws DataGridConnectionRefusedException + */ + @RequestMapping(value = "/info/", method = RequestMethod.POST) + public String getFileInfo(final Model model, final String path) throws DataGridConnectionRefusedException { + + System.out.println("CollectionController getInfoFile() starts !!"); + DataGridCollectionAndDataObject dataGridObj = null; + Map replicasMap = null; + + try { + System.out.println("Path = " + path); + + dataGridObj = cs.findByName(path); + + if (dataGridObj != null && !dataGridObj.isCollection()) { + replicasMap = cs.listReplicasByResource(path); + dataGridObj.setChecksum(cs.getChecksum(path)); + dataGridObj.setNumberOfReplicas(cs.getTotalNumberOfReplsForDataObject(path)); + dataGridObj.setReplicaNumber(String.valueOf(cs.getReplicationNumber(path))); + permissionsService.resolveMostPermissiveAccessForUser(dataGridObj, + loggedUserUtils.getLoggedDataGridUser()); + + } + + } catch (DataGridConnectionRefusedException e) { + logger.error("Could not connect to the data grid", e); + throw e; + } catch (DataGridException e) { + logger.error("Could not get file info for {}", path, e); + } + + model.addAttribute("collectionAndDataObject", dataGridObj); + model.addAttribute("currentCollection", dataGridObj); + model.addAttribute("replicasMap", replicasMap); + model.addAttribute("infoFlag", true); + + System.out.println("permissionOnCurrentPath =======" + cs.getPermissionsForPath(path)); + System.out.println("currentCollection.getName() == " + dataGridObj.getName()); + + System.out.println("CollectionController getInfoFile() ends !!"); + return "collections/info :: infoView"; + // return "collections/info"; + } + + /** + * Finds all collections and files existing under a certain path for a given + * group name. + * + * @param model + * @param path + * start point to get collections and files + * @param groupName + * group that all collections and files permissions will be listed + * @return + * @throws DataGridConnectionRefusedException + * @throws JargonException + * @throws FileNotFoundException + */ + @RequestMapping(value = "/getDirectoriesAndFilesForGroupForm") + public String getDirectoriesAndFilesForGroupForm(final Model model, @RequestParam("path") String path, + @RequestParam("groupName") final String groupName, + @RequestParam("retrievePermissions") final boolean retrievePermissions) + throws DataGridConnectionRefusedException, FileNotFoundException, JargonException { + if (path == null || path == "") { + path = "/"; + } + + List list = null; + list = cs.getSubCollectionsAndDataObjectsUnderPath(path); + + Set readPermissions = null; + Set writePermissions = null; + Set ownershipPermissions = null; + Set inheritPermissions = null; + + if (retrievePermissions) { + readPermissions = cs.listReadPermissionsForPathAndGroup(path, groupName); + writePermissions = cs.listWritePermissionsForPathAndGroup(path, groupName); + ownershipPermissions = cs.listOwnershipForPathAndGroup(path, groupName); + inheritPermissions = cs.listInheritanceForPath(path); + } else { + readPermissions = new HashSet(); + writePermissions = new HashSet(); + ownershipPermissions = new HashSet(); + inheritPermissions = new HashSet(); + } + + List groupBookmarks = new ArrayList(); + if (groupName.length() > 0) { + DataGridGroup group = groupService.findByGroupname(groupName).get(0); + groupBookmarks = groupBookmarkService.findBookmarksForGroupAsString(group); + } + + model.addAttribute("dataGridCollectionAndDataObjectList", list); + model.addAttribute("currentPath", path); + model.addAttribute("readPermissions", readPermissions); + model.addAttribute("writePermissions", writePermissions); + model.addAttribute("ownershipPermissions", ownershipPermissions); + model.addAttribute("inheritPermissions", inheritPermissions); + model.addAttribute("addBookmark", groupBookmarkController.getAddBookmark()); + model.addAttribute("removeBookmark", groupBookmarkController.getRemoveBookmark()); + model.addAttribute("groupBookmarks", groupBookmarks); + + return "collections/treeViewForGroupForm :: treeView"; + } + + /** + * Finds all collections existing under a certain path. + * + * @param model + * @param path + * start point to get collections and files + * @param username + * user who all collections and files permissions will be listed + * @return the template that will render the tree + * @throws DataGridConnectionRefusedException + * @throws JargonException + * @throws FileNotFoundException + */ + @RequestMapping(value = "/getDirectoriesAndFilesForUser") + public String getDirectoriesAndFilesForUser(final Model model, @RequestParam("path") final String path, + @RequestParam("username") final String username, + @RequestParam("retrievePermissions") final boolean retrievePermissions) + throws DataGridConnectionRefusedException, FileNotFoundException, JargonException { + + List list = new ArrayList(); + Set readPermissions = new HashSet(); + Set writePermissions = new HashSet(); + Set ownershipPermissions = new HashSet(); + Set inheritPermissions = new HashSet(); + List userBookmarks = new ArrayList(); + + // If a string is null, empty or contains only white spaces, StringUtils + // returns true + boolean isPathEmpty = StringUtils.isEmptyOrWhitespace(path); + boolean isUsernameEmpty = StringUtils.isEmptyOrWhitespace(username); + + if (!isPathEmpty) { + // When adding a user (there is no username), we still need to be + // able to walk through the iRODS tree + list = cs.getSubCollectionsAndDataObjectsUnderPath(path); + + if (!isUsernameEmpty) { + if (retrievePermissions) { + readPermissions = cs.listReadPermissionsForPathAndUser(path, username); + writePermissions = cs.listWritePermissionsForPathAndUser(path, username); + ownershipPermissions = cs.listOwnershipForPathAndUser(path, username); + inheritPermissions = cs.listInheritanceForPath(path); + } + + List users = userService.findByUsername(username); + if (users != null && !users.isEmpty()) { + userBookmarks = userBookmarkService.findBookmarksForUserAsString(users.get(0)); + } + } + } + + model.addAttribute("dataGridCollectionAndDataObjectList", list); + model.addAttribute("currentPath", path); + model.addAttribute("readPermissions", readPermissions); + model.addAttribute("writePermissions", writePermissions); + model.addAttribute("ownershipPermissions", ownershipPermissions); + model.addAttribute("inheritPermissions", inheritPermissions); + model.addAttribute("addBookmark", new ArrayList()); + model.addAttribute("removeBookmark", new ArrayList()); + model.addAttribute("userBookmarks", userBookmarks); + + return "collections/treeViewForUserForm :: treeView"; + } + + /** + * Looks for collections or data objects that match the parameter string + * + * @param model + * @param name + * collection name that will be searched in the data grid + * @return the template that renders all collections and data objects matching + * the parameter string + * @throws DataGridConnectionRefusedException + */ + @RequestMapping(value = "/find/{name}") + public String listCollectionsAndDataObjects(final Model model, @PathVariable final String name) + throws DataGridConnectionRefusedException { + logger.info("Finding collections or data objects that match " + name); + + // Find collections and data objects + List dataGridCollectionAndDataObjects = cs + .searchCollectionAndDataObjectsByName(name + "%"); + model.addAttribute("dataGridCollectionAndDataObjects", dataGridCollectionAndDataObjects); + return "collections/collectionsBrowser :: treeView"; + } + + /** + * Performs the action of actually creating a collection in iRODS + * + * @param model + * @param collection + * @return if the creation of collection was successful, it returns the + * collection management template, and returns the add collection + * template, otherwise. + * @throws DataGridConnectionRefusedException + */ + @RequestMapping(value = "add/action/", method = RequestMethod.POST) + public String addCollection(final Model model, @ModelAttribute final CollectionOrDataObjectForm collection, + final RedirectAttributes redirectAttributes) throws DataGridConnectionRefusedException { + DataGridCollectionAndDataObject newCollection = new DataGridCollectionAndDataObject( + currentPath + '/' + collection.getCollectionName(), collection.getCollectionName(), currentPath, true); + + newCollection.setParentPath(currentPath); + newCollection.setCreatedAt(new Date()); + newCollection.setModifiedAt(newCollection.getCreatedAt()); + newCollection.setInheritanceOption(collection.getInheritOption()); + + boolean creationSucessful; + try { + creationSucessful = cs.createCollection(newCollection); + + if (creationSucessful) { + redirectAttributes.addFlashAttribute("collectionAddedSuccessfully", collection.getCollectionName()); + } + } catch (DataGridConnectionRefusedException e) { + throw e; + } catch (DataGridException e) { + logger.error("Could not create collection/data object (lack of permission): ", e.getMessage()); + redirectAttributes.addFlashAttribute("missingPermissionError", true); + } + + return "redirect:/collections/"; + } + + /** + * Performs the action of modifying a collection + * + * @throws DataGridConnectionRefusedException + */ + @RequestMapping(value = "modify/action", method = RequestMethod.POST) + public String modifyAction(@ModelAttribute final CollectionOrDataObjectForm collForm, + final RedirectAttributes redirectAttributes) throws DataGridException { + String previousPath = collForm.getPath(); + String parentPath = previousPath.substring(0, previousPath.lastIndexOf("/")); + String newPath = String.format("%s/%s", parentPath, collForm.getCollectionName()); + + logger.info("Modify action for " + previousPath + "/" + newPath); + boolean modificationSuccessful = cs.modifyCollectionAndDataObject(previousPath, newPath, + collForm.getInheritOption()); + + if (modificationSuccessful) { + logger.debug("Collection/Data Object {} modified to {}", previousPath, newPath); + + userBookmarkService.updateBookmark(previousPath, newPath); + groupBookmarkService.updateBookmark(previousPath, newPath); + + redirectAttributes.addFlashAttribute("collectionModifiedSuccessfully", collForm.getCollectionName()); + } + + return "redirect:/collections/"; + } + + @RequestMapping(value = "applyTemplatesToCollections/", method = RequestMethod.POST) + public String applyTemplatesToCollections(final RedirectAttributes redirectAttributes, + @ModelAttribute final MetadataTemplateForm template) throws DataGridConnectionRefusedException { + boolean templatesAppliedSuccessfully = applyTemplatesToPath(template); + redirectAttributes.addFlashAttribute("templatesAppliedSuccessfully", templatesAppliedSuccessfully); + return "redirect:/collections/"; + } + + private boolean applyTemplatesToPath(final MetadataTemplateForm template) + throws DataGridConnectionRefusedException { + boolean allMetadataAdded = true; + List attributes = template.getAvuAttributes(); + List values = template.getAvuValues(); + List units = template.getAvuUnits(); + + if (attributes == null || values == null || units == null) { + return false; + } + + for (int i = 0; i < attributes.size(); i++) { + String attr = attributes.isEmpty() ? "" : attributes.get(i); + String val = values.isEmpty() ? "" : values.get(i); + String unit = units.isEmpty() ? "" : units.get(i); + for (String path : template.getPaths()) { + boolean isMetadadaAdded = metadataService.addMetadataToPath(path, attr, val, unit); + if (!isMetadadaAdded) { + allMetadataAdded = false; + } + } + } + + return allMetadataAdded; + } + + /* + * **************************************************************************** + * ************************ USER COLLECTION CONTROLLER ************************ + * **************************************************************************** + */ + + /** + * Responds the collections/home request + * + * @param model + * @return the collection management template + * @throws DataGridConnectionRefusedException + */ + @RequestMapping(value = "/home/") + public String homeCollection(final Model model) throws DataGridException { + // cleaning session variables + logger.info("homeCollection()"); + sourcePaths.clear(); + currentPath = cs.getHomeDirectyForCurrentUser(); + parentPath = currentPath; + return "redirect:/collections/"; + } + + /** + * Responds the collections/public request + * + * @param model + * @return the collection management template + */ + @RequestMapping(value = "/public/") + public String publicCollection(final Model model) throws DataGridException { + // cleaning session variables + sourcePaths.clear(); + + currentPath = cs.getHomeDirectyForPublic(); + parentPath = currentPath; + + model.addAttribute("publicPath", currentPath); + model.addAttribute("currentPath", currentPath); + model.addAttribute("parentPath", parentPath); + model.addAttribute("homePath", cs.getHomeDirectyForCurrentUser()); + model.addAttribute("resources", resourceService.findAll()); + + return "collections/collectionManagement"; + } + + /** + * Responds the collections/trash request + * + * @param model + * @return the collection management template + * @throws DataGridException + */ + @RequestMapping(value = "/trash/") + public String trashCollection(final Model model) throws DataGridException { + // cleaning session variables + sourcePaths.clear(); + + if (userTrashPath == null || userTrashPath.equals("")) { + userTrashPath = String.format("/%s/trash/home/%s", irodsServices.getCurrentUserZone(), + irodsServices.getCurrentUser()); + } + currentPath = userTrashPath; + parentPath = currentPath; + + model.addAttribute("currentPath", currentPath); + model.addAttribute("parentPath", parentPath); + model.addAttribute("publicPath", cs.getHomeDirectyForPublic()); + model.addAttribute("homePath", cs.getHomeDirectyForCurrentUser()); + model.addAttribute("resources", resourceService.findAll()); + + return "collections/collectionManagement"; + } + + @RequestMapping(value = "/getBreadCrumbForObject/") + public String getBreadCrumbForObject(final Model model, @RequestParam("path") String path) + throws DataGridConnectionRefusedException { + if (path.isEmpty()) { + path = currentPath; + } else { + if (path.endsWith("/") && path.compareTo("/") != 0) { + path = path.substring(0, path.length() - 1); + } + if (!path.equals(currentPath) + && (collectionHistoryBack.isEmpty() || !currentPath.equals(collectionHistoryBack.peek()))) { + while (collectionHistoryBack.size() >= MAX_HISTORY_SIZE) { + collectionHistoryBack.remove(0); + } + collectionHistoryBack.push(currentPath); + if (!collectionHistoryForward.isEmpty()) { + collectionHistoryForward.clear(); + } + } + currentPath = path; + } + + setBreadcrumbToModel(model, path); + return "collections/collectionsBreadCrumb"; + } + + /* + * ***************************************************************************** + * ******************************** VALIDATION ********************************* + * ***************************************************************************** + */ + + /** + * Validates a collection name in iRODS + * + * @return True, if the collection name can be used. False, otherwise. + * @throws DataGridConnectionRefusedException + */ + @ResponseBody + @RequestMapping(value = "isValidCollectionName/{newObjectName}/", method = RequestMethod.GET, produces = { + "text/plain" }) + public String isValidCollectionName(@PathVariable final String newObjectName) throws DataGridException { + String rc = "true"; + String newPath = String.format("%s/%s", currentPath, newObjectName); + + try { + cs.findByName(newPath); + rc = "false"; + } catch (DataGridException e) { + logger.debug("Path {} does not exist. Executing modification", newPath, e); + } + return rc; + } + + /* + * ************************************************************************* + * ******************************** UTILS ********************************** + * ************************************************************************* + */ + + /** + * Finds all collections and data objects existing under a certain path + * + * @param request + * contains all parameters in a map, we can use it to get all + * parameters passed in request + * @return json with collections and data objects + * @throws DataGridConnectionRefusedException + */ + @RequestMapping(value = "getPaginatedJSONObjs/") + @ResponseBody + public String getPaginatedJSONObjs(final HttpServletRequest request) throws DataGridConnectionRefusedException { + List dataGridCollectionAndDataObjects; + + int draw = Integer.parseInt(request.getParameter("draw")); + int start = Integer.parseInt(request.getParameter("start")); + int length = Integer.parseInt(request.getParameter("length")); + String searchString = request.getParameter("search[value]"); + int orderColumn = Integer.parseInt(request.getParameter("order[0][column]")); + String orderDir = request.getParameter("order[0][dir]"); + boolean deployRule = request.getParameter("rulesdeployment") != null; + + // Pagination context to get the sequence number for the listed items + DataGridPageContext pageContext = new DataGridPageContext(); + + ObjectMapper mapper = new ObjectMapper(); + Map jsonResponse = new HashMap(); + jsonResponse.put("draw", String.valueOf(draw)); + jsonResponse.put("recordsTotal", String.valueOf(1)); + jsonResponse.put("recordsFiltered", String.valueOf(0)); + jsonResponse.put("data", new ArrayList()); + String jsonString = ""; + + try { + String path = currentPath; + if (deployRule) { + path = ruleDeploymentService.getRuleCachePath(); + } + + Double startPage = Math.floor(start / length) + 1; + dataGridCollectionAndDataObjects = cs.getSubCollectionsAndDataObjectsUnderPathThatMatchSearchTextPaginated( + path, searchString, startPage.intValue(), length, orderColumn, orderDir, pageContext); + totalObjsForCurrentSearch = pageContext.getTotalNumberOfItems(); + totalObjsForCurrentPath = pageContext.getTotalNumberOfItems(); + + jsonResponse.put("recordsTotal", String.valueOf(totalObjsForCurrentPath)); + jsonResponse.put("recordsFiltered", String.valueOf(totalObjsForCurrentSearch)); + jsonResponse.put("data", dataGridCollectionAndDataObjects); + } catch (DataGridConnectionRefusedException e) { + throw e; + } catch (Exception e) { + logger.error("Could not get collections/data objs under path {}: {}", currentPath, e.getMessage()); + } + + try { + jsonString = mapper.writeValueAsString(jsonResponse); + } catch (JsonProcessingException e) { + logger.error("Could not parse hashmap in collections to json: {}", e.getMessage()); + } + + return jsonString; + } + + /** + * @return the sourcePaths + */ + public List getSourcePaths() { + return sourcePaths; + } + + /** + * @return the currentPath + */ + public String getCurrentPath() { + return currentPath; + } + + public String getParentPath() { + return parentPath; + } + + /** + * Removes a path from the user's navigation history + * + * @param path + * path to be removed + */ + public void removePathFromHistory(final String path) { + if (path == null || path.isEmpty()) { + return; + } + + collectionHistoryBack.remove(path); + collectionHistoryForward.remove(path); + } + + /* + * ************************************************************************** + * **************************** PRIVATE METHODS ***************************** + * ************************************************************************** + */ + + /** + * Sets the current path and parent path based on a given path. + * + * @param path + * new path to update current path and parent path + */ + private void assignNewValuesToCurrentAndParentPath(final String path) { + if (path == null || path.isEmpty()) { + return; + } + + currentPath = path; + parentPath = currentPath.substring(0, currentPath.lastIndexOf("/") + 1); + } + + /** + * Creates the breadcrumb based on a given path. + * + * @param model + * Model attribute to set variables to be used in the view + * @param path + * path that will be displayed in the breadcrumb + */ + private void setBreadcrumbToModel(final Model model, final String path) { + DataGridCollectionAndDataObject obj; + try { + obj = cs.findByName(path); + } catch (DataGridException e) { + obj = new DataGridCollectionAndDataObject(); + obj.setPath(path); + obj.setCollection(false); + obj.setParentPath(path.substring(0, path.lastIndexOf("/") + 1)); + obj.setName(path.substring(path.lastIndexOf("/") + 1, path.length())); + logger.error("Could not find DataGridCollectionAndDataObject by path: {}", e.getMessage()); + } + + setBreadcrumbToModel(model, obj); + } + + /** + * Creates the breadcrumb based on a given path. + * + * @param model + * Model attribute to set variables to be used in the view + * @param obj + * {@code DataGridCollectionAndDataObject} object + */ + private void setBreadcrumbToModel(final Model model, final DataGridCollectionAndDataObject obj) { + ArrayList listHistoryBack = new ArrayList(collectionHistoryBack); + Collections.reverse(listHistoryBack); + + DataGridUser user = loggedUserUtils.getLoggedDataGridUser(); + boolean isPathFavorite = favoritesService.isPathFavoriteForUser(user, obj.getPath()); + + model.addAttribute("starredPath", isPathFavorite); + model.addAttribute("collectionPastHistory", listHistoryBack); + model.addAttribute("collectionPastHistoryEmpty", collectionHistoryBack.isEmpty()); + model.addAttribute("collectionForwardHistory", collectionHistoryForward); + model.addAttribute("collectionForwardHistoryEmpty", collectionHistoryForward.isEmpty()); + model.addAttribute("collectionForwardHistory", collectionHistoryForward); + model.addAttribute("collectionAndDataObject", obj); + model.addAttribute("breadcrumb", new DataGridBreadcrumb(obj.getPath())); + model.addAttribute("homeCollectionName", irodsServices.getCurrentUser()); + } + + /** + * Finds all collections and data objects existing under a certain path + * + * @param model + * @param path + * path to get all directories and data objects from + * @return collections browser template that renders all items of certain path + * (parent) + * @throws DataGridConnectionRefusedException + * if Metalnx cannot connect to the grid. + */ + private String getCollBrowserView(final Model model, String path) throws DataGridException { + logger.info("getCollBrowserView()"); + + logger.info("model:{}", model); + logger.info("path:{}", path); + if (cs.isPathValid(path)) { + if (path.endsWith("/") && path.compareTo("/") != 0) { + path = path.substring(0, path.length() - 1); + } + currentPath = path; + } else { + model.addAttribute("invalidPath", path); + path = currentPath; + } + + DataGridUser user = loggedUserUtils.getLoggedDataGridUser(); + logger.info("find collection by name:{}", path); + DataGridCollectionAndDataObject dataGridObj = cs.findByName(path); + + if (dataGridObj.isDataObject()) { + dataGridObj.setChecksum(cs.getChecksum(path)); + dataGridObj.setNumberOfReplicas(cs.getTotalNumberOfReplsForDataObject(path)); + dataGridObj.setReplicaNumber(String.valueOf(cs.getReplicationNumber(path))); + } + + permissionsService.resolveMostPermissiveAccessForUser(dataGridObj, user); + + if (zoneTrashPath == null || zoneTrashPath.isEmpty()) { + zoneTrashPath = String.format("/%s/trash", irodsServices.getCurrentUserZone()); + } + + CollectionOrDataObjectForm collectionForm = new CollectionOrDataObjectForm(); + collectionForm.setInheritOption(cs.getInheritanceOptionForCollection(currentPath)); + + String permissionType = cs.getPermissionsForPath(path); + boolean isPermissionOwn = "own".equals(permissionType); + boolean isTrash = path.contains(zoneTrashPath) && (isPermissionOwn || user.isAdmin()); + boolean inheritanceDisabled = !isPermissionOwn && collectionForm.getInheritOption(); + + model.addAttribute("collectionAndDataObject", dataGridObj); + model.addAttribute("isTrash", isTrash); + model.addAttribute("permissionType", permissionType); + model.addAttribute("currentPath", currentPath); + model.addAttribute("isCurrentPathCollection", cs.isCollection(path)); + model.addAttribute("user", user); + model.addAttribute("trashColl", cs.getTrashForPath(currentPath)); + model.addAttribute("collection", collectionForm); + model.addAttribute("inheritanceDisabled", inheritanceDisabled); + model.addAttribute("requestMapping", "/collections/add/action/"); + model.addAttribute("parentPath", parentPath); + setBreadcrumbToModel(model, dataGridObj); + return "collections/collectionsBrowser"; + // return "collections/info"; + } + + /** + * Adds a given path to the list of paths visited by the user + * + * @param path + * path to a collection or data object to be added to history + */ + private void addPathToHistory(final String path) { + if (path.equals(currentPath)) { + return; + } + + while (collectionHistoryBack.size() >= MAX_HISTORY_SIZE) { + collectionHistoryBack.remove(0); + } + + collectionHistoryBack.push(currentPath); + + if (!collectionHistoryForward.isEmpty()) { + collectionHistoryForward.clear(); + } + } +} diff --git a/src/emc-metalnx-shared/src/main/java/com/emc/metalnx/controller/CollectionController.java b/src/emc-metalnx-shared/src/main/java/com/emc/metalnx/controller/CollectionController.java index da88fb8f3..3ec3a1307 100755 --- a/src/emc-metalnx-shared/src/main/java/com/emc/metalnx/controller/CollectionController.java +++ b/src/emc-metalnx-shared/src/main/java/com/emc/metalnx/controller/CollectionController.java @@ -16,21 +16,16 @@ package com.emc.metalnx.controller; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.Stack; import javax.annotation.PostConstruct; import javax.servlet.http.HttpServletRequest; -import org.irods.jargon.core.exception.FileNotFoundException; import org.irods.jargon.core.exception.JargonException; +import org.irods.jargon.core.utils.CollectionAndPath; +import org.irods.jargon.core.utils.MiscIRODSUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -38,29 +33,18 @@ import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.util.AntPathMatcher; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.SessionAttributes; import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.servlet.mvc.support.RedirectAttributes; -import org.thymeleaf.util.StringUtils; +import org.springframework.web.servlet.HandlerMapping; import com.emc.metalnx.controller.utils.LoggedUserUtils; -import com.emc.metalnx.core.domain.entity.DataGridCollectionAndDataObject; -import com.emc.metalnx.core.domain.entity.DataGridGroup; -import com.emc.metalnx.core.domain.entity.DataGridPageContext; -import com.emc.metalnx.core.domain.entity.DataGridResource; import com.emc.metalnx.core.domain.entity.DataGridUser; -import com.emc.metalnx.core.domain.exceptions.DataGridConnectionRefusedException; import com.emc.metalnx.core.domain.exceptions.DataGridException; -import com.emc.metalnx.modelattribute.breadcrumb.DataGridBreadcrumb; -import com.emc.metalnx.modelattribute.collection.CollectionOrDataObjectForm; -import com.emc.metalnx.modelattribute.metadatatemplate.MetadataTemplateForm; import com.emc.metalnx.services.interfaces.CollectionService; import com.emc.metalnx.services.interfaces.FavoritesService; import com.emc.metalnx.services.interfaces.GroupBookmarkService; @@ -72,8 +56,6 @@ import com.emc.metalnx.services.interfaces.RuleDeploymentService; import com.emc.metalnx.services.interfaces.UserBookmarkService; import com.emc.metalnx.services.interfaces.UserService; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; @Controller @Scope(WebApplicationContext.SCOPE_SESSION) @@ -146,9 +128,6 @@ public class CollectionController { private boolean cameFromFilePropertiesSearch; private boolean cameFromBookmarks; - private Stack collectionHistoryBack; - private Stack collectionHistoryForward; - // variable to save trash path for the logged user private String userTrashPath = ""; // saves the trash under the zone @@ -158,16 +137,11 @@ public class CollectionController { @PostConstruct public void init() throws DataGridException { - collectionHistoryBack = new Stack(); - collectionHistoryForward = new Stack(); cameFromMetadataSearch = false; cameFromFilePropertiesSearch = false; cameFromBookmarks = false; - sourcePaths = new ArrayList<>(); - parentPath = ""; - currentPath = ""; } /** @@ -175,12 +149,67 @@ public void init() throws DataGridException { * * @param model * @return the collection management template + * @throws JargonException * @throws DataGridException */ - @RequestMapping(value = "/") - public String index(final Model model, final HttpServletRequest request, - @RequestParam(value = "uploadNewTab", required = false) final boolean uploadNewTab) - throws DataGridConnectionRefusedException { + @RequestMapping(value = "/**", method = RequestMethod.GET) + public String indexViaUrl(final Model model, final HttpServletRequest request) { + logger.info("index()"); + + try { + final String path = "/" + extractFilePath(request); + logger.info("path ::" + path); + + DataGridUser loggedUser = loggedUserUtils.getLoggedDataGridUser(); + String uiMode = (String) request.getSession().getAttribute("uiMode"); + + sourcePaths = MiscIRODSUtils.breakIRODSPathIntoComponents(path); + CollectionAndPath collectionAndPath = MiscIRODSUtils.separateCollectionAndPathFromGivenAbsolutePath(path); + this.parentPath = collectionAndPath.getCollectionParent(); + this.currentPath = path; + + if (uiMode == null || uiMode.isEmpty()) { + boolean isUserAdmin = loggedUser != null && loggedUser.isAdmin(); + uiMode = isUserAdmin ? UI_ADMIN_MODE : UI_USER_MODE; + } + + if (uiMode.equals(UI_USER_MODE)) { + model.addAttribute("homePath", cs.getHomeDirectyForCurrentUser()); + model.addAttribute("publicPath", cs.getHomeDirectyForPublic()); + } + + model.addAttribute("cameFromFilePropertiesSearch", cameFromFilePropertiesSearch); + model.addAttribute("cameFromMetadataSearch", cameFromMetadataSearch); + model.addAttribute("cameFromBookmarks", cameFromBookmarks); + model.addAttribute("uiMode", uiMode); + model.addAttribute("currentPath", currentPath); + model.addAttribute("parentPath", parentPath); + model.addAttribute("resources", resourceService.findAll()); + model.addAttribute("overwriteFileOption", loggedUser != null && loggedUser.isForceFileOverwriting()); + } catch (JargonException | DataGridException e) { + logger.error("error establishing collection location", e); + model.addAttribute("unexpectedError", true); + } + + cameFromMetadataSearch = false; + cameFromFilePropertiesSearch = false; + cameFromBookmarks = false; + + logger.info("returning to collections/collectionManagement"); + + return "collections/collectionManagement"; + + } + + /** + * Legacy index method used in other controllers, eventually factor out TODO: + * factor this out and make explicit via urls etc - mcc + * + * @param model + * @param request + * @return + */ + public String index(final Model model, final HttpServletRequest request) { logger.info("index()"); try { sourcePaths.clear(); @@ -204,9 +233,6 @@ public String index(final Model model, final HttpServletRequest request, model.addAttribute("homePath", cs.getHomeDirectyForCurrentUser()); model.addAttribute("publicPath", cs.getHomeDirectyForPublic()); } - if (uploadNewTab) { - model.addAttribute("uploadNewTab", uploadNewTab); - } model.addAttribute("cameFromFilePropertiesSearch", cameFromFilePropertiesSearch); model.addAttribute("cameFromMetadataSearch", cameFromMetadataSearch); @@ -263,873 +289,143 @@ public void redirectFromFilePropertiesToCollections(@RequestParam final String p } /** - * Get a list of resources in which an object doesn't have replicas + * Sets the current path and parent path based on a given path. * - * @param model - * @return list of resources in which an object can be replicated - * @throws DataGridConnectionRefusedException + * @param path + * new path to update current path and parent path */ - @RequestMapping(value = "getAvailableRescForPath/") - public String getAvailableRescForPath(final Model model, @RequestParam("isUpload") final boolean isUpload) - throws DataGridConnectionRefusedException { - - Map replicasMap = null; - List resources = resourceService.findFirstLevelResources(); - - if (!isUpload) { - for (String path : sourcePaths) { - replicasMap = cs.listReplicasByResource(path); - for (DataGridResource resc : replicasMap.values()) { - if (resources.contains(resc)) { - resources.remove(resc); - } - } - } + private void assignNewValuesToCurrentAndParentPath(final String path) { + if (path == null || path.isEmpty()) { + return; } - model.addAttribute("resources", resources); - return "collections/collectionsResourcesForReplica"; - } - /** - * Switches an admin from the Rods_Admin UI to the Rods_User UI and vice-versa. - * - * @param model - * @return redirects an admin user from to the new UI view mode (admin view or - * user view) - */ - @RequestMapping(value = "/switchMode/") - @ResponseStatus(value = HttpStatus.OK) - public void switchMode(final Model model, final HttpServletRequest request, - @RequestParam("currentMode") final String currentMode, final RedirectAttributes redirectAttributes) { - - // if the admin is currently seeing the Admin UI, we need to switch it - // over to the USER UI - if (currentMode.equalsIgnoreCase(UI_ADMIN_MODE)) { - request.getSession().setAttribute("uiMode", UI_USER_MODE); - } - // if the admin is currently seeing the User UI, we need to switch it - // over to the ADMIN UI - else if (currentMode.equalsIgnoreCase(UI_USER_MODE)) { - request.getSession().setAttribute("uiMode", UI_ADMIN_MODE); - } + currentPath = path; + parentPath = currentPath.substring(0, currentPath.lastIndexOf("/") + 1); } /** - * Responds the getSubdirectories request finding collections and data objects - * that exist underneath a certain path - * - * @param model - * @param path - * path to find all subdirectories and objects - * @return treeView template that renders all nodes of certain path (parent) - * @throws DataGridException - * if Metalnx cannot find collections and objects inside the path + * TODO: refactor into a service object, including obtaining the encoding - mcc + * + * @param request + * @return + * @throws JargonException */ - @RequestMapping(value = "/getSubDirectories/", method = RequestMethod.POST) - public String getSubDirectories(final Model model, @RequestParam("path") String path) throws DataGridException { - - // removes all ocurrences of "/" at the end of the path string - while (path.endsWith("/") && !"/".equals(path)) { - path = path.substring(0, path.lastIndexOf("/")); + private String extractFilePath(HttpServletRequest request) throws JargonException { + String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE); + try { + path = URLDecoder.decode(path, + this.getIrodsServices().getIrodsAccessObjectFactory().getJargonProperties().getEncoding()); + } catch (UnsupportedEncodingException | JargonException e) { + logger.error("unable to decode path", e); + throw new JargonException(e); } - - logger.info("Get subdirectories of {}", path); - - System.out.println("In GetSubdirectories!!"); - System.out.println("path :: " +path); - - // put old path in collection history stack - addPathToHistory(path); - - return getCollBrowserView(model, path); + String bestMatchPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE); + AntPathMatcher apm = new AntPathMatcher(); + return apm.extractPathWithinPattern(bestMatchPattern, path); } - - - /** - * Goes back in collection historic stack - * - * @param model - * @param steps - * @return treeView template that renders all nodes of certain path (parent) - * @throws DataGridConnectionRefusedException - */ - @RequestMapping(value = "/goBackHistory/", method = RequestMethod.POST) - public String goBackHistory(final Model model, @RequestParam("steps") final int steps) - throws DataGridException, JargonException { - if (collectionHistoryBack.size() < steps || steps < 1) { - model.addAttribute("invalidStepsBackwards", steps); - logger.info("It is not possible to go back {} steps, current stack size is {}", steps, - collectionHistoryBack.size()); - return getCollBrowserView(model, currentPath); - } - - logger.info("Going back {} steps in collection history", steps); - // pop paths from collectionHistoryBack and push them to - // collectionHistoryForward - while (collectionHistoryForward.size() >= MAX_HISTORY_SIZE) { - collectionHistoryForward.remove(0); - } - collectionHistoryForward.push(currentPath); - for (int i = 0; i < steps - 1; i++) { - String elementHistory = collectionHistoryBack.pop(); - while (collectionHistoryForward.size() >= MAX_HISTORY_SIZE) { - collectionHistoryForward.remove(0); - } - collectionHistoryForward.push(elementHistory); - } - - return getCollBrowserView(model, collectionHistoryBack.pop()); + public ResourceService getResourceService() { + return resourceService; } - /** - * Goes forward in collection historic stack - * - * @param model - * @param steps - * @return treeView template that renders all nodes of certain path (parent) - * @throws DataGridConnectionRefusedException - */ - @RequestMapping(value = "/goForwardHistory/", method = RequestMethod.POST) - public String goForwardHistory(final Model model, @RequestParam("steps") final int steps) - throws DataGridException, JargonException { - if (collectionHistoryForward.size() < steps || steps < 1) { - model.addAttribute("invalidStepsForward", steps); - return getCollBrowserView(model, currentPath); - } - - logger.info("Going {} steps forward in collection history", steps); - - // pop paths from collectionHistoryBack and push them to - // collectionHistoryForward - while (collectionHistoryBack.size() >= MAX_HISTORY_SIZE) { - collectionHistoryBack.remove(0); - } - collectionHistoryBack.push(currentPath); - for (int i = 0; i < steps - 1; i++) { - String elementHistory = collectionHistoryForward.pop(); - while (collectionHistoryBack.size() >= MAX_HISTORY_SIZE) { - collectionHistoryBack.remove(0); - } - collectionHistoryBack.push(elementHistory); - } - - return getCollBrowserView(model, collectionHistoryForward.pop()); + public void setResourceService(ResourceService resourceService) { + this.resourceService = resourceService; } - /** - * Responds the getSubdirectories request finding collections and data objects - * that exist underneath a certain path - * - * @param model - * @param path - * @return treeView template that renders all nodes of certain path (parent) - * @throws DataGridConnectionRefusedException - */ - @RequestMapping(value = "/getSubDirectoriesOldTree/") - public String getSubDirectoriesOldTree(final Model model, @RequestParam("path") String path) - throws DataGridConnectionRefusedException { - - if (path.isEmpty()) { - path = "/"; - } else { - if (path.endsWith("/") && path.compareTo("/") != 0) { - path = path.substring(0, path.length() - 1); - } - } - - // The line below was modified so that only collection would be retrieved - model.addAttribute("dataGridCollectionAndDataObjectList", cs.getSubCollectionsUnderPath(path)); - - return "collections/oldTreeView :: oldTreeView"; + public UserService getUserService() { + return userService; } - /** - * Gets checksum, total number of replicas and where each replica lives in the - * data grid for a specific data object - * - * @param model - * @param path - * path to the data object to get checksum and replica information - * @return the template that shows the data object information - * @throws DataGridConnectionRefusedException - */ - @RequestMapping(value = "/info/" , method = RequestMethod.POST) - public String getFileInfo(final Model model, final String path) - throws DataGridConnectionRefusedException { - - System.out.println("CollectionController getInfoFile() starts !!"); - DataGridCollectionAndDataObject dataGridObj = null; - Map replicasMap = null; - - try { - System.out.println("Path = " +path); - - dataGridObj = cs.findByName(path); - - if (dataGridObj != null && !dataGridObj.isCollection()) { - replicasMap = cs.listReplicasByResource(path); - dataGridObj.setChecksum(cs.getChecksum(path)); - dataGridObj.setNumberOfReplicas(cs.getTotalNumberOfReplsForDataObject(path)); - dataGridObj.setReplicaNumber(String.valueOf(cs.getReplicationNumber(path))); - permissionsService.resolveMostPermissiveAccessForUser(dataGridObj, - loggedUserUtils.getLoggedDataGridUser()); - - - } - - } catch (DataGridConnectionRefusedException e) { - logger.error("Could not connect to the data grid", e); - throw e; - } catch (DataGridException e) { - logger.error("Could not get file info for {}", path, e); - } - - model.addAttribute("collectionAndDataObject", dataGridObj); - model.addAttribute("currentCollection", dataGridObj); - model.addAttribute("replicasMap", replicasMap); - model.addAttribute("infoFlag", true); - - - System.out.println("permissionOnCurrentPath =======" + cs.getPermissionsForPath(path)); - System.out.println("currentCollection.getName() == "+ dataGridObj.getName()); - - System.out.println("CollectionController getInfoFile() ends !!"); - return "collections/info :: infoView"; - //return "collections/info"; + public void setUserService(UserService userService) { + this.userService = userService; } - /** - * Finds all collections and files existing under a certain path for a given - * group name. - * - * @param model - * @param path - * start point to get collections and files - * @param groupName - * group that all collections and files permissions will be listed - * @return - * @throws DataGridConnectionRefusedException - * @throws JargonException - * @throws FileNotFoundException - */ - @RequestMapping(value = "/getDirectoriesAndFilesForGroupForm") - public String getDirectoriesAndFilesForGroupForm(final Model model, @RequestParam("path") String path, - @RequestParam("groupName") final String groupName, - @RequestParam("retrievePermissions") final boolean retrievePermissions) - throws DataGridConnectionRefusedException, FileNotFoundException, JargonException { - if (path == null || path == "") { - path = "/"; - } - - List list = null; - list = cs.getSubCollectionsAndDataObjectsUnderPath(path); - - Set readPermissions = null; - Set writePermissions = null; - Set ownershipPermissions = null; - Set inheritPermissions = null; - - if (retrievePermissions) { - readPermissions = cs.listReadPermissionsForPathAndGroup(path, groupName); - writePermissions = cs.listWritePermissionsForPathAndGroup(path, groupName); - ownershipPermissions = cs.listOwnershipForPathAndGroup(path, groupName); - inheritPermissions = cs.listInheritanceForPath(path); - } else { - readPermissions = new HashSet(); - writePermissions = new HashSet(); - ownershipPermissions = new HashSet(); - inheritPermissions = new HashSet(); - } - - List groupBookmarks = new ArrayList(); - if (groupName.length() > 0) { - DataGridGroup group = groupService.findByGroupname(groupName).get(0); - groupBookmarks = groupBookmarkService.findBookmarksForGroupAsString(group); - } - - model.addAttribute("dataGridCollectionAndDataObjectList", list); - model.addAttribute("currentPath", path); - model.addAttribute("readPermissions", readPermissions); - model.addAttribute("writePermissions", writePermissions); - model.addAttribute("ownershipPermissions", ownershipPermissions); - model.addAttribute("inheritPermissions", inheritPermissions); - model.addAttribute("addBookmark", groupBookmarkController.getAddBookmark()); - model.addAttribute("removeBookmark", groupBookmarkController.getRemoveBookmark()); - model.addAttribute("groupBookmarks", groupBookmarks); - - return "collections/treeViewForGroupForm :: treeView"; + public GroupService getGroupService() { + return groupService; } - /** - * Finds all collections existing under a certain path. - * - * @param model - * @param path - * start point to get collections and files - * @param username - * user who all collections and files permissions will be listed - * @return the template that will render the tree - * @throws DataGridConnectionRefusedException - * @throws JargonException - * @throws FileNotFoundException - */ - @RequestMapping(value = "/getDirectoriesAndFilesForUser") - public String getDirectoriesAndFilesForUser(final Model model, @RequestParam("path") final String path, - @RequestParam("username") final String username, - @RequestParam("retrievePermissions") final boolean retrievePermissions) - throws DataGridConnectionRefusedException, FileNotFoundException, JargonException { - - List list = new ArrayList(); - Set readPermissions = new HashSet(); - Set writePermissions = new HashSet(); - Set ownershipPermissions = new HashSet(); - Set inheritPermissions = new HashSet(); - List userBookmarks = new ArrayList(); - - // If a string is null, empty or contains only white spaces, StringUtils - // returns true - boolean isPathEmpty = StringUtils.isEmptyOrWhitespace(path); - boolean isUsernameEmpty = StringUtils.isEmptyOrWhitespace(username); - - if (!isPathEmpty) { - // When adding a user (there is no username), we still need to be - // able to walk through the iRODS tree - list = cs.getSubCollectionsAndDataObjectsUnderPath(path); - - if (!isUsernameEmpty) { - if (retrievePermissions) { - readPermissions = cs.listReadPermissionsForPathAndUser(path, username); - writePermissions = cs.listWritePermissionsForPathAndUser(path, username); - ownershipPermissions = cs.listOwnershipForPathAndUser(path, username); - inheritPermissions = cs.listInheritanceForPath(path); - } - - List users = userService.findByUsername(username); - if (users != null && !users.isEmpty()) { - userBookmarks = userBookmarkService.findBookmarksForUserAsString(users.get(0)); - } - } - } - - model.addAttribute("dataGridCollectionAndDataObjectList", list); - model.addAttribute("currentPath", path); - model.addAttribute("readPermissions", readPermissions); - model.addAttribute("writePermissions", writePermissions); - model.addAttribute("ownershipPermissions", ownershipPermissions); - model.addAttribute("inheritPermissions", inheritPermissions); - model.addAttribute("addBookmark", new ArrayList()); - model.addAttribute("removeBookmark", new ArrayList()); - model.addAttribute("userBookmarks", userBookmarks); - - return "collections/treeViewForUserForm :: treeView"; + public void setGroupService(GroupService groupService) { + this.groupService = groupService; } - /** - * Looks for collections or data objects that match the parameter string - * - * @param model - * @param name - * collection name that will be searched in the data grid - * @return the template that renders all collections and data objects matching - * the parameter string - * @throws DataGridConnectionRefusedException - */ - @RequestMapping(value = "/find/{name}") - public String listCollectionsAndDataObjects(final Model model, @PathVariable final String name) - throws DataGridConnectionRefusedException { - logger.info("Finding collections or data objects that match " + name); - - // Find collections and data objects - List dataGridCollectionAndDataObjects = cs - .searchCollectionAndDataObjectsByName(name + "%"); - model.addAttribute("dataGridCollectionAndDataObjects", dataGridCollectionAndDataObjects); - return "collections/collectionsBrowser :: treeView"; + public GroupBookmarkService getGroupBookmarkService() { + return groupBookmarkService; } - /** - * Performs the action of actually creating a collection in iRODS - * - * @param model - * @param collection - * @return if the creation of collection was successful, it returns the - * collection management template, and returns the add collection - * template, otherwise. - * @throws DataGridConnectionRefusedException - */ - @RequestMapping(value = "add/action/", method = RequestMethod.POST) - public String addCollection(final Model model, @ModelAttribute final CollectionOrDataObjectForm collection, - final RedirectAttributes redirectAttributes) throws DataGridConnectionRefusedException { - DataGridCollectionAndDataObject newCollection = new DataGridCollectionAndDataObject( - currentPath + '/' + collection.getCollectionName(), collection.getCollectionName(), currentPath, true); - - newCollection.setParentPath(currentPath); - newCollection.setCreatedAt(new Date()); - newCollection.setModifiedAt(newCollection.getCreatedAt()); - newCollection.setInheritanceOption(collection.getInheritOption()); - - boolean creationSucessful; - try { - creationSucessful = cs.createCollection(newCollection); - - if (creationSucessful) { - redirectAttributes.addFlashAttribute("collectionAddedSuccessfully", collection.getCollectionName()); - } - } catch (DataGridConnectionRefusedException e) { - throw e; - } catch (DataGridException e) { - logger.error("Could not create collection/data object (lack of permission): ", e.getMessage()); - redirectAttributes.addFlashAttribute("missingPermissionError", true); - } - - return "redirect:/collections/"; + public void setGroupBookmarkService(GroupBookmarkService groupBookmarkService) { + this.groupBookmarkService = groupBookmarkService; } - /** - * Performs the action of modifying a collection - * - * @throws DataGridConnectionRefusedException - */ - @RequestMapping(value = "modify/action", method = RequestMethod.POST) - public String modifyAction(@ModelAttribute final CollectionOrDataObjectForm collForm, - final RedirectAttributes redirectAttributes) throws DataGridException { - String previousPath = collForm.getPath(); - String parentPath = previousPath.substring(0, previousPath.lastIndexOf("/")); - String newPath = String.format("%s/%s", parentPath, collForm.getCollectionName()); - - logger.info("Modify action for " + previousPath + "/" + newPath); - boolean modificationSuccessful = cs.modifyCollectionAndDataObject(previousPath, newPath, - collForm.getInheritOption()); - - if (modificationSuccessful) { - logger.debug("Collection/Data Object {} modified to {}", previousPath, newPath); - - userBookmarkService.updateBookmark(previousPath, newPath); - groupBookmarkService.updateBookmark(previousPath, newPath); - - redirectAttributes.addFlashAttribute("collectionModifiedSuccessfully", collForm.getCollectionName()); - } - - return "redirect:/collections/"; + public UserBookmarkService getUserBookmarkService() { + return userBookmarkService; } - @RequestMapping(value = "applyTemplatesToCollections/", method = RequestMethod.POST) - public String applyTemplatesToCollections(final RedirectAttributes redirectAttributes, - @ModelAttribute final MetadataTemplateForm template) throws DataGridConnectionRefusedException { - boolean templatesAppliedSuccessfully = applyTemplatesToPath(template); - redirectAttributes.addFlashAttribute("templatesAppliedSuccessfully", templatesAppliedSuccessfully); - return "redirect:/collections/"; + public void setUserBookmarkService(UserBookmarkService userBookmarkService) { + this.userBookmarkService = userBookmarkService; } - private boolean applyTemplatesToPath(final MetadataTemplateForm template) - throws DataGridConnectionRefusedException { - boolean allMetadataAdded = true; - List attributes = template.getAvuAttributes(); - List values = template.getAvuValues(); - List units = template.getAvuUnits(); - - if (attributes == null || values == null || units == null) { - return false; - } - - for (int i = 0; i < attributes.size(); i++) { - String attr = attributes.isEmpty() ? "" : attributes.get(i); - String val = values.isEmpty() ? "" : values.get(i); - String unit = units.isEmpty() ? "" : units.get(i); - for (String path : template.getPaths()) { - boolean isMetadadaAdded = metadataService.addMetadataToPath(path, attr, val, unit); - if (!isMetadadaAdded) { - allMetadataAdded = false; - } - } - } - - return allMetadataAdded; + public MetadataService getMetadataService() { + return metadataService; } - /* - * **************************************************************************** - * ************************ USER COLLECTION CONTROLLER ************************ - * **************************************************************************** - */ - - /** - * Responds the collections/home request - * - * @param model - * @return the collection management template - * @throws DataGridConnectionRefusedException - */ - @RequestMapping(value = "/home/") - public String homeCollection(final Model model) throws DataGridException { - // cleaning session variables - logger.info("homeCollection()"); - sourcePaths.clear(); - currentPath = cs.getHomeDirectyForCurrentUser(); - parentPath = currentPath; - return "redirect:/collections/"; + public void setMetadataService(MetadataService metadataService) { + this.metadataService = metadataService; } - /** - * Responds the collections/public request - * - * @param model - * @return the collection management template - */ - @RequestMapping(value = "/public/") - public String publicCollection(final Model model) throws DataGridException { - // cleaning session variables - sourcePaths.clear(); - - currentPath = cs.getHomeDirectyForPublic(); - parentPath = currentPath; - - model.addAttribute("publicPath", currentPath); - model.addAttribute("currentPath", currentPath); - model.addAttribute("parentPath", parentPath); - model.addAttribute("homePath", cs.getHomeDirectyForCurrentUser()); - model.addAttribute("resources", resourceService.findAll()); - - return "collections/collectionManagement"; + public GroupBookmarkController getGroupBookmarkController() { + return groupBookmarkController; } - /** - * Responds the collections/trash request - * - * @param model - * @return the collection management template - * @throws DataGridException - */ - @RequestMapping(value = "/trash/") - public String trashCollection(final Model model) throws DataGridException { - // cleaning session variables - sourcePaths.clear(); - - if (userTrashPath == null || userTrashPath.equals("")) { - userTrashPath = String.format("/%s/trash/home/%s", irodsServices.getCurrentUserZone(), - irodsServices.getCurrentUser()); - } - currentPath = userTrashPath; - parentPath = currentPath; - - model.addAttribute("currentPath", currentPath); - model.addAttribute("parentPath", parentPath); - model.addAttribute("publicPath", cs.getHomeDirectyForPublic()); - model.addAttribute("homePath", cs.getHomeDirectyForCurrentUser()); - model.addAttribute("resources", resourceService.findAll()); - - return "collections/collectionManagement"; + public void setGroupBookmarkController(GroupBookmarkController groupBookmarkController) { + this.groupBookmarkController = groupBookmarkController; } - @RequestMapping(value = "/getBreadCrumbForObject/") - public String getBreadCrumbForObject(final Model model, @RequestParam("path") String path) - throws DataGridConnectionRefusedException { - if (path.isEmpty()) { - path = currentPath; - } else { - if (path.endsWith("/") && path.compareTo("/") != 0) { - path = path.substring(0, path.length() - 1); - } - if (!path.equals(currentPath) - && (collectionHistoryBack.isEmpty() || !currentPath.equals(collectionHistoryBack.peek()))) { - while (collectionHistoryBack.size() >= MAX_HISTORY_SIZE) { - collectionHistoryBack.remove(0); - } - collectionHistoryBack.push(currentPath); - if (!collectionHistoryForward.isEmpty()) { - collectionHistoryForward.clear(); - } - } - currentPath = path; - } - - setBreadcrumbToModel(model, path); - return "collections/collectionsBreadCrumb"; + public PermissionsService getPermissionsService() { + return permissionsService; } - /* - * ***************************************************************************** - * ******************************** VALIDATION ********************************* - * ***************************************************************************** - */ - - /** - * Validates a collection name in iRODS - * - * @return True, if the collection name can be used. False, otherwise. - * @throws DataGridConnectionRefusedException - */ - @ResponseBody - @RequestMapping(value = "isValidCollectionName/{newObjectName}/", method = RequestMethod.GET, produces = { - "text/plain" }) - public String isValidCollectionName(@PathVariable final String newObjectName) throws DataGridException { - String rc = "true"; - String newPath = String.format("%s/%s", currentPath, newObjectName); - - try { - cs.findByName(newPath); - rc = "false"; - } catch (DataGridException e) { - logger.debug("Path {} does not exist. Executing modification", newPath, e); - } - return rc; + public void setPermissionsService(PermissionsService permissionsService) { + this.permissionsService = permissionsService; } - /* - * ************************************************************************* - * ******************************** UTILS ********************************** - * ************************************************************************* - */ - - /** - * Finds all collections and data objects existing under a certain path - * - * @param request - * contains all parameters in a map, we can use it to get all - * parameters passed in request - * @return json with collections and data objects - * @throws DataGridConnectionRefusedException - */ - @RequestMapping(value = "getPaginatedJSONObjs/") - @ResponseBody - public String getPaginatedJSONObjs(final HttpServletRequest request) throws DataGridConnectionRefusedException { - List dataGridCollectionAndDataObjects; - - int draw = Integer.parseInt(request.getParameter("draw")); - int start = Integer.parseInt(request.getParameter("start")); - int length = Integer.parseInt(request.getParameter("length")); - String searchString = request.getParameter("search[value]"); - int orderColumn = Integer.parseInt(request.getParameter("order[0][column]")); - String orderDir = request.getParameter("order[0][dir]"); - boolean deployRule = request.getParameter("rulesdeployment") != null; - - // Pagination context to get the sequence number for the listed items - DataGridPageContext pageContext = new DataGridPageContext(); - - ObjectMapper mapper = new ObjectMapper(); - Map jsonResponse = new HashMap(); - jsonResponse.put("draw", String.valueOf(draw)); - jsonResponse.put("recordsTotal", String.valueOf(1)); - jsonResponse.put("recordsFiltered", String.valueOf(0)); - jsonResponse.put("data", new ArrayList()); - String jsonString = ""; - - try { - String path = currentPath; - if (deployRule) { - path = ruleDeploymentService.getRuleCachePath(); - } - - Double startPage = Math.floor(start / length) + 1; - dataGridCollectionAndDataObjects = cs.getSubCollectionsAndDataObjectsUnderPathThatMatchSearchTextPaginated( - path, searchString, startPage.intValue(), length, orderColumn, orderDir, pageContext); - totalObjsForCurrentSearch = pageContext.getTotalNumberOfItems(); - totalObjsForCurrentPath = pageContext.getTotalNumberOfItems(); - - jsonResponse.put("recordsTotal", String.valueOf(totalObjsForCurrentPath)); - jsonResponse.put("recordsFiltered", String.valueOf(totalObjsForCurrentSearch)); - jsonResponse.put("data", dataGridCollectionAndDataObjects); - } catch (DataGridConnectionRefusedException e) { - throw e; - } catch (Exception e) { - logger.error("Could not get collections/data objs under path {}: {}", currentPath, e.getMessage()); - } - - try { - jsonString = mapper.writeValueAsString(jsonResponse); - } catch (JsonProcessingException e) { - logger.error("Could not parse hashmap in collections to json: {}", e.getMessage()); - } - - return jsonString; + public IRODSServices getIrodsServices() { + return irodsServices; } - /** - * @return the sourcePaths - */ - public List getSourcePaths() { - return sourcePaths; + public void setIrodsServices(IRODSServices irodsServices) { + this.irodsServices = irodsServices; } - /** - * @return the currentPath - */ - public String getCurrentPath() { - return currentPath; + public FavoritesService getFavoritesService() { + return favoritesService; } - public String getParentPath() { - return parentPath; + public void setFavoritesService(FavoritesService favoritesService) { + this.favoritesService = favoritesService; } - /** - * Removes a path from the user's navigation history - * - * @param path - * path to be removed - */ - public void removePathFromHistory(final String path) { - if (path == null || path.isEmpty()) { - return; - } - - collectionHistoryBack.remove(path); - collectionHistoryForward.remove(path); + public LoggedUserUtils getLoggedUserUtils() { + return loggedUserUtils; } - /* - * ************************************************************************** - * **************************** PRIVATE METHODS ***************************** - * ************************************************************************** - */ - - /** - * Sets the current path and parent path based on a given path. - * - * @param path - * new path to update current path and parent path - */ - private void assignNewValuesToCurrentAndParentPath(final String path) { - if (path == null || path.isEmpty()) { - return; - } - - currentPath = path; - parentPath = currentPath.substring(0, currentPath.lastIndexOf("/") + 1); + public void setLoggedUserUtils(LoggedUserUtils loggedUserUtils) { + this.loggedUserUtils = loggedUserUtils; } - /** - * Creates the breadcrumb based on a given path. - * - * @param model - * Model attribute to set variables to be used in the view - * @param path - * path that will be displayed in the breadcrumb - */ - private void setBreadcrumbToModel(final Model model, final String path) { - DataGridCollectionAndDataObject obj; - try { - obj = cs.findByName(path); - } catch (DataGridException e) { - obj = new DataGridCollectionAndDataObject(); - obj.setPath(path); - obj.setCollection(false); - obj.setParentPath(path.substring(0, path.lastIndexOf("/") + 1)); - obj.setName(path.substring(path.lastIndexOf("/") + 1, path.length())); - logger.error("Could not find DataGridCollectionAndDataObject by path: {}", e.getMessage()); - } - - setBreadcrumbToModel(model, obj); + public RuleDeploymentService getRuleDeploymentService() { + return ruleDeploymentService; } - /** - * Creates the breadcrumb based on a given path. - * - * @param model - * Model attribute to set variables to be used in the view - * @param obj - * {@code DataGridCollectionAndDataObject} object - */ - private void setBreadcrumbToModel(final Model model, final DataGridCollectionAndDataObject obj) { - ArrayList listHistoryBack = new ArrayList(collectionHistoryBack); - Collections.reverse(listHistoryBack); - - DataGridUser user = loggedUserUtils.getLoggedDataGridUser(); - boolean isPathFavorite = favoritesService.isPathFavoriteForUser(user, obj.getPath()); - - model.addAttribute("starredPath", isPathFavorite); - model.addAttribute("collectionPastHistory", listHistoryBack); - model.addAttribute("collectionPastHistoryEmpty", collectionHistoryBack.isEmpty()); - model.addAttribute("collectionForwardHistory", collectionHistoryForward); - model.addAttribute("collectionForwardHistoryEmpty", collectionHistoryForward.isEmpty()); - model.addAttribute("collectionForwardHistory", collectionHistoryForward); - model.addAttribute("collectionAndDataObject", obj); - model.addAttribute("breadcrumb", new DataGridBreadcrumb(obj.getPath())); - model.addAttribute("homeCollectionName", irodsServices.getCurrentUser()); + public void setRuleDeploymentService(RuleDeploymentService ruleDeploymentService) { + this.ruleDeploymentService = ruleDeploymentService; } - /** - * Finds all collections and data objects existing under a certain path - * - * @param model - * @param path - * path to get all directories and data objects from - * @return collections browser template that renders all items of certain path - * (parent) - * @throws DataGridConnectionRefusedException - * if Metalnx cannot connect to the grid. - */ - private String getCollBrowserView(final Model model, String path) throws DataGridException { - logger.info("getCollBrowserView()"); - if (cs.isPathValid(path)) { - if (path.endsWith("/") && path.compareTo("/") != 0) { - path = path.substring(0, path.length() - 1); - } - currentPath = path; - } else { - model.addAttribute("invalidPath", path); - path = currentPath; - } - - DataGridUser user = loggedUserUtils.getLoggedDataGridUser(); - logger.info("find collection by name:{}", path); - DataGridCollectionAndDataObject dataGridObj = cs.findByName(path); - - if (dataGridObj.isDataObject()) { - dataGridObj.setChecksum(cs.getChecksum(path)); - dataGridObj.setNumberOfReplicas(cs.getTotalNumberOfReplsForDataObject(path)); - dataGridObj.setReplicaNumber(String.valueOf(cs.getReplicationNumber(path))); - } - - permissionsService.resolveMostPermissiveAccessForUser(dataGridObj, user); - - if (zoneTrashPath == null || zoneTrashPath.isEmpty()) { - zoneTrashPath = String.format("/%s/trash", irodsServices.getCurrentUserZone()); - } - - CollectionOrDataObjectForm collectionForm = new CollectionOrDataObjectForm(); - collectionForm.setInheritOption(cs.getInheritanceOptionForCollection(currentPath)); - - String permissionType = cs.getPermissionsForPath(path); - boolean isPermissionOwn = "own".equals(permissionType); - boolean isTrash = path.contains(zoneTrashPath) && (isPermissionOwn || user.isAdmin()); - boolean inheritanceDisabled = !isPermissionOwn && collectionForm.getInheritOption(); - - model.addAttribute("collectionAndDataObject", dataGridObj); - model.addAttribute("isTrash", isTrash); - model.addAttribute("permissionType", permissionType); - model.addAttribute("currentPath", currentPath); - model.addAttribute("isCurrentPathCollection", cs.isCollection(path)); - model.addAttribute("user", user); - model.addAttribute("trashColl", cs.getTrashForPath(currentPath)); - model.addAttribute("collection", collectionForm); - model.addAttribute("inheritanceDisabled", inheritanceDisabled); - model.addAttribute("requestMapping", "/collections/add/action/"); - model.addAttribute("parentPath", parentPath); - setBreadcrumbToModel(model, dataGridObj); - return "collections/collectionsBrowser"; - //return "collections/info"; + public String getCurrentPath() { + return currentPath; } - /** - * Adds a given path to the list of paths visited by the user - * - * @param path - * path to a collection or data object to be added to history - */ - private void addPathToHistory(final String path) { - if (path.equals(currentPath)) { - return; - } - - while (collectionHistoryBack.size() >= MAX_HISTORY_SIZE) { - collectionHistoryBack.remove(0); - } - - collectionHistoryBack.push(currentPath); - - if (!collectionHistoryForward.isEmpty()) { - collectionHistoryForward.clear(); - } + public void setCurrentPath(String currentPath) { + this.currentPath = currentPath; } + } diff --git a/src/emc-metalnx-shared/src/main/java/com/emc/metalnx/controller/CollectionInfoController.java b/src/emc-metalnx-shared/src/main/java/com/emc/metalnx/controller/CollectionInfoController.java index 0f6d54c16..3740c7b67 100644 --- a/src/emc-metalnx-shared/src/main/java/com/emc/metalnx/controller/CollectionInfoController.java +++ b/src/emc-metalnx-shared/src/main/java/com/emc/metalnx/controller/CollectionInfoController.java @@ -2,6 +2,8 @@ import java.io.IOException; import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; import javax.servlet.http.HttpServletRequest; @@ -21,7 +23,6 @@ import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.util.AntPathMatcher; -import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; @@ -30,7 +31,6 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.servlet.HandlerMapping; -import com.emc.metalnx.controller.utils.LoggedUserUtils; import com.emc.metalnx.core.domain.exceptions.DataGridConnectionRefusedException; import com.emc.metalnx.core.domain.exceptions.DataGridException; import com.emc.metalnx.services.interfaces.CollectionService; @@ -55,7 +55,7 @@ public class CollectionInfoController { @Autowired IRODSServices irodsServices; - + @Autowired IconService iconService; @@ -66,7 +66,7 @@ public class CollectionInfoController { @RequestMapping(value = "/**", method = RequestMethod.GET) public String getTestCollectionInfo(final Model model, HttpServletRequest request) - throws DataGridException, DataGridConnectionRefusedException { + throws DataGridException, DataGridConnectionRefusedException, JargonException { logger.info("CollectionInfoController getTestCollectionInfo() starts !!"); final String path = "/" + extractFilePath(request); @@ -75,32 +75,31 @@ public String getTestCollectionInfo(final Model model, HttpServletRequest reques @SuppressWarnings("rawtypes") DataProfile dataProfile = getCollectionDataProfile(path); - + String iconToDisplay = ""; - - if(dataProfile!= null && dataProfile.isFile()) + + if (dataProfile != null && dataProfile.isFile()) iconToDisplay = iconService.getIconToDisplayFile(dataProfile.getDataType().getMimeType()); - if(dataProfile!= null && !dataProfile.isFile()) + if (dataProfile != null && !dataProfile.isFile()) iconToDisplay = iconService.getIconToDisplayCollection(); - - model.addAttribute("iconToDisplay", iconToDisplay); + + model.addAttribute("iconToDisplay", iconToDisplay); model.addAttribute("dataProfile", dataProfile); String template = ""; - - if(!dataProfile.isFile()) + + if (!dataProfile.isFile()) template = "collections/collectionInfo"; - if(dataProfile.isFile()) + if (dataProfile.isFile()) template = "collections/fileInfo"; - - return template; - - //:: mainPage(page='collections/collectionInfo', fragment='collectionInfo')"; - //"main :: mainPage(page='some-page', fragment='somePage')"; + + return template; + + // :: mainPage(page='collections/collectionInfo', fragment='collectionInfo')"; + // "main :: mainPage(page='some-page', fragment='somePage')"; } - + @SuppressWarnings("unchecked") public DataProfile getCollectionDataProfile(String path) throws DataGridException { - IRODSAccount irodsAccount = irodsServices.getUserAO().getIRODSAccount(); logger.debug("got irodsAccount:{}", irodsAccount); @@ -116,47 +115,45 @@ public DataProfile getCollectionDataProfile(String path) thro DataProfile dataProfile = dataProfilerService.retrieveDataProfile(path); logger.info("------CollectionInfoController getTestCollectionInfo() ends !!"); logger.info("data profile retrieved:{}", dataProfile); - + /* * TODO: after this do an if test and send to right view with the DataProfile in * the model */ return dataProfile; - + } catch (JargonException e) { logger.error("Could not retrieve collection/dataobject from path: {}", path, e); throw new DataGridException(e.getMessage()); } } - - - + @RequestMapping(value = "/collectionFileInfo/", method = RequestMethod.POST) - public String getCollectionFileInfo(final Model model, @RequestParam("path") - final String path) throws DataGridException { + public String getCollectionFileInfo(final Model model, @RequestParam("path") final String path) + throws DataGridException { + + logger.info("CollectionInfoController getCollectionFileInfo() starts :: " + path); - logger.info("CollectionInfoController getCollectionFileInfo() starts :: " +path); - @SuppressWarnings("rawtypes") DataProfile dataProfile = getCollectionDataProfile(path); - + String iconToDisplay = ""; - - if(dataProfile!= null && dataProfile.isFile()) + + if (dataProfile != null && dataProfile.isFile()) iconToDisplay = iconService.getIconToDisplayFile(dataProfile.getDataType().getMimeType()); - if(dataProfile!= null && !dataProfile.isFile()) + if (dataProfile != null && !dataProfile.isFile()) iconToDisplay = iconService.getIconToDisplayCollection(); - - model.addAttribute("iconToDisplay", iconToDisplay); + + model.addAttribute("iconToDisplay", iconToDisplay); model.addAttribute("dataProfile", dataProfile); - + logger.info("getCollectionFileInfo() ends !!"); return "collections/info :: infoView"; - //return "collections/info"; + // return "collections/info"; } - - @RequestMapping(value = "/getFile/",produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) + + @RequestMapping(value = "/getFile/", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) public @ResponseBody byte[] getFile() throws IOException { logger.info("getFile() starts!!"); InputStream in = getClass() @@ -199,8 +196,15 @@ public String getCollectionFileInfo(final Model model, @RequestParam("path") * * } */ - private static String extractFilePath(HttpServletRequest request) { + private String extractFilePath(HttpServletRequest request) throws JargonException { String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE); + try { + path = URLDecoder.decode(path, + this.getIrodsServices().getIrodsAccessObjectFactory().getJargonProperties().getEncoding()); + } catch (UnsupportedEncodingException | JargonException e) { + logger.error("unable to decode path", e); + throw new JargonException(e); + } String bestMatchPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE); AntPathMatcher apm = new AntPathMatcher(); return apm.extractPathWithinPattern(bestMatchPattern, path); diff --git a/src/emc-metalnx-shared/src/main/java/com/emc/metalnx/controller/FileOperationsController.java b/src/emc-metalnx-shared/src/main/java/com/emc/metalnx/controller/FileOperationsController.java index 981fdfce6..3b159c3f6 100755 --- a/src/emc-metalnx-shared/src/main/java/com/emc/metalnx/controller/FileOperationsController.java +++ b/src/emc-metalnx-shared/src/main/java/com/emc/metalnx/controller/FileOperationsController.java @@ -60,6 +60,9 @@ public class FileOperationsController { private static final Logger logger = LoggerFactory.getLogger(FileOperationsController.class); private static String TRASH_PATH; + @Autowired + private BrowseController browseController; + @Autowired private CollectionController collectionController; @@ -115,7 +118,7 @@ public String move(final Model model, @RequestParam("targetPath") final String t model.addAttribute("failedMoves", failedMoves); - return collectionController.getSubDirectories(model, targetPath); + return browseController.getSubDirectories(model, targetPath); } @RequestMapping(value = "/copy", method = RequestMethod.POST) @@ -142,7 +145,7 @@ public String copy(final Model model, @RequestParam("targetPath") final String t model.addAttribute("failedCopies", failedCopies); - return collectionController.getSubDirectories(model, targetPath); + return browseController.getSubDirectories(model, targetPath); } /** @@ -173,14 +176,14 @@ public String deleteReplica(final Model model, @RequestParam("path") final Strin } else { model.addAttribute("delReplReturn", "failure"); } - return collectionController.getFileInfo(model, path); + return browseController.getFileInfo(model, path); } @RequestMapping(value = "/replicate", method = RequestMethod.POST) public String replicate(final Model model, final HttpServletRequest request) throws DataGridConnectionRefusedException { - List sourcePaths = collectionController.getSourcePaths(); + List sourcePaths = browseController.getSourcePaths(); String[] resources = request.getParameterMap().get("resourcesForReplication"); List failedReplicas = new ArrayList<>(); @@ -203,7 +206,7 @@ public String replicate(final Model model, final HttpServletRequest request) sourcePaths.clear(); } - return collectionController.index(model, request, false); + return collectionController.index(model, request); } @RequestMapping(value = "/prepareFilesForDownload/", method = RequestMethod.GET) @@ -262,7 +265,7 @@ public String deleteCollectionAndDataObject(final Model model, @RequestParam("pa fileDeleted = path.substring(path.lastIndexOf("/") + 1, path.length()); } - collectionController.removePathFromHistory(path); + browseController.removePathFromHistory(path); } if (fileDeleted != null) { @@ -270,15 +273,15 @@ public String deleteCollectionAndDataObject(final Model model, @RequestParam("pa } model.addAttribute("failedDeletions", failedDeletions); - model.addAttribute("currentPath", collectionController.getCurrentPath()); - model.addAttribute("parentPath", collectionController.getParentPath()); + model.addAttribute("currentPath", browseController.getCurrentPath()); + model.addAttribute("parentPath", browseController.getParentPath()); - return collectionController.getSubDirectories(model, collectionController.getCurrentPath()); + return browseController.getSubDirectories(model, browseController.getCurrentPath()); } @RequestMapping(value = "emptyTrash/", method = RequestMethod.POST) public ResponseEntity emptyTrash() throws DataGridConnectionRefusedException, JargonException { - String trashForCurrentPath = collectionService.getTrashForPath(collectionController.getCurrentPath()); + String trashForCurrentPath = collectionService.getTrashForPath(browseController.getCurrentPath()); DataGridUser loggedUser = loggedUserUtils.getLoggedDataGridUser(); if (fileOperationService.emptyTrash(loggedUser, trashForCurrentPath)) { return new ResponseEntity<>(HttpStatus.OK); @@ -298,8 +301,8 @@ public ResponseEntity emptyTrash() throws DataGridConnectionRefusedExcep */ @RequestMapping(value = "modify/", method = RequestMethod.GET) public String showModifyForm(final Model model, @RequestParam("path") final String path) throws DataGridException { - String currentPath = collectionController.getCurrentPath(); - String parentPath = collectionController.getParentPath(); + String currentPath = browseController.getCurrentPath(); + String parentPath = browseController.getParentPath(); String formType = "editDataObjectForm"; CollectionOrDataObjectForm targetForm = new CollectionOrDataObjectForm(); diff --git a/src/emc-metalnx-shared/src/main/resources/i18n/messages_en.properties b/src/emc-metalnx-shared/src/main/resources/i18n/messages_en.properties index 5e939d937..9d19999de 100644 --- a/src/emc-metalnx-shared/src/main/resources/i18n/messages_en.properties +++ b/src/emc-metalnx-shared/src/main/resources/i18n/messages_en.properties @@ -18,6 +18,8 @@ text.back=Back text.creation.date=Creation Date text.contains=Contains +text.collections=Collections +text.close=Close text.file.name=File Name text.info=Info text.delete=Delete diff --git a/src/emc-metalnx-shared/src/main/resources/views/collections/collectionManagement.html b/src/emc-metalnx-shared/src/main/resources/views/collections/collectionManagement.html index b09fc74a0..b2696d39c 100755 --- a/src/emc-metalnx-shared/src/main/resources/views/collections/collectionManagement.html +++ b/src/emc-metalnx-shared/src/main/resources/views/collections/collectionManagement.html @@ -37,17 +37,18 @@

  • -
  • Collections
  • +
  • Collections
  • @@ -661,12 +662,12 @@ function getSubDirectories(path) { //alert("getSubDirectories") - console.log("Collection managemnet - getSubDirectories()"); + console.log("Collection management - getSubDirectories()"); $("#table-loader").show(); $("#tree-view-panel-body").hide(); setTimeout(function () { - ajaxEncapsulation("/emc-metalnx-web/collections/getSubDirectories/", "POST", {path: path}, displaySubDirectories, null, null, null); + ajaxEncapsulation("/emc-metalnx-web/browse/getSubDirectories/", "POST", {path: path}, displaySubDirectories, null, null, null); currentPath = path; console.log("currentpath " +currentPath); console.log("path " +path) @@ -686,7 +687,7 @@ var groupName = $("#collectionInfoGroupName").text(); ajaxEncapsulation( - "/emc-metalnx-web/collections/getSubDirectoriesOldTree/", + "/emc-metalnx-web/browse/getSubDirectoriesOldTree/", "POST", {path : directoryPath, groupName : groupName}, function (data){ @@ -946,10 +947,10 @@ $("#table-loader").show(); $("#table-loader").nextAll().remove(); - url = "/emc-metalnx-web/collections/info/"; + url = "/emc-metalnx-web/browse/info/"; ajaxEncapsulation(url, "POST", {path: path}, displayInfoDetails, null, null, null); ajaxEncapsulation( - '/emc-metalnx-web/collections/getBreadCrumbForObject/', + '/emc-metalnx-web/browse/getBreadCrumbForObject/', "POST", {path: path}, function(data){ @@ -964,7 +965,7 @@ } */ function goBackHistory(steps){ ajaxEncapsulation( - '/emc-metalnx-web/collections/goBackHistory/', + '/emc-metalnx-web/browse/goBackHistory/', "POST", {steps: steps}, displaySubDirectories, @@ -973,7 +974,7 @@ } function goForwardHistory(steps){ ajaxEncapsulation( - '/emc-metalnx-web/collections/goForwardHistory/', + '/emc-metalnx-web/browse/goForwardHistory/', "POST", {steps: steps}, displaySubDirectories, diff --git a/src/emc-metalnx-shared/src/main/resources/views/collections/collectionsBreadCrumb.html b/src/emc-metalnx-shared/src/main/resources/views/collections/collectionsBreadCrumb.html index ef367082a..45895bb51 100755 --- a/src/emc-metalnx-shared/src/main/resources/views/collections/collectionsBreadCrumb.html +++ b/src/emc-metalnx-shared/src/main/resources/views/collections/collectionsBreadCrumb.html @@ -21,20 +21,8 @@ Toggle Dropdown diff --git a/src/emc-metalnx-shared/src/main/resources/views/collections/collectionsBrowser.html b/src/emc-metalnx-shared/src/main/resources/views/collections/collectionsBrowser.html index cbf64c430..14c029a30 100755 --- a/src/emc-metalnx-shared/src/main/resources/views/collections/collectionsBrowser.html +++ b/src/emc-metalnx-shared/src/main/resources/views/collections/collectionsBrowser.html @@ -264,7 +264,7 @@
    - +
    @@ -290,7 +290,7 @@ - + @@ -395,7 +395,7 @@
    data.search.search = ""; }, "ajax": { - url: '/emc-metalnx-web/collections/getPaginatedJSONObjs/', + url: '/emc-metalnx-web/browse/getPaginatedJSONObjs/', data: {'rulesdeployment': true} }, "initComplete": function(settings){ diff --git a/src/emc-metalnx-web/src/main/resources/log4j.properties b/src/emc-metalnx-web/src/main/resources/log4j.properties index 1661b6e45..9bb369ef1 100644 --- a/src/emc-metalnx-web/src/main/resources/log4j.properties +++ b/src/emc-metalnx-web/src/main/resources/log4j.properties @@ -26,7 +26,7 @@ log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1 # Third Party frameworks log4j.logger.org.springframework=WARN log4j.logger.org.thymeleaf=INFO -log4j.logger.org.irods=DEBUG +log4j.logger.org.irods=WARN # logs the SQL statements - set DEBUG for detailed info log4j.logger.org.hibernate.SQL=ERROR diff --git a/src/emc-metalnx-web/src/main/webapp/WEB-INF/applicationContext.xml b/src/emc-metalnx-web/src/main/webapp/WEB-INF/applicationContext.xml index 004afcff1..4acf6a1b0 100755 --- a/src/emc-metalnx-web/src/main/webapp/WEB-INF/applicationContext.xml +++ b/src/emc-metalnx-web/src/main/webapp/WEB-INF/applicationContext.xml @@ -82,6 +82,8 @@ It allows theming and custom messages --> + + From 16d176e5a26c67f5b4a18463325c96bd791dd3fd Mon Sep 17 00:00:00 2001 From: Mike Conway Date: Fri, 26 Jan 2018 13:50:16 -0500 Subject: [PATCH 2/7] #63 new and upload tested --- .../metalnx/controller/BrowseController.java | 22 +++++++--- .../metalnx/modelattribute/enums/URLMap.java | 14 +++--- .../collections/collectionsBreadCrumb.html | 43 ++----------------- .../views/collections/collectionsBrowser.html | 2 +- 4 files changed, 27 insertions(+), 54 deletions(-) diff --git a/src/emc-metalnx-shared/src/main/java/com/emc/metalnx/controller/BrowseController.java b/src/emc-metalnx-shared/src/main/java/com/emc/metalnx/controller/BrowseController.java index a872d2f5d..d3cc5faf7 100644 --- a/src/emc-metalnx-shared/src/main/java/com/emc/metalnx/controller/BrowseController.java +++ b/src/emc-metalnx-shared/src/main/java/com/emc/metalnx/controller/BrowseController.java @@ -162,7 +162,7 @@ public class BrowseController { // saves the trash under the zone private String zoneTrashPath = ""; - private static final Logger logger = LoggerFactory.getLogger(CollectionController.class); + private static final Logger logger = LoggerFactory.getLogger(BrowseController.class); @PostConstruct public void init() throws DataGridException { @@ -570,12 +570,19 @@ public String listCollectionsAndDataObjects(final Model model, @PathVariable fin * template, otherwise. * @throws DataGridConnectionRefusedException */ - @RequestMapping(value = "add/action/", method = RequestMethod.POST) + @RequestMapping(value = "add/action", method = RequestMethod.POST) public String addCollection(final Model model, @ModelAttribute final CollectionOrDataObjectForm collection, final RedirectAttributes redirectAttributes) throws DataGridConnectionRefusedException { + + logger.info("addCollection()"); + logger.info("collection:{}", collection); + logger.info("redirectAttributes:{}", redirectAttributes); + DataGridCollectionAndDataObject newCollection = new DataGridCollectionAndDataObject( currentPath + '/' + collection.getCollectionName(), collection.getCollectionName(), currentPath, true); + logger.info("newCollection:{}", newCollection); + newCollection.setParentPath(currentPath); newCollection.setCreatedAt(new Date()); newCollection.setModifiedAt(newCollection.getCreatedAt()); @@ -584,6 +591,7 @@ public String addCollection(final Model model, @ModelAttribute final CollectionO boolean creationSucessful; try { creationSucessful = cs.createCollection(newCollection); + logger.info("creationSuccessful?:{}", creationSucessful); if (creationSucessful) { redirectAttributes.addFlashAttribute("collectionAddedSuccessfully", collection.getCollectionName()); @@ -595,7 +603,7 @@ public String addCollection(final Model model, @ModelAttribute final CollectionO redirectAttributes.addFlashAttribute("missingPermissionError", true); } - return "redirect:/collections/"; + return "redirect:/collections" + currentPath; } /** @@ -623,7 +631,7 @@ public String modifyAction(@ModelAttribute final CollectionOrDataObjectForm coll redirectAttributes.addFlashAttribute("collectionModifiedSuccessfully", collForm.getCollectionName()); } - return "redirect:/collections/"; + return "redirect:/collections" + parentPath; } @RequestMapping(value = "applyTemplatesToCollections/", method = RequestMethod.POST) @@ -680,7 +688,7 @@ public String homeCollection(final Model model) throws DataGridException { sourcePaths.clear(); currentPath = cs.getHomeDirectyForCurrentUser(); parentPath = currentPath; - return "redirect:/collections/"; + return "redirect:/collections" + currentPath; } /** @@ -703,7 +711,7 @@ public String publicCollection(final Model model) throws DataGridException { model.addAttribute("homePath", cs.getHomeDirectyForCurrentUser()); model.addAttribute("resources", resourceService.findAll()); - return "collections/collectionManagement"; + return "collections" + currentPath; } /** @@ -731,7 +739,7 @@ public String trashCollection(final Model model) throws DataGridException { model.addAttribute("homePath", cs.getHomeDirectyForCurrentUser()); model.addAttribute("resources", resourceService.findAll()); - return "collections/collectionManagement"; + return "collections" + currentPath; } @RequestMapping(value = "/getBreadCrumbForObject/") diff --git a/src/emc-metalnx-shared/src/main/java/com/emc/metalnx/modelattribute/enums/URLMap.java b/src/emc-metalnx-shared/src/main/java/com/emc/metalnx/modelattribute/enums/URLMap.java index 352fbd75c..6c45afe47 100755 --- a/src/emc-metalnx-shared/src/main/java/com/emc/metalnx/modelattribute/enums/URLMap.java +++ b/src/emc-metalnx-shared/src/main/java/com/emc/metalnx/modelattribute/enums/URLMap.java @@ -51,10 +51,10 @@ public class URLMap { public static final String URL_COLLECTIONS_INFO = "/info/"; public static final String URL_COLLECTIONS_MANAGEMENT = "/collections/"; - public static final String URL_ADD_COLLECTION = "/emc-metalnx-web/collections/add/"; + public static final String URL_ADD_COLLECTION = "/emc-metalnx-web/browse/add/"; public static final String URL_MODIFY_COLLECTION = "/emc-metalnx-web/fileOperation/modify/"; public static final String URL_DELETE_COLLECTION = "/emc-metalnx-web/fileOperation/delete/"; - public static final String URL_COLLECTION_VALIDATE_NAME = "/emc-metalnx-web/collections/isValidCollectionName/"; + public static final String URL_COLLECTION_VALIDATE_NAME = "/emc-metalnx-web/browse/isValidCollectionName/"; public static final String URL_METADATA_SEARCH = "/metadata/"; @@ -85,13 +85,13 @@ public class URLMap { public static final String URL_DELETE_SPECIFIC_QUERY = "/emc-metalnx-web/specificqueries/remove/"; public static final String URL_SPECIFIC_QUERY_VALIDATE = "/emc-metalnx-web/specificqueries/validate/"; - public static final String URL_HOME_COLLECTION_USER = "/collections/home/"; - public static final String URL_PUBLIC_COLLECTION_USER = "/collections/public/"; - public static final String URL_TRASH_COLLECTION_USER = "/collections/trash/"; - public static final String URL_ADD_COLLECTION_USER = "/emc-metalnx-web/collections/add/"; + public static final String URL_HOME_COLLECTION_USER = "/browse/home"; + public static final String URL_PUBLIC_COLLECTION_USER = "/browse/public/"; + public static final String URL_TRASH_COLLECTION_USER = "/browse/trash/"; + public static final String URL_ADD_COLLECTION_USER = "/emc-metalnx-web/browse/add/"; public static final String URL_MODIFY_COLLECTION_USER = "/emc-metalnx-web/fileOperation/modify/"; public static final String URL_DELETE_COLLECTION_USER = "/fileOperation/delete/"; - public static final String URL_COLLECTION_VALIDATE_NAME_USER = "/emc-metalnx-web/collections/isValidCollectionName/"; + public static final String URL_COLLECTION_VALIDATE_NAME_USER = "/emc-metalnx-web/browse/isValidCollectionName/"; public static final String URL_LOGOUT = "/logout/"; public static final String URL_TICKETS = "/tickets/"; diff --git a/src/emc-metalnx-shared/src/main/resources/views/collections/collectionsBreadCrumb.html b/src/emc-metalnx-shared/src/main/resources/views/collections/collectionsBreadCrumb.html index 45895bb51..ca6ebe6fe 100755 --- a/src/emc-metalnx-shared/src/main/resources/views/collections/collectionsBreadCrumb.html +++ b/src/emc-metalnx-shared/src/main/resources/views/collections/collectionsBreadCrumb.html @@ -38,7 +38,7 @@ @@ -58,7 +58,7 @@ @@ -66,7 +66,7 @@ @@ -98,42 +98,7 @@
    - - - - - + From 031c99a279faac9e0c2871fc920bfa74763f4ace Mon Sep 17 00:00:00 2001 From: Mike Conway Date: Mon, 29 Jan 2018 07:12:45 -0500 Subject: [PATCH 4/7] #65 wip --- .../src/main/webapp/WEB-INF/applicationContext.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/emc-metalnx-web/src/main/webapp/WEB-INF/applicationContext.xml b/src/emc-metalnx-web/src/main/webapp/WEB-INF/applicationContext.xml index 39306825d..c55f014f0 100755 --- a/src/emc-metalnx-web/src/main/webapp/WEB-INF/applicationContext.xml +++ b/src/emc-metalnx-web/src/main/webapp/WEB-INF/applicationContext.xml @@ -31,8 +31,8 @@ - - file:///C:/Users/hetalben/opt/etc/irods-ext/metalnx.properties + file:/etc/irods-ext/metalnx.properties + @@ -41,8 +41,8 @@ - - + + From 816c1b301a15b344f29cd7a5068627624632fbf5 Mon Sep 17 00:00:00 2001 From: Mike Conway Date: Mon, 29 Jan 2018 09:36:09 -0500 Subject: [PATCH 5/7] #65 tweaking move/copy --- .../collections/collectionManagement.html | 118 +++++++++++------- .../views/collections/collectionsBrowser.html | 7 +- .../collectionManagementOldTree.html | 6 +- .../views/collections/oldTreeView.html | 4 +- .../collections/treeViewForGroupForm.html | 6 +- .../collections/treeViewForUserForm.html | 6 +- 6 files changed, 82 insertions(+), 65 deletions(-) diff --git a/src/emc-metalnx-shared/src/main/resources/views/collections/collectionManagement.html b/src/emc-metalnx-shared/src/main/resources/views/collections/collectionManagement.html index b2696d39c..1cd0a9e47 100755 --- a/src/emc-metalnx-shared/src/main/resources/views/collections/collectionManagement.html +++ b/src/emc-metalnx-shared/src/main/resources/views/collections/collectionManagement.html @@ -223,7 +223,7 @@

    - @@ -233,7 +233,7 @@

    - Public @@ -324,7 +324,7 @@

    - iRods @@ -333,7 +333,7 @@

    - @@ -343,7 +343,7 @@

    - Public @@ -723,13 +723,13 @@

    } function showModifyForm() { - var cbChecked = $('input[name="collectionPathCheckboxes"]:checked').length; - - if (cbChecked > 1) return; - - var url = [[ ${ urlMap.URL_MODIFY_COLLECTION_USER } ]]; - var path = $('input[name="collectionPathCheckboxes"]:checked').val(); - ajaxEncapsulation(url, "GET", {path: path}, displayModifyForm, null, null, null); + var cbChecked = $('input[name="collectionPathCheckboxes"]:checked').length; + + if (cbChecked > 1) return; + + var url = [[ ${ urlMap.URL_MODIFY_COLLECTION_USER } ]]; + var path = $('input[name="collectionPathCheckboxes"]:checked').val(); + ajaxEncapsulation(url, "GET", {path: path}, displayModifyForm, null, null, null); } function submitForm() { @@ -737,29 +737,46 @@ $(".registerForm").submit(); } } + + function callbackMoveAndCopyError(path){ + $("#moveModal").modal("hide"); + + //reset the modal + cleanModals(); + + //updating the list of files and collections + currentPath = path; + + positionBrowserToPath(path); + + //xs$("#tree-view-panel-body").html(data); + } + function callbackMoveAndCopy(data){ $("#moveModal").modal("hide"); //reset the modal - cleanModals(); + cleanModals(); //updating the list of files and collections currentPath = targetPath; totalCheckboxesChecked = 0; - resetDataTablesStart(); + //resetDataTablesStart(); + + positionBrowserToPath(targetPath); $("#tree-view-panel-body").html(data); } function updateResourceForReplicationOptions() { - $("#selectResource > option").remove(); - $("#selectResourceToUpload > option").each(function() { - if(!$(this).is(":selected")) { - $("#selectResource").append($(this).clone()); - } - }); + $("#selectResource > option").remove(); + $("#selectResourceToUpload > option").each(function() { + if(!$(this).is(":selected")) { + $("#selectResource").append($(this).clone()); + } + }); } $("#moveBtn").click(function() { @@ -839,34 +856,41 @@ return paths; } + + /** + * position the collection browser to the new path + */ + function positionBrowserToPath(path) { + window.location.href = '/emc-metalnx-web/collections' + path; //relative to domain + } function deleteAction(){ - setOperationInProgress(); - $("#actions button").prop("disabled", true); - $('#actionsWait').show(); - $('#actionLabel').html([[#{collections.empty.trash.status}]]); - $("#uploadIcon").prop("disabled", true); - $("#uploadIcon").addClass("disabled"); - $("#showCollectionFormBtn").prop("disabled", true); - $("#showCollectionFormBtn").addClass("disabled"); - - var paths = findPathsSelected(); - var url = "/emc-metalnx-web/fileOperation/delete/"; - - ajaxEncapsulation( - url, - "POST", - {paths: paths}, - function (data) { - unsetOperationInProgress(); - resetDataTablesStart(); - $("#tree-view-panel-body").html(data); - - } - ); - - $("#deleteModal").modal("hide"); - cleanModals(); + setOperationInProgress(); + $("#actions button").prop("disabled", true); + $('#actionsWait').show(); + $('#actionLabel').html([[#{collections.empty.trash.status}]]); + $("#uploadIcon").prop("disabled", true); + $("#uploadIcon").addClass("disabled"); + $("#showCollectionFormBtn").prop("disabled", true); + $("#showCollectionFormBtn").addClass("disabled"); + + var paths = findPathsSelected(); + var url = "/emc-metalnx-web/fileOperation/delete/"; + + ajaxEncapsulation( + url, + "POST", + {paths: paths}, + function (data) { + unsetOperationInProgress(); + resetDataTablesStart(); + $("#tree-view-panel-body").html(data); + + } + ); + + $("#deleteModal").modal("hide"); + cleanModals(); } $('.modal').on('hidden.bs.modal', function(e){ @@ -987,7 +1011,7 @@ $('.targetPathInfoSpan').html(targetPath); } - //this function below only wqorks with favorites and user bookmarks table because they have the same number of columns + //this function below only works with favorites and user bookmarks table because they have the same number of columns function modalMoveCopyFavAndUserbookmarkDatatable(datatableId, datatableVar, urlService){ datatableVar = $('#'+datatableId).DataTable( { "serverSide": true, diff --git a/src/emc-metalnx-shared/src/main/resources/views/collections/collectionsBrowser.html b/src/emc-metalnx-shared/src/main/resources/views/collections/collectionsBrowser.html index 2e6291ca9..c518ca2ce 100755 --- a/src/emc-metalnx-shared/src/main/resources/views/collections/collectionsBrowser.html +++ b/src/emc-metalnx-shared/src/main/resources/views/collections/collectionsBrowser.html @@ -551,12 +551,7 @@

    - - iRods + /

    diff --git a/src/emc-metalnx-ui-admin/src/main/resources/views/collections/oldTreeView.html b/src/emc-metalnx-ui-admin/src/main/resources/views/collections/oldTreeView.html index 8bfe5c429..d6846c975 100755 --- a/src/emc-metalnx-ui-admin/src/main/resources/views/collections/oldTreeView.html +++ b/src/emc-metalnx-ui-admin/src/main/resources/views/collections/oldTreeView.html @@ -21,7 +21,7 @@
  • - @@ -29,9 +29,7 @@ - -

  • diff --git a/src/emc-metalnx-ui-admin/src/main/resources/views/collections/treeViewForGroupForm.html b/src/emc-metalnx-ui-admin/src/main/resources/views/collections/treeViewForGroupForm.html index 292616c4c..c40410bd9 100755 --- a/src/emc-metalnx-ui-admin/src/main/resources/views/collections/treeViewForGroupForm.html +++ b/src/emc-metalnx-ui-admin/src/main/resources/views/collections/treeViewForGroupForm.html @@ -39,12 +39,12 @@