src/share/jaxws_classes/com/sun/xml/internal/ws/spi/db/JAXBWrapperAccessor.java

Tue, 09 Apr 2013 14:51:13 +0100

author
alanb
date
Tue, 09 Apr 2013 14:51:13 +0100
changeset 368
0989ad8c0860
parent 286
f50545b5e2f1
child 384
8f2986ff0235
permissions
-rw-r--r--

8010393: Update JAX-WS RI to 2.2.9-b12941
Reviewed-by: alanb, erikj
Contributed-by: miroslav.kos@oracle.com, martin.grebac@oracle.com

     1 /*
     2  * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 package com.sun.xml.internal.ws.spi.db;
    28 import java.lang.reflect.Array;
    29 import java.lang.reflect.Field;
    30 import java.lang.reflect.GenericArrayType;
    31 import java.lang.reflect.Method;
    32 import java.lang.reflect.ParameterizedType;
    33 import java.lang.reflect.Type;
    34 import java.security.AccessController;
    35 import java.security.PrivilegedActionException;
    36 import java.security.PrivilegedExceptionAction;
    37 import java.util.ArrayList;
    38 import java.util.Arrays;
    39 import java.util.HashMap;
    40 import java.util.HashSet;
    41 import java.util.List;
    43 import javax.xml.bind.JAXBElement;
    44 import javax.xml.bind.annotation.XmlElement;
    45 import javax.xml.bind.annotation.XmlElementRef;
    46 import javax.xml.namespace.QName;
    48 /**
    49  * JAXBWrapperAccessor
    50  *
    51  * @author shih-chang.chen@oracle.com
    52  */
    53 @SuppressWarnings({ "unchecked", "rawtypes" })
    54 public class JAXBWrapperAccessor extends WrapperAccessor {
    56     protected Class<?> contentClass;
    57     protected HashMap<Object, Class> elementDeclaredTypes;
    59     public JAXBWrapperAccessor(Class<?> wrapperBean) {
    60         contentClass = (Class<?>) wrapperBean;
    62         HashMap<Object, PropertySetter> setByQName = new HashMap<Object, PropertySetter>();
    63         HashMap<Object, PropertySetter> setByLocalpart = new HashMap<Object, PropertySetter>();
    64         HashMap<String, Method> publicSetters = new HashMap<String, Method>();
    66         HashMap<Object, PropertyGetter> getByQName = new HashMap<Object, PropertyGetter>();
    67         HashMap<Object, PropertyGetter> getByLocalpart = new HashMap<Object, PropertyGetter>();
    68         HashMap<String, Method> publicGetters = new HashMap<String, Method>();
    70         HashMap<Object, Class> elementDeclaredTypesByQName = new HashMap<Object, Class>();
    71         HashMap<Object, Class> elementDeclaredTypesByLocalpart = new HashMap<Object, Class>();
    73         for (Method method : contentClass.getMethods()) {
    74             if (PropertySetterBase.setterPattern(method)) {
    75                 String key = method.getName()
    76                         .substring(3, method.getName().length()).toLowerCase();
    77                 publicSetters.put(key, method);
    78             }
    79             if (PropertyGetterBase.getterPattern(method)) {
    80                 String methodName = method.getName();
    81                 String key = methodName.startsWith("is") ? methodName
    82                         .substring(2, method.getName().length()).toLowerCase()
    83                         : methodName.substring(3, method.getName().length())
    84                                 .toLowerCase();
    85                 publicGetters.put(key, method);
    86             }
    87         }
    88         HashSet<String> elementLocalNames = new HashSet<String>();
    89         for (Field field : getAllFields(contentClass)) {
    90             XmlElement xmlElem = field.getAnnotation(XmlElement.class);
    91             XmlElementRef xmlElemRef = field.getAnnotation(XmlElementRef.class);
    92             String fieldName = field.getName().toLowerCase();
    93             String namespace = "";
    94             String localName = field.getName();
    95             if (xmlElem != null) {
    96                 namespace = xmlElem.namespace();
    97                 if (xmlElem.name() != null && !xmlElem.name().equals("")
    98                         && !xmlElem.name().equals("##default")) {
    99                     localName = xmlElem.name();
   100                 }
   101             } else if (xmlElemRef != null) {
   102                 namespace = xmlElemRef.namespace();
   103                 if (xmlElemRef.name() != null && !xmlElemRef.name().equals("")
   104                         && !xmlElemRef.name().equals("##default")) {
   105                     localName = xmlElemRef.name();
   106                 }
   107             }
   108             if (elementLocalNames.contains(localName)) {
   109                 this.elementLocalNameCollision = true;
   110             } else {
   111                 elementLocalNames.add(localName);
   112             }
   114             QName qname = new QName(namespace, localName);
   115             if (field.getType().equals(JAXBElement.class)) {
   116                 if (field.getGenericType() instanceof ParameterizedType) {
   117                     Type arg = ((ParameterizedType) field.getGenericType())
   118                             .getActualTypeArguments()[0];
   119                     if (arg instanceof Class) {
   120                         elementDeclaredTypesByQName.put(qname, (Class) arg);
   121                         elementDeclaredTypesByLocalpart.put(localName,
   122                                 (Class) arg);
   123                     } else if (arg instanceof GenericArrayType) {
   124                         Type componentType = ((GenericArrayType) arg)
   125                                 .getGenericComponentType();
   126                         if (componentType instanceof Class) {
   127                             Class arrayClass = Array.newInstance(
   128                                     (Class) componentType, 0).getClass();
   129                             elementDeclaredTypesByQName.put(qname, arrayClass);
   130                             elementDeclaredTypesByLocalpart.put(localName,
   131                                     arrayClass);
   132                         }
   133                     }
   134                 }
   136             }
   137             // _return
   138             if (fieldName.startsWith("_") && !localName.startsWith("_")) {
   139                 fieldName = fieldName.substring(1);
   140             }
   141             Method setMethod = publicSetters.get(fieldName);
   142             Method getMethod = publicGetters.get(fieldName);
   143             PropertySetter setter = createPropertySetter(field, setMethod);
   144             PropertyGetter getter = createPropertyGetter(field, getMethod);
   145             setByQName.put(qname, setter);
   146             setByLocalpart.put(localName, setter);
   147             getByQName.put(qname, getter);
   148             getByLocalpart.put(localName, getter);
   149         }
   150         if (this.elementLocalNameCollision) {
   151             this.propertySetters = setByQName;
   152             this.propertyGetters = getByQName;
   153             elementDeclaredTypes = elementDeclaredTypesByQName;
   154         } else {
   155             this.propertySetters = setByLocalpart;
   156             this.propertyGetters = getByLocalpart;
   157             elementDeclaredTypes = elementDeclaredTypesByLocalpart;
   158         }
   159     }
   161     static protected List<Field> getAllFields(Class<?> clz) {
   162         List<Field> list = new ArrayList<Field>();
   163         while (!Object.class.equals(clz)) {
   164             list.addAll(Arrays.asList(getDeclaredFields(clz)));
   165             clz = clz.getSuperclass();
   166         }
   167         return list;
   168     }
   170     static protected Field[] getDeclaredFields(final Class<?> clz) {
   171         try {
   172             return (System.getSecurityManager() == null) ? clz .getDeclaredFields() :
   173                 AccessController.doPrivileged(new PrivilegedExceptionAction<Field[]>() {
   174                         @Override
   175                         public Field[] run() throws IllegalAccessException {
   176                             return clz.getDeclaredFields();
   177                         }
   178                     });
   179         } catch (PrivilegedActionException e) {
   180             // TODO Auto-generated catch block
   181             e.printStackTrace();
   182             return null;
   183         }
   184     }
   186     static protected PropertyGetter createPropertyGetter(Field field, Method getMethod) {
   187         if (!field.isAccessible()) {
   188             if (getMethod != null) {
   189                 MethodGetter methodGetter = new MethodGetter(getMethod);
   190                 if (methodGetter.getType().toString().equals(field.getType().toString())) {
   191                     return methodGetter;
   192                 }
   193             }
   194         }
   195         return new FieldGetter(field);
   196     }
   198     static protected PropertySetter createPropertySetter(Field field,
   199             Method setter) {
   200         if (!field.isAccessible()) {
   201             if (setter != null) {
   202                 MethodSetter injection = new MethodSetter(setter);
   203                 if (injection.getType().toString().equals(field.getType().toString())) {
   204                     return injection;
   205                 }
   206             }
   207         }
   208         return new FieldSetter(field);
   209     }
   211     private Class getElementDeclaredType(QName name) {
   212         Object key = (this.elementLocalNameCollision) ? name : name
   213                 .getLocalPart();
   214         return elementDeclaredTypes.get(key);
   215     }
   217     @Override
   218     public PropertyAccessor getPropertyAccessor(String ns, String name) {
   219         final QName n = new QName(ns, name);
   220         final PropertySetter setter = getPropertySetter(n);
   221         final PropertyGetter getter = getPropertyGetter(n);
   222         final boolean isJAXBElement = setter.getType()
   223                 .equals(JAXBElement.class);
   224         final boolean isListType = java.util.List.class.isAssignableFrom(setter
   225                 .getType());
   226         final Class elementDeclaredType = isJAXBElement ? getElementDeclaredType(n)
   227                 : null;
   228         return new PropertyAccessor() {
   229             @Override
   230             public Object get(Object bean) throws DatabindingException {
   231                 Object val;
   232                 if (isJAXBElement) {
   233                     JAXBElement<Object> jaxbElement = (JAXBElement<Object>) getter.get(bean);
   234                     val = (jaxbElement == null) ? null : jaxbElement.getValue();
   235                 } else {
   236                     val = getter.get(bean);
   237                 }
   238                 if (val == null && isListType) {
   239                     val = new java.util.ArrayList();
   240                     set(bean, val);
   241                 }
   242                 return val;
   243             }
   245             @Override
   246             public void set(Object bean, Object value) throws DatabindingException {
   247                 if (isJAXBElement) {
   248                     JAXBElement<Object> jaxbElement = new JAXBElement<Object>(
   249                             n, elementDeclaredType, contentClass, value);
   250                     setter.set(bean, jaxbElement);
   251                 } else {
   252                     setter.set(bean, value);
   253                 }
   254             }
   255         };
   256     }
   257 }

mercurial