static ContentRepository create(final File repoRoot, final File tmpRoot, long timeout, long lock) { return new ContentRepositoryImpl(repoRoot, tmpRoot, timeout, lock); } }
protected ContentRepositoryImpl(final File repoRoot, final File tmpRoot, long obsolescenceTimeout, long lockTimeout) { Assert.checkNotNullParam("repoRoot", repoRoot); Assert.checkNotNullParam("tmpRoot", tmpRoot); checkDirectory(repoRoot); this.repoRoot = repoRoot; checkDirectory(tmpRoot); this.tmpRoot = tmpRoot; this.obsolescenceTimeout = obsolescenceTimeout; this.lockTimeout = lockTimeout; try { this.messageDigest = MessageDigest.getInstance("SHA-1"); } catch (NoSuchAlgorithmException e) { throw DeploymentRepositoryLogger.ROOT_LOGGER.cannotObtainSha1(e, MessageDigest.class.getSimpleName()); } }
private void deleteFileWithEmptyAncestorDirectories(Path path) throws IOException { if (!this.repoRoot.toPath().equals(path)) { Files.deleteIfExists(path); Path parent = path.getParent(); try (Stream<Path> files = Files.list(parent)) { if (Files.isDirectory(parent) && !files.findAny().isPresent()) { deleteFileWithEmptyAncestorDirectories(parent); } } } }
final Path realFile = getDeploymentContentFile(sha1Bytes, true); if (hasContent(sha1Bytes)) { moveTempToPermanent(tmp, realFile); DeploymentRepositoryLogger.ROOT_LOGGER.contentAdded(realFile.toAbsolutePath().toString());
@Override public List<ContentRepositoryElement> listContent(byte[] deploymentHash, String path, ContentFilter filter) throws ExplodedContentException { Path tmpDir = null; try { if (!lock(deploymentHash)) { throw DeploymentRepositoryLogger.ROOT_LOGGER.errorLockingDeployment(); } tmpDir = Files.createTempDirectory(tmpRoot.toPath(), HashUtil.bytesToHexString(deploymentHash)); final Path rootPath = resolveSecurely(getDeploymentContentFile(deploymentHash), path); List<ContentRepositoryElement> result = PathUtil.listFiles(rootPath, tmpDir, filter); return result; } catch (InterruptedException ex) { Thread.currentThread().interrupt(); throw new RuntimeException(ex); } catch (IOException ex) { DeploymentRepositoryLogger.ROOT_LOGGER.warn(ex); throw DeploymentRepositoryLogger.ROOT_LOGGER.errorAccessingDeployment(ex); } finally { unlock(deploymentHash); if(tmpDir != null) { deleteSilentlyRecursively(tmpDir); } } }
@Override public byte[] removeContentFromExploded(byte[] deploymentHash, List<String> paths) throws ExplodedContentException { Path contentPath = getDeploymentContentFile(deploymentHash); try { if (Files.exists(contentPath) && Files.isDirectory(contentPath) && this.readWrite) { for (String path : paths) { Path targetFile = resolveSecurely(contentDir, path); deleteFileWithEmptyAncestorDirectories(targetFile); final Path realFile = getDeploymentContentFile(sha1Bytes, true); if (hasContent(sha1Bytes)) { moveTempToPermanent(contentDir, realFile); deleteRecursively(tmp); DeploymentRepositoryLogger.ROOT_LOGGER.contentAdded(realFile.toAbsolutePath().toString());
/** * Mark content as obsolete. If content was already marked for obsolescenceTimeout ms then it is removed. * * @param ref the content refrence to be marked as obsolete. * * @return true if the content refrence is removed, fale otherwise. */ private boolean markAsObsolete(ContentReference ref) { if (obsoleteContents.containsKey(ref.getHexHash())) { //This content is already marked as obsolete if (obsoleteContents.get(ref.getHexHash()) + obsolescenceTimeout < System.currentTimeMillis()) { DeploymentRepositoryLogger.ROOT_LOGGER.obsoleteContentCleaned(ref.getContentIdentifier()); removeContent(ref); return true; } } else { obsoleteContents.put(ref.getHexHash(), System.currentTimeMillis()); //Mark content as obsolete } return false; }
protected Path getDeploymentContentFile(byte[] deploymentHash) { return getDeploymentContentFile(deploymentHash, false); }
@Override public byte[] addContent(InputStream stream) throws IOException { byte[] result = super.addContent(stream); final Path realFile = getDeploymentContentFile(result, true); try (Git git = gitRepository.getGit()) { git.add().addFilepattern(gitRepository.getPattern(realFile)).call(); } catch (GitAPIException ex) { throw new IOException(ex); } return result; }
@Override public byte[] explodeSubContent(byte[] deploymentHash, String relativePath) throws ExplodedContentException { byte[] result = super.explodeSubContent(deploymentHash, relativePath); if (!Arrays.equals(deploymentHash, result)) { final Path realFile = getDeploymentContentFile(result, true); try (Git git = gitRepository.getGit()) { git.add().addFilepattern(gitRepository.getPattern(realFile)).call(); } catch (GitAPIException ex) { throw new ExplodedContentException(ex.getMessage(), ex); } } return result; }
@Override public byte[] addContentToExploded(byte[] deploymentHash, List<ExplodedContent> addFiles, boolean overwrite) throws ExplodedContentException { byte[] result = super.addContentToExploded(deploymentHash, addFiles, overwrite); if (!Arrays.equals(deploymentHash, result)) { final Path realFile = getDeploymentContentFile(result, true); try (Git git = gitRepository.getGit()) { git.add().addFilepattern(gitRepository.getPattern(realFile)).call(); } catch (GitAPIException ex) { throw new ExplodedContentException(ex.getMessage(), ex); } } return result; }
@Override public byte[] explodeContent(byte[] deploymentHash) throws ExplodedContentException { byte[] result = super.explodeContent(deploymentHash); if (!Arrays.equals(deploymentHash, result)) { final Path realFile = getDeploymentContentFile(result, true); try (Git git = gitRepository.getGit()) { git.add().addFilepattern(gitRepository.getPattern(realFile)).call(); } catch (GitAPIException ex) { throw new ExplodedContentException(ex.getMessage(), ex); } } return result; }
protected Path getDeploymentContentFile(byte[] deploymentHash, boolean validate) { return getDeploymentHashDir(deploymentHash, validate).resolve(CONTENT); }
@Override public byte[] explodeContent(byte[] deploymentHash) throws ExplodedContentException { Path contentPath = getDeploymentContentFile(deploymentHash); if (!Files.exists(contentPath)) { throw DeploymentRepositoryLogger.ROOT_LOGGER.archiveNotFound(contentPath.toString()); unzip(contentPath, contentDir); byte[] sha1Bytes = HashUtil.hashPath(messageDigest, contentDir); final Path realFile = getDeploymentContentFile(sha1Bytes, true); if (hasContent(sha1Bytes)) { moveTempToPermanent(contentDir, realFile); deleteRecursively(tmp); DeploymentRepositoryLogger.ROOT_LOGGER.contentExploded(realFile.toAbsolutePath().toString());
@Override public TypedInputStream readContent(byte[] deploymentHash, String path) throws ExplodedContentException { Path tmpDir = null; try { if(!lock(deploymentHash)) { throw DeploymentRepositoryLogger.ROOT_LOGGER.errorLockingDeployment(); } Path src = resolveSecurely(getDeploymentContentFile(deploymentHash), path); tmpDir = Files.createTempDirectory(tmpRoot.toPath(), HashUtil.bytesToHexString(deploymentHash)); Path file = PathUtil.readFile(src, tmpDir); Path tmp = Files.createTempFile(tmpRoot.toPath(), CONTENT, getFileExtension(src)); Files.copy(file, tmp, StandardCopyOption.COPY_ATTRIBUTES, StandardCopyOption.REPLACE_EXISTING); return new TemporaryFileInputStream(tmp); } catch (InterruptedException ex) { Thread.currentThread().interrupt(); throw new RuntimeException(ex); } catch (IOException ex) { DeploymentRepositoryLogger.ROOT_LOGGER.warn(ex); throw DeploymentRepositoryLogger.ROOT_LOGGER.errorAccessingDeployment(ex); } finally { unlock(deploymentHash); deleteSilentlyRecursively(tmpDir); } }
@Override public void removeContent(ContentReference reference) { final Path realFile = getDeploymentContentFile(reference.getHash()); super.removeContent(reference); if (!Files.exists(realFile)) { try (Git git = gitRepository.getGit()) { Set<String> deletedFiles = git.status().call().getMissing(); RmCommand rmCommand = git.rm(); for (String file : deletedFiles) { rmCommand.addFilepattern(file); } rmCommand.addFilepattern(gitRepository.getPattern(realFile)).call(); } catch (GitAPIException ex) { throw new RuntimeException(ex); } } }
@Override public boolean hasContent(byte[] hash) { return Files.exists(getDeploymentContentFile(hash)); }
@Override public byte[] addContent(InputStream stream) throws IOException { byte[] result = super.addContent(stream); final Path realFile = getDeploymentContentFile(result, true); try (Git git = gitRepository.getGit()) { git.add().addFilepattern(gitRepository.getPattern(realFile)).call(); } catch (GitAPIException ex) { throw new IOException(ex); } return result; }
@Override public byte[] explodeSubContent(byte[] deploymentHash, String relativePath) throws ExplodedContentException { byte[] result = super.explodeSubContent(deploymentHash, relativePath); if (!Arrays.equals(deploymentHash, result)) { final Path realFile = getDeploymentContentFile(result, true); try (Git git = gitRepository.getGit()) { git.add().addFilepattern(gitRepository.getPattern(realFile)).call(); } catch (GitAPIException ex) { throw new ExplodedContentException(ex.getMessage(), ex); } } return result; }
@Override public byte[] addContentToExploded(byte[] deploymentHash, List<ExplodedContent> addFiles, boolean overwrite) throws ExplodedContentException { byte[] result = super.addContentToExploded(deploymentHash, addFiles, overwrite); if (!Arrays.equals(deploymentHash, result)) { final Path realFile = getDeploymentContentFile(result, true); try (Git git = gitRepository.getGit()) { git.add().addFilepattern(gitRepository.getPattern(realFile)).call(); } catch (GitAPIException ex) { throw new ExplodedContentException(ex.getMessage(), ex); } } return result; }