View Javadoc

1   /*
2    * Copyright 2007-2008 the original author or authors.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.gwe.drivers.fileSystems.handles;
18  
19  import java.io.IOException;
20  import java.io.InputStream;
21  import java.io.OutputStream;
22  import java.net.InetAddress;
23  import java.net.UnknownHostException;
24  import java.util.UUID;
25  
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  import org.apache.commons.vfs.AllFileSelector;
29  import org.apache.commons.vfs.FileObject;
30  import org.apache.commons.vfs.FileSystemException;
31  import org.apache.commons.vfs.FileSystemManager;
32  import org.apache.commons.vfs.FileSystemOptions;
33  import org.apache.commons.vfs.VFS;
34  import org.apache.commons.vfs.impl.DefaultFileSystemConfigBuilder;
35  import org.apache.commons.vfs.provider.sftp.SftpFileSystemConfigBuilder;
36  import org.apache.commons.vfs.provider.sftp.SftpPPKAuth;
37  import org.gwe.drivers.HandleOperationException;
38  import org.gwe.drivers.fileSystems.FileHandle;
39  import org.gwe.drivers.netAccess.ConnectorException;
40  import org.gwe.drivers.netAccess.HostHandle;
41  import org.gwe.drivers.netAccess.ShellCommand;
42  import org.gwe.drivers.netAccess.handles.JSchUserInfo;
43  import org.gwe.utils.IOUtils;
44  import org.gwe.utils.rex.REXException;
45  import org.gwe.utils.security.AccountInfo;
46  import org.gwe.utils.security.ProtocolScheme;
47  import org.gwe.utils.security.ResourceLink;
48  import org.gwe.utils.security.ThinURI;
49  
50  /**
51   * This class wraps a VFS filesystem.
52   * 
53   * @author Neil Jones
54   * @author Marco Ruiz
55   * @since Jan 24, 2007
56   */
57  public class VfsHandle extends FileHandle {
58      private static Log log = LogFactory.getLog(VfsHandle.class);
59      
60      private static FileSystemManager vfsManager = null;
61  
62      private FileObject fileObj;
63  
64      public VfsHandle(ResourceLink<FileHandle> link) throws FileSystemException, HandleOperationException {
65      	super(link);
66          String uriStr = link.getURI().toString();
67          fileObj = (link.getAccountInfo() != null) ? 
68          		getVFSManager().resolveFile(uriStr, createOptions(link)) : getVFSManager().resolveFile(uriStr);
69      }
70      
71      private VfsHandle(ResourceLink<FileHandle> link, FileObject fileObj) throws FileSystemException, HandleOperationException {
72      	super(link);
73          this.fileObj = fileObj; 
74      }
75      
76      private FileSystemManager getVFSManager() throws HandleOperationException {
77          // TODO: For some reason, the SFTP provider deadlocks.  This needs fixing. 
78          try {
79              if (vfsManager == null) vfsManager = VFS.getManager();
80              return vfsManager;
81  //            ((StandardFileSystemManager)vfsManager).addProvider("ssftp", provider);
82          } catch (FileSystemException fex) {
83              throw new HandleOperationException("Unable to connect to the manager; this is probably fatal", fex);
84          }
85      }
86  
87  	private FileSystemOptions createOptions(ResourceLink<FileHandle> link) throws FileSystemException {
88          log.debug("Setting credential \"" + link + "\" for file '" + link.getURI().getPath() + "'");
89          AccountInfo acct = link.getAccountInfo();
90  	    FileSystemOptions opts = new FileSystemOptions();
91          DefaultFileSystemConfigBuilder.getInstance().setUserAuthenticator(opts, new VfsAuthBridge(acct));
92  	    if (ProtocolScheme.SFTP.toString().equalsIgnoreCase(link.getURI().getScheme())) {
93  	    	SftpFileSystemConfigBuilder configBuilder = SftpFileSystemConfigBuilder.getInstance();
94  	    	configBuilder.setStrictHostKeyChecking(opts, "ask");
95  	    	configBuilder.setUserInfo(opts, new JSchUserInfo(link.getAccountInfo()));
96  	    	if (acct.getPassword() == null) {
97  		        SftpPPKAuth ppkAuth = new SftpPPKAuth(acct.getPrivateKey(), acct.getPublicKey(), acct.getPassphrase());
98  				configBuilder.setPPKAuth(opts, ppkAuth);
99  		    }
100 	    }
101 	    return opts;
102     }
103 
104 	public void createFolder() throws HandleOperationException {
105         if (exists()) return;
106 
107         try {
108             fileObj.createFolder();
109         } catch(FileSystemException e) {
110             throw new HandleOperationException("Error creating folder", e);
111         }
112     }
113 
114     public boolean exists() throws HandleOperationException {
115         try {
116             return fileObj.exists();
117         } catch (FileSystemException fex) {
118             throw new HandleOperationException("Could not check file existence", fex);
119         }
120     }
121     
122     public boolean isDirectory() throws HandleOperationException {
123         try {
124             return fileObj.getType().hasChildren();
125         } catch (NullPointerException e) {
126         	return false;
127         } catch (FileSystemException fex) {
128             throw new HandleOperationException("Could not check directoriness", fex);
129         }
130     }
131 
132     public void copyTo(FileHandle otherFile) throws HandleOperationException {
133     	super.copyTo(otherFile);
134     }
135 
136 	@Override
137     protected FileHandle createCompressedCopyHandle(boolean createFile) throws HandleOperationException {
138 		String filePath = IOUtils.getFilePath(getPath());
139         String fileName = IOUtils.getFileName(getPath());
140         String newFileName = fileName + "-gwe-" + UUID.randomUUID().toString() + "-gwe.tar.gz";
141         
142         if (createFile) {
143 			try {
144 				HostHandle sshHandle = createHostHandle(ProtocolScheme.SSH);
145 				sshHandle.runCommand(new ShellCommand("tar -czf " + newFileName + " " + fileName, filePath, null));
146 		        sshHandle.close();
147 	        } catch (ConnectorException e) {
148 	        	throw new HandleOperationException(e);
149 	        } catch (REXException e) {
150 	        	throw new HandleOperationException(e);
151             }
152         }
153 		
154         String newFileURI = IOUtils.concatenatePaths(IOUtils.getFilePath(link.getURI().toString()), newFileName);
155         try {
156             ThinURI fileURI = ThinURI.create(ThinURI.asNormalizedFileURI(resolveLocalHostName(), newFileURI));
157 			ResourceLink<FileHandle> fileLink = new ResourceLink<FileHandle>(fileURI, link.getAccountInfo());
158 	        return fileLink.createHandle();
159         } catch (REXException e) {
160         	throw new HandleOperationException(e);
161         }
162     }
163 	
164 	private String resolveLocalHostName() {
165 		try {
166 	        return InetAddress.getLocalHost().getCanonicalHostName();
167         } catch (UnknownHostException e) {
168         	return "localhost";
169         }
170 	}
171 
172 	@Override
173     protected void decompressInto(FileHandle otherFile, String directoryName) throws HandleOperationException {
174         String compressedFileName = IOUtils.getFileName(getPath());
175         String compressedFilePath = IOUtils.getFilePath(getPath());
176         String extractedDirFullPath = IOUtils.concatenatePaths(compressedFilePath, directoryName);
177 
178 		try {
179 			HostHandle sshHandle = createHostHandle(ProtocolScheme.SSH);
180 	        sshHandle.runCommand(new ShellCommand("tar -xzf " + compressedFileName, compressedFilePath, null));
181 			sshHandle.runCommand("mv " + extractedDirFullPath + " " + otherFile.getPath());
182 	        sshHandle.close();
183         } catch (ConnectorException e) {
184         	throw new HandleOperationException(e);
185         } catch (REXException e) {
186         	throw new HandleOperationException(e);
187         }
188     }
189 
190 	public InputStream getInputStream() throws HandleOperationException {
191         try {
192             return fileObj.getContent().getInputStream();
193         } catch (FileSystemException fex) {
194             throw new HandleOperationException("Could not read contents from file '" + link.getURI().getPath() + "'", fex);
195         }
196     }
197     
198     public OutputStream getOutputStream() throws HandleOperationException {
199         try {
200             return fileObj.getContent().getOutputStream();
201         } catch (FileSystemException fex) {
202             throw new HandleOperationException("Could not create contents for file '" + link.getURI().getPath() + "'", fex);
203         }
204     }
205     
206     public FileHandle[] getChildren() throws HandleOperationException {
207         try {
208             FileObject[] files = fileObj.getChildren();
209             FileHandle[] res = new FileHandle[files.length];
210             for (int idx = 0; idx < res.length; ++idx) {
211 				ThinURI uri = new ThinURI(getURI().getScheme(), getURI().getHost(), files[idx].getName().getPath());
212 				ResourceLink currLink = new ResourceLink(uri, link.getAccountInfo());
213 				res[idx] = new VfsHandle(currLink, files[idx]);
214 			}
215             return res;
216         } catch (FileSystemException fex) {
217             throw new HandleOperationException("Error listing directory", fex);
218         }
219     }
220 
221     public long getSize() throws HandleOperationException {
222         try {
223             return fileObj.getContent().getSize();
224         } catch (FileSystemException fex) {
225             throw new HandleOperationException("Could not compute file size", fex);
226         }
227     }
228 
229 	public boolean delete() throws HandleOperationException {
230 		try {
231 			fileObj.delete(new AllFileSelector());
232 			return fileObj.delete();
233 		} catch (FileSystemException fex) {
234             throw new HandleOperationException("Could not delete file", fex);
235 		}
236 	}
237 	
238 	public void close() throws HandleOperationException {
239 		try {
240 	        fileObj.close();
241         } catch (IOException e) {
242         	throw new HandleOperationException("Could not close file", e);
243         }
244 	}
245 	
246 	public void finalize() {
247 		if (fileObj != null) {
248 			try {
249 	            close();
250             } catch (HandleOperationException e) {}
251 		}
252 	}
253 }
254 
255 
256