From 74cfa00427a38c95026b4517a17bab32514156f7 Mon Sep 17 00:00:00 2001 From: Georg Seibt <seibt@fim.uni-passau.de> Date: Fri, 28 Oct 2016 15:44:27 +0200 Subject: [PATCH] add a method for converting a path string returned by git to a Path object --- .../fim/seibt/gitwrapper/repo/GitWrapper.java | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/src/de/uni_passau/fim/seibt/gitwrapper/repo/GitWrapper.java b/src/de/uni_passau/fim/seibt/gitwrapper/repo/GitWrapper.java index f94cef0..d9bf376 100644 --- a/src/de/uni_passau/fim/seibt/gitwrapper/repo/GitWrapper.java +++ b/src/de/uni_passau/fim/seibt/gitwrapper/repo/GitWrapper.java @@ -2,11 +2,17 @@ package de.uni_passau.fim.seibt.gitwrapper.repo; import java.io.File; import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; +import java.nio.file.InvalidPathException; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Scanner; import java.util.function.Function; @@ -218,6 +224,103 @@ public class GitWrapper extends ToolWrapper { || res.getStdOutTrimmed().startsWith(ERROR_PREFIX); } + /** + * Converts the given {@code path} {@link String} to a {@link Path} object. This method will perform unquoting if + * necessary. If there is an exception unquoting or converting to a path an empty optional will be returned. + * + * @param path + * the {@link String} to convert to a {@link Path} + * @return optionally the {@link Path} corresponding to the given {@link String} returned by git + */ + public Optional<Path> getPath(String path) { + Objects.requireNonNull(path, "The given String 'path' must not be null."); + + if (path.length() >= 2 && path.charAt(0) == '"' && path.charAt(path.length() - 1) == '"') { + + try { + path = unquote(path); + } catch (IllegalArgumentException e) { + LOG.log(Level.WARNING, "Failed to unquote the path '" + path + "'.", e); + return Optional.empty(); + } + } + + try { + return Optional.of(Paths.get(path)); + } catch (InvalidPathException e) { + LOG.log(Level.WARNING, "Failed to construct a Path object from path '" + path + "'.", e); + return Optional.empty(); + } + } + + /** + * Unquotes the given {@link String}. This method assumes that the given {@link String} begins and ends with the + * character '"'. It will replace escape sequences \a, \b, \f, \n, \r, \t, \v, \\, and \" with their corresponding + * unquoted characters. + * + * @param quoted + * the quoted {@link String} + * @return the unquoted {@link String} + * @throws IllegalArgumentException + * if the given {@link String} does not start with a '"' character or there is an + * illegal escape sequence in {@code quoted} + */ + private String unquote(String quoted) { + StringReader rdr = new StringReader(quoted); + StringWriter wtr = new StringWriter(quoted.length() - 2); + + int ch; + + try { + if (rdr.read() != '"') { + throw new IllegalArgumentException("Quoted strings begin with the character <\">"); + } + + while ((ch = rdr.read()) != -1) { + + if (ch == '"') { + break; + } else if (ch != '\\') { + wtr.write(ch); + continue; + } + + switch ((ch = rdr.read())) { + case 'a': + wtr.write(0x07); + break; + case 'b': + wtr.write('\b'); + break; + case 'f': + wtr.write('\f'); + break; + case 'n': + wtr.write('\n'); + break; + case 'r': + wtr.write('\r'); + break; + case 't': + wtr.write('\t'); + break; + case 'v': + wtr.write(0x0B); + break; + case '\\': case '"': + wtr.write(ch); + break; + default: + throw new IllegalArgumentException("Illegal escape character <" + (char) ch + ">."); + } + } + } catch (IOException e) { + throw new RuntimeException("The StringReader will not be closed and as such can not throw an IOException.", e); + } + + return wtr.toString(); + } + /** * Executes '<git command> <firstParameter> <parameters>' and returns the exit code and the output * of the command. If there is an exception executing the command an empty {@link Optional} will be returned. -- GitLab