001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with 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,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019:
020: package org.apache.geronimo.deployment.service;
021:
022: import java.beans.BeanInfo;
023: import java.beans.IntrospectionException;
024: import java.beans.Introspector;
025: import java.beans.PropertyDescriptor;
026: import java.beans.PropertyEditorSupport;
027: import java.lang.reflect.Method;
028:
029: import javax.xml.namespace.QName;
030:
031: import org.apache.geronimo.common.DeploymentException;
032: import org.apache.geronimo.common.propertyeditor.PropertyEditorException;
033: import org.apache.geronimo.deployment.javabean.xbeans.BeanPropertyType;
034: import org.apache.geronimo.deployment.javabean.xbeans.JavabeanDocument;
035: import org.apache.geronimo.deployment.javabean.xbeans.JavabeanType;
036: import org.apache.geronimo.deployment.javabean.xbeans.PropertyType;
037: import org.apache.geronimo.crypto.EncryptionManager;
038: import org.apache.xmlbeans.XmlException;
039: import org.apache.xmlbeans.XmlOptions;
040:
041: /**
042: *
043: * @version $Rev:$ $Date:$
044: */
045: public class JavaBeanXmlAttributeEditor extends PropertyEditorSupport {
046: private static final QName QNAME = JavabeanDocument.type
047: .getDocumentElementName();
048: private static final Class[] PRIMITIVES_CLASSES = new Class[] {
049: String.class, Boolean.class, Character.class, Byte.class,
050: Short.class, Integer.class, Long.class, Float.class,
051: Double.class };
052:
053: private final Class javaBeanClazz;
054: private final XmlAttributeBuilder xmlAttributeBuilder;
055:
056: public JavaBeanXmlAttributeEditor(Class clazz) {
057: if (null == clazz) {
058: throw new IllegalArgumentException("clazz is required");
059: }
060: this .javaBeanClazz = clazz;
061:
062: xmlAttributeBuilder = newXmlAttributeBuilder();
063: }
064:
065: protected JavaBeanXmlAttributeBuilder newXmlAttributeBuilder() {
066: return new JavaBeanXmlAttributeBuilder();
067: }
068:
069: @Override
070: public void setAsText(String text) throws IllegalArgumentException {
071: try {
072: JavabeanDocument document = JavabeanDocument.Factory
073: .parse(text);
074: JavabeanType javaBeanType = document.getJavabean();
075:
076: Object javabean = xmlAttributeBuilder.getValue(
077: javaBeanType, javaBeanClazz.getName(), getClass()
078: .getClassLoader());
079:
080: setValue(javabean);
081: } catch (XmlException e) {
082: throw new PropertyEditorException(e);
083: } catch (DeploymentException e) {
084: throw new PropertyEditorException(e);
085: }
086: }
087:
088: @Override
089: public String getAsText() {
090: JavabeanType javabeanType = getJavabeanType(getValue());
091:
092: XmlOptions xmlOptions = new XmlOptions();
093: xmlOptions.setSaveSyntheticDocumentElement(QNAME);
094: xmlOptions.setSavePrettyPrint();
095: return javabeanType.xmlText(xmlOptions);
096: }
097:
098: protected JavabeanType getJavabeanType(Object javaBean) {
099: JavabeanType javabeanType = JavabeanType.Factory.newInstance();
100:
101: javabeanType.setClass1(javaBean.getClass().getName());
102:
103: PropertyDescriptor[] propertyDescriptors;
104: try {
105: BeanInfo beanInfo = Introspector.getBeanInfo(javaBean
106: .getClass());
107: propertyDescriptors = beanInfo.getPropertyDescriptors();
108: } catch (IntrospectionException e) {
109: throw new IllegalStateException("See nested", e);
110: }
111:
112: for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
113: handle(javaBean, propertyDescriptor, javabeanType);
114: }
115:
116: return javabeanType;
117: }
118:
119: protected void handle(Object javaBean,
120: PropertyDescriptor propertyDescriptor,
121: JavabeanType javabeanType) {
122: Method readMethod = propertyDescriptor.getReadMethod();
123: if (null == readMethod) {
124: return;
125: } else if (readMethod.isAnnotationPresent(DoNotPersist.class)
126: || readMethod.getName().equals("getClass")) {
127: return;
128: }
129:
130: Object value;
131: try {
132: value = readMethod.invoke(javaBean, null);
133: } catch (Exception e) {
134: throw new IllegalStateException("See nested", e);
135: }
136: if (null == value) {
137: return;
138: }
139:
140: if (isPrimitive(value)) {
141: PropertyType propertyType = javabeanType.addNewProperty();
142: propertyType.setName(propertyDescriptor.getName());
143:
144: String valueAsString = value.toString();
145: if (readMethod.isAnnotationPresent(EncryptOnPersist.class)) {
146: valueAsString = EncryptionManager
147: .encrypt(valueAsString);
148: }
149:
150: propertyType.setStringValue(valueAsString);
151: } else {
152: JavabeanType nestedJavabeanType = getJavabeanType(value);
153:
154: BeanPropertyType propertyType = javabeanType
155: .addNewBeanProperty();
156: propertyType.setName(propertyDescriptor.getName());
157: propertyType.setJavabean(nestedJavabeanType);
158: }
159: }
160:
161: protected boolean isPrimitive(Object propertyValue) {
162: Class valueClass = propertyValue.getClass();
163: for (Class primitiveClass : PRIMITIVES_CLASSES) {
164: if (valueClass.equals(primitiveClass)) {
165: return true;
166: }
167: }
168: return false;
169: }
170:
171: }
|