1 29 30 package com.caucho.jaxb.skeleton; 31 32 import com.caucho.jaxb.JAXBContextImpl; 33 import com.caucho.util.L10N; 34 35 import javax.xml.bind.JAXBException; 36 import javax.xml.bind.Marshaller; 37 import javax.xml.bind.Unmarshaller; 38 39 import javax.xml.bind.annotation.XmlAttribute; 40 import javax.xml.bind.annotation.XmlElement; 41 import javax.xml.bind.annotation.XmlElementWrapper; 42 import javax.xml.bind.annotation.XmlType; 43 44 import javax.xml.namespace.QName ; 45 46 import javax.xml.stream.XMLStreamException; 47 import javax.xml.stream.XMLStreamReader; 48 import javax.xml.stream.XMLStreamWriter; 49 50 import javax.xml.XMLConstants ; 51 52 import java.beans.PropertyDescriptor ; 53 54 import java.lang.annotation.Annotation ; 55 56 import java.lang.reflect.Field ; 57 import java.lang.reflect.GenericArrayType ; 58 import java.lang.reflect.Method ; 59 import java.lang.reflect.ParameterizedType ; 60 import java.lang.reflect.Type ; 61 62 import java.io.IOException ; 63 64 import java.util.Map ; 65 66 67 public abstract class Accessor { 68 public static final L10N L = new L10N(Accessor.class); 69 70 public static final String XML_SCHEMA_PREFIX = "xsd"; 71 public static final String XML_INSTANCE_PREFIX = "xsi"; 72 73 private static boolean _generateRICompatibleSchema = true; 74 75 protected JAXBContextImpl _context; 76 protected Property _property; 77 78 public static void setGenerateRICompatibleSchema(boolean compatible) 79 { 80 _generateRICompatibleSchema = compatible; 81 } 82 83 protected Accessor(JAXBContextImpl context) 84 { 85 _context = context; 86 } 87 88 public JAXBContextImpl getContext() 89 { 90 return _context; 91 } 92 93 public void write(Marshaller m, XMLStreamWriter out, Object obj) 94 throws IOException , XMLStreamException, JAXBException 95 { 96 98 _property.write(m, out, obj, getQName()); 99 100 } 102 103 public Object read(Unmarshaller u, XMLStreamReader in) 104 throws IOException , XMLStreamException, JAXBException 105 { 106 return _property.read(u, in, getQName()); 107 } 108 109 protected void writeStartElement(XMLStreamWriter out, Object obj) 110 throws IOException , XMLStreamException, JAXBException 111 { 112 XmlElementWrapper wrapper = getAnnotation(XmlElementWrapper.class); 114 XmlElement element = getAnnotation(XmlElement.class); 115 116 if (wrapper != null) { 117 if (obj == null && ! wrapper.nillable()) 118 return; 119 120 if (wrapper.name().equals("##default")) 121 out.writeStartElement(getName()); 122 else if (wrapper.namespace().equals("##default")) 123 out.writeStartElement(wrapper.name()); 124 else 125 out.writeStartElement(wrapper.namespace(), wrapper.name()); 126 127 if (obj == null) { 128 out.writeAttribute(XML_INSTANCE_PREFIX, 129 XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, 130 "nil", "true"); 131 } 132 } 133 else if (element != null) { 134 if (obj == null && ! element.nillable()) 135 return; 136 137 if (element.name().equals("##default")) 138 out.writeStartElement(getName()); 139 else if (element.namespace().equals("##default")) 140 out.writeStartElement(element.name()); 141 else 142 out.writeStartElement(element.namespace(), element.name()); 143 144 if (obj == null) { 145 out.writeAttribute(XML_INSTANCE_PREFIX, 146 XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, 147 "nil", "true"); 148 } 149 } 150 else { 151 if (obj == null) return; 152 153 QName qname = getQName(); 154 155 if (qname.getNamespaceURI() == null || "".equals(qname.getNamespaceURI())) 156 out.writeStartElement(qname.getLocalPart()); 157 else 158 out.writeStartElement(qname.getNamespaceURI(), qname.getLocalPart()); 159 } 160 } 161 162 protected void writeEndElement(XMLStreamWriter out, Object obj) 163 throws IOException , XMLStreamException, JAXBException 164 { 165 XmlElementWrapper wrapper = getAnnotation(XmlElementWrapper.class); 166 XmlElement element = getAnnotation(XmlElement.class); 167 168 if (wrapper != null) { 169 if (obj == null && !wrapper.nillable()) 170 return; 171 } 172 else if (element != null) { 173 if (obj == null && !element.nillable()) 174 return; 175 } 176 else { 177 if (obj == null) return; 178 } 179 180 out.writeEndElement(); 181 } 182 183 private QName getTypeQName() 184 { 185 XmlType xmlType = getAnnotation(XmlType.class); 186 187 if (xmlType == null || xmlType.name().equals("#default")) 188 return new QName (getName()); 189 190 if (xmlType.namespace().equals("#default")) 191 return new QName (xmlType.name()); 192 193 return new QName (xmlType.namespace(), xmlType.name()); 194 } 195 196 private QName getQName() 197 { 198 XmlElementWrapper wrapper = getAnnotation(XmlElementWrapper.class); 199 XmlElement element = getAnnotation(XmlElement.class); 200 201 if (wrapper != null) { 202 if (wrapper.name().equals("##default")) 203 return getTypeQName(); 204 else if (wrapper.namespace().equals("##default")) 205 return new QName (wrapper.name()); 206 else 207 return new QName (wrapper.namespace(), wrapper.name()); 208 } 209 else if (element != null) { 210 if (element.name().equals("##default")) 211 return getTypeQName(); 212 else if (element.namespace().equals("##default")) 213 return new QName (element.name()); 214 else 215 return new QName (element.namespace(), element.name()); 216 } 217 218 return getTypeQName(); 219 } 220 221 public void generateSchema(XMLStreamWriter out) 222 throws JAXBException, XMLStreamException 223 { 224 XmlAttribute attribute = getAnnotation(XmlAttribute.class); 225 226 if (attribute != null) { 227 out.writeEmptyElement(XML_SCHEMA_PREFIX, "attribute", 228 XMLConstants.W3C_XML_SCHEMA_NS_URI); 229 230 233 if (attribute.required() || 234 (_generateRICompatibleSchema && getType().isPrimitive())) 235 out.writeAttribute("use", "required"); 236 } 237 else { 238 out.writeEmptyElement(XML_SCHEMA_PREFIX, "element", 239 XMLConstants.W3C_XML_SCHEMA_NS_URI); 240 241 XmlElement element = getAnnotation(XmlElement.class); 242 243 if (! _generateRICompatibleSchema || ! getType().isPrimitive()) { 244 if (element != null) { 245 if (element.required()) 246 out.writeAttribute("minOccurs", "1"); 247 else 248 out.writeAttribute("minOccurs", "0"); 249 250 if (element.nillable()) 251 out.writeAttribute("nillable", "true"); 252 } 253 else 254 out.writeAttribute("minOccurs", "0"); 255 } 256 257 if (_property.getMaxOccurs() != null) 258 out.writeAttribute("maxOccurs", _property.getMaxOccurs()); 259 } 260 261 out.writeAttribute("type", _property.getSchemaType()); 262 out.writeAttribute("name", getName()); 263 } 264 265 public boolean isXmlPrimitiveType() 266 { 267 return _property.isXmlPrimitiveType(); 268 } 269 270 public String getSchemaType() 271 { 272 return _property.getSchemaType(); 273 } 274 275 public abstract Object get(Object o) throws JAXBException; 276 public abstract void set(Object o, Object value) throws JAXBException; 277 public abstract String getName(); 278 public abstract Class getType(); 279 public abstract Type getGenericType(); 280 public abstract <A extends Annotation > A getAnnotation(Class <A> c); 281 } 282 | Popular Tags |