1 /*
2  * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Distribution License v. 1.0, which is available at
6  * http://www.eclipse.org/org/documents/edl-v10.php.
7  *
8  * SPDX-License-Identifier: BSD-3-Clause
9  */

10
11 package com.sun.xml.bind.v2.runtime.property;
12
13 import java.io.IOException;
14
15 import javax.xml.stream.XMLStreamException;
16
17 import com.sun.xml.bind.api.AccessorException;
18 import com.sun.xml.bind.v2.util.QNameMap;
19 import com.sun.xml.bind.v2.model.core.AttributePropertyInfo;
20 import com.sun.xml.bind.v2.model.core.PropertyKind;
21 import com.sun.xml.bind.v2.model.runtime.RuntimeAttributePropertyInfo;
22 import com.sun.xml.bind.v2.runtime.JAXBContextImpl;
23 import com.sun.xml.bind.v2.runtime.Name;
24 import com.sun.xml.bind.v2.runtime.XMLSerializer;
25 import com.sun.xml.bind.v2.runtime.JaxBeanInfo;
26 import com.sun.xml.bind.v2.runtime.unmarshaller.ChildLoader;
27 import com.sun.xml.bind.v2.runtime.reflect.Accessor;
28 import com.sun.xml.bind.v2.runtime.reflect.TransducedAccessor;
29
30 import org.xml.sax.SAXException;
31
32 /**
33  * {@link Property} implementation for {@link AttributePropertyInfo}.
34  *
35  * <p>
36  * This one works for both leaves and nodes, scalars and arrays.
37  *
38  * <p>
39  * Implements {@link Comparable} so that it can be sorted lexicographically.
40  *
41  * @author Kohsuke Kawaguchi (kk@kohsuke.org)
42  */

43 public final class AttributeProperty<BeanT> extends PropertyImpl<BeanT>
44     implements Comparable<AttributeProperty> {
45
46     /**
47      * Attribute name.
48      */

49     public final Name attName;
50
51     /**
52      * Heart of the conversion logic.
53      */

54     public final TransducedAccessor<BeanT> xacc;
55
56     private final Accessor acc;
57
58     public AttributeProperty(JAXBContextImpl context, RuntimeAttributePropertyInfo prop) {
59         super(context,prop);
60         this.attName = context.nameBuilder.createAttributeName(prop.getXmlName());
61         this.xacc = TransducedAccessor.get(context,prop);
62         this.acc = prop.getAccessor();   // we only use this for binder, so don't waste memory by optimizing
63     }
64
65     /**
66      * Marshals one attribute.
67      *
68      * @see JaxBeanInfo#serializeAttributes(Object, XMLSerializer)
69      */

70     public void serializeAttributes(BeanT o, XMLSerializer w) throws SAXException, AccessorException, IOException, XMLStreamException {
71         CharSequence value = xacc.print(o);
72         if(value!=null)
73             w.attribute(attName,value.toString());
74     }
75
76     public void serializeURIs(BeanT o, XMLSerializer w) throws AccessorException, SAXException {
77         xacc.declareNamespace(o,w);
78     }
79
80     public boolean hasSerializeURIAction() {
81         return xacc.useNamespace();
82     }
83
84     public void buildChildElementUnmarshallers(UnmarshallerChain chainElem, QNameMap<ChildLoader> handlers) {
85         throw new IllegalStateException();
86     }
87
88    
89     public PropertyKind getKind() {
90         return PropertyKind.ATTRIBUTE;
91     }
92
93     public void reset(BeanT o) throws AccessorException {
94         acc.set(o,null);
95     }
96
97     public String getIdValue(BeanT bean) throws AccessorException, SAXException {
98         return xacc.print(bean).toString();
99     }
100
101     public int compareTo(AttributeProperty that) {
102         return this.attName.compareTo(that.attName);
103     }
104 }
105