All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.lithium.flow.shell.sshj.SshjFiler Maven / Gradle / Ivy

/*
 * Copyright 2015 Lithium Technologies, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.lithium.flow.shell.sshj;

import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.stream.Collectors.toList;

import com.lithium.flow.filer.Filer;
import com.lithium.flow.filer.Record;
import com.lithium.flow.filer.RecordPath;
import com.lithium.flow.io.DataIo;
import com.lithium.flow.util.Unchecked;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;

import javax.annotation.Nonnull;

import net.schmizz.sshj.sftp.FileAttributes;
import net.schmizz.sshj.sftp.FileMode;
import net.schmizz.sshj.sftp.OpenMode;
import net.schmizz.sshj.sftp.RemoteFile;
import net.schmizz.sshj.sftp.RemoteResourceInfo;
import net.schmizz.sshj.sftp.SFTPClient;

/**
 * @author Matt Ayres
 */
public class SshjFiler implements Filer {
	private static final Set READ_MODES = EnumSet.of(OpenMode.READ);
	private static final Set WRITE_MODES = EnumSet.of(OpenMode.WRITE, OpenMode.CREAT, OpenMode.TRUNC);
	private static final Set APPEND_MODES = EnumSet.of(OpenMode.WRITE, OpenMode.CREAT, OpenMode.APPEND);
	private static final Set OPEN_WRITE_MODES = EnumSet.of(OpenMode.READ, OpenMode.WRITE, OpenMode.CREAT);

	private final URI uri;
	private final SFTPClient sftp;

	public SshjFiler(@Nonnull Sshj ssh, @Nonnull URI uri) throws IOException {
		this.uri = checkNotNull(uri);
		sftp = checkNotNull(ssh).newSFTPClient();
	}

	@Override
	@Nonnull
	public URI getUri() throws IOException {
		return uri;
	}

	@Override
	@Nonnull
	public List listRecords(@Nonnull String path) throws IOException {
		return getRecord(path).exists()
				? sftp.ls(path).stream().map(this::getRecord).collect(toList())
				: Collections.emptyList();
	}

	@Nonnull
	private Record getRecord(@Nonnull RemoteResourceInfo info) {
		if (info.getAttributes().getType() == FileMode.Type.SYMLINK) {
			return Unchecked.get(() -> getRecord(info.getPath()));
		}

		long time = info.getAttributes().getMtime() * 1000;
		long size = info.getAttributes().getSize();
		return new Record(uri, RecordPath.from(info.getParent(), info.getName()), time, size, info.isDirectory());
	}

	@Override
	@Nonnull
	public Record getRecord(@Nonnull String path) throws IOException {
		try {
			FileAttributes attributes = sftp.stat(path);
			return new Record(uri, RecordPath.from(path), attributes.getMtime() * 1000,
					attributes.getSize(), attributes.getMode().getType() == FileMode.Type.DIRECTORY);
		} catch (IOException e) {
			return Record.noFile(uri, path);
		}
	}

	@Override
	@Nonnull
	public InputStream readFile(@Nonnull String path) throws IOException {
		RemoteFile remoteFile = sftp.open(path, READ_MODES);
		return remoteFile.new ReadAheadRemoteFileInputStream(16);
	}

	@Override
	@Nonnull
	public OutputStream writeFile(@Nonnull String path) throws IOException {
		RemoteFile remoteFile = sftp.open(path, WRITE_MODES);
		return remoteFile.new RemoteFileOutputStream(0, 16);
	}

	@Override
	@Nonnull
	public OutputStream appendFile(@Nonnull String path) throws IOException {
		RemoteFile remoteFile = sftp.open(path, APPEND_MODES);
		return remoteFile.new RemoteFileOutputStream(remoteFile.length(), 16);
	}

	@Override
	@Nonnull
	public DataIo openFile(@Nonnull String path, boolean write) throws IOException {
		return new SshjDataIo(sftp.open(path, write ? OPEN_WRITE_MODES : READ_MODES));
	}

	@Override
	public void setFileTime(@Nonnull String path, long time) throws IOException {
		sftp.setattr(path, new FileAttributes.Builder().withAtimeMtime(time / 1000, time / 1000).build());
	}

	@Override
	public void deleteFile(@Nonnull String path) throws IOException {
		sftp.rm(path);
	}

	@Override
	public void renameFile(@Nonnull String oldPath, @Nonnull String newPath) throws IOException {
		sftp.rename(oldPath, newPath);
	}

	@Override
	public void createDirs(@Nonnull String path) throws IOException {
		synchronized (sftp) {
			sftp.mkdirs(path);
		}
	}

	@Override
	public void close() throws IOException {
		sftp.close();
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy