/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* 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 Lesser General Public License for more details.
*
* Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.pms.ui.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URL;
import java.net.URLClassLoader;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.TreeItem;
import org.pentaho.di.core.Props;
import org.pentaho.di.core.database.DatabaseMeta;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.pms.messages.Messages;
/**
* This class is used to define a number of default values for various settings throughout Pentaho Metadata.
* It also contains a number of static final methods to make your life easier.
*
* @author Matt
* @since 07-05-2003
*
*/
public class Const
{
/**
* What's the file systems file separator on this operating system?
*/
public static final String FILE_SEPARATOR = System.getProperty("file.separator"); //$NON-NLS-1$
/**
* CR: operating systems specific Cariage Return
*/
public static final String CR = System.getProperty("line.separator"); //$NON-NLS-1$
/**
* The Java runtime version
*/
public static final String JAVA_VERSION = System.getProperty("java.vm.version"); //$NON-NLS-1$
/**
* The margin between the different dialog components & widgets
*/
public static final int MARGIN = 3;
/**
* The default percentage of the width of screen where we consider the middle of a dialog.
*/
public static final int MIDDLE_PCT = 30;
/**
* The default width of an arrow in the Graphical Views
*/
public static final int ARROW_WIDTH = 1;
/**
* The horizontal and vertical margin of a dialog box.
*/
public static final int FORM_MARGIN = 3;
/**
* The default shadow size on the graphical view.
*/
public static final int SHADOW_SIZE = 4;
/**
* The size of relationship symbols
*/
public static final int SYMBOLSIZE = 10;
/**
* Max nr. of files to remember
*/
public static final int MAX_FILE_HIST = 9;
/**
* The default locale (system defined)
*/
public static final Locale DEFAULT_LOCALE = Locale.getDefault();
/**
* The default decimal separator . or ,
*/
public static final char DEFAULT_DECIMAL_SEPARATOR = (new DecimalFormatSymbols(DEFAULT_LOCALE)).getDecimalSeparator();
/**
* The default grouping separator , or .
*/
public static final char DEFAULT_GROUPING_SEPARATOR = (new DecimalFormatSymbols(DEFAULT_LOCALE)).getGroupingSeparator();
/**
* The default currency symbol
*/
public static final String DEFAULT_CURRENCY_SYMBOL = (new DecimalFormatSymbols(DEFAULT_LOCALE)).getCurrencySymbol();
/**
* The default number format
*/
public static final String DEFAULT_NUMBER_FORMAT = ((DecimalFormat) (NumberFormat.getInstance())).toPattern();
/**
* Default font name for the fixed width font
*/
public static final String FONT_FIXED_NAME = "Courier"; //$NON-NLS-1$
/**
* Default font size for the fixed width font
*/
public static final int FONT_FIXED_SIZE = 9;
/**
* Default font type for the fixed width font
*/
public static final int FONT_FIXED_TYPE = SWT.NORMAL;
/**
* Default icon size
*/
public static final int ICON_SIZE = 48;
/**
* Default line width for arrows & around icons
*/
public static final int LINE_WIDTH = 2;
/**
* Default grid size to which the graphical views snap.
*/
public static final int GRID_SIZE = 20;
/**
* The minimal size of a note on a graphical view (width & height)
*/
public static final int NOTE_MIN_SIZE = 20;
/**
* The margin between the text of a note and its border.
*/
public static final int NOTE_MARGIN = 5;
/**
* The default red-component of the background color
*/
public static final int COLOR_BACKGROUND_RED = 255;
/**
* The default green-component of the background color
*/
public static final int COLOR_BACKGROUND_GREEN = 255;
/**
* The default blue-component of the background color
*/
public static final int COLOR_BACKGROUND_BLUE = 255;
/**
* The default red-component of the graph background color
*/
public static final int COLOR_GRAPH_RED = 255;
/**
* The default green-component of the graph background color
*/
public static final int COLOR_GRAPH_GREEN = 255;
/**
* The default blue-component of the graph background color
*/
public static final int COLOR_GRAPH_BLUE = 255;
/**
* The default red-component of the tab selected color
*/
public static final int COLOR_TAB_RED = 200;
/**
* The default green-component of the tab selected color
*/
public static final int COLOR_TAB_GREEN = 200;
/**
* The default blue-component of the tab selected color
*/
public static final int COLOR_TAB_BLUE = 255;
/**
* The default undo level for Kettle
*/
public static final int MAX_UNDO = 100;
/**
* Path to the users home directory
*/
public static final String USER_HOME_DIRECTORY = Const.isEmpty(System.getProperty("PENTAHO_META_HOME"))?System.getProperty("user.home"):System.getProperty("PENTAHO_META"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
/**
* The base name of the Pentaho metadata editor logfile
*/
public static final String META_EDITOR_LOG_FILE = "pentaho-meta"; //$NON-NLS-1$
/**
* Default we store our information in Unicode UTF-8 character set.
*/
public static final String XML_ENCODING = "UTF-8"; //$NON-NLS-1$
/**
* Default server web service URL for retrieving security information
*/
public static final String DEFAULT_SERVICE_URL = "http://localhost:8080/pentaho/api/userrolelist"; //$NON-NLS-1$
/**
* Name of the service to retrieve security information
*/
public static final String SECURITY_SERVICE_NAME = "SecurityDetails"; //$NON-NLS-1$
/**
* Name of the parameter passed to the service to retrieve security information
*/
public static final String SECURITY_SERVICE_PARAMETER = "details"; //$NON-NLS-1$
/**
* The directory / path to load images from
*/
public static final String IMAGE_DIRECTORY = "/org/pentaho/pms/ui/images/"; //$NON-NLS-1$
/**
* Determines the Pentaho metadata base directory in the user's home directory.
* @return The Pentaho metadata base directory.
*/
public static final String getBaseDirectory()
{
return USER_HOME_DIRECTORY + FILE_SEPARATOR + ".pentaho-meta"; //$NON-NLS-1$
}
/**
* @return The properties filename for the Pentaho Metadata Editor
*/
public static final String getPropertiesFile()
{
return Const.getBaseDirectory()+Const.FILE_SEPARATOR+".pme-rc"; //$NON-NLS-1$
}
/**
* @return the saved query file name
*/
public static String getQueryFile()
{
return Const.getBaseDirectory()+Const.FILE_SEPARATOR+".query"; //$NON-NLS-1$
}
/**
* @return the saved query file name
*/
public static String getDomainRecoveryFile()
{
return Const.getBaseDirectory()+Const.FILE_SEPARATOR+"recovery_"; //$NON-NLS-1$
}
/**
* See if the pentaho metadata base directory exists, otherwise create it.
*/
public static final void checkPentahoMetadataDirectory()
{
File dir = new File(getBaseDirectory());
if (!dir.exists())
{
try
{
dir.mkdirs();
}
catch(Exception e)
{
// serious problem, serious measures...
throw new RuntimeException(Messages.getString("Const.ERROR_0001_CANT_CREATE_DIRECTORY")+dir.toString()+"]"); //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
/**
* rounds double f to any number of places after decimal point
* Does arithmetic using BigDecimal class to avoid integer overflow while rounding
*
* @param f The value to round
* @param places The number of decimal places
* @return The rounded floating point value
*/
public static final double round(double f, int places)
{
java.math.BigDecimal bdtemp = new java.math.BigDecimal(f);
bdtemp = bdtemp.setScale(places, java.math.BigDecimal.ROUND_HALF_EVEN);
return bdtemp.doubleValue();
}
/**
* Convert a String into an integer. If the conversion fails, assign a default value.
* @param str The String to convert to an integer
* @param def The default value
* @return The converted value or the default.
*/
public static final int toInt(String str, int def)
{
int retval;
try
{
retval = Integer.parseInt(str);
} catch (Exception e)
{
retval = def;
}
return retval;
}
/**
* Convert a String into a long integer. If the conversion fails, assign a default value.
* @param str The String to convert to a long integer
* @param def The default value
* @return The converted value or the default.
*/
public static final long toLong(String str, long def)
{
long retval;
try
{
retval = Long.parseLong(str);
} catch (Exception e)
{
retval = def;
}
return retval;
}
/**
* Convert a String into a double. If the conversion fails, assign a default value.
* @param str The String to convert to a double
* @param def The default value
* @return The converted value or the default.
*/
public static final double toDouble(String str, double def)
{
double retval;
try
{
retval = Double.parseDouble(str);
} catch (Exception e)
{
retval = def;
}
return retval;
}
/**
* Convert a String into a date.
* The date format is <code>yyyy/MM/dd HH:mm:ss.SSS</code>.
* If the conversion fails, assign a default value.
* @param str The String to convert into a Date
* @param def The default value
* @return The converted value or the default.
*/
public static final Date toDate(String str, Date def)
{
SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS", Locale.US); //$NON-NLS-1$
try
{
return df.parse(str);
} catch (ParseException e)
{
return def;
}
}
/**
* Right trim: remove spaces to the right of a string
* @param str The string to right trim
* @return The trimmed string.
*/
public static final String rtrim(String str)
{
int max = str.length();
while (max > 0 && isSpace(str.charAt(max - 1)))
max--;
return str.substring(0, max);
}
/**
* Determines whether or not a character is considered a space.
* A character is considered a space in Kettle if it is a space, a tab, a newline or a cariage return.
* @param c The character to verify if it is a space.
* @return true if the character is a space. false otherwise.
*/
public static final boolean isSpace(char c)
{
return c == ' ' || c == '\t' || c == '\r' || c == '\n';
}
/**
* Left trim: remove spaces to the left of a String.
* @param str The String to left trim
* @return The left trimmed String
*/
public static final String ltrim(String str)
{
int from = 0;
while (from < str.length() && isSpace(str.charAt(from)))
from++;
return str.substring(from);
}
/**
* Trims a string: removes the leading and trailing spaces of a String.
* @param str The string to trim
* @return The trimmed string.
*/
public static final String trim(String str)
{
int max = str.length() - 1;
int min = 0;
while (min <= max && isSpace(str.charAt(min)))
min++;
while (max >= 0 && isSpace(str.charAt(max)))
max--;
if (max < min)
return ""; //$NON-NLS-1$
return str.substring(min, max + 1);
}
/**
* Right pad a string: adds spaces to a string until a certain length.
* If the length is smaller then the limit specified, the String is truncated.
* @param ret The string to pad
* @param limit The desired length of the padded string.
* @return The padded String.
*/
public static final String rightPad(String ret, int limit)
{
if (ret == null)
return rightPad(new StringBuffer(), limit);
else
return rightPad(new StringBuffer(ret), limit);
}
/**
* Right pad a StringBuffer: adds spaces to a string until a certain length.
* If the length is smaller then the limit specified, the String is truncated.
* @param ret The StringBuffer to pad
* @param limit The desired length of the padded string.
* @return The padded String.
*/
public static final String rightPad(StringBuffer ret, int limit)
{
int len = ret.length();
int l;
if (len > limit)
{
ret.setLength(limit);
} else
{
for (l = len; l < limit; l++)
ret.append(' ');
}
return ret.toString();
}
/**
* Replace values in a String with another.
* @param string The original String.
* @param repl The text to replace
* @param with The new text bit
* @return The resulting string with the text pieces replaced.
*/
public static final String replace(String string, String repl, String with)
{
StringBuffer str = new StringBuffer(string);
for (int i = str.length() - 1; i >= 0; i--)
{
if (str.substring(i).startsWith(repl))
{
str.delete(i, i + repl.length());
str.insert(i, with);
}
}
return str.toString();
}
/**
* Alternate faster version of string replace using a stringbuffer as input.
*
* @param str The string where we want to replace in
* @param code The code to search for
* @param repl The replacement string for code
*/
public static void repl(StringBuffer str, String code, String repl)
{
int clength = code.length();
int i = str.length() - clength;
while (i >= 0)
{
String look = str.substring(i, i + clength);
if (look.equalsIgnoreCase(code)) // Look for a match!
{
str.replace(i, i + clength, repl);
}
i--;
}
}
/**
* Count the number of spaces to the left of a text. (leading)
* @param field The text to examine
* @return The number of leading spaces found.
*/
public static final int nrSpacesBefore(String field)
{
int nr = 0;
int len = field.length();
while (nr < len && field.charAt(nr) == ' ')
{
nr++;
}
return nr;
}
/**
* Count the number of spaces to the right of a text. (trailing)
* @param field The text to examine
* @return The number of trailing spaces found.
*/
public static final int nrSpacesAfter(String field)
{
int nr = 0;
int len = field.length();
while (nr < len && field.charAt(field.length() - 1 - nr) == ' ')
{
nr++;
}
return nr;
}
/**
* Checks whether or not a String consists only of spaces.
* @param str The string to check
* @return true if the string has nothing but spaces.
*/
public static final boolean onlySpaces(String str)
{
for (int i = 0; i < str.length(); i++)
if (!isSpace(str.charAt(i)))
return false;
return true;
}
/**
* determine the OS name
* @return The name of the OS
*/
public static final String getOS()
{
return System.getProperty("os.name"); //$NON-NLS-1$
}
/**
* @return True if the OS is a Windows derivative.
*/
public static final boolean isWindows()
{
return getOS().startsWith("Windows"); //$NON-NLS-1$
}
/**
* @return true if the OS is Apple OSX
* @see <a href="http://developer.apple.com/technotes/tn2002/tn2110.html">Apple developer documentation</a>
*/
public static final boolean isOSX()
{
return getOS().toLowerCase().startsWith("mac os x"); //$NON-NLS-1$
}
/**
* Determine the hostname of the machine Kettle is running on
* @return The hostname
*/
public static final String getHostname()
{
String lastHostname = "localhost"; //$NON-NLS-1$
try
{
Enumeration en = NetworkInterface.getNetworkInterfaces();
while (en.hasMoreElements())
{
NetworkInterface nwi = (NetworkInterface) en.nextElement();
Enumeration ip = nwi.getInetAddresses();
while (ip.hasMoreElements())
{
InetAddress in = (InetAddress) ip.nextElement();
lastHostname=in.getHostName();
if (!lastHostname.equalsIgnoreCase("localhost") && !(lastHostname.indexOf(":")>=0) ) //$NON-NLS-1$ //$NON-NLS-2$
{
return lastHostname;
}
}
}
} catch (SocketException e)
{
}
return lastHostname;
}
/**
* Determins the IP address of the machine Kettle is running on.
* @return The IP address
*/
public static final String getIPAddress()
{
try
{
Enumeration enumInterfaces = NetworkInterface.getNetworkInterfaces();
while (enumInterfaces.hasMoreElements())
{
NetworkInterface nwi = (NetworkInterface) enumInterfaces.nextElement();
Enumeration ip = nwi.getInetAddresses();
while (ip.hasMoreElements())
{
InetAddress in = (InetAddress) ip.nextElement();
if (!in.isLoopbackAddress() && in.toString().indexOf(":") < 0) //$NON-NLS-1$
{
return in.getHostAddress();
}
}
}
} catch (SocketException e)
{
}
return "127.0.0.1"; //$NON-NLS-1$
}
/**
* Tries to determine the MAC address of the machine Kettle is running on.
* @return The MAC address.
*/
public static final String getMACAddress()
{
String ip = getIPAddress();
String mac = "none"; //$NON-NLS-1$
String os = getOS();
String s = ""; //$NON-NLS-1$
if (os.equalsIgnoreCase("Windows NT") || os.equalsIgnoreCase("Windows 2000") || os.equalsIgnoreCase("Windows XP") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|| os.equalsIgnoreCase("Windows 95") || os.equalsIgnoreCase("Windows 98") || os.equalsIgnoreCase("Windows Me") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|| os.startsWith("Windows")) //$NON-NLS-1$
{
try
{
Process p = Runtime.getRuntime().exec("nbtstat -a " + ip); //$NON-NLS-1$
// read the standard output of the command
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
while (!procDone(p))
{
while ((s = stdInput.readLine()) != null)
{
if (s.indexOf("MAC") >= 0) //$NON-NLS-1$
{
int idx = s.indexOf("="); //$NON-NLS-1$
mac = s.substring(idx + 2);
}
}
}
stdInput.close();
} catch (Exception e)
{
}
} else if (os.equalsIgnoreCase("Linux")) //$NON-NLS-1$
{
try
{
Process p = Runtime.getRuntime().exec("/sbin/ifconfig -a"); //$NON-NLS-1$
// read the standard output of the command
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
while (!procDone(p))
{
while ((s = stdInput.readLine()) != null)
{
int idx = s.indexOf("HWaddr"); //$NON-NLS-1$
if (idx >= 0)
{
mac = s.substring(idx + 7);
}
}
}
stdInput.close();
} catch (Exception e)
{
}
} else if (os.equalsIgnoreCase("Solaris")) //$NON-NLS-1$
{
try
{
Process p = Runtime.getRuntime().exec("/usr/sbin/ifconfig -a"); //$NON-NLS-1$
// read the standard output of the command
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
while (!procDone(p))
{
while ((s = stdInput.readLine()) != null)
{
int idx = s.indexOf("ether"); //$NON-NLS-1$
if (idx >= 0)
{
mac = s.substring(idx + 6);
}
}
}
stdInput.close();
} catch (Exception e)
{
}
} else if (os.equalsIgnoreCase("HP-UX")) //$NON-NLS-1$
{
try
{
Process p = Runtime.getRuntime().exec("/usr/sbin/lanscan -a"); //$NON-NLS-1$
// read the standard output of the command
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
while (!procDone(p))
{
while ((s = stdInput.readLine()) != null)
{
if (s.indexOf("MAC") >= 0) //$NON-NLS-1$
{
int idx = s.indexOf("0x"); //$NON-NLS-1$
mac = s.substring(idx + 2);
}
}
}
stdInput.close();
} catch (Exception e)
{
}
}
return Const.trim(mac);
}
private static final boolean procDone(Process p)
{
try
{
p.exitValue();
return true;
} catch (IllegalThreadStateException e)
{
return false;
}
}
/**
* Determine the level of where the TreeItem is position in a tree.
* @param ti The TreeItem
* @param nrLevelsToSkip
* @return The level of the item in the tree
*/
public static final int getTreeLevel(TreeItem ti)
{
return getTreeLevel(ti, 0);
}
/**
* Determine the level of where the TreeItem is position in a tree.
* @param ti The TreeItem
* @param nrLevelsToSkip the number of levels to skip
* @return The level of the item in the tree
*/
public static final int getTreeLevel(TreeItem ti, int nrLevelsToSkip)
{
int level = 1;
TreeItem parent = ti.getParentItem();
while (parent != null)
{
level++;
parent = parent.getParentItem();
}
level-=nrLevelsToSkip;
if (level<0) level=0;
return level;
}
/**
* Get an array of strings containing the path from the given TreeItem to the parent.
* @param ti The TreeItem to look at
* @return An array of string describing the path to the TreeItem.
*/
public static final String[] getTreeStrings(TreeItem ti)
{
return getTreeStrings(ti, 0);
}
/**
* Get an array of strings containing the path from the given TreeItem to the parent.
* @param ti The TreeItem to look at
* @param nrLevelsToSkip the number of levels to skip at the root of the tree.
* @return An array of string describing the path to the TreeItem.
*/
public static final String[] getTreeStrings(TreeItem ti, int nrLevelsToSkip)
{
int nrLevels = getTreeLevel(ti, nrLevelsToSkip);
String retval[] = new String[nrLevels];
if (nrLevels==0) return retval;
int current = nrLevels - 1;
retval[current] = ti.getText();
TreeItem parent = ti.getParentItem();
current--;
while (current>=0)
{
retval[current] = parent.getText();
parent = parent.getParentItem();
current--;
}
return retval;
}
/**
* Return the tree path seperated by Const.FILE_SEPARATOR, starting from a certain depth in the tree.
*
* @param ti The TreeItem to get the path for
* @param from The depth to start at, use 0 to get the complete tree.
* @return The tree path.
*/
public static final String getTreePath(TreeItem ti, int from)
{
String path[] = getTreeStrings(ti);
if (path == null)
return null;
String retval = ""; //$NON-NLS-1$
for (int i = from; i < path.length; i++)
{
if (!path[i].equalsIgnoreCase(Const.FILE_SEPARATOR))
{
retval += Const.FILE_SEPARATOR + path[i];
}
}
return retval;
}
/**
* Flips the TreeItem from expanded to not expanded or vice-versa.
* @param ti The TreeItem to flip.
*/
public static final void flipExpanded(TreeItem ti)
{
ti.setExpanded(!ti.getExpanded());
}
/**
* Finds a TreeItem with a certain label (name) in a (part of a) tree.
* @param parent The TreeItem where we start looking.
* @param name The name or item label to look for.
* @return The TreeItem if the label was found, null if nothing was found.
*/
public static final TreeItem findTreeItem(TreeItem parent, String name)
{
if (parent.getText().equalsIgnoreCase(name))
return parent;
TreeItem ti[] = parent.getItems();
for (int i = 0; i < ti.length; i++)
{
TreeItem child = findTreeItem(ti[i], name);
if (child != null)
return child;
}
return null;
}
/**
* Find a database with a certain name in an arraylist of databases.
* @param databases The ArrayList of databases
* @param dbname The name of the database connection
* @return The database object if one was found, null otherwise.
*/
public static final DatabaseMeta findDatabase(List databases, String dbname)
{
if (databases == null)
return null;
for (int i = 0; i < databases.size(); i++)
{
DatabaseMeta ci = (DatabaseMeta) databases.get(i);
if (ci.getName().equalsIgnoreCase(dbname))
return ci;
}
return null;
}
/**
* Find a database with a certain name in an arraylist of databases.
* @param databases The ArrayList of databases
* @param dbname The name of the database connection
* @return The database object if one was found, null otherwise.
*/
public static final DatabaseMeta findDatabase(List databases, String dbname, String exclude)
{
if (databases == null)
return null;
for (int i = 0; i < databases.size(); i++)
{
DatabaseMeta ci = (DatabaseMeta) databases.get(i);
if (ci.getName().equalsIgnoreCase(dbname))
return ci;
}
return null;
}
/**
* Gets the value of a commandline option
* @param args The command line arguments
* @param option The option to look for
* @return The value of the commandline option specified.
* @deprecated
*/
public static final String getCommandlineOption(List args, String option)
{
String optionStart[] = new String[] { "-", "/" }; //$NON-NLS-1$ //$NON-NLS-2$
String optionDelim[] = new String[] { "=", ":" }; //$NON-NLS-1$ //$NON-NLS-2$
for (int s = 0; s < optionStart.length; s++)
{
for (int d = 0; d < optionDelim.length; d++)
{
String optstr = optionStart[s] + option + optionDelim[d];
String retval = searchCommandLineOption(args, optstr);
if (retval != null)
return retval;
}
}
return null;
}
/**
* Searches a command line option with a certain prefix in a list of command line options
* @param args The list to search
* @param prefix The prefix to look for
* @return The content.
*/
private static final String searchCommandLineOption(List args, String prefix)
{
String retval = null;
for (int i = args.size() - 1; i >= 0; i--)
{
String arg = (String) args.get(i);
if (arg != null && arg.toUpperCase().startsWith(prefix.toUpperCase()))
{
retval = arg.substring(prefix.length());
// remove this options from the arguments list...
// This is why we go from back to front...
args.remove(i);
}
}
return retval;
}
/**
* Retrieves the content of an environment variable
*
* @param variable The name of the environment variable
* @param deflt The default value in case no value was found
* @return The value of the environment variable or the value of deflt in case no variable was defined.
*/
public static String getEnvironmentVariable(String variable, String deflt)
{
return System.getProperty(variable, deflt);
}
/**
* Replaces environment variables in a string.
* For example if you set KETTLE_HOME as an environment variable, you can
* use %%KETTLE_HOME%% in dialogs etc. to refer to this value.
* This procedures looks for %%...%% pairs and replaces them including the
* name of the environment variable with the actual value.
* In case the variable was not set, nothing is replaced!
*
* @param string The source string where text is going to be replaced.
*
* @return The expanded string.
* @deprecated use StringUtil.environmentSubstitute(): handles both Windows and unix conventions
*/
public static final String replEnv(String string)
{
if (string == null)
return null;
StringBuffer str = new StringBuffer(string);
int idx = str.indexOf("%%"); //$NON-NLS-1$
while (idx >= 0)
{
//OK, so we found a marker, look for the next one...
int to = str.indexOf("%%", idx + 2); //$NON-NLS-1$
if (to >= 0)
{
// OK, we found the other marker also...
String marker = str.substring(idx, to + 2);
String var = str.substring(idx + 2, to);
if (var != null && var.length() > 0)
{
// Get the environment variable
String newval = getEnvironmentVariable(var, null);
if (newval != null)
{
// Replace the whole bunch
str.replace(idx, to + 2, newval);
// The last position has changed...
to += newval.length() - marker.length();
}
}
} else
// We found the start, but NOT the ending %% without closing %%
{
to = idx;
}
// Look for the next variable to replace...
idx = str.indexOf("%%", to + 1); //$NON-NLS-1$
}
return str.toString();
}
/**
* Replaces environment variables in an array of strings.<p>
* See also: replEnv(String string)
* @param string The array of strings that wants its variables to be replaced.
* @return the array with the environment variables replaced.
* @deprecated please use StringUtil.environmentSubstitute now.
*/
public static final String[] replEnv(String string[])
{
String retval[] = new String[string.length];
for (int i = 0; i < string.length; i++)
{
retval[i] = Const.replEnv(string[i]);
}
return retval;
}
/**
* Implements Oracle style NVL function
* @param source The source argument
* @param def The default value in case source is null or the length of the string is 0
* @return source if source is not null, otherwise return def
*/
public static final String NVL(String source, String def)
{
if (source == null || source.length() == 0)
return def;
return source;
}
/**
* Search for a string in an array of strings and return the index.
* @param lookup The string to search for
* @param array The array of strings to look in
* @return The index of a search string in an array of strings. -1 if not found.
*/
public static final int indexOfString(String lookup, String array[])
{
if (array == null)
return -1;
if (lookup == null)
return -1;
for (int i = 0; i < array.length; i++)
{
if (lookup.equalsIgnoreCase(array[i]))
return i;
}
return -1;
}
/**
* Search for a string in a list of strings and return the index.
* @param lookup The string to search for
* @param list The ArrayList of strings to look in
* @return The index of a search string in an array of strings. -1 if not found.
*/
public static final int indexOfString(String lookup, List list)
{
if (list == null)
return -1;
for (int i = 0; i < list.size(); i++)
{
String compare = (String) list.get(i);
if (lookup.equalsIgnoreCase(compare))
return i;
}
return -1;
}
/**
* Sort the strings of an array in alphabetical order.
* @param input The array of strings to sort.
* @return The sorted array of strings.
*/
public static final String[] sortStrings(String input[])
{
Arrays.sort(input);
return input;
}
/**
* Convert strings separated by a string into an array of strings.<p>
* <code>
Example: a;b;c;d == new String[] { a, b, c, d }
* </code>
*
* @param string The string to split
* @param separator The separator used.
* @return the string split into an array of strings
*
* @deprecated
*/
public static final String[] splitString(String string, String separator)
{
/*
* 0123456
* Example a;b;c;d --> new String[] { a, b, c, d }
*/
List<String> list = new ArrayList<String>();
if (string == null || string.length() == 0)
{
return new String[] {};
}
int sepLen = separator.length();
int from = 0;
int end = string.length() - sepLen + 1;
for (int i = from; i < end; i += sepLen)
{
if (string.substring(i, i + sepLen).equalsIgnoreCase(separator))
{
// OK, we found a separator, the string to add to the list
// is [from, i[
list.add(NVL(string.substring(from, i), "")); //$NON-NLS-1$
from = i + sepLen;
}
}
// Wait, if the string didn't end with a separator, we still have information at the end of the string...
// In our example that would be "d"...
if (from + sepLen <= string.length())
{
list.add(NVL(string.substring(from, string.length()), "")); //$NON-NLS-1$
}
return list.toArray(new String[list.size()]);
}
/**
* Convert strings separated by a character into an array of strings.<p>
* <code>
Example: a;b;c;d == new String[] { a, b, c, d }
* </code>
*
* @param string The string to split
* @param separator The separator used.
* @return the string split into an array of strings
*/
public static final String[] splitString(String string, char separator)
{
/*
* 0123456
* Example a;b;c;d --> new String[] { a, b, c, d }
*/
List<String> list = new ArrayList<String>();
if (string == null || string.length() == 0)
{
return new String[] {};
}
int from = 0;
int end = string.length();
for (int i = from; i < end; i += 1)
{
if (string.charAt(i) == separator)
{
// OK, we found a separator, the string to add to the list
// is [from, i[
list.add(NVL(string.substring(from, i), "")); //$NON-NLS-1$
from = i + 1;
}
}
// Wait, if the string didn't end with a separator, we still have information at the end of the string...
// In our example that would be "d"...
if (from + 1 <= string.length())
{
list.add(NVL(string.substring(from, string.length()), "")); //$NON-NLS-1$
}
return list.toArray(new String[list.size()]);
}
/**
* Convert strings separated by a string into an array of strings.<p>
* <code>
* Example /a/b/c --> new String[] { a, b, c }
* </code>
*
* @param path The string to split
* @param separator The separator used.
* @return the string split into an array of strings
*/
public static final String[] splitPath(String path, String separator)
{
/*
* 012345
* Example /a/b/c --> new String[] { a, b, c }
*/
if (path == null || path.length() == 0 || path.equals(separator))
{
return new String[] {};
}
int sepLen = separator.length();
int nr_separators = 0;
int from = path.startsWith(separator) ? sepLen : 0;
if (from != 0)
nr_separators++;
for (int i = from; i < path.length(); i += sepLen)
{
if (path.substring(i, i + sepLen).equalsIgnoreCase(separator))
{
nr_separators++;
}
}
String spath[] = new String[nr_separators];
int nr = 0;
for (int i = from; i < path.length(); i += sepLen)
{
if (path.substring(i, i + sepLen).equalsIgnoreCase(separator))
{
spath[nr] = path.substring(from, i);
nr++;
from = i + sepLen;
}
}
if (nr < spath.length)
{
spath[nr] = path.substring(from);
}
//
// a --> { a }
//
if (spath.length == 0 && path.length() > 0)
{
spath = new String[] { path };
}
return spath;
}
/**
* Sorts the array of Strings, determines the uniquely occuring strings.
* @param strings the array that you want to do a distinct on
* @return a sorted array of uniquely occuring strings
*/
public static final String[] getDistinctStrings(String[] strings)
{
if (strings == null)
return null;
if (strings.length == 0)
return new String[] {};
String[] sorted = sortStrings(strings);
List<String> result = new ArrayList<String>();
String previous = ""; //$NON-NLS-1$
for (int i = 0; i < sorted.length; i++)
{
if (!sorted[i].equalsIgnoreCase(previous))
{
result.add(sorted[i]);
}
previous = sorted[i];
}
return result.toArray(new String[result.size()]);
}
/**
* Returns a string of the stack trace of the specified exception
*/
public static final String getStackTracker(Throwable e)
{
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
e.printStackTrace(printWriter);
String string = stringWriter.getBuffer().toString();
try { stringWriter.close(); } catch(IOException ioe) {} // is this really required?
return string;
}
/**
* Check if the string supplied is empty. A String is empty when it is null or when the length is 0
* @param string The string to check
* @return true if the string supplied is empty
*/
public static final boolean isEmpty(String string)
{
return string==null || string.length()==0;
}
/**
* Check if the stringBuffer supplied is empty. A StringBuffer is empty when it is null or when the length is 0
* @param string The stringBuffer to check
* @return true if the stringBuffer supplied is empty
*/
public static final boolean isEmpty(StringBuffer string)
{
return string==null || string.length()==0;
}
/**
* @return a new ClassLoader
*/
public static final ClassLoader createNewClassLoader() throws KettleException
{
try
{
// Nothing really in URL, everything is in scope.
URL urls[] = new URL[] { };
URLClassLoader ucl = new URLClassLoader(urls);
return ucl;
}
catch (Exception e)
{
throw new KettleException(Messages.getString("Const.ERROR_0002_UNEXPECTED_CLASSLOADER_CREATION"), e); //$NON-NLS-1$
}
}
/**
* Utility class for use in JavaScript to create a new byte array.
* This is surprisingly difficult to do in JavaScript.
*
* @return a new java byte array
*/
public static final byte[] createByteArray(int size)
{
return new byte[size];
}
/**
* Sets the first character of each word in upper-case.
* @param string The strings to convert to initcap
* @return the input string but with the first character of each word converted to upper-case.
*/
public static final String initCap(String string)
{
StringBuffer change=new StringBuffer(string);
boolean new_word;
int i;
char lower, upper, ch;
new_word=true;
for (i=0 ; i<string.length() ; i++)
{
lower=change.substring(i,i+1).toLowerCase().charAt(0); // Lowercase is default.
upper=change.substring(i,i+1).toUpperCase().charAt(0); // Uppercase for new words.
ch=upper;
if (new_word)
{
change.setCharAt(i, upper);
}
else
{
change.setCharAt(i, lower);
}
new_word = false;
if ( !(ch>='A' && ch<='Z') &&
!(ch>='0' && ch<='9') &&
ch!='_'
) new_word = true;
}
return change.toString();
}
/**
* Convert a normal name with spaces into an ID: with underscores replacing the spaces, etc.
* @param name the name to convert to an ID
* @return The ID-ified name
*/
public static final String toID(String name)
{
name = Const.replace(name, " ", "_"); //$NON-NLS-1$ //$NON-NLS-2$
name = Const.replace(name, ".", "_"); //$NON-NLS-1$ //$NON-NLS-2$
name = Const.replace(name, ",", "_"); //$NON-NLS-1$ //$NON-NLS-2$
name = Const.replace(name, ":", "_"); //$NON-NLS-1$ //$NON-NLS-2$
name = Const.replace(name, "(", "_"); //$NON-NLS-1$ //$NON-NLS-2$
name = Const.replace(name, ")", "_"); //$NON-NLS-1$ //$NON-NLS-2$
name = Const.replace(name, "{", "_"); //$NON-NLS-1$ //$NON-NLS-2$
name = Const.replace(name, "}", "_"); //$NON-NLS-1$ //$NON-NLS-2$
name = Const.replace(name, "[", "_"); //$NON-NLS-1$ //$NON-NLS-2$
name = Const.replace(name, "]", "_"); //$NON-NLS-1$ //$NON-NLS-2$
name = Const.replace(name, "*", "_TIMES_"); //$NON-NLS-1$ //$NON-NLS-2$
name = Const.replace(name, "/", "_DIVIDED_BY_"); //$NON-NLS-1$ //$NON-NLS-2$
name = Const.replace(name, "+", "_PLUS_"); //$NON-NLS-1$ //$NON-NLS-2$
name = Const.replace(name, "-", "_MINUS_"); //$NON-NLS-1$ //$NON-NLS-2$
name = Const.replace(name, "____", "_"); //$NON-NLS-1$ //$NON-NLS-2$
name = Const.replace(name, "___", "_"); //$NON-NLS-1$ //$NON-NLS-2$
name = Const.replace(name, "__", "_"); //$NON-NLS-1$ //$NON-NLS-2$
return name;
}
/**
* Convert a ID with underscored into a name: with spaces and capital etc...
* @param id the id to convert to a name
* @return The name converted from an ID
*/
public static String fromID(String id)
{
id = Const.replace(id, "_", " "); //$NON-NLS-1$ //$NON-NLS-2$
id = Const.initCap(id);
return id;
}
public static String getCustomParameter(Props props, String param, String defaultValue){
if (props.getCustomParameter(param, null)==null){
props.setCustomParameter(param, defaultValue);
props.saveProps();
}
return props.getCustomParameter(param, defaultValue);
}
}