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}