001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.commons.cli; 020 021import java.io.IOException; 022import java.io.InputStream; 023import java.util.ArrayList; 024 025import lucee.commons.io.IOUtil; 026import lucee.commons.io.SystemUtil; 027import lucee.commons.lang.StringUtil; 028 029public class Command { 030 031 public static Process createProcess(String cmdline,boolean translate) throws IOException { 032 if(!translate)return Runtime.getRuntime().exec(cmdline); 033 return Runtime.getRuntime().exec(toArray(cmdline)); 034 } 035 036 /** 037 * @param cmdline command line 038 * @param translate translate the command line or not 039 * @return 040 * @throws IOException 041 * @throws InterruptedException 042 */ 043 public static CommandResult execute(String cmdline,boolean translate) throws IOException, InterruptedException { 044 if(!translate)return execute(Runtime.getRuntime().exec(cmdline)); 045 return execute(Runtime.getRuntime().exec(toArray(cmdline))); 046 } 047 048 public static CommandResult execute(String[] cmdline) throws IOException, InterruptedException { 049 return execute(Runtime.getRuntime().exec(cmdline)); 050 } 051 public static CommandResult execute(String cmd,String[] args) throws IOException, InterruptedException { 052 return execute(StringUtil.merge(cmd,args)); 053 } 054 055 public static CommandResult execute(Process p) throws IOException, InterruptedException { 056 InputStream is=null; 057 InputStream es=null; 058 IOException ioe; 059 try { 060 StreamGobbler in=new StreamGobbler(is=p.getInputStream()); 061 StreamGobbler err=new StreamGobbler(es=p.getErrorStream()); 062 in.start(); 063 err.start(); 064 if(p.waitFor()!=0){ 065 err.join(); 066 if((ioe=err.getException())!=null) throw ioe; 067 String str=err.getString(); 068 if(!StringUtil.isEmpty(str)) 069 throw new CommandException(str); 070 } 071 in.join(); 072 if((ioe=in.getException())!=null) throw ioe; 073 074 return new CommandResult( in.getString(), err.getString() ); 075 } 076 finally { 077 IOUtil.closeEL(is); 078 IOUtil.closeEL(es); 079 } 080 } 081 082 083 084 085 private static String[] toArray(String str) { 086 if(StringUtil.isEmpty(str)) return new String[]{""}; 087 str=str.trim(); 088 StringBuilder sb=new StringBuilder(); 089 ArrayList<String> list=new ArrayList<String>(); 090 char[] carr = str.toCharArray(); 091 char c;//,last=0; 092 char inside=0; 093 for(int i=0;i<carr.length;i++){ 094 c=carr[i]; 095 //if(i>0)last=carr[i-1]; 096 switch(c){ 097 // DELIMITER 098 /*case '\\': 099 if(i+1<carr.length){ 100 sb.append(carr[++i]); 101 } 102 else sb.append(c); 103 break;*/ 104 // QUOTE 105 case '\'': 106 case '"': 107 if(inside==0){ 108 if(str.lastIndexOf(c)>i) 109 inside=c; 110 else 111 sb.append(c); 112 } 113 else if(inside==c) { 114 inside=0; 115 } 116 else sb.append(c); 117 break; 118 // WHITE SPACE 119 case ' ': 120 case '\b': 121 case '\t': 122 case '\n': 123 case '\r': 124 case '\f': 125 //if(last=='\\')sb.setCharAt(sb.length()-1,c); 126 if(inside==0) { 127 populateList(sb,list); 128 } 129 else sb.append(c); 130 break; 131 // OTHERS 132 default: 133 sb.append(c); 134 } 135 } 136 populateList(sb, list); 137 138 139 return list.toArray(new String[list.size()]); 140 } 141 142 private static void populateList(StringBuilder sb, ArrayList<String> list) { 143 144 String tmp = sb.toString(); 145 tmp=tmp.trim(); 146 if(tmp.length()>0)list.add(tmp); 147 sb.delete(0, sb.length()); 148 } 149} 150 151 152class StreamGobbler extends Thread { 153 154 155 InputStream is; 156 private String str; 157 private IOException ioe; 158 159 StreamGobbler(InputStream is) { 160 this.is = is; 161 } 162 163 @Override 164 public void run() { 165 try { 166 str=IOUtil.toString(is,SystemUtil.getCharset()); 167 } catch (IOException ioe) { 168 this.ioe=ioe; 169 } 170 } 171 172 /** 173 * @return the str 174 */ 175 public String getString() { 176 return str; 177 } 178 179 /** 180 * @return the ioe 181 */ 182 public IOException getException() { 183 return ioe; 184 } 185 186}