0001: /*
0002: * Licensed to the Apache Software Foundation (ASF) under one or more
0003: * contributor license agreements. See the NOTICE file distributed with
0004: * this work for additional information regarding copyright ownership.
0005: * The ASF licenses this file to You under the Apache License, Version 2.0
0006: * (the "License"); you may not use this file except in compliance with
0007: * the License. You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: *
0017: */
0018:
0019: package org.apache.jmeter.util;
0020:
0021: import java.awt.Dimension;
0022: import java.awt.HeadlessException;
0023: import java.awt.event.ActionListener;
0024: import java.io.BufferedReader;
0025: import java.io.File;
0026: import java.io.FileInputStream;
0027: import java.io.IOException;
0028: import java.io.InputStream;
0029: import java.io.InputStreamReader;
0030: import java.net.URL;
0031: import java.util.Enumeration;
0032: import java.util.Hashtable;
0033: import java.util.Iterator;
0034: import java.util.Locale;
0035: import java.util.MissingResourceException;
0036: import java.util.Properties;
0037: import java.util.Random;
0038: import java.util.ResourceBundle;
0039: import java.util.StringTokenizer;
0040: import java.util.Vector;
0041:
0042: import javax.swing.ImageIcon;
0043: import javax.swing.JButton;
0044: import javax.swing.JComboBox;
0045: import javax.swing.JOptionPane; // import javax.xml.parsers.SAXParserFactory;
0046:
0047: import org.apache.jmeter.gui.GuiPackage;
0048: import org.apache.jorphan.logging.LoggingManager;
0049: import org.apache.jorphan.test.UnitTestManager;
0050: import org.apache.jorphan.util.JOrphanUtils;
0051: import org.apache.log.Logger;
0052: import org.apache.oro.text.PatternCacheLRU;
0053: import org.apache.oro.text.regex.Pattern;
0054: import org.apache.oro.text.regex.Perl5Compiler;
0055: import org.apache.oro.text.regex.Perl5Matcher;
0056: import org.xml.sax.XMLReader;
0057:
0058: /**
0059: * This class contains the static utility methods used by JMeter.
0060: *
0061: */
0062: public class JMeterUtils implements UnitTestManager {
0063: private static Logger log = LoggingManager.getLoggerForClass();
0064:
0065: private static PatternCacheLRU patternCache = new PatternCacheLRU(
0066: getPropDefault("oro.patterncache.size", 1000), // $NON-NLS-1$
0067: new Perl5Compiler());
0068:
0069: private static final String EXPERT_MODE_PROPERTY = "jmeter.expertMode"; // $NON-NLS-1$
0070:
0071: private static Properties appProperties;
0072:
0073: private static Vector localeChangeListeners = new Vector();
0074:
0075: private static Locale locale;
0076:
0077: private static ResourceBundle resources;
0078:
0079: private static ThreadLocal localMatcher = new ThreadLocal() {
0080: protected Object initialValue() {
0081: return new Perl5Matcher();
0082: }
0083: };
0084:
0085: // Provide Random numbers to whomever wants one
0086: private static Random rand = new Random();
0087:
0088: /**
0089: * Gets Perl5Matcher for this thread.
0090: */
0091: public static Perl5Matcher getMatcher() {
0092: return (Perl5Matcher) localMatcher.get();
0093: }
0094:
0095: /**
0096: * This method is used by the init method to load the property file that may
0097: * even reside in the user space, or in the classpath under
0098: * org.apache.jmeter.jmeter.properties.
0099: *
0100: * The method also initialises logging and sets up the default Locale
0101: *
0102: * TODO - perhaps remove?
0103: * [still used
0104: *
0105: * @param file
0106: * the file to load
0107: * @return the Properties from the file
0108: */
0109: public static Properties getProperties(String file) {
0110: loadJMeterProperties(file);
0111: initLogging();
0112: initLocale();
0113: return appProperties;
0114: }
0115:
0116: /**
0117: * Initialise JMeter logging
0118: */
0119: public static void initLogging() {
0120: LoggingManager.initializeLogging(appProperties);
0121: log = LoggingManager.getLoggerForClass();
0122: }
0123:
0124: /**
0125: * Initialise the JMeter Locale
0126: */
0127: public static void initLocale() {
0128: String loc = appProperties.getProperty("language"); // $NON-NLS-1$
0129: if (loc != null) {
0130: String[] parts = JOrphanUtils.split(loc, "_");// $NON-NLS-1$
0131: if (parts.length == 2) {
0132: setLocale(new Locale(parts[0], parts[1]));
0133: } else {
0134: setLocale(new Locale(loc, "")); // $NON-NLS-1$
0135: }
0136:
0137: } else {
0138: setLocale(Locale.getDefault());
0139: }
0140: }
0141:
0142: /**
0143: * Load the JMeter properties file; if not found, then
0144: * default to "org/apache/jmeter/jmeter.properties" from the classpath
0145: *
0146: * c.f. loadProperties
0147: *
0148: */
0149: public static void loadJMeterProperties(String file) {
0150: Properties p = new Properties(System.getProperties());
0151: InputStream is = null;
0152: try {
0153: File f = new File(file);
0154: is = new FileInputStream(f);
0155: p.load(is);
0156: } catch (IOException e) {
0157: try {
0158: is = ClassLoader
0159: .getSystemResourceAsStream("org/apache/jmeter/jmeter.properties"); // $NON-NLS-1$
0160: if (is == null)
0161: throw new RuntimeException(
0162: "Could not read JMeter properties file");
0163: p.load(is);
0164: } catch (IOException ex) {
0165: // JMeter.fail("Could not read internal resource. " +
0166: // "Archive is broken.");
0167: }
0168: } finally {
0169: JOrphanUtils.closeQuietly(is);
0170: }
0171: appProperties = p;
0172: }
0173:
0174: /**
0175: * This method loads a property file that may reside in the user space, or
0176: * in the classpath
0177: *
0178: * @param file
0179: * the file to load
0180: * @return the Properties from the file
0181: */
0182: public static Properties loadProperties(String file) {
0183: Properties p = new Properties();
0184: InputStream is = null;
0185: try {
0186: File f = new File(file);
0187: is = new FileInputStream(f);
0188: p.load(is);
0189: } catch (IOException e) {
0190: try {
0191: final URL resource = JMeterUtils.class.getClassLoader()
0192: .getResource(file);
0193: if (resource == null) {
0194: log.warn("Cannot find " + file);
0195: return null;
0196: }
0197: is = resource.openStream();
0198: if (is == null) {
0199: log.warn("Cannot open " + file);
0200: return null;
0201: }
0202: p.load(is);
0203: } catch (IOException ex) {
0204: log.warn("Error reading " + file + " " + ex.toString());
0205: return null;
0206: }
0207: } finally {
0208: JOrphanUtils.closeQuietly(is);
0209: }
0210: return p;
0211: }
0212:
0213: public static PatternCacheLRU getPatternCache() {
0214: return patternCache;
0215: }
0216:
0217: /**
0218: * Get a compiled expression from the pattern cache (READ_ONLY).
0219: *
0220: * @param expression
0221: * @return compiled pattern
0222: *
0223: * @throws org.apache.oro.text.regex.MalformedPatternException (Runtime)
0224: * This should be caught for expressions that may vary (e.g. user input)
0225: *
0226: */
0227: public static Pattern getPattern(String expression) {
0228: return getPattern(expression, Perl5Compiler.READ_ONLY_MASK);
0229: }
0230:
0231: /**
0232: * Get a compiled expression from the pattern cache.
0233: *
0234: * @param expression RE
0235: * @param options e.g. READ_ONLY_MASK
0236: * @return compiled pattern
0237: *
0238: * @throws org.apache.oro.text.regex.MalformedPatternException (Runtime)
0239: * This should be caught for expressions that may vary (e.g. user input)
0240: *
0241: */
0242: public static Pattern getPattern(String expression, int options) {
0243: return patternCache.getPattern(expression, options);
0244: }
0245:
0246: public void initializeProperties(String file) {
0247: System.out.println("Initializing Properties: " + file);
0248: getProperties(file);
0249: }
0250:
0251: public static String[] getSearchPaths() {
0252: String p = JMeterUtils.getPropDefault("search_paths", null); // $NON-NLS-1$
0253: String[] result = new String[1];
0254:
0255: if (p != null) {
0256: String[] paths = p.split(";"); // $NON-NLS-1$
0257: result = new String[paths.length + 1];
0258: for (int i = 1; i < result.length; i++) {
0259: result[i] = paths[i - 1];
0260: }
0261: }
0262: result[0] = getJMeterHome() + "/lib/ext"; // $NON-NLS-1$
0263: return result;
0264: }
0265:
0266: /**
0267: * Provide random numbers
0268: *
0269: * @param r -
0270: * the upper bound (exclusive)
0271: */
0272: public static int getRandomInt(int r) {
0273: return rand.nextInt(r);
0274: }
0275:
0276: /**
0277: * Changes the current locale: re-reads resource strings and notifies
0278: * listeners.
0279: *
0280: * @param loc -
0281: * new locale
0282: */
0283: public static void setLocale(Locale loc) {
0284: log.info("Setting Locale to " + loc.toString());
0285: locale = loc;
0286: /*
0287: * See bug 29920. getBundle() defaults to the property file for the
0288: * default Locale before it defaults to the base property file, so we
0289: * need to change the default Locale to ensure the base property file is
0290: * found.
0291: */
0292: Locale def = null;
0293: if (loc.getLanguage().equals(Locale.ENGLISH.getLanguage())) {
0294: def = Locale.getDefault();
0295: // Don't change locale from en_GB to en
0296: if (!def.getLanguage().equals(Locale.ENGLISH.getLanguage())) {
0297: Locale.setDefault(Locale.ENGLISH);
0298: } else {
0299: def = null; // no need to reset Locale
0300: }
0301: }
0302: resources = ResourceBundle.getBundle(
0303: "org.apache.jmeter.resources.messages", locale); // $NON-NLS-1$
0304: notifyLocaleChangeListeners();
0305: /*
0306: * Reset Locale if necessary so other locales are properly handled
0307: */
0308: if (def != null) {
0309: Locale.setDefault(def);
0310: }
0311: }
0312:
0313: /**
0314: * Gets the current locale.
0315: *
0316: * @return current locale
0317: */
0318: public static Locale getLocale() {
0319: return locale;
0320: }
0321:
0322: public static void addLocaleChangeListener(
0323: LocaleChangeListener listener) {
0324: localeChangeListeners.add(listener);
0325: }
0326:
0327: public static void removeLocaleChangeListener(
0328: LocaleChangeListener listener) {
0329: localeChangeListeners.remove(listener);
0330: }
0331:
0332: /**
0333: * Notify all listeners interested in locale changes.
0334: *
0335: */
0336: private static void notifyLocaleChangeListeners() {
0337: LocaleChangeEvent event = new LocaleChangeEvent(
0338: JMeterUtils.class, locale);
0339: Iterator iterator = ((Vector) localeChangeListeners.clone())
0340: .iterator();
0341:
0342: while (iterator.hasNext()) {
0343: LocaleChangeListener listener = (LocaleChangeListener) iterator
0344: .next();
0345: listener.localeChanged(event);
0346: }
0347: }
0348:
0349: /**
0350: * Gets the resource string for this key.
0351: *
0352: * If the resource is not found, a warning is logged
0353: *
0354: * @param key
0355: * the key in the resource file
0356: * @return the resource string if the key is found; otherwise, return
0357: * "[res_key="+key+"]"
0358: */
0359: public static String getResString(String key) {
0360: return getResStringDefault(key, RES_KEY_PFX + key + "]"); // $NON-NLS-1$
0361: }
0362:
0363: public static final String RES_KEY_PFX = "[res_key="; // $NON-NLS-1$
0364:
0365: /**
0366: * Gets the resource string for this key.
0367: *
0368: * If the resource is not found, a warning is logged
0369: *
0370: * @param key
0371: * the key in the resource file
0372: * @param defaultValue -
0373: * the default value
0374: *
0375: * @return the resource string if the key is found; otherwise, return the
0376: * default
0377: * @deprecated Only intended for use in development; use
0378: * getResString(String) normally
0379: */
0380: public static String getResString(String key, String defaultValue) {
0381: return getResStringDefault(key, defaultValue);
0382: }
0383:
0384: /*
0385: * Helper method to do the actual work of fetching resources; allows
0386: * getResString(S,S) to be deprecated without affecting getResString(S);
0387: */
0388: private static String getResStringDefault(String key,
0389: String defaultValue) {
0390: if (key == null) {
0391: return null;
0392: }
0393: key = key.replace(' ', '_'); // TODO - why does it do this? // $NON-NLS-1$ // $NON-NLS-2$
0394: key = key.toLowerCase(); // (it's been here since v1.1)
0395: String resString = null;
0396: try {
0397: resString = resources.getString(key);
0398: } catch (MissingResourceException mre) {
0399: log.warn("ERROR! Resource string not found: [" + key + "]",
0400: mre);
0401: resString = defaultValue;
0402: }
0403: return resString;
0404: }
0405:
0406: /**
0407: * This gets the currently defined appProperties. It can only be called
0408: * after the {@link #getProperties(String)} method is called.
0409: *
0410: * @return The JMeterProperties value
0411: */
0412: public static Properties getJMeterProperties() {
0413: return appProperties;
0414: }
0415:
0416: /**
0417: * This looks for the requested image in the classpath under
0418: * org.apache.jmeter.images. <name>
0419: *
0420: * @param name
0421: * Description of Parameter
0422: * @return The Image value
0423: */
0424: public static ImageIcon getImage(String name) {
0425: try {
0426: return new ImageIcon(JMeterUtils.class.getClassLoader()
0427: .getResource(
0428: "org/apache/jmeter/images/" + name.trim())); // $NON-NLS-1$
0429: } catch (NullPointerException e) {
0430: log.warn("no icon for " + name);
0431: return null;
0432: } catch (NoClassDefFoundError e) {// Can be returned by headless hosts
0433: log.info("no icon for " + name + " " + e.getMessage());
0434: return null;
0435: } catch (InternalError e) {// Can be returned by headless hosts
0436: log.info("no icon for " + name + " " + e.getMessage());
0437: return null;
0438: }
0439: }
0440:
0441: /**
0442: * This looks for the requested image in the classpath under
0443: * org.apache.jmeter.images. <name>, and also sets the description
0444: * of the image, which is useful if the icon is going to be placed
0445: * on the clipboard.
0446: *
0447: * @param name
0448: * the name of the image
0449: * @param description
0450: * the description of the image
0451: * @return The Image value
0452: */
0453: public static ImageIcon getImage(String name, String description) {
0454: ImageIcon icon = getImage(name);
0455: if (icon != null) {
0456: icon.setDescription(description);
0457: }
0458: return icon;
0459: }
0460:
0461: public static String getResourceFileAsText(String name) {
0462: BufferedReader fileReader = null;
0463: try {
0464: String lineEnd = System.getProperty("line.separator"); // $NON-NLS-1$
0465: fileReader = new BufferedReader(new InputStreamReader(
0466: JMeterUtils.class.getClassLoader()
0467: .getResourceAsStream(name)));
0468: StringBuffer text = new StringBuffer();
0469: String line = "NOTNULL"; // $NON-NLS-1$
0470: while (line != null) {
0471: line = fileReader.readLine();
0472: if (line != null) {
0473: text.append(line);
0474: text.append(lineEnd);
0475: }
0476: }
0477: // Done by finally block: fileReader.close();
0478: return text.toString();
0479: } catch (NullPointerException e) // Cannot find file
0480: {
0481: return ""; // $NON-NLS-1$
0482: } catch (IOException e) {
0483: return ""; // $NON-NLS-1$
0484: } finally {
0485: if (fileReader != null)
0486: try {
0487: fileReader.close();
0488: } catch (IOException e1) {
0489: }
0490: }
0491: }
0492:
0493: /**
0494: * Creates the vector of Timers plugins.
0495: *
0496: * @param properties
0497: * Description of Parameter
0498: * @return The Timers value
0499: */
0500: public static Vector getTimers(Properties properties) {
0501: return instantiate(getVector(properties, "timer."), // $NON-NLS-1$
0502: "org.apache.jmeter.timers.Timer"); // $NON-NLS-1$
0503: }
0504:
0505: /**
0506: * Creates the vector of visualizer plugins.
0507: *
0508: * @param properties
0509: * Description of Parameter
0510: * @return The Visualizers value
0511: */
0512: public static Vector getVisualizers(Properties properties) {
0513: return instantiate(getVector(properties, "visualizer."), // $NON-NLS-1$
0514: "org.apache.jmeter.visualizers.Visualizer"); // $NON-NLS-1$
0515: }
0516:
0517: /**
0518: * Creates a vector of SampleController plugins.
0519: *
0520: * @param properties
0521: * The properties with information about the samplers
0522: * @return The Controllers value
0523: */
0524: // TODO - does not appear to be called directly
0525: public static Vector getControllers(Properties properties) {
0526: String name = "controller."; // $NON-NLS-1$
0527: Vector v = new Vector();
0528: Enumeration names = properties.keys();
0529: while (names.hasMoreElements()) {
0530: String prop = (String) names.nextElement();
0531: if (prop.startsWith(name)) {
0532: Object o = instantiate(properties.getProperty(prop),
0533: "org.apache.jmeter.control.SamplerController"); // $NON-NLS-1$
0534: v.addElement(o);
0535: }
0536: }
0537: return v;
0538: }
0539:
0540: /**
0541: * Create a string of class names for a particular SamplerController
0542: *
0543: * @param properties
0544: * The properties with info about the samples.
0545: * @param name
0546: * The name of the sampler controller.
0547: * @return The TestSamples value
0548: */
0549: public static String[] getTestSamples(Properties properties,
0550: String name) {
0551: return (String[]) getVector(properties, name + ".testsample")
0552: .toArray(new String[0]); // $NON-NLS-1$
0553: }
0554:
0555: /**
0556: * Create an instance of an org.xml.sax.Parser based on the default props.
0557: *
0558: * @return The XMLParser value
0559: */
0560: public static XMLReader getXMLParser() {
0561: XMLReader reader = null;
0562: try {
0563: reader = (XMLReader) instantiate(getPropDefault(
0564: "xml.parser", // $NON-NLS-1$
0565: "org.apache.xerces.parsers.SAXParser"), // $NON-NLS-1$
0566: "org.xml.sax.XMLReader"); // $NON-NLS-1$
0567: // reader = xmlFactory.newSAXParser().getXMLReader();
0568: } catch (Exception e) {
0569: reader = (XMLReader) instantiate(getPropDefault(
0570: "xml.parser", // $NON-NLS-1$
0571: "org.apache.xerces.parsers.SAXParser"), // $NON-NLS-1$
0572: "org.xml.sax.XMLReader"); // $NON-NLS-1$
0573: }
0574: return reader;
0575: }
0576:
0577: /**
0578: * Creates the vector of alias strings.
0579: *
0580: * @param properties
0581: * Description of Parameter
0582: * @return The Alias value
0583: */
0584: public static Hashtable getAlias(Properties properties) {
0585: return getHashtable(properties, "alias."); // $NON-NLS-1$
0586: }
0587:
0588: /**
0589: * Creates a vector of strings for all the properties that start with a
0590: * common prefix.
0591: *
0592: * @param properties
0593: * Description of Parameter
0594: * @param name
0595: * Description of Parameter
0596: * @return The Vector value
0597: */
0598: public static Vector getVector(Properties properties, String name) {
0599: Vector v = new Vector();
0600: Enumeration names = properties.keys();
0601: while (names.hasMoreElements()) {
0602: String prop = (String) names.nextElement();
0603: if (prop.startsWith(name)) {
0604: v.addElement(properties.getProperty(prop));
0605: }
0606: }
0607: return v;
0608: }
0609:
0610: /**
0611: * Creates a table of strings for all the properties that start with a
0612: * common prefix.
0613: *
0614: * @param properties
0615: * Description of Parameter
0616: * @param name
0617: * Description of Parameter
0618: * @return The Hashtable value
0619: */
0620: public static Hashtable getHashtable(Properties properties,
0621: String name) {
0622: Hashtable t = new Hashtable();
0623: Enumeration names = properties.keys();
0624: while (names.hasMoreElements()) {
0625: String prop = (String) names.nextElement();
0626: if (prop.startsWith(name)) {
0627: t.put(prop.substring(name.length()), properties
0628: .getProperty(prop));
0629: }
0630: }
0631: return t;
0632: }
0633:
0634: /**
0635: * Get a int value with default if not present.
0636: *
0637: * @param propName
0638: * the name of the property.
0639: * @param defaultVal
0640: * the default value.
0641: * @return The PropDefault value
0642: */
0643: public static int getPropDefault(String propName, int defaultVal) {
0644: int ans;
0645: try {
0646: ans = (Integer.valueOf(appProperties.getProperty(propName,
0647: Integer.toString(defaultVal)).trim())).intValue();
0648: } catch (Exception e) {
0649: ans = defaultVal;
0650: }
0651: return ans;
0652: }
0653:
0654: /**
0655: * Get a boolean value with default if not present.
0656: *
0657: * @param propName
0658: * the name of the property.
0659: * @param defaultVal
0660: * the default value.
0661: * @return The PropDefault value
0662: */
0663: public static boolean getPropDefault(String propName,
0664: boolean defaultVal) {
0665: boolean ans;
0666: try {
0667: String strVal = appProperties.getProperty(propName,
0668: Boolean.toString(defaultVal)).trim();
0669: if (strVal.equalsIgnoreCase("true")
0670: || strVal.equalsIgnoreCase("t")) { // $NON-NLS-1$ // $NON-NLS-2$
0671: ans = true;
0672: } else if (strVal.equalsIgnoreCase("false")
0673: || strVal.equalsIgnoreCase("f")) { // $NON-NLS-1$ // $NON-NLS-2$
0674: ans = false;
0675: } else {
0676: ans = ((Integer.valueOf(strVal)).intValue() == 1);
0677: }
0678: } catch (Exception e) {
0679: ans = defaultVal;
0680: }
0681: return ans;
0682: }
0683:
0684: /**
0685: * Get a long value with default if not present.
0686: *
0687: * @param propName
0688: * the name of the property.
0689: * @param defaultVal
0690: * the default value.
0691: * @return The PropDefault value
0692: */
0693: public static long getPropDefault(String propName, long defaultVal) {
0694: long ans;
0695: try {
0696: ans = (Long.valueOf(appProperties.getProperty(propName,
0697: Long.toString(defaultVal)).trim())).longValue();
0698: } catch (Exception e) {
0699: ans = defaultVal;
0700: }
0701: return ans;
0702: }
0703:
0704: /**
0705: * Get a String value with default if not present.
0706: *
0707: * @param propName
0708: * the name of the property.
0709: * @param defaultVal
0710: * the default value.
0711: * @return The PropDefault value
0712: */
0713: public static String getPropDefault(String propName,
0714: String defaultVal) {
0715: String ans;
0716: try {
0717: ans = appProperties.getProperty(propName, defaultVal)
0718: .trim();
0719: } catch (Exception e) {
0720: ans = defaultVal;
0721: }
0722: return ans;
0723: }
0724:
0725: /**
0726: * Get the value of a JMeter property.
0727: *
0728: * @param propName
0729: * the name of the property.
0730: * @return the value of the JMeter property, or null if not defined
0731: */
0732: public static String getProperty(String propName) {
0733: String ans = null;
0734: try {
0735: ans = appProperties.getProperty(propName);
0736: } catch (Exception e) {
0737: ans = null;
0738: }
0739: return ans;
0740: }
0741:
0742: /**
0743: * Set a String value
0744: *
0745: * @param propName
0746: * the name of the property.
0747: * @param propValue
0748: * the value of the property
0749: * @return the previous value of the property
0750: */
0751: public static Object setProperty(String propName, String propValue) {
0752: return appProperties.setProperty(propName, propValue);
0753: }
0754:
0755: /**
0756: * Sets the selection of the JComboBox to the Object 'name' from the list in
0757: * namVec.
0758: */
0759: public static void selJComboBoxItem(Properties properties,
0760: JComboBox combo, Vector namVec, String name) {
0761: int idx = namVec.indexOf(name);
0762: combo.setSelectedIndex(idx);
0763: // Redisplay.
0764: combo.updateUI();
0765: return;
0766: }
0767:
0768: /**
0769: * Instatiate an object and guarantee its class.
0770: *
0771: * @param className
0772: * The name of the class to instantiate.
0773: * @param impls
0774: * The name of the class it subclases.
0775: * @return Description of the Returned Value
0776: */
0777: public static Object instantiate(String className, String impls) {
0778: if (className != null) {
0779: className = className.trim();
0780: }
0781:
0782: if (impls != null) {
0783: impls = impls.trim();
0784: }
0785:
0786: try {
0787: Class c = Class.forName(impls);
0788: try {
0789: Class o = Class.forName(className);
0790: Object res = o.newInstance();
0791: if (c.isInstance(res)) {
0792: return res;
0793: }
0794: throw new IllegalArgumentException(className
0795: + " is not an instance of " + impls);
0796: } catch (ClassNotFoundException e) {
0797: log.error("Error loading class " + className
0798: + ": class is not found");
0799: } catch (IllegalAccessException e) {
0800: log.error("Error loading class " + className
0801: + ": does not have access");
0802: } catch (InstantiationException e) {
0803: log.error("Error loading class " + className
0804: + ": could not instantiate");
0805: } catch (NoClassDefFoundError e) {
0806: log.error("Error loading class " + className
0807: + ": couldn't find class " + e.getMessage());
0808: }
0809: } catch (ClassNotFoundException e) {
0810: log.error("Error loading class " + impls
0811: + ": was not found.");
0812: }
0813: return null;
0814: }
0815:
0816: /**
0817: * Instantiate a vector of classes
0818: *
0819: * @param v
0820: * Description of Parameter
0821: * @param className
0822: * Description of Parameter
0823: * @return Description of the Returned Value
0824: */
0825: public static Vector instantiate(Vector v, String className) {
0826: Vector i = new Vector();
0827: try {
0828: Class c = Class.forName(className);
0829: Enumeration elements = v.elements();
0830: while (elements.hasMoreElements()) {
0831: String name = (String) elements.nextElement();
0832: try {
0833: Object o = Class.forName(name).newInstance();
0834: if (c.isInstance(o)) {
0835: i.addElement(o);
0836: }
0837: } catch (ClassNotFoundException e) {
0838: log.error("Error loading class " + name
0839: + ": class is not found");
0840: } catch (IllegalAccessException e) {
0841: log.error("Error loading class " + name
0842: + ": does not have access");
0843: } catch (InstantiationException e) {
0844: log.error("Error loading class " + name
0845: + ": could not instantiate");
0846: } catch (NoClassDefFoundError e) {
0847: log
0848: .error("Error loading class " + name
0849: + ": couldn't find class "
0850: + e.getMessage());
0851: }
0852: }
0853: } catch (ClassNotFoundException e) {
0854: log.error("Error loading class " + className
0855: + ": class is not found");
0856: }
0857: return i;
0858: }
0859:
0860: /**
0861: * Tokenize a string into a vector of tokens
0862: *
0863: * @param string
0864: * Description of Parameter
0865: * @param separator
0866: * Description of Parameter
0867: * @return Description of the Returned Value
0868: */
0869: //TODO move to JOrphanUtils ?
0870: public static Vector tokenize(String string, String separator) {
0871: Vector v = new Vector();
0872: StringTokenizer s = new StringTokenizer(string, separator);
0873: while (s.hasMoreTokens()) {
0874: v.addElement(s.nextToken());
0875: }
0876: return v;
0877: }
0878:
0879: /**
0880: * Create a button with the netscape style
0881: *
0882: * @param name
0883: * Description of Parameter
0884: * @param listener
0885: * Description of Parameter
0886: * @return Description of the Returned Value
0887: */
0888: public static JButton createButton(String name,
0889: ActionListener listener) {
0890: JButton button = new JButton(getImage(name + ".on.gif")); // $NON-NLS-1$
0891: button.setDisabledIcon(getImage(name + ".off.gif")); // $NON-NLS-1$
0892: button.setRolloverIcon(getImage(name + ".over.gif")); // $NON-NLS-1$
0893: button.setPressedIcon(getImage(name + ".down.gif")); // $NON-NLS-1$
0894: button.setActionCommand(name);
0895: button.addActionListener(listener);
0896: button.setRolloverEnabled(true);
0897: button.setFocusPainted(false);
0898: button.setBorderPainted(false);
0899: button.setOpaque(false);
0900: button.setPreferredSize(new Dimension(24, 24));
0901: return button;
0902: }
0903:
0904: /**
0905: * Create a button with the netscape style
0906: *
0907: * @param name
0908: * Description of Parameter
0909: * @param listener
0910: * Description of Parameter
0911: * @return Description of the Returned Value
0912: */
0913: public static JButton createSimpleButton(String name,
0914: ActionListener listener) {
0915: JButton button = new JButton(getImage(name + ".gif")); // $NON-NLS-1$
0916: button.setActionCommand(name);
0917: button.addActionListener(listener);
0918: button.setFocusPainted(false);
0919: button.setBorderPainted(false);
0920: button.setOpaque(false);
0921: button.setPreferredSize(new Dimension(25, 25));
0922: return button;
0923: }
0924:
0925: /**
0926: * Report an error through a dialog box.
0927: * Title defaults to "error_title" resource string
0928: * @param errorMsg - the error message.
0929: */
0930: public static void reportErrorToUser(String errorMsg) {
0931: reportErrorToUser(errorMsg, JMeterUtils
0932: .getResString("error_title")); // $NON-NLS-1$
0933: }
0934:
0935: /**
0936: * Report an error through a dialog box.
0937: *
0938: * @param errorMsg - the error message.
0939: * @param titleMsg - title string
0940: */
0941: public static void reportErrorToUser(String errorMsg,
0942: String titleMsg) {
0943: if (errorMsg == null) {
0944: errorMsg = "Unknown error - see log file";
0945: log
0946: .warn("Unknown error", new Throwable(
0947: "errorMsg == null"));
0948: }
0949: GuiPackage instance = GuiPackage.getInstance();
0950: if (instance == null) {
0951: System.out.println(errorMsg);
0952: return; // Done
0953: }
0954: try {
0955: JOptionPane.showMessageDialog(instance.getMainFrame(),
0956: errorMsg, titleMsg, JOptionPane.ERROR_MESSAGE);
0957: } catch (HeadlessException e) {
0958: log.warn("reportErrorToUser(\"" + errorMsg + "\") caused",
0959: e);
0960: }
0961: }
0962:
0963: /**
0964: * Finds a string in an array of strings and returns the
0965: *
0966: * @param array
0967: * Array of strings.
0968: * @param value
0969: * String to compare to array values.
0970: * @return Index of value in array, or -1 if not in array.
0971: */
0972: //TODO - move to JOrphanUtils?
0973: public static int findInArray(String[] array, String value) {
0974: int count = -1;
0975: int index = -1;
0976: if (array != null && value != null) {
0977: while (++count < array.length) {
0978: if (array[count] != null && array[count].equals(value)) {
0979: index = count;
0980: break;
0981: }
0982: }
0983: }
0984: return index;
0985: }
0986:
0987: /**
0988: * Takes an array of strings and a tokenizer character, and returns a string
0989: * of all the strings concatenated with the tokenizer string in between each
0990: * one.
0991: *
0992: * @param splittee
0993: * Array of Objects to be concatenated.
0994: * @param splitChar
0995: * Object to unsplit the strings with.
0996: * @return Array of all the tokens.
0997: */
0998: //TODO - move to JOrphanUtils?
0999: public static String unsplit(Object[] splittee, Object splitChar) {
1000: StringBuffer retVal = new StringBuffer();
1001: int count = -1;
1002: while (++count < splittee.length) {
1003: if (splittee[count] != null) {
1004: retVal.append(splittee[count]);
1005: }
1006: if (count + 1 < splittee.length
1007: && splittee[count + 1] != null) {
1008: retVal.append(splitChar);
1009: }
1010: }
1011: return retVal.toString();
1012: }
1013:
1014: // End Method
1015:
1016: /**
1017: * Takes an array of strings and a tokenizer character, and returns a string
1018: * of all the strings concatenated with the tokenizer string in between each
1019: * one.
1020: *
1021: * @param splittee
1022: * Array of Objects to be concatenated.
1023: * @param splitChar
1024: * Object to unsplit the strings with.
1025: * @param def
1026: * Default value to replace null values in array.
1027: * @return Array of all the tokens.
1028: */
1029: //TODO - move to JOrphanUtils?
1030: public static String unsplit(Object[] splittee, Object splitChar,
1031: String def) {
1032: StringBuffer retVal = new StringBuffer();
1033: int count = -1;
1034: while (++count < splittee.length) {
1035: if (splittee[count] != null) {
1036: retVal.append(splittee[count]);
1037: } else {
1038: retVal.append(def);
1039: }
1040: if (count + 1 < splittee.length) {
1041: retVal.append(splitChar);
1042: }
1043: }
1044: return retVal.toString();
1045: }
1046:
1047: /**
1048: * Get the JMeter home directory - does not include the trailing separator.
1049: *
1050: * @return the home directory
1051: */
1052: public static String getJMeterHome() {
1053: return jmDir;
1054: }
1055:
1056: /**
1057: * Get the JMeter bin directory - does not include the trailing separator.
1058: *
1059: * @return the bin directory
1060: */
1061: public static String getJMeterBinDir() {
1062: return jmBin;
1063: }
1064:
1065: public static void setJMeterHome(String home) {
1066: jmDir = home;
1067: jmBin = jmDir + File.separator + "bin"; // $NON-NLS-1$
1068: }
1069:
1070: private static String jmDir; // JMeter Home directory (excludes trailing separator)
1071: private static String jmBin; // JMeter bin directory (excludes trailing separator)
1072:
1073: /**
1074: * Gets the JMeter Version.
1075: *
1076: * @return the JMeter version string
1077: */
1078: public static String getJMeterVersion() {
1079: return JMeterVersion.getVERSION();
1080: }
1081:
1082: /**
1083: * Gets the JMeter copyright.
1084: *
1085: * @return the JMeter copyright string
1086: */
1087: public static String getJMeterCopyright() {
1088: return JMeterVersion.COPYRIGHT;
1089: }
1090:
1091: /**
1092: * Determine whether we are in 'expert' mode. Certain features may be hidden
1093: * from user's view unless in expert mode.
1094: *
1095: * @return true iif we're in expert mode
1096: */
1097: public static boolean isExpertMode() {
1098: return JMeterUtils.getPropDefault(EXPERT_MODE_PROPERTY, false);
1099: }
1100:
1101: /**
1102: * Find a file in the current directory or in the JMeter bin directory.
1103: *
1104: * @param fileName
1105: * @return File object
1106: */
1107: public static File findFile(String fileName) {
1108: File f = new File(fileName);
1109: if (!f.exists()) {
1110: f = new File(getJMeterBinDir(), fileName);
1111: }
1112: return f;
1113: }
1114: }
|