001    /**
002     *
003     *  Licensed to the Apache Software Foundation (ASF) under one or more
004     *  contributor license agreements.  See the NOTICE file distributed with
005     *  this work for additional information regarding copyright ownership.
006     *  The ASF licenses this file to You under the Apache License, Version 2.0
007     *  (the "License"); you may not use this file except in compliance with
008     *  the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     *  Unless required by applicable law or agreed to in writing, software
013     *  distributed under the License is distributed on an "AS IS" BASIS,
014     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     *  See the License for the specific language governing permissions and
016     *  limitations under the License.
017     */
018    package org.apache.geronimo.deployment.service;
019    
020    import java.beans.BeanInfo;
021    import java.beans.IntrospectionException;
022    import java.beans.Introspector;
023    import java.beans.PropertyDescriptor;
024    import java.beans.PropertyEditor;
025    import java.lang.reflect.Method;
026    
027    import org.apache.geronimo.common.DeploymentException;
028    import org.apache.geronimo.common.propertyeditor.PropertyEditors;
029    import org.apache.geronimo.deployment.javabean.xbeans.JavabeanType;
030    import org.apache.geronimo.deployment.javabean.xbeans.PropertyType;
031    import org.apache.geronimo.deployment.javabean.xbeans.BeanPropertyType;
032    import org.apache.geronimo.gbean.GBeanInfo;
033    import org.apache.geronimo.gbean.GBeanInfoBuilder;
034    import org.apache.xmlbeans.XmlObject;
035    
036    /**
037     * @version $Rev: 470597 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $
038     */
039    public class JavaBeanXmlAttributeBuilder implements XmlAttributeBuilder {
040    
041        private static final String NAMESPACE = "http://geronimo.apache.org/xml/ns/deployment/javabean-1.0";
042    
043        public String getNamespace() {
044            return NAMESPACE;
045        }
046    
047        public Object getValue(XmlObject xmlObject, String type, ClassLoader cl) throws DeploymentException {
048            JavabeanType javabean = (JavabeanType) xmlObject.copy().changeType(JavabeanType.type);
049            return getValue(javabean, type, cl);
050        }
051    
052        private Object getValue(JavabeanType javabean, String className, ClassLoader cl) throws DeploymentException {
053            Class clazz = null;
054            try {
055                clazz = cl.loadClass(className);
056            } catch (ClassNotFoundException e) {
057                throw new DeploymentException("Could not load alleged javabean class " + className, e);
058            }
059            Object instance = null;
060            try {
061                instance = clazz.newInstance();
062            } catch (Exception e) {
063                throw new DeploymentException("Could not create java bean instance", e);
064            }
065            PropertyDescriptor[] propertyDescriptors;
066            try {
067                BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
068                propertyDescriptors = beanInfo.getPropertyDescriptors();
069            } catch (IntrospectionException e) {
070                throw new DeploymentException("Could not analyze java bean class", e);
071            }
072    
073            PropertyType[] properties = javabean.getPropertyArray();
074            for (int i = 0; i < properties.length; i++) {
075                PropertyType property = properties[i];
076                String propertyName = Introspector.decapitalize(property.getName());
077                String propertyString = property.getStringValue().trim();
078                for (int j = 0; j < propertyDescriptors.length; j++) {
079                    PropertyDescriptor propertyDescriptor = propertyDescriptors[j];
080                    if (propertyName.equals(propertyDescriptor.getName())) {
081                        String type = propertyDescriptor.getPropertyType().getName();
082                        PropertyEditor propertyEditor = null;
083                        try {
084                            propertyEditor = PropertyEditors.findEditor(type, cl);
085                        } catch (ClassNotFoundException e) {
086                            throw new DeploymentException("Could not load editor for type " + type, e);
087                        }
088                        if (propertyEditor == null) {
089                            throw new DeploymentException("Unable to find PropertyEditor for " + type);
090                        }
091                        propertyEditor.setAsText(propertyString);
092                        Object value = propertyEditor.getValue();
093                        Method m = propertyDescriptor.getWriteMethod();
094                        try {
095                            m.invoke(instance, new Object[] {value});
096                        } catch (Exception e) {
097                            throw new DeploymentException("Could not set property value for property named " + propertyName, e);
098                        }
099                        break;
100                    }
101                }
102            }
103    
104            BeanPropertyType[] beanProperties = javabean.getBeanPropertyArray();
105            for (int i = 0; i < beanProperties.length; i++) {
106                BeanPropertyType beanProperty = beanProperties[i];
107                String propertyName = Introspector.decapitalize(beanProperty.getName().trim());
108                JavabeanType innerBean = beanProperty.getJavabean();
109                for (int j = 0; j < propertyDescriptors.length; j++) {
110                    PropertyDescriptor propertyDescriptor = propertyDescriptors[j];
111                    if (propertyName.equals(propertyDescriptor.getName())) {
112                        String propertyType = propertyDescriptor.getPropertyType().getName();
113                        Object value = getValue(innerBean, propertyType, cl);
114                        Method m = propertyDescriptor.getWriteMethod();
115                        try {
116                            m.invoke(instance, new Object[] {value});
117                        } catch (Exception e) {
118                            throw new DeploymentException("Could not set property value for property named " + propertyName, e);
119                        }
120                        break;
121                    }
122                }
123            }
124            return instance;
125        }
126    
127        public static final GBeanInfo GBEAN_INFO;
128    
129        static {
130            GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(JavaBeanXmlAttributeBuilder.class, "XmlAttributeBuilder");
131            infoBuilder.addInterface(XmlAttributeBuilder.class);
132            GBEAN_INFO = infoBuilder.getBeanInfo();
133        }
134    
135        public static GBeanInfo getGBeanInfo() {
136            return GBEAN_INFO;
137        }
138    }