Mon, 28 May 2018 10:36:45 +0800
Merge
aoqi@0 | 1 | /* |
aoqi@0 | 2 | * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
aoqi@0 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
aoqi@0 | 4 | * |
aoqi@0 | 5 | * This code is free software; you can redistribute it and/or modify it |
aoqi@0 | 6 | * under the terms of the GNU General Public License version 2 only, as |
aoqi@0 | 7 | * published by the Free Software Foundation. Oracle designates this |
aoqi@0 | 8 | * particular file as subject to the "Classpath" exception as provided |
aoqi@0 | 9 | * by Oracle in the LICENSE file that accompanied this code. |
aoqi@0 | 10 | * |
aoqi@0 | 11 | * This code is distributed in the hope that it will be useful, but WITHOUT |
aoqi@0 | 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
aoqi@0 | 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
aoqi@0 | 14 | * version 2 for more details (a copy is included in the LICENSE file that |
aoqi@0 | 15 | * accompanied this code). |
aoqi@0 | 16 | * |
aoqi@0 | 17 | * You should have received a copy of the GNU General Public License version |
aoqi@0 | 18 | * 2 along with this work; if not, write to the Free Software Foundation, |
aoqi@0 | 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
aoqi@0 | 20 | * |
aoqi@0 | 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
aoqi@0 | 22 | * or visit www.oracle.com if you need additional information or have any |
aoqi@0 | 23 | * questions. |
aoqi@0 | 24 | */ |
aoqi@0 | 25 | |
aoqi@0 | 26 | package com.sun.xml.internal.bind.v2.runtime; |
aoqi@0 | 27 | |
aoqi@0 | 28 | import java.io.IOException; |
aoqi@0 | 29 | import java.lang.reflect.InvocationTargetException; |
aoqi@0 | 30 | import java.lang.reflect.Method; |
aoqi@0 | 31 | import java.lang.reflect.Modifier; |
aoqi@0 | 32 | import java.util.Collection; |
aoqi@0 | 33 | import java.util.Collections; |
aoqi@0 | 34 | import java.util.List; |
aoqi@0 | 35 | import java.util.Map; |
aoqi@0 | 36 | import java.util.logging.Level; |
aoqi@0 | 37 | import java.util.logging.Logger; |
aoqi@0 | 38 | |
aoqi@0 | 39 | import javax.xml.bind.ValidationEvent; |
aoqi@0 | 40 | import javax.xml.bind.annotation.XmlRootElement; |
aoqi@0 | 41 | import javax.xml.bind.helpers.ValidationEventImpl; |
aoqi@0 | 42 | import javax.xml.namespace.QName; |
aoqi@0 | 43 | import javax.xml.stream.XMLStreamException; |
aoqi@0 | 44 | |
aoqi@0 | 45 | import com.sun.istack.internal.FinalArrayList; |
aoqi@0 | 46 | import com.sun.xml.internal.bind.Util; |
aoqi@0 | 47 | import com.sun.xml.internal.bind.api.AccessorException; |
aoqi@0 | 48 | import com.sun.xml.internal.bind.v2.ClassFactory; |
aoqi@0 | 49 | import com.sun.xml.internal.bind.v2.WellKnownNamespace; |
aoqi@0 | 50 | import com.sun.xml.internal.bind.v2.model.core.ID; |
aoqi@0 | 51 | import com.sun.xml.internal.bind.v2.model.runtime.RuntimeClassInfo; |
aoqi@0 | 52 | import com.sun.xml.internal.bind.v2.model.runtime.RuntimePropertyInfo; |
aoqi@0 | 53 | import com.sun.xml.internal.bind.v2.runtime.property.AttributeProperty; |
aoqi@0 | 54 | import com.sun.xml.internal.bind.v2.runtime.property.Property; |
aoqi@0 | 55 | import com.sun.xml.internal.bind.v2.runtime.property.PropertyFactory; |
aoqi@0 | 56 | import com.sun.xml.internal.bind.v2.runtime.reflect.Accessor; |
aoqi@0 | 57 | import com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader; |
aoqi@0 | 58 | import com.sun.xml.internal.bind.v2.runtime.unmarshaller.StructureLoader; |
aoqi@0 | 59 | import com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext; |
aoqi@0 | 60 | import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiTypeLoader; |
aoqi@0 | 61 | |
aoqi@0 | 62 | import org.xml.sax.Locator; |
aoqi@0 | 63 | import org.xml.sax.SAXException; |
aoqi@0 | 64 | import org.xml.sax.helpers.LocatorImpl; |
aoqi@0 | 65 | |
aoqi@0 | 66 | /** |
aoqi@0 | 67 | * {@link JaxBeanInfo} implementation for j2s bean. |
aoqi@0 | 68 | * |
aoqi@0 | 69 | * @author Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com) |
aoqi@0 | 70 | */ |
aoqi@0 | 71 | public final class ClassBeanInfoImpl<BeanT> extends JaxBeanInfo<BeanT> implements AttributeAccessor<BeanT> { |
aoqi@0 | 72 | |
aoqi@0 | 73 | /** |
aoqi@0 | 74 | * Properties of this bean class but not its ancestor classes. |
aoqi@0 | 75 | */ |
aoqi@0 | 76 | public final Property<BeanT>[] properties; |
aoqi@0 | 77 | |
aoqi@0 | 78 | /** |
aoqi@0 | 79 | * Non-null if this bean has an ID property. |
aoqi@0 | 80 | */ |
aoqi@0 | 81 | private Property<? super BeanT> idProperty; |
aoqi@0 | 82 | |
aoqi@0 | 83 | /** |
aoqi@0 | 84 | * Immutable configured loader for this class. |
aoqi@0 | 85 | * |
aoqi@0 | 86 | * <p> |
aoqi@0 | 87 | * Set from the link method, but considered final. |
aoqi@0 | 88 | */ |
aoqi@0 | 89 | private Loader loader; |
aoqi@0 | 90 | private Loader loaderWithTypeSubst; |
aoqi@0 | 91 | |
aoqi@0 | 92 | /** |
aoqi@0 | 93 | * Set only until the link phase to avoid leaking memory. |
aoqi@0 | 94 | */ |
aoqi@0 | 95 | private RuntimeClassInfo ci; |
aoqi@0 | 96 | |
aoqi@0 | 97 | private final Accessor<? super BeanT,Map<QName,String>> inheritedAttWildcard; |
aoqi@0 | 98 | private final Transducer<BeanT> xducer; |
aoqi@0 | 99 | |
aoqi@0 | 100 | /** |
aoqi@0 | 101 | * {@link ClassBeanInfoImpl} that represents the super class of {@link #jaxbType}. |
aoqi@0 | 102 | */ |
aoqi@0 | 103 | public final ClassBeanInfoImpl<? super BeanT> superClazz; |
aoqi@0 | 104 | |
aoqi@0 | 105 | private final Accessor<? super BeanT,Locator> xmlLocatorField; |
aoqi@0 | 106 | |
aoqi@0 | 107 | private final Name tagName; |
aoqi@0 | 108 | |
aoqi@0 | 109 | private boolean retainPropertyInfo = false; |
aoqi@0 | 110 | |
aoqi@0 | 111 | /** |
aoqi@0 | 112 | * The {@link AttributeProperty}s for this type and all its ancestors. |
aoqi@0 | 113 | * If {@link JAXBContextImpl#c14nSupport} is true, this is sorted alphabetically. |
aoqi@0 | 114 | */ |
aoqi@0 | 115 | private /*final*/ AttributeProperty<BeanT>[] attributeProperties; |
aoqi@0 | 116 | |
aoqi@0 | 117 | /** |
aoqi@0 | 118 | * {@link Property}s that need to receive {@link Property#serializeURIs(Object, XMLSerializer)} callback. |
aoqi@0 | 119 | */ |
aoqi@0 | 120 | private /*final*/ Property<BeanT>[] uriProperties; |
aoqi@0 | 121 | |
aoqi@0 | 122 | private final Method factoryMethod; |
aoqi@0 | 123 | |
aoqi@0 | 124 | /*package*/ ClassBeanInfoImpl(JAXBContextImpl owner, RuntimeClassInfo ci) { |
aoqi@0 | 125 | super(owner,ci,ci.getClazz(),ci.getTypeName(),ci.isElement(),false,true); |
aoqi@0 | 126 | |
aoqi@0 | 127 | this.ci = ci; |
aoqi@0 | 128 | this.inheritedAttWildcard = ci.getAttributeWildcard(); |
aoqi@0 | 129 | this.xducer = ci.getTransducer(); |
aoqi@0 | 130 | this.factoryMethod = ci.getFactoryMethod(); |
aoqi@0 | 131 | this.retainPropertyInfo = owner.retainPropertyInfo; |
aoqi@0 | 132 | |
aoqi@0 | 133 | // make the factory accessible |
aoqi@0 | 134 | if(factoryMethod!=null) { |
aoqi@0 | 135 | int classMod = factoryMethod.getDeclaringClass().getModifiers(); |
aoqi@0 | 136 | |
aoqi@0 | 137 | if(!Modifier.isPublic(classMod) || !Modifier.isPublic(factoryMethod.getModifiers())) { |
aoqi@0 | 138 | // attempt to make it work even if the constructor is not accessible |
aoqi@0 | 139 | try { |
aoqi@0 | 140 | factoryMethod.setAccessible(true); |
aoqi@0 | 141 | } catch(SecurityException e) { |
aoqi@0 | 142 | // but if we don't have a permission to do so, work gracefully. |
aoqi@0 | 143 | logger.log(Level.FINE,"Unable to make the method of "+factoryMethod+" accessible",e); |
aoqi@0 | 144 | throw e; |
aoqi@0 | 145 | } |
aoqi@0 | 146 | } |
aoqi@0 | 147 | } |
aoqi@0 | 148 | |
aoqi@0 | 149 | |
aoqi@0 | 150 | if(ci.getBaseClass()==null) |
aoqi@0 | 151 | this.superClazz = null; |
aoqi@0 | 152 | else |
aoqi@0 | 153 | this.superClazz = owner.getOrCreate(ci.getBaseClass()); |
aoqi@0 | 154 | |
aoqi@0 | 155 | if(superClazz!=null && superClazz.xmlLocatorField!=null) |
aoqi@0 | 156 | xmlLocatorField = superClazz.xmlLocatorField; |
aoqi@0 | 157 | else |
aoqi@0 | 158 | xmlLocatorField = ci.getLocatorField(); |
aoqi@0 | 159 | |
aoqi@0 | 160 | // create property objects |
aoqi@0 | 161 | Collection<? extends RuntimePropertyInfo> ps = ci.getProperties(); |
aoqi@0 | 162 | this.properties = new Property[ps.size()]; |
aoqi@0 | 163 | int idx=0; |
aoqi@0 | 164 | boolean elementOnly = true; |
aoqi@0 | 165 | for( RuntimePropertyInfo info : ps ) { |
aoqi@0 | 166 | Property p = PropertyFactory.create(owner,info); |
aoqi@0 | 167 | if(info.id()==ID.ID) |
aoqi@0 | 168 | idProperty = p; |
aoqi@0 | 169 | properties[idx++] = p; |
aoqi@0 | 170 | elementOnly &= info.elementOnlyContent(); |
aoqi@0 | 171 | checkOverrideProperties(p); |
aoqi@0 | 172 | } |
aoqi@0 | 173 | // super class' idProperty might not be computed at this point, |
aoqi@0 | 174 | // so check that later |
aoqi@0 | 175 | |
aoqi@0 | 176 | hasElementOnlyContentModel( elementOnly ); |
aoqi@0 | 177 | // again update this value later when we know that of the super class |
aoqi@0 | 178 | |
aoqi@0 | 179 | if(ci.isElement()) |
aoqi@0 | 180 | tagName = owner.nameBuilder.createElementName(ci.getElementName()); |
aoqi@0 | 181 | else |
aoqi@0 | 182 | tagName = null; |
aoqi@0 | 183 | |
aoqi@0 | 184 | setLifecycleFlags(); |
aoqi@0 | 185 | } |
aoqi@0 | 186 | |
aoqi@0 | 187 | private void checkOverrideProperties(Property p) { |
aoqi@0 | 188 | ClassBeanInfoImpl bi = this; |
aoqi@0 | 189 | while ((bi = bi.superClazz) != null) { |
aoqi@0 | 190 | Property[] props = bi.properties; |
aoqi@0 | 191 | if (props == null) break; |
aoqi@0 | 192 | for (Property superProperty : props) { |
aoqi@0 | 193 | if (superProperty != null) { |
aoqi@0 | 194 | String spName = superProperty.getFieldName(); |
aoqi@0 | 195 | if ((spName != null) && (spName.equals(p.getFieldName()))) { |
aoqi@0 | 196 | superProperty.setHiddenByOverride(true); |
aoqi@0 | 197 | } |
aoqi@0 | 198 | } |
aoqi@0 | 199 | } |
aoqi@0 | 200 | } |
aoqi@0 | 201 | } |
aoqi@0 | 202 | |
aoqi@0 | 203 | @Override |
aoqi@0 | 204 | protected void link(JAXBContextImpl grammar) { |
aoqi@0 | 205 | if(uriProperties!=null) |
aoqi@0 | 206 | return; // avoid linking twice |
aoqi@0 | 207 | |
aoqi@0 | 208 | super.link(grammar); |
aoqi@0 | 209 | |
aoqi@0 | 210 | if(superClazz!=null) |
aoqi@0 | 211 | superClazz.link(grammar); |
aoqi@0 | 212 | |
aoqi@0 | 213 | getLoader(grammar,true); // make sure to build the loader if we haven't done so. |
aoqi@0 | 214 | |
aoqi@0 | 215 | // propagate values from super class |
aoqi@0 | 216 | if(superClazz!=null) { |
aoqi@0 | 217 | if(idProperty==null) |
aoqi@0 | 218 | idProperty = superClazz.idProperty; |
aoqi@0 | 219 | |
aoqi@0 | 220 | if(!superClazz.hasElementOnlyContentModel()) |
aoqi@0 | 221 | hasElementOnlyContentModel(false); |
aoqi@0 | 222 | } |
aoqi@0 | 223 | |
aoqi@0 | 224 | // create a list of attribute/URI handlers |
aoqi@0 | 225 | List<AttributeProperty> attProps = new FinalArrayList<AttributeProperty>(); |
aoqi@0 | 226 | List<Property> uriProps = new FinalArrayList<Property>(); |
aoqi@0 | 227 | for (ClassBeanInfoImpl bi = this; bi != null; bi = bi.superClazz) { |
aoqi@0 | 228 | for (int i = 0; i < bi.properties.length; i++) { |
aoqi@0 | 229 | Property p = bi.properties[i]; |
aoqi@0 | 230 | if(p instanceof AttributeProperty) |
aoqi@0 | 231 | attProps.add((AttributeProperty) p); |
aoqi@0 | 232 | if(p.hasSerializeURIAction()) |
aoqi@0 | 233 | uriProps.add(p); |
aoqi@0 | 234 | } |
aoqi@0 | 235 | } |
aoqi@0 | 236 | if(grammar.c14nSupport) |
aoqi@0 | 237 | Collections.sort(attProps); |
aoqi@0 | 238 | |
aoqi@0 | 239 | if(attProps.isEmpty()) |
aoqi@0 | 240 | attributeProperties = EMPTY_PROPERTIES; |
aoqi@0 | 241 | else |
aoqi@0 | 242 | attributeProperties = attProps.toArray(new AttributeProperty[attProps.size()]); |
aoqi@0 | 243 | |
aoqi@0 | 244 | if(uriProps.isEmpty()) |
aoqi@0 | 245 | uriProperties = EMPTY_PROPERTIES; |
aoqi@0 | 246 | else |
aoqi@0 | 247 | uriProperties = uriProps.toArray(new Property[uriProps.size()]); |
aoqi@0 | 248 | } |
aoqi@0 | 249 | |
aoqi@0 | 250 | @Override |
aoqi@0 | 251 | public void wrapUp() { |
aoqi@0 | 252 | for (Property p : properties) |
aoqi@0 | 253 | p.wrapUp(); |
aoqi@0 | 254 | ci = null; |
aoqi@0 | 255 | super.wrapUp(); |
aoqi@0 | 256 | } |
aoqi@0 | 257 | |
aoqi@0 | 258 | public String getElementNamespaceURI(BeanT bean) { |
aoqi@0 | 259 | return tagName.nsUri; |
aoqi@0 | 260 | } |
aoqi@0 | 261 | |
aoqi@0 | 262 | public String getElementLocalName(BeanT bean) { |
aoqi@0 | 263 | return tagName.localName; |
aoqi@0 | 264 | } |
aoqi@0 | 265 | |
aoqi@0 | 266 | public BeanT createInstance(UnmarshallingContext context) throws IllegalAccessException, InvocationTargetException, InstantiationException, SAXException { |
aoqi@0 | 267 | |
aoqi@0 | 268 | BeanT bean = null; |
aoqi@0 | 269 | if (factoryMethod == null){ |
aoqi@0 | 270 | bean = ClassFactory.create0(jaxbType); |
aoqi@0 | 271 | }else { |
aoqi@0 | 272 | Object o = ClassFactory.create(factoryMethod); |
aoqi@0 | 273 | if( jaxbType.isInstance(o) ){ |
aoqi@0 | 274 | bean = (BeanT)o; |
aoqi@0 | 275 | } else { |
aoqi@0 | 276 | throw new InstantiationException("The factory method didn't return a correct object"); |
aoqi@0 | 277 | } |
aoqi@0 | 278 | } |
aoqi@0 | 279 | |
aoqi@0 | 280 | if(xmlLocatorField!=null) |
aoqi@0 | 281 | // need to copy because Locator is mutable |
aoqi@0 | 282 | try { |
aoqi@0 | 283 | xmlLocatorField.set(bean,new LocatorImpl(context.getLocator())); |
aoqi@0 | 284 | } catch (AccessorException e) { |
aoqi@0 | 285 | context.handleError(e); |
aoqi@0 | 286 | } |
aoqi@0 | 287 | return bean; |
aoqi@0 | 288 | } |
aoqi@0 | 289 | |
aoqi@0 | 290 | public boolean reset(BeanT bean, UnmarshallingContext context) throws SAXException { |
aoqi@0 | 291 | try { |
aoqi@0 | 292 | if(superClazz!=null) |
aoqi@0 | 293 | superClazz.reset(bean,context); |
aoqi@0 | 294 | for( Property<BeanT> p : properties ) |
aoqi@0 | 295 | p.reset(bean); |
aoqi@0 | 296 | return true; |
aoqi@0 | 297 | } catch (AccessorException e) { |
aoqi@0 | 298 | context.handleError(e); |
aoqi@0 | 299 | return false; |
aoqi@0 | 300 | } |
aoqi@0 | 301 | } |
aoqi@0 | 302 | |
aoqi@0 | 303 | public String getId(BeanT bean, XMLSerializer target) throws SAXException { |
aoqi@0 | 304 | if(idProperty!=null) { |
aoqi@0 | 305 | try { |
aoqi@0 | 306 | return idProperty.getIdValue(bean); |
aoqi@0 | 307 | } catch (AccessorException e) { |
aoqi@0 | 308 | target.reportError(null,e); |
aoqi@0 | 309 | } |
aoqi@0 | 310 | } |
aoqi@0 | 311 | return null; |
aoqi@0 | 312 | } |
aoqi@0 | 313 | |
aoqi@0 | 314 | public void serializeRoot(BeanT bean, XMLSerializer target) throws SAXException, IOException, XMLStreamException { |
aoqi@0 | 315 | if(tagName==null) { |
aoqi@0 | 316 | Class beanClass = bean.getClass(); |
aoqi@0 | 317 | String message; |
aoqi@0 | 318 | if (beanClass.isAnnotationPresent(XmlRootElement.class)) { |
aoqi@0 | 319 | message = Messages.UNABLE_TO_MARSHAL_UNBOUND_CLASS.format(beanClass.getName()); |
aoqi@0 | 320 | } else { |
aoqi@0 | 321 | message = Messages.UNABLE_TO_MARSHAL_NON_ELEMENT.format(beanClass.getName()); |
aoqi@0 | 322 | } |
aoqi@0 | 323 | target.reportError(new ValidationEventImpl(ValidationEvent.ERROR,message,null, null)); |
aoqi@0 | 324 | } else { |
aoqi@0 | 325 | target.startElement(tagName,bean); |
aoqi@0 | 326 | target.childAsSoleContent(bean,null); |
aoqi@0 | 327 | target.endElement(); |
aoqi@0 | 328 | if (retainPropertyInfo) { |
aoqi@0 | 329 | target.currentProperty.remove(); |
aoqi@0 | 330 | } |
aoqi@0 | 331 | } |
aoqi@0 | 332 | } |
aoqi@0 | 333 | |
aoqi@0 | 334 | public void serializeBody(BeanT bean, XMLSerializer target) throws SAXException, IOException, XMLStreamException { |
aoqi@0 | 335 | if (superClazz != null) { |
aoqi@0 | 336 | superClazz.serializeBody(bean, target); |
aoqi@0 | 337 | } |
aoqi@0 | 338 | try { |
aoqi@0 | 339 | for (Property<BeanT> p : properties) { |
aoqi@0 | 340 | if (retainPropertyInfo) { |
aoqi@0 | 341 | target.currentProperty.set(p); |
aoqi@0 | 342 | } |
aoqi@0 | 343 | boolean isThereAnOverridingProperty = p.isHiddenByOverride(); |
aoqi@0 | 344 | if (!isThereAnOverridingProperty || bean.getClass().equals(jaxbType)) { |
aoqi@0 | 345 | p.serializeBody(bean, target, null); |
aoqi@0 | 346 | } else if (isThereAnOverridingProperty) { |
aoqi@0 | 347 | // need to double check the override - it should be safe to do after the model has been created because it's targeted to override properties only |
aoqi@0 | 348 | Class beanClass = bean.getClass(); |
aoqi@0 | 349 | if (Utils.REFLECTION_NAVIGATOR.getDeclaredField(beanClass, p.getFieldName()) == null) { |
aoqi@0 | 350 | p.serializeBody(bean, target, null); |
aoqi@0 | 351 | } |
aoqi@0 | 352 | } |
aoqi@0 | 353 | } |
aoqi@0 | 354 | } catch (AccessorException e) { |
aoqi@0 | 355 | target.reportError(null, e); |
aoqi@0 | 356 | } |
aoqi@0 | 357 | } |
aoqi@0 | 358 | |
aoqi@0 | 359 | public void serializeAttributes(BeanT bean, XMLSerializer target) throws SAXException, IOException, XMLStreamException { |
aoqi@0 | 360 | for( AttributeProperty<BeanT> p : attributeProperties ) |
aoqi@0 | 361 | try { |
aoqi@0 | 362 | if (retainPropertyInfo) { |
aoqi@0 | 363 | final Property parentProperty = target.getCurrentProperty(); |
aoqi@0 | 364 | target.currentProperty.set(p); |
aoqi@0 | 365 | p.serializeAttributes(bean,target); |
aoqi@0 | 366 | target.currentProperty.set(parentProperty); |
aoqi@0 | 367 | } else { |
aoqi@0 | 368 | p.serializeAttributes(bean,target); |
aoqi@0 | 369 | } |
aoqi@0 | 370 | if (p.attName.equals(WellKnownNamespace.XML_SCHEMA_INSTANCE, "nil")) { |
aoqi@0 | 371 | isNilIncluded = true; |
aoqi@0 | 372 | } |
aoqi@0 | 373 | } catch (AccessorException e) { |
aoqi@0 | 374 | target.reportError(null,e); |
aoqi@0 | 375 | } |
aoqi@0 | 376 | |
aoqi@0 | 377 | try { |
aoqi@0 | 378 | if(inheritedAttWildcard!=null) { |
aoqi@0 | 379 | Map<QName,String> map = inheritedAttWildcard.get(bean); |
aoqi@0 | 380 | target.attWildcardAsAttributes(map,null); |
aoqi@0 | 381 | } |
aoqi@0 | 382 | } catch (AccessorException e) { |
aoqi@0 | 383 | target.reportError(null,e); |
aoqi@0 | 384 | } |
aoqi@0 | 385 | } |
aoqi@0 | 386 | |
aoqi@0 | 387 | public void serializeURIs(BeanT bean, XMLSerializer target) throws SAXException { |
aoqi@0 | 388 | try { |
aoqi@0 | 389 | if (retainPropertyInfo) { |
aoqi@0 | 390 | final Property parentProperty = target.getCurrentProperty(); |
aoqi@0 | 391 | for( Property<BeanT> p : uriProperties ) { |
aoqi@0 | 392 | target.currentProperty.set(p); |
aoqi@0 | 393 | p.serializeURIs(bean,target); |
aoqi@0 | 394 | } |
aoqi@0 | 395 | target.currentProperty.set(parentProperty); |
aoqi@0 | 396 | } else { |
aoqi@0 | 397 | for( Property<BeanT> p : uriProperties ) { |
aoqi@0 | 398 | p.serializeURIs(bean,target); |
aoqi@0 | 399 | } |
aoqi@0 | 400 | } |
aoqi@0 | 401 | if(inheritedAttWildcard!=null) { |
aoqi@0 | 402 | Map<QName,String> map = inheritedAttWildcard.get(bean); |
aoqi@0 | 403 | target.attWildcardAsURIs(map,null); |
aoqi@0 | 404 | } |
aoqi@0 | 405 | } catch (AccessorException e) { |
aoqi@0 | 406 | target.reportError(null,e); |
aoqi@0 | 407 | } |
aoqi@0 | 408 | } |
aoqi@0 | 409 | |
aoqi@0 | 410 | public Loader getLoader(JAXBContextImpl context, boolean typeSubstitutionCapable) { |
aoqi@0 | 411 | if(loader==null) { |
aoqi@0 | 412 | // these variables have to be set before they are initialized, |
aoqi@0 | 413 | // because the initialization may build other loaders and they may refer to this. |
aoqi@0 | 414 | StructureLoader sl = new StructureLoader(this); |
aoqi@0 | 415 | loader = sl; |
aoqi@0 | 416 | if(ci.hasSubClasses()) |
aoqi@0 | 417 | loaderWithTypeSubst = new XsiTypeLoader(this); |
aoqi@0 | 418 | else |
aoqi@0 | 419 | // optimization. we know there can be no @xsi:type |
aoqi@0 | 420 | loaderWithTypeSubst = loader; |
aoqi@0 | 421 | |
aoqi@0 | 422 | |
aoqi@0 | 423 | sl.init(context,this,ci.getAttributeWildcard()); |
aoqi@0 | 424 | } |
aoqi@0 | 425 | if(typeSubstitutionCapable) |
aoqi@0 | 426 | return loaderWithTypeSubst; |
aoqi@0 | 427 | else |
aoqi@0 | 428 | return loader; |
aoqi@0 | 429 | } |
aoqi@0 | 430 | |
aoqi@0 | 431 | public Transducer<BeanT> getTransducer() { |
aoqi@0 | 432 | return xducer; |
aoqi@0 | 433 | } |
aoqi@0 | 434 | |
aoqi@0 | 435 | private static final AttributeProperty[] EMPTY_PROPERTIES = new AttributeProperty[0]; |
aoqi@0 | 436 | |
aoqi@0 | 437 | private static final Logger logger = Util.getClassLogger(); |
aoqi@0 | 438 | |
aoqi@0 | 439 | } |