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 } |