public FsEntry(FsEntry parent, String name, byte[] hash) { this.parent = parent; this.name = name; this.hash = hash; this.dir = false; this.p = null; if(parent != null) { depth = parent.depth + 1; parent.addChild(this); } else { depth = 0; } }
private static void collectPath(FsEntry entry, StringBuilder buf) { if(entry.parent == null) { return; } collectPath(entry.parent, buf); if(buf.length() > 0) { buf.append('/'); } buf.append(entry.getName()); }
void diffAdded() { diffStatus = ADDED; if(!children.isEmpty()) { for(FsEntry child : children.values()) { child.diffAdded(); } } }
private void doDiff(FsEntry originalEntry, FsEntry otherEntry) throws ProvisioningException { if(originalEntry.isDir() != otherEntry.isDir()) { removed = CollectionUtils.put(removed, originalEntry.getRelativePath(), originalEntry); added = CollectionUtils.put(added, otherEntry.getRelativePath(), otherEntry); return; if (originalEntry.hasChildren()) { final Map<String, FsEntry> otherChildren = otherEntry.cloneChildren(); for (FsEntry originalChild : originalEntry.getChildren()) { final FsEntry otherChild = otherChildren.remove(originalChild.getName()); if(otherChild == null) { originalChild.diffRemoved(); removed = CollectionUtils.put(removed, originalChild.getRelativePath(), originalChild); continue; otherChild.diffAdded(); added = CollectionUtils.put(added, otherChild.getRelativePath(), otherChild); } else if(otherEntry.hasChildren()) { for (FsEntry otherChild : otherEntry.getChildren()) { otherChild.diffAdded(); added = CollectionUtils.put(added, otherChild.getRelativePath(), otherChild); if(!Arrays.equals(originalEntry.getHash(), otherEntry.getHash())) { originalEntry.diffModified(); otherEntry.diffModified(); modified = CollectionUtils.put(modified, originalEntry.getRelativePath(), new FsEntry[] {originalEntry, otherEntry});
private void initChildren(final FsEntry parent) throws IOException { boolean hasDirs = false; try(DirectoryStream<Path> stream = Files.newDirectoryStream(parent.p)) { for(Path c : stream) { if(!pathFilters.isEmpty() && isFiltered(parent, c.getFileName().toString())) { continue; } hasDirs |= new FsEntry(parent, c).dir; } } if(hasDirs) { for(FsEntry child : parent.getChildren()) { if(!child.dir) { continue; } initChildren(child); } } }
private static void readHashes(FsEntry parent, List<FsEntry> dirs) throws ProvisioningException { int dirsTotal = 0; try(DirectoryStream<Path> stream = Files.newDirectoryStream(parent.getPath())) { for(Path child : stream) { if(child.getFileName().toString().equals(Constants.HASHES)) { try(BufferedReader reader = Files.newBufferedReader(child)) { String line = reader.readLine(); while(line != null) { new FsEntry(parent, line, HashUtils.hexStringToByteArray(reader.readLine())); line = reader.readLine(); } } catch (IOException e) { throw new ProvisioningException("Failed to read hashes", e); } } else { dirs.add(new FsEntry(parent, child)); ++dirsTotal; } } } catch (IOException e) { throw new ProvisioningException("Failed to read hashes", e); } while(dirsTotal > 0) { readHashes(dirs.remove(dirs.size() - 1), dirs); --dirsTotal; } }
public FsEntry forPath(Path p) throws ProvisioningException { final FsEntry entry = new FsEntry(null, p); if(entry.dir) { try { initChildren(entry); } catch (IOException e) { throw new ProvisioningException(Errors.fsEntryInit(p), e); } } return entry; }
void diffSuppress() { diffStatus = SUPPRESSED; if(!children.isEmpty()) { for(FsEntry child : children.values()) { child.diffSuppress(); } } }
public void dumpAsTree(PrintStream out) throws IOException { dumpAsTree(children.isEmpty() ? Collections.emptyList() : new ArrayList<>(), out); }
void diffRemoved() { diffStatus = REMOVED; if(!children.isEmpty()) { for(FsEntry child : children.values()) { child.diffRemoved(); } } }
public String getRelativePath() { if (relativePath == null) { final StringBuilder buf = new StringBuilder(); collectPath(this, buf); if(dir) { buf.append('/'); } relativePath = buf.toString(); } return relativePath; }
public FsEntry getEntry(String relativePath) { final FsEntry[] fsEntries = modified.get(relativePath); if(fsEntries != null) { return fsEntries[1]; } FsEntry fsEntry = added.get(relativePath); if(fsEntry == null) { fsEntry = removed.get(relativePath); if(fsEntry == null) { final String[] pathElements = relativePath.split("/"); FsEntry originalEntry = original; FsEntry otherEntry = other; for(String name : pathElements) { originalEntry = originalEntry == null ? null : originalEntry.getChild(name); otherEntry = otherEntry == null ? null : otherEntry.getChild(name); if(originalEntry == null && otherEntry == null) { return null; } } fsEntry = originalEntry == null ? otherEntry : originalEntry; } } return fsEntry; }
final Path hashesDir = LayoutUtils.getHashesDir(getInstallationHome()); if(Files.exists(hashesDir)) { final FsEntry originalState = new FsEntry(null, hashesDir); readHashes(originalState, new ArrayList<>()); final FsEntry currentState = getDefaultFsEntryFactory().forPath(getInstallationHome());
public void suppress(String relativePath) throws ProvisioningException { final FsEntry[] fsEntries = modified.get(relativePath); if(fsEntries != null) { fsEntries[0].diffSuppress(); fsEntries[1].diffSuppress(); return; } final FsEntry entry = getEntry(relativePath); if(entry == null) { throw new ProvisioningException("Failed to locate " + relativePath + " in the diff"); } entry.diffSuppress(); }
final String name = names[i++]; dirs.set(dirsI, i < names.length); children.get(name).dumpAsTree(dirs, out);
public FsEntry(FsEntry parent, Path p) { this.parent = parent; this.p = p; this.name = p.getFileName().toString(); this.dir = Files.isDirectory(p); if(parent != null) { depth = parent.depth + 1; parent.addChild(this); } else { depth = 0; } }