private OverthereFile createConnectionTemporaryDirectory() { OverthereFile temporaryDirectory = getFile(temporaryDirectoryPath); Random r = new Random(); DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd'T'HHmmssSSS"); String prefix = "overthere-" + dateFormat.format(new Date()); String infix = ""; String suffix = ".tmp"; for (int i = 0; i < temporaryFileCreationRetries; i++) { OverthereFile tempDir = getFileForTempFile(temporaryDirectory, prefix + infix + suffix); if (!tempDir.exists()) { tempDir.mkdir(); logger.info("Created connection temporary directory {}", tempDir); return tempDir; } infix = "-" + Long.toString(Math.abs(r.nextLong())); } throw new RuntimeIOException("Cannot create connection temporary directory on " + this); }
@Override public Iterable<? extends LocalSourceFile> getChildren(LocalFileFilter filter) throws IOException { List<LocalSourceFile> files = newArrayList(); for (OverthereFile each : f.listFiles()) { files.add(new OverthereFileLocalSourceFile(each)); } return files; }
@Override protected void copyFrom(OverthereFile source) { logger.debug("Copying file or directory {} to {}", source, this); SCPUploadClient uploadClient = connection.getSshClient().newSCPFileTransfer().newSCPUploadClient(); try { if (source.isDirectory() && this.exists()) { for (OverthereFile sourceFile : source.listFiles()) { uploadClient.copy(new OverthereFileLocalSourceFile(sourceFile), getPath()); } } else { uploadClient.copy(new OverthereFileLocalSourceFile(source), getPath()); } } catch (IOException e) { throw new RuntimeIOException("Cannot copy " + source + " to " + this, e); } }
/** * Creates a reference to a temporary file on the host. This file has a unique name and will be * automatically removed when this connection is closed. <b>N.B.:</b> The file is not actually * created until a put method is invoked. * * @param prefix the prefix string to be used in generating the file's name; must be at least * three characters long * @param suffix the suffix string to be used in generating the file's name; may be <code>null * </code>, in which case the suffix ".tmp" will be used * @return a reference to the temporary file on the host */ @Override public final OverthereFile getTempFile(String prefix, String suffix) throws RuntimeIOException { if (prefix == null) throw new NullPointerException("prefix is null"); if (suffix == null) { suffix = ".tmp"; } Random r = new Random(); String infix = ""; for (int i = 0; i < temporaryFileCreationRetries; i++) { OverthereFile f = getFileForTempFile(getConnectionTemporaryDirectory(), prefix + infix + suffix); if (!f.exists()) { logger.debug("Created temporary file {}", f); return f; } infix = "-" + Long.toString(Math.abs(r.nextLong())); } throw new RuntimeIOException("Cannot generate a unique temporary file name on " + this); }
/** * Main recursive method to examine the directory hierarchy. * * @param directory the directory to examine, not null * @param depth the directory level (starting directory = 0) * @throws IOException if an I/O Error occurs */ private void walk(OverthereFile directory, int depth) throws IOException { if (handleDirectory(directory, depth)) { handleDirectoryStart(directory, depth); int childDepth = depth + 1; if (depthLimit < 0 || childDepth <= depthLimit) { List<OverthereFile> childFiles = listFiles(directory); if (childFiles == null) { handleRestricted(directory, childDepth); } else { for (OverthereFile childFile : childFiles) { if (childFile.isDirectory()) { walk(childFile, childDepth); } else { handleFile(childFile, childDepth); } } } } handleDirectoryEnd(directory, depth); } }
private void deleteConnectionTemporaryDirectory() { if (connectionTemporaryDirectory != null) { try { logger.info("Deleting connection temporary directory {}", connectionTemporaryDirectory); connectionTemporaryDirectory.deleteRecursively(); } catch (RuntimeException exc) { logger.warn( "Got exception while deleting connection temporary directory {}. Ignoring it.", connectionTemporaryDirectory, exc); } } }
public static void main(String[] args) throws IOException { ConnectionOptions options = new ConnectionOptions(); options.set(ADDRESS, "unix-box"); options.set(USERNAME, "demo"); options.set(PASSWORD, "secret"); options.set(OPERATING_SYSTEM, UNIX); options.set(CONNECTION_TYPE, SFTP); OverthereConnection connection = Overthere.getConnection("ssh", options); try { connection.execute(CmdLine.build("cp", "-r", "/var/log/apt", "/tmp/logs1")); OverthereFile logs1 = connection.getFile("/tmp/logs1"); OverthereFile logs2 = connection.getFile("/tmp/logs2"); logs2.delete(); System.err.println("Exists #1: " + logs1.exists()); System.err.println("Exists #2: " + logs2.exists()); logs1.renameTo(logs2); System.err.println("Exists #1: " + logs1.exists()); System.err.println("Exists #2: " + logs2.exists()); logs2.copyTo(logs1); System.err.println("Exists #1: " + logs1.exists()); System.err.println("Exists #2: " + logs2.exists()); logs1.deleteRecursively(); logs2.deleteRecursively(); System.err.println("Exists #1: " + logs1.exists()); System.err.println("Exists #2: " + logs2.exists()); } finally { connection.close(); } }
@Override public boolean isDirectory() { return f.isDirectory(); }
@Override public boolean isFile() { return f.isFile(); }
@Override public int getPermissions() throws IOException { return f.isDirectory() ? 0755 : 0644; }
@Override public InputStream getInputStream() throws IOException { return f.getInputStream(); }
@Override public long getLength() { return f.length(); }
@Override public String getName() { return f.getName(); }
/** * Lists the files in the directory. * * @param directory in which to list files. * @return all the files in the directory as filtering. */ protected List<OverthereFile> listFiles(OverthereFile directory) { return directory.listFiles(); }
@Test public void shouldCreateWriteReadAndRemoveTemporaryFile() throws IOException { final String prefix = "prefix"; final String suffix = "suffix"; final byte[] contents = ("Contents of the temporary file created at " + System.currentTimeMillis() + "ms since the epoch") .getBytes(); OverthereFile tempFile = connection.getTempFile(prefix, suffix); assertThat( "Expected a non-null return value from HostConnection.getTempFile()", tempFile, notNullValue()); assertThat( "Expected name of temporary file to start with the prefix", tempFile.getName(), startsWith(prefix)); assertThat( "Expected name of temporary file to end with the suffix", tempFile.getName(), endsWith(suffix)); assertThat("Expected temporary file to not exist yet", tempFile.exists(), equalTo(false)); OutputStream out = tempFile.getOutputStream(); try { out.write(contents); } finally { closeQuietly(out); } assertThat( "Expected temporary file to exist after writing to it", tempFile.exists(), equalTo(true)); assertThat( "Expected temporary file to not be a directory", tempFile.isDirectory(), equalTo(false)); assertThat( "Expected temporary file to have the size of the contents written to it", tempFile.length(), equalTo((long) contents.length)); assertThat("Expected temporary file to be readable", tempFile.canRead(), equalTo(true)); assertThat("Expected temporary file to be writeable", tempFile.canWrite(), equalTo(true)); // Windows systems don't support the concept of checking for executability if (connection.getHostOperatingSystem() == OperatingSystemFamily.UNIX) { assertFalse("Expected temporary file to not be executable", tempFile.canExecute()); } DataInputStream in = new DataInputStream(tempFile.getInputStream()); try { final byte[] contentsRead = new byte[contents.length]; in.readFully(contentsRead); assertThat( "Expected input stream to be exhausted after reading the full contents", in.available(), equalTo(0)); assertThat( "Expected contents in temporary file to be identical to data written into it", contentsRead, equalTo(contents)); } finally { closeQuietly(in); } tempFile.delete(); assertThat("Expected temporary file to no longer exist", tempFile.exists(), equalTo(false)); }
@Test public void shouldCreatePopulateListAndRemoveTemporaryDirectory() { final String prefix = "prefix"; final String suffix = "suffix"; OverthereFile tempDir = connection.getTempFile(prefix, suffix); assertThat( "Expected a non-null return value from HostConnection.getTempFile()", tempDir, notNullValue()); assertThat( "Expected name of temporary file to start with the prefix", tempDir.getName(), startsWith(prefix)); assertThat( "Expected name of temporary file to end with the suffix", tempDir.getName(), endsWith(suffix)); assertThat("Expected temporary file to not exist yet", tempDir.exists(), equalTo(false)); tempDir.mkdir(); assertThat( "Expected temporary directory to exist after creating it", tempDir.exists(), equalTo(true)); assertThat( "Expected temporary directory to be a directory", tempDir.isDirectory(), equalTo(true)); OverthereFile anotherTempDir = connection.getTempFile(prefix, suffix); assertThat( "Expected temporary directories created with identical prefix and suffix to still be different", tempDir.getPath(), not(equalTo(anotherTempDir.getPath()))); OverthereFile nested1 = tempDir.getFile("nested1"); OverthereFile nested2 = nested1.getFile("nested2"); OverthereFile nested3 = nested2.getFile("nested3"); assertThat("Expected deeply nested directory to not exist", nested3.exists(), equalTo(false)); try { nested3.mkdir(); fail("Expected not to be able to create a deeply nested directory in one go"); } catch (RuntimeIOException expected1) { } assertThat( "Expected deeply nested directory to still not exist", nested3.exists(), equalTo(false)); nested3.mkdirs(); assertThat( "Expected deeply nested directory to exist after invoking mkdirs on it", nested3.exists(), equalTo(true)); final byte[] contents = ("Contents of the temporary file created at " + System.currentTimeMillis() + "ms since the epoch") .getBytes(); OverthereFile regularFile = tempDir.getFile("somefile.txt"); OverthereUtils.write(contents, regularFile); List<OverthereFile> dirContents = tempDir.listFiles(); assertThat("Expected directory to contain two entries", dirContents.size(), equalTo(2)); assertThat( "Expected directory to contain parent of deeply nested directory", dirContents.contains(nested1), equalTo(true)); assertThat( "Expected directory to contain regular file that was just created", dirContents.contains(regularFile), equalTo(true)); try { nested1.delete(); } catch (RuntimeIOException expected2) { } nested1.deleteRecursively(); assertThat( "Expected parent of deeply nested directory to have been removed recursively", nested1.exists(), equalTo(false)); regularFile.delete(); tempDir.delete(); assertThat( "Expected temporary directory to not exist after removing it when it was empty", tempDir.exists(), equalTo(false)); }