/** * This file is part of Waarp Project. * * Copyright 2009, Frederic Bregier, and individual contributors by the @author tags. See the * COPYRIGHT.txt in the distribution for a full listing of individual contributors. * * All Waarp Project is free software: you can redistribute it and/or modify it under the terms of * the GNU General Public License as published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * Waarp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. * * You should have received a copy of the GNU General Public License along with Waarp . If not, see * <http://www.gnu.org/licenses/>. */ package org.waarp.openr66.context.filesystem; import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.waarp.common.command.exception.CommandAbstractException; import org.waarp.common.command.exception.Reply550Exception; import org.waarp.common.command.exception.Reply553Exception; import org.waarp.common.file.filesystembased.FilesystemBasedDirImpl; import org.waarp.common.file.filesystembased.FilesystemBasedOptsMLSxImpl; import org.waarp.common.file.filesystembased.specific.FilesystemBasedCommonsIo; import org.waarp.common.file.filesystembased.specific.FilesystemBasedDirJdkAbstract; import org.waarp.openr66.context.R66Session; import org.waarp.openr66.context.authentication.R66Auth; import org.waarp.openr66.protocol.configuration.Configuration; /** * Directory representation * * @author frederic bregier * */ public class R66Dir extends FilesystemBasedDirImpl { /** * @param session */ public R66Dir(R66Session session) { super(session, new FilesystemBasedOptsMLSxImpl()); } public R66File newFile(String path, boolean append) throws CommandAbstractException { return new R66File((R66Session) getSession(), this, path, append); } /** * Same as setUnique() except that File will be prefixed by id and postfixed by filename * * @param prefix * @param filename * @return the R66File with a unique filename and a temporary extension * @throws CommandAbstractException */ public synchronized R66File setUniqueFile(long prefix, String filename) throws CommandAbstractException { checkIdentify(); File file = null; String prename = prefix + "_"; if (prename.length() < 3) { prename = "xx_" + prename; } String basename = R66File.getBasename(filename); if (basename.length() > Configuration.configuration.getMaxfilenamelength() - 55) { basename = basename.substring(basename.length() - Configuration.configuration.getMaxfilenamelength() + 55); } try { file = File.createTempFile(prename, "_" + basename + Configuration.EXT_R66, getFileFromPath(currentDir)); } catch (IOException e) { throw new Reply550Exception("Cannot create unique file from " + basename); } String currentFile = getRelativePath(file); return newFile(normalizePath(currentFile), false); } /** * * @param file * @return the final unique basename without the temporary extension */ public static String getFinalUniqueFilename(R66File file) { String finalpath = file.getBasename(); int pos = finalpath.lastIndexOf(Configuration.EXT_R66); if (pos > 0) { finalpath = finalpath.substring(0, pos); } return finalpath; } /** * Finds all files matching a wildcard expression (based on '?', '~' or '*') but without * checking BusinessPath, thus returning absolute path. * * @param pathWithWildcard * The wildcard expression with a business path. * @return List of String as relative paths matching the wildcard expression. Those files are * tested as valid from business point of view. If Wildcard support is not active, if * the path contains any wildcards, it will throw an error. * @throws CommandAbstractException */ protected List<String> wildcardFilesNoCheck(String pathWithWildcard) throws CommandAbstractException { List<String> resultPaths = new ArrayList<String>(); // First check if pathWithWildcard contains wildcards if (!(pathWithWildcard.contains("*") || pathWithWildcard.contains("?") || pathWithWildcard .contains("~"))) { // No so simply return the list containing this path resultPaths.add(pathWithWildcard); return resultPaths; } // Do we support Wildcard path if (!FilesystemBasedDirJdkAbstract.ueApacheCommonsIo) { throw new Reply553Exception("Wildcards in pathname is not allowed"); } File wildcardFile = new File(pathWithWildcard); File rootFile; if (ISUNIX) { rootFile = new File("/"); } else { rootFile = getCorrespondingRoot(wildcardFile); } // Split wildcard path into subdirectories. List<String> subdirs = new ArrayList<String>(); while (wildcardFile != null) { File parent = wildcardFile.getParentFile(); if (parent == null) { subdirs.add(0, wildcardFile.getPath()); break; } subdirs.add(0, wildcardFile.getName()); if (parent.equals(rootFile)) { // End of wildcard path subdirs.add(0, parent.getPath()); break; } wildcardFile = parent; } List<File> basedPaths = new ArrayList<File>(); // First set root basedPaths.add(new File(subdirs.get(0))); int i = 1; // For each wilcard subdirectory while (i < subdirs.size()) { // Set current filter FileFilter fileFilter = FilesystemBasedCommonsIo .getWildcardFileFilter(subdirs.get(i)); List<File> newBasedPaths = new ArrayList<File>(); // Look for matches in all the current search paths for (File dir : basedPaths) { if (dir.isDirectory()) { for (File match : dir.listFiles(fileFilter)) { newBasedPaths.add(match); } } } // base Search Path changes now basedPaths = newBasedPaths; i++; } // Valid each file first for (File file : basedPaths) { resultPaths.add(file.getAbsolutePath()); } return resultPaths; } /** * Create a new file according to the path without checking BusinessPath, so as external File. * * @param path * @return the File created * @throws CommandAbstractException */ public R66File setFileNoCheck(String path) throws CommandAbstractException { checkIdentify(); String newpath = consolidatePath(path); List<String> paths = wildcardFilesNoCheck(newpath); if (paths.size() != 1) { throw new Reply550Exception("File not found from: " + newpath + " and " + paths.size() + " founds"); } String extDir = paths.get(0); return new R66File((R66Session) getSession(), this, extDir); } /** * This method returns the Full path for the current directory * * @return the full path associated with the current Dir */ public String getFullPath() { if (session.getAuth() == null) { return currentDir; } if (isAbsolute(currentDir)) { return currentDir; } return ((R66Auth) session.getAuth()).getAbsolutePath(currentDir); } @Override public String toString() { return "Dir: " + currentDir; } }