org.apache.tomcat.util.IntrospectionUtils Maven / Gradle / Ivy
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* 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.tomcat.util;
import java.lang.reflect.*;
import java.net.*;
import java.io.*;
import java.util.*;
// Depends: JDK1.1
/**
* Utils for introspection and reflection
*/
public final class IntrospectionUtils {
private static com.sun.org.apache.commons.logging.Log log=
com.sun.org.apache.commons.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 ) {
d("No setAttribute in " + proxy.getClass() );
return;
}
if( false )
d("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 ) {
d("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 ) {
d(msg);
for( int i=0; i 1 ) d("setProperty(" +
o.getClass() + " " + name + "=" +
value +")" );
String setter= "set" +capitalize(name);
try {
Method methods[]=findMethods( o.getClass() );
Method setPropertyMethod=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;
}
}
// 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]= Integer.valueOf(value);
} catch( NumberFormatException ex ) {ok=false;}
// Try a setFoo ( boolean )
} else if ("java.lang.Boolean".
equals( paramType.getName()) ||
"boolean".equals( paramType.getName())) {
params[0] = Boolean.valueOf(value);
// Try a setFoo ( long )
} else if ("java.lang.Long".equals( paramType.getName()) ||
"long".equals( paramType.getName())) {
try {
params[0]= Long.valueOf(value);
} catch( NumberFormatException ex ) {ok=false;}
} 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;
}
}
// save "setProperty" for later
if( "setProperty".equals( methods[i].getName())) {
setPropertyMethod=methods[i];
}
}
// Ok, no setXXX found, try a setProperty("name", "value")
if( setPropertyMethod != null ) {
Object params[]=new Object[2];
params[0]=name;
params[1]=value;
setPropertyMethod.invoke( o, params );
}
} 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();
}
}
public static Object getProperty( Object o, String name ) {
String getter= "get" +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( "getProperty".equals( methods[i].getName())) {
getPropertyMethod=methods[i];
}
if( "getAttribute".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;
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( value.charAt( pos + 1 ) );
prev=pos+2; // 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; icp to a Vector
* jars as file URLs (We use Vector for JDK 1.1 compat).
*
* @param cp a String classpath of directory or jar file
* elements separated by path.separator delimiters.
* @return a Vector of URLs.
*/
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= 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 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; i0) sb.append( ", ");
sb.append(params[i]);
}
sb.append(")");
d(sb.toString());
}
return o;
}
// -------------------- 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 );
}
}