diff --git a/build.xml b/build.xml index c7f5cd3..1fa6ec7 100644 --- a/build.xml +++ b/build.xml @@ -108,7 +108,6 @@ - @@ -571,20 +570,6 @@ limitations under the License.-->'> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Preparing build directory... - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/optional/project.xml b/optional/project.xml deleted file mode 100644 index 98067cc..0000000 --- a/optional/project.xml +++ /dev/null @@ -1,169 +0,0 @@ - - - - 3 - - Logging - commons-logging-optional - 1.1-SNAPSHOT - 2001 - Commons Logging (Optional Implementations) - - Commons Logging is a thin adapter allowing configurable bridging to other, - well known logging systems. This package contains non-core implementations. - - /images/logo.png - - http://jakarta.apache.org/commons/logging/optional - org.apache.commons.logging - - - The Apache Software Foundation - http://jakarta.apache.org - http://jakarta.apache.org/images/original-jakarta-logo.gif - - - - - The Apache Software License, Version 2.0 - /LICENSE.txt - repo - - - - jakarta - http://issues.apache.org/bugzilla/ - jakarta.apache.org - /www/jakarta.apache.org/commons/logging/optional - /www/jakarta.apache.org/builds/jakarta-commons/logging/optional/ - - - scm:svn:http://svn.apache.org/repos/asf/jakarta/commons/proper/logging/trunk - http://svn.apache.org/repos/asf/jakarta/commons/proper/logging/trunk - - - - - Commons Dev List - commons-dev-subscribe@jakarta.apache.org - commons-dev-unsubscribe@jakarta.apache.org - http://mail-archives.apache.org/eyebrowse/SummarizeList?listName=commons-dev@jakarta.apache.org - - - Commons User List - commons-user-subscribe@jakarta.apache.org - commons-user-unsubscribe@jakarta.apache.org - http://mail-archives.apache.org/eyebrowse/SummarizeList?listName=commons-user@jakarta.apache.org - - - - - - Morgan Delagrange - morgand - morgand at apache dot org - Apache - Java Developer - - - Rodney Waldhoff - rwaldhoff - rwaldhoff at apache org - Apache Software Foundation - - - Craig McClanahan - craigmcc - craigmcc at apache org - Apache Software Foundation - - - Scott Sanders - sanders - sanders at apache dot org - Apache Software Foundation - - - Robert Burrell Donkin - rdonkin - rdonkin at apache dot org - Apache Software Foundation - - - Peter Donald - donaldp - donaldp at apache dot org - - - - Costin Manolache - costin - costin at apache dot org - Apache Software Foundation - - - Richard Sitze - rsitze - rsitze at apache dot org - Apache Software Foundation - - - Juozas Baliuka - baliuka - baliuka@apache.org - - - Java Developer - - - - - - - - junit - 3.8.1 - - - - commons-logging - 1.0.4 - http://jakarta.apache.org/commons/logging.html - - - - log4j - 1.1.3 - - - - - - commons-dev@jakarta.apache.org - src/java - src/test - - - - maven-javadoc-plugin - maven-jdepend-plugin - maven-jxr-plugin - - - diff --git a/optional/src/conf/MANIFEST.MF b/optional/src/conf/MANIFEST.MF deleted file mode 100644 index 1c3129d..0000000 --- a/optional/src/conf/MANIFEST.MF +++ /dev/null @@ -1,5 +0,0 @@ -Extension-Name: org.apache.commons.logging-optional -Specification-Vendor: Apache Software Foundation -Specification-Version: 1.0 -Implementation-Vendor: Apache Software Foundation -Implementation-Version: 1.0.5 diff --git a/optional/src/java/org/apache/commons/logging/impl/Log4JCategoryLog.java b/optional/src/java/org/apache/commons/logging/impl/Log4JCategoryLog.java deleted file mode 100644 index 739d1c6..0000000 --- a/optional/src/java/org/apache/commons/logging/impl/Log4JCategoryLog.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright 2001-2004 The Apache Software Foundation. - * - * 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 org.apache.commons.logging.impl; - -import org.apache.commons.logging.Log; -import org.apache.log4j.Category; -import org.apache.log4j.Priority; - -/** - *

Implementation of Log that maps directly to a Log4J - * Category. Initial configuration of the corresponding - * Category instances should be done in the usual manner, as outlined in - * the Log4J documentation.

- * - * @deprecated Use Log4JLogger instead. - * - * @author Scott Sanders - * @author Rod Waldhoff - * @author Robert Burrell Donkin - * @version $Id$ - */ -public final class Log4JCategoryLog implements Log { - - - // ------------------------------------------------------------- Attributes - - /** The fully qualified name of the Log4JCategoryLog class. */ - private static final String FQCN = Log4JCategoryLog.class.getName(); - - /** Log to this category */ - private Category category = null; - - - // ------------------------------------------------------------ Constructor - - public Log4JCategoryLog() { - } - - - /** - * Base constructor. - */ - public Log4JCategoryLog(String name) { - this.category=Category.getInstance(name); - } - - /** For use with a log4j factory. - */ - public Log4JCategoryLog(Category category ) { - this.category=category; - } - - - // ---------------------------------------------------------- Implmentation - - - /** - * Log a message to the Log4j Category with TRACE priority. - * Currently logs to DEBUG level in Log4J. - */ - public void trace(Object message) { - category.log(FQCN, Priority.DEBUG, message, null); - } - - - /** - * Log an error to the Log4j Category with TRACE priority. - * Currently logs to DEBUG level in Log4J. - */ - public void trace(Object message, Throwable t) { - category.log(FQCN, Priority.DEBUG, message, t ); - } - - - /** - * Log a message to the Log4j Category with DEBUG priority. - */ - public void debug(Object message) { - category.log(FQCN, Priority.DEBUG, message, null); - } - - /** - * Log an error to the Log4j Category with DEBUG priority. - */ - public void debug(Object message, Throwable t) { - category.log(FQCN, Priority.DEBUG, message, t ); - } - - - /** - * Log a message to the Log4j Category with INFO priority. - */ - public void info(Object message) { - category.log(FQCN, Priority.INFO, message, null ); - } - - - /** - * Log an error to the Log4j Category with INFO priority. - */ - public void info(Object message, Throwable t) { - category.log(FQCN, Priority.INFO, message, t ); - } - - - /** - * Log a message to the Log4j Category with WARN priority. - */ - public void warn(Object message) { - category.log(FQCN, Priority.WARN, message, null ); - } - - - /** - * Log an error to the Log4j Category with WARN priority. - */ - public void warn(Object message, Throwable t) { - category.log(FQCN, Priority.WARN, message, t ); - } - - - /** - * Log a message to the Log4j Category with ERROR priority. - */ - public void error(Object message) { - category.log(FQCN, Priority.ERROR, message, null ); - } - - - /** - * Log an error to the Log4j Category with ERROR priority. - */ - public void error(Object message, Throwable t) { - category.log(FQCN, Priority.ERROR, message, t ); - } - - - /** - * Log a message to the Log4j Category with FATAL priority. - */ - public void fatal(Object message) { - category.log(FQCN, Priority.FATAL, message, null ); - } - - - /** - * Log an error to the Log4j Category with FATAL priority. - */ - public void fatal(Object message, Throwable t) { - category.log(FQCN, Priority.FATAL, message, t ); - } - - - /** - * Return the native Category instance we are using. - */ - public Category getCategory() { - return (this.category); - } - - - /** - * Check whether the Log4j Category used is enabled for DEBUG priority. - */ - public boolean isDebugEnabled() { - return category.isDebugEnabled(); - } - - - /** - * Check whether the Log4j Category used is enabled for ERROR priority. - */ - public boolean isErrorEnabled() { - return category.isEnabledFor(Priority.ERROR); - } - - - /** - * Check whether the Log4j Category used is enabled for FATAL priority. - */ - public boolean isFatalEnabled() { - return category.isEnabledFor(Priority.FATAL); - } - - - /** - * Check whether the Log4j Category used is enabled for INFO priority. - */ - public boolean isInfoEnabled() { - return category.isInfoEnabled(); - } - - - /** - * Check whether the Log4j Category used is enabled for TRACE priority. - * For Log4J, this returns the value of isDebugEnabled() - */ - public boolean isTraceEnabled() { - return category.isDebugEnabled(); - } - - /** - * Check whether the Log4j Category used is enabled for WARN priority. - */ - public boolean isWarnEnabled() { - return category.isEnabledFor(Priority.WARN); - } -} diff --git a/optional/src/java/org/apache/commons/logging/impl/MemoryLog.java b/optional/src/java/org/apache/commons/logging/impl/MemoryLog.java deleted file mode 100644 index c24ff3b..0000000 --- a/optional/src/java/org/apache/commons/logging/impl/MemoryLog.java +++ /dev/null @@ -1,432 +0,0 @@ -/* - * Copyright 2004 The Apache Software Foundation. - * - * 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 org.apache.commons.logging.impl; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.List; - -import org.apache.commons.logging.Log; - -/** - *

Memory implementation of Log that keeps all log message as - * entries in memory. The class is designed to be used in unit tests. - * The default log level is TRACE.

- *

The code borrows heavily from the SimpleLog class.

- * @author Jörg Schaible - * @version $Id$ - */ -public class MemoryLog implements Log { - - // ------------------------------------------------------- Class Attributes - - /** - * A class for a log entry. - */ - public static class Entry { - - private final Date date; - private final String name; - private final int level; - private final Object message; - private final Throwable throwable; - - /** - * Construct a log entry. - * @param name the logger's name - * @param level the log level - * @param message the message to log - * @param t the throwable attending the log - */ - private Entry(String name, int level, Object message, Throwable t) { - this.date = new Date(); - this.name = name; - this.level = level; - this.message = message; - this.throwable = t; - } - - /** - * @return Returns the logging date. - */ - public Date getDate() { - return date; - } - - /** - * @return Returns the logger's name. - */ - public String getLogName() { - return name; - } - - /** - * @return Returns the log message. - */ - public Object getMessage() { - return message; - } - /** - * @return Returns the attendent {@link java.lang.Throwable} of the log or null. - */ - public Throwable getThrowable() { - return throwable; - } - - /** - * @return Returns the log level. - */ - public int getLevel() { - return level; - } - } - - /** The list with all log entries. */ - private static final List logEntries = Collections.synchronizedList(new ArrayList()); - - - // ---------------------------------------------------- Log Level Constants - - /** "Trace" level logging. */ - public static final int LOG_LEVEL_TRACE = 1; - /** "Debug" level logging. */ - public static final int LOG_LEVEL_DEBUG = 2; - /** "Info" level logging. */ - public static final int LOG_LEVEL_INFO = 3; - /** "Warn" level logging. */ - public static final int LOG_LEVEL_WARN = 4; - /** "Error" level logging. */ - public static final int LOG_LEVEL_ERROR = 5; - /** "Fatal" level logging. */ - public static final int LOG_LEVEL_FATAL = 6; - - /** Enable all logging levels */ - public static final int LOG_LEVEL_ALL = (LOG_LEVEL_TRACE - 1); - - /** Enable no logging levels */ - public static final int LOG_LEVEL_OFF = (LOG_LEVEL_FATAL + 1); - - - // ------------------------------------------------------------- Attributes - - /** The name of this simple log instance */ - protected String logName = null; - /** The current log level */ - protected int currentLogLevel; - - - // ------------------------------------------------------------ Constructor - - /** - * Construct a simple log with given name. - * - * @param name log name - */ - public MemoryLog(String name) { - - logName = name; - - // Set initial log level - setLevel(MemoryLog.LOG_LEVEL_TRACE); - } - - - // -------------------------------------------------------- Properties - - /** - *

Set logging level.

- * - * @param currentLogLevel new logging level - */ - public void setLevel(int currentLogLevel) { - - this.currentLogLevel = currentLogLevel; - - } - - - /** - * @return Returns the logging level. - */ - public int getLevel() { - - return currentLogLevel; - } - - - // -------------------------------------------------------- Logging Methods - - - /** - *

Do the actual logging. - * This method assembles the message - * and then calls write() to cause it to be written.

- * - * @param type One of the LOG_LEVEL_XXX constants defining the log level - * @param message The message itself (typically a String) - * @param t The exception whose stack trace should be logged - */ - protected void log(int type, Object message, Throwable t) { - - if(isLevelEnabled(type)) { - Entry entry = new Entry(logName, type, message, t); - logEntries.add(entry); - } - } - - - /** - * @param logLevel is this level enabled? - * @return Returns true if the current level is enabled. - */ - protected boolean isLevelEnabled(int logLevel) { - // log level are numerically ordered so can use simple numeric - // comparison - return (logLevel >= currentLogLevel); - } - - - /** - * @return Returns the log entries. - */ - public static List getLogEntries() { - return Collections.unmodifiableList(logEntries); - } - - - /** - * Reset the MemoryLog and clear the log entries. - */ - public static void reset() { - logEntries.clear(); - } - - - // -------------------------------------------------------- Log Implementation - - - /** - *

Log a message with debug log level.

- */ - public final void debug(Object message) { - - if (isLevelEnabled(MemoryLog.LOG_LEVEL_DEBUG)) { - log(MemoryLog.LOG_LEVEL_DEBUG, message, null); - } - } - - - /** - *

Log an error with debug log level.

- */ - public final void debug(Object message, Throwable t) { - - if (isLevelEnabled(MemoryLog.LOG_LEVEL_DEBUG)) { - log(MemoryLog.LOG_LEVEL_DEBUG, message, t); - } - } - - - /** - *

Log a message with trace log level.

- */ - public final void trace(Object message) { - - if (isLevelEnabled(MemoryLog.LOG_LEVEL_TRACE)) { - log(MemoryLog.LOG_LEVEL_TRACE, message, null); - } - } - - - /** - *

Log an error with trace log level.

- */ - public final void trace(Object message, Throwable t) { - - if (isLevelEnabled(MemoryLog.LOG_LEVEL_TRACE)) { - log(MemoryLog.LOG_LEVEL_TRACE, message, t); - } - } - - - /** - *

Log a message with info log level.

- */ - public final void info(Object message) { - - if (isLevelEnabled(MemoryLog.LOG_LEVEL_INFO)) { - log(MemoryLog.LOG_LEVEL_INFO,message,null); - } - } - - - /** - *

Log an error with info log level.

- */ - public final void info(Object message, Throwable t) { - - if (isLevelEnabled(MemoryLog.LOG_LEVEL_INFO)) { - log(MemoryLog.LOG_LEVEL_INFO, message, t); - } - } - - - /** - *

Log a message with warn log level.

- */ - public final void warn(Object message) { - - if (isLevelEnabled(MemoryLog.LOG_LEVEL_WARN)) { - log(MemoryLog.LOG_LEVEL_WARN, message, null); - } - } - - - /** - *

Log an error with warn log level.

- */ - public final void warn(Object message, Throwable t) { - - if (isLevelEnabled(MemoryLog.LOG_LEVEL_WARN)) { - log(MemoryLog.LOG_LEVEL_WARN, message, t); - } - } - - - /** - *

Log a message with error log level.

- */ - public final void error(Object message) { - - if (isLevelEnabled(MemoryLog.LOG_LEVEL_ERROR)) { - log(MemoryLog.LOG_LEVEL_ERROR, message, null); - } - } - - - /** - *

Log an error with error log level.

- */ - public final void error(Object message, Throwable t) { - - if (isLevelEnabled(MemoryLog.LOG_LEVEL_ERROR)) { - log(MemoryLog.LOG_LEVEL_ERROR, message, t); - } - } - - - /** - *

Log a message with fatal log level.

- */ - public final void fatal(Object message) { - - if (isLevelEnabled(MemoryLog.LOG_LEVEL_FATAL)) { - log(MemoryLog.LOG_LEVEL_FATAL, message, null); - } - } - - - /** - *

Log an error with fatal log level.

- */ - public final void fatal(Object message, Throwable t) { - - if (isLevelEnabled(MemoryLog.LOG_LEVEL_FATAL)) { - log(MemoryLog.LOG_LEVEL_FATAL, message, t); - } - } - - - /** - *

Are debug messages currently enabled?

- * - *

This allows expensive operations such as String - * concatenation to be avoided when the message will be ignored by the - * logger.

- */ - public final boolean isDebugEnabled() { - - return isLevelEnabled(MemoryLog.LOG_LEVEL_DEBUG); - } - - - /** - *

Are error messages currently enabled?

- * - *

This allows expensive operations such as String - * concatenation to be avoided when the message will be ignored by the - * logger.

- */ - public final boolean isErrorEnabled() { - - return isLevelEnabled(MemoryLog.LOG_LEVEL_ERROR); - } - - - /** - *

Are fatal messages currently enabled?

- * - *

This allows expensive operations such as String - * concatenation to be avoided when the message will be ignored by the - * logger.

- */ - public final boolean isFatalEnabled() { - - return isLevelEnabled(MemoryLog.LOG_LEVEL_FATAL); - } - - - /** - *

Are info messages currently enabled?

- * - *

This allows expensive operations such as String - * concatenation to be avoided when the message will be ignored by the - * logger.

- */ - public final boolean isInfoEnabled() { - - return isLevelEnabled(MemoryLog.LOG_LEVEL_INFO); - } - - - /** - *

Are trace messages currently enabled?

- * - *

This allows expensive operations such as String - * concatenation to be avoided when the message will be ignored by the - * logger.

- */ - public final boolean isTraceEnabled() { - - return isLevelEnabled(MemoryLog.LOG_LEVEL_TRACE); - } - - - /** - *

Are warn messages currently enabled?

- * - *

This allows expensive operations such as String - * concatenation to be avoided when the message will be ignored by the - * logger.

- */ - public final boolean isWarnEnabled() { - - return isLevelEnabled(MemoryLog.LOG_LEVEL_WARN); - } -} diff --git a/optional/src/java/org/apache/commons/logging/impl/WeakHashtable.java b/optional/src/java/org/apache/commons/logging/impl/WeakHashtable.java deleted file mode 100644 index 232b365..0000000 --- a/optional/src/java/org/apache/commons/logging/impl/WeakHashtable.java +++ /dev/null @@ -1,488 +0,0 @@ -/* - * Copyright 2004 The Apache Software Foundation. - * - * 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 org.apache.commons.logging.impl; - -import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; -import java.util.*; - -/** - *

Implementation of Hashtable that uses WeakReference's - * to hold its keys thus allowing them to be reclaimed by the garbage collector. - * The associated values are retained using strong references.

- * - *

This class follows the symantics of Hashtable as closely as - * possible. It therefore does not accept null values or keys.

- * - *

Note: - * This is not intended to be a general purpose hash table replacement. - * This implementation is also tuned towards a particular purpose: for use as a replacement - * for Hashtable in LogFactory. This application requires - * good liveliness for get and put. Various tradeoffs - * have been made with this in mind. - *

- *

- * Usage: typical use case is as a drop-in replacement - * for the Hashtable used in LogFactory for J2EE enviroments - * running 1.3+ JVMs. Use of this class in most cases (see below) will - * allow classloaders to be collected by the garbage collector without the need - * to call {@link org.apache.commons.logging.LogFactory#release(ClassLoader) LogFactory.release(ClassLoader)}. - *

- * - *

org.apache.commons.logging.LogFactory looks to see whether this - * class is present in the classpath, and if so then uses it to store - * references to the LogFactory implementationd it loads - * (rather than using a standard Hashtable instance). - * Having this class used instead of Hashtable solves - * certain issues related to dynamic reloading of applications in J2EE-style - * environments. However this class requires java 1.3 or later (due to its use - * of java.lang.ref.WeakReference and associates) and therefore cannot be - * included in the main logging distribution which supports JVMs prior to 1.3. - * And by the way, this extends Hashtable rather than HashMap - * for backwards compatibility reasons. See the documentation - * for method LogFactory.createFactoryStore for more details.

- * - *

The reason all this is necessary is due to a issue which - * arises during hot deploy in a J2EE-like containers. - * Each component running in the container owns one or more classloaders; when - * the component loads a LogFactory instance via the component classloader - * a reference to it gets stored in the static LogFactory.factories member, - * keyed by the component's classloader so different components don't - * stomp on each other. When the component is later unloaded, the container - * sets the component's classloader to null with the intent that all the - * component's classes get garbage-collected. However there's still a - * reference to the component's classloader from the "global" LogFactory's - * factories member! If LogFactory.release() is called whenever component - * is unloaded (as happens in some famous containers), the classloaders will be correctly - * garbage collected. - * However, holding the classloader references weakly ensures that the classloader - * will be garbage collected without programmatic intervention. - * Unfortunately, weak references are - * only available in java 1.3+, so this code only uses WeakHashtable if the - * class has explicitly been made available on the classpath.

- * - *

- * Because the presence of this class in the classpath ensures proper - * unload of components without the need to call method - * {@link org.apache.commons.logging.LogFactory#release(ClassLoader) LogFactory.release ClassLoader)}, - * it is recommended that this class be deployed along with the standard - * commons-logging.jar file when using commons-logging in J2EE - * environments (which will presumably be running on Java 1.3 or later). - * There are no know ill effects from using this class.

- * - *

- * Limitations: - * There is still one (unusual) scenario in which a component will not - * be correctly unloaded without an explicit release. Though weak references - * are used for its keys, it is necessary to use - * strong references for its values.

- * - *

If the abstract class LogFactory is - * loaded by the container classloader but a subclass of - * LogFactory [LogFactory1] is loaded by the component's - * classloader and an instance stored in the static map associated with the - * base LogFactory class, then there is a strong reference from the LogFactory - * class to the LogFactory1 instance (as normal) and a strong reference from - * the LogFactory1 instance to the component classloader via - * getClass().getClassLoader(). This chain of references will prevent - * collection of the child classloader.

- * - *

- * Such a situation occurs when the commons-logging.jar is - * loaded by a parent classloader (e.g. a server level classloader in a - * servlet container) and a custom LogFactory implementation is - * loaded by a child classloader (e.g. a web app classloader).

- * - *

To avoid this scenario, ensure - * that any custom LogFactory subclass is loaded by the same classloader as - * the base LogFactory. Creating custom LogFactory subclasses is, - * however, rare. The standard LogFactoryImpl class should be sufficient - * for most or all users.

- * - * - * @author Brian Stansberry - */ -public final class WeakHashtable extends Hashtable { - - /** - * The maximum number of times put() or remove() can be called before - * the map will be purged of all cleared entries. - */ - private static final int MAX_CHANGES_BEFORE_PURGE = 100; - - /** - * The maximum number of times put() or remove() can be called before - * the map will be purged of one cleared entry. - */ - private static final int PARTIAL_PURGE_COUNT = 10; - - /* ReferenceQueue we check for gc'd keys */ - private ReferenceQueue queue = new ReferenceQueue(); - /* Counter used to control how often we purge gc'd entries */ - private int changeCount = 0; - - /** - * Constructs a WeakHashtable with the Hashtable default - * capacity and load factor. - */ - public WeakHashtable() {} - - - /** - *@see Hashtable - */ - public boolean containsKey(Object key) { - // purge should not be required - Referenced referenced = new Referenced(key); - return super.containsKey(referenced); - } - - /** - *@see Hashtable - */ - public Enumeration elements() { - purge(); - return super.elements(); - } - - /** - *@see Hashtable - */ - public Set entrySet() { - purge(); - Set referencedEntries = super.entrySet(); - Set unreferencedEntries = new HashSet(); - for (Iterator it=referencedEntries.iterator(); it.hasNext();) { - Map.Entry entry = (Map.Entry) it.next(); - Referenced referencedKey = (Referenced) entry.getKey(); - Object key = referencedKey.getValue(); - Object value = entry.getValue(); - if (key != null) { - Entry dereferencedEntry = new Entry(key, value); - unreferencedEntries.add(dereferencedEntry); - } - } - return unreferencedEntries; - } - - /** - *@see Hashtable - */ - public Object get(Object key) { - // for performance reasons, no purge - Referenced referenceKey = new Referenced(key); - return super.get(referenceKey); - } - - /** - *@see Hashtable - */ - public Enumeration keys() { - purge(); - final Enumeration enumer = super.keys(); - return new Enumeration() { - public boolean hasMoreElements() { - return enumer.hasMoreElements(); - } - public Object nextElement() { - Referenced nextReference = (Referenced) enumer.nextElement(); - return nextReference.getValue(); - } - }; - } - - - /** - *@see Hashtable - */ - public Set keySet() { - purge(); - Set referencedKeys = super.keySet(); - Set unreferencedKeys = new HashSet(); - for (Iterator it=referencedKeys.iterator(); it.hasNext();) { - Referenced referenceKey = (Referenced) it.next(); - Object keyValue = referenceKey.getValue(); - if (keyValue != null) { - unreferencedKeys.add(keyValue); - } - } - return unreferencedKeys; - } - - /** - *@see Hashtable - */ - public Object put(Object key, Object value) { - // check for nulls, ensuring symantics match superclass - if (key == null) { - throw new NullPointerException("Null keys are not allowed"); - } - if (value == null) { - throw new NullPointerException("Null values are not allowed"); - } - - // for performance reasons, only purge every - // MAX_CHANGES_BEFORE_PURGE times - if (changeCount++ > MAX_CHANGES_BEFORE_PURGE) { - purge(); - changeCount = 0; - } - // do a partial purge more often - else if ((changeCount % PARTIAL_PURGE_COUNT) == 0) { - purgeOne(); - } - - Object result = null; - Referenced keyRef = new Referenced(key, queue); - return super.put(keyRef, value); - } - - /** - *@see Hashtable - */ - public void putAll(Map t) { - if (t != null) { - Set entrySet = t.entrySet(); - for (Iterator it=entrySet.iterator(); it.hasNext();) { - Map.Entry entry = (Map.Entry) it.next(); - put(entry.getKey(), entry.getValue()); - } - } - } - - /** - *@see Hashtable - */ - public Collection values() { - purge(); - return super.values(); - } - - /** - *@see Hashtable - */ - public Object remove(Object key) { - // for performance reasons, only purge every - // MAX_CHANGES_BEFORE_PURGE times - if (changeCount++ > MAX_CHANGES_BEFORE_PURGE) { - purge(); - changeCount = 0; - } - // do a partial purge more often - else if ((changeCount % PARTIAL_PURGE_COUNT) == 0) { - purgeOne(); - } - return super.remove(new Referenced(key)); - } - - /** - *@see Hashtable - */ - public boolean isEmpty() { - purge(); - return super.isEmpty(); - } - - /** - *@see Hashtable - */ - public int size() { - purge(); - return super.size(); - } - - /** - *@see Hashtable - */ - public String toString() { - purge(); - return super.toString(); - } - - /** - * @see Hashtable - */ - protected void rehash() { - // purge here to save the effort of rehashing dead entries - purge(); - super.rehash(); - } - - /** - * Purges all entries whose wrapped keys - * have been garbage collected. - */ - private void purge() { - synchronized (queue) { - WeakKey key; - while ((key = (WeakKey) queue.poll()) != null) { - super.remove(key.getReferenced()); - } - } - } - - /** - * Purges one entry whose wrapped key - * has been garbage collected. - */ - private void purgeOne() { - - synchronized (queue) { - WeakKey key = (WeakKey) queue.poll(); - if (key != null) { - super.remove(key.getReferenced()); - } - } - } - - /** Entry implementation */ - private final static class Entry implements Map.Entry { - - private final Object key; - private final Object value; - - private Entry(Object key, Object value) { - this.key = key; - this.value = value; - } - - public boolean equals(Object o) { - boolean result = false; - if (o != null && o instanceof Map.Entry) { - Map.Entry entry = (Map.Entry) o; - result = (getKey()==null ? - entry.getKey() == null : - getKey().equals(entry.getKey())) - && - (getValue()==null ? - entry.getValue() == null : - getValue().equals(entry.getValue())); - } - return result; - } - - public int hashCode() { - - return (getKey()==null ? 0 : getKey().hashCode()) ^ - (getValue()==null ? 0 : getValue().hashCode()); - } - - public Object setValue(Object value) { - throw new UnsupportedOperationException("Entry.setValue is not supported."); - } - - public Object getValue() { - return value; - } - - public Object getKey() { - return key; - } - } - - - /** Wrapper giving correct symantics for equals and hashcode */ - private final static class Referenced { - - private final WeakReference reference; - private final int hashCode; - - /** - * - * @throws NullPointerException if referant is null - */ - private Referenced(Object referant) { - reference = new WeakReference(referant); - // Calc a permanent hashCode so calls to Hashtable.remove() - // work if the WeakReference has been cleared - hashCode = referant.hashCode(); - } - - /** - * - * @throws NullPointerException if key is null - */ - private Referenced(Object key, ReferenceQueue queue) { - reference = new WeakKey(key, queue, this); - // Calc a permanent hashCode so calls to Hashtable.remove() - // work if the WeakReference has been cleared - hashCode = key.hashCode(); - - } - - public int hashCode() { - return hashCode; - } - - private Object getValue() { - return reference.get(); - } - - public boolean equals(Object o) { - boolean result = false; - if (o instanceof Referenced) { - Referenced otherKey = (Referenced) o; - Object thisKeyValue = getValue(); - Object otherKeyValue = otherKey.getValue(); - if (thisKeyValue == null) { - result = (otherKeyValue == null); - - // Since our hashcode was calculated from the original - // non-null referant, the above check breaks the - // hashcode/equals contract, as two cleared Referenced - // objects could test equal but have different hashcodes. - // We can reduce (not eliminate) the chance of this - // happening by comparing hashcodes. - if (result == true) { - result = (this.hashCode() == otherKey.hashCode()); - } - // In any case, as our c'tor does not allow null referants - // and Hashtable does not do equality checks between - // existing keys, normal hashtable operations should never - // result in an equals comparison between null referants - } - else - { - result = thisKeyValue.equals(otherKeyValue); - } - } - return result; - } - } - - /** - * WeakReference subclass that holds a hard reference to an - * associated value and also makes accessible - * the Referenced object holding it. - */ - private final static class WeakKey extends WeakReference { - - private final Referenced referenced; - - private WeakKey(Object key, - ReferenceQueue queue, - Referenced referenced) { - super(key, queue); - this.referenced = referenced; - } - - private Referenced getReferenced() { - return referenced; - } - } -} diff --git a/optional/src/java/overview.html b/optional/src/java/overview.html deleted file mode 100644 index 484f8ee..0000000 --- a/optional/src/java/overview.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - -Overview Documentation for COMMONS-LOGGING (OPTIONAL) - - -

Contains optional additions to JCL.

- -

Contained are classes which are not considered appropriate -to distribute as part of JCL main distribution. -Some classes are JVM dependent. -Others are targetted at uncommon use cases. -Utility code is also appropriate. -

- - diff --git a/optional/src/test/org/apache/commons/logging/IFactoryCreator.java b/optional/src/test/org/apache/commons/logging/IFactoryCreator.java deleted file mode 100644 index 5ed3ae8..0000000 --- a/optional/src/test/org/apache/commons/logging/IFactoryCreator.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2004 The Apache Software Foundation. - * - * 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 org.apache.commons.logging; - -import java.lang.ref.WeakReference; - - - -/** - * Interface implemented by SubDeploymentClass. The LogFactoryTest's - * IsolatedClassLoader will delegate loading of this interface to the - * test runner's classloader, so the test can interact with - * SubDeploymentClass via this interface. - * - * @author bstansberry - * - * @see LogFactoryTest - */ -public interface IFactoryCreator { - - WeakReference getWeakFactory(); - -} diff --git a/optional/src/test/org/apache/commons/logging/LogFactoryTest.java b/optional/src/test/org/apache/commons/logging/LogFactoryTest.java deleted file mode 100644 index 67c9e85..0000000 --- a/optional/src/test/org/apache/commons/logging/LogFactoryTest.java +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright 2004 The Apache Software Foundation. - * - * 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 org.apache.commons.logging; - -import java.io.ByteArrayOutputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.lang.ref.WeakReference; - -import junit.framework.TestCase; - -import org.apache.commons.logging.impl.LogFactoryImpl; -import org.apache.commons.logging.impl.WeakHashtable; - -public class LogFactoryTest extends TestCase { - - - /** Maximum number of iterations before our test fails */ - private static final int MAX_GC_ITERATIONS = 50; - - private ClassLoader origLoader = null; - private String origFactoryProperty = null; - - public LogFactoryTest(String testName) { - super(testName); - } - - public void testLogFactoryType() { - assertTrue(LogFactory.factories instanceof WeakHashtable); - } - - /** - * Tests that LogFactories are not removed from the map - * if their creating ClassLoader is still alive. - */ - public void testHoldFactories() throws Exception - { - // 1) Basic test - - // Get a weak reference to the factory using the classloader. - // When this reference is cleared we know the factory has been - // cleared from LogFactory.factories as well - WeakReference weakFactory = loadFactoryFromContextClassLoader(); - // Run the gc, confirming that the factory - // is not dropped from the map even though there are - // no other references to it - checkRelease(weakFactory, true); - - // 2) Test using an isolated classloader a la a web app - - // Create a classloader that isolates commons-logging - ClassLoader childLoader = new IsolatedClassLoader(origLoader); - Thread.currentThread().setContextClassLoader(childLoader); - weakFactory = loadFactoryFromContextClassLoader(); - Thread.currentThread().setContextClassLoader(origLoader); - // At this point we still have a reference to childLoader, - // so the factory should not be cleared - - checkRelease(weakFactory, true); - } - - /** - * Tests that a ClassLoader is eventually removed from the map - * after all hard references to it are removed. - */ - public void testReleaseClassLoader() throws Exception - { - // 1) Test of a child classloader that follows the Java2 - // delegation model (e.g. an EJB module classloader) - - // Create a classloader that delegates to its parent - ClassLoader childLoader = new ClassLoader() {}; - // Get a weak reference to the factory using the classloader. - // When this reference is cleared we know the factory has been - // cleared from LogFactory.factories as well - Thread.currentThread().setContextClassLoader(childLoader); - loadFactoryFromContextClassLoader(); - Thread.currentThread().setContextClassLoader(origLoader); - - // Get a WeakReference to the child loader so we know when it - // has been gc'ed - WeakReference weakLoader = new WeakReference(childLoader); - // Remove any hard reference to the childLoader or the factory creator - childLoader = null; - - // Run the gc, confirming that childLoader is dropped from the map - checkRelease(weakLoader, false); - - // 2) Test using an isolated classloader a la a web app - - childLoader = new IsolatedClassLoader(origLoader); - Thread.currentThread().setContextClassLoader(childLoader); - loadFactoryFromContextClassLoader(); - Thread.currentThread().setContextClassLoader(origLoader); - weakLoader = new WeakReference(childLoader); - childLoader = null; // somewhat equivalent to undeploying a webapp - - checkRelease(weakLoader, false); - - } - - /** - * Repeatedly run the gc, checking whether the given WeakReference - * is not cleared and failing or succeeding based on - * parameter failOnRelease. - */ - private void checkRelease(WeakReference reference, boolean failOnRelease) { - - int iterations = 0; - int bytz = 2; - while(true) { - System.gc(); - if(iterations++ > MAX_GC_ITERATIONS){ - if (failOnRelease) { - break; - } - fail("Max iterations reached before reference released."); - } - - if(reference.get() == null) { - if (failOnRelease) { - fail("reference released"); - } - else { - break; - } - } else { - // create garbage: - byte[] b; - try { - b = new byte[bytz]; - bytz = bytz * 2; - } - catch (OutOfMemoryError oom) { - // Doing this is probably a no-no, but it seems to work ;-) - b = null; - System.gc(); - if (failOnRelease) { - break; - } - fail("OutOfMemory before reference released."); - } - } - } - } - - protected void setUp() throws Exception { - // Preserve the original classloader and factory implementation - // class so we can restore them when we are done - origLoader = Thread.currentThread().getContextClassLoader(); - origFactoryProperty = System.getProperty(LogFactory.FACTORY_PROPERTY); - - // Ensure we use LogFactoryImpl as our factory - System.setProperty(LogFactory.FACTORY_PROPERTY, - LogFactoryImpl.class.getName()); - - super.setUp(); - } - - protected void tearDown() throws Exception { - // Set the classloader back to whatever it originally was - Thread.currentThread().setContextClassLoader(origLoader); - - // Set the factory implementation class back to - // whatever it originally was - if (origFactoryProperty != null) { - System.setProperty(LogFactory.FACTORY_PROPERTY, - origFactoryProperty); - } - else { - System.getProperties().remove(LogFactory.FACTORY_PROPERTY); - } - - super.tearDown(); - } - - private static WeakReference loadFactoryFromContextClassLoader() - throws Exception { - ClassLoader loader = Thread.currentThread().getContextClassLoader(); - Class clazz = loader.loadClass(SubDeploymentClass.class.getName()); - IFactoryCreator creator = (IFactoryCreator) clazz.newInstance(); - return creator.getWeakFactory(); - } - - /** - * A ClassLoader that mimics the operation of a web app classloader - * by not delegating some calls to its parent. - * - * In this case it does not delegate loading commons-logging classes, - * acting as if commons-logging were in WEB-INF/lib. However, it does - * delegate loading of IFactoryCreator, thus allowing this class to - * interact with SubDeploymentClass via IFactoryCreator. - */ - private static final class IsolatedClassLoader extends ClassLoader { - - private IsolatedClassLoader(ClassLoader parent) { - super(parent); - } - - protected synchronized Class loadClass(String name, boolean resolve) - throws ClassNotFoundException - { - if (name != null && name.startsWith("org.apache.commons.logging") - && "org.apache.commons.logging.IFactoryCreator".equals(name) == false) { - // First, check if the class has already been loaded - Class c = findClass(name); - - if (resolve) { - resolveClass(c); - } - return c; - } - else { - return super.loadClass(name, resolve); - } - } - - protected Class findClass(String name) throws ClassNotFoundException { - if (name != null && name.startsWith("org.apache.commons.logging") - && "org.apache.commons.logging.IFactoryCreator".equals(name) == false) { - try { - InputStream is = getResourceAsStream( name.replace('.','/').concat(".class")); - byte[] bytes = new byte[1024]; - ByteArrayOutputStream baos = new ByteArrayOutputStream(1024); - int read; - while ((read = is.read(bytes)) > -1) { - baos.write(bytes, 0, read); - } - bytes = baos.toByteArray(); - return this.defineClass(name, bytes, 0, bytes.length); - } catch (FileNotFoundException e) { - throw new ClassNotFoundException("cannot find " + name, e); - } catch (IOException e) { - throw new ClassNotFoundException("cannot read " + name, e); - } - } - else { - return super.findClass(name); - } - } - - } - -} diff --git a/optional/src/test/org/apache/commons/logging/SubDeploymentClass.java b/optional/src/test/org/apache/commons/logging/SubDeploymentClass.java deleted file mode 100644 index ac6bb73..0000000 --- a/optional/src/test/org/apache/commons/logging/SubDeploymentClass.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2004 The Apache Software Foundation. - * - * 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 org.apache.commons.logging; - -import java.lang.ref.WeakReference; - -/** - * Class that mocks a user class deployed in a sub-deployment that - * interacts with LogFactory. - * - * @author bstansberry - * - * @see LogFactoryTest - */ -public class SubDeploymentClass implements IFactoryCreator { - - private WeakReference weakFactory = null; - - public SubDeploymentClass() { - LogFactory factory = LogFactory.getFactory(); - weakFactory = new WeakReference(factory); - } - - public WeakReference getWeakFactory() { - return weakFactory; - } - -} diff --git a/optional/src/test/org/apache/commons/logging/TestAll.java b/optional/src/test/org/apache/commons/logging/TestAll.java deleted file mode 100644 index 9119c9d..0000000 --- a/optional/src/test/org/apache/commons/logging/TestAll.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2004 The Apache Software Foundation. - * - * 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 org.apache.commons.logging; - -import junit.framework.*; -import org.apache.commons.logging.impl.MemoryLogTest; -import org.apache.commons.logging.impl.WeakHashtableTest; - -/** - *

The build script calls just one TestSuite - this one! - * All tests should be written into separate TestSuite's - * and added to this. Don't clutter this class with implementations.

- * - * @version $Revision$ - */ -public class TestAll extends TestCase { - - public TestAll(String testName) { - super(testName); - } - - - public static Test suite() { - TestSuite suite = new TestSuite(); - - suite.addTest(MemoryLogTest.suite()); - suite.addTestSuite(WeakHashtableTest.class); - suite.addTestSuite(LogFactoryTest.class); - - return suite; - } - - /** - * This allows the tests to run as a standalone application. - */ - public static void main(String args[]) { - String[] testCaseName = { TestAll.class.getName() }; - junit.textui.TestRunner.main(testCaseName); - } -} diff --git a/optional/src/test/org/apache/commons/logging/impl/MemoryLogTest.java b/optional/src/test/org/apache/commons/logging/impl/MemoryLogTest.java deleted file mode 100644 index 42cb50d..0000000 --- a/optional/src/test/org/apache/commons/logging/impl/MemoryLogTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2001-2004 The Apache Software Foundation. - * - * 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 org.apache.commons.logging.impl; - -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.impl.MemoryLog; - -import junit.framework.*; - -/** - * Test the MemoryLog. - * @author Jörg Schaible - */ -public class MemoryLogTest - extends TestCase { - - public MemoryLogTest(String testName) { - super(testName); - } - - /** - * @see TestCase#setUp() - */ - protected void setUp() throws Exception { - super.setUp(); - MemoryLog.reset(); - } - - public Log getLogObject() - { - return (Log) new MemoryLog(this.getClass().getName()); - } - - public final void testGetLogEntries() - { - MemoryLog log = (MemoryLog)getLogObject(); - log.setLevel(MemoryLog.LOG_LEVEL_DEBUG); - log.trace("trace"); - log.debug("debug"); - log.info("info"); - log.warn("warn"); - log.error("error", new RuntimeException("error")); - log.fatal("fatal", new RuntimeException("fatal")); - List list = MemoryLog.getLogEntries(); - assertEquals(5, list.size()); - assertEquals("debug",((MemoryLog.Entry)list.get(0)).getMessage()); - assertEquals("info",((MemoryLog.Entry)list.get(1)).getMessage()); - assertEquals("warn",((MemoryLog.Entry)list.get(2)).getMessage()); - assertEquals("error",((MemoryLog.Entry)list.get(3)).getMessage()); - assertEquals("error",((MemoryLog.Entry)list.get(3)).getThrowable().getMessage()); - assertEquals("fatal",((MemoryLog.Entry)list.get(4)).getMessage()); - assertEquals("fatal",((MemoryLog.Entry)list.get(4)).getThrowable().getMessage()); - MemoryLog.reset(); - assertEquals(0, MemoryLog.getLogEntries().size()); - } - - public static void main(String[] args) { - junit.textui.TestRunner.run(MemoryLogTest.suite()); - } - - public static Test suite() { - TestSuite suite = new TestSuite(); - - suite.addTestSuite(MemoryLogTest.class); - - return suite; - } -} diff --git a/optional/src/test/org/apache/commons/logging/impl/WeakHashtableTest.java b/optional/src/test/org/apache/commons/logging/impl/WeakHashtableTest.java deleted file mode 100644 index 7798f74..0000000 --- a/optional/src/test/org/apache/commons/logging/impl/WeakHashtableTest.java +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright 2004 The Apache Software Foundation. - * - * 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 org.apache.commons.logging.impl; - -import java.lang.ref.*; -import junit.framework.*; -import java.util.*; - -public class WeakHashtableTest extends TestCase { - - - /** Maximum number of iterations before our test fails */ - private static final int MAX_GC_ITERATIONS = 50; - - private WeakHashtable weakHashtable; - private Long keyOne; - private Long keyTwo; - private Long keyThree; - private Long valueOne; - private Long valueTwo; - private Long valueThree; - - public WeakHashtableTest(String testName) { - super(testName); - } - - - protected void setUp() throws Exception { - super.setUp(); - weakHashtable = new WeakHashtable(); - - keyOne = new Long(1); - keyTwo = new Long(2); - keyThree = new Long(3); - valueOne = new Long(100); - valueTwo = new Long(200); - valueThree = new Long(300); - - weakHashtable.put(keyOne, valueOne); - weakHashtable.put(keyTwo, valueTwo); - weakHashtable.put(keyThree, valueThree); - } - - /** Tests public boolean contains(ObjectÊvalue) */ - public void testContains() throws Exception { - assertFalse(weakHashtable.contains(new Long(1))); - assertFalse(weakHashtable.contains(new Long(2))); - assertFalse(weakHashtable.contains(new Long(3))); - assertTrue(weakHashtable.contains(new Long(100))); - assertTrue(weakHashtable.contains(new Long(200))); - assertTrue(weakHashtable.contains(new Long(300))); - assertFalse(weakHashtable.contains(new Long(400))); - } - - /** Tests public boolean containsKey(ObjectÊkey) */ - public void testContainsKey() throws Exception { - assertTrue(weakHashtable.containsKey(new Long(1))); - assertTrue(weakHashtable.containsKey(new Long(2))); - assertTrue(weakHashtable.containsKey(new Long(3))); - assertFalse(weakHashtable.containsKey(new Long(100))); - assertFalse(weakHashtable.containsKey(new Long(200))); - assertFalse(weakHashtable.containsKey(new Long(300))); - assertFalse(weakHashtable.containsKey(new Long(400))); - } - - /** Tests public boolean containsValue(ObjectÊvalue) */ - public void testContainsValue() throws Exception { - assertFalse(weakHashtable.containsValue(new Long(1))); - assertFalse(weakHashtable.containsValue(new Long(2))); - assertFalse(weakHashtable.containsValue(new Long(3))); - assertTrue(weakHashtable.containsValue(new Long(100))); - assertTrue(weakHashtable.containsValue(new Long(200))); - assertTrue(weakHashtable.containsValue(new Long(300))); - assertFalse(weakHashtable.containsValue(new Long(400))); - } - - /** Tests public Enumeration elements() */ - public void testElements() throws Exception { - ArrayList elements = new ArrayList(); - for (Enumeration e = weakHashtable.elements(); e.hasMoreElements();) { - elements.add(e.nextElement()); - } - assertEquals(3, elements.size()); - assertTrue(elements.contains(valueOne)); - assertTrue(elements.contains(valueTwo)); - assertTrue(elements.contains(valueThree)); - } - - /** Tests public Set entrySet() */ - public void testEntrySet() throws Exception { - Set entrySet = weakHashtable.entrySet(); - for (Iterator it = entrySet.iterator(); it.hasNext();) { - Map.Entry entry = (Map.Entry) it.next(); - Object key = entry.getKey(); - if (keyOne.equals(key)) { - assertEquals(valueOne, entry.getValue()); - } else if (keyTwo.equals(key)) { - assertEquals(valueTwo, entry.getValue()); - } else if (keyThree.equals(key)) { - assertEquals(valueThree, entry.getValue()); - } else { - fail("Unexpected key"); - } - } - } - - /** Tests public Object get(ObjectÊkey) */ - public void testGet() throws Exception { - assertEquals(valueOne, weakHashtable.get(keyOne)); - assertEquals(valueTwo, weakHashtable.get(keyTwo)); - assertEquals(valueThree, weakHashtable.get(keyThree)); - assertNull(weakHashtable.get(new Long(50))); - } - - /** Tests public Enumeration keys() */ - public void testKeys() throws Exception { - ArrayList keys = new ArrayList(); - for (Enumeration e = weakHashtable.keys(); e.hasMoreElements();) { - keys.add(e.nextElement()); - } - assertEquals(3, keys.size()); - assertTrue(keys.contains(keyOne)); - assertTrue(keys.contains(keyTwo)); - assertTrue(keys.contains(keyThree)); - } - - /** Tests public Set keySet() */ - public void testKeySet() throws Exception { - Set keySet = weakHashtable.keySet(); - assertEquals(3, keySet.size()); - assertTrue(keySet.contains(keyOne)); - assertTrue(keySet.contains(keyTwo)); - assertTrue(keySet.contains(keyThree)); - } - - /** Tests public Object put(ObjectÊkey, ObjectÊvalue) */ - public void testPut() throws Exception { - Long anotherKey = new Long(2004); - weakHashtable.put(anotherKey, new Long(1066)); - - assertEquals(new Long(1066), weakHashtable.get(anotherKey)); - - // Test compliance with the hashtable API re nulls - Exception caught = null; - try { - weakHashtable.put(null, new Object()); - } - catch (Exception e) { - caught = e; - } - assertNotNull("did not throw an exception adding a null key", caught); - caught = null; - try { - weakHashtable.put(new Object(), null); - } - catch (Exception e) { - caught = e; - } - assertNotNull("did not throw an exception adding a null value", caught); - } - - /** Tests public void putAll(MapÊt) */ - public void testPutAll() throws Exception { - Map newValues = new HashMap(); - Long newKey = new Long(1066); - Long newValue = new Long(1415); - newValues.put(newKey, newValue); - Long anotherNewKey = new Long(1645); - Long anotherNewValue = new Long(1815); - newValues.put(anotherNewKey, anotherNewValue); - weakHashtable.putAll(newValues); - - assertEquals(5, weakHashtable.size()); - assertEquals(newValue, weakHashtable.get(newKey)); - assertEquals(anotherNewValue, weakHashtable.get(anotherNewKey)); - } - - /** Tests public Object remove(ObjectÊkey) */ - public void testRemove() throws Exception { - weakHashtable.remove(keyOne); - assertEquals(2, weakHashtable.size()); - assertNull(weakHashtable.get(keyOne)); - } - - /** Tests public Collection values() */ - public void testValues() throws Exception { - Collection values = weakHashtable.values(); - assertEquals(3, values.size()); - assertTrue(values.contains(valueOne)); - assertTrue(values.contains(valueTwo)); - assertTrue(values.contains(valueThree)); - } - - public void testRelease() throws Exception { - assertNotNull(weakHashtable.get(new Long(1))); - ReferenceQueue testQueue = new ReferenceQueue(); - WeakReference weakKeyOne = new WeakReference(keyOne, testQueue); - - // lose our references - keyOne = null; - keyTwo = null; - keyThree = null; - valueOne = null; - valueTwo = null; - valueThree = null; - - int iterations = 0; - int bytz = 2; - while(true) { - System.gc(); - if(iterations++ > MAX_GC_ITERATIONS){ - fail("Max iterations reached before resource released."); - } - - if(weakHashtable.get(new Long(1)) == null) { - break; - - } else { - // create garbage: - byte[] b = new byte[bytz]; - bytz = bytz * 2; - } - } - - // some JVMs seem to take a little time to put references on - // the reference queue once the reference has been collected - // need to think about whether this is enough to justify - // stepping through the collection each time... - while(testQueue.poll() == null) {} - - // Test that the released objects are not taking space in the table - assertEquals("underlying table not emptied", 0, weakHashtable.size()); - } -}