Match path string using glob in Java - java

I have following string as a glob rule:
**/*.txt
And test data:
/foo/bar.txt
/foo/buz.jpg
/foo/oof/text.txt
Is it possible to use glob rule (without converting glob to regex) to match test data and return valud entries ?
One requirement: Java 1.6

If you have Java 7 can use FileSystem.getPathMatcher:
final PathMatcher matcher = FileSystem.getPathMatcher("glob:**/*.txt");
This will require converting your strings into instances of Path:
final Path myPath = Paths.get("/foo/bar.txt");
For earlier versions of Java you might get some mileage out of Apache Commons' WildcardFileFilter. You could also try and steal some code from Spring's AntPathMatcher - that's very close to the glob-to-regex approach though.

FileSystem#getPathMatcher(String) is an abstract method, you cannot use it directly. You need to do get a FileSystem instance first, e.g. the default one:
PathMatcher m = FileSystems.getDefault().getPathMatcher("glob:**/*.txt");
Some examples:
// file path
PathMatcher m = FileSystems.getDefault().getPathMatcher("glob:**/*.txt");
m.matches(Paths.get("/foo/bar.txt")); // true
m.matches(Paths.get("/foo/bar.txt").getFileName()); // false
// file name only
PathMatcher n = FileSystems.getDefault().getPathMatcher("glob:*.txt");
n.matches(Paths.get("/foo/bar.txt")); // false
n.matches(Paths.get("/foo/bar.txt").getFileName()); // true

To add to the previous answer: org.apache.commons.io.FilenameUtils.wildcardMatch(filename, wildcardMatcher)
from Apache commons-lang library.

Related

Groovy remove beginning of path

I'm trying to delete the beginning of a path that has '\' and ' ' in it. I seem to be getting the some issues saying escape character issue at character 3.
Example:
SomePath: C:\Users\ADMINISTRATOR\App Play\blah\blah
SomePath.replaceFirst('C:\\Users\\ADMINISTRATOR\\App Play\\', '');
Path should be blah\blah
I've tried:
SomePath.replaceFirst("C:\Users\ADMINISTRATOR\App Play\", "");
SomePath.replaceFirst("C:\\Users\\ADMINISTRATOR\\App Play\\", "");
SomePath.replaceFirst("C:\\\\Users\\\\ADMINISTRATOR\\\\App Play\\\\", "");
SomePath.replaceAll("C:\Users\ADMINISTRATOR\App Play\", "");
SomePath.replaceAll("C:\\Users\\ADMINISTRATOR\\App Play\\", "");
SomePath.replaceAll("C:\\\\Users\\\\ADMINISTRATOR\\\\App Play\\\\", "");
Just gave it a try... the examples with four backslashes work for me:
def somePath = "C:\\Users\\ADMINISTRATOR\\App Play\\blah\\blah"
println somePath
somePath.replaceFirst("C:\\\\Users\\\\ADMINISTRATOR\\\\App Play\\\\", "");
The problem is that the string needs one escaping \ and since the replaceFirst uses a regexp, the regexp-engine needs another \ to escape the \. The result are four backslashes.
Btw: you can use string operations to get your path, but you could also try file operations like this:
def root= new File("C:\\Users\\ADMINISTRATOR\\App Play\\")
def full= new File("C:\\Users\\ADMINISTRATOR\\App Play\\blah\\blah")
def relPath = root.toPath().relativize( full.toPath() ).toFile()
println relPath
(taken from https://gist.github.com/ysb33r/5804364)
You can tackle this problem differently. You could tokenize your input path using \ as a delimiter and then you could pick the last 2 elements (blah and blah) or skip first 4 elements (C:, Users, ADMINISTRATOR, App Play). It depends which assumption is easier to deduct for you. Consider following example:
def somePath = 'C:\\Users\\ADMINISTRATOR\\App Play\\blah\\blah'
// Build a new path by accepting the last 2 parts of the initial path
assert 'blah\\blah' == somePath.tokenize('\\')[-2..-1].join('\\')
// Build a new path by skipping the first 4 parts from initial path
assert 'blah\\blah' == somePath.tokenize('\\').drop(4).join('\\')
First option works better if you want only two last parts from the initial path. Second option works better if you can expect final path like blah\blah\blahhhh because you don't know how many nested children initial path contains and you want to start building a new path right after \App Play\ .

Looking for files of certain extension using lambda

As an exercise, I decide to rewrite some code of mine to use lambda expression. The code should check if a given string is a path to a file with .pdf extension and then it should display all the files that meet this requirement. This so what I've already come up with:
Files.newDirectoryStream(Paths.get(args[0]), path -> path.toFile()
.toString()
.endsWith(".pdf"))
.forEach(System.out::println);
This code fails at one point: it also displays directories. Could you tell me why the following code fails to compile?
Files.newDirectoryStream(Paths.get(args[0]), path -> path.toFile()
.isFile()
.toString()
.endsWith(".pdf"))
.forEach(System.out::println);
Your second code fails to compile because isFile returns a boolean. Once you have a boolean, file name is gone; even if you could convert it to String, matching its suffix to ".pdf" would fail anyway.
You are testing two separate conditions, so you should test them in two separate checks:
Files.newDirectoryStream(Paths.get(args[0]), path ->
Files.isRegularFile(path) && path.toString().endsWith(".pdf")
).forEach(System.out::println);
Note that path.toString().endsWith(...) can be checked without converting Path to File.
Because the compiler expects to have a boolean as second argument of
newDirectoryStream(Path dir, DirectoryStream.Filter<? super Path> filter)
Filter being a functional interface defined as :
boolean accept(T entry) throws IOException;
But here :
.isFile()
.toString()
a String is returned.
Make things in two times by combining two boolean expressions :
Files.newDirectoryStream(Paths.get(args[0]), path ->
Files.isRegularFile(path)
&& path.toString().endsWith(".pdf"))
.forEach(System.out::println);
In addition to Andreas comment about :
path.toFile().toString().endsWith(".pdf"))
that may be abbreviated by : path.toString().endsWith(".pdf"), you could also replace
path.toFile().isFile() by Files.isRegularFile(path).
It allows to rely only on the java.nio.file API rather that mixing it with the java.io.file API.

How to split the string using comma delimiter in Jenkins Groovy script?

I have tried to get all the solution files(*.sln) in a given path and print it individually by split the string(each solution file path) using comma delimiter. Programming script language am using is Jenkins Groovy. Am getting the below specified error when build the Jenkins job. Any one please look into this and guide me to proceed in a right way.
def finder = new FileNameFinder()
def files = finder.getFileNames 'D:\jobs', '**/*.sln'
def resultList = files.tokenize(",")
for(i=0; i<resultList.size();i++)
{
println resultList[i]
}
Error Details:
hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: java.util.ArrayList.tokenize() is applicable for argument types: (java.lang.String) values: [,]
Possible solutions: toUnique(), toUnique(), toUnique(java.util.Comparator), takeWhile(groovy.lang.Closure), toUnique(groovy.lang.Closure), toUnique(java.util.Comparator)
Thanks in advance!!
Myself itself found an answer for my above problem. Please find below the modified working code.
def finder = new FileNameFinder()
def files = finder.getFileNames 'D:\jobs', '**/*.sln'
assert files instanceof List
println files.size()+" solution files found in the given path. Below are the found solution files details. \n"
for(i=0;i<files.size();i++)
{
println files[i];
}
Thanks

Regular expression in Java and in Eclipse?

I want to remove all empty linse in Java. In Eclipse I will use:
\n( *)\n (or "\r\n( *)\r\n" in Windows)
. But in Java it isn't work (I used:
str=str.replaceAll("\n( *)\n")
). How to do it in Java using replaceAll? Sample:
package example
○○○○
public ... (where ○ is space)
I would do it like this
java.util.regex.Pattern ws = Pattern.compile("[\r|\n][\\s]*[\r|\n]");
java.util.regex.Matcher matcher = ws.matcher(str);
str = matcher.replaceAll(" ");

ClosureCompiler: create_name_map_files from Java API

from command-line i can get a alias list of the function renaming from compiler.jar
Help says:
java -jar compiler.jar --help
[...]
--create_name_map_files : If true, variable renaming and
property renaming map files will be
produced as {binary name}_vars_map.out
and {binary name}_props_map.out. Note
that this flag cannot be used in
conjunction with either variableMapOut
putFile or property_map_output_file
--create_source_map VAL : If specified, a source map file
mapping the generated source files
back to the original source file will
be output to the specified path. The
%outname% placeholder will expand to
the name of the output file that the
source map corresponds to.
[...]
so, how can i get "create_name_map_files" from inline java? i took a look into the AbstractCommandLineRunner.java but all classes/methods which relate to this command line option are private and not reachable from my code..
My Code:
CompilerOptions opt = new CompilerOptions();
// decide mode
compilationLevel.ADVANCED_OPTIMIZATIONS.setOptionsForCompilationLevel(opt);
opt.prettyPrint = false;
Compiler.setLoggingLevel(Level.OFF);
Compiler compressor = new Compiler();
compressor.disableThreads();
List<SourceFile> inputs = ...;
List<SourceFile> externs = ...;
compressor.compile(externs, inputs, opt);
you can just use the option : variable_map_output_file filename , similarly for props.
Note that: The flags variable_map_output_file and create_name_map_files cannot both be used simultaniously.
From CommandLineRunner.java, I would say
opt.setCreateNameMapFiles(true)
The "compile" function returns a Result object that contains the variable (variableMap) and property (propertyMap) renaming maps. These properties contain VariableMap objects that can be serialized:
Result result = compiler.compiler(...);
result.variableMap.save(varmapPath);
result.propertyMap.save(propmapPath);

Categories

Resources