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

Print this page


   1 /*
   2  * Copyright (c) 1997, 2013, 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


  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;
  42 
  43 import javax.xml.bind.JAXBElement;
  44 import javax.xml.bind.annotation.XmlElement;
  45 import javax.xml.bind.annotation.XmlElementRef;
  46 import javax.xml.bind.annotation.XmlElementWrapper;
  47 import javax.xml.namespace.QName;


  48 
  49 /**
  50  * JAXBWrapperAccessor
  51  *
  52  * @author shih-chang.chen@oracle.com
  53  */
  54 @SuppressWarnings({ "unchecked", "rawtypes" })
  55 public class JAXBWrapperAccessor extends WrapperAccessor {
  56 
  57     protected Class<?> contentClass;
  58     protected HashMap<Object, Class> elementDeclaredTypes;
  59 
  60     public JAXBWrapperAccessor(Class<?> wrapperBean) {

  61         contentClass = (Class<?>) wrapperBean;
  62 
  63         HashMap<Object, PropertySetter> setByQName = new HashMap<Object, PropertySetter>();
  64         HashMap<Object, PropertySetter> setByLocalpart = new HashMap<Object, PropertySetter>();
  65         HashMap<String, Method> publicSetters = new HashMap<String, Method>();
  66 
  67         HashMap<Object, PropertyGetter> getByQName = new HashMap<Object, PropertyGetter>();
  68         HashMap<Object, PropertyGetter> getByLocalpart = new HashMap<Object, PropertyGetter>();
  69         HashMap<String, Method> publicGetters = new HashMap<String, Method>();
  70 
  71         HashMap<Object, Class> elementDeclaredTypesByQName = new HashMap<Object, Class>();
  72         HashMap<Object, Class> elementDeclaredTypesByLocalpart = new HashMap<Object, Class>();
  73 
  74         for (Method method : contentClass.getMethods()) {
  75             if (PropertySetterBase.setterPattern(method)) {
  76                 String key = method.getName()
  77                         .substring(3, method.getName().length()).toLowerCase();
  78                 publicSetters.put(key, method);
  79             }
  80             if (PropertyGetterBase.getterPattern(method)) {


 125                     Type arg = ((ParameterizedType) field.getGenericType())
 126                             .getActualTypeArguments()[0];
 127                     if (arg instanceof Class) {
 128                         elementDeclaredTypesByQName.put(qname, (Class) arg);
 129                         elementDeclaredTypesByLocalpart.put(localName,
 130                                 (Class) arg);
 131                     } else if (arg instanceof GenericArrayType) {
 132                         Type componentType = ((GenericArrayType) arg)
 133                                 .getGenericComponentType();
 134                         if (componentType instanceof Class) {
 135                             Class arrayClass = Array.newInstance(
 136                                     (Class) componentType, 0).getClass();
 137                             elementDeclaredTypesByQName.put(qname, arrayClass);
 138                             elementDeclaredTypesByLocalpart.put(localName,
 139                                     arrayClass);
 140                         }
 141                     }
 142                 }
 143 
 144             }
 145             // _return
 146             if (fieldName.startsWith("_") && !localName.startsWith("_")) {
 147                 fieldName = fieldName.substring(1);
 148             }
 149             Method setMethod = publicSetters.get(fieldName);
 150             Method getMethod = publicGetters.get(fieldName);
 151             PropertySetter setter = createPropertySetter(field, setMethod);
 152             PropertyGetter getter = createPropertyGetter(field, getMethod);
 153             setByQName.put(qname, setter);
 154             setByLocalpart.put(localName, setter);
 155             getByQName.put(qname, getter);
 156             getByLocalpart.put(localName, getter);
 157         }

 158         if (this.elementLocalNameCollision) {
 159             this.propertySetters = setByQName;
 160             this.propertyGetters = getByQName;
 161             elementDeclaredTypes = elementDeclaredTypesByQName;
 162         } else {
 163             this.propertySetters = setByLocalpart;
 164             this.propertyGetters = getByLocalpart;
 165             elementDeclaredTypes = elementDeclaredTypesByLocalpart;
 166         }
 167     }
 168 
 169     static protected List<Field> getAllFields(Class<?> clz) {


















 170         List<Field> list = new ArrayList<Field>();
 171         while (!Object.class.equals(clz)) {
 172             list.addAll(Arrays.asList(getDeclaredFields(clz)));
 173             clz = clz.getSuperclass();
 174         }
 175         return list;
 176     }
 177 
 178     static protected Field[] getDeclaredFields(final Class<?> clz) {
 179         try {
 180             return (System.getSecurityManager() == null) ? clz .getDeclaredFields() :
 181                 AccessController.doPrivileged(new PrivilegedExceptionAction<Field[]>() {
 182                         @Override
 183                         public Field[] run() throws IllegalAccessException {
 184                             return clz.getDeclaredFields();
 185                         }
 186                     });
 187         } catch (PrivilegedActionException e) {
 188             // TODO Auto-generated catch block
 189             e.printStackTrace();
 190             return null;
 191         }
 192     }
 193 
 194     static protected PropertyGetter createPropertyGetter(Field field, Method getMethod) {
 195         if (!field.isAccessible()) {
 196             if (getMethod != null) {
 197                 MethodGetter methodGetter = new MethodGetter(getMethod);
 198                 if (methodGetter.getType().toString().equals(field.getType().toString())) {
 199                     return methodGetter;
 200                 }
 201             }
 202         }
 203         return new FieldGetter(field);
 204     }
 205 
 206     static protected PropertySetter createPropertySetter(Field field,
 207             Method setter) {
 208         if (!field.isAccessible()) {
 209             if (setter != null) {
 210                 MethodSetter injection = new MethodSetter(setter);
 211                 if (injection.getType().toString().equals(field.getType().toString())) {
 212                     return injection;
 213                 }
 214             }
 215         }
 216         return new FieldSetter(field);
 217     }
 218 
 219     private Class getElementDeclaredType(QName name) {
 220         Object key = (this.elementLocalNameCollision) ? name : name
 221                 .getLocalPart();
 222         return elementDeclaredTypes.get(key);
 223     }
 224 
 225     @Override
 226     public PropertyAccessor getPropertyAccessor(String ns, String name) {
 227         final QName n = new QName(ns, name);
 228         final PropertySetter setter = getPropertySetter(n);
 229         final PropertyGetter getter = getPropertyGetter(n);
 230         final boolean isJAXBElement = setter.getType()
 231                 .equals(JAXBElement.class);
 232         final boolean isListType = java.util.List.class.isAssignableFrom(setter
 233                 .getType());
 234         final Class elementDeclaredType = isJAXBElement ? getElementDeclaredType(n)
 235                 : null;
 236         return new PropertyAccessor() {
 237             @Override
 238             public Object get(Object bean) throws DatabindingException {
 239                 Object val;
 240                 if (isJAXBElement) {
 241                     JAXBElement<Object> jaxbElement = (JAXBElement<Object>) getter.get(bean);
 242                     val = (jaxbElement == null) ? null : jaxbElement.getValue();
 243                 } else {
 244                     val = getter.get(bean);
 245                 }
 246                 if (val == null && isListType) {
 247                     val = new java.util.ArrayList();
 248                     set(bean, val);
 249                 }
 250                 return val;
 251             }
 252 
 253             @Override
 254             public void set(Object bean, Object value) throws DatabindingException {
 255                 if (isJAXBElement) {
 256                     JAXBElement<Object> jaxbElement = new JAXBElement<Object>(
 257                             n, elementDeclaredType, contentClass, value);
 258                     setter.set(bean, jaxbElement);
 259                 } else {
 260                     setter.set(bean, value);
 261                 }
 262             }
 263         };
 264     }




















































































 265 }
   1 /*
   2  * Copyright (c) 1997, 2014, 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


  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;
  42 
  43 import javax.xml.bind.JAXBElement;
  44 import javax.xml.bind.annotation.XmlElement;
  45 import javax.xml.bind.annotation.XmlElementRef;
  46 import javax.xml.bind.annotation.XmlElementWrapper;
  47 import javax.xml.namespace.QName;
  48 import javax.xml.ws.WebServiceException;
  49 import static com.sun.xml.internal.ws.spi.db.PropertyGetterBase.verifyWrapperType;
  50 
  51 /**
  52  * JAXBWrapperAccessor
  53  *
  54  * @author shih-chang.chen@oracle.com
  55  */
  56 @SuppressWarnings({ "unchecked", "rawtypes" })
  57 public class JAXBWrapperAccessor extends WrapperAccessor {
  58 
  59     protected Class<?> contentClass;
  60     protected HashMap<Object, Class> elementDeclaredTypes;
  61 
  62     public JAXBWrapperAccessor(Class<?> wrapperBean) {
  63         verifyWrapperType(wrapperBean);
  64         contentClass = (Class<?>) wrapperBean;
  65 
  66         HashMap<Object, PropertySetter> setByQName = new HashMap<Object, PropertySetter>();
  67         HashMap<Object, PropertySetter> setByLocalpart = new HashMap<Object, PropertySetter>();
  68         HashMap<String, Method> publicSetters = new HashMap<String, Method>();
  69 
  70         HashMap<Object, PropertyGetter> getByQName = new HashMap<Object, PropertyGetter>();
  71         HashMap<Object, PropertyGetter> getByLocalpart = new HashMap<Object, PropertyGetter>();
  72         HashMap<String, Method> publicGetters = new HashMap<String, Method>();
  73 
  74         HashMap<Object, Class> elementDeclaredTypesByQName = new HashMap<Object, Class>();
  75         HashMap<Object, Class> elementDeclaredTypesByLocalpart = new HashMap<Object, Class>();
  76 
  77         for (Method method : contentClass.getMethods()) {
  78             if (PropertySetterBase.setterPattern(method)) {
  79                 String key = method.getName()
  80                         .substring(3, method.getName().length()).toLowerCase();
  81                 publicSetters.put(key, method);
  82             }
  83             if (PropertyGetterBase.getterPattern(method)) {


 128                     Type arg = ((ParameterizedType) field.getGenericType())
 129                             .getActualTypeArguments()[0];
 130                     if (arg instanceof Class) {
 131                         elementDeclaredTypesByQName.put(qname, (Class) arg);
 132                         elementDeclaredTypesByLocalpart.put(localName,
 133                                 (Class) arg);
 134                     } else if (arg instanceof GenericArrayType) {
 135                         Type componentType = ((GenericArrayType) arg)
 136                                 .getGenericComponentType();
 137                         if (componentType instanceof Class) {
 138                             Class arrayClass = Array.newInstance(
 139                                     (Class) componentType, 0).getClass();
 140                             elementDeclaredTypesByQName.put(qname, arrayClass);
 141                             elementDeclaredTypesByLocalpart.put(localName,
 142                                     arrayClass);
 143                         }
 144                     }
 145                 }
 146 
 147             }
 148             Method setMethod = accessor(publicSetters, fieldName, localName);
 149             Method getMethod = accessor(publicGetters, fieldName, localName);
 150             if ( isProperty(field, getMethod, setMethod) ) {



 151                 PropertySetter setter = createPropertySetter(field, setMethod);
 152                 PropertyGetter getter = createPropertyGetter(field, getMethod);
 153                 setByQName.put(qname, setter);
 154                 setByLocalpart.put(localName, setter);
 155                 getByQName.put(qname, getter);
 156                 getByLocalpart.put(localName, getter);
 157             }
 158         }
 159         if (this.elementLocalNameCollision) {
 160             this.propertySetters = setByQName;
 161             this.propertyGetters = getByQName;
 162             elementDeclaredTypes = elementDeclaredTypesByQName;
 163         } else {
 164             this.propertySetters = setByLocalpart;
 165             this.propertyGetters = getByLocalpart;
 166             elementDeclaredTypes = elementDeclaredTypesByLocalpart;
 167         }
 168     }
 169 
 170     static private Method accessor(HashMap<String, Method> map, String fieldName, String localName) {
 171         Method a = map.get(fieldName);
 172         if (a == null) a = map.get(localName);
 173         if (a == null && fieldName.startsWith("_")) a = map.get(fieldName.substring(1));
 174         return a;
 175     }
 176 
 177     static private boolean isProperty(Field field, Method getter, Method setter) {
 178         if (java.lang.reflect.Modifier.isPublic(field.getModifiers())) return true;
 179         if (getter == null) return false;
 180         if (setter == null) {
 181             return java.util.Collection.class.isAssignableFrom(field.getType()) ||
 182                    java.util.Map.class.isAssignableFrom(field.getType()) ;
 183         } else {
 184             return true;
 185         }
 186     }
 187 
 188     static private List<Field> getAllFields(Class<?> clz) {
 189         List<Field> list = new ArrayList<Field>();
 190         while (!Object.class.equals(clz)) {
 191             list.addAll(Arrays.asList(getDeclaredFields(clz)));
 192             clz = clz.getSuperclass();
 193         }
 194         return list;
 195     }
 196 
 197     static private Field[] getDeclaredFields(final Class<?> clz) {
 198         try {
 199             return AccessController.doPrivileged(new PrivilegedExceptionAction<Field[]>() {

 200                         @Override
 201                         public Field[] run() throws IllegalAccessException {
 202                             return clz.getDeclaredFields();
 203                         }
 204                     });
 205         } catch (PrivilegedActionException e) {
 206             throw new WebServiceException(e);


 207         }
 208     }
 209 
 210     static private PropertyGetter createPropertyGetter(Field field, Method getMethod) {
 211         if (!field.isAccessible()) {
 212             if (getMethod != null) {
 213                 MethodGetter methodGetter = new MethodGetter(getMethod);
 214                 if (methodGetter.getType().toString().equals(field.getType().toString())) {
 215                     return methodGetter;
 216                 }
 217             }
 218         }
 219         return new PrivFieldGetter(field);
 220     }
 221 
 222     static private PropertySetter createPropertySetter(Field field,
 223             Method setter) {
 224         if (!field.isAccessible()) {
 225             if (setter != null) {
 226                 MethodSetter injection = new MethodSetter(setter);
 227                 if (injection.getType().toString().equals(field.getType().toString())) {
 228                     return injection;
 229                 }
 230             }
 231         }
 232         return new PrivFieldSetter(field);
 233     }
 234 
 235     private Class getElementDeclaredType(QName name) {
 236         Object key = (this.elementLocalNameCollision) ? name : name
 237                 .getLocalPart();
 238         return elementDeclaredTypes.get(key);
 239     }
 240 
 241     @Override
 242     public PropertyAccessor getPropertyAccessor(String ns, String name) {
 243         final QName n = new QName(ns, name);
 244         final PropertySetter setter = getPropertySetter(n);
 245         final PropertyGetter getter = getPropertyGetter(n);
 246         final boolean isJAXBElement = setter.getType()
 247                 .equals(JAXBElement.class);
 248         final boolean isListType = java.util.List.class.isAssignableFrom(setter
 249                 .getType());
 250         final Class elementDeclaredType = isJAXBElement ? getElementDeclaredType(n)
 251                 : null;
 252         return new PropertyAccessor() {
 253             @Override
 254             public Object get(Object bean) throws DatabindingException {
 255                 Object val;
 256                 if (isJAXBElement) {
 257                     JAXBElement<Object> jaxbElement = (JAXBElement<Object>) JAXBWrapperAccessor.get(getter, bean);
 258                     val = (jaxbElement == null) ? null : jaxbElement.getValue();
 259                 } else {
 260                     val = JAXBWrapperAccessor.get(getter, bean);
 261                 }
 262                 if (val == null && isListType) {
 263                     val = new java.util.ArrayList();
 264                     set(bean, val);
 265                 }
 266                 return val;
 267             }
 268 
 269             @Override
 270             public void set(Object bean, Object value) throws DatabindingException {
 271                 if (isJAXBElement) {
 272                     JAXBElement<Object> jaxbElement = new JAXBElement<Object>(
 273                             n, elementDeclaredType, contentClass, value);
 274                     JAXBWrapperAccessor.set(setter, bean, jaxbElement);
 275                 } else {
 276                     JAXBWrapperAccessor.set(setter, bean, value);
 277                 }
 278             }
 279         };
 280     }
 281 
 282     static  private Object get(PropertyGetter getter, Object wrapperInstance) {
 283         return (getter instanceof PrivFieldGetter)?
 284             ((PrivFieldGetter)getter).getPriv(wrapperInstance):
 285             getter.get(wrapperInstance);
 286     }
 287 
 288     static private void set(PropertySetter setter, Object wrapperInstance, Object value) {
 289         if (setter instanceof PrivFieldSetter)
 290             ((PrivFieldSetter)setter).setPriv(wrapperInstance, value);
 291         else
 292             setter.set(wrapperInstance, value);
 293     }
 294 
 295 
 296     static private class PrivFieldSetter extends FieldSetter {
 297         private PrivFieldSetter(Field f) {
 298             super(f);
 299         }
 300         private void setPriv(final Object instance, final Object val) {
 301             final Object resource = (type.isPrimitive() && val == null)? uninitializedValue(type): val;
 302             if (field.isAccessible()) {
 303                 try {
 304                     field.set(instance, resource);
 305                 } catch (Exception e) {
 306                     throw new WebServiceException(e);
 307                 }
 308             } else {
 309                 try {
 310                     AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
 311                         public Object run() throws IllegalAccessException {
 312                             if (!field.isAccessible()) {
 313                                 field.setAccessible(true);
 314                             }
 315                             field.set(instance, resource);
 316                             return null;
 317                         }
 318                     });
 319                 } catch (PrivilegedActionException e) {
 320                     throw new WebServiceException(e);
 321                 }
 322             }
 323         }
 324     }
 325 
 326     static private class PrivFieldGetter extends FieldGetter {
 327         private PrivFieldGetter(Field f) {
 328             super(f);
 329         }
 330         static private class PrivilegedGetter implements PrivilegedExceptionAction {
 331             private Object value;
 332             private Field  field;
 333             private Object instance;
 334             public PrivilegedGetter(Field field, Object instance) {
 335                 super();
 336                 this.field = field;
 337                 this.instance = instance;
 338             }
 339             public Object run() throws IllegalAccessException {
 340                 if (!field.isAccessible()) {
 341                     field.setAccessible(true);
 342                 }
 343                 value = field.get(instance);
 344                 return null;
 345             }
 346         }
 347         private Object getPriv(final Object instance) {
 348             if (field.isAccessible()) {
 349                 try {
 350                     return field.get(instance);
 351                 } catch (Exception e) {
 352                     throw new WebServiceException(e);
 353                 }
 354             } else {
 355                 PrivilegedGetter privilegedGetter = new PrivilegedGetter(field, instance);
 356                 try {
 357                     AccessController.doPrivileged(privilegedGetter);
 358                 } catch (PrivilegedActionException e) {
 359                     throw new WebServiceException(e);
 360                 }
 361                 return privilegedGetter.value;
 362             }
 363         }
 364     }
 365 }