001: /**
002: * $Id: ExecuteUtil.java,v 1.7 2007/01/26 03:48:34 portalbld Exp $
003: * Copyright 2004 Sun Microsystems, Inc. All
004: * rights reserved. Use of this product is subject
005: * to license terms. Federal Acquisitions:
006: * Commercial Software -- Government Users
007: * Subject to Standard License Terms and
008: * Conditions.
009: *
010: * Sun, Sun Microsystems, the Sun logo, and Sun ONE
011: * are trademarks or registered trademarks of Sun Microsystems,
012: * Inc. in the United States and other countries.
013: */package com.sun.portal.fabric.util;
014:
015: import java.io.File;
016: import java.io.IOException;
017: import java.util.logging.Level;
018: import java.util.logging.Logger;
019: import java.util.logging.LogRecord;
020:
021: import com.sun.portal.util.Platform;
022:
023: import com.sun.portal.log.common.PortalLogger;
024:
025: /**
026: * Constructor for the Execute Utility
027: */
028: public class ExecuteUtil {
029:
030: /**
031: * Logger object to be used for logging output
032: */
033: private static Logger logger = PortalLogger
034: .getLogger(ExecuteUtil.class);
035:
036: /**
037: * Flag used to determine if output stream data needs to be stored after the exec
038: * method is invoked
039: */
040: private boolean storeOutput = false;
041:
042: /**
043: * Flag used to determine if error stream data needs to be stored after the exec
044: * method is invoked
045: */
046: private boolean storeError = false;
047:
048: /**
049: * Data in output stream is stored in this string
050: */
051: private String execOutput = null;
052:
053: /**
054: * Data in error stream is stored in this string
055: */
056: private String execError = null;
057:
058: /**
059: * This method should be used to instruct the ExecuteUtil object to
060: * retain the output of the process. This method should be invoked
061: * with the correct params before the <B>exec</B> method is invoked
062: * @param preserve boolean value flag that is used to decide if the output
063: of the process needs to be store for retrival after the execution
064: */
065: public void storeOutput(boolean preserve) {
066: storeOutput = preserve;
067: }
068:
069: /**
070: * This method should be used to instruct the ExecuteUtil object to
071: * retain the error of the process. This method should be invoked
072: * with the correct params before the <B>exec</B> method is invoked
073: * @param preserve boolean value flag that is used to decide if the error
074: * stream of the process needs to be store for retrival after the
075: * execution
076: */
077: public void storeError(boolean preserve) {
078: storeError = preserve;
079: }
080:
081: /**
082: * Gets the data that was collected from the error stream of the process
083: * that was executed before this call
084: * @return Returns the content of the error stream as a String.
085: * A <CODE>null</CODE> is returned if the <CODE>storeError()</CODE>
086: * method was not called before the <CODE>exec</CODE> call
087: */
088: public String getError() {
089: return execError;
090: }
091:
092: /**
093: * Gets the data that was collected from the output stream of the process
094: * that was executed before this call
095: * @return Returns the content of the output stream as a String.
096: * A <CODE>null</CODE> is returned if the <CODE>storeOutput()</CODE>
097: * method was not called before the <CODE>exec</CODE> call
098: */
099: public String getOutput() {
100: return execOutput;
101: }
102:
103: /**
104: * Executes a command using the Runtime object
105: * @param command Command as a String
106: * @param args A String array of arguments that the command needs for execution
107: * @return Returns the exit value of the command that was executed
108: */
109: public int exec(String command, String[] args) {
110: return exec(command, args, null);
111: }
112:
113: private static boolean isWinOS() {
114: return Platform.name.equals("windows");
115: }
116:
117: /**
118: * Executes a command using the Runtime object
119: * @param command Command as a String
120: * @param args A String array of arguments that the command needs for execution
121: * @param envs A String array of environment variables
122: * @return Returns the exit value of the command that was executed
123: */
124: public int exec(String command, String[] args, String[] envs) {
125:
126: int exitVal = -1;
127:
128: // Reset Ouput and Error to null
129: execOutput = null;
130: execError = null;
131:
132: int size = (args == null) ? 1 : 1 + args.length;
133:
134: File parent = new File(command).getParentFile();
135: if (isWinOS()) {
136: size += (parent == null) ? 2 : 7;
137: }
138:
139: String[] cmdList = new String[size];
140:
141: if (isWinOS()) {
142:
143: if (parent == null) {
144: cmdList[0] = "cmd";
145: cmdList[1] = "/c";
146: cmdList[2] = command;
147: if (args != null) {
148: for (int i = 0; i < args.length; i++) {
149: cmdList[i + 3] = args[i];
150: }
151: }
152: } else {
153:
154: String cmdDir = null;
155:
156: try {
157: cmdDir = parent.getCanonicalPath();
158: } catch (IOException ioe) {
159: // Cannot get canonical path
160: // hardcode
161: cmdDir = "c:";
162: }
163:
164: cmdList[0] = "cmd";
165: cmdList[1] = "/c";
166: cmdList[2] = cmdDir.substring(0, 2);
167: cmdList[3] = "&&";
168: cmdList[4] = "cd";
169: cmdList[5] = cmdDir.substring(2);
170: cmdList[6] = "&&";
171: cmdList[7] = command;
172: if (args != null) {
173: for (int i = 0; i < args.length; i++) {
174: cmdList[i + 8] = args[i];
175: }
176: }
177: }
178: } else {
179: cmdList[0] = command;
180: if (args != null) {
181: for (int i = 0; i < args.length; i++) {
182: cmdList[i + 1] = args[i];
183: }
184: }
185: }
186:
187: try {
188:
189: Runtime rt = Runtime.getRuntime();
190: Process proc = rt.exec(cmdList, envs);
191:
192: StreamLogger procOutputLogger = new StreamLogger(proc
193: .getInputStream(), command + "(Output)",
194: storeOutput);
195: if (isWinOS())
196: new Thread(procOutputLogger).start();
197: else
198: procOutputLogger.run();
199: StreamLogger procErrorLogger = new StreamLogger(proc
200: .getErrorStream(), command + "(Error)", storeError);
201: if (isWinOS())
202: new Thread(procErrorLogger).start();
203: else
204: procErrorLogger.run();
205:
206: exitVal = waitFor(proc);
207: closeStreams(proc);
208:
209: if (storeOutput) {
210: execOutput = procOutputLogger.getContent();
211: }
212:
213: if (storeError) {
214: execError = procErrorLogger.getContent();
215: }
216: } catch (IOException e) {
217:
218: if (logger.isLoggable(Level.SEVERE)) {
219: LogRecord record = new LogRecord(Level.SEVERE,
220: "PSFB_CSPFU0003");
221: record.setParameters(new String[] { command });
222: record.setThrown(e);
223: record.setLoggerName(logger.getName());
224: logger.log(record);
225: }
226: }
227:
228: return exitVal;
229:
230: }
231:
232: /**
233: * Waits for a given process and sets the exit value
234: * @param process the process that needs to be waited for
235: * @return Returns the exit value of the process what is being waited for
236: */
237: private int waitFor(Process process) {
238:
239: int exitValue = -1;
240:
241: try {
242: process.waitFor();
243: exitValue = process.exitValue();
244: } catch (InterruptedException e) {
245: process.destroy();
246: }
247: return exitValue;
248: }
249:
250: /**
251: * Close the streams belonging to the given Process.
252: * @param process the <CODE>Process</CODE>.
253: */
254: private void closeStreams(Process process) {
255: try {
256: if (!isWinOS())
257: process.getInputStream().close();
258: } catch (IOException eyeOhEx) {
259: }
260: try {
261: if (!isWinOS())
262: process.getOutputStream().close();
263: } catch (IOException eyeOhEx) {
264: }
265: try {
266: if (!isWinOS())
267: process.getErrorStream().close();
268: } catch (IOException eyeOhEx) {
269: }
270: }
271:
272: }
|