jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/spi/db/JAXBWrapperAccessor.java
changeset 23782 953bfc3fbe31
parent 18372 4d90cbb0d70a
equal deleted inserted replaced
23403:85dbdc227c5e 23782:953bfc3fbe31
     1 /*
     1 /*
     2  * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
     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.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    43 import javax.xml.bind.JAXBElement;
    43 import javax.xml.bind.JAXBElement;
    44 import javax.xml.bind.annotation.XmlElement;
    44 import javax.xml.bind.annotation.XmlElement;
    45 import javax.xml.bind.annotation.XmlElementRef;
    45 import javax.xml.bind.annotation.XmlElementRef;
    46 import javax.xml.bind.annotation.XmlElementWrapper;
    46 import javax.xml.bind.annotation.XmlElementWrapper;
    47 import javax.xml.namespace.QName;
    47 import javax.xml.namespace.QName;
       
    48 import javax.xml.ws.WebServiceException;
       
    49 import static com.sun.xml.internal.ws.spi.db.PropertyGetterBase.verifyWrapperType;
    48 
    50 
    49 /**
    51 /**
    50  * JAXBWrapperAccessor
    52  * JAXBWrapperAccessor
    51  *
    53  *
    52  * @author shih-chang.chen@oracle.com
    54  * @author shih-chang.chen@oracle.com
    56 
    58 
    57     protected Class<?> contentClass;
    59     protected Class<?> contentClass;
    58     protected HashMap<Object, Class> elementDeclaredTypes;
    60     protected HashMap<Object, Class> elementDeclaredTypes;
    59 
    61 
    60     public JAXBWrapperAccessor(Class<?> wrapperBean) {
    62     public JAXBWrapperAccessor(Class<?> wrapperBean) {
       
    63         verifyWrapperType(wrapperBean);
    61         contentClass = (Class<?>) wrapperBean;
    64         contentClass = (Class<?>) wrapperBean;
    62 
    65 
    63         HashMap<Object, PropertySetter> setByQName = new HashMap<Object, PropertySetter>();
    66         HashMap<Object, PropertySetter> setByQName = new HashMap<Object, PropertySetter>();
    64         HashMap<Object, PropertySetter> setByLocalpart = new HashMap<Object, PropertySetter>();
    67         HashMap<Object, PropertySetter> setByLocalpart = new HashMap<Object, PropertySetter>();
    65         HashMap<String, Method> publicSetters = new HashMap<String, Method>();
    68         HashMap<String, Method> publicSetters = new HashMap<String, Method>();
   140                         }
   143                         }
   141                     }
   144                     }
   142                 }
   145                 }
   143 
   146 
   144             }
   147             }
   145             // _return
   148             Method setMethod = accessor(publicSetters, fieldName, localName);
   146             if (fieldName.startsWith("_") && !localName.startsWith("_")) {
   149             Method getMethod = accessor(publicGetters, fieldName, localName);
   147                 fieldName = fieldName.substring(1);
   150             if ( isProperty(field, getMethod, setMethod) ) {
   148             }
   151                 PropertySetter setter = createPropertySetter(field, setMethod);
   149             Method setMethod = publicSetters.get(fieldName);
   152                 PropertyGetter getter = createPropertyGetter(field, getMethod);
   150             Method getMethod = publicGetters.get(fieldName);
   153                 setByQName.put(qname, setter);
   151             PropertySetter setter = createPropertySetter(field, setMethod);
   154                 setByLocalpart.put(localName, setter);
   152             PropertyGetter getter = createPropertyGetter(field, getMethod);
   155                 getByQName.put(qname, getter);
   153             setByQName.put(qname, setter);
   156                 getByLocalpart.put(localName, getter);
   154             setByLocalpart.put(localName, setter);
   157             }
   155             getByQName.put(qname, getter);
       
   156             getByLocalpart.put(localName, getter);
       
   157         }
   158         }
   158         if (this.elementLocalNameCollision) {
   159         if (this.elementLocalNameCollision) {
   159             this.propertySetters = setByQName;
   160             this.propertySetters = setByQName;
   160             this.propertyGetters = getByQName;
   161             this.propertyGetters = getByQName;
   161             elementDeclaredTypes = elementDeclaredTypesByQName;
   162             elementDeclaredTypes = elementDeclaredTypesByQName;
   164             this.propertyGetters = getByLocalpart;
   165             this.propertyGetters = getByLocalpart;
   165             elementDeclaredTypes = elementDeclaredTypesByLocalpart;
   166             elementDeclaredTypes = elementDeclaredTypesByLocalpart;
   166         }
   167         }
   167     }
   168     }
   168 
   169 
   169     static protected List<Field> getAllFields(Class<?> clz) {
   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) {
   170         List<Field> list = new ArrayList<Field>();
   189         List<Field> list = new ArrayList<Field>();
   171         while (!Object.class.equals(clz)) {
   190         while (!Object.class.equals(clz)) {
   172             list.addAll(Arrays.asList(getDeclaredFields(clz)));
   191             list.addAll(Arrays.asList(getDeclaredFields(clz)));
   173             clz = clz.getSuperclass();
   192             clz = clz.getSuperclass();
   174         }
   193         }
   175         return list;
   194         return list;
   176     }
   195     }
   177 
   196 
   178     static protected Field[] getDeclaredFields(final Class<?> clz) {
   197     static private Field[] getDeclaredFields(final Class<?> clz) {
   179         try {
   198         try {
   180             return (System.getSecurityManager() == null) ? clz .getDeclaredFields() :
   199             return AccessController.doPrivileged(new PrivilegedExceptionAction<Field[]>() {
   181                 AccessController.doPrivileged(new PrivilegedExceptionAction<Field[]>() {
       
   182                         @Override
   200                         @Override
   183                         public Field[] run() throws IllegalAccessException {
   201                         public Field[] run() throws IllegalAccessException {
   184                             return clz.getDeclaredFields();
   202                             return clz.getDeclaredFields();
   185                         }
   203                         }
   186                     });
   204                     });
   187         } catch (PrivilegedActionException e) {
   205         } catch (PrivilegedActionException e) {
   188             // TODO Auto-generated catch block
   206             throw new WebServiceException(e);
   189             e.printStackTrace();
   207         }
   190             return null;
   208     }
   191         }
   209 
   192     }
   210     static private PropertyGetter createPropertyGetter(Field field, Method getMethod) {
   193 
       
   194     static protected PropertyGetter createPropertyGetter(Field field, Method getMethod) {
       
   195         if (!field.isAccessible()) {
   211         if (!field.isAccessible()) {
   196             if (getMethod != null) {
   212             if (getMethod != null) {
   197                 MethodGetter methodGetter = new MethodGetter(getMethod);
   213                 MethodGetter methodGetter = new MethodGetter(getMethod);
   198                 if (methodGetter.getType().toString().equals(field.getType().toString())) {
   214                 if (methodGetter.getType().toString().equals(field.getType().toString())) {
   199                     return methodGetter;
   215                     return methodGetter;
   200                 }
   216                 }
   201             }
   217             }
   202         }
   218         }
   203         return new FieldGetter(field);
   219         return new PrivFieldGetter(field);
   204     }
   220     }
   205 
   221 
   206     static protected PropertySetter createPropertySetter(Field field,
   222     static private PropertySetter createPropertySetter(Field field,
   207             Method setter) {
   223             Method setter) {
   208         if (!field.isAccessible()) {
   224         if (!field.isAccessible()) {
   209             if (setter != null) {
   225             if (setter != null) {
   210                 MethodSetter injection = new MethodSetter(setter);
   226                 MethodSetter injection = new MethodSetter(setter);
   211                 if (injection.getType().toString().equals(field.getType().toString())) {
   227                 if (injection.getType().toString().equals(field.getType().toString())) {
   212                     return injection;
   228                     return injection;
   213                 }
   229                 }
   214             }
   230             }
   215         }
   231         }
   216         return new FieldSetter(field);
   232         return new PrivFieldSetter(field);
   217     }
   233     }
   218 
   234 
   219     private Class getElementDeclaredType(QName name) {
   235     private Class getElementDeclaredType(QName name) {
   220         Object key = (this.elementLocalNameCollision) ? name : name
   236         Object key = (this.elementLocalNameCollision) ? name : name
   221                 .getLocalPart();
   237                 .getLocalPart();
   236         return new PropertyAccessor() {
   252         return new PropertyAccessor() {
   237             @Override
   253             @Override
   238             public Object get(Object bean) throws DatabindingException {
   254             public Object get(Object bean) throws DatabindingException {
   239                 Object val;
   255                 Object val;
   240                 if (isJAXBElement) {
   256                 if (isJAXBElement) {
   241                     JAXBElement<Object> jaxbElement = (JAXBElement<Object>) getter.get(bean);
   257                     JAXBElement<Object> jaxbElement = (JAXBElement<Object>) JAXBWrapperAccessor.get(getter, bean);
   242                     val = (jaxbElement == null) ? null : jaxbElement.getValue();
   258                     val = (jaxbElement == null) ? null : jaxbElement.getValue();
   243                 } else {
   259                 } else {
   244                     val = getter.get(bean);
   260                     val = JAXBWrapperAccessor.get(getter, bean);
   245                 }
   261                 }
   246                 if (val == null && isListType) {
   262                 if (val == null && isListType) {
   247                     val = new java.util.ArrayList();
   263                     val = new java.util.ArrayList();
   248                     set(bean, val);
   264                     set(bean, val);
   249                 }
   265                 }
   253             @Override
   269             @Override
   254             public void set(Object bean, Object value) throws DatabindingException {
   270             public void set(Object bean, Object value) throws DatabindingException {
   255                 if (isJAXBElement) {
   271                 if (isJAXBElement) {
   256                     JAXBElement<Object> jaxbElement = new JAXBElement<Object>(
   272                     JAXBElement<Object> jaxbElement = new JAXBElement<Object>(
   257                             n, elementDeclaredType, contentClass, value);
   273                             n, elementDeclaredType, contentClass, value);
   258                     setter.set(bean, jaxbElement);
   274                     JAXBWrapperAccessor.set(setter, bean, jaxbElement);
   259                 } else {
   275                 } else {
   260                     setter.set(bean, value);
   276                     JAXBWrapperAccessor.set(setter, bean, value);
   261                 }
   277                 }
   262             }
   278             }
   263         };
   279         };
   264     }
   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     }
   265 }
   365 }