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: 
429diff
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: 
429diff
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: 
423diff
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: 
413diff
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: 
423diff
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: 
423diff
changeset | 69 RegularFileStats(SessionContext ctx) { | 
| 
48f993aa2f41
FIXMEs: exceptions, javadoc
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
423diff
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: 
476diff
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: 
476diff
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: 
476diff
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: 
476diff
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: 
476diff
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: 
476diff
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: 
476diff
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: 
476diff
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: 
476diff
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: 
476diff
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: 
476diff
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: 
476diff
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: 
476diff
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: 
476diff
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: 
476diff
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: 
423diff
changeset | 103 /** | 
| 
48f993aa2f41
FIXMEs: exceptions, javadoc
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
423diff
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: 
423diff
changeset | 105 * @param f file to check, doesn't need to exist | 
| 
48f993aa2f41
FIXMEs: exceptions, javadoc
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
423diff
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: 
423diff
changeset | 108 isExec = isSymlink = false; | 
| 
48f993aa2f41
FIXMEs: exceptions, javadoc
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
423diff
changeset | 109 symlinkValue = null; | 
| 
48f993aa2f41
FIXMEs: exceptions, javadoc
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
423diff
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: 
425diff
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: 
456diff
changeset | 118 try { | 
| 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
456diff
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: 
456diff
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: 
456diff
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: 
476diff
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: 
476diff
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: 
456diff
changeset | 145 isExec = execs.contains(fileName); | 
| 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
456diff
changeset | 146 isSymlink = links.containsKey(fileName); | 
| 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
456diff
changeset | 147 if (isSymlink) { | 
| 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
456diff
changeset | 148 symlinkValue = links.get(fileName); | 
| 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
456diff
changeset | 149 } else { | 
| 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
456diff
changeset | 150 symlinkValue = null; | 
| 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
456diff
changeset | 151 } | 
| 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
456diff
changeset | 152 } catch (InterruptedException ex) { | 
| 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
456diff
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: 
456diff
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: 
456diff
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: 
456diff
changeset | 156 } catch (IOException ex) { | 
| 
c02b5710d9ac
Defect: only first file in directory got flags initialized
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
456diff
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: 
456diff
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: 
476diff
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: 
476diff
changeset | 176 | 
| 
661e77dc88ba
Mac support: respect Mac alternatives of command-line arguments for common unix tools
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
476diff
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: 
476diff
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: 
476diff
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: 
476diff
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 } | 
