001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.log4j.config; 019 020import org.apache.log4j.Priority; 021import org.apache.log4j.helpers.LogLog; 022 023import java.beans.BeanInfo; 024import java.beans.IntrospectionException; 025import java.beans.Introspector; 026import java.beans.PropertyDescriptor; 027import java.io.InterruptedIOException; 028import java.lang.reflect.InvocationTargetException; 029import java.lang.reflect.Method; 030 031 032/** 033 Used for inferring configuration information for a log4j's component. 034 035 @author Anders Kristensen 036 */ 037public class PropertyGetter { 038 protected static final Object[] NULL_ARG = new Object[] {}; 039 protected Object obj; 040 protected PropertyDescriptor[] props; 041 042 public interface PropertyCallback { 043 void foundProperty(Object obj, String prefix, String name, Object value); 044 } 045 046 /** 047 Create a new PropertyGetter for the specified Object. This is done 048 in prepartion for invoking {@link 049 #getProperties(PropertyGetter.PropertyCallback, String)} one or 050 more times. 051 052 @param obj the object for which to set properties */ 053 public 054 PropertyGetter(Object obj) throws IntrospectionException { 055 BeanInfo bi = Introspector.getBeanInfo(obj.getClass()); 056 props = bi.getPropertyDescriptors(); 057 this.obj = obj; 058 } 059 060 public 061 static 062 void getProperties(Object obj, PropertyCallback callback, String prefix) { 063 try { 064 new PropertyGetter(obj).getProperties(callback, prefix); 065 } catch (IntrospectionException ex) { 066 LogLog.error("Failed to introspect object " + obj, ex); 067 } 068 } 069 070 public 071 void getProperties(PropertyCallback callback, String prefix) { 072 for (int i = 0; i < props.length; i++) { 073 Method getter = props[i].getReadMethod(); 074 if (getter == null) continue; 075 if (!isHandledType(getter.getReturnType())) { 076 //System.err.println("Ignoring " + props[i].getName() +" " + getter.getReturnType()); 077 continue; 078 } 079 String name = props[i].getName(); 080 try { 081 Object result = getter.invoke(obj, NULL_ARG); 082 //System.err.println("PROP " + name +": " + result); 083 if (result != null) { 084 callback.foundProperty(obj, prefix, name, result); 085 } 086 } catch (IllegalAccessException ex) { 087 LogLog.warn("Failed to get value of property " + name); 088 } catch (InvocationTargetException ex) { 089 if (ex.getTargetException() instanceof InterruptedException 090 || ex.getTargetException() instanceof InterruptedIOException) { 091 Thread.currentThread().interrupt(); 092 } 093 LogLog.warn("Failed to get value of property " + name); 094 } catch (RuntimeException ex) { 095 LogLog.warn("Failed to get value of property " + name); 096 } 097 } 098 } 099 100 protected 101 boolean isHandledType(Class type) { 102 return String.class.isAssignableFrom(type) || 103 Integer.TYPE.isAssignableFrom(type) || 104 Long.TYPE.isAssignableFrom(type) || 105 Boolean.TYPE.isAssignableFrom(type) || 106 Priority.class.isAssignableFrom(type); 107 } 108}