@Override protected void handleFileTypeCollision( LocalRepoTransaction transaction, UUID fromRepositoryId, File file, Class<? extends RepoFileDto> fromFileType) { // In contrast to CloudStore, Subshare does not rename the collision-file immediately. // Therefore, // this method is invoked when a type-collision was already handled somewhere else and we're // re-downloading // here. final RemoteRepository remoteRepository = transaction.getDao(RemoteRepositoryDao.class).getRemoteRepositoryOrFail(fromRepositoryId); final LastSyncToRemoteRepo lastSyncToRemoteRepo = transaction.getDao(LastSyncToRemoteRepoDao.class).getLastSyncToRemoteRepo(remoteRepository); final File localRoot = getLocalRepoManager().getLocalRoot(); final RepoFile repoFile = transaction.getDao(RepoFileDao.class).getRepoFile(localRoot, file); if (lastSyncToRemoteRepo != null && repoFile.getLocalRevision() <= lastSyncToRemoteRepo.getLocalRepositoryRevisionSynced()) { file.deleteRecursively(); return; } super.handleFileTypeCollision(transaction, fromRepositoryId, file, fromFileType); }
public void clearCryptoRepoFileDeleted(String path) { path = prefixPath(path); try (final LocalRepoTransaction transaction = getLocalRepoManager().beginWriteTransaction(); ) { getCryptree(transaction).clearCryptoRepoFileDeleted(path); transaction.commit(); } }
private void putPaddingMetaData(String path, SsNormalFileDto fromNormalFileDto) { path = prefixPath(path); // does a null-check assertNotNull("fromNormalFileDto", fromNormalFileDto); final File file = getFile(path); try (final LocalRepoTransaction transaction = getLocalRepoManager().beginWriteTransaction(); ) { final RepoFile repoFile = transaction .getDao(RepoFileDao.class) .getRepoFile(getLocalRepoManager().getLocalRoot(), file); if (!(repoFile instanceof NormalFile)) { throw new IllegalStateException( String.format( "RepoFile is not an instance of NormalFile! repoFile=%s file=%s", repoFile, file)); } final SsNormalFile normalFile = (SsNormalFile) repoFile; normalFile.setLengthWithPadding(fromNormalFileDto.getLengthWithPadding()); final Map<Long, SsFileChunk> offset2FileChunk = new HashMap<>(normalFile.getFileChunks().size()); for (FileChunk fc : normalFile.getFileChunks()) offset2FileChunk.put(fc.getOffset(), (SsFileChunk) fc); for (final FileChunkDto fcDto : fromNormalFileDto.getFileChunkDtos()) { SsFileChunkDto fileChunkDto = (SsFileChunkDto) fcDto; // If there is at least 1 byte of real data, the SHA1 (as well as the entire FileChunk // object) // is created from it and we don't need to store the FileChunk we received from the other // side. if (fileChunkDto.getLength() > 0) continue; boolean isNew = false; SsFileChunk fileChunk = offset2FileChunk.get(fileChunkDto.getOffset()); if (fileChunk == null) { isNew = true; fileChunk = (SsFileChunk) createObject(FileChunk.class); fileChunk.setNormalFile(normalFile); fileChunk.setOffset(fileChunkDto.getOffset()); } fileChunk.makeWritable(); fileChunk.setLength(fileChunkDto.getLength()); fileChunk.setLengthWithPadding(fileChunkDto.getLengthWithPadding()); fileChunk.setSha1(fileChunkDto.getSha1()); fileChunk.makeReadOnly(); if (isNew) normalFile.getFileChunks().add(fileChunk); } transaction.commit(); } }
protected void createAndPersistPreliminaryCollision( final LocalRepoManager localRepoManager, final File file, String localPath, Uid cryptoRepoFileId) { assertNotNull("localRepoManager", localRepoManager); if (localPath == null) assertNotNull("localPath/file", file); logger.debug( "createAndPersistPreliminaryCollision: localRoot='{}' localRepositoryId={} file='{}' localPath='{}' cryptoRepoFileId={}", localRepoManager.getLocalRoot(), getRepositoryId(), (file == null ? "" : file.getAbsolutePath()), (localPath == null ? "" : localPath), cryptoRepoFileId); try (final LocalRepoTransaction tx = localRepoManager.beginWriteTransaction(); ) { if (localPath == null) localPath = '/' + localRepoManager .getLocalRoot() .relativize(file) .replace(FILE_SEPARATOR_CHAR, '/'); final PreliminaryCollisionDao pcDao = tx.getDao(PreliminaryCollisionDao.class); PreliminaryCollision preliminaryCollision = pcDao.getPreliminaryCollision(localPath); if (preliminaryCollision == null) { preliminaryCollision = new PreliminaryCollision(); preliminaryCollision.setPath(localPath); preliminaryCollision = pcDao.makePersistent(preliminaryCollision); } final CryptoRepoFileDao crfDao = tx.getDao(CryptoRepoFileDao.class); if (cryptoRepoFileId != null) { CryptoRepoFile cryptoRepoFile = crfDao.getCryptoRepoFileOrFail(cryptoRepoFileId); preliminaryCollision.setCryptoRepoFile(cryptoRepoFile); } else if (file != null) { final RepoFileDao rfDao = tx.getDao(RepoFileDao.class); final RepoFile repoFile = rfDao.getRepoFile(localRepoManager.getLocalRoot(), file); if (repoFile != null) { final CryptoRepoFile cryptoRepoFile = crfDao.getCryptoRepoFileOrFail(repoFile); preliminaryCollision.setCryptoRepoFile(cryptoRepoFile); } } tx.commit(); } catch (IOException x) { throw new RuntimeException(x); } }
private void deleteRepoFileRecursively( final LocalRepoTransaction transaction, final RepoFile repoFile) { final RepoFileDao repoFileDao = transaction.getDao(RepoFileDao.class); for (final RepoFile childRepoFile : repoFileDao.getChildRepoFiles(repoFile)) deleteRepoFileRecursively(transaction, childRepoFile); repoFileDao.deletePersistent(repoFile); }
@Override protected void assertNoDeleteModificationCollision( LocalRepoTransaction transaction, UUID fromRepositoryId, final String path) throws CollisionException { // super.assertNoDeleteModificationCollision(transaction, fromRepositoryId, path); // // DeleteModification is *NOT* used by Subshare! final Uid cryptoRepoFileId = getCryptree(transaction).getCryptoRepoFileId(path); if (cryptoRepoFileId == null) return; final PreliminaryDeletionDao pdDao = transaction.getDao(PreliminaryDeletionDao.class); final CryptoRepoFile cryptoRepoFile = transaction.getDao(CryptoRepoFileDao.class).getCryptoRepoFileOrFail(cryptoRepoFileId); CryptoRepoFile crf = cryptoRepoFile; while (crf != null) { final String candidateLocalPath = crf.getLocalPathOrFail(); final PreliminaryDeletion preliminaryDeletion = pdDao.getPreliminaryDeletion(crf); if (crf.getDeleted() != null || preliminaryDeletion != null) { transaction.addPostCloseListener( new LocalRepoTransactionPostCloseAdapter() { @Override public void postRollback(LocalRepoTransactionPostCloseEvent event) { createAndPersistPreliminaryCollision( event.getLocalRepoManager(), null, path, cryptoRepoFileId); } @Override public void postCommit(LocalRepoTransactionPostCloseEvent event) { throw new IllegalStateException("Commit is not allowed, anymore!"); } }); throw new DeleteModificationCollisionException( String.format( "The associated CryptoRepoFile or one of its parents is marked as deleted! repositoryId=%s path='%s' deletedPath='%s'", fromRepositoryId, path, candidateLocalPath)); } crf = crf.getParent(); } }
@Override protected RepoFile syncRepoFile(final LocalRepoTransaction transaction, final File file) { assertNotNull("transaction", transaction); assertNotNull("file", file); final File localRoot = getLocalRepoManager().getLocalRoot(); final RepoFileDao rfDao = transaction.getDao(RepoFileDao.class); RepoFile repoFile = rfDao.getRepoFile(localRoot, file); // If the type changed, we must delete the RepoFile here before invoking the super-method, // because this would otherwise cause an invocation of Cryptree.preDelete(...) causing // the actual file to be deleted. if (repoFile != null && !LocalRepoSync.create(transaction).isRepoFileTypeCorrect(repoFile, file)) { rfDao.deletePersistent(repoFile); repoFile = null; transaction.flush(); } repoFile = super.syncRepoFile(transaction, file); return repoFile; }
@Override public void delete(String path) { if (isMetaOnly()) { path = prefixPath(path); final File localRoot = getLocalRepoManager().getLocalRoot(); try (final LocalRepoTransaction transaction = getLocalRepoManager().beginWriteTransaction(); ) { final RepoFileDao repoFileDao = transaction.getDao(RepoFileDao.class); final File file = getFile(path); final RepoFile repoFile = repoFileDao.getRepoFile(localRoot, file); if (repoFile != null) deleteRepoFileRecursively(transaction, repoFile); transaction.commit(); } } else { try { super.delete(path); } catch (CollisionException x) { clearCryptoRepoFileDeleted(path); throw x; } } }
private boolean isMetaOnly() { if (metaOnly == null) { // final Iterator<UUID> repoIdIt = // getLocalRepoManager().getRemoteRepositoryId2RemoteRootMap().keySet().iterator(); // if (! repoIdIt.hasNext()) // throw new IllegalStateException("There is no remote-repository!"); // // final UUID serverRepositoryId = repoIdIt.next(); try (final LocalRepoTransaction transaction = getLocalRepoManager().beginReadTransaction(); ) { final LocalRepoStorage lrs = LocalRepoStorageFactoryRegistry.getInstance() .getLocalRepoStorageFactoryOrFail() .getLocalRepoStorageOrCreate(transaction); // final Cryptree cryptree = // CryptreeFactoryRegistry.getInstance().getCryptreeFactoryOrFail().getCryptreeOrCreate(transaction, serverRepositoryId); metaOnly = lrs.isMetaOnly(); transaction.commit(); } } return metaOnly; }
@Override protected File handleFileCollision( final LocalRepoTransaction transaction, final UUID fromRepositoryId, final File file) { transaction.addPostCloseListener( new LocalRepoTransactionPostCloseAdapter() { @Override public void postRollback(LocalRepoTransactionPostCloseEvent event) { createAndPersistPreliminaryCollision(event.getLocalRepoManager(), file, null, null); } @Override public void postCommit(LocalRepoTransactionPostCloseEvent event) { throw new IllegalStateException("Commit is not allowed, anymore!"); } }); throw new CollisionException(); }