📄 reflectionutils.java
字号:
/* * Copyright 2004,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.bsf.util;import java.beans.BeanInfo;import java.beans.Beans;import java.beans.EventSetDescriptor;import java.beans.FeatureDescriptor;import java.beans.IndexedPropertyDescriptor;import java.beans.IntrospectionException;import java.beans.Introspector;import java.beans.PropertyDescriptor;import java.io.IOException;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import org.apache.bsf.util.event.EventAdapter;import org.apache.bsf.util.event.EventAdapterRegistry;import org.apache.bsf.util.event.EventProcessor;import org.apache.bsf.util.type.TypeConvertor;import org.apache.bsf.util.type.TypeConvertorRegistry;/** * This file is a collection of reflection utilities. There are utilities * for creating beans, getting bean infos, setting/getting properties, * and binding events. * * @author Sanjiva Weerawarana * @author Joseph Kesselman */public class ReflectionUtils { ////////////////////////////////////////////////////////////////////////// /** * Add an event processor as a listener to some event coming out of an * object. * * @param source event source * @param eventSetName name of event set from event src to bind to * @param processor event processor the event should be delegated to * when it occurs; either via processEvent or * processExceptionableEvent. * * @exception IntrospectionException if unable to introspect * @exception IllegalArgumentException if event set is unknown * @exception IllegalAccessException if the event adapter class or * initializer is not accessible. * @exception InstantiationException if event adapter instantiation fails * @exception InvocationTargetException if something goes wrong while * running add event listener method */ public static void addEventListener (Object source, String eventSetName, EventProcessor processor) throws IntrospectionException, IllegalArgumentException, IllegalAccessException, InstantiationException, InvocationTargetException { // find the event set descriptor for this event BeanInfo bi = Introspector.getBeanInfo (source.getClass ()); EventSetDescriptor esd = (EventSetDescriptor) findFeatureByName ("event", eventSetName, bi.getEventSetDescriptors ()); if (esd == null) // no events found, maybe a proxy from OpenOffice.org? { throw new IllegalArgumentException ("event set '" + eventSetName + "' unknown for source type '" + source.getClass () + "'"); } // get the class object for the event Class listenerType=esd.getListenerType(); // get ListenerType class object from EventSetDescriptor // find an event adapter class of the right type Class adapterClass = EventAdapterRegistry.lookup (listenerType); if (adapterClass == null) { throw new IllegalArgumentException ("event adapter for listener type " + "'" + listenerType + "' (eventset " + "'" + eventSetName + "') unknown"); } // create the event adapter and give it the event processor EventAdapter adapter = (EventAdapter) adapterClass.newInstance (); adapter.setEventProcessor (processor); // bind the adapter to the source bean Method addListenerMethod; Object[] args; if (eventSetName.equals ("propertyChange") || eventSetName.equals ("vetoableChange")) { // In Java 1.2, beans may have direct listener adding methods // for property and vetoable change events which take the // property name as a filter to be applied at the event source. // The filter property of the event processor should be used // in this case to support the source-side filtering. // // ** TBD **: the following two lines need to change appropriately addListenerMethod = esd.getAddListenerMethod (); args = new Object[] {adapter}; } else { addListenerMethod = esd.getAddListenerMethod (); args = new Object[] {adapter}; } addListenerMethod.invoke (source, args); } ////////////////////////////////////////////////////////////////////////// /** * Create a bean using given class loader and using the appropriate * constructor for the given args of the given arg types. * @param cld the class loader to use. If null, Class.forName is used. * @param className name of class to instantiate * @param argTypes array of argument types * @param args array of arguments * * @return the newly created bean * * @exception ClassNotFoundException if class is not loaded * @exception NoSuchMethodException if constructor can't be found * @exception InstantiationException if class can't be instantiated * @exception IllegalAccessException if class is not accessible * @exception IllegalArgumentException if argument problem * @exception InvocationTargetException if constructor excepted * @exception IOException if I/O error in beans.instantiate */ public static Bean createBean (ClassLoader cld, String className, Class[] argTypes, Object[] args) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException { if (argTypes != null) { // find the right constructor and use that to create bean Class cl = (cld != null) ? cld.loadClass (className) : Thread.currentThread().getContextClassLoader().loadClass (className); // rgf, 2006-01-05 // : Class.forName (className); Constructor c = MethodUtils.getConstructor (cl, argTypes); return new Bean (cl, c.newInstance (args)); } else { // create the bean with no args constructor Object obj = Beans.instantiate (cld, className); return new Bean (obj.getClass (), obj); } } ////////////////////////////////////////////////////////////////////////// /** * Create a bean using given class loader and using the appropriate * constructor for the given args. Figures out the arg types and * calls above. * @param cld the class loader to use. If null, Class.forName is used. * @param className name of class to instantiate * @param args array of arguments * * @return the newly created bean * * @exception ClassNotFoundException if class is not loaded * @exception NoSuchMethodException if constructor can't be found * @exception InstantiationException if class can't be instantiated * @exception IllegalAccessException if class is not accessible * @exception IllegalArgumentException if argument problem * @exception InvocationTargetException if constructor excepted * @exception IOException if I/O error in beans.instantiate */ public static Bean createBean (ClassLoader cld, String className, Object[] args) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException { Class[] argTypes = null; if (args != null) { argTypes = new Class[args.length]; for (int i = 0; i < args.length; i++) { argTypes[i] = (args[i] != null) ? args[i].getClass () : null; } } return createBean (cld, className, argTypes, args); } ////////////////////////////////////////////////////////////////////////// /** * locate the item in the fds array whose name is as given. returns * null if not found. */ private static FeatureDescriptor findFeatureByName (String featureType, String name, FeatureDescriptor[] fds) { for (int i = 0; i < fds.length; i++) { if (name.equals (fds[i].getName())) { return fds[i];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -