All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.esotericsoftware.wildcard.Paths Maven / Gradle / Ivy


package com.esotericsoftware.wildcard;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * Collects filesystem paths using wildcards, preserving the directory structure. Copies, deletes, and zips paths.
 *
 * 

* Code Source *

* *

* This is external code that was copied into the CedarCommon codebase under * the terms of its license. *

* *
* * * * * * * * * * * *
Source:Wildcard
Date:April, 2014
*
*/ public class Paths implements Iterable { static private final Comparator LONGEST_TO_SHORTEST = new Comparator() { public int compare (Path s1, Path s2) { return s2.absolute().length() - s1.absolute().length(); } }; static private List defaultGlobExcludes; final List paths = new ArrayList(32); /** * Creates an empty Paths object. */ public Paths () { } /** * Creates a Paths object and calls {@link #glob(String, String[])} with the specified arguments. */ public Paths (String dir, String... patterns) { glob(dir, patterns); } /** * Creates a Paths object and calls {@link #glob(String, List)} with the specified arguments. */ public Paths (String dir, List patterns) { glob(dir, patterns); } /** * Collects all files and directories in the specified directory matching the wildcard patterns. * @param dir The directory containing the paths to collect. If it does not exist, no paths are collected. If null, "." is * assumed. * @param patterns The wildcard patterns of the paths to collect or exclude. Patterns may optionally contain wildcards * represented by asterisks and question marks. If empty or omitted then the dir parameter is split on the "|" * character, the first element is used as the directory and remaining are used as the patterns. If null, ** is * assumed (collects all paths).
*
* A single question mark (?) matches any single character. Eg, something? collects any path that is named * "something" plus any character.
*
* A single asterisk (*) matches any characters up to the next slash (/). Eg, *\*\something* collects any path that * has two directories of any name, then a file or directory that starts with the name "something".
*
* A double asterisk (**) matches any characters. Eg, **\something\** collects any path that contains a directory * named "something".
*
* A pattern starting with an exclamation point (!) causes paths matched by the pattern to be excluded, even if other * patterns would select the paths. */ public void glob (String dir, String... patterns) { if (dir == null) dir = "."; if (patterns != null && patterns.length == 0) { String[] split = dir.split("\\|"); if (split.length > 1) { dir = split[0]; patterns = new String[split.length - 1]; for (int i = 1, n = split.length; i < n; i++) patterns[i - 1] = split[i]; } } File dirFile = new File(dir); if (!dirFile.exists()) return; List includes = new ArrayList(); List excludes = new ArrayList(); if (patterns != null) { for (String pattern : patterns) { if (pattern.charAt(0) == '!') excludes.add(pattern.substring(1)); else includes.add(pattern); } } if (includes.isEmpty()) includes.add("**"); if (defaultGlobExcludes != null) excludes.addAll(defaultGlobExcludes); GlobScanner scanner = new GlobScanner(dirFile, includes, excludes); String rootDir = scanner.rootDir().getPath().replace('\\', '/'); if (!rootDir.endsWith("/")) rootDir += '/'; for (String filePath : scanner.matches()) paths.add(new Path(rootDir, filePath)); } /** * Calls {@link #glob(String, String...)}. */ public void glob (String dir, List patterns) { if (patterns == null) throw new IllegalArgumentException("patterns cannot be null."); glob(dir, patterns.toArray(new String[patterns.size()])); } /** * Collects all files and directories in the specified directory matching the regular expression patterns. This method is much * slower than {@link #glob(String, String...)} because every file and directory under the specified directory must be * inspected. * @param dir The directory containing the paths to collect. If it does not exist, no paths are collected. * @param patterns The regular expression patterns of the paths to collect or exclude. If empty or omitted then the dir * parameter is split on the "|" character, the first element is used as the directory and remaining are used as the * patterns. If null, ** is assumed (collects all paths).
*
* A pattern starting with an exclamation point (!) causes paths matched by the pattern to be excluded, even if other * patterns would select the paths. */ public void regex (String dir, String... patterns) { if (dir == null) dir = "."; if (patterns != null && patterns.length == 0) { String[] split = dir.split("\\|"); if (split.length > 1) { dir = split[0]; patterns = new String[split.length - 1]; for (int i = 1, n = split.length; i < n; i++) patterns[i - 1] = split[i]; } } File dirFile = new File(dir); if (!dirFile.exists()) return; List includes = new ArrayList(); List excludes = new ArrayList(); if (patterns != null) { for (String pattern : patterns) { if (pattern.charAt(0) == '!') excludes.add(pattern.substring(1)); else includes.add(pattern); } } if (includes.isEmpty()) includes.add(".*"); RegexScanner scanner = new RegexScanner(dirFile, includes, excludes); String rootDir = scanner.rootDir().getPath().replace('\\', '/'); if (!rootDir.endsWith("/")) rootDir += '/'; for (String filePath : scanner.matches()) paths.add(new Path(rootDir, filePath)); } /** * Copies the files and directories to the specified directory. * @return A paths object containing the paths of the new files. */ public Paths copyTo (String destDir) throws IOException { Paths newPaths = new Paths(); for (Path path : paths) { File destFile = new File(destDir, path.name); File srcFile = path.file(); if (srcFile.isDirectory()) { destFile.mkdirs(); } else { destFile.getParentFile().mkdirs(); copyFile(srcFile, destFile); } newPaths.paths.add(new Path(destDir, path.name)); } return newPaths; } /** * Deletes all the files, directories, and any files in the directories. * @return False if any file could not be deleted. */ public boolean delete () { boolean success = true; List pathsCopy = new ArrayList(paths); Collections.sort(pathsCopy, LONGEST_TO_SHORTEST); for (File file : getFiles(pathsCopy)) { if (file.isDirectory()) { if (!deleteDirectory(file)) success = false; } else { if (!file.delete()) success = false; } } return success; } /** * Compresses the files and directories specified by the paths into a new zip file at the specified location. If there are no * paths or all the paths are directories, no zip file will be created. */ public void zip (String destFile) throws IOException { Paths zipPaths = filesOnly(); if (zipPaths.paths.isEmpty()) return; byte[] buf = new byte[1024]; ZipOutputStream out = new ZipOutputStream(new FileOutputStream(destFile)); try { for (Path path : zipPaths.paths) { File file = path.file(); out.putNextEntry(new ZipEntry(path.name.replace('\\', '/'))); FileInputStream in = new FileInputStream(file); int len; while ((len = in.read(buf)) > 0) out.write(buf, 0, len); in.close(); out.closeEntry(); } } finally { out.close(); } } public int count () { return paths.size(); } public boolean isEmpty () { return paths.isEmpty(); } /** * Returns the absolute paths delimited by the specified character. */ public String toString (String delimiter) { StringBuffer buffer = new StringBuffer(256); for (String path : getPaths()) { if (buffer.length() > 0) buffer.append(delimiter); buffer.append(path); } return buffer.toString(); } /** * Returns the absolute paths delimited by commas. */ public String toString () { return toString(", "); } /** * Returns a Paths object containing the paths that are files. */ public Paths filesOnly () { Paths newPaths = new Paths(); for (Path path : paths) { if (path.file().isFile()) newPaths.paths.add(path); } return newPaths; } /** * Returns a Paths object containing the paths that are directories. */ public Paths dirsOnly () { Paths newPaths = new Paths(); for (Path path : paths) { if (path.file().isDirectory()) newPaths.paths.add(path); } return newPaths; } /** * Returns the paths as File objects. */ public List getFiles () { return getFiles(paths); } private ArrayList getFiles (List paths) { ArrayList files = new ArrayList(paths.size()); int i = 0; for (Path path : paths) files.add(path.file()); return files; } /** * Returns the portion of the path after the root directory where the path was collected. */ public List getRelativePaths () { ArrayList stringPaths = new ArrayList(paths.size()); int i = 0; for (Path path : paths) stringPaths.add(path.name); return stringPaths; } /** * Returns the full paths. */ public List getPaths () { ArrayList stringPaths = new ArrayList(paths.size()); int i = 0; for (File file : getFiles()) stringPaths.add(file.getPath()); return stringPaths; } /** * Returns the paths' filenames. */ public List getNames () { ArrayList stringPaths = new ArrayList(paths.size()); int i = 0; for (File file : getFiles()) stringPaths.add(file.getName()); return stringPaths; } /** * Adds a single path to this Paths object. */ public void add (String dir, String name) { paths.add(new Path(dir, name)); } /** * Adds all paths from the specified Paths object to this Paths object. */ public void add (Paths paths) { this.paths.addAll(paths.paths); } /** * Iterates over the absolute paths. The iterator supports the remove method. */ public Iterator iterator () { return new Iterator() { private Iterator iter = paths.iterator(); public void remove () { iter.remove(); } public String next () { return iter.next().absolute(); } public boolean hasNext () { return iter.hasNext(); } }; } /** * Iterates over the paths as File objects. The iterator supports the remove method. */ public Iterator fileIterator () { return new Iterator() { private Iterator iter = paths.iterator(); public void remove () { iter.remove(); } public File next () { return iter.next().file(); } public boolean hasNext () { return iter.hasNext(); } }; } static private final class Path { public final String dir; public final String name; public Path (String dir, String name) { this.dir = dir; this.name = name; } public String absolute () { return dir + name; } public File file () { return new File(dir, name); } } /** * Sets the exclude patterns that will be used in addition to the excludes specified for all glob searches. */ static public void setDefaultGlobExcludes (String... defaultGlobExcludes) { Paths.defaultGlobExcludes = Arrays.asList(defaultGlobExcludes); } /** * Copies one file to another. */ static private void copyFile (File in, File out) throws IOException { FileChannel sourceChannel = new FileInputStream(in).getChannel(); FileChannel destinationChannel = new FileOutputStream(out).getChannel(); sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel); sourceChannel.close(); destinationChannel.close(); } /** * Deletes a directory and all files and directories it contains. */ static private boolean deleteDirectory (File file) { if (file.exists()) { File[] files = file.listFiles(); for (int i = 0, n = files.length; i < n; i++) { if (files[i].isDirectory()) deleteDirectory(files[i]); else files[i].delete(); } } return file.delete(); } public static void main (String[] args) { if (args.length == 0) { System.out.println("Usage: dir [pattern] [, pattern ...]"); System.exit(0); } List patterns = Arrays.asList(args); patterns = patterns.subList(1, patterns.size()); for (String path : new Paths(args[0], patterns)) System.out.println(path); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy