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
39
40 import javax.xml.bind.JAXBElement;
41 import javax.xml.bind.annotation.adapters.XmlAdapter;
42
43 import com.sun.istack.internal.Nullable;
44 import com.sun.xml.internal.bind.Util;
45 import com.sun.xml.internal.bind.api.AccessorException;
46 import com.sun.xml.internal.bind.api.JAXBRIContext;
47 import com.sun.xml.internal.bind.v2.model.core.Adapter;
48 import com.sun.xml.internal.bind.v2.model.impl.RuntimeModelBuilder;
49 import com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl;
50 import com.sun.xml.internal.bind.v2.runtime.reflect.opt.OptimizedAccessorFactory;
51 import com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader;
52 import com.sun.xml.internal.bind.v2.runtime.unmarshaller.Receiver;
53 import com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext;
54
55 import org.xml.sax.SAXException;
56
57 /**
58 * Accesses a particular property of a bean.
59 * <p/>
60 * <p/>
61 * This interface encapsulates the access to the actual data store.
62 * The intention is to generate implementations for a particular bean
63 * and a property to improve the performance.
64 * <p/>
65 * <p/>
66 * Accessor can be used as a receiver. Upon receiving an object
67 * it sets that to the field.
68 *
69 * @author Kohsuke Kawaguchi (kk@kohsuke.org)
70 * @see Accessor.FieldReflection
71 * @see TransducedAccessor
72 */
73 public abstract class Accessor<BeanT, ValueT> implements Receiver {
74
75 public final Class<ValueT> valueType;
76
77 public Class<ValueT> getValueType() {
78 return valueType;
79 }
80
81 protected Accessor(Class<ValueT> valueType) {
82 this.valueType = valueType;
83 }
84
85 /**
102 * may throw an exception.
103 * @since 2.0 EA1
104 */
105 public abstract ValueT get(BeanT bean) throws AccessorException;
106
107 /**
108 * Sets the value of the property of the given bean object.
109 *
110 * @param bean must not be null.
111 * @param value the value to be set. Setting value to null means resetting
112 * to the VM default value (even for primitive properties.)
113 * @throws AccessorException if failed to set a value. For example, the setter method
114 * may throw an exception.
115 * @since 2.0 EA1
116 */
117 public abstract void set(BeanT bean, ValueT value) throws AccessorException;
118
119
120 /**
121 * Sets the value without adapting the value.
122 * <p/>
123 * This ugly entry point is only used by JAX-WS.
124 * See {@link JAXBRIContext#getElementPropertyAccessor}
125 */
126 public Object getUnadapted(BeanT bean) throws AccessorException {
127 return get(bean);
128 }
129
130 /**
131 * Returns true if this accessor wraps an adapter.
132 * <p/>
133 * This method needs to be used with care, but it helps some optimization.
134 */
135 public boolean isAdapted() {
136 return false;
137 }
138
139 /**
140 * Sets the value without adapting the value.
141 * <p/>
142 * This ugly entry point is only used by JAX-WS.
143 * See {@link JAXBRIContext#getElementPropertyAccessor}
144 */
145 public void setUnadapted(BeanT bean, Object value) throws AccessorException {
146 set(bean, (ValueT) value);
147 }
148
149 public void receive(UnmarshallingContext.State state, Object o) throws SAXException {
150 try {
151 set((BeanT) state.getTarget(), (ValueT) o);
152 } catch (AccessorException e) {
153 Loader.handleGenericException(e, true);
154 } catch (IllegalAccessError iae) {
155 // throw UnmarshalException instead IllegalAccesssError | Issue 475
156 Loader.handleGenericError(iae);
157 }
158 }
159
160 private static List<Class> nonAbstractableClasses = Arrays.asList(new Class[]{
161 Object.class,
377
378 @Override
379 public Accessor<BeanT, ValueT> optimize(JAXBContextImpl context) {
380 if (getter == null || setter == null)
381 // if we aren't complete, OptimizedAccessor won't always work
382 return this;
383 if (context != null && context.fastBoot)
384 // let's not waste time on doing this for the sake of faster boot.
385 return this;
386
387 Accessor<BeanT, ValueT> acc = OptimizedAccessorFactory.get(getter, setter);
388 if (acc != null)
389 return acc;
390 else
391 return this;
392 }
393 }
394
395 /**
396 * A version of {@link GetterSetterReflection} that doesn't have any setter.
397 * <p/>
398 * <p/>
399 * This provides a user-friendly error message.
400 */
401 public static class GetterOnlyReflection<BeanT, ValueT> extends GetterSetterReflection<BeanT, ValueT> {
402 public GetterOnlyReflection(Method getter) {
403 super(getter, null);
404 }
405
406 @Override
407 public void set(BeanT bean, ValueT value) throws AccessorException {
408 throw new AccessorException(Messages.NO_SETTER.format(getter.toString()));
409 }
410 }
411
412 /**
413 * A version of {@link GetterSetterReflection} thaat doesn't have any getter.
414 * <p/>
415 * <p/>
416 * This provides a user-friendly error message.
417 */
418 public static class SetterOnlyReflection<BeanT, ValueT> extends GetterSetterReflection<BeanT, ValueT> {
419 public SetterOnlyReflection(Method setter) {
420 super(null, setter);
421 }
422
423 @Override
424 public ValueT get(BeanT bean) throws AccessorException {
425 throw new AccessorException(Messages.NO_GETTER.format(setter.toString()));
426 }
427 }
428
429 /**
430 * Gets the special {@link Accessor} used to recover from errors.
431 */
432 @SuppressWarnings("unchecked")
433 public static <A, B> Accessor<A, B> getErrorInstance() {
434 return ERROR;
435 }
|
1 /*
2 * Copyright (c) 1997, 2015, 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
39
40 import javax.xml.bind.JAXBElement;
41 import javax.xml.bind.annotation.adapters.XmlAdapter;
42
43 import com.sun.istack.internal.Nullable;
44 import com.sun.xml.internal.bind.Util;
45 import com.sun.xml.internal.bind.api.AccessorException;
46 import com.sun.xml.internal.bind.api.JAXBRIContext;
47 import com.sun.xml.internal.bind.v2.model.core.Adapter;
48 import com.sun.xml.internal.bind.v2.model.impl.RuntimeModelBuilder;
49 import com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl;
50 import com.sun.xml.internal.bind.v2.runtime.reflect.opt.OptimizedAccessorFactory;
51 import com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader;
52 import com.sun.xml.internal.bind.v2.runtime.unmarshaller.Receiver;
53 import com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext;
54
55 import org.xml.sax.SAXException;
56
57 /**
58 * Accesses a particular property of a bean.
59 * <p>
60 * <p>
61 * This interface encapsulates the access to the actual data store.
62 * The intention is to generate implementations for a particular bean
63 * and a property to improve the performance.
64 * <p>
65 * <p>
66 * Accessor can be used as a receiver. Upon receiving an object
67 * it sets that to the field.
68 *
69 * @author Kohsuke Kawaguchi (kk@kohsuke.org)
70 * @see Accessor.FieldReflection
71 * @see TransducedAccessor
72 */
73 public abstract class Accessor<BeanT, ValueT> implements Receiver {
74
75 public final Class<ValueT> valueType;
76
77 public Class<ValueT> getValueType() {
78 return valueType;
79 }
80
81 protected Accessor(Class<ValueT> valueType) {
82 this.valueType = valueType;
83 }
84
85 /**
102 * may throw an exception.
103 * @since 2.0 EA1
104 */
105 public abstract ValueT get(BeanT bean) throws AccessorException;
106
107 /**
108 * Sets the value of the property of the given bean object.
109 *
110 * @param bean must not be null.
111 * @param value the value to be set. Setting value to null means resetting
112 * to the VM default value (even for primitive properties.)
113 * @throws AccessorException if failed to set a value. For example, the setter method
114 * may throw an exception.
115 * @since 2.0 EA1
116 */
117 public abstract void set(BeanT bean, ValueT value) throws AccessorException;
118
119
120 /**
121 * Sets the value without adapting the value.
122 * <p>
123 * This ugly entry point is only used by JAX-WS.
124 * See {@link JAXBRIContext#getElementPropertyAccessor}
125 */
126 public Object getUnadapted(BeanT bean) throws AccessorException {
127 return get(bean);
128 }
129
130 /**
131 * Returns true if this accessor wraps an adapter.
132 * <p>
133 * This method needs to be used with care, but it helps some optimization.
134 */
135 public boolean isAdapted() {
136 return false;
137 }
138
139 /**
140 * Sets the value without adapting the value.
141 * <p>
142 * This ugly entry point is only used by JAX-WS.
143 * See {@link JAXBRIContext#getElementPropertyAccessor}
144 */
145 public void setUnadapted(BeanT bean, Object value) throws AccessorException {
146 set(bean, (ValueT) value);
147 }
148
149 public void receive(UnmarshallingContext.State state, Object o) throws SAXException {
150 try {
151 set((BeanT) state.getTarget(), (ValueT) o);
152 } catch (AccessorException e) {
153 Loader.handleGenericException(e, true);
154 } catch (IllegalAccessError iae) {
155 // throw UnmarshalException instead IllegalAccesssError | Issue 475
156 Loader.handleGenericError(iae);
157 }
158 }
159
160 private static List<Class> nonAbstractableClasses = Arrays.asList(new Class[]{
161 Object.class,
377
378 @Override
379 public Accessor<BeanT, ValueT> optimize(JAXBContextImpl context) {
380 if (getter == null || setter == null)
381 // if we aren't complete, OptimizedAccessor won't always work
382 return this;
383 if (context != null && context.fastBoot)
384 // let's not waste time on doing this for the sake of faster boot.
385 return this;
386
387 Accessor<BeanT, ValueT> acc = OptimizedAccessorFactory.get(getter, setter);
388 if (acc != null)
389 return acc;
390 else
391 return this;
392 }
393 }
394
395 /**
396 * A version of {@link GetterSetterReflection} that doesn't have any setter.
397 * <p>
398 * <p>
399 * This provides a user-friendly error message.
400 */
401 public static class GetterOnlyReflection<BeanT, ValueT> extends GetterSetterReflection<BeanT, ValueT> {
402 public GetterOnlyReflection(Method getter) {
403 super(getter, null);
404 }
405
406 @Override
407 public void set(BeanT bean, ValueT value) throws AccessorException {
408 throw new AccessorException(Messages.NO_SETTER.format(getter.toString()));
409 }
410 }
411
412 /**
413 * A version of {@link GetterSetterReflection} thaat doesn't have any getter.
414 * <p>
415 * <p>
416 * This provides a user-friendly error message.
417 */
418 public static class SetterOnlyReflection<BeanT, ValueT> extends GetterSetterReflection<BeanT, ValueT> {
419 public SetterOnlyReflection(Method setter) {
420 super(null, setter);
421 }
422
423 @Override
424 public ValueT get(BeanT bean) throws AccessorException {
425 throw new AccessorException(Messages.NO_GETTER.format(setter.toString()));
426 }
427 }
428
429 /**
430 * Gets the special {@link Accessor} used to recover from errors.
431 */
432 @SuppressWarnings("unchecked")
433 public static <A, B> Accessor<A, B> getErrorInstance() {
434 return ERROR;
435 }
|