de.mcs.jmeasurement.JMConfig Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of JMeasurement Show documentation
Show all versions of JMeasurement Show documentation
JMeasurement profiling programs in production enviroment
/*
* MCS Media Computer Software Copyright (c) 2006 by MCS
* -------------------------------------- Created on 31.12.2006 by w.klaas
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
/**
*
*/
package de.mcs.jmeasurement;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.InvalidPropertiesFormatException;
import java.util.Properties;
import java.util.Timer;
import java.util.TimerTask;
import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanRegistrationException;
import javax.management.NotCompliantMBeanException;
import de.mcs.jmeasurement.MeasurePoint.PRIORITY;
/**
* This class hold's all configuration settings for the MeasureFactory. It can load the configuration from a property
* file (with automatic file change checking) or an xml file. (Standard format) All defined options are declared as
* constants. All settings could be overridden by program, so they will not be reload automatically again. The simpelst
* configuration is to call the configure methode of the MeasureFactory. The property file will be searched
* automatically in the classpath and loaded. The class can save the actual settings to an property or xml file, too.
* Here is an example of a jmconfig.properties file:
*
*
* OPTION_ENABLE_MEASUREMENT=true
* OPTION_PRIORITY=[HIGHEST,HIGH,MEDIUM,LOW,LOWEST] Defaults to MEDIUM
* OPTION_BACKGROUND_TIME=10000
* OPTION_ENABLE_AUTOSNAPSHOT=true
* OPTION_ENABLE_MEMORY_SAVINGS=true
* OPTION_POINT_IDLETIME=60000
* OPTION_WORKINGPATH=e\:\\temp\\data\\
* OPTION_EXCEPTION_HANDLING =2
* OPTION_CONFIG_AUTOFILE=true
* OPTION_DISABLE_DEVIATION=false
* OPTION_ENABLE_JMX=false
*
*
* @author w.klaas
*/
public class JMConfig {
/** adding the jmx bean automatically to the first jmx container. */
public static final String OPTION_ENABLE_JMX = "OPTION_ENABLE_JMX";
/** constant for enabling the measurement. */
public static final String OPTION_ENABLE_MEASUREMENT = "OPTION_ENABLE_MEASUREMENT";
/** constant for setting the priority. */
public static final String OPTION_PRIORITY = "OPTION_PRIORITY";
/** automatically reload the config file. */
public static final String OPTION_CONFIG_AUTOFILE = "OPTION_CONFIG_AUTOFILE";
/** constant for deviation disabling. */
public static final String OPTION_DISABLE_DEVIATION = "OPTION_DISABLE_DEVIATION";
/** Enable the automatic snapshot system. */
public static final String OPTION_ENABLE_AUTOSNAPSHOT = "OPTION_ENABLE_AUTOSNAPSHOT";
/** Time (in msec) to process background thread. */
public static final String OPTION_BACKGROUND_TIME = "OPTION_BACKGROUND_TIME";
/** Enable the automatic memory saving system. */
public static final String OPTION_ENABLE_MEMORY_SAVINGS = "OPTION_ENABLE_MEMORY_SAVINGS";
/** Enable the automatic memory saving system. */
public static final String OPTION_POINT_IDLETIME = "OPTION_POINT_IDLETIME";
/** Path where to store the measuredata. */
public static final String OPTION_WORKINGPATH = "OPTION_WORKINGPATH";
/** Name of the application under test. */
public static final String OPTION_APPLICATION_NAME = "OPTION_APPLICATION_NAME";
/** With the automatic interface measuring, you can set that the parameters should be added to the point name. */
public static final String OPTION_POINT_NAME_WITH_PARAMETER = "OPTION_POINT_NAME_WITH_PARAMETER";
/** exception handling. */
public static final String OPTION_EXCEPTION_HANDLING = "OPTION_EXCEPTION_HANDLING";
/** constants for exception handling. Only counting. */
public static final int EXCEPTION_COUNT = 0;
/** constants for exception handling. Counting and activation and name. */
public static final int EXCEPTION_NAME = 1;
/** constants for exception handling. Full stacktrace. */
public static final int EXCEPTION_TRACE = 2;
/**
* this class will hold a simple default value for a setting. (needed for
* the defaults array)
*
* @author w.klaas
*/
static class JMDefault {
/** name of the setting. */
private String name;
/** default value of the setting. */
private String value;
/**
* constructor.
*
* @param aName
* name of the setting.
* @param aValue
* default value of this setting.
*/
JMDefault(final String aName, final String aValue) {
this.name = aName;
this.value = aValue;
}
}
/** the defaults array, with all default values for the JMeasureFactory. */
private static final JMDefault[] DEFAULTS = { new JMDefault(OPTION_ENABLE_MEASUREMENT, "true"),
new JMDefault(OPTION_CONFIG_AUTOFILE, "false"), new JMDefault(OPTION_PRIORITY, "MEDIUM"),
new JMDefault(OPTION_WORKINGPATH, System.getProperty("java.io.tmpdir")),
new JMDefault(OPTION_ENABLE_AUTOSNAPSHOT, "false"), new JMDefault(OPTION_ENABLE_MEMORY_SAVINGS, "false"),
new JMDefault(OPTION_POINT_IDLETIME, "90000"), new JMDefault(OPTION_DISABLE_DEVIATION, "false"),
new JMDefault(OPTION_APPLICATION_NAME, ""), new JMDefault(OPTION_EXCEPTION_HANDLING, "0"),
new JMDefault(OPTION_ENABLE_JMX, "false"), new JMDefault(OPTION_BACKGROUND_TIME, "0") };
/** this will hold the configuration. */
private Properties config;
/** this will hold the overriding settings. */
private Properties override;
/** the timestamp for the properties or xml file. */
private long fileTimeStamp = 0;
/** the timer for the background process. */
private Timer backgroundtimer;
/** the url to the input file for reloading. */
private URL inputURL;
/** cached value of the measurement enabling, for faster access. */
private boolean enableMeasurement;
/**
* This is the background task for checking the file periodically.
*
* @author w.klaas
*/
class ConfigTask extends TimerTask {
/**
* This method will be called everytime the file must be checked for
* differences.
*/
@Override
public void run() {
if (inputURL != null) {
long newFileTimeStamp = 0;
try {
newFileTimeStamp = new File(inputURL.toURI()).lastModified();
} catch (URISyntaxException e) {
e.printStackTrace();
}
if (fileTimeStamp != 0) {
if (fileTimeStamp < newFileTimeStamp) {
load();
fileTimeStamp = newFileTimeStamp;
}
}
}
}
}
/**
* constructing a new configuration with default values.
*/
public JMConfig() {
config = new Properties();
override = new Properties();
initDefaults();
}
/** initialise the default values. */
private void initDefaults() {
for (int i = 0; i < DEFAULTS.length; i++) {
JMDefault element = DEFAULTS[i];
config.setProperty(element.name, element.value);
}
processConfig();
}
/**
* load configuration from jmconfig.properties file in the classpath.
*
* @return true
if the file could be loaded, otherwise false
.
*/
public final boolean configure() {
inputURL = getClass().getClassLoader().getResource("jmconfig.properties");
if (inputURL == null) {
inputURL = getClass().getClassLoader().getResource("jmconfig.xml");
if (inputURL == null) {
return false;
}
}
if (inputURL.getProtocol().equalsIgnoreCase("file")) {
try {
fileTimeStamp = new File(inputURL.toURI()).lastModified();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
return load();
}
/**
* load configuration from the given file.
*
* @param jmConfig
* the config file to load.
* @return true
if the file could be loaded, otherwise false
.
*/
public final boolean configure(final File jmConfig) {
try {
inputURL = jmConfig.toURI().toURL();
if (inputURL.getProtocol().equalsIgnoreCase("file")) {
try {
fileTimeStamp = new File(inputURL.toURI()).lastModified();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return load();
}
/**
* loading the configuration from a file. This method will differe between
* the loading of a property file or xml file.
*
* @return true
if the file could be readed and processed
* right, otherwise false
*/
private boolean load() {
InputStream input;
try {
input = inputURL.openStream();
try {
if (inputURL.getFile().toLowerCase().endsWith(".xml")) {
return loadFromXML(input);
} else {
return loadFromFile(input);
}
} finally {
input.close();
}
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
/**
* Loading configuration from input stream as a property file.
*
* @param input
* the stream to read from
* @return true
if the file could be readed and processed
* right, otherwise false
*/
private boolean loadFromFile(final InputStream input) {
try {
config.load(input);
processConfig();
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
/**
* Loading configuration from input stream as a xml file.
*
* @param input
* the stream to read from
* @return true
if the file could be readed and processed
* right, otherwise false
*/
private boolean loadFromXML(final InputStream input) {
try {
config.loadFromXML(input);
processConfig();
return true;
} catch (InvalidPropertiesFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
/**
* processing the configuration. This will check, if an automatic file
* watcher will be established or not.
*
* @throws NotCompliantMBeanException
* @throws MBeanRegistrationException
* @throws InstanceAlreadyExistsException
*/
private void processConfig() {
if (getBoolean(JMConfig.OPTION_CONFIG_AUTOFILE)) {
if (backgroundtimer != null) {
if (backgroundtimer != null) {
backgroundtimer.cancel();
backgroundtimer.purge();
backgroundtimer = null;
}
}
backgroundtimer = new Timer("JMeasurement Config Background Timer", true);
long period = getLong(JMConfig.OPTION_BACKGROUND_TIME);
backgroundtimer.scheduleAtFixedRate(new ConfigTask(), period, period);
}
// here we are actualising the cache value
enableMeasurement = getBoolean(OPTION_ENABLE_MEASUREMENT);
// now setting the background timing in factory
if (getLong(JMConfig.OPTION_BACKGROUND_TIME) > 0) {
if (MeasureFactory.isBackgroundProcessing()) {
MeasureFactory.setBackgroundProcessing(false);
}
MeasureFactory.setBackgroundProcessing(true);
}
if (getBoolean(OPTION_ENABLE_JMX)) {
MeasureFactory.registerMBeans();
} else {
MeasureFactory.deregisterMBeans();
}
MeasureFactory.setPriority(PRIORITY.valueOf(getProperty(OPTION_PRIORITY, PRIORITY.MEDIUM.name())));
}
/**
* setting a string setting.
*
* @param key
* name of the setting
* @param value
* value of the setting
*/
public final void setProperty(final String key, final String value) {
override.setProperty(key, value);
processConfig();
}
/**
* setting a integer setting.
*
* @param key
* name of the setting
* @param value
* value of the setting
*/
public final void setInteger(final String key, final int value) {
setProperty(key, Integer.toString(value));
}
/**
* setting a boolean setting.
*
* @param key
* name of the setting
* @param value
* value of the setting
*/
public final void setBoolean(final String key, final boolean value) {
setProperty(key, Boolean.toString(value));
}
/**
* setting a long setting.
*
* @param key
* name of the setting
* @param value
* value of the setting
*/
public final void setLong(final String key, final long value) {
setProperty(key, Long.toString(value));
}
/**
* looking if the parameter is in the config.
* @param key name of the parameter
* @return true or false
*/
public final boolean contains(String key) {
return override.containsKey(key) || config.containsKey(key);
}
/**
* getting a boolean setting.
*
* @param key
* name of the setting
* @return value value of the setting
*/
public final boolean getBoolean(final String key) {
return Boolean.parseBoolean(getProperty(key));
}
/**
* getting a integer setting.
*
* @param key
* name of the setting
* @return value value of the setting
*/
public final int getInteger(final String key) {
return Integer.parseInt(getProperty(key));
}
/**
* getting a string setting.
*
* @param key
* name of the setting
* @return value value of the setting
*/
public final String getProperty(final String key) {
if (override.containsKey(key)) {
return override.getProperty(key);
}
return config.getProperty(key);
}
/**
* getting a string setting.
*
* @param key
* name of the setting
* @param defaultValue
* the default value, will be delivered if the key is not set.
* @return value value of the setting
*/
public final String getProperty(final String key, final String defaultValue) {
if (override.containsKey(key)) {
return override.getProperty(key);
}
return config.getProperty(key, defaultValue);
}
/**
* getting a long setting.
*
* @param key
* name of the setting
* @return value value of the setting
*/
public final long getLong(final String key) {
return Long.parseLong(getProperty(key));
}
/**
* removes the setting with the name as an overridden setting. So from now
* on the setting will be used as in the config file or as the default
* value.
*
* @param key
* name of the setting to remove from the override setting list.
*/
public final void remove(final String key) {
if (override.containsKey(key)) {
override.remove(key);
}
}
/**
* @return the enableMeasurement
*/
public final boolean isEnableMeasurement() {
return enableMeasurement;
}
/**
* @param value
* the enableMeasurement to set
*/
public final void setEnableMeasurement(final boolean value) {
setBoolean(OPTION_ENABLE_MEASUREMENT, value);
}
}