/******************************************************************************
* Product: Adempiere ERP & CRM Smart Business Solution *
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. This program is distributed in the hope *
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
* For the text or an alternative of this public license, you may reach us *
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
* or via info@compiere.org or http://www.compiere.org/license.html *
*****************************************************************************/
package org.compiere.util;
import java.awt.Dimension;
import java.awt.Point;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.sql.Timestamp;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import org.adempiere.exceptions.AdempiereException;
import org.compiere.Adempiere;
import org.compiere.model.ModelValidationEngine;
import org.compiere.model.SystemProperties;
/**
* Load and Save Settings from property file (idempiere.properties).
* Initiated in {@link Adempiere#startup(boolean)}
*
* @author Jorg Janke
* @version $Id$
*
* @author Teo Sarca, www.arhipac.ro
*
FR [ 1658127 ] Select charset encoding on import
* FR [ 2406123 ] Ini.saveProperties fails if target directory does not exist
*/
public final class Ini implements Serializable
{
/**
* generated serial id
*/
private static final long serialVersionUID = -8936090051638559660L;
/** Logger */
private static CLogger log = CLogger.getCLogger(Ini.class);
/** Property file name */
public static final String IDEMPIERE_PROPERTY_FILE = "idempiere.properties";
/** Apps User ID */
public static final String P_UID = "ApplicationUserID";
private static final String DEFAULT_UID = "GardenAdmin";
/** Apps Password */
public static final String P_PWD = "ApplicationPassword";
private static final String DEFAULT_PWD = "";
/** Store Password */
public static final String P_STORE_PWD = "StorePassword";
private static final boolean DEFAULT_STORE_PWD = false;
/** Trace Level */
public static final String P_TRACELEVEL = "TraceLevel";
private static final String DEFAULT_TRACELEVEL = "WARNING";
/** Trace to File */
public static final String P_TRACEFILE = "TraceFile";
private static final boolean DEFAULT_TRACEFILE = false;
/** Language */
public static final String P_LANGUAGE = "Language";
private static final String DEFAULT_LANGUAGE = Language.getName(System.getProperty("user.language") + "_" + System.getProperty("user.country"));
/** Ini File Name */
public static final String P_INI = "FileNameINI";
private static final String DEFAULT_INI = "";
/** Connection Details */
public static final String P_CONNECTION = "Connection";
private static final String DEFAULT_CONNECTION = "";
/** Data Source */
public static final String P_CONTEXT = "DataSource";
private static final String DEFAULT_CONTEXT = "java:adempiereDB";
/** Look and Feel */
public static final String P_UI_LOOK = "UILookFeel";
private static final String DEFAULT_UI_LOOK = "Adempiere";
/** UI Theme */
private static final String DEFAULT_UI_THEME = "Adempiere Theme";
/** UI Theme */
public static final String P_UI_THEME = "UITheme";
/** Auto Commit */
public static final String P_A_COMMIT = "AutoCommit";
private static final boolean DEFAULT_A_COMMIT = true;
/** Auto Login */
public static final String P_A_LOGIN = "AutoLogin";
private static final boolean DEFAULT_A_LOGIN = false;
/** Auto New Record */
public static final String P_A_NEW = "AutoNew";
private static final boolean DEFAULT_A_NEW = false;
/** Dictionary Maintenance */
public static final String P_ADEMPIERESYS = "AdempiereSys"; // Save system records
private static final boolean DEFAULT_ADEMPIERESYS = false;
/** Log Migration Script */
public static final String P_LOGMIGRATIONSCRIPT = "LogMigrationScript"; // Log migration script
private static final boolean DEFAULT_LOGMIGRATIONSCRIPT = false;
/** Show Acct Tabs */
public static final String P_SHOW_ACCT = "ShowAcct";
private static final boolean DEFAULT_SHOW_ACCT = true;
/** Show Translation Tabs */
public static final String P_SHOW_TRL = "ShowTrl";
private static final boolean DEFAULT_SHOW_TRL = false;
/** Cache Windows */
public static final String P_CACHE_WINDOW = "CacheWindow";
private static final boolean DEFAULT_CACHE_WINDOW = true;
/** Temp Directory */
public static final String P_TEMP_DIR = "TempDir";
private static final String DEFAULT_TEMP_DIR = "";
/** Role */
public static final String P_ROLE = "Role";
private static final String DEFAULT_ROLE = "";
/** Client Name */
public static final String P_CLIENT = "Client";
private static final String DEFAULT_CLIENT = "";
/** Org Name */
public static final String P_ORG = "Organization";
private static final String DEFAULT_ORG = "";
/** Printer Name */
public static final String P_PRINTER = "Printer";
private static final String DEFAULT_PRINTER = "";
/** Warehouse Name */
public static final String P_WAREHOUSE = "Warehouse";
private static final String DEFAULT_WAREHOUSE = "";
/** Current Date */
public static final String P_TODAY = "CDate";
private static final Timestamp DEFAULT_TODAY = new Timestamp(System.currentTimeMillis());
/** Print Preview */
public static final String P_PRINTPREVIEW = "PrintPreview";
private static final boolean DEFAULT_PRINTPREVIEW = false;
/** Validate connection on startup */
public static final String P_VALIDATE_CONNECTION_ON_STARTUP = "ValidateConnectionOnStartup";
private static final boolean DEFAULT_VALIDATE_CONNECTION_ON_STARTUP = false;
/** Single instance per window id **/
public static final String P_SINGLE_INSTANCE_PER_WINDOW = "SingleInstancePerWindow";
public static final boolean DEFAULT_SINGLE_INSTANCE_PER_WINDOW = false;
/** Open new windows as maximized **/
public static final String P_OPEN_WINDOW_MAXIMIZED = "OpenWindowMaximized";
public static final boolean DEFAULT_OPEN_WINDOW_MAXIMIZED = false;
//
private static final String P_WARNING = "Warning";
private static final String DEFAULT_WARNING = "Do_not_change_any_of_the_data_as_they_will_have_undocumented_side_effects.";
private static final String P_WARNING_de = "WarningD";
private static final String DEFAULT_WARNING_de ="Einstellungen_nicht_aendern,_da_diese_undokumentierte_Nebenwirkungen_haben.";
/** Charset */
public static final String P_CHARSET = "Charset";
/** Charser Default Value */
private static final String DEFAULT_CHARSET = "UTF-8";
/** Load tab fields meta data using background thread **/
public static final String P_LOAD_TAB_META_DATA_BG = "LoadTabMetaDataBackground";
public static final String DEFAULT_LOAD_TAB_META_DATA_BG = "N";
/** Ini Properties */
private static final String[] PROPERTIES = new String[] {
P_UID, P_PWD, P_TRACELEVEL, P_TRACEFILE,
P_LANGUAGE, P_INI,
P_CONNECTION, P_STORE_PWD,
P_UI_LOOK, P_UI_THEME, /* P_UI_FLAT,*/
P_A_COMMIT, P_A_LOGIN, P_A_NEW,
P_ADEMPIERESYS, P_LOGMIGRATIONSCRIPT, P_SHOW_ACCT, P_SHOW_TRL,
P_CACHE_WINDOW,
P_CONTEXT, P_TEMP_DIR,
P_ROLE, P_CLIENT, P_ORG, P_PRINTER, P_WAREHOUSE, P_TODAY,
P_PRINTPREVIEW,
P_VALIDATE_CONNECTION_ON_STARTUP,
P_SINGLE_INSTANCE_PER_WINDOW,
P_OPEN_WINDOW_MAXIMIZED,
P_WARNING, P_WARNING_de,
P_CHARSET, P_LOAD_TAB_META_DATA_BG
};
/** Ini Property Values */
private static final String[] VALUES = new String[] {
DEFAULT_UID, DEFAULT_PWD, DEFAULT_TRACELEVEL, DEFAULT_TRACEFILE?"Y":"N",
DEFAULT_LANGUAGE, DEFAULT_INI,
DEFAULT_CONNECTION, DEFAULT_STORE_PWD?"Y":"N",
DEFAULT_UI_LOOK, DEFAULT_UI_THEME, /* DEFAULT_UI_FLAT?"Y":"N", */
DEFAULT_A_COMMIT?"Y":"N", DEFAULT_A_LOGIN?"Y":"N", DEFAULT_A_NEW?"Y":"N",
DEFAULT_ADEMPIERESYS?"Y":"N", DEFAULT_LOGMIGRATIONSCRIPT?"Y":"N", DEFAULT_SHOW_ACCT?"Y":"N", DEFAULT_SHOW_TRL?"Y":"N",
DEFAULT_CACHE_WINDOW?"Y":"N",
DEFAULT_CONTEXT, DEFAULT_TEMP_DIR,
DEFAULT_ROLE, DEFAULT_CLIENT, DEFAULT_ORG, DEFAULT_PRINTER, DEFAULT_WAREHOUSE, DEFAULT_TODAY.toString(),
DEFAULT_PRINTPREVIEW?"Y":"N",
DEFAULT_VALIDATE_CONNECTION_ON_STARTUP?"Y":"N",
DEFAULT_SINGLE_INSTANCE_PER_WINDOW?"Y":"N",
DEFAULT_OPEN_WINDOW_MAXIMIZED?"Y":"N",
DEFAULT_WARNING, DEFAULT_WARNING_de,
DEFAULT_CHARSET, DEFAULT_LOAD_TAB_META_DATA_BG
};
/** Container for Properties */
private volatile static Properties s_prop = new Properties();
private static String s_propertyFileName = null;
/**
* Save INI parameters to disk
* @param tryUserHome true to try user home first
*/
@SuppressWarnings("deprecation")
public static void saveProperties (boolean tryUserHome)
{
if (Ini.isClient() && DB.isConnected()) {
// Call ModelValidators beforeSaveProperties
ModelValidationEngine.get().beforeSaveProperties();
}
String fileName = getFileName (tryUserHome);
FileOutputStream fos = null;
try
{
File f = new File(fileName);
f.getAbsoluteFile().getParentFile().mkdirs(); // Create all dirs if not exist - teo_sarca FR [ 2406123 ]
fos = new FileOutputStream(f);
s_prop.store(fos, "Adempiere");
fos.flush();
}
catch (Exception e)
{
log.log(Level.SEVERE, "Cannot save Properties to " + fileName + " - " + e.toString(), e);
return;
}
catch (Throwable t)
{
log.log(Level.SEVERE, "Cannot save Properties to " + fileName + " - " + t.toString(), t);
return;
}
finally
{
if (fos != null)
{
try
{
fos.close();
}
catch (Exception e)
{
log.log(Level.SEVERE, "Cannot close Properties to " + fileName + " - " + e.toString(), e);
}
}
}
if (log.isLoggable(Level.FINER)) log.finer(fileName);
} // save
/**
* Load INI parameters from disk
* @param reload reload
*/
public static void loadProperties (boolean reload)
{
if (reload || s_prop.size() == 0)
{
loadProperties(getFileName(s_client));
}
} // loadProperties
/**
* Load INI parameters from filename.
* Logger is on default level (INFO)
* @param filename to load
* @return true if first time
*/
public static boolean loadProperties (String filename)
{
boolean loadOK = true;
boolean firstTime = false;
s_prop = new Properties();
FileInputStream fis = null;
try
{
fis = new FileInputStream(filename);
s_prop.load(fis);
}
catch (FileNotFoundException e)
{
log.warning(filename + " not found");
loadOK = false;
}
catch (Exception e)
{
log.log(Level.SEVERE, filename + " - " + e.toString());
loadOK = false;
}
catch (Throwable t)
{
log.log(Level.SEVERE, filename + " - " + t.toString());
loadOK = false;
}
finally
{
if (fis != null)
{
try
{
fis.close();
}
catch (Exception e) {}
}
}
if (!loadOK || s_prop.getProperty(P_TODAY, "").equals(""))
{
if (log.isLoggable(Level.CONFIG)) log.config(filename);
firstTime = true;
}
checkProperties();
// Save if not exist or could not be read
if (!loadOK || firstTime)
saveProperties(true);
s_loaded = true;
if (log.isLoggable(Level.INFO)) log.info(filename + " #" + s_prop.size());
s_propertyFileName = filename;
return firstTime;
} // loadProperties
private static void checkProperties() {
// Check/set properties defaults
for (int i = 0; i < PROPERTIES.length; i++)
{
if (VALUES[i].length() > 0)
checkProperty(PROPERTIES[i], VALUES[i]);
}
//
String tempDir = System.getProperty("java.io.tmpdir");
if (tempDir == null || tempDir.length() == 1)
tempDir = getAdempiereHome();
if (tempDir == null)
tempDir = "";
checkProperty(P_TEMP_DIR, tempDir);
}
/**
* Delete Property file
*/
public static void deletePropertyFile()
{
String fileName = getFileName(s_client);
File file = new File(fileName);
if (file.exists())
{
try
{
if (!file.delete())
file.deleteOnExit();
s_prop = new Properties();
if (log.isLoggable(Level.CONFIG)) log.config (fileName);
}
catch (Exception e)
{
log.log (Level.WARNING, "Cannot delete Property file", e);
}
}
} // deleteProperties
/**
* Load property and set to default, if not exists
*
* @param key Key
* @param defaultValue Default Value
* @return Property
*/
private static String checkProperty (String key, String defaultValue)
{
String result = null;
if (key.equals(P_WARNING) || key.equals(P_WARNING_de))
result = defaultValue;
else if (!isClient())
result = s_prop.getProperty (key, SecureInterface.CLEARVALUE_START + defaultValue + SecureInterface.CLEARVALUE_END);
else
result = s_prop.getProperty (key, SecureEngine.encrypt(defaultValue, 0));
s_prop.setProperty (key, result);
return result;
} // checkProperty
/**
* Return File Name of INI file
*
* Examples:
* C:\WinNT\Profiles\jjanke\idempiere.properties
* D:\idempiere\idempiere.properties
* idempiere.properties
*
* Can be overwritten by -DPropertyFile=myFile allowing multiple
* configurations / property files.
* @param tryUserHome true to try user home first, ignore for server
* @return file name
*/
public static String getFileName (boolean tryUserHome)
{
if (SystemProperties.getPropertyFile() != null)
return SystemProperties.getPropertyFile();
//
String base = null;
if (tryUserHome && s_client)
base = System.getProperty("user.home");
// Server
if (!s_client || base == null || base.length() == 0)
{
String home = getAdempiereHome();
if (home != null)
base = home;
}
if (base != null && !base.endsWith(File.separator))
base += File.separator;
if (base == null)
base = "";
//
return base + IDEMPIERE_PROPERTY_FILE;
} // getFileName
/**
* Set Property
* @param key Key
* @param value Value
*/
public static void setProperty (String key, String value)
{
if (s_prop == null)
s_prop = new Properties();
if (key.equals(P_WARNING) || key.equals(P_WARNING_de))
s_prop.setProperty(key, value);
else if (key.endsWith(".TraceLevel"))
s_prop.setProperty(key, value);
else if (!isClient())
s_prop.setProperty(key, SecureInterface.CLEARVALUE_START + value + SecureInterface.CLEARVALUE_END);
else
{
if (value == null)
s_prop.setProperty(key, "");
else
{
String eValue = SecureEngine.encrypt(value, 0);
if (eValue == null)
s_prop.setProperty(key, "");
else
s_prop.setProperty(key, eValue);
}
}
} // setProperty
/**
* Set Property
* @param key Key
* @param value Value
*/
public static void setProperty (String key, boolean value)
{
setProperty (key, value ? "Y" : "N");
} // setProperty
/**
* Set Property
* @param key Key
* @param value Value
*/
public static void setProperty (String key, int value)
{
setProperty (key, String.valueOf(value));
} // setProperty
/**
* Get Property
* @param key Key
* @return Value
*/
public static String getProperty (String key)
{
if (key == null)
return "";
String retStr = s_prop.getProperty(key, "");
if (retStr == null || retStr.length() == 0)
return "";
//
String value = SecureEngine.decrypt(retStr, 0);
if (value == null)
return "";
return value;
} // getProperty
/**
* Get Property as Boolean
* @param key Key
* @return Value
*/
public static boolean isPropertyBool (String key)
{
return getProperty (key).equals("Y");
} // getProperty
/**
* Cache Windows
* @return true if windows are cached
* @deprecated window is always cache for better performance
*/
@Deprecated
public static boolean isCacheWindow()
{
return getProperty (P_CACHE_WINDOW).equals("Y");
} // isCacheWindow
/**
* Get Properties
*
* @return Ini properties
*/
public static Properties getProperties()
{
return s_prop;
} // getProperties
/**
* toString
* @return String representation
*/
public static String getAsString()
{
StringBuilder buf = new StringBuilder ("Ini[");
Enumeration> e = s_prop.keys();
while (e.hasMoreElements())
{
String key = (String)e.nextElement();
buf.append(key).append("=");
buf.append(getProperty(key)).append("; ");
}
buf.append("]");
return buf.toString();
} // toString
/** System environment prefix */
public static final String ENV_PREFIX = "env.";
/** System Property Value of IDEMPIERE_HOME */
public static final String IDEMPIERE_HOME = "IDEMPIERE_HOME";
/** IsClient Internal marker */
private static boolean s_client = false;
/** IsClient Internal marker */
private static boolean s_loaded = false;
/** Show license dialog for first time **/
private static boolean s_license_dialog = true;
/**
* Are we in Client Mode ?
* @return true if client
*/
public static boolean isClient()
{
return s_client;
} // isClient
/**
* Set Client Mode
* @param client client
*/
public static void setClient (boolean client)
{
s_client = client;
} // setClient
/**
* Set show license dialog for new setup
* @param b
*/
public static void setShowLicenseDialog(boolean b)
{
s_license_dialog = b;
}
/**
* Is show license dialog for new setup
* @return boolean
*/
public static boolean isShowLicenseDialog()
{
return s_license_dialog;
}
/**
* Are the properties loaded?
* @return true if properties loaded.
*/
public static boolean isLoaded()
{
return s_loaded;
} // isLoaded
/**
* Get iDempiere Home from Environment
* @return idempiereHome or null
*/
public static String getAdempiereHome()
{
String env = SystemProperties.getEnvIdempiereHome();
if (env == null || env.trim().length() == 0)
env = SystemProperties.getIdempiereHome();
if (env == null || env.trim().length() == 0)
{
//client - user home, server - current working directory
String current = isClient() ? System.getProperty("user.home")
: System.getProperty("user.dir");
if (current != null && current.trim().length() > 0)
{
//check directory exists and writable
File file = new File(current);
if (file.exists() && file.canWrite())
{
env = current;
}
}
}
if (env == null || env.trim().length() == 0 ) // Fallback
env = File.separator + "idempiere";
return env;
} // getAdempiereHome
/**
* Set iDempiere Home
* @param idempiereHome IDEMPIERE_HOME
*/
public static void setAdempiereHome (String idempiereHome)
{
if (idempiereHome != null && idempiereHome.length() > 0)
System.setProperty (IDEMPIERE_HOME, idempiereHome);
} // setAdempiereHome
/**
* Find iDempiere Home
* @return idempiere home or null
*/
public static String findAdempiereHome()
{
return getAdempiereHome();
} // findAdempiereHome
/**
* Get Window Dimension
* @param AD_Window_ID window no
* @return dimension or null
*/
@Deprecated
public static Dimension getWindowDimension(int AD_Window_ID)
{
String key = "WindowDim" + AD_Window_ID;
String value = (String)s_prop.get(key);
if (value == null || value.length() == 0)
return null;
int index = value.indexOf('|');
if (index == -1)
return null;
try
{
String w = value.substring(0, index);
String h = value.substring(index+1);
return new Dimension(Integer.parseInt(w),Integer.parseInt(h));
}
catch (Exception e)
{
}
return null;
} // getWindowDimension
/**
* Set Window Dimension
* @param AD_Window_ID window
* @param windowDimension dimension - null to remove
*/
@Deprecated
public static void setWindowDimension(int AD_Window_ID, Dimension windowDimension)
{
String key = "WindowDim" + AD_Window_ID;
if (windowDimension != null)
{
String value = windowDimension.width + "|" + windowDimension.height;
s_prop.put(key, value);
}
else
s_prop.remove(key);
} // setWindowDimension
/**
* Get Window Location
* @param AD_Window_ID window id
* @return location or null
*/
@Deprecated
public static Point getWindowLocation(int AD_Window_ID)
{
String key = "WindowLoc" + AD_Window_ID;
String value = (String)s_prop.get(key);
if (value == null || value.length() == 0)
return null;
int index = value.indexOf('|');
if (index == -1)
return null;
try
{
String x = value.substring(0, index);
String y = value.substring(index+1);
return new Point(Integer.parseInt(x),Integer.parseInt(y));
}
catch (Exception e)
{
}
return null;
} // getWindowLocation
/**
* Set Window Location
* @param AD_Window_ID window
* @param windowLocation location - null to remove
*/
@Deprecated
public static void setWindowLocation(int AD_Window_ID, Point windowLocation)
{
String key = "WindowLoc" + AD_Window_ID;
if (windowLocation != null)
{
String value = windowLocation.x + "|" + windowLocation.y;
s_prop.put(key, value);
}
else
s_prop.remove(key);
} // setWindowLocation
/**
* Get Divider Location
* @return location
*/
@Deprecated
public static int getDividerLocation()
{
String key = "Divider";
String value = (String)s_prop.get(key);
if (value == null || value.length() == 0)
return 0;
try
{
return Integer.parseInt(value);
}
catch (Exception e)
{
}
return 0;
} // getDividerLocation
/**
* Set Divider Location
* @param dividerLocation location
*/
@Deprecated
public static void setDividerLocation(int dividerLocation)
{
String key = "Divider";
String value = String.valueOf(dividerLocation);
s_prop.put(key, value);
} // setDividerLocation
/**
* Get Available Encoding Charsets
* @return array of available encoding charsets
* @since 3.1.4
*/
public static Charset[] getAvailableCharsets() {
Collection col = Charset.availableCharsets().values();
Charset[] arr = new Charset[col.size()];
col.toArray(arr);
return arr;
}
/**
* Get current charset
* @return current charset
* @since 3.1.4
*/
public static Charset getCharset() {
String charsetName = getProperty(P_CHARSET);
if (charsetName == null || charsetName.length() == 0)
return Charset.defaultCharset();
try {
return Charset.forName(charsetName);
} catch (Exception e) {
}
return Charset.defaultCharset();
}
/**
* Get property file name
* @return property file name
*/
public static String getPropertyFileName()
{
return s_propertyFileName;
}
/**
* Get value of a secret variable
* @param secretVar secret variable name
* @return value of secret variable
*/
public static String getVar(String secretVar) {
String cmd = getUtilsCmd("getVar");
String[] command = new String[] {
cmd,
secretVar
};
String retValue = runCommand(command);
return retValue;
}
/**
* Set value of secret variable
* @param secretVar
* @param secretValue
*/
public static void setVar(String secretVar, String secretValue) {
String cmd = getUtilsCmd("setVar");
String[] command = new String[] {
cmd,
secretVar,
secretValue
};
runCommand(command);
}
/**
* Get absolute path of script
* @param script command script file name
* @return absolute path of script
*/
private static String getUtilsCmd(String script) {
File utilsFolder = new File(getAdempiereHome() + File.separator + "utils");
if (! utilsFolder.exists()) {
// /utils does not exist, probably running on eclipse
if (Env.isWindows()) {
utilsFolder = new File(getAdempiereHome() + File.separator + "org.adempiere.server-feature" + File.separator + "utils.windows");
} else {
utilsFolder = new File(getAdempiereHome() + File.separator + "org.adempiere.server-feature" + File.separator + "utils.unix");
}
if (! utilsFolder.exists()) {
throw new AdempiereException("Folder utils does not exist");
}
}
File cmd = new File(utilsFolder, script + (Env.isWindows() ? ".bat" : ".sh"));
if (! cmd.exists() || ! cmd.canExecute()) {
throw new AdempiereException("File does not exist or canno execute " + cmd.getAbsolutePath());
}
return cmd.getAbsolutePath();
}
/**
* Run shell command
* @param command
* @return command output
*/
public static String runCommand(String[] command) {
StringBuilder msg = new StringBuilder();
try {
String s;
Process p = Runtime.getRuntime().exec(command);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
// read the output from the command
while ((s = stdInput.readLine()) != null) {
msg.append(s);
}
// read any errors from the attempted command
while ((s = stdError.readLine()) != null) {
msg.append(s);
}
if ( !p.waitFor(5, TimeUnit.SECONDS)) {
throw new AdempiereException("Timeout waiting 5 seconds for " + command[0]);
}
if (p.exitValue() != 0) {
throw new Exception(msg.toString());
}
}
catch (Exception e) {
throw new AdempiereException("Could not execute " + command[0], e);
}
return msg.toString();
}
} // Ini