/** * Resolves the given node name against this path. * * @param nodeName a node name relative to this path. * @return A new path with an absolute URI. */ public FsNodePath resolve(final FsNodeName nodeName) { if (nodeName.isRoot() && null == this.uri.getQuery()) return this; return new FsNodePath( this.mountPoint, new FsNodeName(this.nodeName, nodeName)); }
private boolean invariants() { assert null != getUri(); assert !getUri().isAbsolute(); assert null == getUri().getRawAuthority(); assert null != getUri().getRawPath(); assert null == getUri().getRawFragment(); assert getUri().normalize() == getUri(); String p = getUri().getRawPath(); assert !"..".equals(p); assert !p.startsWith(SEPARATOR); assert !p.startsWith("." + SEPARATOR); assert !p.startsWith(".." + SEPARATOR); assert !p.endsWith(SEPARATOR); return true; }
private FsNodePath resolve(final String path) throws URISyntaxException { splitter.split(path); final String pp = splitter.getParentPath(); final FsNodeName nn; final FsNodePath np; if (null != pp) { nn = new FsNodeName( builder.path(splitter.getMemberName()).getUri(), NULL); np = resolve(pp); } else { nn = new FsNodeName( builder.path(path).query(memberQuery).getUri(), CANONICALIZE); np = root; } URI npu; FsNodePath rnp; if (nn.isRoot() || (npu = np.getUri()).isOpaque() || !npu.isAbsolute()) { rnp = np.resolve(nn); } else { final String npup = npu.getPath(); if (!npup.endsWith(SEPARATOR)) npu = new UriBuilder(npu).path(npup + SEPARATOR_CHAR).getUri(); rnp = new FsNodePath(new FsMountPoint(npu), nn); } final FsScheme s = detector.scheme(nn.toString()); if (null != s) rnp = new FsNodePath(new FsMountPoint(s, rnp), ROOT); return rnp; }
@Override public void unlink( final BitField<FsAccessOption> options, final FsNodeName name) throws IOException { Path file = target.resolve(name.getPath()); delete(file); }
/** * Returns the nullable parent of the given file system node path. * * @param path a file system node path. * @return The parent file system node path or null if {@code path} does * not name a parent. * @throws URISyntaxException */ static @Nullable FsNodePath parent(FsNodePath path) throws URISyntaxException { FsMountPoint mp = path.getMountPoint(); FsNodeName en = path.getNodeName(); if (en.isRoot()) { if (null == mp) return null; path = mp.getPath(); if (null != path) return parent(path); URI mpu = mp.getUri(); URI pu = mpu.resolve(DOT_DOT_URI); if (mpu.getRawPath().length() <= pu.getRawPath().length()) return null; return new FsNodePath(pu); } else { URI pu = en.getUri().resolve(DOT_URI); en = new FsNodeName(pu, CANONICALIZE); return new FsNodePath(mp, en); } } }
@Override public final void unlink( final BitField<FsAccessOption> options, final FsNodeName name) throws IOException { try { controller.unlink(options, name); } catch (final ControlFlowException ex) { // If the exception is caused by a key exception, then throw this // cause instead in order to avoid treating the target archive file // like a false positive and routing this operation to the parent // file system. // This prevents the application from inadvertently deleting an // encrypted ZIP file just because the user cancelled key prompting. final IOException keyEx = findKeyException(ex); if (null == keyEx) throw ex; throw keyEx; } final FsModel model = getModel(); final URI mpu = driver.mountPointUri(model); final URI fsu = driver.fileSystemUri(model, name.toString()); if (!fsu.equals(mpu) || name.isRoot()) keyManager().unlink(fsu); }
/** * Returns {@code true} if and only if this {@code TPath} addresses an * archive file. * Whether or not this is true solely depends on the * {@link TArchiveDetector} which was used to construct this {@code TPath} * - no file system tests are performed by this method! * * @return {@code true} if and only if this {@code TPath} addresses an * archive file. * @see #isEntry */ public boolean isArchive() { final FsNodePath nodePath = getNodePath(); final boolean root = nodePath.getNodeName().isRoot(); final FsMountPoint parent = nodePath.getMountPoint().getParent(); return root && null != parent; }
URI mpu; if (null == mountPoint) { this.uri = nodeName.getUri(); } else if (nodeName.isRoot()) { this.uri = mountPoint.getUri(); } else if ((mpu = mountPoint.getUri()).isOpaque()) { final URI enu = nodeName.getUri(); final String enup = enu.getRawPath(); final int enupl = enup.length(); this.uri = mpu.resolve(nodeName.getUri());
HttpNode( final HttpController controller, final FsNodeName name) { assert null != controller; this.controller = controller; this.name = name.toString(); this.uri = controller.resolve(name).getUri(); }
.toUri(), modifier); nodeName = new FsNodeName( b.clear() .pathQuery(ssp.substring(i + 2)) if (NULL != modifier) { URI mpu = mountPoint.getUri(); URI nuri = new URI(mpu.getScheme() + ':' + mpu.getRawSchemeSpecificPart() + nodeName.getUri()); if (!uri.equals(nuri)) uri = nuri; nodeName = new FsNodeName(mountPoint.getUri().relativize(uri), modifier); } else { mountPoint = null; nodeName = new FsNodeName(uri, modifier); if (NULL != modifier) uri = nodeName.getUri();
/** * Constructs a new file system node name by parsing the given URI * after applying the given URI modifier. * This static factory method calls * {@link #FsNodeName(URI, FsUriModifier) new FsNodeName(uri, modifier)} * and wraps any thrown {@link URISyntaxException} in an * {@link IllegalArgumentException}. * * @param uri the {@link #getUri() URI}. * @param modifier the URI modifier. * @throws NullPointerException if {@code uri} or {@code modifier} are * {@code null}. * @throws IllegalArgumentException if {@code uri} still does not conform * to the syntax constraints for file system node names after its * modification. * @return A new file system node name. */ public static FsNodeName create(URI uri, FsUriModifier modifier) { try { return uri.toString().isEmpty() ? ROOT : new FsNodeName(uri, modifier); } catch (URISyntaxException ex) { throw new IllegalArgumentException(ex); } }
private void parse(final URI uri) throws URISyntaxException { if (uri.isAbsolute()) throw new QuotedUriSyntaxException(uri, "Scheme component defined"); if (null != uri.getRawAuthority()) throw new QuotedUriSyntaxException(uri, "Authority component defined"); if (null == uri.getRawPath()) throw new QuotedUriSyntaxException(uri, "Path component undefined"); if (null != uri.getRawFragment()) throw new QuotedUriSyntaxException(uri, "Fragment component defined"); this.uri = uri; final String p = uri.getRawPath(); if (p.startsWith(SEPARATOR)) throw new QuotedUriSyntaxException(uri, "Illegal start of path component"); if (!p.isEmpty() && DOT_DOT_SEPARATOR.startsWith(p.substring(0, Math.min(p.length(), DOT_DOT_SEPARATOR.length())))) throw new QuotedUriSyntaxException(uri, "Illegal start of path component"); if (p.endsWith(SEPARATOR)) throw new QuotedUriSyntaxException(uri, "Illegal separator \"" + SEPARATOR + "\" at end of path component"); assert invariants(); }
/** * Constructs a new file system node name by parsing the given URI. * This static factory method calls * {@link #FsNodeName(URI, FsUriModifier) new FsNodeName(uri, FsUriModifier.NULL)} * and wraps any thrown {@link URISyntaxException} in an * {@link IllegalArgumentException}. * * @param uri the {@link #getUri() URI}. * @throws NullPointerException if {@code uri} is {@code null}. * @throws IllegalArgumentException if {@code uri} does not conform to the * syntax constraints for file system node names. * @return A new file system node name. */ public static FsNodeName create(URI uri) { return create(uri, NULL); }
/** * Returns the node name relative to the parent file system. * That is, if this object addresses an entry located within an archive * file, then this method returns the relative path of the entry in the * enclosing archive file separated by the entry separator character * {@code '/'}, or {@code null} otherwise. * <p> * This method always returns an undotified path, i.e. all redundant * occurences of {@code "."} and {@code ".."} in the path are removed * wherever possible. * * @return The entry name relative to the enclosing archive file. */ public @Nullable String getEnclEntryName() { return null == nodeName ? null : nodeName.getPath(); }
/** * Returns {@code true} if and only if this {@code TPath} addresses an * entry located within an archive file. * Whether or not this is true solely depends on the * {@link TArchiveDetector} which was used to construct this {@code TPath} * - no file system tests are performed by this method! * * @return {@code true} if and only if this {@code TPath} addresses an * entry located within an archive file. * @see #isArchive */ public boolean isEntry() { final FsNodePath nodePath = getNodePath(); final boolean root = nodePath.getNodeName().isRoot(); final FsMountPoint parent = nodePath.getMountPoint().getParent(); return !root ? null != parent : null != parent && null != parent.getParent(); }
file.getParentFile().getPath(), separatorChar) && !nodeName.toString().isEmpty(); return true;
/** * Initialize this file object by scanning its path for archive * files, using the given {@code ancestor} file (i.e. a direct or * indirect parent file) if any. * {@code file} and {@code config} must already be initialized! * Must not be called to re-initialize this object! */ private void scan(final @CheckForNull TFile ancestor) { final String path = super.getPath(); assert ancestor == null || path.startsWith(ancestor.getPath()); assert file.getPath().equals(path); assert null != detector; final StringBuilder nodeNameBuf = new StringBuilder(path.length()); scan(detector, ancestor, 0, path, nodeNameBuf, new PathSplitter(separatorChar, false)); try { nodeName = 0 >= nodeNameBuf.length() ? null : new FsNodeName( new UriBuilder().path(nodeNameBuf.toString()).getUri(), CANONICALIZE); } catch (URISyntaxException ex) { throw new AssertionError(ex); } }
/** * Returns the entry name relative to the innermost archive file. * That is, if this object addresses an archive file, then this method * returns the empty string {@code ""}. * If this object addresses an entry located within an archive file, * then this method returns the relative path of the entry in the * enclosing archive file separated by the entry separator character * {@code '/'}, or {@code null} otherwise. * <p> * This method always returns an undotified path, i.e. all redundant * occurences of {@code "."} and {@code ".."} in the path are removed * wherever possible. * * @return The entry name relative to the innermost archive file. */ public @Nullable String getInnerEntryName() { final FsNodeName nodeName; return this == innerArchive ? ROOT.getPath() : null == (nodeName = this.nodeName) ? null : nodeName.getPath(); }