diff -r 88b85470e72c -r f50545b5e2f1 src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/RuntimeModelBuilder.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/RuntimeModelBuilder.java Tue Mar 06 16:09:35 2012 -0800 @@ -0,0 +1,184 @@ +/* + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.xml.internal.bind.v2.model.impl; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.Map; + +import javax.activation.MimeType; + +import com.sun.xml.internal.bind.WhiteSpaceProcessor; +import com.sun.xml.internal.bind.api.AccessorException; +import com.sun.xml.internal.bind.v2.model.annotation.Locatable; +import com.sun.xml.internal.bind.v2.model.annotation.RuntimeAnnotationReader; +import com.sun.xml.internal.bind.v2.model.core.ID; +import com.sun.xml.internal.bind.v2.model.nav.Navigator; +import com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator; +import com.sun.xml.internal.bind.v2.model.runtime.RuntimeNonElement; +import com.sun.xml.internal.bind.v2.model.runtime.RuntimeNonElementRef; +import com.sun.xml.internal.bind.v2.model.runtime.RuntimePropertyInfo; +import com.sun.xml.internal.bind.v2.model.runtime.RuntimeTypeInfoSet; +import com.sun.xml.internal.bind.v2.runtime.FilterTransducer; +import com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationException; +import com.sun.xml.internal.bind.v2.runtime.InlineBinaryTransducer; +import com.sun.xml.internal.bind.v2.runtime.MimeTypedTransducer; +import com.sun.xml.internal.bind.v2.runtime.SchemaTypeTransducer; +import com.sun.xml.internal.bind.v2.runtime.Transducer; +import com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl; +import com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext; +import com.sun.istack.internal.Nullable; + +import com.sun.xml.internal.bind.v2.WellKnownNamespace; +import javax.xml.namespace.QName; +import org.xml.sax.SAXException; + +/** + * {@link ModelBuilder} that works at the run-time by using + * the {@code java.lang.reflect} package. + * + *

+ * This extends {@link ModelBuilder} by providing more functionalities such + * as accessing the fields and classes. + * + * @author Kohsuke Kawaguchi (kk@kohsuke.org) + */ +public class RuntimeModelBuilder extends ModelBuilder { + /** + * The {@link JAXBContextImpl} for which the model is built. + * Null when created for reflection. + */ + public final @Nullable JAXBContextImpl context; + + public RuntimeModelBuilder(JAXBContextImpl context, RuntimeAnnotationReader annotationReader, Map subclassReplacements, String defaultNamespaceRemap) { + super(annotationReader, Navigator.REFLECTION, subclassReplacements, defaultNamespaceRemap); + this.context = context; + } + + @Override + public RuntimeNonElement getClassInfo( Class clazz, Locatable upstream ) { + return (RuntimeNonElement)super.getClassInfo(clazz,upstream); + } + + @Override + public RuntimeNonElement getClassInfo( Class clazz, boolean searchForSuperClass, Locatable upstream ) { + return (RuntimeNonElement)super.getClassInfo(clazz,searchForSuperClass,upstream); + } + + @Override + protected RuntimeEnumLeafInfoImpl createEnumLeafInfo(Class clazz, Locatable upstream) { + return new RuntimeEnumLeafInfoImpl(this,upstream,clazz); + } + + @Override + protected RuntimeClassInfoImpl createClassInfo( Class clazz, Locatable upstream ) { + return new RuntimeClassInfoImpl(this,upstream,clazz); + } + + @Override + public RuntimeElementInfoImpl createElementInfo(RegistryInfoImpl registryInfo, Method method) throws IllegalAnnotationException { + return new RuntimeElementInfoImpl(this,registryInfo, method); + } + + @Override + public RuntimeArrayInfoImpl createArrayInfo(Locatable upstream, Type arrayType) { + return new RuntimeArrayInfoImpl(this, upstream, (Class)arrayType); + } + + public ReflectionNavigator getNavigator() { + return (ReflectionNavigator)nav; + } + + @Override + protected RuntimeTypeInfoSetImpl createTypeInfoSet() { + return new RuntimeTypeInfoSetImpl(reader); + } + + @Override + public RuntimeTypeInfoSet link() { + return (RuntimeTypeInfoSet)super.link(); + } + + /** + * Creates a {@link Transducer} given a reference. + * + * Used to implement {@link RuntimeNonElementRef#getTransducer()}. + * Shouldn't be called from anywhere else. + * + * TODO: this is not the proper place for this class to be in. + */ + public static Transducer createTransducer(RuntimeNonElementRef ref) { + Transducer t = ref.getTarget().getTransducer(); + RuntimePropertyInfo src = ref.getSource(); + ID id = src.id(); + + if(id==ID.IDREF) + return RuntimeBuiltinLeafInfoImpl.STRING; + + if(id==ID.ID) + t = new IDTransducerImpl(t); + + MimeType emt = src.getExpectedMimeType(); + if(emt!=null) + t = new MimeTypedTransducer(t,emt); + + if(src.inlineBinaryData()) + t = new InlineBinaryTransducer(t); + + if(src.getSchemaType()!=null) { + if (src.getSchemaType().equals(createXSSimpleType())) { + return RuntimeBuiltinLeafInfoImpl.STRING; + } + t = new SchemaTypeTransducer(t,src.getSchemaType()); + } + + return t; + } + + private static QName createXSSimpleType() { + return new QName(WellKnownNamespace.XML_SCHEMA,"anySimpleType"); + } + + /** + * Transducer implementation for ID. + * + * This transducer wraps another {@link Transducer} and adds + * handling for ID. + */ + private static final class IDTransducerImpl extends FilterTransducer { + public IDTransducerImpl(Transducer core) { + super(core); + } + + @Override + public ValueT parse(CharSequence lexical) throws AccessorException, SAXException { + String value = WhiteSpaceProcessor.trim(lexical).toString(); + UnmarshallingContext.getInstance().addToIdTable(value); + return core.parse(value); + } + } +}