Example #1
0
 /**
  * Get the container which security callback affects this item. This searches up the path of
  * parents to see wether it can find any container with a callback. If no callback can be found,
  * null is returned.
  *
  * @param vfsItem
  * @return
  */
 public static VFSContainer findInheritingSecurityCallbackContainer(VFSItem vfsItem) {
   if (vfsItem == null) return null;
   // first resolve delegates of any NamedContainers to get the actual container (might be a
   // MergeSource)
   if (vfsItem instanceof NamedContainerImpl)
     return findInheritingSecurityCallbackContainer(((NamedContainerImpl) vfsItem).getDelegate());
   // special treatment for MergeSource
   if (vfsItem instanceof MergeSource) {
     MergeSource mergeSource = (MergeSource) vfsItem;
     VFSContainer rootWriteContainer = mergeSource.getRootWriteContainer();
     if (rootWriteContainer != null && rootWriteContainer.getLocalSecurityCallback() != null) {
       // if the root write container has a security callback set, it will always override
       // any local securitycallback set on the mergesource
       return rootWriteContainer;
     } else if (mergeSource.getLocalSecurityCallback() != null) {
       return mergeSource;
     } else if (mergeSource.getParentContainer() != null) {
       return findInheritingSecurityCallbackContainer(mergeSource.getParentContainer());
     }
   } else {
     if ((vfsItem instanceof VFSContainer) && (vfsItem.getLocalSecurityCallback() != null))
       return (VFSContainer) vfsItem;
     if (vfsItem.getParentContainer() != null)
       return findInheritingSecurityCallbackContainer(vfsItem.getParentContainer());
   }
   return null;
 }
Example #2
0
 /**
  * Check if the file exist or not
  *
  * @param item
  * @return
  */
 public static boolean exists(VFSItem item) {
   if (item instanceof NamedContainerImpl) {
     item = ((NamedContainerImpl) item).getDelegate();
   }
   if (item instanceof MergeSource) {
     MergeSource source = (MergeSource) item;
     item = source.getRootWriteContainer();
     if (item == null) {
       // no write container, but the virtual container exist
       return true;
     }
   }
   if (item instanceof LocalImpl) {
     LocalImpl localFile = (LocalImpl) item;
     return localFile.getBasefile() != null && localFile.getBasefile().exists();
   }
   return false;
 }
Example #3
0
  private static ContainerAndFile findWritableRootFolderForRecursion(
      VFSContainer rootDir, String relFilePath, int recursionLevel) {
    recursionLevel++;
    if (recursionLevel > 20) {
      // Emergency exit condition: a directory hierarchy that has more than 20
      // levels? Probably not..
      log.warn(
          "Reached recursion level while finding writable root Folder - most likely a bug. rootDir::"
              + rootDir
              + " relFilePath::"
              + relFilePath);
      return null;
    }

    if (rootDir instanceof NamedContainerImpl) {
      rootDir = ((NamedContainerImpl) rootDir).getDelegate();
    }
    if (rootDir instanceof MergeSource) {
      MergeSource mergedDir = (MergeSource) rootDir;
      // first check if the next level is not a second MergeSource
      int stop = relFilePath.indexOf("/", 1);
      if (stop > 0) {
        String nextLevel = extractChild(relFilePath);
        VFSItem item = mergedDir.resolve(nextLevel);
        if (item instanceof NamedContainerImpl) {
          item = ((NamedContainerImpl) item).getDelegate();
        }
        if (item instanceof MergeSource) {
          rootDir = (MergeSource) item;
          relFilePath = relFilePath.substring(stop);
          return findWritableRootFolderForRecursion(rootDir, relFilePath, recursionLevel);
        }
      }

      VFSContainer rootWriteContainer = mergedDir.getRootWriteContainer();
      if (rootWriteContainer == null) {
        // we have a merge source without a write container, try it one higher,
        // go through all children of this one and search the correct child in
        // the path
        List<VFSItem> children = rootDir.getItems();
        if (children.isEmpty()) {
          // ups, a merge source without children, no good, return null
          return null;
        }

        String nextChildName = relFilePath.substring(1, relFilePath.indexOf("/", 1));
        for (VFSItem child : children) {
          // look up for the next child in the path
          if (child.getName().equals(nextChildName)) {
            // use this child as new root and remove the child name from the rel
            // path
            if (child instanceof VFSContainer) {
              rootDir = (VFSContainer) child;
              relFilePath = relFilePath.substring(relFilePath.indexOf("/", 1));
              break;
            } else {
              // ups, a merge source with a child that is not a VFSContainer -
              // no good, return null
              return null;
            }
          }
        }
      } else {
        // ok, we found a merge source with a write container
        rootDir = rootWriteContainer;
      }
    }
    if (rootDir != null && rootDir instanceof LocalFolderImpl) {
      // finished, we found a local folder we can use to write
      return new ContainerAndFile(rootDir, relFilePath);
    } else {
      // do recursion
      return findWritableRootFolderForRecursion(rootDir, relFilePath, recursionLevel);
    }
  }
Example #4
0
  /**
   * Get the path as string of the given item relative to the root container and the relative base
   * path
   *
   * @param item the item for which the relative path should be returned
   * @param rootContainer The root container for which the relative path should be calculated
   * @param relativeBasePath when NULL, the path will be calculated relative to the rootContainer;
   *     when NOT NULL, the relativeBasePath must represent a relative path within the root
   *     container that serves as the base. In this case, the calculated relative item path will
   *     start from this relativeBasePath
   * @return
   */
  public static String getRelativeItemPath(
      VFSItem item, VFSContainer rootContainer, String relativeBasePath) {
    // 1) Create path absolute to the root container
    if (item == null) return null;
    String absPath = "";
    VFSItem tmpItem = item;
    // Check for merged containers to fix problems with named containers, see OLAT-3848
    List<NamedContainerImpl> namedRootChilds = new ArrayList<NamedContainerImpl>();
    for (VFSItem rootItem : rootContainer.getItems()) {
      if (rootItem instanceof NamedContainerImpl) {
        namedRootChilds.add((NamedContainerImpl) rootItem);
      }
    }
    // Check if root container is the same as the item and vice versa. It is
    // necessary to perform the check on both containers to catch all potential
    // cases with MergedSource and NamedContainer where the check in one
    // direction is not necessarily the same as the opposite check
    while (tmpItem != null && !rootContainer.isSame(tmpItem) && !tmpItem.isSame(rootContainer)) {
      String itemFileName = tmpItem.getName();
      // fxdiff FXOLAT-125: virtual file system for CP
      if (tmpItem instanceof NamedLeaf) {
        itemFileName = ((NamedLeaf) tmpItem).getDelegate().getName();
      }

      // Special case: check if this is a named container, see OLAT-3848
      for (NamedContainerImpl namedRootChild : namedRootChilds) {
        if (namedRootChild.isSame(tmpItem)) {
          itemFileName = namedRootChild.getName();
        }
      }
      absPath = "/" + itemFileName + absPath;
      tmpItem = tmpItem.getParentContainer();
      if (tmpItem != null) {
        // test if this this is a merge source child container, see OLAT-5726
        VFSContainer grandParent = tmpItem.getParentContainer();
        if (grandParent instanceof MergeSource) {
          MergeSource mergeGrandParent = (MergeSource) grandParent;
          if (mergeGrandParent.isContainersChild((VFSContainer) tmpItem)) {
            // skip this parent container and use the merge grand-parent
            // instead, otherwise path contains the container twice
            tmpItem = mergeGrandParent;
          }
        }
      }
    }

    if (relativeBasePath == null) {
      return absPath;
    }
    // 2) Compute rel path to base dir of the current file

    // selpath = /a/irwas/subsub/nochsub/note.html 5
    // filenam = /a/irwas/index.html 3
    // --> subsub/nochsub/note.gif

    // or /a/irwas/bla/index.html
    // to /a/other/b/gugus.gif
    // --> ../../ other/b/gugus.gif

    // or /a/other/b/main.html
    // to /a/irwas/bla/goto.html
    // --> ../../ other/b/gugus.gif

    String base = relativeBasePath; // assume "/" is here
    if (!(base.indexOf("/") == 0)) {
      base = "/" + base;
    }

    String[] baseA = base.split("/");
    String[] targetA = absPath.split("/");
    int sp = 1;
    for (; sp < Math.min(baseA.length, targetA.length); sp++) {
      if (!baseA[sp].equals(targetA[sp])) {
        break;
      }
    }
    // special case: self-reference
    if (absPath.equals(base)) {
      sp = 1;
    }
    StringBuilder buffer = new StringBuilder();
    for (int i = sp; i < baseA.length - 1; i++) {
      buffer.append("../");
    }
    for (int i = sp; i < targetA.length; i++) {
      buffer.append(targetA[i] + "/");
    }
    buffer.deleteCharAt(buffer.length() - 1);
    String path = buffer.toString();

    String trimmed = path; // selectedPath.substring(1);
    return trimmed;
  }