public void setRemoteLocation(RemoteFile remoteFile) { remoteLocation = remoteFile.getName(); }
public RemoteFile getRemoteFile() throws StorageException { return RemoteFile.createRemoteFile(remoteLocation); }
@Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (!(obj instanceof DatabaseRemoteFile)) { return false; } DatabaseRemoteFile other = (DatabaseRemoteFile) obj; if (clientName == null) { if (other.clientName != null) { return false; } } else if (!clientName.equals(other.clientName)) { return false; } if (clientVersion != other.clientVersion) { return false; } return true; }
logger.log(Level.INFO, "File {0} not found, checking if it is being deleted ...", remoteFile.getName()); if (action.getType().equals(ActionType.DELETE) && action.getRemoteFile().equals(remoteFile)) { tempRemoteFile = action.getTempRemoteFile(); break; new Object[] { remoteFile.getName(), tempRemoteFile.getName() }); logger.log(Level.WARNING, "-> File {0} does not exist and is not in any transaction. Throwing exception.", remoteFile.getName()); throw new StorageFileNotFoundException("File " + remoteFile.getName() + " does not exist and is not in any transaction");
private boolean removeFolder(RemoteFile remoteFile) throws StorageException { PathAwareRemoteFileAttributes pathAwareRemoteFileAttributes = remoteFile.getAttributes(PathAwareRemoteFileAttributes.class); boolean notAPathAwareRemoteFile = pathAwareRemoteFileAttributes == null || !pathAwareRemoteFileAttributes.hasPath(); if (notAPathAwareRemoteFile) { return true; } else { String remoteFilePath = pathToString(Paths.get(underlyingTransferManager.getRemoteFilePath(remoteFile.getClass()), pathAwareRemoteFileAttributes.getPath())); logger.log(Level.INFO, "Remote file is path aware, cleaning empty folders at " + remoteFilePath); boolean success = removeFolder(remoteFilePath); return success; } }
@Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((clientName == null) ? 0 : clientName.hashCode()); result = prime * result + (int) (clientVersion ^ (clientVersion >>> 32)); return result; }
/** * Creates a new remote file by its name. The name is used by {@link TransferManager}s * to identify a file on the remote storage. * * <p>The constructor parses and validates the given name using the * {@link #validateName(String) validateName()} method. While <tt>RemoteFile</tt> has no name * pattern (and never throws an exception), sub-classes might. * * <p><b>Important:</b> Sub-classes must also implement a one-parameter constructor that takes a * <tt>String</tt> argument. This constructor is required by the {@link RemoteFileFactory}. * * @param name The name of the file (as it is identified by Syncany) * @throws StorageException If the name does not match the name pattern defined by the class.<br /> * <b>Note:</b> <tt>RemoteFile</tt> does never throw this exceptions, however, subclasses might. */ public RemoteFile(String name) throws StorageException { this.name = validateName(name); this.attributes = Maps.newHashMap(); }
private RemoteFile createPathAwareRemoteFile(RemoteFile remoteFile) throws StorageException { PathAwareRemoteFileAttributes pathAwareRemoteFileAttributes = new PathAwareRemoteFileAttributes(); remoteFile.setAttributes(pathAwareRemoteFileAttributes); if (isFolderizable(remoteFile.getClass())) { // If remote file is folderizable, i.e. an 'affected file', // get the sub-path for it String subPathId = getSubPathId(remoteFile); String subPath = getSubPath(subPathId); pathAwareRemoteFileAttributes.setPath(subPath); } return remoteFile; }
private boolean createFolder(RemoteFile remoteFile) throws StorageException { PathAwareRemoteFileAttributes pathAwareRemoteFileAttributes = remoteFile.getAttributes(PathAwareRemoteFileAttributes.class); boolean notAPathAwareRemoteFile = pathAwareRemoteFileAttributes == null || !pathAwareRemoteFileAttributes.hasPath(); if (notAPathAwareRemoteFile) { return true; } else { String remoteFilePath = pathToString(Paths.get(underlyingTransferManager.getRemoteFilePath(remoteFile.getClass()), pathAwareRemoteFileAttributes.getPath())); logger.log(Level.INFO, "Remote file is path aware, creating folder " + remoteFilePath); boolean success = pathAwareFeatureExtension.createPath(remoteFilePath); return success; } }
/** * Initializes a new randomly named temp file. * * @throws StorageException */ public TempRemoteFile(RemoteFile targetRemoteFile) throws StorageException { super(String.format(NAME_FORMAT, CipherUtil.createRandomAlphabeticString(5), targetRemoteFile.getName())); }
public TempRemoteFile getTempRemoteFile() { try { return RemoteFile.createRemoteFile(remoteTempLocation, TempRemoteFile.class); } catch (StorageException e) { logger.log(Level.INFO, "Invalid remote temporary filename: " + remoteTempLocation, e); return null; } }
private File getRemoteFile(RemoteFile remoteFile) { String rootPath = getRemoteFilePath(remoteFile.getClass()); return Paths.get(rootPath, remoteFile.getName()).toFile(); }
@Override protected String validateName(String name) throws StorageException { Matcher matcher = NAME_PATTERN.matcher(name); if (!matcher.matches()) { throw new StorageException(name + ": remote filename pattern does not match: " + NAME_PATTERN.pattern() + " expected."); } try { targetRemoteFile = RemoteFile.createRemoteFile(matcher.group(2)); } catch (Exception e) { throw new StorageException(name + ": remote filename pattern does not match: " + NAME_PATTERN.pattern() + " expected."); } return name; } }
/** * Returns the subpath identifier for this file. For {@link MultichunkRemoteFile}s, this is the * hex string of the multichunk identifier. For all other files, this is the 128-bit murmur3 hash * of the full filename (fast algorithm!). */ private String getSubPathId(RemoteFile remoteFile) { if (remoteFile.getClass() == MultichunkRemoteFile.class) { return StringUtil.toHex(((MultichunkRemoteFile) remoteFile).getMultiChunkId()); } else { return StringUtil.toHex(Hashing.murmur3_128().hashString(remoteFile.getName(), Charsets.UTF_8).asBytes()); } }
private <T extends RemoteFile> void list(String remoteFilePath, Map<String, T> remoteFiles, Class<T> remoteFileClass) throws StorageException { logger.log(Level.INFO, "Listing folder for files matching " + remoteFileClass.getSimpleName() + ": " + remoteFilePath); Map<String, FileType> folderList = pathAwareFeatureExtension.listFolder(remoteFilePath); for (Map.Entry<String, FileType> folderListEntry : folderList.entrySet()) { String fileName = folderListEntry.getKey(); FileType fileType = folderListEntry.getValue(); if (fileType == FileType.FILE) { try { remoteFiles.put(fileName, RemoteFile.createRemoteFile(fileName, remoteFileClass)); logger.log(Level.INFO, "- File: " + fileName); } catch (StorageException e) { // We don't care and ignore non-matching files! } } else if (fileType == FileType.FOLDER) { logger.log(Level.INFO, "- Folder: " + fileName); String newRemoteFilePath = remoteFilePath + folderSeparator + fileName; list(newRemoteFilePath, remoteFiles, remoteFileClass); } } }
if (deletedFile.getClass().equals(remoteFileClass)) { T concreteDeletedFile = remoteFileClass.cast(deletedFile); filteredFiles.put(concreteDeletedFile.getName(), concreteDeletedFile);
@Override public <T extends RemoteFile> Map<String, T> list(Class<T> remoteFileClass) throws StorageException { connect(); Path folder = Paths.get(getRemoteFilePath(remoteFileClass)); Map<String, T> files = Maps.newHashMap(); try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(folder)) { for (Path path : directoryStream) { try { T remoteFile = RemoteFile.createRemoteFile(path.getFileName().toString(), remoteFileClass); files.put(path.getFileName().toString(), remoteFile); } catch (StorageException e) { logger.log(Level.INFO, "Cannot create instance of " + remoteFileClass.getSimpleName() + " for file " + path + "; maybe invalid file name pattern. Ignoring file."); } } } catch (IOException e) { logger.log(Level.SEVERE, "Unable to list directory", e); } return files; }
@Override public void printResults(OperationResult operationResult) { LsRemoteOperationResult concreteOperationResult = (LsRemoteOperationResult) operationResult; List<DatabaseRemoteFile> remoteStatus = concreteOperationResult.getUnknownRemoteDatabases(); if (remoteStatus.size() > 0) { for (RemoteFile unknownRemoteFile : remoteStatus) { out.println("? "+unknownRemoteFile.getName()); } } else { out.println("No remote changes."); } }
/** * Creates a remote file based on a name and derives the class name using the * file name. * * <p>The name must match the corresponding name pattern (nameprefix-...), and * the derived class can either be <tt>RemoteFile</tt>, or a sub-class thereof. * * @param name The name of the remote file * @return Returns a new object of the given class */ @SuppressWarnings("unchecked") public static <T extends RemoteFile> T createRemoteFile(String name) throws StorageException { String prefix = name.contains("-") ? name.substring(0, name.indexOf('-')) : name; String camelCasePrefix = StringUtil.toCamelCase(prefix); try { Class<T> remoteFileClass = (Class<T>) Class.forName(REMOTE_FILE_PACKAGE + "." + camelCasePrefix + REMOTE_FILE_SUFFIX); return createRemoteFile(name, remoteFileClass); } catch (ClassNotFoundException | StorageException e) { logger.log(Level.INFO, "Invalid filename for remote file " + name); throw new StorageException("Invalid filename for remote file " + name); } }
@Override public void move(RemoteFile sourceFile, RemoteFile targetFile) throws StorageException { String operationType = "move"; String operationDescription = "move(" + sourceFile.getName() + "," + targetFile.getName() + ")"; if (isNextOperationSuccessful(operationType, operationDescription)) { super.move(sourceFile, targetFile); } else { throw new StorageException("Operation failed: " + operationDescription); } }