/** * # Copyright (c) 2009, Perforce Software, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL PERFORCE SOFTWARE, INC. BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.perforce.p4java.extras; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; /** * File helper that execs platform-specific commands to be used on Java 1.5 * systems that don't have access to file commands available in 1.6 * java.io.File. * * @author Kevin Sawicki (ksawicki@perforce.com) * */ public class ExecFileCommandsHelper implements P4JSystemFileCommandsHelper { /** * WINDOWS_OS */ public static final String WINDOWS_OS = "windows"; /** * ATTRIB - attrib command name */ public static final String ATTRIB = "attrib"; /** * LS - ls command name */ public static final String LS = "ls"; /** * CHMOD - chmod command name */ public static final String CHMOD = "chmod"; /** * LS_DEFAULT */ public static final String LS_DEFAULT = "/bin/" + LS; /** * CHMOD_DEFAULT */ public static final String CHMOD_DEFAULT = "/bin/" + CHMOD; private class ExecOutput { int returnCode; String response; } boolean onWindows = false; boolean onUnix = false; private String lsCommand = null; private String chmodCommand = null; private String attribCommand = null; /** * Create a file commands helper that execs processes to change file * permissions */ public ExecFileCommandsHelper() { String os = System.getProperty("os.name"); if (os != null) { if (os.toLowerCase().contains(WINDOWS_OS)) { onWindows = true; attribCommand = ATTRIB; } else { // Assume unix-like OS with access to chmod onUnix = true; if (new File(LS_DEFAULT).exists()) { lsCommand = LS_DEFAULT; } else { // Fall-back to relative ls lsCommand = LS; } if (new File(CHMOD_DEFAULT).exists()) { chmodCommand = CHMOD_DEFAULT; } else { // Fall-back to relative chmod binary name chmodCommand = CHMOD; } } } } private ExecOutput exec(String command, String[] args, String fileName) { ExecOutput execOutput = new ExecOutput(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); PrintWriter output = new PrintWriter(outputStream, true); List<String> fullCommand = new ArrayList<String>(); fullCommand.add(command); if (args != null) { for (String arg : args) { fullCommand.add(arg); } } fullCommand.add(fileName); BufferedReader processOutputReader = null; ProcessBuilder builder = new ProcessBuilder(fullCommand); int returnCode = -1; try { Process process = builder.start(); processOutputReader = new BufferedReader(new InputStreamReader( process.getInputStream())); String line = processOutputReader.readLine(); while (line != null) { output.println(line); line = processOutputReader.readLine(); } returnCode = process.waitFor(); } catch (IOException e) { P4JLog.exception(e); } catch (InterruptedException e) { P4JLog.exception(e); } finally { output.close(); if (processOutputReader != null) { try { processOutputReader.close(); } catch (IOException e) { } } } execOutput.returnCode = returnCode; execOutput.response = outputStream.toString(); return execOutput; } /** * @see com.perforce.p4java.impl.generic.sys.P4JSystemFileCommandsHelper#canExecute(java.lang.String) */ public boolean canExecute(String fileName) { boolean executable = false; if (fileName != null) { if (onWindows) { // All files executable on Windows executable = true; } else if (onUnix) { ExecOutput output = exec(lsCommand, new String[] { "-aF" }, fileName); // Remove trailing newlines output.response = output.response.trim(); if (output.response.endsWith("*")) { if (!fileName.endsWith("*")) { executable = true; } else { // Handle case where file ends with one or more '*' int lastSlash = output.response.lastIndexOf('/'); if (lastSlash != -1 && lastSlash + 1 < output.response.length()) { String outputName = output.response .substring(lastSlash + 1); String name = new File(fileName).getName(); executable = outputName.equals(name + "*"); } } } } } return executable; } /** * @see com.perforce.p4java.impl.generic.sys.P4JSystemFileCommandsHelper#isSymlink(java.lang.String) */ public boolean isSymlink(String fileName) { // No current symlink detection support return false; } /** * @see com.perforce.p4java.impl.generic.sys.P4JSystemFileCommandsHelper#setExecutable(java.lang.String, * boolean, boolean) */ public boolean setExecutable(String fileName, boolean executable, boolean ownerOnly) { boolean madeExecutable = false; if (fileName != null) { if (onWindows) { // All files executable on Windows madeExecutable = true; } else if (onUnix) { String arg = ownerOnly ? "u+x" : "a+x"; madeExecutable = exec(chmodCommand, new String[] { arg }, fileName).returnCode == 0; } } return madeExecutable; } /** * @see com.perforce.p4java.impl.generic.sys.P4JSystemFileCommandsHelper#setOwnerReadOnly(java.lang.String) */ public boolean setOwnerReadOnly(String fileName) { boolean set = setReadable(fileName, false, false); set &= setReadable(fileName, true, true); return false; } /** * @see com.perforce.p4java.impl.generic.sys.P4JSystemFileCommandsHelper#setReadable(java.lang.String, * boolean, boolean) */ public boolean setReadable(String fileName, boolean readable, boolean ownerOnly) { boolean madeReadable = false; if (fileName != null) { if (onWindows) { // All files readable on Windows madeReadable = true; } else if (onUnix) { String arg = (ownerOnly ? "u" : "a") + (readable ? "+r" : "-r"); madeReadable = exec(chmodCommand, new String[] { arg }, fileName).returnCode == 0; } } return madeReadable; } /** * @see com.perforce.p4java.impl.generic.sys.P4JSystemFileCommandsHelper#setWritable(java.lang.String, * boolean) */ public boolean setWritable(String fileName, boolean writable) { boolean madeWritable = false; if (fileName != null) { if (onWindows) { String arg = writable ? "-R" : "+R"; madeWritable = exec(attribCommand, new String[] { arg }, fileName).returnCode == 0; } else if (onUnix) { String arg = writable ? "+w" : "-w"; madeWritable = exec(chmodCommand, new String[] { arg }, fileName).returnCode == 0; } } return madeWritable; } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#2 | 7392 | Kevin Sawicki | Use String.trim() when checking output of ls from canExecute. | ||
#1 | 7391 | Kevin Sawicki |
Adding p4java extras project to the public depot with ExecFileCommandsHelper. |