/* * PathUtils.java * */ package org.smartly.commons.util; import org.smartly.IConstants; import org.smartly.Smartly; import org.smartly.commons.lang.CharEncoding; import java.io.File; import java.net.URLEncoder; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; /** * Contains utility for path management. * Depends on StringUtils. * * @author */ public abstract class PathUtils implements IConstants { /** * Array of file system types. i.e. ["http://", "ftp://", ...] * */ public static final String[] FILESYSTEM_TYPES = SystemUtils.FileType.getValues(); private static final boolean IS_WINDOWS = SystemUtils.isWindows(); private static final String TEMP = "/temp"; /** * Returns temp folder. * * @return temp folder name for current user */ public static String getTemporaryDirectory() { final String temp = concat(IConstants.USER_HOME, TEMP); try { FileUtils.mkdirs(temp); } catch (Throwable ignored) { } return temp; } /** * Returns a temp folder * * @param subFolder Sub folder * @return Temp folder name for current user */ public static String getTemporaryDirectory(final String subFolder) { final String temp = concat(getTemporaryDirectory(), subFolder); try { FileUtils.mkdirs(temp); } catch (Throwable ignored) { } return temp; } /** * Extract parent Path from file name. i.e. "c:/mydir/filename.txt" returns * "c:/mydir/". * * @param path File path. i.e. "c:/mydir/filename.txt" * @return Parent path. i.e. "c:/mydir/" */ public static String getParent(final String path) { try { final int separatorIndex = path.lastIndexOf(FOLDER_SEPARATOR); final String result; if (separatorIndex == -1) { result = ""; } else if (separatorIndex == 0) { result = FOLDER_SEPARATOR; } else { result = path.substring(0, separatorIndex); } return result; //final File file = new File(clean); //return file.getParent(); } catch (Throwable ignored) { } return path; } /** * Extract the filename from the given path, * e.g. "mypath/myfile.txt" -> "myfile.txt". * * @param path the file path (may be <code>null</code>) * @return the extracted filename, or <code>null</code> if none */ public static String getFilename(final String path) { return getFilename(path, true); } /** * Extract the filename from the given path. * If "includeextension" is true the returned value will include * file extension (i.e. "myfile.txt"), otherwise file name extension * is stripped (i.e. "myfile"). * * @param path * @param includeextension * @return */ public static String getFilename(final String path, final boolean includeextension) { if (path == null) { return null; } final int separatorIndex = path.lastIndexOf(FOLDER_SEPARATOR); final String filename = separatorIndex != -1 ? path.substring(separatorIndex + 1) : path; if (!includeextension) { return stripFilenameExtension(filename); } else { return filename; } } /** * Extract the filename extension from the given path, * e.g. "mypath/myfile.txt" -> "txt". * * @param path the file path (may be <code>null</code>) * @return the extracted filename extension, or <code>null</code> if none */ public static String getFilenameExtension(final String path) { return getFilenameExtension(path, false); } /** * Extract the filename extension from the given path, * e.g. "mypath/myfile.txt" -> "txt". * * @param path the file path (may be <code>null</code>) * @param includeDot if true result is ".ext", else "ext" * @return the extracted filename extension, or <code>null</code> if none */ public static String getFilenameExtension(final String path, boolean includeDot) { if (path == null) { return null; } final int sepIndex = path.lastIndexOf(FOLDER_SEPARATOR); final int dotIndex = path.lastIndexOf(EXTENSION_SEPARATOR); if (sepIndex > -1 && dotIndex < sepIndex) { return null; } if (includeDot) { return (dotIndex != -1 ? path.substring(dotIndex) : null); } else { return (dotIndex != -1 ? path.substring(dotIndex + 1) : null); } } /** * Return true if path has an extension. * * @param path * @return */ public static boolean isFile(final String path) { try { final String ext = PathUtils.getFilenameExtension(path); if (StringUtils.hasText(ext)) { return true; } else { final File file = new File(path); return file.isFile() || !file.isDirectory(); } } catch (Throwable ignored) { } return false; } /** * Return false is path has an extension or if it's not a directory. * * @param path * @return */ public static boolean isDirectory(final String path) { final String ext = PathUtils.getFilenameExtension(path); if (StringUtils.hasText(ext)) { return false; } else { final File file = new File(path); return file.isDirectory(); } } /** * Strip the filename extension from the given path, * e.g. "mypath/myfile.txt" -> "mypath/myfile". * * @param path the file path (may be <code>null</code>) * @return the path with stripped filename extension, * or <code>null</code> if none */ public static String stripFilenameExtension(final String path) { if (path == null) { return null; } int sepIndex = path.lastIndexOf(EXTENSION_SEPARATOR); return (sepIndex != -1 ? path.substring(0, sepIndex) : path); } public static String changeFileExtension(final String path, String extension) { final String filename = stripFilenameExtension(path); if (!extension.startsWith(".")) { extension = "." + extension; } return filename.concat(extension); } public static String changeFileName(final String path, final String newName) { final String parent = PathUtils.getParent(path); return PathUtils.join(parent, newName); } public static String suggestFileName(final String fileName) { return PathUtils.suggestFileName(fileName, true); } public static String suggestFileName(final String fileName, final boolean preserveExtension) { final File file = new File(fileName); if (file.exists()) { final String name = stripFilenameExtension(file.getName()); final String path = file.getParent(); String ext = preserveExtension ? PathUtils.getFilenameExtension(fileName) : ""; // txt if (StringUtils.hasText(ext)) { ext = ".".concat(ext); } else { ext = ""; } Integer i = 1; while (true) { final String tmpName; if (StringUtils.hasText(path)) { tmpName = path.concat(FOLDER_SEPARATOR).concat(name).concat("_").concat(i.toString()).concat(ext); } else { tmpName = name.concat("_").concat(i.toString()).concat(ext); } final File tmpFile = new File(tmpName); if (!tmpFile.exists()) { return tmpFile.getAbsolutePath(); } i++; } } else { return fileName; } } /** * Return true if path's extension start with passed parameter. * This is case insentive. * * @param path File path. i.e. : "c:/file.txt" * @param extension Extension. i.e.: ".txt", "txt", ... * @return True if path's extension start with passed extension. */ public static boolean extensionStartWith(final String path, final String extension) { if (!StringUtils.hasText(extension) || !StringUtils.hasText(path)) { return false; } final String curext = getFilenameExtension(path); if (!StringUtils.hasText(curext)) { return false; } return curext.toLowerCase().startsWith(getFilenameExtension(".".concat(extension).toLowerCase())); } /** * Replace all windows folder separator "\" with java separator "/". * Remove also duplicates. * * @param path path to convert. i.e. "c:\\myfile.txt" * @return converted path. i.e. : "c:/myfile.txt" */ public static String rawConvertAndReplaceDuplicates(final String path) { if (StringUtils.hasText(path)) { //-- replace '\' with '/' --// final String result = path.replace(WINDOWS_FOLDER_SEPARATOR, FOLDER_SEPARATOR); return StringUtils.replaceDuplicates( result, FOLDER_SEPARATOR, FILESYSTEM_TYPES); } return path; } /** * Replace all windows folder separator "\" with java separator "/". * Remove also duplicates, but preserve protocols ("http://", "ftp://", etc..). * * @param path path to convert. i.e. "c:\\myfile.txt", "file:///path//folder/file.txt" * @return converted path. i.e. : "c:/myfile.txt", "file:///path/folder/file.txt" */ public static String toUnixPath(final String path) { return PathUtils.toUnixPath(path, FILESYSTEM_TYPES); } /** * Replace all windows folder separator "\" with java separator "/". * Remove also duplicates excluding those declared in "exclusion". * * @param path path to convert. i.e. "c:\\myfile.txt" * are removed. i.e. "//" become "/". * @param exclusion Array of esclusions from duplicates replacement. * i.e. ["file://", "http://"] * @return converted path. i.e. : "c:/myfile.txt" */ public static String toUnixPath(final String path, final String[] exclusion) { if (StringUtils.hasText(path)) { final String result = path.replace(WINDOWS_FOLDER_SEPARATOR, FOLDER_SEPARATOR); return null != exclusion && exclusion.length > 0 ? StringUtils.replaceDuplicates(result, FOLDER_SEPARATOR, exclusion) : StringUtils.replaceDuplicates(result, FOLDER_SEPARATOR); } return path; } /** * Replace all windows folder separator "\" with java separator "/". * Remove also duplicates and add a separator at the end * if path is not a file path. * * @param path Path to validate. i.e. "c:\\path" * @return validated path. i.e. : "c:/mypath/". If original path * is a file name * (i.e. "c:/myfile.txt"), no separator is added at the and of path. */ public static String validateFolderSeparator(final String path) { final String result = PathUtils.toUnixPath(path); // add separator at the end if result has none, and if is not a file name if (!StringUtils.hasText(PathUtils.getFilenameExtension(result)) && !result.endsWith(FOLDER_SEPARATOR)) { return result.concat(FOLDER_SEPARATOR); } else { return result; } } /** * Apply the given relative path to the given path, * assuming standard Java folder separation (i.e. "/" separators);<br> * i.e. full="<b>c:/fullfilepath/text.txt</b>" relative="/relative/relativefile.jpg" * output="c:/fullfilepath/relative/relativefile.jpg"<br> * i.e. full="<b>c:/fullfilepath/</b>" relative="/relative/relativefile.jpg" * output="c:/fullfilepath/relative/relativefile.jpg"<br> * i.e. full="<b>c:/fullfilepath</b>" relative="/relative/relativefile.jpg" * output="c:/relative/relativefile.jpg"; (Absolute path has no slash at the end).<br> * * @param path the path to start from (usually a full file path) * @param relativePath the relative path to apply * (relative to the full file path above) * @return the full file path that results from applying the relative path */ public static String applyRelativePath(final String path, final String relativePath) { int separatorIndex = path.lastIndexOf(FOLDER_SEPARATOR); if (separatorIndex != -1) { String newPath = path.substring(0, separatorIndex); if (!relativePath.startsWith(FOLDER_SEPARATOR)) { newPath += FOLDER_SEPARATOR; } return newPath + relativePath; } else { return relativePath; } } /** * Count the path levels. * * @param path The path. i.e. : "c:/test/folder1/folder2" * @return */ public static int getPathLevels(final String path) { int counter = 0; String[] tokens = toUnixPath(path).split("/"); for (String token : tokens) { if (StringUtils.hasText(token)) { if (!StringUtils.hasText(getFilenameExtension(token))) { counter++; } } } return counter; } public static String getPathRoot(final String path) { final String[] tokens = toUnixPath(path).split("/"); if (tokens.length > 0) { for (final String token : tokens) { if (StringUtils.hasLength(token)) { return FOLDER_SEPARATOR + token; } } } return path; } public static String splitPathRoot(final String path) { final String root = getPathRoot(path); if (StringUtils.hasText(root) && !root.equalsIgnoreCase("/")) { return path.substring(path.indexOf(root) + root.length()); } return path; } public static String getCanonicalPath(final String path) { try { return (new File(path)).getCanonicalPath(); } catch (Throwable ignored) { return path; } } /** * Check a path for folders, and return a sequence of "../" * to use as a prefix for relative path navigation in http application.<br> * i.e.: "/folder1/folder2/page1.html" return "../../". If you want navigate * to "/page2.html" from "/folder1/folder2/page1.html" you can use * "../../page2.html". * * @param path the path to check * @return sequence of "../" for each path folder. */ public static String getPathLevelsPrefix(final String path) { final int count = getPathLevels(path); StringBuilder result = new StringBuilder(); for (int i = 0; i < count; i++) { result.append("../"); } return result.toString(); } /** * Transform a path in relative path adding a dot (.) at beginning.<br/> * If path has a protocol (i.e. "http://"), the absolute path is returned. * * @param path Path. i.e. "/system/templates" * @return Relative path. i.e. "./system/templates" */ public static String getRelativePath(final String path) { if (StringUtils.hasText(path) && !PathUtils.hasProtocol(path)) { if (PathUtils.isAbsolute(path)) { if (path.startsWith(FOLDER_SEPARATOR)) { return ".".concat(path); } else { return ".".concat(FOLDER_SEPARATOR).concat(path); } } } return path; } /** * Return a relative URL from navigation from a starting point to a destination.<br> * i.e. getRelativePath("/folder1/page1.html", "home.html") returns "../home.html"<br> * If I want navigate from page1.html to home.html, I must consider that page1.html is * child of "folder1" folder. * * @param startingPoint Starting page * @param destination Destination page * @return Relative URL for http navigation from "startingPoint" to "destination.".<br> * i.e. getRelativePath("/folder1/page1.html", "home.html") returns "../home.html" */ public static String getRelativePath(final String startingPoint, final String destination) { final String prefix = getPathLevelsPrefix(startingPoint); return PathUtils.join(prefix, destination); } /** * Return true if passed file match at least with one of wildChars.<br> * e.g. file "c:/file.txt" match with ["*.jpg", "*.txt"].<br> * e.g. file "c:/file.txt" does not match with ["*.jpg", "*.gif"].<br> * * @param path file name or full file path. e.g. "file.txt", "c:\file.txt" * @param wildChars Array of wild-chars to check. e.g. ["*.txt", "file*.gif", "another.*"] * @return true if at least one wild-char is matched with path. */ public static boolean fileMatch(String path, String[] wildChars) { for (String wildChar : wildChars) { if (fileMatch(path, wildChar)) { return true; } } return false; } /** * Return true if passed file match with wildChar.<br> * e.g. file "c:/file.txt" match with ["*.jpg", "*.txt"].<br> * e.g. file "c:/file.txt" does not match with ["*.jpg", "*.gif"].<br> * * @param path file name or full file path. e.g. "file.txt", "c:\file.txt" * @param wildChar wild-char to check. e.g. "*.txt" * @return true if wild-char is matched with path. */ public static boolean fileMatch(String path, String wildChar) { String mypath = toUnixPath(path); String[] tokens = wildChar.split("\\."); boolean result = false; String nameFilter = tokens[0].trim(); String extFilter = tokens[1].trim(); String fileName = getFilename(mypath).toLowerCase(); String clearNameFilter = nameFilter.replace("*", ""); String clearExtFilter = extFilter.replace("*", ""); if (extFilter.equals("*")) { // All extensions if (nameFilter.equals("*")) { // *.* result = true; } else if (nameFilter.endsWith("*")) { // file*.* if (fileName.startsWith(clearNameFilter.toLowerCase())) { result = true; } } else { // file.* if (stripFilenameExtension(fileName).equalsIgnoreCase(nameFilter)) { result = true; } } } else { // only certain extensions if (nameFilter.equals("*")) { // *.EXT if (fileName.endsWith(extFilter.toLowerCase())) { result = true; } } else if (nameFilter.endsWith("*")) { // file*.EXT if (fileName.startsWith(clearNameFilter.toLowerCase()) && fileName.endsWith(extFilter.toLowerCase())) { result = true; } } else { // file.EXT if (fileName.equalsIgnoreCase(nameFilter + "." + extFilter)) { result = true; } } } return result; } /** * Return true if file name is base file name.<br> * Base file name is a file name, without any localization info. * i.e. "file_it.properties" is not a base name.<br> * i.e. "file.properties" is a base name. * * @param path Path to check * @return */ public static boolean isBaseName(final String path) { final String fileName = PathUtils.getFilename(path, false); final String[] tokens = fileName.split("_"); if (null != tokens && tokens.length > 0) { final String token = tokens[tokens.length - 1]; if (LocaleUtils.isISOLanguage(token) || LocaleUtils.isISOCountry(token)) { return false; } } return true; } /** * Return true if path is an absolute path.<br> * Linux path and windows have same result. * All paths are considered relatives path if starts with "." (dot). * * @param path Path to check * @return true if path is absolute. */ public static boolean isAbsolute(final String path) { final String checkpath = toUnixPath(path); if (checkpath.startsWith(".")) { return false; } else if (checkpath.indexOf(":") > 0 || checkpath.startsWith(FOLDER_SEPARATOR)) { // 'c:', 'http://' return true; } return false; } /** * Return true if passed path is a jar path. * * @param path Path * @return True is path contains String ".jar!", i.e. "file:/c:/myjar.jar!/org/sf/path" */ public static boolean isJar(final String path) { return path.indexOf(".jar!") > -1; } /** * Return true if path is an absolute path.<br/> * This method uses O.S. specific functions, so * Linux path and windows path may have different results. * * @param path Path to check * @return true if path is absolute. */ public static boolean isAbsoluteOS(final String path) { final String checkpath = toUnixPath(path); if (checkpath.indexOf(":") > 0) { // 'c:', 'http://' return true; } else if (checkpath.startsWith("./") || checkpath.startsWith("../")) { // './', '../' return false; } else if (IS_WINDOWS) { // windows path check if (checkpath.startsWith("/")) { return false; } } // Operating System decision. return (new File(path)).isAbsolute(); } /** * Return true if path is an Http path. * * @param path Path to check * @return true if path is absolute. */ public static boolean isHttp(final String path) { if (!StringUtils.hasText(path)) { return false; } final String lower = path.toLowerCase(); return lower.startsWith("http:") || lower.startsWith("https:"); } public static boolean isFtp(final String path) { return PathUtils.hasProtocol(path, SystemUtils.FileType.ftp.getValue()) || PathUtils.hasProtocol(path, SystemUtils.FileType.sftp.getValue()); } /** * Return true if text is a valid URI. * * @param path absolute or relative path or what else. * @return true, if path has a protocol or start with relative path. */ public static boolean isURI(final String path) { try { if (!StringUtils.hasText(path)) { return false; } return hasProtocol(path) || path.startsWith(".") || path.startsWith("/") || path.startsWith("\\"); } catch (Throwable ignored) { } return false; } public static boolean hasProtocol(final String path) { if (StringUtils.hasText(path)) { for (final String protocol : FILESYSTEM_TYPES) { if (path.startsWith(protocol)) { return true; } } } return false; } public static boolean hasProtocol(final String path, final String prot) { if (StringUtils.hasText(path)) { for (final String protocol : FILESYSTEM_TYPES) { if (path.startsWith(protocol)) { if (protocol.equalsIgnoreCase(prot)) { return true; } } } } return false; } public static String getProtocol(final String path) { if (StringUtils.hasText(path)) { for (final String protocol : FILESYSTEM_TYPES) { if (path.startsWith(protocol)) { return protocol; } } } return ""; } public static String stripProtocol(final String path) { final String protocol = getProtocol(path); if (StringUtils.hasText(protocol)) { return path.substring(protocol.length()); } return path; } /** * Add parameters to URI. i.e. "/uri/page?param1=1234¶m2=567" * * @param uri URI * @param params Map of parameters * @return URI with parameters . i.e. "/uri/page?param1=1234¶m2=567" */ public static String addURIParameters(final String uri, final Map<String, Object> params) { return addURIParameters(uri, params, true, true); } public static String addURIParameters(final String uri, final Object var_params, final boolean encodeValues) { final Map<String, Object> params = var_params instanceof Map ? (Map) var_params : CollectionUtils.stringToMap(var_params.toString(), "&"); return addURIParameters(uri, params, encodeValues, true); } public static String addURIParameters(final String uri, final Map<String, Object> params, final boolean encodeValues, final boolean checkForDuplicates) { // check if parameters exists if (StringUtils.hasText(uri) && !CollectionUtils.isEmpty(params)) { final StringBuilder result = new StringBuilder(); //-- append or insert params? --// if (uri.contains("?")) { if (checkForDuplicates) { // check for duplicate parameters final String[] tokens = StringUtils.split(uri, "?"); result.append(tokens[0]); final Map<String, Object> existing_params = CollectionUtils.stringToMap(tokens[1], "&"); final Set<String> keys = existing_params.keySet(); for (final String key : keys) { // add existing to passed params if (!params.containsKey(key)) { params.put(key, existing_params.get(key)); } } result.append("?"); } else { result.append("&"); } } else { result.append(uri); result.append("?"); } final StringBuilder paramsStr = new StringBuilder(); final Set<String> keys = params.keySet(); for (final String key : keys) { final Object value = params.get(key); if (null != value) { if (paramsStr.length() > 0) { paramsStr.append("&"); } paramsStr.append(key).append("="); if (encodeValues && !StringUtils.isURLEncoded(value.toString())) { paramsStr.append(encode(value.toString())); } else { paramsStr.append(value.toString()); } } } result.append(paramsStr); return result.toString(); } else { return uri; } } /** * Resolve path from c:/dir1/dir2/../file.txt to C:/dir1/file.txt * * @param url Path. ie: c:/dir1/dir2/../file.txt * @return Resolved Path C:/dir1/file.txt */ public static String resolve(final String url) { final String protocol = PathUtils.getProtocol(url); final String path = StringUtils.hasText(protocol) ? url.substring(protocol.length()) : url; final List<String> list = new LinkedList<String>(); final String[] tokens = StringUtils.split(path, "/"); for (int i = 0; i < tokens.length; i++) { final String token = tokens[i]; if (StringUtils.hasText(token)) { if (token.equalsIgnoreCase("..")) { // move back if (!list.isEmpty()) { list.remove(list.size() - 1); } } else if (!token.equalsIgnoreCase(".")) { // add token list.add(i == tokens.length - 1 ? token : token + "/"); } } } return protocol + (list.isEmpty() ? path : CollectionUtils.toString(list)); } /** * Concat two paths, but does not check for duplicate folder separators * or folder separators format (unix or windows).<br> * This method assumes that path are unix like. * * @param path1 * @param path2 * @return Concatenated path. */ public static String concat(final String path1, final String path2) { if (StringUtils.hasText(path1)) { if (!path1.endsWith(FOLDER_SEPARATOR) && !path2.startsWith(FOLDER_SEPARATOR)) { return path1.concat(FOLDER_SEPARATOR).concat(path2); } else { if (path1.equalsIgnoreCase(FOLDER_SEPARATOR)) { return path2; } if (path1.endsWith(FOLDER_SEPARATOR) && path2.startsWith(FOLDER_SEPARATOR)) { return path1.concat(path2.substring(1)); } return path1.concat(path2); } } else { return path2; } } /** * Like concat, but clean path 2 * * @param path1 * @param path2 * @return Concatenated path. */ public static String join(final String path1, final String path2) { final String cleanpath2 = clean(path2); if (StringUtils.hasText(path1)) { if (!path1.endsWith(FOLDER_SEPARATOR) && !cleanpath2.startsWith(FOLDER_SEPARATOR)) { return path1.concat(FOLDER_SEPARATOR).concat(cleanpath2); } else { if (path1.equalsIgnoreCase(FOLDER_SEPARATOR)) { return cleanpath2; } if (path1.endsWith(FOLDER_SEPARATOR) && path2.startsWith(FOLDER_SEPARATOR)) { return path1.concat(cleanpath2.substring(1)); } return path1.concat(cleanpath2); } } else { return cleanpath2; } } /** * Merge two paths. <br> * Ex: merge ("c:\myRoot", "myFileName") * result = "c:\myRoot\myFileName" * * @param path1 First path * @param path2 Second path * @return Merged path */ public static String merge(final String path1, final String path2) { //-- Remove characters like '//', '..//../' --// final String root = PathUtils.toUnixPath(path1); final String path = PathUtils.toUnixPath(path2); return mergeCleanPath(root, path, false); } /** * Combine two paths melting folders with same names. * Ex: combine("d:\myRoot\folder1", "folder1\myFileName") * result = "d:\myRoot\folder1\myFileName"; * * @param path1 root path. i.e. "d:\myRoot\folder1" * @param path2 second path. i.e. "d:\myRoot\folder1\myFileName" * @return The fusion between two paths. i.e. "d:\myRoot\folder1\myFileName" */ public static String combine(final String path1, final String path2) { final String root = PathUtils.toUnixPath(path1, SystemUtils.FileType.getValues()); final String path = PathUtils.toUnixPath(path2); return mergeCleanPath(root, path, true); } /** * Subtract first path to second one. * <p> * subtractPath = "c:/forder1/"<br> * inPath = "c:/forder1/dir/test.txt"<br> * result = "/dir/test.txt"; * </p> * * @param subtractPath Path to remove from inPath * @param fullPath Original path * @return Resultant path */ public static String subtract(String subtractPath, String fullPath) { //-- Clean the subtract path --// subtractPath = PathUtils.validateFolderSeparator(subtractPath); //subtractPath = PathUtils.cleanPath(subtractPath); if (subtractPath.startsWith(FOLDER_SEPARATOR) && subtractPath.endsWith(FOLDER_SEPARATOR)) { subtractPath = subtractPath.substring(1); } //-- Clean inputpath (the result) --// String result = fullPath; if (!PathUtils.isAbsolute(subtractPath)) { if (!subtractPath.endsWith(FOLDER_SEPARATOR)) { subtractPath = subtractPath.concat(FOLDER_SEPARATOR); } if (!subtractPath.startsWith(FOLDER_SEPARATOR)) { subtractPath = FOLDER_SEPARATOR.concat(subtractPath); } result = result.replace(subtractPath, "/"); } else { result = result.replace(subtractPath, ""); } // if result path is not absolute, check if start with / if (!PathUtils.isAbsolute(result) && !result.startsWith(FOLDER_SEPARATOR)) { result = FOLDER_SEPARATOR.concat(result); } return result; } /** * Return absolute path relative at current folder. */ public static String getAbsolutePath(final String path) { if (PathUtils.isAbsolute(path)) { return path; } final File f = new File(Smartly.getHome()); final String converted; final String relativePath = path.startsWith(".") ? path.substring(1) : path; if (f.getAbsolutePath().endsWith(".")) { converted = PathUtils.toUnixPath(f.getAbsolutePath().replace(".", relativePath)); } else { converted = PathUtils.toUnixPath(join(f.getAbsolutePath(), relativePath)); } return converted; } public static String getPackagePath(final Class clazz) { if (null != clazz) { return clazz.getPackage().getName().replace(".", "/"); } else { return null; } } public static String getClassPath(final Class clazz) { return clazz.getName().replace(".", "/"); } public static String getClassPath(final String className) { if (className.indexOf("/") == -1 && className.indexOf("\\") == -1) { return className.replace(".", "/"); } else { return className; } } /** * Short cut to File.exists() method */ public static boolean exists(String path) { final File file = new File(path); return file.exists(); } /** * Creates a path based on current date and time.<br/> * * @param detail 0=yyyy/MM/dd, 1=yyyy/, 2=yyyy/MM, 3=yyyy/MM/dd, 4=yyyy/MM/dd/hh, 5=yyyy/MM/dd/hh/mm, 6=yyyy/MM/dd/hh/mm/ss/ * @return Path. i.e. "2013/01/25/18" */ public static String getDateTimePath(final int detail) { final DateWrapper dt = new DateWrapper(DateUtils.now()); final String year = dt.getYear() + FOLDER_SEPARATOR; final String month = dt.getMonth() + FOLDER_SEPARATOR; final String day = dt.getDay() + FOLDER_SEPARATOR; final String hour = dt.getHour() + FOLDER_SEPARATOR; final String min = dt.getMinute() + FOLDER_SEPARATOR; final String sec = dt.getSecond() + FOLDER_SEPARATOR; if (detail == 1) { return FOLDER_SEPARATOR.concat(year); } else if (detail == 2) { return FOLDER_SEPARATOR.concat(year).concat(month); } else if (detail == 3) { return FOLDER_SEPARATOR.concat(year).concat(month).concat(day); } else if (detail == 4) { return FOLDER_SEPARATOR.concat(year).concat(month).concat(day).concat(hour); } else if (detail == 5) { return FOLDER_SEPARATOR.concat(year).concat(month).concat(day).concat(hour).concat(min); } else if (detail == 6) { return FOLDER_SEPARATOR.concat(year).concat(month).concat(day).concat(hour).concat(min).concat(sec); } else { return FOLDER_SEPARATOR.concat(year).concat(month).concat(day); } } // ------------------------------------------------------------------------ // p r i v a t e // ------------------------------------------------------------------------ private static String mergeCleanPath(final String root, final String path2, final boolean mergeNames) { if (!StringUtils.hasText(root)) { return path2; } final String path = clean(path2); final String result; final StringBuilder sb = new StringBuilder(); if (StringUtils.hasText(path)) { if (mergeNames) { sb.append(PathUtils.mergeNames(root, path)); } else { sb.append(root); } //-- Append last '/' --// if (!sb.toString().endsWith(FOLDER_SEPARATOR) && !path.startsWith(FOLDER_SEPARATOR)) { sb.append(FOLDER_SEPARATOR); } //-- append path to root --// sb.append(path); result = sb.toString(); //cleanPath(sb.toString()); } else { sb.append(root); result = sb.toString(); } return result; } private static String mergeNames(final String root, final String path) { final StringBuilder sb = new StringBuilder(); final String[] rootTokens = root.split(FOLDER_SEPARATOR); for (int i = 0; i < rootTokens.length; i++) { final String token = rootTokens[i]; if (StringUtils.hasText(token)) { if (path.startsWith(token) || path.startsWith(FOLDER_SEPARATOR + token)) { break; } else { final boolean abs = i == 0 ? PathUtils.isAbsolute(token) : false; if (!abs && !sb.toString().endsWith(FOLDER_SEPARATOR)) { sb.append(FOLDER_SEPARATOR); } // is root? if (sb.length() == 0) { sb.append(checkFsType(token)); } else { sb.append(token); } } } } // add folder separator only if already does not end with it. if (sb.lastIndexOf(FOLDER_SEPARATOR) != sb.length() - 1 && !path.startsWith(FOLDER_SEPARATOR)) { sb.append(FOLDER_SEPARATOR); } return sb.toString(); } private static String checkFsType(final String text) { final SystemUtils.FileType type = SystemUtils.FileType.getType(text); if (null == type) { return text; } else { return type.getValue(); } } private static String clean(final String path) { if (StringUtils.hasText(path) && path.startsWith(".") && path.length() > 1) { return path.substring(path.indexOf(".") + 1); } else { return path; } } private static String encode(final String s) { try { return URLEncoder.encode(s, CharEncoding.getDefault()); } catch (Exception ignored) { } return s; } }