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 }