Skip to content

Commit

Permalink
[FIX] XQuery, URI handling. Fixes #1292
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristianGruen committed May 5, 2016
1 parent c9d2ca4 commit b9ad006
Show file tree
Hide file tree
Showing 20 changed files with 137 additions and 124 deletions.
5 changes: 3 additions & 2 deletions basex-core/src/main/java/org/basex/build/DirParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,16 @@ public final class DirParser extends Parser {
public DirParser(final IO source, final MainOptions options) {
super(source, options);

final String dir = source.dir();
final boolean isDir = source.isDir();
final String dir = isDir ? source.path() : source.dir();
root = dir.endsWith("/") ? dir : dir + '/';
skipCorrupt = options.get(MainOptions.SKIPCORRUPT);
archives = options.get(MainOptions.ADDARCHIVES);
archiveName = options.get(MainOptions.ARCHIVENAME);
addRaw = options.get(MainOptions.ADDRAW);
dtd = options.get(MainOptions.DTD);
rawParser = options.get(MainOptions.PARSER) == MainParser.RAW;
filter = !source.isDir() && !source.isArchive() ? null :
filter = !isDir && !source.isArchive() ? null :
Pattern.compile(IOFile.regex(options.get(MainOptions.CREATEFILTER)));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ final class DialogGeneralPrefs extends BaseXBack {
public void actionPerformed(final ActionEvent e) {
final String path = dbPath.getText();
final IOFile dir = new BaseXFileChooser(CHOOSE_DIR, path, gui).select(Mode.DOPEN);
if(dir != null) dbPath.setText(dir.dir());
if(dir != null) dbPath.setText(dir.path());
}
});

Expand All @@ -80,7 +80,7 @@ public void actionPerformed(final ActionEvent e) {
public void actionPerformed(final ActionEvent e) {
final String path = repoPath.getText();
final IOFile dir = new BaseXFileChooser(CHOOSE_DIR, path, gui).select(Mode.DOPEN);
if(dir != null) repoPath.setText(dir.dir());
if(dir != null) repoPath.setText(dir.path());
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ void refreshTree() {
final ProjectNode node = (ProjectNode) en.nextElement();
if(node.file == null) continue;

final String path = node.file.path(), dir = node.file.dir() + '/';
final String path = node.file.path(), dir = node.file.dir();
boolean found = false;
for(final String p : paths) {
if(p.equals(path) || p.startsWith(dir)) {
Expand Down
39 changes: 24 additions & 15 deletions basex-core/src/main/java/org/basex/io/IO.java
Original file line number Diff line number Diff line change
Expand Up @@ -169,13 +169,20 @@ public boolean exists() {

/**
* Tests if this is a directory instance.
* Returns {@code false} for IO instances other than {@link IOFile}.
* @return result of check
*/
public boolean isDir() {
return false;
}

/**
* Tests if this is an absolute path.
* @return result of check
*/
public boolean isAbsolute() {
return true;
}

/**
* Tests if the file suffix matches the specified suffixes.
* @param suffixes suffixes to compare with
Expand Down Expand Up @@ -234,13 +241,14 @@ public long length() {
public abstract InputStream inputStream() throws IOException;

/**
* Merges two paths. Returns the new specified path for {@link IOContent} and
* {@link IOStream} instances.
* @param in name/path to be appended
* Merges two paths.
* @param path path to be merged
* @return resulting reference
*/
public IO merge(final String in) {
return get(in);
public final IO merge(final String path) {
if(path.isEmpty()) return this;
final IO io = IO.get(path);
return io.isAbsolute() ? io : IO.get((pth.endsWith("/") ? pth : dir()) + path);
}

/**
Expand Down Expand Up @@ -287,14 +295,23 @@ public final void name(final String name) {
}

/**
* Returns the path.
* Returns the full path.
* The path uses forward slashes, no matter which OS is used.
* @return path
*/
public final String path() {
return pth;
}

/**
* Returns the directory path (all characters up to the last slash).
* No check will be performed if the directory exists.
* @return directory path
*/
public final String dir() {
return pth.substring(0, pth.lastIndexOf('/') + 1);
}

/**
* Creates a URL from the specified path.
* Returns the original path for IO instances other than {@link IOFile}.
Expand All @@ -304,14 +321,6 @@ public String url() {
return pth;
}

/**
* Returns the directory path.
* @return chopped filename
*/
public String dir() {
return "";
}

/**
* Compares the filename of the specified IO reference.
* @param io io reference
Expand Down
2 changes: 1 addition & 1 deletion basex-core/src/main/java/org/basex/io/IOContent.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public IOContent(final byte[] content) {
* @param content contents
*/
public IOContent(final String content) {
this(Token.token(content), "");
this(Token.token(content));
}

/**
Expand Down
70 changes: 41 additions & 29 deletions basex-core/src/main/java/org/basex/io/IOFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,45 +19,62 @@
* @author Christian Gruen
*/
public final class IOFile extends IO {
/** Pattern for absolute file paths. */
public static final Pattern ABSOLUTE =
Pattern.compile(Prop.WIN ? "^(/|\\|[a-zA-Z]:).*$" : "^/.*");
/** Pattern for valid file names. */
private static final Pattern VALIDNAME =
Pattern.compile("^[^\\\\/" + (Prop.WIN ? ":*?\"<>\\|" : "") + "]+$");
/** File reference. */
private final File file;
/** Indicate if supplied path was absolute. */
private final boolean absolute;

/**
* Constructor.
* @param path file path
* @param file file reference
* @param original original path
*/
public IOFile(final String path) {
this(new File(path));
private IOFile(final File file, final String original) {
super(new PathList().create(file.getAbsolutePath()));
absolute = file.isAbsolute();
this.file = absolute ? file : file.getAbsoluteFile();
// preserve trailing slash
if(original.endsWith("/") || original.endsWith("\\")) pth += '/';
}

/**
* Constructor.
* @param file file reference
*/
public IOFile(final File file) {
super(new PathList().create(file.getAbsolutePath()));
this.file = file.isAbsolute() ? file : file.getAbsoluteFile();
this(file, "");
}

/**
* Constructor.
* @param dir directory
* @param name file name
* @param path file path
*/
public IOFile(final String dir, final String name) {
this(new File(dir, name));
public IOFile(final String path) {
this(new File(path), path);
}

/**
* Constructor.
* @param dir directory
* @param name file name
* @param dir parent directory string
* @param child child directory string
*/
public IOFile(final IOFile dir, final String name) {
this(new File(dir.file, name));
public IOFile(final String dir, final String child) {
this(new File(dir, child), child);
}

/**
* Constructor.
* @param dir directory string
* @param child child path string
*/
public IOFile(final IOFile dir, final String child) {
this(new File(dir.file, child), child);
}

/**
Expand Down Expand Up @@ -97,6 +114,11 @@ public boolean isDir() {
return file.isDirectory();
}

@Override
public boolean isAbsolute() {
return absolute;
}

@Override
public long timeStamp() {
return file.lastModified();
Expand Down Expand Up @@ -129,14 +151,7 @@ public InputStream inputStream() throws IOException {
*/
public IOFile resolve(final String path) {
final File f = new File(path);
return f.isAbsolute() ? new IOFile(f) : new IOFile(dir(), path);
}

@Override
public IO merge(final String path) {
final IO io = IO.get(path);
if(!(io instanceof IOFile) || path.contains(":") || path.startsWith("/")) return io;
return new IOFile(dir(), path);
return f.isAbsolute() ? new IOFile(f) : new IOFile(isDir() ? pth : dir(), path);
}

/**
Expand All @@ -147,11 +162,6 @@ public boolean md() {
return file.exists() || file.mkdirs();
}

@Override
public String dir() {
return isDir() ? pth : pth.substring(0, pth.lastIndexOf('/') + 1);
}

/**
* Returns the parent of this file or directory or {@code null} if there is no parent directory.
* @return directory or {@code null}
Expand Down Expand Up @@ -338,7 +348,7 @@ public IOFile normalize() {
// STATIC METHODS ===============================================================================

/**
* Checks if the specified sting is a valid file name.
* Checks if the specified string is a valid file name.
* @param name file name
* @return result of check
*/
Expand All @@ -355,9 +365,11 @@ public static boolean isValid(final String path) {
// no colon: treat as file path
final int c = path.indexOf(':');
if(c == -1) return true;
// Windows drive letter? Colon after first slash?
// Windows drive letter?
final int fs = path.indexOf('/'), bs = path.indexOf('\\');
return c == 1 && Token.letter(path.charAt(0)) || fs != -1 && fs < c || bs != -1 && bs < c;
if(Prop.WIN && c == 1 && Token.letter(path.charAt(0)) && (fs == 2 || bs == 2)) return true;
// ensure that slash occurs before colon
return fs != -1 && fs < c || bs != -1 && bs < c;
}

/**
Expand Down
11 changes: 2 additions & 9 deletions basex-core/src/main/java/org/basex/io/IOUrl.java
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,8 @@ public URLConnection connection() throws IOException {
}

@Override
public String dir() {
return pth.endsWith("/") ? pth : pth.substring(0, pth.lastIndexOf('/') + 1);
}

@Override
public IO merge(final String path) {
final IO io = IO.get(path);
if(!(io instanceof IOFile) || path.contains(":") || path.startsWith("/")) return io;
return IO.get((pth.endsWith("/") ? pth : pth.replace("^(.*/).*", "$1")) + path);
public boolean isDir() {
return pth.endsWith("/");
}

/**
Expand Down
4 changes: 2 additions & 2 deletions basex-core/src/main/java/org/basex/query/QueryInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ public String toString(final QueryProcessor qp, final long printed, final long h
else tb.add(LOCAL).add(' ').add(Arrays.toString(writeLocked.toArray()));
tb.add(NL);
}
final IO io = qp.sc.baseIO();
final String name = io == null ? "" : " \"" + io.name() + '"';
final IO baseIO = qp.sc.baseIO();
final String name = baseIO == null ? "" : " \"" + baseIO.name() + '"';
tb.addExt(NL + QUERY_EXECUTED_X_X, name, Performance.getTime(total, runs));
return tb.toString();
}
Expand Down
4 changes: 1 addition & 3 deletions basex-core/src/main/java/org/basex/query/QueryInput.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ public final class QueryInput {
*/
public QueryInput(final String original, final StaticContext sc) {
this.original = original;

final IO baseIO = sc.baseIO();
io = baseIO == null ? IO.get(original) : baseIO.merge(original);
io = sc.resolve(original);

// check if the specified input string can be rewritten to a database name and path
String name = original.startsWith("/") ? original.substring(1) : original, path = "";
Expand Down
10 changes: 4 additions & 6 deletions basex-core/src/main/java/org/basex/query/QueryParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,7 @@ public QueryParser(final String query, final String path, final QueryContext qct

// set path to query file
final MainOptions opts = qctx.context.options;
final String uri = path != null ? path : opts.get(MainOptions.QUERYPATH);
if(!uri.isEmpty()) sc.baseURI(uri);
sc.baseURI(path != null ? path : opts.get(MainOptions.QUERYPATH));

// bind external variables
for(final Entry<String, String> entry : opts.toMap(MainOptions.BINDINGS).entrySet()) {
Expand Down Expand Up @@ -214,8 +213,8 @@ public final LibraryModule parseLibrary(final boolean check) throws QueryExcepti
wsCheck(";");

// get absolute path
final IO base = sc.baseIO();
final byte[] path = token(base == null ? "" : base.path());
final IO baseO = sc.baseIO();
final byte[] path = token(baseO == null ? "" : baseO.path());
qc.modParsed.put(path, uri);
qc.modStack.push(path);

Expand Down Expand Up @@ -679,8 +678,7 @@ private boolean defaultCollationDecl() throws QueryException {
*/
private void baseURIDecl() throws QueryException {
if(!decl.add(BASE_URI)) throw error(DUPLBASE);
final byte[] base = stringLiteral();
if(base.length != 0) sc.baseURI(string(base));
sc.baseURI(string(stringLiteral()));
}

/**
Expand Down
4 changes: 2 additions & 2 deletions basex-core/src/main/java/org/basex/query/QueryResources.java
Original file line number Diff line number Diff line change
Expand Up @@ -389,8 +389,8 @@ private Data create(final QueryInput input, final boolean single, final InputInf

// check if input points to a single file
final IO io = input.io;
if(!io.exists()) throw WHICHRES_X.get(ii, input.original);
if(single && io.isDir()) throw RESDIR_X.get(ii, input.original);
if(!io.exists()) throw WHICHRES_X.get(ii, io);
if(single && io.isDir()) throw RESDIR_X.get(ii, io);

// overwrite parsing options with default values
final boolean mem = !context.options.get(MainOptions.FORCECREATE);
Expand Down
Loading

0 comments on commit b9ad006

Please sign in to comment.