Mercurial > jhg
annotate src/org/tmatesoft/hg/util/RegularFileStats.java @ 713:661e77dc88ba tip
Mac support: respect Mac alternatives of command-line arguments for common unix tools
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> | 
|---|---|
| date | Sun, 03 Aug 2014 18:09:00 +0200 | 
| parents | c02b5710d9ac | 
| children | 
| rev | line source | 
|---|---|
| 
413
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
1 /* | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
2 * Copyright (c) 2012 TMate Software Ltd | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
3 * | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
4 * This program is free software; you can redistribute it and/or modify | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
5 * it under the terms of the GNU General Public License as published by | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
6 * the Free Software Foundation; version 2 of the License. | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
7 * | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
8 * This program is distributed in the hope that it will be useful, | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
11 * GNU General Public License for more details. | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
12 * | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
13 * For information on how to redistribute this software under | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
14 * the terms of a license other than GNU General Public License | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
15 * contact TMate Software at support@hg4j.com | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
16 */ | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
17 package org.tmatesoft.hg.util; | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
18 | 
| 
456
 
909306e412e2
Refactor LogFacility and SessionContext, better API for both
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
429 
diff
changeset
 | 
19 import static org.tmatesoft.hg.util.LogFacility.Severity.Warn; | 
| 
 
909306e412e2
Refactor LogFacility and SessionContext, better API for both
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
429 
diff
changeset
 | 
20 | 
| 
413
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
21 import java.io.File; | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
22 import java.io.IOException; | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
23 import java.util.ArrayList; | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
24 import java.util.Arrays; | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
25 import java.util.Collections; | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
26 import java.util.HashMap; | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
27 import java.util.HashSet; | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
28 import java.util.List; | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
29 import java.util.Map; | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
30 import java.util.Set; | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
31 import java.util.TreeMap; | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
32 import java.util.regex.Matcher; | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
33 import java.util.regex.Pattern; | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
34 | 
| 
425
 
48f993aa2f41
FIXMEs: exceptions, javadoc
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
423 
diff
changeset
 | 
35 import org.tmatesoft.hg.core.SessionContext; | 
| 
413
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
36 import org.tmatesoft.hg.internal.Internals; | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
37 import org.tmatesoft.hg.internal.ProcessExecHelper; | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
38 | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
39 /** | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
40 * Utility to collect executable files and symbolic links in a directory. | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
41 * | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
42 * | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
43 * Not public as present approach (expect file but collect once per directory) may need to be made explicit | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
44 * | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
45 * TODO post-1.0 Add Linux-specific set of tests (similar to my test-flags repository, with symlink, executable and regular file, | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
46 * and few revisions where link and exec flags change. +testcase when link points to non-existing file (shall not report as missing, | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
47 * iow either FileInfo.exist() shall respect symlinks or WCSC account for ) | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
48 * | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
49 * TODO post-1.0 Add extraction of link modification time, see RegularFileInfo#lastModified() | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
50 * | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
51 * @author Artem Tikhomirov | 
| 
423
 
9c9c442b5f2e
Major refactoring of exception handling. Low-level API uses RuntimeExceptions, while checked are left for higher level
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
413 
diff
changeset
 | 
52 * @author TMate Software Ltd. | 
| 
413
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
53 */ | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
54 /*package-local*/ class RegularFileStats { | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
55 private boolean isExec, isSymlink; | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
56 private String symlinkValue; | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
57 private final List<String> command; | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
58 private final ProcessExecHelper execHelper; | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
59 private final Matcher linkMatcher, execMatcher; | 
| 
425
 
48f993aa2f41
FIXMEs: exceptions, javadoc
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
423 
diff
changeset
 | 
60 private final SessionContext sessionContext; | 
| 
413
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
61 | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
62 | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
63 // directory name to (short link name -> link target) | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
64 private Map<String, Map<String, String>> dir2links = new TreeMap<String, Map<String, String>>(); | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
65 // directory name to set of executable file short names | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
66 private Map<String, Set<String>> dir2execs = new TreeMap<String, Set<String>>(); | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
67 | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
68 | 
| 
425
 
48f993aa2f41
FIXMEs: exceptions, javadoc
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
423 
diff
changeset
 | 
69 RegularFileStats(SessionContext ctx) { | 
| 
 
48f993aa2f41
FIXMEs: exceptions, javadoc
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
423 
diff
changeset
 | 
70 sessionContext = ctx; | 
| 
713
 
661e77dc88ba
Mac support: respect Mac alternatives of command-line arguments for common unix tools
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
476 
diff
changeset
 | 
71 final Pattern pLink, pExec; | 
| 
413
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
72 if (Internals.runningOnWindows()) { | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
73 // XXX this implementation is not yet tested against any Windows repository, | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
74 // only against sample dir listings. As long as Mercurial doesn't handle Windows | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
75 // links, we don't really need this | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
76 command = Arrays.asList("cmd", "/c", "dir"); | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
77 // Windows patterns need to work against full directory listing (I didn't find a way | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
78 // to list single file with its attributes like SYMLINK) | 
| 
713
 
661e77dc88ba
Mac support: respect Mac alternatives of command-line arguments for common unix tools
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
476 
diff
changeset
 | 
79 pLink = Pattern.compile("^\\S+.*\\s+<SYMLINK>\\s+(\\S.*)\\s+\\[(.+)\\]$", Pattern.MULTILINE); | 
| 
 
661e77dc88ba
Mac support: respect Mac alternatives of command-line arguments for common unix tools
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
476 
diff
changeset
 | 
80 pExec = Pattern.compile("^\\S+.*\\s+\\d+\\s+(\\S.*\\.exe)$", Pattern.MULTILINE); | 
| 
 
661e77dc88ba
Mac support: respect Mac alternatives of command-line arguments for common unix tools
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
476 
diff
changeset
 | 
81 } else if (Internals.runningOnMac()) { | 
| 
 
661e77dc88ba
Mac support: respect Mac alternatives of command-line arguments for common unix tools
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
476 
diff
changeset
 | 
82 command = Arrays.asList("/bin/ls", "-lnoT"); | 
| 
 
661e77dc88ba
Mac support: respect Mac alternatives of command-line arguments for common unix tools
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
476 
diff
changeset
 | 
83 // -n to present userid and group as digits | 
| 
 
661e77dc88ba
Mac support: respect Mac alternatives of command-line arguments for common unix tools
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
476 
diff
changeset
 | 
84 // -o don't need group | 
| 
 
661e77dc88ba
Mac support: respect Mac alternatives of command-line arguments for common unix tools
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
476 
diff
changeset
 | 
85 // -T complete time in standard format (used as boundary in the pattern) | 
| 
 
661e77dc88ba
Mac support: respect Mac alternatives of command-line arguments for common unix tools
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
476 
diff
changeset
 | 
86 // Perhaps, shall use -B for octal non-printable characters. Shall implement unescapeFilename, below, then. | 
| 
 
661e77dc88ba
Mac support: respect Mac alternatives of command-line arguments for common unix tools
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
476 
diff
changeset
 | 
87 pLink = Pattern.compile("^lrwxr.xr.x\\s.*\\s\\d\\d:\\d\\d:\\d\\d \\d\\d\\d\\d (.+) -> (.+)$", Pattern.MULTILINE); | 
| 
 
661e77dc88ba
Mac support: respect Mac alternatives of command-line arguments for common unix tools
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
476 
diff
changeset
 | 
88 pExec = Pattern.compile("^-..[sx]..[sx]..[sx]\\s.*\\s\\d\\d:\\d\\d:\\d\\d \\d\\d\\d\\d (.+)$", Pattern.MULTILINE); | 
| 
413
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
89 } else { | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
90 command = Arrays.asList("/bin/ls", "-l", "-Q"); // -Q is essential to get quoted name - the only way to | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
91 // tell exact file name (which may start or end with spaces. | 
| 
713
 
661e77dc88ba
Mac support: respect Mac alternatives of command-line arguments for common unix tools
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
476 
diff
changeset
 | 
92 pLink = Pattern.compile("^lrwxrwxrwx\\s.*\\s\"(.*)\"\\s+->\\s+\"(.*)\"$", Pattern.MULTILINE); | 
| 
413
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
93 // pLink: group(1) is full name if single file listing (ls -l /usr/bin/java) and short name if directory listing (ls -l /usr/bin) | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
94 // group(2) is link target | 
| 
713
 
661e77dc88ba
Mac support: respect Mac alternatives of command-line arguments for common unix tools
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
476 
diff
changeset
 | 
95 pExec = Pattern.compile("^-..[sx]..[sx]..[sx]\\s.*\\s\"(.+)\"$", Pattern.MULTILINE); | 
| 
413
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
96 // pExec: group(1) is name of executable file | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
97 } | 
| 
713
 
661e77dc88ba
Mac support: respect Mac alternatives of command-line arguments for common unix tools
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
476 
diff
changeset
 | 
98 linkMatcher = pLink.matcher(""); | 
| 
 
661e77dc88ba
Mac support: respect Mac alternatives of command-line arguments for common unix tools
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
476 
diff
changeset
 | 
99 execMatcher = pExec.matcher(""); | 
| 
413
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
100 execHelper = new ProcessExecHelper(); | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
101 } | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
102 | 
| 
425
 
48f993aa2f41
FIXMEs: exceptions, javadoc
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
423 
diff
changeset
 | 
103 /** | 
| 
 
48f993aa2f41
FIXMEs: exceptions, javadoc
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
423 
diff
changeset
 | 
104 * Fails silently indicating false for both x and l in case interaction with file system failed | 
| 
 
48f993aa2f41
FIXMEs: exceptions, javadoc
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
423 
diff
changeset
 | 
105 * @param f file to check, doesn't need to exist | 
| 
 
48f993aa2f41
FIXMEs: exceptions, javadoc
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
423 
diff
changeset
 | 
106 */ | 
| 
413
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
107 public void init(File f) { | 
| 
425
 
48f993aa2f41
FIXMEs: exceptions, javadoc
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
423 
diff
changeset
 | 
108 isExec = isSymlink = false; | 
| 
 
48f993aa2f41
FIXMEs: exceptions, javadoc
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
423 
diff
changeset
 | 
109 symlinkValue = null; | 
| 
 
48f993aa2f41
FIXMEs: exceptions, javadoc
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
423 
diff
changeset
 | 
110 // | 
| 
413
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
111 // can't check isFile because Java would say false for a symlink with non-existing target | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
112 if (f.isDirectory()) { | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
113 // perhaps, shall just collect stats for all files and set false to exec/link flags? | 
| 
429
 
cd658b24a620
FIXMEs: javadoc, proper use of constants
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
425 
diff
changeset
 | 
114 throw new IllegalArgumentException(); | 
| 
413
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
115 } | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
116 final String dirName = f.getParentFile().getAbsolutePath(); | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
117 final String fileName = f.getName(); | 
| 
476
 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
456 
diff
changeset
 | 
118 try { | 
| 
 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
456 
diff
changeset
 | 
119 Map<String, String> links = dir2links.get(dirName); | 
| 
 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
456 
diff
changeset
 | 
120 Set<String> execs = dir2execs.get(dirName); | 
| 
 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
456 
diff
changeset
 | 
121 if (links == null || execs == null) { | 
| 
413
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
122 ArrayList<String> cmd = new ArrayList<String>(command); | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
123 cmd.add(dirName); | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
124 CharSequence result = execHelper.exec(cmd); | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
125 | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
126 if (execMatcher.reset(result).find()) { | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
127 execs = new HashSet<String>(); | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
128 do { | 
| 
713
 
661e77dc88ba
Mac support: respect Mac alternatives of command-line arguments for common unix tools
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
476 
diff
changeset
 | 
129 execs.add(unescapeFilename(execMatcher.group(1))); | 
| 
413
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
130 } while (execMatcher.find()); | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
131 } else { | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
132 execs = Collections.emptySet(); // indicate we tried and found nothing | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
133 } | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
134 if (linkMatcher.reset(result).find()) { | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
135 links = new HashMap<String, String>(); | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
136 do { | 
| 
713
 
661e77dc88ba
Mac support: respect Mac alternatives of command-line arguments for common unix tools
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
476 
diff
changeset
 | 
137 links.put(unescapeFilename(linkMatcher.group(1)), unescapeFilename(linkMatcher.group(2))); | 
| 
413
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
138 } while (linkMatcher.find()); | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
139 } else { | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
140 links = Collections.emptyMap(); | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
141 } | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
142 dir2links.put(dirName, links); | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
143 dir2execs.put(dirName, execs); | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
144 } | 
| 
476
 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
456 
diff
changeset
 | 
145 isExec = execs.contains(fileName); | 
| 
 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
456 
diff
changeset
 | 
146 isSymlink = links.containsKey(fileName); | 
| 
 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
456 
diff
changeset
 | 
147 if (isSymlink) { | 
| 
 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
456 
diff
changeset
 | 
148 symlinkValue = links.get(fileName); | 
| 
 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
456 
diff
changeset
 | 
149 } else { | 
| 
 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
456 
diff
changeset
 | 
150 symlinkValue = null; | 
| 
 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
456 
diff
changeset
 | 
151 } | 
| 
 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
456 
diff
changeset
 | 
152 } catch (InterruptedException ex) { | 
| 
 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
456 
diff
changeset
 | 
153 sessionContext.getLog().dump(getClass(), Warn, ex, String.format("Failed to detect flags for %s", f)); | 
| 
 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
456 
diff
changeset
 | 
154 // try again? ensure not too long? stop right away? | 
| 
 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
456 
diff
changeset
 | 
155 // IGNORE, keep isExec and isSymlink false | 
| 
 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
456 
diff
changeset
 | 
156 } catch (IOException ex) { | 
| 
 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
456 
diff
changeset
 | 
157 sessionContext.getLog().dump(getClass(), Warn, ex, String.format("Failed to detect flags for %s", f)); | 
| 
 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
456 
diff
changeset
 | 
158 // IGNORE, keep isExec and isSymlink false | 
| 
413
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
159 } | 
| 
713
 
661e77dc88ba
Mac support: respect Mac alternatives of command-line arguments for common unix tools
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
476 
diff
changeset
 | 
160 } | 
| 
413
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
161 | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
162 public boolean isExecutable() { | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
163 return isExec; | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
164 } | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
165 | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
166 public boolean isSymlink() { | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
167 return isSymlink; | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
168 } | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
169 | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
170 public String getSymlinkTarget() { | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
171 if (isSymlink) { | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
172 return symlinkValue; | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
173 } | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
174 throw new UnsupportedOperationException(); | 
| 
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
175 } | 
| 
713
 
661e77dc88ba
Mac support: respect Mac alternatives of command-line arguments for common unix tools
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
476 
diff
changeset
 | 
176 | 
| 
 
661e77dc88ba
Mac support: respect Mac alternatives of command-line arguments for common unix tools
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
476 
diff
changeset
 | 
177 // FIXME nop at the moment, but need to implement if use escape code for non-printable characters | 
| 
 
661e77dc88ba
Mac support: respect Mac alternatives of command-line arguments for common unix tools
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
476 
diff
changeset
 | 
178 private static String unescapeFilename(String cs) { | 
| 
 
661e77dc88ba
Mac support: respect Mac alternatives of command-line arguments for common unix tools
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
476 
diff
changeset
 | 
179 return cs; | 
| 
 
661e77dc88ba
Mac support: respect Mac alternatives of command-line arguments for common unix tools
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents: 
476 
diff
changeset
 | 
180 } | 
| 
413
 
7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
 
Artem Tikhomirov <tikhomirov.artem@gmail.com> 
parents:  
diff
changeset
 | 
181 } | 
