You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by oh...@apache.org on 2012/12/02 22:18:14 UTC

svn commit: r1416264 - in /commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder: BasicBuilderParametersBeanInfo.java BuilderParametersBeanInfo.java FileBasedBuilderParametersBeanInfo.java

Author: oheger
Date: Sun Dec  2 21:18:13 2012
New Revision: 1416264

URL: http://svn.apache.org/viewvc?rev=1416264&view=rev
Log:
Provided extended bean info for builder parameter classes.

Added:
    commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/BasicBuilderParametersBeanInfo.java   (with props)
    commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/BuilderParametersBeanInfo.java   (with props)
    commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/FileBasedBuilderParametersBeanInfo.java   (with props)

Added: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/BasicBuilderParametersBeanInfo.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/BasicBuilderParametersBeanInfo.java?rev=1416264&view=auto
==============================================================================
--- commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/BasicBuilderParametersBeanInfo.java (added)
+++ commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/BasicBuilderParametersBeanInfo.java Sun Dec  2 21:18:13 2012
@@ -0,0 +1,34 @@
+/*
+ * 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.commons.configuration.builder;
+
+/**
+ * An additional {@code BeanInfo} class for {@link BasicBuilderParameters}.
+ *
+ * @version $Id$
+ * @since 2.0
+ */
+public class BasicBuilderParametersBeanInfo extends BuilderParametersBeanInfo
+{
+    /**
+     * Creates a new instance of {@code BasicBuilderParametersBeanInfo}.
+     */
+    public BasicBuilderParametersBeanInfo()
+    {
+        super(BasicBuilderParameters.class);
+    }
+}

Propchange: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/BasicBuilderParametersBeanInfo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/BasicBuilderParametersBeanInfo.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/BasicBuilderParametersBeanInfo.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/BuilderParametersBeanInfo.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/BuilderParametersBeanInfo.java?rev=1416264&view=auto
==============================================================================
--- commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/BuilderParametersBeanInfo.java (added)
+++ commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/BuilderParametersBeanInfo.java Sun Dec  2 21:18:13 2012
@@ -0,0 +1,219 @@
+/*
+ * 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.commons.configuration.builder;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.beans.SimpleBeanInfo;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Locale;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * <p>
+ * A base class for providing additional {@code BeanInfo} information for
+ * parameter classes for {@link BasicConfigurationBuilder}.
+ * </p>
+ * <p>
+ * Because parameter classes typically use a fluent API their properties are not
+ * detected by standard introspection mechanisms. To make them available to
+ * <em>Commons BeanUtils</em> (which is used to process bean declarations), the
+ * properties have to be explicitly listed in custom property descriptors. This
+ * base class provides functionality to do this.
+ * </p>
+ * <p>
+ * An instance of this class is passed the class of the associated bean at
+ * construction time. It then obtains all properties of the bean class using
+ * standard introspection. In a second step, all methods starting with the
+ * prefix {@code set} are searched. Such methods are typically used to set
+ * properties in fluent API style. If a method is found whose name is not
+ * contained in the list of properties, it is added as an additional property.
+ * </p>
+ *
+ * @version $Id$
+ * @since 2.0
+ */
+public abstract class BuilderParametersBeanInfo extends SimpleBeanInfo
+{
+    /** Constant for the prefix for set methods. */
+    private static final String PREFIX_SET_METHOD = "set";
+
+    /** The logger. */
+    private static final Log LOG = LogFactory
+            .getLog(BuilderParametersBeanInfo.class);
+
+    /** The property descriptors supported by the associated bean. */
+    private final PropertyDescriptor[] propertyDescriptors;
+
+    /** An array with additional BeanInfo objects. */
+    private final BeanInfo[] additionalBeanInfo;
+
+    /**
+     * Creates a new instance of {@code BuilderParametersBeanInfo} and
+     * initializes it from the specified bean class.
+     *
+     * @param beanClass the associated bean class
+     */
+    protected BuilderParametersBeanInfo(Class<?> beanClass)
+    {
+        LOG.info("Initializing BeanInfo for " + beanClass);
+        BeanInfo stdInfo = obtainStandardBeanInfo(beanClass);
+        if (stdInfo != null)
+        {
+            additionalBeanInfo = new BeanInfo[1];
+            additionalBeanInfo[0] = stdInfo;
+        }
+        else
+        {
+            additionalBeanInfo = null;
+        }
+        propertyDescriptors = extractPropertyDescriptors(beanClass, stdInfo);
+    }
+
+    @Override
+    public BeanInfo[] getAdditionalBeanInfo()
+    {
+        return additionalBeanInfo;
+    }
+
+    @Override
+    public PropertyDescriptor[] getPropertyDescriptors()
+    {
+        return propertyDescriptors;
+    }
+
+    /**
+     * Performs standard introspection on the specified bean class.
+     *
+     * @param beanClass the bean class in question
+     * @return the {@code BeanInfo} for this bean class (<b>null</b> if an error
+     *         occurs)
+     */
+    private static BeanInfo obtainStandardBeanInfo(Class<?> beanClass)
+    {
+        try
+        {
+            return Introspector.getBeanInfo(beanClass,
+                    Introspector.IGNORE_IMMEDIATE_BEANINFO);
+        }
+        catch (IntrospectionException e)
+        {
+            return null;
+        }
+    }
+
+    /**
+     * Determines all property descriptors for fluent API properties which are
+     * not detected by standard bean introspection.
+     *
+     * @param beanClass the bean class to be processed
+     * @param stdBeanInfo the {@code BeanInfo} obtained by standard bean
+     *        introspection
+     * @return an array with property descriptors for the properties discovered
+     */
+    private static PropertyDescriptor[] extractPropertyDescriptors(
+            Class<?> beanClass, BeanInfo stdBeanInfo)
+    {
+        Set<String> propertyNames = fetchPropertyNames(stdBeanInfo);
+        Collection<PropertyDescriptor> descriptors =
+                new LinkedList<PropertyDescriptor>();
+
+        for (Method m : beanClass.getMethods())
+        {
+            if (m.getName().startsWith(PREFIX_SET_METHOD))
+            {
+                String propertyName = propertyName(m);
+                if (!propertyNames.contains(propertyName))
+                {
+                    try
+                    {
+                        descriptors.add(createFluentPropertyDescritor(m,
+                                propertyName));
+                    }
+                    catch (IntrospectionException e)
+                    {
+                        LOG.warn("Error when creating PropertyDescriptor for "
+                                + m + "! Ignoring this property.", e);
+                    }
+                }
+            }
+        }
+
+        return descriptors.toArray(new PropertyDescriptor[descriptors.size()]);
+    }
+
+    /**
+     * Obtains the names of all properties from the given {@code BeanInfo}
+     * object.
+     *
+     * @param info the {@code BeanInfo} (may be <b>null</b>)
+     * @return a set with all property names
+     */
+    private static Set<String> fetchPropertyNames(BeanInfo info)
+    {
+        Set<String> propertyNames = new HashSet<String>();
+        if (info != null)
+        {
+            PropertyDescriptor[] descs = info.getPropertyDescriptors();
+            if (descs != null)
+            {
+                for (PropertyDescriptor pd : descs)
+                {
+                    propertyNames.add(pd.getName());
+                }
+            }
+        }
+
+        return propertyNames;
+    }
+
+    /**
+     * Creates a property descriptor for a fluent API property.
+     *
+     * @param m the set method for the fluent API property
+     * @param propertyName the name of the corresponding property
+     * @return the descriptor
+     * @throws IntrospectionException if an error occurs
+     */
+    private static PropertyDescriptor createFluentPropertyDescritor(Method m,
+            String propertyName) throws IntrospectionException
+    {
+        return new PropertyDescriptor(propertyName(m), null, m);
+    }
+
+    /**
+     * Derives the name of a property from the given set method.
+     *
+     * @param m the method
+     * @return the corresponding property name
+     */
+    private static String propertyName(Method m)
+    {
+        String methodName = m.getName().substring(PREFIX_SET_METHOD.length());
+        return (methodName.length() > 1) ? Character.toLowerCase(methodName
+                .charAt(0)) + methodName.substring(1) : methodName
+                .toLowerCase(Locale.ENGLISH);
+    }
+}

Propchange: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/BuilderParametersBeanInfo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/BuilderParametersBeanInfo.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/BuilderParametersBeanInfo.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/FileBasedBuilderParametersBeanInfo.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/FileBasedBuilderParametersBeanInfo.java?rev=1416264&view=auto
==============================================================================
--- commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/FileBasedBuilderParametersBeanInfo.java (added)
+++ commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/FileBasedBuilderParametersBeanInfo.java Sun Dec  2 21:18:13 2012
@@ -0,0 +1,35 @@
+/*
+ * 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.commons.configuration.builder;
+
+/**
+ * An additional {@code BeanInfo} class for {@link FileBasedBuilderParameters}.
+ *
+ * @version $Id$
+ * @since 2.0
+ */
+public class FileBasedBuilderParametersBeanInfo extends
+        BuilderParametersBeanInfo
+{
+    /**
+     * Creates a new instance of {@code FileBasedBuilderParametersBeanInfo}.
+     */
+    public FileBasedBuilderParametersBeanInfo()
+    {
+        super(FileBasedBuilderParameters.class);
+    }
+}

Propchange: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/FileBasedBuilderParametersBeanInfo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/FileBasedBuilderParametersBeanInfo.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/FileBasedBuilderParametersBeanInfo.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain