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 package org.apache.geronimo.deployment.service;
018
019 import java.beans.BeanInfo;
020 import java.beans.IntrospectionException;
021 import java.beans.Introspector;
022 import java.beans.PropertyDescriptor;
023 import java.beans.PropertyEditor;
024 import java.lang.reflect.Method;
025
026 import org.apache.geronimo.common.DeploymentException;
027 import org.apache.geronimo.common.propertyeditor.PropertyEditors;
028 import org.apache.geronimo.deployment.javabean.xbeans.JavabeanType;
029 import org.apache.geronimo.deployment.javabean.xbeans.PropertyType;
030 import org.apache.geronimo.deployment.javabean.xbeans.BeanPropertyType;
031 import org.apache.geronimo.gbean.GBeanInfo;
032 import org.apache.geronimo.gbean.GBeanInfoBuilder;
033 import org.apache.geronimo.crypto.EncryptionManager;
034 import org.apache.xmlbeans.XmlObject;
035
036 /**
037 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
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 type, ClassLoader cl) throws DeploymentException {
053 String className = type;
054 if (javabean.isSetClass1()) {
055 className = javabean.getClass1();
056 }
057 Class clazz = null;
058 try {
059 clazz = cl.loadClass(className);
060 if (!type.equals(className) && !cl.loadClass(type).isAssignableFrom(clazz)) {
061 throw new DeploymentException("javabean class " + className + " is not of the expected type " + type);
062 }
063 } catch (ClassNotFoundException e) {
064 throw new DeploymentException("Could not load alleged javabean class " + className, e);
065 }
066 Object instance = null;
067 try {
068 instance = clazz.newInstance();
069 } catch (Exception e) {
070 throw new DeploymentException("Could not create java bean instance", e);
071 }
072
073 PropertyDescriptor[] propertyDescriptors;
074 try {
075 BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
076 propertyDescriptors = beanInfo.getPropertyDescriptors();
077 } catch (IntrospectionException e) {
078 throw new DeploymentException("Could not analyze java bean class", e);
079 }
080
081 PropertyType[] properties = javabean.getPropertyArray();
082 for (int i = 0; i < properties.length; i++) {
083 PropertyType property = properties[i];
084 String propertyName = Introspector.decapitalize(property.getName());
085 String propertyString = property.getStringValue().trim();
086 for (int j = 0; j < propertyDescriptors.length; j++) {
087 PropertyDescriptor propertyDescriptor = propertyDescriptors[j];
088 if (propertyName.equals(propertyDescriptor.getName())) {
089 Method writeMethod = propertyDescriptor.getWriteMethod();
090 if (writeMethod.isAnnotationPresent(EncryptOnPersist.class)) {
091 propertyString = (String) EncryptionManager.decrypt(propertyString);
092 }
093
094 String protertyType = propertyDescriptor.getPropertyType().getName();
095
096 PropertyEditor propertyEditor = null;
097 try {
098 propertyEditor = PropertyEditors.findEditor(protertyType, cl);
099 } catch (ClassNotFoundException e) {
100 throw new DeploymentException("Could not load editor for type " + protertyType, e);
101 }
102 if (propertyEditor == null) {
103 throw new DeploymentException("Unable to find PropertyEditor for " + protertyType);
104 }
105 propertyEditor.setAsText(propertyString);
106 Object value = propertyEditor.getValue();
107
108 try {
109 writeMethod.invoke(instance, new Object[] {value});
110 } catch (Exception e) {
111 throw new DeploymentException("Could not set property value for property named " + propertyName, e);
112 }
113 break;
114 }
115 }
116 }
117
118 BeanPropertyType[] beanProperties = javabean.getBeanPropertyArray();
119 for (int i = 0; i < beanProperties.length; i++) {
120 BeanPropertyType beanProperty = beanProperties[i];
121 String propertyName = Introspector.decapitalize(beanProperty.getName().trim());
122 JavabeanType innerBean = beanProperty.getJavabean();
123 for (int j = 0; j < propertyDescriptors.length; j++) {
124 PropertyDescriptor propertyDescriptor = propertyDescriptors[j];
125 if (propertyName.equals(propertyDescriptor.getName())) {
126 String propertyType = propertyDescriptor.getPropertyType().getName();
127 Object value = getValue(innerBean, propertyType, cl);
128 Method m = propertyDescriptor.getWriteMethod();
129 try {
130 m.invoke(instance, new Object[] {value});
131 } catch (Exception e) {
132 throw new DeploymentException("Could not set property value for property named " + propertyName, e);
133 }
134 break;
135 }
136 }
137 }
138 return instance;
139 }
140
141 public static final GBeanInfo GBEAN_INFO;
142
143 static {
144 GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(JavaBeanXmlAttributeBuilder.class, "XmlAttributeBuilder");
145 infoBuilder.addInterface(XmlAttributeBuilder.class);
146 GBEAN_INFO = infoBuilder.getBeanInfo();
147 }
148
149 public static GBeanInfo getGBeanInfo() {
150 return GBEAN_INFO;
151 }
152 }