1
2
3
4
5
6
7
8
9
10
11
12 package com.atlassian.theplugin.eclipse.util;
13
14 import java.io.BufferedReader;
15 import java.io.File;
16 import java.io.FileFilter;
17 import java.io.FileInputStream;
18 import java.io.FileOutputStream;
19 import java.io.IOException;
20 import java.io.InputStreamReader;
21 import java.lang.reflect.Method;
22 import java.text.MessageFormat;
23 import java.util.Arrays;
24 import java.util.Collections;
25 import java.util.Comparator;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.MissingResourceException;
31 import java.util.ResourceBundle;
32 import java.util.Set;
33
34 import org.eclipse.core.internal.preferences.Base64;
35 import org.eclipse.core.resources.IContainer;
36 import org.eclipse.core.resources.IProject;
37 import org.eclipse.core.resources.IResource;
38 import org.eclipse.core.resources.IResourceVisitor;
39 import org.eclipse.core.resources.IWorkspaceRoot;
40 import org.eclipse.core.resources.ResourcesPlugin;
41 import org.eclipse.core.runtime.CoreException;
42 import org.eclipse.core.runtime.IPath;
43 import org.eclipse.core.runtime.IProgressMonitor;
44 import org.eclipse.core.runtime.Platform;
45
46 import com.atlassian.theplugin.eclipse.preferences.Activator;
47
48
49
50
51
52
53 public final class FileUtil {
54 public static final IResource[] NO_CHILDREN = new IResource[0];
55
56 public static IResource selectOneOf(IResource[] scope, IResource[] set) {
57 for (int i = 0; i < set.length; i++) {
58 if (FileUtil.relatesTo(scope, set[i])) {
59 return set[i];
60 }
61 }
62 return null;
63 }
64
65 public static boolean relatesTo(IResource[] set, IResource resource) {
66 for (int i = 0; i < set.length; i++) {
67 if (FileUtil.relatesTo(set[i], resource)) {
68 return true;
69 }
70 }
71 return false;
72 }
73
74 public static boolean relatesTo(IResource set, IResource resource) {
75 return set.equals(resource) ? true : (resource == null ? false
76 : FileUtil.relatesTo(set, resource.getParent()));
77 }
78
79 public static String getResource(ResourceBundle bundle, String key) {
80 if (key == null) {
81 return null;
82 }
83 if (bundle == null) {
84 return key;
85 }
86 String retVal = FileUtil.getResourceImpl(bundle, key);
87 if (retVal != null) {
88 if (key.indexOf("Error") != -1) {
89 String id = FileUtil.getResourceImpl(bundle, key + ".Id");
90 if (id != null) {
91 retVal = id + ": " + retVal;
92 }
93 }
94 return retVal;
95 }
96 return key;
97 }
98
99 public static String getWorkingCopyPath(IResource resource) {
100 return FileUtil.getResourcePath(resource).toString();
101 }
102
103 public static IPath getResourcePath(IResource resource) {
104 IPath location = resource.getLocation();
105 if (location == null) {
106 String errMessage = Activator.getDefault().getResource(
107 "Error.InaccessibleResource");
108 throw new RuntimeException(MessageFormat.format(errMessage,
109 new Object[] { resource.getFullPath().toString() }));
110 }
111 return location;
112 }
113
114 @SuppressWarnings("unchecked")
115 public static Map<String, String> getEnvironmentVariables() {
116 try {
117 Method getenv = System.class.getMethod("getenv", (Class[]) null);
118 return (Map<String, String>) getenv.invoke((Object[]) null,
119 (Object[]) null);
120 } catch (Exception ex) {
121 try {
122 boolean isWindows = FileUtil.isWindows();
123 Process p = isWindows ? Runtime.getRuntime().exec(
124 "cmd.exe /c set") : Runtime.getRuntime().exec("env");
125
126 BufferedReader br = new BufferedReader(new InputStreamReader(p
127 .getInputStream()));
128 String varLine;
129 Map<String, String> retVal = new HashMap<String, String>();
130 while ((varLine = br.readLine()) != null) {
131 int idx = varLine.indexOf('=');
132 if (idx != -1) {
133 String name = varLine.substring(0, idx);
134 retVal.put(isWindows ? name.toUpperCase() : name,
135 varLine.substring(idx + 1));
136 } else if (varLine.length() > 0) {
137 retVal.put(varLine, "");
138 }
139 }
140 return retVal;
141 } catch (IOException ex1) {
142 return Collections.EMPTY_MAP;
143 }
144 }
145 }
146
147 public static String normalizePath(String path) {
148 return FileUtil.isWindows() ? path.replace('/', '\\') : path.replace(
149 '\\', '/');
150 }
151
152 public static boolean isWindows() {
153 return FileUtil.getOSName().indexOf("windows") != -1;
154 }
155
156 public static String getOSName() {
157 return System.getProperty("os.name").toLowerCase();
158 }
159
160 public static boolean isCaseInsensitiveOS() {
161 return !(Platform.OS_MACOSX.equals(Platform.getOS()) ? false
162 : new java.io.File("a").compareTo(new java.io.File("A")) != 0);
163 }
164
165 public static boolean isLinked(IResource resource) {
166
167 return resource.isLinked(IResource.CHECK_ANCESTORS);
168 }
169
170 public static String[] asPathArray(IResource[] resources) {
171 String[] retVal = new String[resources.length];
172 for (int i = 0; i < resources.length; i++) {
173 retVal[i] = FileUtil.normalizePath(FileUtil
174 .getWorkingCopyPath(resources[i]));
175 }
176 return retVal;
177 }
178
179 public static String[] asPathArray(File[] files) {
180 String[] retVal = new String[files.length];
181 for (int i = 0; i < files.length; i++) {
182 retVal[i] = FileUtil.normalizePath(files[i].getAbsolutePath());
183 }
184 return retVal;
185 }
186
187
188
189
190
191
192
193
194
195 public static String formatResourceName(String projectName) {
196
197 return PatternProvider.replaceAll(projectName, "([\\/:])+", ".");
198 }
199
200 public static String formatPath(String path) {
201 return PatternProvider.replaceAll(path, "\\\\", "/");
202 }
203
204 public static String getUsernameParam(String username) {
205 return username == null || username.trim().length() == 0 ? ""
206 : " --username \"" + username + "\"";
207 }
208
209 public static String flattenText(String text) {
210 StringBuffer flat = new StringBuffer(text.length() + 20);
211 boolean skipAdjacentLineSeparator = true;
212 for (int i = 0; i < text.length(); i++) {
213 char currentChar = text.charAt(i);
214 if (currentChar == '\r' || currentChar == '\n') {
215 if (!skipAdjacentLineSeparator) {
216 flat.append("/");
217 }
218 skipAdjacentLineSeparator = true;
219 } else {
220 flat.append(currentChar);
221 skipAdjacentLineSeparator = false;
222 }
223 }
224 return flat.toString().replace('\t', ' ');
225 }
226
227 public static int getMaxStringLength(String[] strings) {
228 int result = 0;
229 for (int i = 0; i < strings.length; i++) {
230 result = Math.max(result, strings[i].length());
231 }
232 return result;
233 }
234
235 public static String formatMultilineText(String text) {
236 if (text.length() > 0 && text.substring(0, 1).matches("(\\s)+")) {
237 text = text.replaceFirst("(\\s)+", "");
238 }
239 if (text.length() == 0) {
240 return "";
241 }
242 text = text.replace('\t', ' ');
243 int idx = text.indexOf('\n');
244 int idx1 = text.indexOf('\r');
245 if (idx == -1) {
246 idx = idx1;
247 }
248 idx = idx < idx1 || idx1 == -1 ? idx : idx1;
249 if (idx != -1) {
250 if (text.substring(idx).trim().length() != 0) {
251 return text.substring(0, idx) + "...";
252 } else {
253 return text.substring(0, idx);
254 }
255 }
256 return text;
257 }
258
259 @SuppressWarnings("restriction")
260 public static String[] decodeStringToArray(String encodedString) {
261 String[] valuesArray = new String[] {};
262 if (encodedString != null && encodedString.length() > 0) {
263 valuesArray = encodedString.split(";");
264 for (int i = 0; i < valuesArray.length; i++) {
265 valuesArray[i] = new String(Base64.decode(valuesArray[i]
266 .getBytes()));
267 }
268 }
269 return valuesArray;
270 }
271
272 @SuppressWarnings("restriction")
273 public static String encodeArrayToString(String[] valuesArray) {
274 String result = "";
275 for (int i = 0; i < valuesArray.length; i++) {
276 String str = new String(Base64.encode(valuesArray[i].getBytes()));
277 result += result.length() == 0 ? str : (";" + str);
278 }
279 return result;
280 }
281
282 public static void visitNodes(IResource resource, IResourceVisitor visitor,
283 int depth) throws CoreException {
284 boolean stepInside = visitor.visit(resource);
285 if (stepInside && resource instanceof IContainer
286 && depth != IResource.DEPTH_ZERO && resource.isAccessible()) {
287
288 IContainer container = (IContainer) resource;
289 IResource[] children = FileUtil.resourceMembers(container, true);
290 int nextDepth = depth == IResource.DEPTH_ONE ? IResource.DEPTH_ZERO
291 : depth;
292 for (int i = 0; i < children.length; i++) {
293 FileUtil.visitNodes(children[i], visitor, nextDepth);
294 }
295 }
296 }
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408 public static boolean deleteRecursive(File node) {
409 return FileUtil.deleteRecursive(node, null);
410 }
411
412 public static boolean deleteRecursive(File node, IProgressMonitor monitor) {
413 if (node.isDirectory()) {
414 File[] files = node.listFiles();
415 if (files != null) {
416 for (int i = 0; i < files.length
417 && (monitor == null || !monitor.isCanceled()); i++) {
418 FileUtil.deleteRecursive(files[i], monitor);
419 }
420 }
421 }
422 return node.delete();
423 }
424
425 public static void copyAll(File to, File what, IProgressMonitor monitor)
426 throws Exception {
427 FileUtil.copyAll(to, what, false, monitor);
428 }
429
430 public static final int COPY_NO_OPTIONS = 0x00;
431 public static final int COPY_IGNORE_EXISTING_FOLDERS = 0x01;
432 public static final int COPY_OVERRIDE_EXISTING_FILES = 0x02;
433
434 public static void copyAll(File to, File what,
435 boolean ignoreExistingFolders, IProgressMonitor monitor)
436 throws Exception {
437 FileUtil.copyAll(to, what,
438 ignoreExistingFolders ? FileUtil.COPY_IGNORE_EXISTING_FOLDERS
439 : FileUtil.COPY_NO_OPTIONS, null, monitor);
440 }
441
442 public static void copyAll(File to, File what, int options,
443 FileFilter filter, IProgressMonitor monitor) throws Exception {
444 if (what.isDirectory()) {
445 to = new File(to.getAbsolutePath() + "/" + what.getName());
446 if (monitor.isCanceled()) {
447 return;
448 }
449 if (!to.mkdirs()
450 && ((options & FileUtil.COPY_IGNORE_EXISTING_FOLDERS) == 0)) {
451 String errMessage = Activator.getDefault().getResource(
452 "Error.CreateDirectory");
453 throw new Exception(MessageFormat.format(errMessage,
454 new Object[] { to.getAbsolutePath() }));
455 }
456 File[] files = what.listFiles(filter);
457 if (files != null) {
458 for (int i = 0; i < files.length && !monitor.isCanceled(); i++) {
459 FileUtil.copyAll(to, files[i], options, filter, monitor);
460 }
461 }
462 } else {
463 FileUtil.copyFile(to, what, options, monitor);
464 }
465 }
466
467 public static void copyFile(File to, File what, IProgressMonitor monitor)
468 throws Exception {
469 FileUtil.copyFile(to, what, FileUtil.COPY_OVERRIDE_EXISTING_FILES,
470 monitor);
471 }
472
473 public static void copyFile(File to, File what, int options,
474 IProgressMonitor monitor) throws Exception {
475 if (to.exists() && to.isDirectory()) {
476 to = new File(to.getAbsolutePath() + "/" + what.getName());
477 }
478 if ((!to.exists() || (options & FileUtil.COPY_OVERRIDE_EXISTING_FILES) != 0)
479 && !monitor.isCanceled()) {
480 FileOutputStream output = null;
481 FileInputStream input = null;
482 try {
483 output = new FileOutputStream(to);
484 input = new FileInputStream(what);
485 byte[] buf = new byte[2048];
486 int loaded = 0;
487 while ((loaded = input.read(buf)) > 0 && !monitor.isCanceled()) {
488 output.write(buf, 0, loaded);
489 }
490 } finally {
491 if (output != null) {
492 try {
493 output.close();
494 } catch (Exception ex) {
495
496 }
497 }
498 if (input != null) {
499 try {
500 input.close();
501 } catch (Exception ex) {
502
503 }
504 }
505 }
506 }
507 }
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536 public static IResource[] getPathNodes(IResource resource) {
537 return FileUtil.getPathNodes(new IResource[] { resource });
538 }
539
540 public static IResource[] getPathNodes(IResource[] resources) {
541 List<IResource> tmp = Arrays.asList(resources);
542 Set<IResource> modifiedRoots = new HashSet<IResource>();
543 IWorkspaceRoot wRoot = ResourcesPlugin.getWorkspace().getRoot();
544
545 for (int i = 0; i < resources.length; i++) {
546 IResource root = resources[i];
547 while ((root = root.getParent()) != wRoot) {
548 if (!tmp.contains(root)) {
549 modifiedRoots.add(root);
550 } else {
551 break;
552 }
553 }
554 }
555
556 return (IResource[]) modifiedRoots.toArray(new IResource[modifiedRoots
557 .size()]);
558 }
559
560 public static void reorder(IResource[] resources, final boolean parent2Child) {
561 Arrays.sort(resources, new Comparator<IResource>() {
562 public int compare(IResource rf, IResource rs) {
563 String first = rf.getFullPath().toString();
564 String second = rs.getFullPath().toString();
565 return parent2Child ? first.compareTo(second) : second
566 .compareTo(first);
567 }
568 });
569 }
570
571 public static void reorder(File[] files, final boolean parent2Child) {
572 Arrays.sort(files, new Comparator<File>() {
573 public int compare(File o1, File o2) {
574 String first = ((File) o1).getAbsolutePath();
575 String second = ((File) o2).getAbsolutePath();
576 return parent2Child ? first.compareTo(second) : second
577 .compareTo(first);
578 }
579 });
580 }
581
582 public static IResource[] shrinkChildNodes(IResource[] resources) {
583 Set<IResource> tRoots = new HashSet<IResource>(Arrays.asList(resources));
584 for (int i = 0; i < resources.length; i++) {
585 if (FileUtil.hasRoots(tRoots, resources[i])) {
586 tRoots.remove(resources[i]);
587 }
588 }
589 return (IResource[]) tRoots.toArray(new IResource[tRoots.size()]);
590 }
591
592 public static File[] shrinkChildNodes(File[] files, boolean skipFiles) {
593 Set<File> tRoots = new HashSet<File>(Arrays.asList(files));
594 for (int i = 0; i < files.length; i++) {
595 if (skipFiles && files[i].isFile()) {
596 continue;
597 }
598 if (FileUtil.hasRoots(tRoots, files[i])) {
599 tRoots.remove(files[i]);
600 }
601 }
602 return (File[]) tRoots.toArray(new File[tRoots.size()]);
603 }
604
605 public static IResource[] resourceMembers(IContainer node,
606 boolean includePhantoms) throws CoreException {
607 try {
608 return node.members(includePhantoms);
609 } catch (CoreException ex) {
610
611
612
613 if (node.isAccessible()) {
614 throw ex;
615 }
616 }
617 return new IResource[0];
618 }
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633 public static boolean hasNature(IResource resource, String natureId)
634 throws CoreException {
635 IProject project = resource.getProject();
636 if (project == null) {
637 return false;
638 }
639 String[] natureIds = project.getDescription().getNatureIds();
640 for (int i = 0; i < natureIds.length; i++) {
641 if (natureId.equals(natureIds[i])) {
642 return true;
643 }
644 }
645 return false;
646 }
647
648 private static boolean hasRoots(Set<IResource> roots, IResource node) {
649 while ((node = node.getParent()) != null) {
650 if (roots.contains(node)) {
651 return true;
652 }
653 }
654 return false;
655 }
656
657 private static boolean hasRoots(Set<File> roots, File node) {
658 while ((node = node.getParentFile()) != null) {
659 if (roots.contains(node)) {
660 return true;
661 }
662 }
663 return false;
664 }
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708 private static String getResourceImpl(ResourceBundle bundle, String key) {
709 try {
710 return bundle.getString(key);
711 } catch (MissingResourceException ex) {
712 return null;
713 }
714 }
715
716 private FileUtil() {
717 }
718
719 }