PageRenderTime 41ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/org.cfeclipse.cfml/src/org/cfeclipse/cfml/views/explorer/vfs/view/VFSUtil.java

https://github.com/lcamilo15/cfeclipse
Java | 451 lines | 292 code | 65 blank | 94 comment | 54 complexity | 67209455e850f4bbdfb39d1c920dc76b MD5 | raw file
  1. package org.cfeclipse.cfml.views.explorer.vfs.view;
  2. import java.io.File;
  3. import java.io.FileOutputStream;
  4. import java.io.RandomAccessFile;
  5. import java.lang.reflect.InvocationTargetException;
  6. import java.net.URI;
  7. import java.net.URISyntaxException;
  8. import java.util.ArrayList;
  9. import java.util.Collections;
  10. import java.util.Comparator;
  11. import java.util.Date;
  12. import java.util.TreeMap;
  13. import java.util.List;
  14. import java.util.Vector;
  15. import org.apache.commons.vfs.FileContent;
  16. import org.apache.commons.vfs.FileName;
  17. import org.apache.commons.vfs.FileObject;
  18. import org.apache.commons.vfs.FileSystemException;
  19. import org.apache.commons.vfs.FileSystemManager;
  20. import org.apache.commons.vfs.FileType;
  21. import org.eclipse.jface.dialogs.IInputValidator;
  22. import org.eclipse.jface.dialogs.InputDialog;
  23. import org.eclipse.jface.dialogs.MessageDialog;
  24. import org.eclipse.jface.dialogs.ProgressMonitorDialog;
  25. import org.eclipse.jface.window.Window;
  26. import org.eclipse.jface.wizard.WizardDialog;
  27. import org.eclipse.swt.SWT;
  28. import org.eclipse.swt.widgets.Display;
  29. import org.eclipse.swt.widgets.Shell;
  30. import org.eclipse.swt.widgets.Tree;
  31. import org.eclipse.swt.widgets.TreeItem;
  32. import org.cfeclipse.cfml.net.FTPConnectionProperties;
  33. import org.cfeclipse.cfml.net.ftp.FTPConnection;
  34. import org.cfeclipse.cfml.util.CFPluginImages;
  35. import org.cfeclipse.cfml.views.explorer.vfs.FileOperation;
  36. public class VFSUtil
  37. {
  38. public static String USER_HOME = System.getProperty("user.home");
  39. private static String VFS_PATH = USER_HOME + FileName.SEPARATOR + ".vfs";
  40. private static Shell Shell = Display.getCurrent().getActiveShell();
  41. /*
  42. * Missing from Commons VFS
  43. */
  44. static public boolean isDirectory (FileObject f )
  45. {
  46. try {
  47. if ( f.getType() == null ) return false;
  48. return f.getType().equals(FileType.FOLDER);
  49. } catch (Exception e) {
  50. VFSView.error("VFSUtil.isDirectory: " + e);
  51. return false;
  52. }
  53. }
  54. /**
  55. * Sorts files lexicographically by name.
  56. *
  57. * @param files the array of Files to be sorted
  58. */
  59. static void sortFiles(FileObject[] files) {
  60. /* Very lazy merge sort algorithm */
  61. sortBlock(files, 0, files.length - 1, new FileObject[files.length]);
  62. }
  63. private static void sortBlock(FileObject[] files, int start, int end, FileObject[] mergeTemp) {
  64. final int length = end - start + 1;
  65. if (length < 8) {
  66. for (int i = end; i > start; --i) {
  67. for (int j = end; j > start; --j) {
  68. if (compareFiles(files[j - 1], files[j]) > 0) {
  69. final FileObject temp = files[j];
  70. files[j] = files[j-1];
  71. files[j-1] = temp;
  72. }
  73. }
  74. }
  75. return;
  76. }
  77. final int mid = (start + end) / 2;
  78. sortBlock(files, start, mid, mergeTemp);
  79. sortBlock(files, mid + 1, end, mergeTemp);
  80. int x = start;
  81. int y = mid + 1;
  82. for (int i = 0; i < length; ++i) {
  83. if ((x > mid) || ((y <= end) && compareFiles(files[x], files[y]) > 0)) {
  84. mergeTemp[i] = files[y++];
  85. } else {
  86. mergeTemp[i] = files[x++];
  87. }
  88. }
  89. for (int i = 0; i < length; ++i) files[i + start] = mergeTemp[i];
  90. }
  91. static int compareFiles(FileObject a, FileObject b) {
  92. // sort case-sensitive files in a case-insensitive manner
  93. int compare = a.getName().getBaseName().compareToIgnoreCase(b.getName().getBaseName());
  94. if (compare == 0) compare = a.getName().compareTo(b.getName());
  95. return compare;
  96. }
  97. /*
  98. * Message Boxes
  99. */
  100. public static void MessageBoxError(String text )
  101. {
  102. MessageDialog.openError(Shell, VFSView.getResourceString("msg.box.title") ,text);
  103. }
  104. public static void MessageBoxInfo(String text )
  105. {
  106. MessageDialog.openInformation(Shell, VFSView.getResourceString("msg.box.title") ,text);
  107. }
  108. public static boolean MessageBoxYesNo(String text )
  109. {
  110. return MessageDialog.openQuestion(Shell, VFSView.getResourceString("msg.box.title") ,text);
  111. }
  112. /*
  113. * Create a new file
  114. */
  115. public static void newFile(FileObject parent) {
  116. InputDialog d = new InputDialog(Shell
  117. , VFSView.getResourceString("dialog.new.file.title", new Object[] {parent})
  118. , VFSView.getResourceString("dialog.new.file.label", new Object[] {parent})
  119. , "", new VFSUtil.LengthValidator() );
  120. if ( d.open() == Window.OK) {
  121. try {
  122. String newFolder = d.getValue();
  123. FileObject newFile = parent.resolveFile(newFolder);
  124. newFile.createFile();
  125. } catch (FileSystemException e) {
  126. MessageBoxError( e.getMessage());
  127. }
  128. }
  129. }
  130. /*
  131. * Create a new Folder
  132. */
  133. public static void newFolder(FileObject parent) {
  134. InputDialog d = new InputDialog(Shell
  135. , VFSView.getResourceString("dialog.new.folder.title", new Object[] {parent})
  136. , VFSView.getResourceString("dialog.new.folder.label", new Object[] {parent})
  137. , "", new VFSUtil.LengthValidator() );
  138. if ( d.open() == Window.OK) {
  139. String newFolder = d.getValue();
  140. try {
  141. FileObject newFile = parent.resolveFile(newFolder);
  142. newFile.createFolder();
  143. } catch (FileSystemException e) {
  144. MessageBoxError( e.getMessage());
  145. }
  146. }
  147. }
  148. /* Shell:
  149. * Sets the title to indicate the selected directory
  150. */
  151. public static void setUiStateIdle (Shell shell, String title) {
  152. shell.setText(VFSView.getResourceString("Title"
  153. , new Object[] { title }));
  154. shell.setCursor(CFPluginImages.cursors[CFPluginImages.cursorDefault]);
  155. }
  156. public static void setUiStateListContents (Shell shell, String title) {
  157. shell.setText(VFSView.getResourceString("Title.Listing.files"
  158. , new Object[] { title }));
  159. shell.setCursor(CFPluginImages.cursors[CFPluginImages.cursorWait]);
  160. }
  161. /**
  162. * Load VFS URIs from $HOME/.vfs (1 URI per line)
  163. * @param fsMananger
  164. * @return
  165. */
  166. public static TreeMap<String, FTPConnectionProperties> loadFileSystems ()
  167. {
  168. String[] connections = FTPConnectionProperties.getConnectionIds();
  169. final TreeMap<String, FTPConnectionProperties> items = new TreeMap<String, FTPConnectionProperties>();
  170. for (int i=0;i<connections.length;i++) {
  171. FTPConnectionProperties connectionProperties = new FTPConnectionProperties(connections[i]);
  172. items.put(connections[i], connectionProperties);
  173. }
  174. return items;
  175. }
  176. /**
  177. * Remove a file system URI from $HOME/.vfs
  178. * @param uri URI to be removed
  179. */
  180. public static boolean removeFileSystem(String uri)
  181. {
  182. if ( MessageBoxYesNo(VFSView.getResourceString("remove.remote.fs", uri)))
  183. {
  184. //System.out.println("remove uri=" + uri);
  185. try {
  186. if ( ! new File(VFS_PATH).exists() ) return false;
  187. StringBuffer buf = new StringBuffer();
  188. RandomAccessFile f = new RandomAccessFile(VFS_PATH, "r");
  189. String line = null;
  190. while ( (line = f.readLine()) != null ) {
  191. // ignore comments
  192. //if ( line.startsWith("#")) continue;
  193. if ( line.length() > 0 && !uri.equalsIgnoreCase(line)) {
  194. //System.out.println("found uri=" + uri);
  195. buf.append(line + "\n");
  196. }
  197. }
  198. f.close();
  199. // re-save stuff
  200. new FileOutputStream(VFS_PATH, false).write(buf.toString().getBytes());
  201. return true;
  202. } catch (Exception e) {
  203. VFSView.debug(e);
  204. return false;
  205. }
  206. }
  207. else
  208. return false;
  209. }
  210. /**
  211. * Add a File System object to the tree
  212. * @param file
  213. */
  214. public static void treeAddFsNode (Tree tree, FTPConnectionProperties connectionProperties)
  215. {
  216. TreeItem item = new TreeItem(tree, SWT.NULL);
  217. String nodeName = connectionProperties.getConnectionid() + " (" + connectionProperties.getURI() + ")";
  218. item.setText(nodeName);
  219. String icon = connectionProperties.getType().equals("file") ? CFPluginImages.ICON_DRIVE : CFPluginImages.ICON_DRIVE_FTP;
  220. item.setImage(VFSView.iconCache.get(icon));
  221. item.setData(VFSView.TREEITEMDATA_FILE, nodeName );
  222. item.setData(VFSView.TREEITEMDATA_URI, connectionProperties.getURI()); //file );
  223. item.setData(VFSView.TREEITEMDATA_CONNECTIONID, connectionProperties.getConnectionid()); //file );
  224. item.setData(VFSView.TREEITEMDATA_IMAGEEXPANDED, VFSView.iconCache.get(CFPluginImages.ICON_DRIVE_SFTP));
  225. item.setData(VFSView.TREEITEMDATA_IMAGECOLLAPSED, VFSView.iconCache.get(CFPluginImages.ICON_DRIVE));
  226. new TreeItem(item, SWT.NULL); // placeholder child item to get "expand" button
  227. }
  228. /**
  229. * Remove user/pwd information from a file system URI
  230. * @param file
  231. * @return
  232. */
  233. static public String stripUserTokens (String file)
  234. {
  235. try {
  236. if ( file.indexOf(' ') != -1)
  237. return file.toString();
  238. URI Uri = new URI(file);
  239. String port = (Uri.getPort() > 0) ? ":" + Uri.getPort() : "";
  240. String Path = (Uri.getScheme().equals("smb")) ? "/" : Uri.getPath();
  241. // remove paths from smb Uris
  242. String newUri = (Uri.getHost() != null )
  243. ? Uri.getScheme() + "://" + Uri.getHost() + port + Path
  244. : file.toString();
  245. return newUri;
  246. } catch (URISyntaxException e) {
  247. //VFSView.error("stripUserTokens " + e);
  248. VFSView.debug(e);
  249. return file.toString();
  250. }
  251. }
  252. /**
  253. * This class validates a String. It makes sure that the String is between 5 and 8
  254. * characters
  255. */
  256. static class LengthValidator implements IInputValidator {
  257. /**
  258. * Validates the String. Returns null for no error, or an error message
  259. *
  260. * @param newText the String to validate
  261. * @return String
  262. */
  263. public String isValid(String newText) {
  264. int len = newText.length();
  265. // Determine if input is too short or too long
  266. if (len == 0)
  267. return VFSView.getResourceString("dialog.new.folder.validator.label");
  268. // Input must be OK
  269. return null;
  270. }
  271. }
  272. /*
  273. * Build a String list of exception messages
  274. */
  275. static public String getErrorMessageStack (Exception e) {
  276. StringBuffer buf = new StringBuffer(e.getMessage());
  277. Throwable t = e.getCause();
  278. while ( t != null) {
  279. buf.append(t.toString());
  280. t = t.getCause();
  281. }
  282. return buf.toString();
  283. }
  284. /**
  285. * Compare 2 URIs using simple string comparissons. By host, scheme, and path only.
  286. * This is used to avoid FileObject comparissons which attempt a server connection
  287. * thus hanging the UI when one of the hosts is down
  288. */
  289. public static boolean compareURIs(String uri1, String uri2)
  290. {
  291. try {
  292. // A simple hack: if any space is present just compare the strings
  293. if ( uri1.indexOf(' ') != -1 || uri2.indexOf(' ') != -1)
  294. return uri1.equalsIgnoreCase(uri2);
  295. // This will throw a syntax error if the URI has spaces (file:// in Win32)
  296. final URI Uri1 = new URI(uri1);
  297. final URI Uri2 = new URI(uri2);
  298. final String path1 = Uri1.getPath().endsWith("/") ? Uri1.getPath().substring(0, Uri1.getPath().length() - 1 ) : Uri1.getPath() ;
  299. final String path2 = Uri2.getPath().endsWith("/") ? Uri2.getPath().substring(0, Uri2.getPath().length() - 1 ) : Uri2.getPath() ;
  300. boolean local = Uri1.getHost() == null || Uri2.getHost() == null;
  301. boolean b1 = Uri1.getScheme().equalsIgnoreCase(Uri2.getScheme());
  302. boolean b2 = path1.equalsIgnoreCase(path2);
  303. //System.out.println("compareURIs uri1=" + uri1 + " uri2=" + uri2 + " Uri1=" + Uri1 + " Uri2=" + Uri2);
  304. //System.out.println("local="+ local + " b1=" +b1 + " b2=" + b2 + " Uri object comp=" + Uri1.equals(Uri2));
  305. // non local URIs must match: scheme, host,path
  306. if ( ! local) {
  307. boolean b3 = Uri1.getHost().equals(Uri2.getHost());
  308. if ( b1 && b2 && b3) {
  309. // System.err.println("compareURIs " + uri1 + " == " + uri2);
  310. return true;
  311. }
  312. }
  313. // local (file://) URIs must match scheme && path
  314. else if ( b1 && b2 ) {
  315. // System.err.println("compareURIs " + uri1 + " == " + uri2 );
  316. return true;
  317. }
  318. }
  319. catch (Exception e) {
  320. VFSView.debug(e);
  321. }
  322. return false;
  323. }
  324. /**
  325. * Get a file object VFS attributes as string
  326. * @param file
  327. * @return
  328. */
  329. public static String getFileAttributes(FileObject file)
  330. {
  331. StringBuffer buf = new StringBuffer(file.getName().getPath());
  332. try {
  333. if ( file.getType() == null || ! file.getType().hasContent() )
  334. return buf.toString();
  335. FileContent c = file.getContent();
  336. // Get standard attributes: Size, last modified
  337. if ( ! isDirectory(file)) {
  338. buf.append("\n" + VFSView.getResourceString("table.Size.title")
  339. + ": " + c. getSize());
  340. buf.append("\n"+ VFSView.getResourceString("table.Modified.title")
  341. + ": " + VFSView.dateFormat.format(new Date(c.getLastModifiedTime())));
  342. }
  343. // Get custom attributes
  344. String[] attNames = c.getAttributeNames();
  345. for (int i = 0; i < attNames.length; i++) {
  346. buf.append("\n" + attNames[i] + ": " + c.getAttribute(attNames[i]) );
  347. }
  348. } catch (FileSystemException e) {
  349. VFSView.debug(e);
  350. }
  351. return buf.toString();
  352. }
  353. /**
  354. * Run a commons VFS copy operation with progress monitor
  355. * @param fsManager Common VFS file system manager
  356. * @param sourceNames String[] of source URIs
  357. * @param sourceConnectionId
  358. * @param targetFile Destination file object
  359. * @param destConnectionId
  360. */
  361. public static void copyFiles (FileSystemManager fsManager, String[] sourceNames, FTPConnectionProperties sourceConnection, FileObject targetFile, FTPConnectionProperties destConnection)
  362. {
  363. // run a copy operation
  364. try {
  365. // if copying 1 file, the progresss dialog will show a bouncing progress
  366. boolean indeterminate = (sourceNames.length == 1);
  367. FileOperation copyOperation = new FileOperation(fsManager, FileOperation.COPY, indeterminate);
  368. // set copy op arguments
  369. copyOperation.setCopyArgs(sourceNames, sourceConnection, targetFile, destConnection);
  370. // fire operation
  371. new ProgressMonitorDialog(Shell).run(true, true, copyOperation);
  372. }
  373. catch (InvocationTargetException e)
  374. {
  375. VFSView.debug(e);
  376. final String msg = (e.getMessage() != null)
  377. ? e.getMessage() : e.getCause().getClass().toString();
  378. VFSUtil.MessageBoxError(msg);
  379. }
  380. catch (InterruptedException e)
  381. {
  382. VFSView.debug(e);
  383. VFSUtil.MessageBoxInfo(VFSUtil.getErrorMessageStack(e));
  384. }
  385. }
  386. }