ExtendedProperties.java

Index Score
org.apache.commons.collections
Commons Collections

View: Reasons, Metrics, Source Code

These are the metrics that contribute to the Enerjy Score for this file, ranked by impact. So the metrics listed at the top influence the score to a greater extent that the metrics listed at the bottom.

MetricDescription
DOC_COMMENTNumber of javadoc comment lines
COMMENTSComment lines
DECL_COMMENTSComments in declarations
SIZESize of the file in bytes
BLOCKSNumber of blocks
LINESNumber of lines in the source file
CYCLOMATICCyclomatic complexity
RETURNSNumber of return points from functions
INTERFACE_COMPLEXITYInterface complexity
LOOPSNumber of loops
PARAMSNumber of formal parameter declarations
COMPARISONSNumber of comparison operators
OPERATORSNumber of operators
EXEC_COMMENTSComments in executable code
PROGRAM_LENGTHHalstead program length
JAVA0133JAVA0133 Non-synchronized method overrides synchronized method
LOGICAL_LINESNumber of statements
LOCLines of code
ELOCEffective lines of code
OPERANDSNumber of operands
FUNCTIONSNumber of function declarations
EXITSProcedure exits
UNIQUE_OPERANDSNumber of unique operands
LINE_COMMENTNumber of line comments
PROGRAM_VOCABHalstead program vocabulary
JAVA0254JAVA0254 Use enhanced for loop construct instead of Iterator
JAVA0132JAVA0132 Method overload with compatible signature
JAVA0108JAVA0108 Incorrect javadoc: no @param tag for 'parameter'
JAVA0034JAVA0034 Missing braces in if statement
WHITESPACENumber of whitespace lines
JAVA0110JAVA0110 Incorrect javadoc: no @return tag
JAVA0049JAVA0049 Nested block at depth N (maximum: M)
JAVA0143JAVA0143 Synchronized method
JAVA0128JAVA0128 Public constructor in non-public class
UNIQUE_OPERATORSNumber of unique operators
JAVA0278JAVA0278 Unnecessary use of Boolean constructor
NEST_DEPTHMaximum nesting depth
JAVA0068JAVA0068 Modifiers not declared in recommended order
JAVA0117JAVA0117 Missing javadoc: method 'method'
JAVA0177JAVA0177 Variable declaration missing initializer
JAVA0119JAVA0119 Control variable changed within body of for loop
PROGRAM_VOLUMEHalstead program volume
JAVA0136JAVA0136 N methods defined in class (maximum: M)
JAVA0160JAVA0160 Method does not throw specified exception
JAVA0126JAVA0126 Method declares unchecked exception in throws
JAVA0179JAVA0179 Local variable hides visible field
JAVA0123JAVA0123 Use all three components of for loop
JAVA0287JAVA0287 Unnecessary null check
JAVA0075JAVA0075 Method parameter hides field
JAVA0270JAVA0270 Use Java 5.0 enhanced for loop construct to iterate over all elements in an array
JAVA0145JAVA0145 Tab character used in source file
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 org.apache.commons.collections; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.LineNumberReader; import java.io.OutputStream; import java.io.PrintWriter; import java.io.Reader; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.NoSuchElementException; import java.util.Properties; import java.util.StringTokenizer; import java.util.Vector; /** * This class extends normal Java properties by adding the possibility * to use the same key many times concatenating the value strings * instead of overwriting them. * <p> * <b>Please consider using the * {@link org.apache.commons.configuration.PropertiesConfiguration} class in * <a href="http://commons.apache.org/configuration">Commons Configuration</a>. * It's an evolution of <code>ExtendedProperties</code> supporting more * features like automatic reloading, advanced interpolation, more type * conversions, changes notifications and file layout preservation.</b> * <p> * The Extended Properties syntax is explained here: * * <ul> * <li> * Each property has the syntax <code>key = value</code> * </li> * <li> * The <i>key</i> may use any character but the equal sign '='. * </li> * <li> * <i>value</i> may be separated on different lines if a backslash * is placed at the end of the line that continues below. * </li> * <li> * If <i>value</i> is a list of strings, each token is separated * by a comma ','. * </li> * <li> * Commas in each token are escaped placing a backslash right before * the comma. * </li> * <li> * Backslashes are escaped by using two consecutive backslashes i.e. \\ * </li> * <li> * If a <i>key</i> is used more than once, the values are appended * as if they were on the same line separated with commas. * </li> * <li> * Blank lines and lines starting with character '#' are skipped. * </li> * <li> * If a property is named "include" (or whatever is defined by * setInclude() and getInclude() and the value of that property is * the full path to a file on disk, that file will be included into * the ConfigurationsRepository. You can also pull in files relative * to the parent configuration file. So if you have something * like the following: * * include = additional.properties * * Then "additional.properties" is expected to be in the same * directory as the parent configuration file. * * Duplicate name values will be replaced, so be careful. * * </li> * </ul> * * <p>Here is an example of a valid extended properties file: * * <p><pre> * # lines starting with # are comments * * # This is the simplest property * key = value * * # A long property may be separated on multiple lines * longvalue = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \ * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa * * # This is a property with many tokens * tokens_on_a_line = first token, second token * * # This sequence generates exactly the same result * tokens_on_multiple_lines = first token * tokens_on_multiple_lines = second token * * # commas may be escaped in tokens * commas.escaped = Hi\, what'up? * </pre> * * <p><b>NOTE</b>: this class has <b>not</b> been written for * performance nor low memory usage. In fact, it's way slower than it * could be and generates too much memory garbage. But since * performance is not an issue during intialization (and there is not * much time to improve it), I wrote it this way. If you don't like * it, go ahead and tune it up! * * @since Commons Collections 1.0 * @version $Revision: 656318 $ $Date: 2008-05-14 11:32:07 -0400 (Wed, 14 May 2008) $ * * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a> * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a> * @author <a href="mailto:daveb@miceda-data">Dave Bryson</a> * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a> * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a> * @author <a href="mailto:leon@opticode.co.za">Leon Messerschmidt</a> * @author <a href="mailto:kjohnson@transparent.com">Kent Johnson</a> * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a> * @author <a href="mailto:ipriha@surfeu.fi">Ilkka Priha</a> * @author Janek Bogucki * @author Mohan Kishore * @author Stephen Colebourne * @author Shinobu Kawai * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> */ public class ExtendedProperties extends Hashtable { /** * Default configurations repository. */ private ExtendedProperties defaults; /** * The file connected to this repository (holding comments and * such). * * @serial */ protected String file; /** * Base path of the configuration file used to create * this ExtendedProperties object. */ protected String basePath; /** * File separator. */ protected String fileSeparator = System.getProperty("file.separator"); /** * Has this configuration been intialized. */ protected boolean isInitialized = false; /** * This is the name of the property that can point to other * properties file for including other properties files. */ private String includePropertyName = null; /** * This is the default name of the property that can point to other * properties file for including other properties files. * * @deprecated Use getInclude() and setInclude() methods which operate * on an instance variable from v3.3. Due to be removed in v4.0. */ protected static String include = "include"; /** * These are the keys in the order they listed * in the configuration file. This is useful when * you wish to perform operations with configuration * information in a particular order. */ protected ArrayList keysAsListed = new ArrayList(); protected final static String START_TOKEN="${"; protected final static String END_TOKEN="}"; /** * Interpolate key names to handle ${key} stuff * * @param base string to interpolate * @return returns the key name with the ${key} substituted */ protected String interpolate(String base) { // COPIED from [configuration] 2003-12-29 return (interpolateHelper(base, null)); } /** * Recursive handler for multiple levels of interpolation. * * When called the first time, priorVariables should be null. * * @param base string with the ${key} variables * @param priorVariables serves two purposes: to allow checking for * loops, and creating a meaningful exception message should a loop * occur. It's 0'th element will be set to the value of base from * the first call. All subsequent interpolated variables are added * afterward. * * @return the string with the interpolation taken care of */ protected String interpolateHelper(String base, List priorVariables) { // COPIED from [configuration] 2003-12-29 if (base == null) { return null; } // on the first call initialize priorVariables // and add base as the first element if (priorVariables == null) { priorVariables = new ArrayList(); priorVariables.add(base); } int begin = -1; int end = -1; int prec = 0 - END_TOKEN.length(); String variable = null; StringBuffer result = new StringBuffer(); // FIXME: we should probably allow the escaping of the start token while (((begin = base.indexOf(START_TOKEN, prec + END_TOKEN.length())) > -1) && ((end = base.indexOf(END_TOKEN, begin)) > -1)) { result.append(base.substring(prec + END_TOKEN.length(), begin)); variable = base.substring(begin + START_TOKEN.length(), end); // if we've got a loop, create a useful exception message and throw if (priorVariables.contains(variable)) { String initialBase = priorVariables.remove(0).toString(); priorVariables.add(variable); StringBuffer priorVariableSb = new StringBuffer(); // create a nice trace of interpolated variables like so: // var1->var2->var3 for (Iterator it = priorVariables.iterator(); it.hasNext();) { priorVariableSb.append(it.next()); if (it.hasNext()) { priorVariableSb.append("->"); } } throw new IllegalStateException( "infinite loop in property interpolation of " + initialBase + ": " + priorVariableSb.toString()); } // otherwise, add this variable to the interpolation list. else { priorVariables.add(variable); } //QUESTION: getProperty or getPropertyDirect Object value = getProperty(variable); if (value != null) { result.append(interpolateHelper(value.toString(), priorVariables)); // pop the interpolated variable off the stack // this maintains priorVariables correctness for // properties with multiple interpolations, e.g. // prop.name=${some.other.prop1}/blahblah/${some.other.prop2} priorVariables.remove(priorVariables.size() - 1); } else if (defaults != null && defaults.getString(variable, null) != null) { result.append(defaults.getString(variable)); } else { //variable not defined - so put it back in the value result.append(START_TOKEN).append(variable).append(END_TOKEN); } prec = end; } result.append(base.substring(prec + END_TOKEN.length(), base.length())); return result.toString(); } /** * Inserts a backslash before every comma and backslash. */ private static String escape(String s) { StringBuffer buf = new StringBuffer(s); for (int i = 0; i < buf.length(); i++) { char c = buf.charAt(i); if (c == ',' || c == '\\') { buf.insert(i, '\\'); i++; } } return buf.toString(); } /** * Removes a backslash from every pair of backslashes. */ private static String unescape(String s) { StringBuffer buf = new StringBuffer(s); for (int i = 0; i < buf.length() - 1; i++) { char c1 = buf.charAt(i); char c2 = buf.charAt(i + 1); if (c1 == '\\' && c2 == '\\') { buf.deleteCharAt(i); } } return buf.toString(); } /** * Counts the number of successive times 'ch' appears in the * 'line' before the position indicated by the 'index'. */ private static int countPreceding(String line, int index, char ch) { int i; for (i = index - 1; i >= 0; i--) { if (line.charAt(i) != ch) { break; } } return index - 1 - i; } /** * Checks if the line ends with odd number of backslashes */ private static boolean endsWithSlash(String line) { if (!line.endsWith("\\")) { return false; } return (countPreceding(line, line.length() - 1, '\\') % 2 == 0); } /** * This class is used to read properties lines. These lines do * not terminate with new-line chars but rather when there is no * backslash sign a the end of the line. This is used to * concatenate multiple lines for readability. */ static class PropertiesReader extends LineNumberReader { /** * Constructor. * * @param reader A Reader. */ public PropertiesReader(Reader reader) { super(reader); } /** * Read a property. * * @return a String property * @throws IOException if there is difficulty reading the source. */ public String readProperty() throws IOException { StringBuffer buffer = new StringBuffer(); String line = readLine(); while (line != null) { line = line.trim(); if ((line.length() != 0) && (line.charAt(0) != '#')) { if (endsWithSlash(line)) { line = line.substring(0, line.length() - 1); buffer.append(line); } else { buffer.append(line); return buffer.toString(); // normal method end } } line = readLine(); } return null; // EOF reached } } /** * This class divides into tokens a property value. Token * separator is "," but commas into the property value are escaped * using the backslash in front. */ static class PropertiesTokenizer extends StringTokenizer { /** * The property delimiter used while parsing (a comma). */ static final String DELIMITER = ","; /** * Constructor. * * @param string A String. */ public PropertiesTokenizer(String string) { super(string, DELIMITER); } /** * Check whether the object has more tokens. * * @return True if the object has more tokens. */ public boolean hasMoreTokens() { return super.hasMoreTokens(); } /** * Get next token. * * @return A String. */ public String nextToken() { StringBuffer buffer = new StringBuffer(); while (hasMoreTokens()) { String token = super.nextToken(); if (endsWithSlash(token)) { buffer.append(token.substring(0, token.length() - 1)); buffer.append(DELIMITER); } else { buffer.append(token); break; } } return buffer.toString().trim(); } } /** * Creates an empty extended properties object. */ public ExtendedProperties() { super(); } /** * Creates and loads the extended properties from the specified file. * * @param file the filename to load * @throws IOException if a file error occurs */ public ExtendedProperties(String file) throws IOException { this(file, null); } /** * Creates and loads the extended properties from the specified file. * * @param file the filename to load * @param defaultFile a second filename to load default values from * @throws IOException if a file error occurs */ public ExtendedProperties(String file, String defaultFile) throws IOException { this.file = file; basePath = new File(file).getAbsolutePath(); basePath = basePath.substring(0, basePath.lastIndexOf(fileSeparator) + 1); FileInputStream in = null; try { in = new FileInputStream(file); this.load(in); } finally { try { if (in != null) { in.close(); } } catch (IOException ex) {} } if (defaultFile != null) { defaults = new ExtendedProperties(defaultFile); } } /** * Indicate to client code whether property * resources have been initialized or not. */ public boolean isInitialized() { return isInitialized; } /** * Gets the property value for including other properties files. * By default it is "include". * <p> * NOTE: Prior to v3.3 this method accessed a static variable. * It now accesses an instance variable. For compatability, if the * instance variable has not been set then the previous static * variable is then accessed. However, the protected static variable * can now only be set by subclasses. * In v4.0, the static variable will be removed. * * @return the property name which includes another property */ public String getInclude() { if (includePropertyName == null) { return include; // backwards compatability } if ("".equals(includePropertyName)) { return null; // hack to allow backwards compatability } return includePropertyName; } /** * Sets the property value for including other properties files. * By default it is "include". * <p> * NOTE: Prior to v3.3 this method set a static variable and affected all * users of the class. It now sets an instance variable. * An empty string is also now converted to null internally. * In v4.0, the static variable will be removed. * * @param inc the property name which includes another property, empty converted to null */ public void setInclude(String inc) { if (inc == null) { inc = ""; // hack to allow backwards compatability } includePropertyName = inc; } /** * Load the properties from the given input stream. * * @param input the InputStream to load from * @throws IOException if an IO error occurs */ public void load(InputStream input) throws IOException { load(input, null); } /** * Load the properties from the given input stream * and using the specified encoding. * * @param input the InputStream to load from * @param enc the encoding to use * @throws IOException if an IO error occurs */ public synchronized void load(InputStream input, String enc) throws IOException { PropertiesReader reader = null; if (enc != null) { try { reader = new PropertiesReader(new InputStreamReader(input, enc)); } catch (UnsupportedEncodingException ex) { // Another try coming up.... } } if (reader == null) { try { reader = new PropertiesReader(new InputStreamReader(input, "8859_1")); } catch (UnsupportedEncodingException ex) { // ISO8859-1 support is required on java platforms but.... // If it's not supported, use the system default encoding reader = new PropertiesReader(new InputStreamReader(input)); } } try { String includeProperty = getInclude(); while (true) { String line = reader.readProperty(); if (line == null) { return; // EOF } int equalSign = line.indexOf('='); if (equalSign > 0) { String key = line.substring(0, equalSign).trim(); String value = line.substring(equalSign + 1).trim(); /* COLLECTIONS-238 allows empty properties to exist by commenting this out // Configure produces lines like this ... just ignore them if ("".equals(value)) { continue; } */ if (includeProperty != null && key.equalsIgnoreCase(includeProperty)) { // Recursively load properties files. File file = null; if (value.startsWith(fileSeparator)) { // We have an absolute path so we'll use this file = new File(value); } else { // We have a relative path, and we have two // possible forms here. If we have the "./" form // then just strip that off first before continuing. if (value.startsWith("." + fileSeparator)) { value = value.substring(2); } file = new File(basePath + value); } if (file != null && file.exists() && file.canRead()) { load(new FileInputStream(file)); } } else { addProperty(key, value); } } } } finally { // Loading is initializing isInitialized = true; } } /** * Gets a property from the configuration. * * @param key property to retrieve * @return value as object. Will return user value if exists, * if not then default value if exists, otherwise null */ public Object getProperty(String key) { // first, try to get from the 'user value' store Object obj = super.get(key); if (obj == null) { // if there isn't a value there, get it from the // defaults if we have them if (defaults != null) { obj = defaults.get(key); } } return obj; } /** * Add a property to the configuration. If it already * exists then the value stated here will be added * to the configuration entry. For example, if * * <code>resource.loader = file</code> * * is already present in the configuration and you * * <code>addProperty("resource.loader", "classpath")</code> * * Then you will end up with a Vector like the * following: * * <code>["file", "classpath"]</code> * * @param key the key to add * @param value the value to add */ public void addProperty(String key, Object value) { if (value instanceof String) { String str = (String) value; if (str.indexOf(PropertiesTokenizer.DELIMITER) > 0) { // token contains commas, so must be split apart then added PropertiesTokenizer tokenizer = new PropertiesTokenizer(str); while (tokenizer.hasMoreTokens()) { String token = tokenizer.nextToken(); addPropertyInternal(key, unescape(token)); } } else { // token contains no commas, so can be simply added addPropertyInternal(key, unescape(str)); } } else { addPropertyInternal(key, value); } // Adding a property connotes initialization isInitialized = true; } /** * Adds a key/value pair to the map. This routine does * no magic morphing. It ensures the keylist is maintained * * @param key the key to store at * @param value the decoded object to store */ private void addPropertyDirect(String key, Object value) { // safety check if (!containsKey(key)) { keysAsListed.add(key); } super.put(key, value); } /** * Adds a decoded property to the map w/o checking for commas - used * internally when a property has been broken up into * strings that could contain escaped commas to prevent * the inadvertent vectorization. * <p> * Thanks to Leon Messerschmidt for this one. * * @param key the key to store at * @param value the decoded object to store */ private void addPropertyInternal(String key, Object value) { Object current = this.get(key); if (current instanceof String) { // one object already in map - convert it to a vector List values = new Vector(2); values.add(current); values.add(value); super.put(key, values); } else if (current instanceof List) { // already a list - just add the new token ((List) current).add(value); } else { // brand new key - store in keysAsListed to retain order if (!containsKey(key)) { keysAsListed.add(key); } super.put(key, value); } } /** * Set a property, this will replace any previously * set values. Set values is implicitly a call * to clearProperty(key), addProperty(key,value). * * @param key the key to set * @param value the value to set */ public void setProperty(String key, Object value) { clearProperty(key); addProperty(key, value); } /** * Save the properties to the given output stream. * <p> * The stream is not closed, but it is flushed. * * @param output an OutputStream, may be null * @param header a textual comment to act as a file header * @throws IOException if an IO error occurs */ public synchronized void save(OutputStream output, String header) throws IOException { if (output == null) { return; } PrintWriter theWrtr = new PrintWriter(output); if (header != null) { theWrtr.println(header); } Enumeration theKeys = keys(); while (theKeys.hasMoreElements()) { String key = (String) theKeys.nextElement(); Object value = get(key); if (value != null) { if (value instanceof String) { StringBuffer currentOutput = new StringBuffer(); currentOutput.append(key); currentOutput.append("="); currentOutput.append(escape((String) value)); theWrtr.println(currentOutput.toString()); } else if (value instanceof List) { List values = (List) value; for (Iterator it = values.iterator(); it.hasNext(); ) { String currentElement = (String) it.next(); StringBuffer currentOutput = new StringBuffer(); currentOutput.append(key); currentOutput.append("="); currentOutput.append(escape(currentElement)); theWrtr.println(currentOutput.toString()); } } } theWrtr.println(); theWrtr.flush(); } } /** * Combines an existing Hashtable with this Hashtable. * <p> * Warning: It will overwrite previous entries without warning. * * @param props the properties to combine */ public void combine(ExtendedProperties props) { for (Iterator it = props.getKeys(); it.hasNext();) { String key = (String) it.next(); super.put(key, props.get(key)); } } /** * Clear a property in the configuration. * * @param key the property key to remove along with corresponding value */ public void clearProperty(String key) { if (containsKey(key)) { // we also need to rebuild the keysAsListed or else // things get *very* confusing for (int i = 0; i < keysAsListed.size(); i++) { if (( keysAsListed.get(i)).equals(key)) { keysAsListed.remove(i); break; } } super.remove(key); } } /** * Get the list of the keys contained in the configuration * repository. * * @return an Iterator over the keys */ public Iterator getKeys() { return keysAsListed.iterator(); } /** * Get the list of the keys contained in the configuration * repository that match the specified prefix. * * @param prefix the prefix to match * @return an Iterator of keys that match the prefix */ public Iterator getKeys(String prefix) { Iterator keys = getKeys(); ArrayList matchingKeys = new ArrayList(); while (keys.hasNext()) { Object key = keys.next(); if (key instanceof String && ((String) key).startsWith(prefix)) { matchingKeys.add(key); } } return matchingKeys.iterator(); } /** * Create an ExtendedProperties object that is a subset * of this one. Take into account duplicate keys * by using the setProperty() in ExtendedProperties. * * @param prefix the prefix to get a subset for * @return a new independent ExtendedProperties */ public ExtendedProperties subset(String prefix) { ExtendedProperties c = new ExtendedProperties(); Iterator keys = getKeys(); boolean validSubset = false; while (keys.hasNext()) { Object key = keys.next(); if (key instanceof String && ((String) key).startsWith(prefix)) { if (!validSubset) { validSubset = true; } /* * Check to make sure that c.subset(prefix) doesn't * blow up when there is only a single property * with the key prefix. This is not a useful * subset but it is a valid subset. */ String newKey = null; if (((String) key).length() == prefix.length()) { newKey = prefix; } else { newKey = ((String) key).substring(prefix.length() + 1); } /* * use addPropertyDirect() - this will plug the data as * is into the Map, but will also do the right thing * re key accounting */ c.addPropertyDirect(newKey, get(key)); } } if (validSubset) { return c; } else { return null; } } /** * Display the configuration for debugging purposes to System.out. */ public void display() { Iterator i = getKeys(); while (i.hasNext()) { String key = (String) i.next(); Object value = get(key); System.out.println(key + " => " + value); } } /** * Get a string associated with the given configuration key. * * @param key The configuration key. * @return The associated string. * @throws ClassCastException is thrown if the key maps to an * object that is not a String. */ public String getString(String key) { return getString(key, null); } /** * Get a string associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated string if key is found, * default value otherwise. * @throws ClassCastException is thrown if the key maps to an * object that is not a String. */ public String getString(String key, String defaultValue) { Object value = get(key); if (value instanceof String) { return interpolate((String) value); } else if (value == null) { if (defaults != null) { return interpolate(defaults.getString(key, defaultValue)); } else { return interpolate(defaultValue); } } else if (value instanceof List) { return interpolate((String) ((List) value).get(0)); } else { throw new ClassCastException('\'' + key + "' doesn't map to a String object"); } } /** * Get a list of properties associated with the given * configuration key. * * @param key The configuration key. * @return The associated properties if key is found. * @throws ClassCastException is thrown if the key maps to an * object that is not a String/List. * @throws IllegalArgumentException if one of the tokens is * malformed (does not contain an equals sign). */ public Properties getProperties(String key) { return getProperties(key, new Properties()); } /** * Get a list of properties associated with the given * configuration key. * * @param key The configuration key. * @return The associated properties if key is found. * @throws ClassCastException is thrown if the key maps to an * object that is not a String/List. * @throws IllegalArgumentException if one of the tokens is * malformed (does not contain an equals sign). */ public Properties getProperties(String key, Properties defaults) { /* * Grab an array of the tokens for this key. */ String[] tokens = getStringArray(key); // Each token is of the form 'key=value'. Properties props = new Properties(defaults); for (int i = 0; i < tokens.length; i++) { String token = tokens[i]; int equalSign = token.indexOf('='); if (equalSign > 0) { String pkey = token.substring(0, equalSign).trim(); String pvalue = token.substring(equalSign + 1).trim(); props.put(pkey, pvalue); } else { throw new IllegalArgumentException('\'' + token + "' does not contain " + "an equals sign"); } } return props; } /** * Get an array of strings associated with the given configuration * key. * * @param key The configuration key. * @return The associated string array if key is found. * @throws ClassCastException is thrown if the key maps to an * object that is not a String/List. */ public String[] getStringArray(String key) { Object value = get(key); List values; if (value instanceof String) { values = new Vector(1); values.add(value); } else if (value instanceof List) { values = (List) value; } else if (value == null) { if (defaults != null) { return defaults.getStringArray(key); } else { return new String[0]; } } else { throw new ClassCastException('\'' + key + "' doesn't map to a String/List object"); } String[] tokens = new String[values.size()]; for (int i = 0; i < tokens.length; i++) { tokens[i] = (String) values.get(i); } return tokens; } /** * Get a Vector of strings associated with the given configuration * key. * * @param key The configuration key. * @return The associated Vector. * @throws ClassCastException is thrown if the key maps to an * object that is not a Vector. */ public Vector getVector(String key) { return getVector(key, null); } /** * Get a Vector of strings associated with the given configuration key. * <p> * The list is a copy of the internal data of this object, and as * such you may alter it freely. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated Vector. * @throws ClassCastException is thrown if the key maps to an * object that is not a Vector. */ public Vector getVector(String key, Vector defaultValue) { Object value = get(key); if (value instanceof List) { return new Vector((List) value); } else if (value instanceof String) { Vector values = new Vector(1); values.add(value); super.put(key, values); return values; } else if (value == null) { if (defaults != null) { return defaults.getVector(key, defaultValue); } else { return ((defaultValue == null) ? new Vector() : defaultValue); } } else { throw new ClassCastException('\'' + key + "' doesn't map to a Vector object"); } } /** * Get a List of strings associated with the given configuration key. * <p> * The list is a copy of the internal data of this object, and as * such you may alter it freely. * * @param key The configuration key. * @return The associated List object. * @throws ClassCastException is thrown if the key maps to an * object that is not a List. * @since Commons Collections 3.2 */ public List getList(String key) { return getList(key, null); } /** * Get a List of strings associated with the given configuration key. * <p> * The list is a copy of the internal data of this object, and as * such you may alter it freely. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated List. * @throws ClassCastException is thrown if the key maps to an * object that is not a List. * @since Commons Collections 3.2 */ public List getList(String key, List defaultValue) { Object value = get(key); if (value instanceof List) { return new ArrayList((List) value); } else if (value instanceof String) { List values = new ArrayList(1); values.add(value); super.put(key, values); return values; } else if (value == null) { if (defaults != null) { return defaults.getList(key, defaultValue); } else { return ((defaultValue == null) ? new ArrayList() : defaultValue); } } else { throw new ClassCastException('\'' + key + "' doesn't map to a List object"); } } /** * Get a boolean associated with the given configuration key. * * @param key The configuration key. * @return The associated boolean. * @throws NoSuchElementException is thrown if the key doesn't * map to an existing object. * @throws ClassCastException is thrown if the key maps to an * object that is not a Boolean. */ public boolean getBoolean(String key) { Boolean b = getBoolean(key, null); if (b != null) { return b.booleanValue(); } else { throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object"); } } /** * Get a boolean associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated boolean. * @throws ClassCastException is thrown if the key maps to an * object that is not a Boolean. */ public boolean getBoolean(String key, boolean defaultValue) { return getBoolean(key, new Boolean(defaultValue)).booleanValue(); } /** * Get a boolean associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated boolean if key is found and has valid * format, default value otherwise. * @throws ClassCastException is thrown if the key maps to an * object that is not a Boolean. */ public Boolean getBoolean(String key, Boolean defaultValue) { Object value = get(key); if (value instanceof Boolean) { return (Boolean) value; } else if (value instanceof String) { String s = testBoolean((String) value); Boolean b = new Boolean(s); super.put(key, b); return b; } else if (value == null) { if (defaults != null) { return defaults.getBoolean(key, defaultValue); } else { return defaultValue; } } else { throw new ClassCastException('\'' + key + "' doesn't map to a Boolean object"); } } /** * Test whether the string represent by value maps to a boolean * value or not. We will allow <code>true</code>, <code>on</code>, * and <code>yes</code> for a <code>true</code> boolean value, and * <code>false</code>, <code>off</code>, and <code>no</code> for * <code>false</code> boolean values. Case of value to test for * boolean status is ignored. * * @param value the value to test for boolean state * @return <code>true</code> or <code>false</code> if the supplied * text maps to a boolean value, or <code>null</code> otherwise. */ public String testBoolean(String value) { String s = value.toLowerCase(Locale.ENGLISH); if (s.equals("true") || s.equals("on") || s.equals("yes")) { return "true"; } else if (s.equals("false") || s.equals("off") || s.equals("no")) { return "false"; } else { return null; } } /** * Get a byte associated with the given configuration key. * * @param key The configuration key. * @return The associated byte. * @throws NoSuchElementException is thrown if the key doesn't * map to an existing object. * @throws ClassCastException is thrown if the key maps to an * object that is not a Byte. * @throws NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public byte getByte(String key) { Byte b = getByte(key, null); if (b != null) { return b.byteValue(); } else { throw new NoSuchElementException('\'' + key + " doesn't map to an existing object"); } } /** * Get a byte associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated byte. * @throws ClassCastException is thrown if the key maps to an * object that is not a Byte. * @throws NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public byte getByte(String key, byte defaultValue) { return getByte(key, new Byte(defaultValue)).byteValue(); } /** * Get a byte associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated byte if key is found and has valid * format, default value otherwise. * @throws ClassCastException is thrown if the key maps to an * object that is not a Byte. * @throws NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public Byte getByte(String key, Byte defaultValue) { Object value = get(key); if (value instanceof Byte) { return (Byte) value; } else if (value instanceof String) { Byte b = new Byte((String) value); super.put(key, b); return b; } else if (value == null) { if (defaults != null) { return defaults.getByte(key, defaultValue); } else { return defaultValue; } } else { throw new ClassCastException('\'' + key + "' doesn't map to a Byte object"); } } /** * Get a short associated with the given configuration key. * * @param key The configuration key. * @return The associated short. * @throws NoSuchElementException is thrown if the key doesn't * map to an existing object. * @throws ClassCastException is thrown if the key maps to an * object that is not a Short. * @throws NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public short getShort(String key) { Short s = getShort(key, null); if (s != null) { return s.shortValue(); } else { throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object"); } } /** * Get a short associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated short. * @throws ClassCastException is thrown if the key maps to an * object that is not a Short. * @throws NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public short getShort(String key, short defaultValue) { return getShort(key, new Short(defaultValue)).shortValue(); } /** * Get a short associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated short if key is found and has valid * format, default value otherwise. * @throws ClassCastException is thrown if the key maps to an * object that is not a Short. * @throws NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public Short getShort(String key, Short defaultValue) { Object value = get(key); if (value instanceof Short) { return (Short) value; } else if (value instanceof String) { Short s = new Short((String) value); super.put(key, s); return s; } else if (value == null) { if (defaults != null) { return defaults.getShort(key, defaultValue); } else { return defaultValue; } } else { throw new ClassCastException('\'' + key + "' doesn't map to a Short object"); } } /** * The purpose of this method is to get the configuration resource * with the given name as an integer. * * @param name The resource name. * @return The value of the resource as an integer. */ public int getInt(String name) { return getInteger(name); } /** * The purpose of this method is to get the configuration resource * with the given name as an integer, or a default value. * * @param name The resource name * @param def The default value of the resource. * @return The value of the resource as an integer. */ public int getInt(String name, int def) { return getInteger(name, def); } /** * Get a int associated with the given configuration key. * * @param key The configuration key. * @return The associated int. * @throws NoSuchElementException is thrown if the key doesn't * map to an existing object. * @throws ClassCastException is thrown if the key maps to an * object that is not a Integer. * @throws NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public int getInteger(String key) { Integer i = getInteger(key, null); if (i != null) { return i.intValue(); } else { throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object"); } } /** * Get a int associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated int. * @throws ClassCastException is thrown if the key maps to an * object that is not a Integer. * @throws NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public int getInteger(String key, int defaultValue) { Integer i = getInteger(key, null); if (i == null) { return defaultValue; } return i.intValue(); } /** * Get a int associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated int if key is found and has valid * format, default value otherwise. * @throws ClassCastException is thrown if the key maps to an * object that is not a Integer. * @throws NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public Integer getInteger(String key, Integer defaultValue) { Object value = get(key); if (value instanceof Integer) { return (Integer) value; } else if (value instanceof String) { Integer i = new Integer((String) value); super.put(key, i); return i; } else if (value == null) { if (defaults != null) { return defaults.getInteger(key, defaultValue); } else { return defaultValue; } } else { throw new ClassCastException('\'' + key + "' doesn't map to a Integer object"); } } /** * Get a long associated with the given configuration key. * * @param key The configuration key. * @return The associated long. * @throws NoSuchElementException is thrown if the key doesn't * map to an existing object. * @throws ClassCastException is thrown if the key maps to an * object that is not a Long. * @throws NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public long getLong(String key) { Long l = getLong(key, null); if (l != null) { return l.longValue(); } else { throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object"); } } /** * Get a long associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated long. * @throws ClassCastException is thrown if the key maps to an * object that is not a Long. * @throws NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public long getLong(String key, long defaultValue) { return getLong(key, new Long(defaultValue)).longValue(); } /** * Get a long associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated long if key is found and has valid * format, default value otherwise. * @throws ClassCastException is thrown if the key maps to an * object that is not a Long. * @throws NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public Long getLong(String key, Long defaultValue) { Object value = get(key); if (value instanceof Long) { return (Long) value; } else if (value instanceof String) { Long l = new Long((String) value); super.put(key, l); return l; } else if (value == null) { if (defaults != null) { return defaults.getLong(key, defaultValue); } else { return defaultValue; } } else { throw new ClassCastException('\'' + key + "' doesn't map to a Long object"); } } /** * Get a float associated with the given configuration key. * * @param key The configuration key. * @return The associated float. * @throws NoSuchElementException is thrown if the key doesn't * map to an existing object. * @throws ClassCastException is thrown if the key maps to an * object that is not a Float. * @throws NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public float getFloat(String key) { Float f = getFloat(key, null); if (f != null) { return f.floatValue(); } else { throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object"); } } /** * Get a float associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated float. * @throws ClassCastException is thrown if the key maps to an * object that is not a Float. * @throws NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public float getFloat(String key, float defaultValue) { return getFloat(key, new Float(defaultValue)).floatValue(); } /** * Get a float associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated float if key is found and has valid * format, default value otherwise. * @throws ClassCastException is thrown if the key maps to an * object that is not a Float. * @throws NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public Float getFloat(String key, Float defaultValue) { Object value = get(key); if (value instanceof Float) { return (Float) value; } else if (value instanceof String) { Float f = new Float((String) value); super.put(key, f); return f; } else if (value == null) { if (defaults != null) { return defaults.getFloat(key, defaultValue); } else { return defaultValue; } } else { throw new ClassCastException('\'' + key + "' doesn't map to a Float object"); } } /** * Get a double associated with the given configuration key. * * @param key The configuration key. * @return The associated double. * @throws NoSuchElementException is thrown if the key doesn't * map to an existing object. * @throws ClassCastException is thrown if the key maps to an * object that is not a Double. * @throws NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public double getDouble(String key) { Double d = getDouble(key, null); if (d != null) { return d.doubleValue(); } else { throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object"); } } /** * Get a double associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated double. * @throws ClassCastException is thrown if the key maps to an * object that is not a Double. * @throws NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public double getDouble(String key, double defaultValue) { return getDouble(key, new Double(defaultValue)).doubleValue(); } /** * Get a double associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated double if key is found and has valid * format, default value otherwise. * @throws ClassCastException is thrown if the key maps to an * object that is not a Double. * @throws NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public Double getDouble(String key, Double defaultValue) { Object value = get(key); if (value instanceof Double) { return (Double) value; } else if (value instanceof String) { Double d = new Double((String) value); super.put(key, d); return d; } else if (value == null) { if (defaults != null) { return defaults.getDouble(key, defaultValue); } else { return defaultValue; } } else { throw new ClassCastException('\'' + key + "' doesn't map to a Double object"); } } /** * Convert a standard properties class into a configuration class. * <p> * NOTE: From Commons Collections 3.2 this method will pick up * any default parent Properties of the specified input object. * * @param props the properties object to convert * @return new ExtendedProperties created from props */ public static ExtendedProperties convertProperties(Properties props) { ExtendedProperties c = new ExtendedProperties(); for (Enumeration e = props.propertyNames(); e.hasMoreElements();) { String s = (String) e.nextElement(); c.setProperty(s, props.getProperty(s)); } return c; } /** * Add a new property specified by the key to the * ExtendedProperties. * * @param key specifying the property * @param value for the property * @return old value of the property */ public Object put(Object key, Object value) { String strKey = String.valueOf(key); Object ret = getProperty(strKey); addProperty(strKey, value); return ret; } /** * Add a map full of key/value pairs to the ExtendedProperties. * If the added map is an ExtendedProperties class, then the * order of the added properties is maintained. * * @param map full of key/value pair data */ public void putAll(Map map) { if (map instanceof ExtendedProperties) { for (Iterator it = ((ExtendedProperties) map).getKeys(); it.hasNext(); ) { Object key = it.next(); put(key, map.get(key)); } } else { for (Iterator it = map.entrySet().iterator(); it.hasNext(); ) { Map.Entry entry = (Map.Entry) it.next(); put(entry.getKey(), entry.getValue()); } } } /** * Remove the property specified by the key from the * ExtendedProperties. * * @param key specifying the property * @return old value of the property */ public Object remove(Object key) { String strKey = String.valueOf(key); Object ret = getProperty(strKey); clearProperty(strKey); return ret; } }

The table below shows all metrics for ExtendedProperties.java.

MetricValueDescription
BLOCKS244.00Number of blocks
BLOCK_COMMENT36.00Number of block comment lines
COMMENTS838.00Comment lines
COMMENT_DENSITY 1.39Comment density
COMPARISONS121.00Number of comparison operators
CYCLOMATIC208.00Cyclomatic complexity
DECL_COMMENTS81.00Comments in declarations
DOC_COMMENT765.00Number of javadoc comment lines
ELOC601.00Effective lines of code
EXEC_COMMENTS31.00Comments in executable code
EXITS104.00Procedure exits
FUNCTIONS68.00Number of function declarations
HALSTEAD_DIFFICULTY120.05Halstead difficulty
HALSTEAD_EFFORT 0.00Halstead effort
INTERFACE_COMPLEXITY227.00Interface complexity
JAVA0001 0.00JAVA0001 Package name does not contain only lower case letters
JAVA0002 0.00JAVA0002 Package name does not begin with a top level domain name or country code
JAVA0003 0.00JAVA0003 Minimize use of on-demand (.*) imports
JAVA0004 0.00JAVA0004 Unnecessary import from java.lang
JAVA0005 0.00JAVA0005 Imports not in specified order
JAVA0006 0.00JAVA0006 Empty finally block
JAVA0007 0.00JAVA0007 Should not declare public field
JAVA0008 1.00JAVA0008 Empty catch block
JAVA0009 0.00JAVA0009 Protected member in final class
JAVA0010 0.00JAVA0010 Non-instantiable class does not contain a non-private static member
JAVA0011 0.00JAVA0011 Abstract class does not contain an abstract method
JAVA0012 0.00JAVA0012 Non-constructor method with same name as declaring class
JAVA0013 0.00JAVA0013 Non-blank final field is not static
JAVA0014 0.00JAVA0014 Class with only static members has non-private constructor
JAVA0015 0.00JAVA0015 Package class contains public nested type
JAVA0016 0.00JAVA0016 Abstract class contains public constructor
JAVA0017 0.00JAVA0017 Class name does not have required form
JAVA0018 0.00JAVA0018 Method name does not have required form
JAVA0019 0.00JAVA0019 Interface name does not have required form
JAVA0020 0.00JAVA0020 Field name does not have required form
JAVA0021 0.00JAVA0021 Interface method name does not have required form
JAVA0022 0.00JAVA0022 Static final field name does not have required form
JAVA0023 0.00JAVA0023 Empty finalize method
JAVA0024 0.00JAVA0024 Empty class
JAVA0025 0.00JAVA0025 Method override is empty
JAVA0026 0.00JAVA0026 Finalize method with parameters
JAVA0029 0.00JAVA0029 Private method not used
JAVA0030 0.00JAVA0030 Private field not used
JAVA0031 0.00JAVA0031 Case statement not properly closed
JAVA0032 0.00JAVA0032 Switch statement missing default
JAVA0033 0.00JAVA0033 default: not last case in switch statement
JAVA0034 0.00JAVA0034 Missing braces in if statement
JAVA0035 0.00JAVA0035 Missing braces in for statement
JAVA0036 0.00JAVA0036 Missing braces in while statement
JAVA0038 0.00JAVA0038 Non-case label in switch statement
JAVA0039 0.00JAVA0039 Break statement with label
JAVA0040 0.00JAVA0040 Switch statement contains N cases (maximum: M)
JAVA0041 0.00JAVA0041 Nested synchronized block
JAVA0042 0.00JAVA0042 Empty synchronized statement
JAVA0043 0.00JAVA0043 Inner class does not use outer class
JAVA0044 0.00JAVA0044 Serializable class with no instance variables
JAVA0045 0.00JAVA0045 Serializable class with only transient fields
JAVA0046 0.00JAVA0046 Name of class not derived from Exception ends with 'Exception'
JAVA0047 0.00JAVA0047 Serializable class derives from invalid base class
JAVA0048 0.00JAVA0048 Name of class derived from Exception does not end with 'Exception'
JAVA0049 3.00JAVA0049 Nested block at depth N (maximum: M)
JAVA0050 0.00JAVA0050 Class derives from java.lang.Error
JAVA0051 0.00JAVA0051 Class derives from java.lang.RuntimeException
JAVA0052 0.00JAVA0052 Class derives from java.lang.Throwable
JAVA0053 0.00JAVA0053 Unused label
JAVA0054 0.00JAVA0054 Inheritance depth N exceeds maximum M
JAVA0055 0.00JAVA0055 Class should be interface
JAVA0056 0.00JAVA0056 Unnecessary abstract modifier for interface or annotation
JAVA0057 0.00JAVA0057 Unnecessary default constructor
JAVA0058 1.00JAVA0058 Constructor calls super()
JAVA0059 1.00JAVA0059 Method override only calls super()
JAVA0061 0.00JAVA0061 Inaccessible member in anonymous class
JAVA0062 0.00JAVA0062 Public class missing public member or protected constructor
JAVA0063 0.00JAVA0063 Identifier name should not contain '$'
JAVA0064 0.00JAVA0064 N variations of identifier name (maximum: M)
JAVA0065 0.00JAVA0065 Unnecessary final modifier for method in final class
JAVA0066 0.00JAVA0066 Unnecessary modifier for interface nested type
JAVA0067 0.00JAVA0067 Array descriptor on identifier name
JAVA0068 2.00JAVA0068 Modifiers not declared in recommended order
JAVA0071 0.00JAVA0071 Strings compared with ==
JAVA0073 0.00JAVA0073 Integer division in floating-point context
JAVA0074 0.00JAVA0074 Use of Object.notify()
JAVA0075 1.00JAVA0075 Method parameter hides field
JAVA0076 0.00JAVA0076 Use of magic number
JAVA0077 0.00JAVA0077 Private field not used in declaring class
JAVA0078 0.00JAVA0078 Floating point values compared with ==
JAVA0079 0.00JAVA0079 Use of instance to reference static member
JAVA0080 0.00JAVA0080 Import declaration not used
JAVA0081 0.00JAVA0081 Boolean literal in comparison
JAVA0082 0.00JAVA0082 Unnecessary widening cast
JAVA0083 0.00JAVA0083 Unnecessary instanceof test
JAVA0084 0.00JAVA0084 Should use compound assignment operator
JAVA0085 0.00JAVA0085 Use of sun.* class
JAVA0087 0.00JAVA0087 Use of Thread.sleep()
JAVA0089 0.00JAVA0089 Use of restricted package
JAVA0092 0.00JAVA0092 Use of restricted type
JAVA0093 0.00JAVA0093 Redundant assignment
JAVA0094 0.00JAVA0094 Field hides a superclass field
JAVA0095 0.00JAVA0095 Uninitialized private field
JAVA0096 0.00JAVA0096 Field in nested class hides outer field
JAVA0098 0.00JAVA0098 Minimize use of implicit field initializers
JAVA0100 0.00JAVA0100 Class contains N non-final fields (maximum: M)
JAVA0101 0.00JAVA0101 Unnecessary modifier for field in interface
JAVA0102 0.00JAVA0102 Last statement in finalize() not super.finalize()
JAVA0103 0.00JAVA0103 Explicit call to finalize()
JAVA0104 0.00JAVA0104 finalize() only calls super.finalize()
JAVA0105 0.00JAVA0105 Duplicate import declaration
JAVA0106 0.00JAVA0106 Unnecessary import from current package
JAVA0108 7.00JAVA0108 Incorrect javadoc: no @param tag for 'parameter'
JAVA0109 0.00JAVA0109 Incorrect javadoc: no parameter 'parameter'
JAVA0110 5.00JAVA0110 Incorrect javadoc: no @return tag
JAVA0111 0.00JAVA0111 Incorrect javadoc: @return tag for void method
JAVA0112 0.00JAVA0112 Incorrect javadoc: no exception 'exception' in throws
JAVA0113 0.00JAVA0113 Incorrect javadoc: no @author tag
JAVA0114 0.00JAVA0114 Incorrect javadoc: no @version tag
JAVA0115 0.00JAVA0115 Incorrect javadoc: no @throws or @exception tag for 'exception'
JAVA0116 0.00JAVA0116 Missing javadoc: field 'field'
JAVA0117 0.00JAVA0117 Missing javadoc: method 'method'
JAVA0118 0.00JAVA0118 Missing javadoc: type 'type'
JAVA0119 1.00JAVA0119 Control variable changed within body of for loop
JAVA0123 1.00JAVA0123 Use all three components of for loop
JAVA0125 0.00JAVA0125 Continue statement with label
JAVA0126 0.00JAVA0126 Method declares unchecked exception in throws
JAVA0128 2.00JAVA0128 Public constructor in non-public class
JAVA0130 0.00JAVA0130 Non-static method does not use instance fields
JAVA0131 0.00JAVA0131 Compatible method does not override base
JAVA013214.00JAVA0132 Method overload with compatible signature
JAVA0133 3.00JAVA0133 Non-synchronized method overrides synchronized method
JAVA0135 0.00JAVA0135 Only one of Object.equals and Object.hashCode defined: missing 'method'
JAVA0136 1.00JAVA0136 N methods defined in class (maximum: M)
JAVA0137 0.00JAVA0137 Non-abstract class missing constructor
JAVA0138 0.00JAVA0138 N parameters defined for method (maximum: M)
JAVA0139 0.00JAVA0139 Definition of main other than public static void main(java.lang.String[])
JAVA0141 0.00JAVA0141 Unnecessary modifier for method in interface
JAVA0143 2.00JAVA0143 Synchronized method
JAVA0144 0.00JAVA0144 Line exceeds maximum M characters
JAVA0145 0.00JAVA0145 Tab character used in source file
JAVA0150 0.00JAVA0150 java.lang.Error (or subclass) thrown
JAVA0153 0.00JAVA0153 Inefficient conversion of integer to string
JAVA0159 0.00JAVA0159 Inefficient conversion of string to integer
JAVA0160 1.00JAVA0160 Method does not throw specified exception
JAVA0161 0.00JAVA0161 Conditional wait() not in loop
JAVA0163 0.00JAVA0163 Empty statement
JAVA0165 0.00JAVA0165 Conflicting return statement in finally block
JAVA0166 0.00JAVA0166 Generic exception caught
JAVA0167 0.00JAVA0167 ThreadDeath not rethrown
JAVA0169 0.00JAVA0169 Unnecessary catch block: exception 'exception'
JAVA0170 0.00JAVA0170 Caught exception not derived from java.lang.Exception
JAVA0171 0.00JAVA0171 Unused local variable
JAVA0173 0.00JAVA0173 Unused method parameter
JAVA0174 0.00JAVA0174 Assigned local variable never used
JAVA0175 0.00JAVA0175 Successive assignment to variable
JAVA0176 0.00JAVA0176 Local variable name does not have required form
JAVA0177 2.00JAVA0177 Variable declaration missing initializer
JAVA0179 1.00JAVA0179 Local variable hides visible field
JAVA0233 0.00JAVA0233 Definition of serialVersionUID other than 'private static final long serialVersionUID'
JAVA0234 1.00JAVA0234 Class is Serializable but does not define serialVersionUID
JAVA0235 0.00JAVA0235 Class defines serialVersionUID but does not implement Serializable
JAVA0236 0.00JAVA0236 Attempt to clone an object which does not implement Cloneable
JAVA0237 0.00JAVA0237 Class implements Cloneable but does not have public clone method
JAVA0238 0.00JAVA0238 Clone method does not call super.clone()
JAVA0239 0.00JAVA0239 Class declares 'readObject' or 'writeObject' but does not implement Serializable
JAVA0240 0.00JAVA0240 Serializable class which declares readObject or writeObject but not both
JAVA0241 0.00JAVA0241 'readObject' or 'writeObject' should be declared private in Serializable class
JAVA0242 0.00JAVA0242 Transient field in non-Serializable class
JAVA0243 0.00JAVA0243 'readResolve' or 'writeReplace' should be declared private or protected
JAVA0244 0.00JAVA0244 Field or method name in subclass differs only by case from inherited field or method
JAVA0245 0.00JAVA0245 JUnit TestCase with non-trivial constructor
JAVA0246 0.00JAVA0246 JUnit assertXXX statement missing message parameter
JAVA0247 0.00JAVA0247 JUnit 'setUp()' and 'tearDown()' should call super method
JAVA0248 0.00JAVA0248 JUnit method 'setUp' or 'tearDown' with incorrect signature
JAVA0249 0.00JAVA0249 JUnit TestCase 'suite()' should be declared static
JAVA0250 0.00JAVA0250 JUnit TestCase declares testXXX method with incorrect signature
JAVA0251 0.00JAVA0251 Use '%n' for line breaks in printf/format for platform independence
JAVA0252 0.00JAVA0252 'enum' is a Java 1.5 reserved word
JAVA0253 0.00JAVA0253 Not all enum constants consumed in switch statement
JAVA0254 7.00JAVA0254 Use enhanced for loop construct instead of Iterator
JAVA0255 0.00JAVA0255 Result of method invocation not used
JAVA0256 0.00JAVA0256 Assignment of external collection/array to field
JAVA0257 0.00JAVA0257 Use of 'Constant Interface' anti-pattern
JAVA0258 1.00JAVA0258 Implement Iterable for foreach compatibility
JAVA0259 0.00JAVA0259 Return of collection/array field
JAVA0260 0.00JAVA0260 Use 'enum' instead of Enumerated Type pattern
JAVA0261 0.00JAVA0261 Use specialized Enum collection types
JAVA0262 0.00JAVA0262 Use of char in integer context
JAVA0263 0.00JAVA0263 Long literal ends with 'l' instead of 'L'
JAVA0264 0.00JAVA0264 Integer math in long context - check for overflow
JAVA0265 0.00JAVA0265 Use of Throwable.printStackTrace()
JAVA0266 1.00JAVA0266 Use of System.out
JAVA0267 0.00JAVA0267 Use of System.err
JAVA0269 0.00JAVA0269 Contents of StringBuffer never used
JAVA0270 1.00JAVA0270 Use Java 5.0 enhanced for loop construct to iterate over all elements in an array
JAVA0271 0.00JAVA0271 Minimize use of on-demand (.*) static imports
JAVA0272 0.00JAVA0272 Thread.run() called
JAVA0273 0.00JAVA0273 Non-final derivative of Thread calls start() in constructor
JAVA0274 0.00JAVA0274 Serializable class has a synchronized readObject()
JAVA0275 0.00JAVA0275 Serializable class has a synchronized w