001/* 002 * jPOS Project [http://jpos.org] 003 * Copyright (C) 2000-2026 jPOS Software SRL 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Affero General Public License as 007 * published by the Free Software Foundation, either version 3 of the 008 * License, or (at your option) any later version. 009 * 010 * This program 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 013 * GNU Affero General Public License for more details. 014 * 015 * You should have received a copy of the GNU Affero General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018 019package org.jpos.q2.qbean; 020 021import org.jpos.q2.QBeanSupport; 022import org.jpos.util.LogEvent; 023import org.jpos.util.Logger; 024 025import java.io.*; 026import java.util.ArrayList; 027import java.util.List; 028 029/** 030* QBean for starting and stopping scripts or programs. 031* <pre> 032* Example xml: 033* <exec class="org.jpos.q2.qbean.QExec"> 034* <attr name="startScript">YOUR PATH TO PROGRAM</attr> 035* <attr name="shutdownScript">YOUR PATH TO PROGRAM</attr> 036* </exec> 037* </pre> 038* @author Alwyn Schoeman 039* @version $Revision$ $Date$ 040*/ 041 042public class QExec extends QBeanSupport implements QExecMBean { 043 String startScript; 044 String shutdownScript; 045 046 @Override 047 protected void startService () throws Exception { 048 exec(startScript); 049 } 050 051 @Override 052 protected void stopService () throws Exception { 053 exec(shutdownScript); 054 } 055 056 public void setStartScript (String scriptPath) { 057 startScript = scriptPath; 058 } 059 060 public String getStartScript () { 061 return startScript; 062 } 063 064 public void setShutdownScript (String scriptPath) { 065 shutdownScript = scriptPath; 066 } 067 068 public String getShutdownScript () { 069 return shutdownScript; 070 } 071 072 private void exec (String script) throws IOException, InterruptedException { 073 if (script != null) { 074 ProcessBuilder pb = new ProcessBuilder (parseCommandLine(script)); 075 Process p = pb.start(); 076 BufferedReader in = p.inputReader(); 077 LogEvent evt = getLog().createInfo("--- " + script + " ---"); 078 String line; 079 while ((line = in.readLine()) != null) { 080 evt.addMessage(line); 081 } 082 p.waitFor(); 083 Logger.log(evt); 084 } 085 } 086 087 public static List<String> parseCommandLine(String commandLine) { 088 if (commandLine == null || commandLine.isEmpty()) 089 throw new IllegalArgumentException("Empty command"); 090 List<String> args = new ArrayList<>(); 091 StringBuilder currentArg = new StringBuilder(); 092 boolean inQuotes = false; 093 boolean isEscaped = false; 094 095 for (int i = 0; i < commandLine.length(); i++) { 096 char c = commandLine.charAt(i); 097 098 if (c == '\\' && !isEscaped) { 099 isEscaped = true; 100 continue; 101 } 102 103 if (c == '\"' && !isEscaped) { 104 inQuotes = !inQuotes; 105 } else { 106 if (c == ' ' && !inQuotes) { 107 if (currentArg.length() > 0) { 108 args.add(currentArg.toString()); 109 currentArg.setLength(0); 110 } 111 } else { 112 currentArg.append(c); 113 } 114 } 115 116 if (isEscaped) { 117 isEscaped = false; 118 } 119 } 120 121 if (currentArg.length() > 0) { 122 args.add(currentArg.toString()); 123 } 124 125 return args; 126 } 127 128}