Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/com.windriver.tcf.rse.ui/src/com/windriver/tcf/rse/ui/TCFFileService.java')
-rw-r--r--plugins/com.windriver.tcf.rse.ui/src/com/windriver/tcf/rse/ui/TCFFileService.java643
1 files changed, 643 insertions, 0 deletions
diff --git a/plugins/com.windriver.tcf.rse.ui/src/com/windriver/tcf/rse/ui/TCFFileService.java b/plugins/com.windriver.tcf.rse.ui/src/com/windriver/tcf/rse/ui/TCFFileService.java
new file mode 100644
index 000000000..6eb030f61
--- /dev/null
+++ b/plugins/com.windriver.tcf.rse.ui/src/com/windriver/tcf/rse/ui/TCFFileService.java
@@ -0,0 +1,643 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package com.windriver.tcf.rse.ui;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.rse.core.model.IHost;
+import org.eclipse.rse.services.clientserver.FileTypeMatcher;
+import org.eclipse.rse.services.clientserver.IMatcher;
+import org.eclipse.rse.services.clientserver.NamePatternMatcher;
+import org.eclipse.rse.services.clientserver.messages.IndicatorException;
+import org.eclipse.rse.services.clientserver.messages.SystemMessage;
+import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
+import org.eclipse.rse.services.files.AbstractFileService;
+import org.eclipse.rse.services.files.IHostFile;
+
+import com.windriver.tcf.api.protocol.IToken;
+import com.windriver.tcf.api.protocol.Protocol;
+import com.windriver.tcf.api.services.IFileSystem;
+import com.windriver.tcf.api.services.IFileSystem.DirEntry;
+import com.windriver.tcf.api.services.IFileSystem.FileAttrs;
+import com.windriver.tcf.api.services.IFileSystem.FileSystemException;
+import com.windriver.tcf.api.services.IFileSystem.IFileHandle;
+import com.windriver.tcf.api.util.TCFFileInputStream;
+import com.windriver.tcf.api.util.TCFFileOutputStream;
+
+public class TCFFileService extends AbstractFileService implements ITCFFileService {
+
+ private final TCFConnectorService connector;
+
+ private UserInfo user_info;
+
+ private static final class UserInfo {
+ final int r_uid;
+ final int e_uid;
+ final int r_gid;
+ final int e_gid;
+ final String home;
+
+ final Throwable error;
+
+ UserInfo(int r_uid, int e_uid, int r_gid, int e_gid, String home) {
+ this.r_uid = r_uid;
+ this.e_uid = e_uid;
+ this.r_gid = r_gid;
+ this.e_gid = e_gid;
+ this.home = home;
+ error = null;
+ }
+
+ UserInfo(Throwable error) {
+ this.error = error;
+ r_uid = -1;
+ e_uid = -1;
+ r_gid = -1;
+ e_gid = -1;
+ home = null;
+ }
+ }
+
+ public TCFFileService(IHost host) {
+ connector = (TCFConnectorService)TCFConnectorServiceManager
+ .getInstance().getConnectorService(host, ITCFSubSystem.class);
+ }
+
+ public String getDescription() {
+ return "The TCF File Service uses the Target Communication Framework to provide service" +
+ "for the Files subsystem. It requires a TCF agent to be running on the remote machine.";
+ }
+
+ public SystemMessage getMessage(String id) {
+ try {
+ return new SystemMessage("TCF", "C", "0001",
+ SystemMessage.ERROR, id, "");
+ }
+ catch (IndicatorException e) {
+ throw new Error(e);
+ }
+ }
+
+ public SystemMessage getMessage(Throwable x) {
+ try {
+ return new SystemMessage("TCF", "C", "0002",
+ SystemMessage.ERROR, x.getClass().getName(), x.getMessage());
+ }
+ catch (IndicatorException e) {
+ throw new Error(e);
+ }
+ }
+
+ public String getName() {
+ return "TCF File Service";
+ }
+
+ public void initService(IProgressMonitor monitor) {
+ }
+
+ public void uninitService(IProgressMonitor monitor) {
+ }
+
+ private String toRemotePath(String parent, String name) throws SystemMessageException {
+ assert !Protocol.isDispatchThread();
+ String s = null;
+ if (parent != null) parent = parent.replace('\\', '/');
+ if (name != null) name = name.replace('\\', '/');
+ if (parent == null || parent.length() == 0) s = name;
+ else if (name == null || name.equals(".")) s = parent;
+ else if (name.equals("/")) s = parent;
+ else if (parent.endsWith("/")) s = parent + name;
+ else s = parent + '/' + name;
+ if (s.startsWith("./") || s.equals(".")) {
+ UserInfo ui = getUserInfo();
+ if (ui.error != null) throw new SystemMessageException(getMessage(ui.error));
+ s = ui.home.replace('\\', '/') + s.substring(1);
+ }
+ while (s.endsWith("/.")) s = s.substring(0, s.length() - 2);
+ return s;
+ }
+
+ public boolean copy(String srcParent,
+ String srcName, String tgtParent, String tgtName, IProgressMonitor monitor)
+ throws SystemMessageException {
+ final String src = toRemotePath(srcParent, srcName);
+ final String tgt = toRemotePath(tgtParent, tgtName);
+ return new TCFRSETask<Boolean>() {
+ public void run() {
+ IFileSystem fs = connector.getFileSystemService();
+ fs.copy(src, tgt, false, false, new IFileSystem.DoneCopy() {
+ public void doneCopy(IToken token, FileSystemException error) {
+ if (error != null) error(error);
+ else done(true);
+ }
+ });
+ }
+ }.getS(monitor, "Copy: " + srcName);
+ }
+
+ public boolean copyBatch(String[] srcParents,
+ String[] srcNames, String tgtParent, IProgressMonitor monitor) throws SystemMessageException {
+ for (int i = 0; i < srcParents.length; i++) {
+ if (!copy(srcParents[i], srcNames[i], tgtParent, srcNames[i], monitor)) return false;
+ }
+ return true;
+ }
+
+ public IHostFile createFile(String parent,
+ String name, IProgressMonitor monitor) throws SystemMessageException {
+ try {
+ getOutputStream(parent, name, true, monitor).close();
+ return getFile(parent, name, monitor);
+ }
+ catch (IOException e) {
+ throw new SystemMessageException(getMessage(e));
+ }
+ }
+
+ public IHostFile createFolder(final String parent, final String name, IProgressMonitor monitor) throws SystemMessageException {
+ final String path = toRemotePath(parent, name);
+ return new TCFRSETask<IHostFile>() {
+ public void run() {
+ final IFileSystem fs = connector.getFileSystemService();
+ fs.mkdir(path, null, new IFileSystem.DoneMkDir() {
+ public void doneMkDir(IToken token, FileSystemException error) {
+ if (error != null) {
+ error(error);
+ return;
+ }
+ fs.stat(path, new IFileSystem.DoneStat() {
+ public void doneStat(IToken token,
+ FileSystemException error, FileAttrs attrs) {
+ if (error != null) error(error);
+ else done(new TCFFileResource(TCFFileService.this,
+ path, null, attrs, false));
+ }
+ });
+ }
+ });
+ }
+ }.getS(monitor, "Create folder");
+ }
+
+ public boolean delete(String parent,
+ String name, IProgressMonitor monitor) throws SystemMessageException {
+ final String path = toRemotePath(parent, name);
+ return new TCFRSETask<Boolean>() {
+ public void run() {
+ final IFileSystem fs = connector.getFileSystemService();
+ fs.stat(path, new IFileSystem.DoneStat() {
+ public void doneStat(IToken token,
+ FileSystemException error, FileAttrs attrs) {
+ if (error != null) {
+ error(error);
+ return;
+ }
+ IFileSystem.DoneRemove done = new IFileSystem.DoneRemove() {
+ public void doneRemove(IToken token, FileSystemException error) {
+ if (error != null) {
+ error(error);
+ return;
+ }
+ done(true);
+ }
+ };
+ if (attrs.isDirectory()) {
+ fs.rmdir(path, done);
+ }
+ else {
+ fs.remove(path, done);
+ }
+ }
+ });
+ }
+ }.getS(monitor, "Delete");
+ }
+
+ public boolean deleteBatch(String[] remoteParents, String[] fileNames, IProgressMonitor monitor)
+ throws SystemMessageException {
+ for (int i = 0; i < remoteParents.length; i++) {
+ delete(remoteParents[i], fileNames[i], monitor);
+ }
+ return true;
+ }
+
+ public boolean download(final String parent,
+ final String name, final File file, final boolean is_binary,
+ final String host_encoding, IProgressMonitor monitor) throws SystemMessageException {
+ monitor.beginTask("Download", 1);
+ try {
+ file.getParentFile().mkdirs();
+ InputStream inp = getInputStream(parent, name, is_binary, new NullProgressMonitor());
+ OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
+ copyStream(inp, out, is_binary, "UTF8", host_encoding);
+ return true;
+ }
+ catch (Throwable x) {
+ if (x instanceof SystemMessageException) throw (SystemMessageException)x;
+ throw new SystemMessageException(getMessage(x));
+ }
+ finally {
+ monitor.done();
+ }
+ }
+
+ public String getEncoding(IProgressMonitor monitor) throws SystemMessageException {
+ return "UTF8";
+ }
+
+ public IHostFile getFile(final String parent,
+ final String name, IProgressMonitor monitor) throws SystemMessageException {
+ final String path = toRemotePath(parent, name);
+ return new TCFRSETask<IHostFile>() {
+ public void run() {
+ IFileSystem fs = connector.getFileSystemService();
+ fs.stat(path, new IFileSystem.DoneStat() {
+ public void doneStat(IToken token,
+ FileSystemException error, FileAttrs attrs) {
+ if (error != null) {
+ if (error.getStatus() == IFileSystem.STATUS_NO_SUCH_FILE) {
+ done(new TCFFileResource(TCFFileService.this, path, null, null, false));
+ return;
+ }
+ error(error);
+ return;
+ }
+ done(new TCFFileResource(TCFFileService.this, path, null, attrs, false));
+ }
+ });
+ }
+ }.getS(monitor, "Stat");
+ }
+
+ protected IHostFile[] internalFetch(final String parent, final String filter, final int fileType, final IProgressMonitor monitor)
+ throws SystemMessageException {
+ final String path = toRemotePath(parent, null);
+ final boolean wantFiles = (fileType==FILE_TYPE_FILES_AND_FOLDERS || (fileType&FILE_TYPE_FILES)!=0);
+ final boolean wantFolders = (fileType==FILE_TYPE_FILES_AND_FOLDERS || (fileType%FILE_TYPE_FOLDERS)!=0);
+ return new TCFRSETask<IHostFile[]>() {
+ private IMatcher matcher = null;
+ public void run() {
+ if (filter == null) {
+ matcher = null;
+ }
+ else if (filter.endsWith(",")) { //$NON-NLS-1$
+ String[] types = filter.split(","); //$NON-NLS-1$
+ matcher = new FileTypeMatcher(types, true);
+ }
+ else {
+ matcher = new NamePatternMatcher(filter, true, true);
+ }
+ final List<TCFFileResource> results = new ArrayList<TCFFileResource>();
+ final IFileSystem fs = connector.getFileSystemService();
+ fs.opendir(path, new IFileSystem.DoneOpen() {
+ public void doneOpen(IToken token, FileSystemException error, final IFileHandle handle) {
+ if (error != null) {
+ error(error);
+ return;
+ }
+ fs.readdir(handle, new IFileSystem.DoneReadDir() {
+ public void doneReadDir(IToken token,
+ FileSystemException error, DirEntry[] entries, boolean eof) {
+ if (error != null) {
+ error(error);
+ return;
+ }
+ for (DirEntry e : entries) {
+ if (e.attrs == null) {
+ // Attrs are not available if, for example,
+ // the entry is a broken symbolic link
+ }
+ else if (e.attrs.isDirectory()) {
+ //dont filter folder names if getting both folders and files
+ if (wantFolders && (matcher==null || fileType==FILE_TYPE_FILES_AND_FOLDERS || matcher.matches(e.filename))) {
+ results.add(new TCFFileResource(TCFFileService.this,
+ path, e.filename, e.attrs, false));
+ }
+ }
+ else if (e.attrs.isFile()) {
+ if (wantFiles && (matcher == null || matcher.matches(e.filename))) {
+ results.add(new TCFFileResource(TCFFileService.this,
+ path, e.filename, e.attrs, false));
+ }
+ }
+ }
+ if (eof) {
+ fs.close(handle, new IFileSystem.DoneClose() {
+ public void doneClose(IToken token, FileSystemException error) {
+ if (error != null) {
+ error(error);
+ return;
+ }
+ done(results.toArray(new TCFFileResource[results.size()]));
+ }
+ });
+ }
+ else {
+ fs.readdir(handle, this);
+ }
+ }
+ });
+ }
+ });
+ }
+ }.getS(monitor, "Get files and folders");
+ }
+
+ public InputStream getInputStream(final String parent, final String name, boolean isBinary, IProgressMonitor monitor)
+ throws SystemMessageException {
+ final String path = toRemotePath(parent, name);
+ final IFileHandle handle = new TCFRSETask<IFileHandle>() {
+ public void run() {
+ IFileSystem fs = connector.getFileSystemService();
+ fs.open(path, IFileSystem.O_READ, null, new IFileSystem.DoneOpen() {
+ public void doneOpen(IToken token, FileSystemException error, IFileHandle handle) {
+ if (error != null) error(error);
+ else done(handle);
+ }
+ });
+ }
+ }.getS(monitor, "Get input stream");
+ return new TCFFileInputStream(handle);
+ }
+
+ public OutputStream getOutputStream(final String parent, final String name, boolean isBinary, IProgressMonitor monitor)
+ throws SystemMessageException {
+ final String path = toRemotePath(parent, name);
+ final IFileHandle handle = new TCFRSETask<IFileHandle>() {
+ public void run() {
+ IFileSystem fs = connector.getFileSystemService();
+ int flags = IFileSystem.O_WRITE | IFileSystem.O_CREAT | IFileSystem.O_TRUNC;
+ fs.open(path, flags, null, new IFileSystem.DoneOpen() {
+ public void doneOpen(IToken token, FileSystemException error, IFileHandle handle) {
+ if (error != null) error(error);
+ else done(handle);
+ }
+ });
+ }
+ }.getS(monitor, "Get output stream");
+ return new TCFFileOutputStream(handle);
+ }
+
+ public IHostFile[] getRoots(IProgressMonitor monitor) throws SystemMessageException {
+ return new TCFRSETask<IHostFile[]>() {
+ public void run() {
+ IFileSystem fs = connector.getFileSystemService();
+ fs.roots(new IFileSystem.DoneRoots() {
+ public void doneRoots(IToken token, FileSystemException error, DirEntry[] entries) {
+ if (error != null) {
+ error(error);
+ return;
+ }
+ List<TCFFileResource> l = new ArrayList<TCFFileResource>();
+ for (DirEntry e : entries) {
+ if (e.attrs == null) continue;
+ l.add(new TCFFileResource(TCFFileService.this, "", e.filename, e.attrs, true));
+ }
+ done(l.toArray(new IHostFile[l.size()]));
+ }
+ });
+ }
+ }.getS(monitor, "Get roots");
+ }
+
+ public IHostFile getUserHome() {
+ UserInfo ui = getUserInfo();
+ try {
+ return getFile(ui.home, ".", new NullProgressMonitor());
+ }
+ catch (SystemMessageException e) {
+ throw new Error(e);
+ }
+ }
+
+ public boolean isCaseSensitive() {
+ return true;
+ }
+
+ public boolean move(final String srcParent,
+ final String srcName, final String tgtParent, final String tgtName, IProgressMonitor monitor)
+ throws SystemMessageException {
+ final String src_path = toRemotePath(srcParent, srcName);
+ final String tgt_path = toRemotePath(tgtParent, tgtName);
+ return new TCFRSETask<Boolean>() {
+ public void run() {
+ IFileSystem fs = connector.getFileSystemService();
+ fs.rename(src_path, tgt_path, new IFileSystem.DoneRename() {
+ public void doneRename(IToken token, FileSystemException error) {
+ if (error != null) error(error);
+ else done(true);
+ }
+ });
+ }
+ }.getS(monitor, "Move");
+ }
+
+ public boolean rename(String remoteParent,
+ String oldName, String newName, IProgressMonitor monitor) throws SystemMessageException {
+ return move(remoteParent, oldName, remoteParent, newName, monitor);
+ }
+
+ public boolean rename(String remoteParent,
+ String oldName, String newName, IHostFile oldFile, IProgressMonitor monitor)
+ throws SystemMessageException {
+ boolean b = move(remoteParent, oldName, remoteParent, newName, monitor);
+ if (b) oldFile.renameTo(toRemotePath(remoteParent, newName));
+ return b;
+ }
+
+ public boolean setLastModified(final String parent,
+ final String name, final long timestamp, IProgressMonitor monitor) throws SystemMessageException {
+ final String path = toRemotePath(parent, name);
+ return new TCFRSETask<Boolean>() {
+ public void run() {
+ IFileSystem fs = connector.getFileSystemService();
+ FileAttrs attrs = new FileAttrs(IFileSystem.ATTR_ACMODTIME,
+ 0, 0, 0, 0, timestamp, timestamp, null);
+ fs.setstat(path, attrs, new IFileSystem.DoneSetStat() {
+ public void doneSetStat(IToken token, FileSystemException error) {
+ if (error != null) error(error);
+ else done(true);
+ }
+ });
+ }
+ }.getS(monitor, "Set modification time");
+ }
+
+ public boolean setReadOnly(final String parent,
+ final String name, final boolean readOnly, IProgressMonitor monitor) throws SystemMessageException {
+ final String path = toRemotePath(parent, name);
+ return new TCFRSETask<Boolean>() {
+ public void run() {
+ final IFileSystem fs = connector.getFileSystemService();
+ fs.stat(path, new IFileSystem.DoneStat() {
+ public void doneStat(IToken token, FileSystemException error, FileAttrs attrs) {
+ if (error != null) {
+ error(error);
+ return;
+ }
+ int p = attrs.permissions;
+ if (readOnly) {
+ p &= ~IFileSystem.S_IWUSR;
+ p &= ~IFileSystem.S_IWGRP;
+ p &= ~IFileSystem.S_IWOTH;
+ }
+ else {
+ p |= IFileSystem.S_IWUSR;
+ p |= IFileSystem.S_IWGRP;
+ p |= IFileSystem.S_IWOTH;
+ }
+ FileAttrs new_attrs = new FileAttrs(IFileSystem.ATTR_PERMISSIONS,
+ 0, 0, 0, p, 0, 0, null);
+ fs.setstat(path, new_attrs, new IFileSystem.DoneSetStat() {
+ public void doneSetStat(IToken token, FileSystemException error) {
+ if (error != null) error(error);
+ else done(true);
+ }
+ });
+ }
+ });
+ }
+ }.getS(monitor, "Set permissions");
+ }
+
+ public boolean upload(InputStream inp,
+ String parent, String name, boolean isBinary,
+ String hostEncoding, IProgressMonitor monitor) throws SystemMessageException {
+ monitor.beginTask("Upload", 1);
+ try {
+ OutputStream out = getOutputStream(parent, name, isBinary, new NullProgressMonitor());
+ copyStream(inp, out, isBinary, hostEncoding, "UTF8");
+ return true;
+ }
+ catch (Throwable x) {
+ if (x instanceof SystemMessageException) throw (SystemMessageException)x;
+ throw new SystemMessageException(getMessage(x));
+ }
+ finally {
+ monitor.done();
+ }
+ }
+
+ public boolean upload(File localFile,
+ String parent, String name, boolean isBinary,
+ String srcEncoding, String hostEncoding, IProgressMonitor monitor)
+ throws SystemMessageException {
+ monitor.beginTask("Upload", 1);
+ try {
+ OutputStream out = getOutputStream(parent, name, isBinary, new NullProgressMonitor());
+ InputStream inp = new BufferedInputStream(new FileInputStream(localFile));
+ copyStream(inp, out, isBinary, hostEncoding, "UTF8");
+ return true;
+ }
+ catch (Throwable x) {
+ if (x instanceof SystemMessageException) throw (SystemMessageException)x;
+ throw new SystemMessageException(getMessage(x));
+ }
+ finally {
+ monitor.done();
+ }
+ }
+
+ private void copyStream(InputStream inp, OutputStream out,
+ boolean is_binary, String inp_encoding, String out_encoding) throws IOException {
+ try {
+ if (!is_binary) {
+ if (inp_encoding.equals("UTF-8")) inp_encoding = "UTF8";
+ if (out_encoding.equals("UTF-8")) out_encoding = "UTF8";
+ }
+ if (is_binary || inp_encoding.equals(out_encoding)) {
+ byte[] buf = new byte[0x1000];
+ for (;;) {
+ int buf_len = inp.read(buf);
+ if (buf_len < 0) break;
+ out.write(buf, 0, buf_len);
+ }
+ }
+ else {
+ Reader reader = new InputStreamReader(inp, inp_encoding);
+ Writer writer = new OutputStreamWriter(out, out_encoding);
+ char[] buf = new char[0x1000];
+ for (;;) {
+ int buf_len = reader.read(buf);
+ if (buf_len < 0) break;
+ writer.write(buf, 0, buf_len);
+ }
+ writer.flush();
+ }
+ }
+ finally {
+ out.close();
+ inp.close();
+ }
+ }
+
+ private synchronized UserInfo getUserInfo() {
+ if (user_info == null || user_info.error != null) {
+ user_info = new TCFRSETask<UserInfo>() {
+ public void run() {
+ IFileSystem fs = connector.getFileSystemService();
+ fs.user(new IFileSystem.DoneUser() {
+ public void doneUser(IToken token, FileSystemException error, int real_uid,
+ int effective_uid, int real_gid, int effective_gid, String home) {
+ if (error != null) done(new UserInfo(error));
+ else done(new UserInfo(real_uid, effective_uid, real_gid, effective_gid, home));
+ }
+ });
+ }
+ }.getE();
+ }
+ return user_info;
+ }
+
+ public boolean canRead(FileAttrs attrs) {
+ if ((attrs.flags & IFileSystem.ATTR_PERMISSIONS) == 0) return false;
+ if ((attrs.flags & IFileSystem.ATTR_UIDGID) == 0) return false;
+ UserInfo ui = getUserInfo();
+ if (ui.error != null) return false;
+ if (ui.e_uid == attrs.uid) {
+ return (attrs.permissions & IFileSystem.S_IRUSR) != 0;
+ }
+ if (ui.e_gid == attrs.gid) {
+ return (attrs.permissions & IFileSystem.S_IRGRP) != 0;
+ }
+ return (attrs.permissions & IFileSystem.S_IROTH) != 0;
+ }
+
+ public boolean canWrite(FileAttrs attrs) {
+ if ((attrs.flags & IFileSystem.ATTR_PERMISSIONS) == 0) return false;
+ if ((attrs.flags & IFileSystem.ATTR_UIDGID) == 0) return false;
+ UserInfo ui = getUserInfo();
+ if (ui.error != null) return false;
+ if (ui.e_uid == attrs.uid) {
+ return (attrs.permissions & IFileSystem.S_IWUSR) != 0;
+ }
+ if (ui.e_gid == attrs.gid) {
+ return (attrs.permissions & IFileSystem.S_IWGRP) != 0;
+ }
+ return (attrs.permissions & IFileSystem.S_IWOTH) != 0;
+ }
+
+}

Back to the top