You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by co...@apache.org on 2008/03/25 07:01:57 UTC

svn commit: r640706 [3/12] - in /tomcat/sandbox/tomcat-lite/tomcat-coyote: ./ org/ org/apache/ org/apache/coyote/ org/apache/coyote/http11/ org/apache/coyote/http11/filters/ org/apache/juli/ org/apache/juli/logging/ org/apache/tomcat/ org/apache/tomcat...

Added: tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/juli/logging/DirectJDKLog.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/juli/logging/DirectJDKLog.java?rev=640706&view=auto
==============================================================================
--- tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/juli/logging/DirectJDKLog.java (added)
+++ tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/juli/logging/DirectJDKLog.java Mon Mar 24 23:01:43 2008
@@ -0,0 +1,178 @@
+/*
+ * 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.juli.logging;
+
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Formatter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+
+/** 
+ * Hardcoded java.util.logging commons-logging implementation.
+ * 
+ * In addition, it curr 
+ * 
+ */
+class DirectJDKLog implements Log {
+    // no reason to hide this - but good reasons to not hide
+    public Logger logger;
+    
+    /** Alternate config reader and console format 
+     */
+    private static final String SIMPLE_FMT="org.apache.juli.JdkLoggerFormatter";
+
+    static {
+        // If user didn't configure the logs, or if juli log manager is used - 
+        // override the formatter.
+        String configClass = 
+          System.getProperty("java.util.logging.config.class");
+        if( configClass == null  && 
+            System.getProperty("java.util.logging.config.file") ==null ||
+            "org.apache.juli.ClassLoaderLogManager".equals(configClass)) {
+          try {
+            Formatter fmt=(Formatter)Class.forName(SIMPLE_FMT).newInstance();
+            Logger root=Logger.getLogger("");
+            Handler handlers[]=root.getHandlers();
+            for( int i=0; i< handlers.length; i++ ) {
+              // I only care about console - that's what's used in default 
+              // config anyway
+              if( handlers[i] instanceof  ConsoleHandler ) {
+                handlers[i].setFormatter(fmt);
+              }
+            }
+          } catch( Throwable t ) {
+            // maybe it wasn't included - the ugly default will be used.
+          }
+        }
+    }
+    
+    public DirectJDKLog(String name ) {
+        logger=Logger.getLogger(name);        
+    }
+    
+    public final boolean isErrorEnabled() {
+        return logger.isLoggable(Level.SEVERE);
+    }
+    
+    public final boolean isWarnEnabled() {
+        return logger.isLoggable(Level.WARNING); 
+    }
+    
+    public final boolean isInfoEnabled() {
+        return logger.isLoggable(Level.INFO);
+    }
+    
+    public final boolean isDebugEnabled() {
+        return logger.isLoggable(Level.FINE);
+    }
+    
+    public final boolean isFatalEnabled() {
+        return logger.isLoggable(Level.SEVERE);
+    }
+    
+    public final boolean isTraceEnabled() {
+        return logger.isLoggable(Level.FINER);
+    }
+    
+    public final void debug(Object message) {
+        log(Level.FINE, String.valueOf(message), null);
+    }
+    
+    public final void debug(Object message, Throwable t) {
+        log(Level.FINE, String.valueOf(message), t);
+    }
+    
+    public final void trace(Object message) {
+        log(Level.FINER, String.valueOf(message), null);
+    }
+    
+    public final void trace(Object message, Throwable t) {
+        log(Level.FINER, String.valueOf(message), t);
+    }
+    
+    public final void info(Object message) {
+        log(Level.INFO, String.valueOf(message), null);
+    }
+    
+    public final void info(Object message, Throwable t) {        
+        log(Level.INFO, String.valueOf(message), t);
+    }
+    
+    public final void warn(Object message) {
+        log(Level.WARNING, String.valueOf(message), null);
+    }
+    
+    public final void warn(Object message, Throwable t) {
+        log(Level.WARNING, String.valueOf(message), t);
+    }
+    
+    public final void error(Object message) {
+        log(Level.SEVERE, String.valueOf(message), null);
+    }
+    
+    public final void error(Object message, Throwable t) {
+        log(Level.SEVERE, String.valueOf(message), t);
+    }
+    
+    public final void fatal(Object message) {
+        log(Level.SEVERE, String.valueOf(message), null);
+    }
+    
+    public final void fatal(Object message, Throwable t) {
+        log(Level.SEVERE, String.valueOf(message), t);
+    }    
+
+    // from commons logging. This would be my number one reason why java.util.logging
+    // is bad - design by comitee can be really bad ! The impact on performance of 
+    // using java.util.logging - and the ugliness if you need to wrap it - is far
+    // worse than the unfriendly and uncommon default format for logs. 
+    
+    private void log( Level level, String msg, Throwable ex ) {
+        if (logger.isLoggable(level)) {
+            // Hack (?) to get the stack trace.
+            Throwable dummyException=new Throwable();
+            StackTraceElement locations[]=dummyException.getStackTrace();
+            // Caller will be the third element
+            String cname="unknown";
+            String method="unknown";
+            if( locations!=null && locations.length >2 ) {
+                StackTraceElement caller=locations[2];
+                cname=caller.getClassName();
+                method=caller.getMethodName();
+            }
+            if( ex==null ) {
+                logger.logp( level, cname, method, msg );
+            } else {
+                logger.logp( level, cname, method, msg, ex );
+            }
+        }
+    }        
+
+    // for LogFactory
+    static void release() {
+        
+    }
+    
+    static Log getInstance(String name) {
+        return new DirectJDKLog( name );
+    }
+}
+
+

Added: tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/juli/logging/Log.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/juli/logging/Log.java?rev=640706&view=auto
==============================================================================
--- tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/juli/logging/Log.java (added)
+++ tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/juli/logging/Log.java Mon Mar 24 23:01:43 2008
@@ -0,0 +1,234 @@
+/*
+ * 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.juli.logging;
+
+/**
+ * <p>A simple logging interface abstracting logging APIs.  In order to be
+ * instantiated successfully by {@link LogFactory}, classes that implement
+ * this interface must have a constructor that takes a single String
+ * parameter representing the "name" of this Log.</p>
+ *
+ * <p> The six logging levels used by <code>Log</code> are (in order):
+ * <ol>
+ * <li>trace (the least serious)</li>
+ * <li>debug</li>
+ * <li>info</li>
+ * <li>warn</li>
+ * <li>error</li>
+ * <li>fatal (the most serious)</li>
+ * </ol>
+ * The mapping of these log levels to the concepts used by the underlying
+ * logging system is implementation dependent.
+ * The implemention should ensure, though, that this ordering behaves
+ * as expected.</p>
+ *
+ * <p>Performance is often a logging concern.
+ * By examining the appropriate property,
+ * a component can avoid expensive operations (producing information
+ * to be logged).</p>
+ *
+ * <p> For example,
+ * <code><pre>
+ *    if (log.isDebugEnabled()) {
+ *        ... do something expensive ...
+ *        log.debug(theResult);
+ *    }
+ * </pre></code>
+ * </p>
+ *
+ * <p>Configuration of the underlying logging system will generally be done
+ * external to the Logging APIs, through whatever mechanism is supported by
+ * that system.</p>
+ *
+ * @author <a href="mailto:sanders@apache.org">Scott Sanders</a>
+ * @author Rod Waldhoff
+ * @version $Id: Log.java 467222 2006-10-24 03:17:11Z markt $
+ */
+public interface Log {
+
+
+    // ----------------------------------------------------- Logging Properties
+
+
+    /**
+     * <p> Is debug logging currently enabled? </p>
+     *
+     * <p> Call this method to prevent having to perform expensive operations
+     * (for example, <code>String</code> concatenation)
+     * when the log level is more than debug. </p>
+     */
+    public boolean isDebugEnabled();
+
+
+    /**
+     * <p> Is error logging currently enabled? </p>
+     *
+     * <p> Call this method to prevent having to perform expensive operations
+     * (for example, <code>String</code> concatenation)
+     * when the log level is more than error. </p>
+     */
+    public boolean isErrorEnabled();
+
+
+    /**
+     * <p> Is fatal logging currently enabled? </p>
+     *
+     * <p> Call this method to prevent having to perform expensive operations
+     * (for example, <code>String</code> concatenation)
+     * when the log level is more than fatal. </p>
+     */
+    public boolean isFatalEnabled();
+
+
+    /**
+     * <p> Is info logging currently enabled? </p>
+     *
+     * <p> Call this method to prevent having to perform expensive operations
+     * (for example, <code>String</code> concatenation)
+     * when the log level is more than info. </p>
+     */
+    public boolean isInfoEnabled();
+
+
+    /**
+     * <p> Is trace logging currently enabled? </p>
+     *
+     * <p> Call this method to prevent having to perform expensive operations
+     * (for example, <code>String</code> concatenation)
+     * when the log level is more than trace. </p>
+     */
+    public boolean isTraceEnabled();
+
+
+    /**
+     * <p> Is warn logging currently enabled? </p>
+     *
+     * <p> Call this method to prevent having to perform expensive operations
+     * (for example, <code>String</code> concatenation)
+     * when the log level is more than warn. </p>
+     */
+    public boolean isWarnEnabled();
+
+
+    // -------------------------------------------------------- Logging Methods
+
+
+    /**
+     * <p> Log a message with trace log level. </p>
+     *
+     * @param message log this message
+     */
+    public void trace(Object message);
+
+
+    /**
+     * <p> Log an error with trace log level. </p>
+     *
+     * @param message log this message
+     * @param t log this cause
+     */
+    public void trace(Object message, Throwable t);
+
+
+    /**
+     * <p> Log a message with debug log level. </p>
+     *
+     * @param message log this message
+     */
+    public void debug(Object message);
+
+
+    /**
+     * <p> Log an error with debug log level. </p>
+     *
+     * @param message log this message
+     * @param t log this cause
+     */
+    public void debug(Object message, Throwable t);
+
+
+    /**
+     * <p> Log a message with info log level. </p>
+     *
+     * @param message log this message
+     */
+    public void info(Object message);
+
+
+    /**
+     * <p> Log an error with info log level. </p>
+     *
+     * @param message log this message
+     * @param t log this cause
+     */
+    public void info(Object message, Throwable t);
+
+
+    /**
+     * <p> Log a message with warn log level. </p>
+     *
+     * @param message log this message
+     */
+    public void warn(Object message);
+
+
+    /**
+     * <p> Log an error with warn log level. </p>
+     *
+     * @param message log this message
+     * @param t log this cause
+     */
+    public void warn(Object message, Throwable t);
+
+
+    /**
+     * <p> Log a message with error log level. </p>
+     *
+     * @param message log this message
+     */
+    public void error(Object message);
+
+
+    /**
+     * <p> Log an error with error log level. </p>
+     *
+     * @param message log this message
+     * @param t log this cause
+     */
+    public void error(Object message, Throwable t);
+
+
+    /**
+     * <p> Log a message with fatal log level. </p>
+     *
+     * @param message log this message
+     */
+    public void fatal(Object message);
+
+
+    /**
+     * <p> Log an error with fatal log level. </p>
+     *
+     * @param message log this message
+     * @param t log this cause
+     */
+    public void fatal(Object message, Throwable t);
+
+
+}

Added: tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/juli/logging/LogConfigurationException.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/juli/logging/LogConfigurationException.java?rev=640706&view=auto
==============================================================================
--- tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/juli/logging/LogConfigurationException.java (added)
+++ tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/juli/logging/LogConfigurationException.java Mon Mar 24 23:01:43 2008
@@ -0,0 +1,92 @@
+/*
+ * 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.juli.logging;
+
+
+/**
+ * <p>An exception that is thrown only if a suitable <code>LogFactory</code>
+ * or <code>Log</code> instance cannot be created by the corresponding
+ * factory methods.</p>
+ *
+ * @author Craig R. McClanahan
+ * @version $Revision: 467222 $ $Date: 2006-10-23 20:17:11 -0700 (Mon, 23 Oct 2006) $
+ */
+
+public class LogConfigurationException extends RuntimeException {
+
+
+    /**
+     * Construct a new exception with <code>null</code> as its detail message.
+     */
+    public LogConfigurationException() {
+        super();
+    }
+
+
+    /**
+     * Construct a new exception with the specified detail message.
+     *
+     * @param message The detail message
+     */
+    public LogConfigurationException(String message) {
+        super(message);
+    }
+
+
+    /**
+     * Construct a new exception with the specified cause and a derived
+     * detail message.
+     *
+     * @param cause The underlying cause
+     */
+    public LogConfigurationException(Throwable cause) {
+        this( ((cause == null) ? null : cause.toString()), cause);
+    }
+
+
+    /**
+     * Construct a new exception with the specified detail message and cause.
+     *
+     * @param message The detail message
+     * @param cause The underlying cause
+     */
+    public LogConfigurationException(String message, Throwable cause) {
+
+        super(message);
+        this.cause = cause; // Two-argument version requires JDK 1.4 or later
+
+    }
+
+
+    /**
+     * The underlying cause of this exception.
+     */
+    protected Throwable cause = null;
+
+
+    /**
+     * Return the underlying cause of this exception (if any).
+     */
+    public Throwable getCause() {
+
+        return (this.cause);
+
+    }
+
+
+}

Added: tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/juli/logging/LogFactory.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/juli/logging/LogFactory.java?rev=640706&view=auto
==============================================================================
--- tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/juli/logging/LogFactory.java (added)
+++ tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/juli/logging/LogFactory.java Mon Mar 24 23:01:43 2008
@@ -0,0 +1,362 @@
+/*
+ * 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.juli.logging;
+
+
+import java.util.Properties;
+
+
+
+/**
+ * Modified LogFactory: removed all discovery, hardcode a specific implementation
+ * If you like a different logging implementation - use either the discovery-based
+ * commons-logging, or better - another implementation hardcoded to your favourite
+ * logging impl.
+ * 
+ * Why ? Each application and deployment can choose a logging implementation - 
+ * that involves configuration, installing the logger jar and optional plugins, etc.
+ * As part of this process - they can as well install the commons-logging implementation
+ * that corresponds to their logger of choice. This completely avoids any discovery
+ * problem, while still allowing the user to switch. 
+ * 
+ * Note that this implementation is not just a wrapper arround JDK logging ( like
+ * the original commons-logging impl ). It adds 2 features - a simpler configuration
+ * ( which is in fact a subset of log4j.properties ) and a formatter that is 
+ * less ugly.   
+ * 
+ * The removal of 'abstract' preserves binary backward compatibility. It is possible
+ * to preserve the abstract - and introduce another ( hardcoded ) factory - but I 
+ * see no benefit. 
+ * 
+ * Since this class is not intended to be extended - and provides
+ * no plugin for other LogFactory implementation - all protected methods are removed.
+ * This can be changed - but again, there is little value in keeping dead code.
+ * Just take a quick look at the removed code ( and it's complexity)  
+ * 
+ * --------------
+ * 
+ * Original comment:
+ * <p>Factory for creating {@link Log} instances, with discovery and
+ * configuration features similar to that employed by standard Java APIs
+ * such as JAXP.</p>
+ * 
+ * <p><strong>IMPLEMENTATION NOTE</strong> - This implementation is heavily
+ * based on the SAXParserFactory and DocumentBuilderFactory implementations
+ * (corresponding to the JAXP pluggability APIs) found in Apache Xerces.</p>
+ * 
+ *
+ * @author Craig R. McClanahan
+ * @author Costin Manolache
+ * @author Richard A. Sitze
+ * @version $Revision: 467222 $ $Date: 2006-10-23 20:17:11 -0700 (Mon, 23 Oct 2006) $
+ */
+public /* abstract */ class LogFactory {
+
+    // ----------------------------------------------------- Manifest Constants
+
+    /**
+     * The name of the property used to identify the LogFactory implementation
+     * class name.
+     */
+    public static final String FACTORY_PROPERTY =
+        "org.apache.commons.logging.LogFactory";
+
+    /**
+     * The fully qualified class name of the fallback <code>LogFactory</code>
+     * implementation class to use, if no other can be found.
+     */
+    public static final String FACTORY_DEFAULT =
+        "org.apache.commons.logging.impl.LogFactoryImpl";
+
+    /**
+     * The name of the properties file to search for.
+     */
+    public static final String FACTORY_PROPERTIES =
+        "commons-logging.properties";
+    
+    /**
+     * <p>Setting this system property value allows the <code>Hashtable</code> used to store
+     * classloaders to be substituted by an alternative implementation.
+     * </p>
+     * <p>
+     * <strong>Note:</strong> <code>LogFactory</code> will print:
+     * <code><pre>
+     * [ERROR] LogFactory: Load of custom hashtable failed</em>
+     * </code></pre>
+     * to system error and then continue using a standard Hashtable.
+     * </p>
+     * <p>
+     * <strong>Usage:</strong> Set this property when Java is invoked
+     * and <code>LogFactory</code> will attempt to load a new instance 
+     * of the given implementation class.
+     * For example, running the following ant scriplet:
+     * <code><pre>
+     *  &lt;java classname="${test.runner}" fork="yes" failonerror="${test.failonerror}"&gt;
+     *     ...
+     *     &lt;sysproperty 
+     *        key="org.apache.commons.logging.LogFactory.HashtableImpl"
+     *        value="org.apache.commons.logging.AltHashtable"/&gt;
+     *  &lt;/java&gt;
+     * </pre></code>
+     * will mean that <code>LogFactory</code> will load an instance of
+     * <code>org.apache.commons.logging.AltHashtable</code>.
+     * </p>
+     * <p>
+     * A typical use case is to allow a custom
+     * Hashtable implementation using weak references to be substituted.
+     * This will allow classloaders to be garbage collected without
+     * the need to release them (on 1.3+ JVMs only, of course ;)
+     * </p>
+     */
+    public static final String HASHTABLE_IMPLEMENTATION_PROPERTY =
+        "org.apache.commons.logging.LogFactory.HashtableImpl";
+    
+    private static LogFactory singleton=new LogFactory();
+
+    Properties logConfig;
+    
+    // ----------------------------------------------------------- Constructors
+
+
+    /**
+     * Protected constructor that is not available for public use.
+     */
+    private LogFactory() {
+        logConfig=new Properties();
+    }
+    
+    // hook for syserr logger - class level
+    void setLogConfig( Properties p ) {
+        this.logConfig=p;
+    }
+    // --------------------------------------------------------- Public Methods
+
+    // only those 2 methods need to change to use a different direct logger.
+    
+    /**
+     * <p>Construct (if necessary) and return a <code>Log</code> instance,
+     * using the factory's current set of configuration attributes.</p>
+     *
+     * <p><strong>NOTE</strong> - Depending upon the implementation of
+     * the <code>LogFactory</code> you are using, the <code>Log</code>
+     * instance you are returned may or may not be local to the current
+     * application, and may or may not be returned again on a subsequent
+     * call with the same name argument.</p>
+     *
+     * @param name Logical name of the <code>Log</code> instance to be
+     *  returned (the meaning of this name is only known to the underlying
+     *  logging implementation that is being wrapped)
+     *
+     * @exception LogConfigurationException if a suitable <code>Log</code>
+     *  instance cannot be returned
+     */
+    public Log getInstance(String name)
+        throws LogConfigurationException {
+        return DirectJDKLog.getInstance(name);
+    }
+
+
+    /**
+     * Release any internal references to previously created {@link Log}
+     * instances returned by this factory.  This is useful in environments
+     * like servlet containers, which implement application reloading by
+     * throwing away a ClassLoader.  Dangling references to objects in that
+     * class loader would prevent garbage collection.
+     */
+    public void release() {
+        DirectJDKLog.release();
+    }
+
+    /**
+     * Return the configuration attribute with the specified name (if any),
+     * or <code>null</code> if there is no such attribute.
+     *
+     * @param name Name of the attribute to return
+     */
+    public Object getAttribute(String name) {
+        return logConfig.get(name);
+    }
+
+
+    /**
+     * Return an array containing the names of all currently defined
+     * configuration attributes.  If there are no such attributes, a zero
+     * length array is returned.
+     */
+    public String[] getAttributeNames() {
+        return (String[])logConfig.keySet().toArray();
+    }
+
+    /**
+     * Remove any configuration attribute associated with the specified name.
+     * If there is no such attribute, no action is taken.
+     *
+     * @param name Name of the attribute to remove
+     */
+    public void removeAttribute(String name) {
+        logConfig.remove(name);
+     }   
+
+
+    /**
+     * Set the configuration attribute with the specified name.  Calling
+     * this with a <code>null</code> value is equivalent to calling
+     * <code>removeAttribute(name)</code>.
+     *
+     * @param name Name of the attribute to set
+     * @param value Value of the attribute to set, or <code>null</code>
+     *  to remove any setting for this attribute
+     */
+    public void setAttribute(String name, Object value) {
+        logConfig.put(name, value);
+    }
+
+
+    /**
+     * Convenience method to derive a name from the specified class and
+     * call <code>getInstance(String)</code> with it.
+     *
+     * @param clazz Class for which a suitable Log name will be derived
+     *
+     * @exception LogConfigurationException if a suitable <code>Log</code>
+     *  instance cannot be returned
+     */
+    public Log getInstance(Class clazz)
+        throws LogConfigurationException {
+        return getInstance( clazz.getName());
+    }
+
+
+    
+
+
+    // ------------------------------------------------------- Static Variables
+
+
+
+    // --------------------------------------------------------- Static Methods
+
+
+    /**
+     * <p>Construct (if necessary) and return a <code>LogFactory</code>
+     * instance, using the following ordered lookup procedure to determine
+     * the name of the implementation class to be loaded.</p>
+     * <ul>
+     * <li>The <code>org.apache.commons.logging.LogFactory</code> system
+     *     property.</li>
+     * <li>The JDK 1.3 Service Discovery mechanism</li>
+     * <li>Use the properties file <code>commons-logging.properties</code>
+     *     file, if found in the class path of this class.  The configuration
+     *     file is in standard <code>java.util.Properties</code> format and
+     *     contains the fully qualified name of the implementation class
+     *     with the key being the system property defined above.</li>
+     * <li>Fall back to a default implementation class
+     *     (<code>org.apache.commons.logging.impl.LogFactoryImpl</code>).</li>
+     * </ul>
+     *
+     * <p><em>NOTE</em> - If the properties file method of identifying the
+     * <code>LogFactory</code> implementation class is utilized, all of the
+     * properties defined in this file will be set as configuration attributes
+     * on the corresponding <code>LogFactory</code> instance.</p>
+     *
+     * @exception LogConfigurationException if the implementation class is not
+     *  available or cannot be instantiated.
+     */
+    public static LogFactory getFactory() throws LogConfigurationException {
+        return singleton;
+    }
+
+
+    /**
+     * Convenience method to return a named logger, without the application
+     * having to care about factories.
+     *
+     * @param clazz Class from which a log name will be derived
+     *
+     * @exception LogConfigurationException if a suitable <code>Log</code>
+     *  instance cannot be returned
+     */
+    public static Log getLog(Class clazz)
+        throws LogConfigurationException {
+        return (getFactory().getInstance(clazz));
+
+    }
+
+
+    /**
+     * Convenience method to return a named logger, without the application
+     * having to care about factories.
+     *
+     * @param name Logical name of the <code>Log</code> instance to be
+     *  returned (the meaning of this name is only known to the underlying
+     *  logging implementation that is being wrapped)
+     *
+     * @exception LogConfigurationException if a suitable <code>Log</code>
+     *  instance cannot be returned
+     */
+    public static Log getLog(String name)
+        throws LogConfigurationException {
+        return (getFactory().getInstance(name));
+
+    }
+
+
+    /**
+     * Release any internal references to previously created {@link LogFactory}
+     * instances that have been associated with the specified class loader
+     * (if any), after calling the instance method <code>release()</code> on
+     * each of them.
+     *
+     * @param classLoader ClassLoader for which to release the LogFactory
+     */
+    public static void release(ClassLoader classLoader) {
+        // nothing - we don't use any class loaders
+    }
+
+
+    /**
+     * Release any internal references to previously created {@link LogFactory}
+     * instances, after calling the instance method <code>release()</code> on
+     * each of them.  This is useful in environments like servlet containers,
+     * which implement application reloading by throwing away a ClassLoader.
+     * Dangling references to objects in that class loader would prevent
+     * garbage collection.
+     */
+    public static void releaseAll() {
+        singleton.release();
+    }
+
+    /**
+     * Returns a string that uniquely identifies the specified object, including
+     * its class.
+     * <p>
+     * The returned string is of form "classname@hashcode", ie is the same as
+     * the return value of the Object.toString() method, but works even when
+     * the specified object's class has overidden the toString method.
+     * 
+     * @param o may be null.
+     * @return a string of form classname@hashcode, or "null" if param o is null.
+     */
+    public static String objectId(Object o) {
+        if (o == null) {
+            return "null";
+        } else {
+            return o.getClass().getName() + "@" + System.identityHashCode(o);
+        }
+    }
+}

Added: tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/juli/logging/package.html
URL: http://svn.apache.org/viewvc/tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/juli/logging/package.html?rev=640706&view=auto
==============================================================================
--- tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/juli/logging/package.html (added)
+++ tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/juli/logging/package.html Mon Mar 24 23:01:43 2008
@@ -0,0 +1,37 @@
+<!--
+  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.
+-->
+<body>
+
+<h3>Overview</h3>
+
+
+<p>This implementation of commons-logging uses a  commons-logging.jar
+ specific to a particular logging framework, instead of discovery. This takes 
+out the guessing, is simpler, faster and more robust. Just like you chose a 
+logging implementation, you should also use a matching commons-logging - for
+example you download log4j.jar and commons-logging-log4j.jar, or use jdk 
+logging and use commons-logging-jdk.jar.</p>
+
+<p>A similar packaging is used by Eclipse SWT - they provide a common widget API,
+ but each platform uses a different implementation jar - instead of using a complex 
+ discovery/plugin mechanism.
+</p> 
+
+<p>This package generates commons-logging-jdk14.jar - i.e. the java.util implementation
+of commons-logging api.<p>
+
+</body>

Added: tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/DomUtil.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/DomUtil.java?rev=640706&view=auto
==============================================================================
--- tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/DomUtil.java (added)
+++ tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/DomUtil.java Mon Mar 24 23:01:43 2008
@@ -0,0 +1,270 @@
+/*
+ * 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.tomcat.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.StringReader;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+
+/**
+ *  Few simple utils to read DOM
+ *
+ * @author Costin Manolache
+ */
+public class DomUtil {
+    private static org.apache.juli.logging.Log log=
+        org.apache.juli.logging.LogFactory.getLog( DomUtil.class );
+
+    // -------------------- DOM utils --------------------
+
+    /** Get the trimed text content of a node or null if there is no text
+     */
+    public static String getContent(Node n ) {
+        if( n==null ) return null;
+        Node n1=DomUtil.getChild(n, Node.TEXT_NODE);
+
+        if( n1==null ) return null;
+
+        String s1=n1.getNodeValue();
+        return s1.trim();
+    }
+
+    /** Get the first element child.
+     * @param parent lookup direct childs
+     * @param name name of the element. If null return the first element.
+     */
+    public static Node getChild( Node parent, String name ) {
+        if( parent==null ) return null;
+        Node first=parent.getFirstChild();
+        if( first==null ) return null;
+
+        for (Node node = first; node != null;
+             node = node.getNextSibling()) {
+            //System.out.println("getNode: " + name + " " + node.getNodeName());
+            if( node.getNodeType()!=Node.ELEMENT_NODE)
+                continue;
+            if( name != null &&
+                name.equals( node.getNodeName() ) ) {
+                return node;
+            }
+            if( name == null ) {
+                return node;
+            }
+        }
+        return null;
+    }
+
+    public static String getAttribute(Node element, String attName ) {
+        NamedNodeMap attrs=element.getAttributes();
+        if( attrs==null ) return null;
+        Node attN=attrs.getNamedItem(attName);
+        if( attN==null ) return null;
+        return attN.getNodeValue();
+    }
+
+    public static void setAttribute(Node node, String attName, String val) {
+        NamedNodeMap attributes=node.getAttributes();
+        Node attNode=node.getOwnerDocument().createAttribute(attName);
+        attNode.setNodeValue( val );
+        attributes.setNamedItem(attNode);
+    }
+    
+    public static void removeAttribute( Node node, String attName ) {
+        NamedNodeMap attributes=node.getAttributes();
+        attributes.removeNamedItem(attName);                
+    }
+    
+    
+    /** Set or replace the text value 
+     */ 
+    public static void setText(Node node, String val) {
+        Node chld=DomUtil.getChild(node, Node.TEXT_NODE);
+        if( chld == null ) {
+            Node textN=node.getOwnerDocument().createTextNode(val);
+            node.appendChild(textN);
+            return;
+        }
+        // change the value
+        chld.setNodeValue(val);           
+    }
+
+    /** Find the first direct child with a given attribute.
+     * @param parent
+     * @param elemName name of the element, or null for any 
+     * @param attName attribute we're looking for
+     * @param attVal attribute value or null if we just want any
+     */ 
+    public static Node findChildWithAtt(Node parent, String elemName,
+                                        String attName, String attVal) {
+        
+        Node child=DomUtil.getChild(parent, Node.ELEMENT_NODE);
+        if( attVal== null ) {
+            while( child!= null &&
+                    ( elemName==null || elemName.equals( child.getNodeName())) && 
+                    DomUtil.getAttribute(child, attName) != null ) {
+                child=getNext(child, elemName, Node.ELEMENT_NODE );
+            }
+        } else {
+            while( child!= null && 
+                    ( elemName==null || elemName.equals( child.getNodeName())) && 
+                    ! attVal.equals( DomUtil.getAttribute(child, attName)) ) {
+                child=getNext(child, elemName, Node.ELEMENT_NODE );
+            }
+        }
+        return child;        
+    }    
+    
+
+    /** Get the first child's content ( ie it's included TEXT node ).
+     */
+    public static String getChildContent( Node parent, String name ) {
+        Node first=parent.getFirstChild();
+        if( first==null ) return null;
+        for (Node node = first; node != null;
+             node = node.getNextSibling()) {
+            //System.out.println("getNode: " + name + " " + node.getNodeName());
+            if( name.equals( node.getNodeName() ) ) {
+                return getContent( node );
+            }
+        }
+        return null;
+    }
+
+    /** Get the first direct child with a given type
+     */
+    public static Node getChild( Node parent, int type ) {
+        Node n=parent.getFirstChild();
+        while( n!=null && type != n.getNodeType() ) {
+            n=n.getNextSibling();
+        }
+        if( n==null ) return null;
+        return n;
+    }
+
+    /** Get the next sibling with the same name and type
+     */
+    public static Node getNext( Node current ) {
+        String name=current.getNodeName();
+        int type=current.getNodeType();
+        return getNext( current, name, type);
+    }
+
+    /** Return the next sibling with a given name and type
+     */ 
+    public static Node getNext( Node current, String name, int type) {
+        Node first=current.getNextSibling();
+        if( first==null ) return null;
+
+        for (Node node = first; node != null;
+             node = node.getNextSibling()) {
+            
+            if( type >= 0 && node.getNodeType() != type ) continue;
+            //System.out.println("getNode: " + name + " " + node.getNodeName());
+            if( name==null )
+                return node;
+            if( name.equals( node.getNodeName() ) ) {
+                return node;
+            }
+        }
+        return null;
+    }
+
+    public static class NullResolver implements EntityResolver {
+        public InputSource resolveEntity (String publicId,
+                                                   String systemId)
+            throws SAXException, IOException
+        {
+            if( log.isTraceEnabled())
+                log.trace("ResolveEntity: " + publicId + " " + systemId);
+            return new InputSource(new StringReader(""));
+        }
+    }
+
+    public static void setAttributes( Object o, Node parent)
+    {
+        NamedNodeMap attrs=parent.getAttributes();
+        if( attrs==null ) return;
+
+        for (int i=0; i<attrs.getLength(); i++ ) {
+            Node n=attrs.item(i);
+            String name=n.getNodeName();
+            String value=n.getNodeValue();
+
+            if( log.isTraceEnabled() )
+                log.trace("Attribute " + parent.getNodeName() + " " +
+                            name + "=" + value);
+            try {
+                IntrospectionUtils.setProperty(o, name, value);
+            } catch( Exception ex ) {
+                ex.printStackTrace();
+            }
+        }
+    }
+
+    /** Read XML as DOM.
+     */
+    public static Document readXml(InputStream is)
+        throws SAXException, IOException, ParserConfigurationException
+    {
+        DocumentBuilderFactory dbf =
+            DocumentBuilderFactory.newInstance();
+
+        dbf.setValidating(false);
+        dbf.setIgnoringComments(false);
+        dbf.setIgnoringElementContentWhitespace(true);
+        //dbf.setCoalescing(true);
+        //dbf.setExpandEntityReferences(true);
+
+        DocumentBuilder db = null;
+        db = dbf.newDocumentBuilder();
+        db.setEntityResolver( new NullResolver() );
+
+        // db.setErrorHandler( new MyErrorHandler());
+
+        Document doc = db.parse(is);
+        return doc;
+    }
+
+    public static void writeXml( Node n, OutputStream os )
+            throws TransformerException
+    {
+        TransformerFactory tf=TransformerFactory.newInstance();
+        //identity
+        Transformer t=tf.newTransformer();
+        t.setOutputProperty(OutputKeys.INDENT, "yes");
+        t.transform(new DOMSource( n ), new StreamResult( os ));
+    }
+}

Added: tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/IntrospectionUtils.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/IntrospectionUtils.java?rev=640706&view=auto
==============================================================================
--- tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/IntrospectionUtils.java (added)
+++ tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/IntrospectionUtils.java Mon Mar 24 23:01:43 2008
@@ -0,0 +1,1026 @@
+/*
+ *  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.tomcat.util;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+// Depends: JDK1.1
+
+/**
+ * Utils for introspection and reflection
+ */
+public final class IntrospectionUtils {
+
+    
+    private static org.apache.juli.logging.Log log=
+        org.apache.juli.logging.LogFactory.getLog( IntrospectionUtils.class );
+    
+    /**
+     * Call execute() - any ant-like task should work
+     */
+    public static void execute(Object proxy, String method) throws Exception {
+        Method executeM = null;
+        Class c = proxy.getClass();
+        Class params[] = new Class[0];
+        //	params[0]=args.getClass();
+        executeM = findMethod(c, method, params);
+        if (executeM == null) {
+            throw new RuntimeException("No execute in " + proxy.getClass());
+        }
+        executeM.invoke(proxy, (Object[]) null);//new Object[] { args });
+    }
+
+    /**
+     * Call void setAttribute( String ,Object )
+     */
+    public static void setAttribute(Object proxy, String n, Object v)
+            throws Exception {
+        if (proxy instanceof AttributeHolder) {
+            ((AttributeHolder) proxy).setAttribute(n, v);
+            return;
+        }
+
+        Method executeM = null;
+        Class c = proxy.getClass();
+        Class params[] = new Class[2];
+        params[0] = String.class;
+        params[1] = Object.class;
+        executeM = findMethod(c, "setAttribute", params);
+        if (executeM == null) {
+            if (log.isDebugEnabled())
+                log.debug("No setAttribute in " + proxy.getClass());
+            return;
+        }
+        if (false)
+            if (log.isDebugEnabled())
+                log.debug("Setting " + n + "=" + v + "  in " + proxy);
+        executeM.invoke(proxy, new Object[] { n, v });
+        return;
+    }
+
+    /**
+     * Call void getAttribute( String )
+     */
+    public static Object getAttribute(Object proxy, String n) throws Exception {
+        Method executeM = null;
+        Class c = proxy.getClass();
+        Class params[] = new Class[1];
+        params[0] = String.class;
+        executeM = findMethod(c, "getAttribute", params);
+        if (executeM == null) {
+            if (log.isDebugEnabled())
+                log.debug("No getAttribute in " + proxy.getClass());
+            return null;
+        }
+        return executeM.invoke(proxy, new Object[] { n });
+    }
+
+    /**
+     * Construct a URLClassLoader. Will compile and work in JDK1.1 too.
+     */
+    public static ClassLoader getURLClassLoader(URL urls[], ClassLoader parent) {
+        try {
+            Class urlCL = Class.forName("java.net.URLClassLoader");
+            Class paramT[] = new Class[2];
+            paramT[0] = urls.getClass();
+            paramT[1] = ClassLoader.class;
+            Method m = findMethod(urlCL, "newInstance", paramT);
+            if (m == null)
+                return null;
+
+            ClassLoader cl = (ClassLoader) m.invoke(urlCL, new Object[] { urls,
+                    parent });
+            return cl;
+        } catch (ClassNotFoundException ex) {
+            // jdk1.1
+            return null;
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            return null;
+        }
+    }
+
+    public static String guessInstall(String installSysProp,
+            String homeSysProp, String jarName) {
+        return guessInstall(installSysProp, homeSysProp, jarName, null);
+    }
+
+    /**
+     * Guess a product install/home by analyzing the class path. It works for
+     * product using the pattern: lib/executable.jar or if executable.jar is
+     * included in classpath by a shell script. ( java -jar also works )
+     * 
+     * Insures both "install" and "home" System properties are set. If either or
+     * both System properties are unset, "install" and "home" will be set to the
+     * same value. This value will be the other System property that is set, or
+     * the guessed value if neither is set.
+     */
+    public static String guessInstall(String installSysProp,
+            String homeSysProp, String jarName, String classFile) {
+        String install = null;
+        String home = null;
+
+        if (installSysProp != null)
+            install = System.getProperty(installSysProp);
+
+        if (homeSysProp != null)
+            home = System.getProperty(homeSysProp);
+
+        if (install != null) {
+            if (home == null)
+                System.getProperties().put(homeSysProp, install);
+            return install;
+        }
+
+        // Find the directory where jarName.jar is located
+
+        String cpath = System.getProperty("java.class.path");
+        String pathSep = System.getProperty("path.separator");
+        StringTokenizer st = new StringTokenizer(cpath, pathSep);
+        while (st.hasMoreTokens()) {
+            String path = st.nextToken();
+            //	    log( "path " + path );
+            if (path.endsWith(jarName)) {
+                home = path.substring(0, path.length() - jarName.length());
+                try {
+                    if ("".equals(home)) {
+                        home = new File("./").getCanonicalPath();
+                    } else if (home.endsWith(File.separator)) {
+                        home = home.substring(0, home.length() - 1);
+                    }
+                    File f = new File(home);
+                    String parentDir = f.getParent();
+                    if (parentDir == null)
+                        parentDir = home; // unix style
+                    File f1 = new File(parentDir);
+                    install = f1.getCanonicalPath();
+                    if (installSysProp != null)
+                        System.getProperties().put(installSysProp, install);
+                    if (home == null && homeSysProp != null)
+                        System.getProperties().put(homeSysProp, install);
+                    return install;
+                } catch (Exception ex) {
+                    ex.printStackTrace();
+                }
+            } else {
+                String fname = path + (path.endsWith("/") ? "" : "/")
+                        + classFile;
+                if (new File(fname).exists()) {
+                    try {
+                        File f = new File(path);
+                        String parentDir = f.getParent();
+                        if (parentDir == null)
+                            parentDir = path; // unix style
+                        File f1 = new File(parentDir);
+                        install = f1.getCanonicalPath();
+                        if (installSysProp != null)
+                            System.getProperties().put(installSysProp, install);
+                        if (home == null && homeSysProp != null)
+                            System.getProperties().put(homeSysProp, install);
+                        return install;
+                    } catch (Exception ex) {
+                        ex.printStackTrace();
+                    }
+                }
+            }
+        }
+
+        // if install directory can't be found, use home as the default
+        if (home != null) {
+            System.getProperties().put(installSysProp, home);
+            return home;
+        }
+
+        return null;
+    }
+
+    /**
+     * Debug method, display the classpath
+     */
+    public static void displayClassPath(String msg, URL[] cp) {
+        if (log.isDebugEnabled()) {
+            log.debug(msg);
+            for (int i = 0; i < cp.length; i++) {
+                log.debug(cp[i].getFile());
+            }
+        }
+    }
+
+    public static String PATH_SEPARATOR = System.getProperty("path.separator");
+
+    /**
+     * Adds classpath entries from a vector of URL's to the "tc_path_add" System
+     * property. This System property lists the classpath entries common to web
+     * applications. This System property is currently used by Jasper when its
+     * JSP servlet compiles the Java file for a JSP.
+     */
+    public static String classPathAdd(URL urls[], String cp) {
+        if (urls == null)
+            return cp;
+
+        for (int i = 0; i < urls.length; i++) {
+            if (cp != null)
+                cp += PATH_SEPARATOR + urls[i].getFile();
+            else
+                cp = urls[i].getFile();
+        }
+        return cp;
+    }
+
+    /**
+     * Find a method with the right name If found, call the method ( if param is
+     * int or boolean we'll convert value to the right type before) - that means
+     * you can have setDebug(1).
+     */
+    public static boolean setProperty(Object o, String name, String value) {
+        if (dbg > 1)
+            d("setProperty(" + o.getClass() + " " + name + "=" + value + ")");
+
+        String setter = "set" + capitalize(name);
+
+        try {
+            Method methods[] = findMethods(o.getClass());
+            Method setPropertyMethodVoid = null;
+            Method setPropertyMethodBool = null;
+
+            // First, the ideal case - a setFoo( String ) method
+            for (int i = 0; i < methods.length; i++) {
+                Class paramT[] = methods[i].getParameterTypes();
+                if (setter.equals(methods[i].getName()) && paramT.length == 1
+                        && "java.lang.String".equals(paramT[0].getName())) {
+
+                    methods[i].invoke(o, new Object[] { value });
+                    return true;
+                }
+            }
+
+            // Try a setFoo ( int ) or ( boolean )
+            for (int i = 0; i < methods.length; i++) {
+                boolean ok = true;
+                if (setter.equals(methods[i].getName())
+                        && methods[i].getParameterTypes().length == 1) {
+
+                    // match - find the type and invoke it
+                    Class paramType = methods[i].getParameterTypes()[0];
+                    Object params[] = new Object[1];
+
+                    // Try a setFoo ( int )
+                    if ("java.lang.Integer".equals(paramType.getName())
+                            || "int".equals(paramType.getName())) {
+                        try {
+                            params[0] = new Integer(value);
+                        } catch (NumberFormatException ex) {
+                            ok = false;
+                        }
+                    // Try a setFoo ( long )
+                    }else if ("java.lang.Long".equals(paramType.getName())
+                                || "long".equals(paramType.getName())) {
+                            try {
+                                params[0] = new Long(value);
+                            } catch (NumberFormatException ex) {
+                                ok = false;
+                            }
+
+                        // Try a setFoo ( boolean )
+                    } else if ("java.lang.Boolean".equals(paramType.getName())
+                            || "boolean".equals(paramType.getName())) {
+                        params[0] = new Boolean(value);
+
+                        // Try a setFoo ( InetAddress )
+                    } else if ("java.net.InetAddress".equals(paramType
+                            .getName())) {
+                        try {
+                            params[0] = InetAddress.getByName(value);
+                        } catch (UnknownHostException exc) {
+                            d("Unable to resolve host name:" + value);
+                            ok = false;
+                        }
+
+                        // Unknown type
+                    } else {
+                        d("Unknown type " + paramType.getName());
+                    }
+
+                    if (ok) {
+                        methods[i].invoke(o, params);
+                        return true;
+                    }
+                }
+
+                // save "setProperty" for later
+                if ("setProperty".equals(methods[i].getName())) {
+                    if (methods[i].getReturnType()==Boolean.TYPE){
+                        setPropertyMethodBool = methods[i];
+                    }else {
+                        setPropertyMethodVoid = methods[i];    
+                    }
+                    
+                }
+            }
+
+            // Ok, no setXXX found, try a setProperty("name", "value")
+            if (setPropertyMethodBool != null || setPropertyMethodVoid != null) {
+                Object params[] = new Object[2];
+                params[0] = name;
+                params[1] = value;
+                if (setPropertyMethodBool != null) {
+                    try {
+                        return (Boolean) setPropertyMethodBool.invoke(o, params);
+                    }catch (IllegalArgumentException biae) {
+                        //the boolean method had the wrong
+                        //parameter types. lets try the other
+                        if (setPropertyMethodVoid!=null) {
+                            setPropertyMethodVoid.invoke(o, params);
+                            return true;
+                        }else {
+                            throw biae;
+                        }
+                    }
+                } else {
+                    setPropertyMethodVoid.invoke(o, params);
+                    return true;
+                }
+            }
+
+        } catch (IllegalArgumentException ex2) {
+            log.warn("IAE " + o + " " + name + " " + value, ex2);
+        } catch (SecurityException ex1) {
+            if (dbg > 0)
+                d("SecurityException for " + o.getClass() + " " + name + "="
+                        + value + ")");
+            if (dbg > 1)
+                ex1.printStackTrace();
+        } catch (IllegalAccessException iae) {
+            if (dbg > 0)
+                d("IllegalAccessException for " + o.getClass() + " " + name
+                        + "=" + value + ")");
+            if (dbg > 1)
+                iae.printStackTrace();
+        } catch (InvocationTargetException ie) {
+            if (dbg > 0)
+                d("InvocationTargetException for " + o.getClass() + " " + name
+                        + "=" + value + ")");
+            if (dbg > 1)
+                ie.printStackTrace();
+        }
+        return false;
+    }
+
+    public static Object getProperty(Object o, String name) {
+        String getter = "get" + capitalize(name);
+        String isGetter = "is" + capitalize(name);
+
+        try {
+            Method methods[] = findMethods(o.getClass());
+            Method getPropertyMethod = null;
+
+            // First, the ideal case - a getFoo() method
+            for (int i = 0; i < methods.length; i++) {
+                Class paramT[] = methods[i].getParameterTypes();
+                if (getter.equals(methods[i].getName()) && paramT.length == 0) {
+                    return methods[i].invoke(o, (Object[]) null);
+                }
+                if (isGetter.equals(methods[i].getName()) && paramT.length == 0) {
+                    return methods[i].invoke(o, (Object[]) null);
+                }
+
+                if ("getProperty".equals(methods[i].getName())) {
+                    getPropertyMethod = methods[i];
+                }
+            }
+
+            // Ok, no setXXX found, try a getProperty("name")
+            if (getPropertyMethod != null) {
+                Object params[] = new Object[1];
+                params[0] = name;
+                return getPropertyMethod.invoke(o, params);
+            }
+
+        } catch (IllegalArgumentException ex2) {
+            log.warn("IAE " + o + " " + name, ex2);
+        } catch (SecurityException ex1) {
+            if (dbg > 0)
+                d("SecurityException for " + o.getClass() + " " + name + ")");
+            if (dbg > 1)
+                ex1.printStackTrace();
+        } catch (IllegalAccessException iae) {
+            if (dbg > 0)
+                d("IllegalAccessException for " + o.getClass() + " " + name
+                        + ")");
+            if (dbg > 1)
+                iae.printStackTrace();
+        } catch (InvocationTargetException ie) {
+            if (dbg > 0)
+                d("InvocationTargetException for " + o.getClass() + " " + name
+                        + ")");
+            if (dbg > 1)
+                ie.printStackTrace();
+        }
+        return null;
+    }
+
+    /** 
+     */
+    public static void setProperty(Object o, String name) {
+        String setter = "set" + capitalize(name);
+        try {
+            Method methods[] = findMethods(o.getClass());
+            Method setPropertyMethod = null;
+            // find setFoo() method
+            for (int i = 0; i < methods.length; i++) {
+                Class paramT[] = methods[i].getParameterTypes();
+                if (setter.equals(methods[i].getName()) && paramT.length == 0) {
+                    methods[i].invoke(o, new Object[] {});
+                    return;
+                }
+            }
+        } catch (Exception ex1) {
+            if (dbg > 0)
+                d("Exception for " + o.getClass() + " " + name);
+            if (dbg > 1)
+                ex1.printStackTrace();
+        }
+    }
+
+    /**
+     * Replace ${NAME} with the property value
+     * 
+     * @deprecated Use the explicit method
+     */
+    public static String replaceProperties(String value, Object getter) {
+        if (getter instanceof Hashtable)
+            return replaceProperties(value, (Hashtable) getter, null);
+
+        if (getter instanceof PropertySource) {
+            PropertySource src[] = new PropertySource[] { (PropertySource) getter };
+            return replaceProperties(value, null, src);
+        }
+        return value;
+    }
+
+    /**
+     * Replace ${NAME} with the property value
+     */
+    public static String replaceProperties(String value, Hashtable staticProp,
+            PropertySource dynamicProp[]) {
+        StringBuffer sb = new StringBuffer();
+        int prev = 0;
+        // assert value!=nil
+        int pos;
+        while ((pos = value.indexOf("$", prev)) >= 0) {
+            if (pos > 0) {
+                sb.append(value.substring(prev, pos));
+            }
+            if (pos == (value.length() - 1)) {
+                sb.append('$');
+                prev = pos + 1;
+            } else if (value.charAt(pos + 1) != '{') {
+                sb.append('$');
+                prev = pos + 1; // XXX
+            } else {
+                int endName = value.indexOf('}', pos);
+                if (endName < 0) {
+                    sb.append(value.substring(pos));
+                    prev = value.length();
+                    continue;
+                }
+                String n = value.substring(pos + 2, endName);
+                String v = null;
+                if (staticProp != null) {
+                    v = (String) ((Hashtable) staticProp).get(n);
+                }
+                if (v == null && dynamicProp != null) {
+                    for (int i = 0; i < dynamicProp.length; i++) {
+                        v = dynamicProp[i].getProperty(n);
+                        if (v != null) {
+                            break;
+                        }
+                    }
+                }
+                if (v == null)
+                    v = "${" + n + "}";
+
+                sb.append(v);
+                prev = endName + 1;
+            }
+        }
+        if (prev < value.length())
+            sb.append(value.substring(prev));
+        return sb.toString();
+    }
+
+    /**
+     * Reverse of Introspector.decapitalize
+     */
+    public static String capitalize(String name) {
+        if (name == null || name.length() == 0) {
+            return name;
+        }
+        char chars[] = name.toCharArray();
+        chars[0] = Character.toUpperCase(chars[0]);
+        return new String(chars);
+    }
+
+    public static String unCapitalize(String name) {
+        if (name == null || name.length() == 0) {
+            return name;
+        }
+        char chars[] = name.toCharArray();
+        chars[0] = Character.toLowerCase(chars[0]);
+        return new String(chars);
+    }
+
+    // -------------------- Class path tools --------------------
+
+    /**
+     * Add all the jar files in a dir to the classpath, represented as a Vector
+     * of URLs.
+     */
+    public static void addToClassPath(Vector cpV, String dir) {
+        try {
+            String cpComp[] = getFilesByExt(dir, ".jar");
+            if (cpComp != null) {
+                int jarCount = cpComp.length;
+                for (int i = 0; i < jarCount; i++) {
+                    URL url = getURL(dir, cpComp[i]);
+                    if (url != null)
+                        cpV.addElement(url);
+                }
+            }
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        }
+    }
+
+    public static void addToolsJar(Vector v) {
+        try {
+            // Add tools.jar in any case
+            File f = new File(System.getProperty("java.home")
+                    + "/../lib/tools.jar");
+
+            if (!f.exists()) {
+                // On some systems java.home gets set to the root of jdk.
+                // That's a bug, but we can work around and be nice.
+                f = new File(System.getProperty("java.home") + "/lib/tools.jar");
+                if (f.exists()) {
+                    if (log.isDebugEnabled())
+                        log.debug("Detected strange java.home value "
+                            + System.getProperty("java.home")
+                            + ", it should point to jre");
+                }
+            }
+            URL url = new URL("file", "", f.getAbsolutePath());
+
+            v.addElement(url);
+        } catch (MalformedURLException ex) {
+            ex.printStackTrace();
+        }
+    }
+
+    /**
+     * Return all files with a given extension in a dir
+     */
+    public static String[] getFilesByExt(String ld, String ext) {
+        File dir = new File(ld);
+        String[] names = null;
+        final String lext = ext;
+        if (dir.isDirectory()) {
+            names = dir.list(new FilenameFilter() {
+                public boolean accept(File d, String name) {
+                    if (name.endsWith(lext)) {
+                        return true;
+                    }
+                    return false;
+                }
+            });
+        }
+        return names;
+    }
+
+    /**
+     * Construct a file url from a file, using a base dir
+     */
+    public static URL getURL(String base, String file) {
+        try {
+            File baseF = new File(base);
+            File f = new File(baseF, file);
+            String path = f.getCanonicalPath();
+            if (f.isDirectory()) {
+                path += "/";
+            }
+            if (!f.exists())
+                return null;
+            return new URL("file", "", path);
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * Add elements from the classpath <i>cp </i> to a Vector <i>jars </i> as
+     * file URLs (We use Vector for JDK 1.1 compat).
+     * <p>
+     * 
+     * @param jars The jar list
+     * @param cp a String classpath of directory or jar file elements
+     *   separated by path.separator delimiters.
+     * @throws IOException If an I/O error occurs
+     * @throws MalformedURLException Doh ;)
+     */
+    public static void addJarsFromClassPath(Vector jars, String cp)
+            throws IOException, MalformedURLException {
+        String sep = System.getProperty("path.separator");
+        String token;
+        StringTokenizer st;
+        if (cp != null) {
+            st = new StringTokenizer(cp, sep);
+            while (st.hasMoreTokens()) {
+                File f = new File(st.nextToken());
+                String path = f.getCanonicalPath();
+                if (f.isDirectory()) {
+                    path += "/";
+                }
+                URL url = new URL("file", "", path);
+                if (!jars.contains(url)) {
+                    jars.addElement(url);
+                }
+            }
+        }
+    }
+
+    /**
+     * Return a URL[] that can be used to construct a class loader
+     */
+    public static URL[] getClassPath(Vector v) {
+        URL[] urls = new URL[v.size()];
+        for (int i = 0; i < v.size(); i++) {
+            urls[i] = (URL) v.elementAt(i);
+        }
+        return urls;
+    }
+
+    /**
+     * Construct a URL classpath from files in a directory, a cpath property,
+     * and tools.jar.
+     */
+    public static URL[] getClassPath(String dir, String cpath,
+            String cpathProp, boolean addTools) throws IOException,
+            MalformedURLException {
+        Vector jarsV = new Vector();
+        if (dir != null) {
+            // Add dir/classes first, if it exists
+            URL url = getURL(dir, "classes");
+            if (url != null)
+                jarsV.addElement(url);
+            addToClassPath(jarsV, dir);
+        }
+
+        if (cpath != null)
+            addJarsFromClassPath(jarsV, cpath);
+
+        if (cpathProp != null) {
+            String cpath1 = System.getProperty(cpathProp);
+            addJarsFromClassPath(jarsV, cpath1);
+        }
+
+        if (addTools)
+            addToolsJar(jarsV);
+
+        return getClassPath(jarsV);
+    }
+
+    // -------------------- Mapping command line params to setters
+
+    public static boolean processArgs(Object proxy, String args[])
+            throws Exception {
+        String args0[] = null;
+        if (null != findMethod(proxy.getClass(), "getOptions1", new Class[] {})) {
+            args0 = (String[]) callMethod0(proxy, "getOptions1");
+        }
+
+        if (args0 == null) {
+            //args0=findVoidSetters(proxy.getClass());
+            args0 = findBooleanSetters(proxy.getClass());
+        }
+        Hashtable h = null;
+        if (null != findMethod(proxy.getClass(), "getOptionAliases",
+                new Class[] {})) {
+            h = (Hashtable) callMethod0(proxy, "getOptionAliases");
+        }
+        return processArgs(proxy, args, args0, null, h);
+    }
+
+    public static boolean processArgs(Object proxy, String args[],
+            String args0[], String args1[], Hashtable aliases) throws Exception {
+        for (int i = 0; i < args.length; i++) {
+            String arg = args[i];
+            if (arg.startsWith("-"))
+                arg = arg.substring(1);
+            if (aliases != null && aliases.get(arg) != null)
+                arg = (String) aliases.get(arg);
+
+            if (args0 != null) {
+                boolean set = false;
+                for (int j = 0; j < args0.length; j++) {
+                    if (args0[j].equalsIgnoreCase(arg)) {
+                        setProperty(proxy, args0[j], "true");
+                        set = true;
+                        break;
+                    }
+                }
+                if (set)
+                    continue;
+            }
+            if (args1 != null) {
+                for (int j = 0; j < args1.length; j++) {
+                    if (args1[j].equalsIgnoreCase(arg)) {
+                        i++;
+                        if (i >= args.length)
+                            return false;
+                        setProperty(proxy, arg, args[i]);
+                        break;
+                    }
+                }
+            } else {
+                // if args1 is not specified,assume all other options have param
+                i++;
+                if (i >= args.length)
+                    return false;
+                setProperty(proxy, arg, args[i]);
+            }
+
+        }
+        return true;
+    }
+
+    // -------------------- other utils --------------------
+    public static void clear() {
+        objectMethods.clear();
+    }
+    
+    public static String[] findVoidSetters(Class c) {
+        Method m[] = findMethods(c);
+        if (m == null)
+            return null;
+        Vector v = new Vector();
+        for (int i = 0; i < m.length; i++) {
+            if (m[i].getName().startsWith("set")
+                    && m[i].getParameterTypes().length == 0) {
+                String arg = m[i].getName().substring(3);
+                v.addElement(unCapitalize(arg));
+            }
+        }
+        String s[] = new String[v.size()];
+        for (int i = 0; i < s.length; i++) {
+            s[i] = (String) v.elementAt(i);
+        }
+        return s;
+    }
+
+    public static String[] findBooleanSetters(Class c) {
+        Method m[] = findMethods(c);
+        if (m == null)
+            return null;
+        Vector v = new Vector();
+        for (int i = 0; i < m.length; i++) {
+            if (m[i].getName().startsWith("set")
+                    && m[i].getParameterTypes().length == 1
+                    && "boolean".equalsIgnoreCase(m[i].getParameterTypes()[0]
+                            .getName())) {
+                String arg = m[i].getName().substring(3);
+                v.addElement(unCapitalize(arg));
+            }
+        }
+        String s[] = new String[v.size()];
+        for (int i = 0; i < s.length; i++) {
+            s[i] = (String) v.elementAt(i);
+        }
+        return s;
+    }
+
+    static Hashtable objectMethods = new Hashtable();
+
+    public static Method[] findMethods(Class c) {
+        Method methods[] = (Method[]) objectMethods.get(c);
+        if (methods != null)
+            return methods;
+
+        methods = c.getMethods();
+        objectMethods.put(c, methods);
+        return methods;
+    }
+
+    public static Method findMethod(Class c, String name, Class params[]) {
+        Method methods[] = findMethods(c);
+        if (methods == null)
+            return null;
+        for (int i = 0; i < methods.length; i++) {
+            if (methods[i].getName().equals(name)) {
+                Class methodParams[] = methods[i].getParameterTypes();
+                if (methodParams == null)
+                    if (params == null || params.length == 0)
+                        return methods[i];
+                if (params == null)
+                    if (methodParams == null || methodParams.length == 0)
+                        return methods[i];
+                if (params.length != methodParams.length)
+                    continue;
+                boolean found = true;
+                for (int j = 0; j < params.length; j++) {
+                    if (params[j] != methodParams[j]) {
+                        found = false;
+                        break;
+                    }
+                }
+                if (found)
+                    return methods[i];
+            }
+        }
+        return null;
+    }
+
+    /** Test if the object implements a particular
+     *  method
+     */
+    public static boolean hasHook(Object obj, String methodN) {
+        try {
+            Method myMethods[] = findMethods(obj.getClass());
+            for (int i = 0; i < myMethods.length; i++) {
+                if (methodN.equals(myMethods[i].getName())) {
+                    // check if it's overriden
+                    Class declaring = myMethods[i].getDeclaringClass();
+                    Class parentOfDeclaring = declaring.getSuperclass();
+                    // this works only if the base class doesn't extend
+                    // another class.
+
+                    // if the method is declared in a top level class
+                    // like BaseInterceptor parent is Object, otherwise
+                    // parent is BaseInterceptor or an intermediate class
+                    if (!"java.lang.Object".equals(parentOfDeclaring.getName())) {
+                        return true;
+                    }
+                }
+            }
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        }
+        return false;
+    }
+
+    public static void callMain(Class c, String args[]) throws Exception {
+        Class p[] = new Class[1];
+        p[0] = args.getClass();
+        Method m = c.getMethod("main", p);
+        m.invoke(c, new Object[] { args });
+    }
+
+    public static Object callMethod1(Object target, String methodN,
+            Object param1, String typeParam1, ClassLoader cl) throws Exception {
+        if (target == null || param1 == null) {
+            d("Assert: Illegal params " + target + " " + param1);
+        }
+        if (dbg > 0)
+            d("callMethod1 " + target.getClass().getName() + " "
+                    + param1.getClass().getName() + " " + typeParam1);
+
+        Class params[] = new Class[1];
+        if (typeParam1 == null)
+            params[0] = param1.getClass();
+        else
+            params[0] = cl.loadClass(typeParam1);
+        Method m = findMethod(target.getClass(), methodN, params);
+        if (m == null)
+            throw new NoSuchMethodException(target.getClass().getName() + " "
+                    + methodN);
+        return m.invoke(target, new Object[] { param1 });
+    }
+
+    public static Object callMethod0(Object target, String methodN)
+            throws Exception {
+        if (target == null) {
+            d("Assert: Illegal params " + target);
+            return null;
+        }
+        if (dbg > 0)
+            d("callMethod0 " + target.getClass().getName() + "." + methodN);
+
+        Class params[] = new Class[0];
+        Method m = findMethod(target.getClass(), methodN, params);
+        if (m == null)
+            throw new NoSuchMethodException(target.getClass().getName() + " "
+                    + methodN);
+        return m.invoke(target, emptyArray);
+    }
+
+    static Object[] emptyArray = new Object[] {};
+
+    public static Object callMethodN(Object target, String methodN,
+            Object params[], Class typeParams[]) throws Exception {
+        Method m = null;
+        m = findMethod(target.getClass(), methodN, typeParams);
+        if (m == null) {
+            d("Can't find method " + methodN + " in " + target + " CLASS "
+                    + target.getClass());
+            return null;
+        }
+        Object o = m.invoke(target, params);
+
+        if (dbg > 0) {
+            // debug
+            StringBuffer sb = new StringBuffer();
+            sb.append("" + target.getClass().getName() + "." + methodN + "( ");
+            for (int i = 0; i < params.length; i++) {
+                if (i > 0)
+                    sb.append(", ");
+                sb.append(params[i]);
+            }
+            sb.append(")");
+            d(sb.toString());
+        }
+        return o;
+    }
+
+    public static Object convert(String object, Class paramType) {
+        Object result = null;
+        if ("java.lang.String".equals(paramType.getName())) {
+            result = object;
+        } else if ("java.lang.Integer".equals(paramType.getName())
+                || "int".equals(paramType.getName())) {
+            try {
+                result = new Integer(object);
+            } catch (NumberFormatException ex) {
+            }
+            // Try a setFoo ( boolean )
+        } else if ("java.lang.Boolean".equals(paramType.getName())
+                || "boolean".equals(paramType.getName())) {
+            result = new Boolean(object);
+
+            // Try a setFoo ( InetAddress )
+        } else if ("java.net.InetAddress".equals(paramType
+                .getName())) {
+            try {
+                result = InetAddress.getByName(object);
+            } catch (UnknownHostException exc) {
+                d("Unable to resolve host name:" + object);
+            }
+
+            // Unknown type
+        } else {
+            d("Unknown type " + paramType.getName());
+        }
+        if (result == null) {
+            throw new IllegalArgumentException("Can't convert argument: " + object);
+        }
+        return result;
+    }
+    
+    // -------------------- Get property --------------------
+    // This provides a layer of abstraction
+
+    public static interface PropertySource {
+
+        public String getProperty(String key);
+
+    }
+
+    public static interface AttributeHolder {
+
+        public void setAttribute(String key, Object o);
+
+    }
+
+    // debug --------------------
+    static final int dbg = 0;
+
+    static void d(String s) {
+        if (log.isDebugEnabled())
+            log.debug("IntrospectionUtils: " + s);
+    }
+}

Added: tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/MutableInteger.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/MutableInteger.java?rev=640706&view=auto
==============================================================================
--- tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/MutableInteger.java (added)
+++ tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/MutableInteger.java Mon Mar 24 23:01:43 2008
@@ -0,0 +1,29 @@
+/*
+ *  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.tomcat.util;
+
+public class MutableInteger {
+    protected int value = 0;
+    public MutableInteger() {}
+    public MutableInteger(int val) {
+        this.value = val;
+    }
+
+    public int get() { return value;}
+    public void set(int val) {this.value = val;}
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org