blob: b897ee089d25e7a903c44768623580d4b147ea2f [file] [log] [blame]
/* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.xmlbeans.impl.marshal;
import org.apache.xmlbeans.GDuration;
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.impl.binding.bts.BindingLoader;
import org.apache.xmlbeans.impl.binding.bts.BindingType;
import org.apache.xmlbeans.impl.binding.bts.BindingTypeName;
import org.apache.xmlbeans.impl.binding.bts.BindingTypeVisitor;
import org.apache.xmlbeans.impl.binding.bts.BuiltinBindingLoader;
import org.apache.xmlbeans.impl.binding.bts.BuiltinBindingType;
import org.apache.xmlbeans.impl.binding.bts.ByNameBean;
import org.apache.xmlbeans.impl.binding.bts.JavaTypeName;
import org.apache.xmlbeans.impl.binding.bts.JaxrpcEnumType;
import org.apache.xmlbeans.impl.binding.bts.ListArrayType;
import org.apache.xmlbeans.impl.binding.bts.SimpleBindingType;
import org.apache.xmlbeans.impl.binding.bts.SimpleContentBean;
import org.apache.xmlbeans.impl.binding.bts.SimpleDocumentBinding;
import org.apache.xmlbeans.impl.binding.bts.SoapArrayType;
import org.apache.xmlbeans.impl.binding.bts.WrappedArrayType;
import org.apache.xmlbeans.impl.binding.bts.XmlTypeName;
import org.apache.xmlbeans.impl.common.ConcurrentReaderHashMap;
import org.apache.xmlbeans.impl.common.XmlWhitespace;
import javax.xml.namespace.QName;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
/**
* Table of TypeMarshaller and TypeUnmarshaller objects keyed by BindingType
*/
final class RuntimeBindingTypeTable
{
//concurrent hashMap allows us to do hash lookups outside of any sync blocks,
//and successful lookups involve no locking, which should be
//99% of the cases in any sort of long running process
private final Map initedTypeMap;
private final Map tempTypeMap = new HashMap();
//access to this object must be inside a synchronized block.
private final FactoryTypeVisitor typeVisitor = new FactoryTypeVisitor();
static final String XSD_NS = "http://www.w3.org/2001/XMLSchema";
private static final String SOAPENC_NS = "http://schemas.xmlsoap.org/soap/encoding/";
private static final ConcurrentReaderHashMap BUILTIN_TYPE_MAP;
static
{
final RuntimeBindingTypeTable tbl =
new RuntimeBindingTypeTable();
tbl.addBuiltinTypes();
BUILTIN_TYPE_MAP = (ConcurrentReaderHashMap)tbl.initedTypeMap;
}
static RuntimeBindingTypeTable createTable()
{
final RuntimeBindingTypeTable tbl =
new RuntimeBindingTypeTable(
(Map)BUILTIN_TYPE_MAP.clone()
);
return tbl;
}
private RuntimeBindingTypeTable(Map typeMap)
{
this.initedTypeMap = typeMap;
}
private RuntimeBindingTypeTable()
{
this(new ConcurrentReaderHashMap());
}
RuntimeBindingType createRuntimeType(BindingType type,
BindingLoader binding_loader)
throws XmlException
{
//return runtimeTypeFactory.createRuntimeType(type, this, binding_loader);
assert type != null;
RuntimeBindingType rtype = (RuntimeBindingType)initedTypeMap.get(type);
if (rtype != null) return rtype;
//safe but slow creation of new type.
synchronized (this) {
rtype = (RuntimeBindingType)tempTypeMap.get(type);
if (rtype == null) {
rtype = allocateType(type);
tempTypeMap.put(type, rtype);
rtype.external_initialize(this, binding_loader);
initedTypeMap.put(type, rtype);
tempTypeMap.remove(type); // save some memory.
}
}
assert rtype != null;
return rtype;
}
private RuntimeBindingType allocateType(BindingType type)
throws XmlException
{
type.accept(typeVisitor);
return typeVisitor.getRuntimeBindingType();
}
//overloaded, more strongly typed versions of createRuntimeType.
//the idea being that this class maintains the matching of the
//two type hiearchies and all casting is done here.
private WrappedArrayRuntimeBindingType createRuntimeType(WrappedArrayType type,
BindingLoader binding_loader)
throws XmlException
{
final RuntimeBindingType rtt =
createRuntimeTypeInternal(type, binding_loader);
return (WrappedArrayRuntimeBindingType)rtt;
}
private SoapArrayRuntimeBindingType createRuntimeType(SoapArrayType type,
BindingLoader binding_loader)
throws XmlException
{
final RuntimeBindingType rtt =
createRuntimeTypeInternal(type, binding_loader);
return (SoapArrayRuntimeBindingType)rtt;
}
private ListArrayRuntimeBindingType createRuntimeType(ListArrayType type,
BindingLoader binding_loader)
throws XmlException
{
final RuntimeBindingType rtt =
createRuntimeTypeInternal(type, binding_loader);
return (ListArrayRuntimeBindingType)rtt;
}
private ByNameRuntimeBindingType createRuntimeType(ByNameBean type,
BindingLoader binding_loader)
throws XmlException
{
final RuntimeBindingType rtt =
createRuntimeTypeInternal(type, binding_loader);
return (ByNameRuntimeBindingType)rtt;
}
private SimpleContentRuntimeBindingType createRuntimeType(SimpleContentBean type,
BindingLoader binding_loader)
throws XmlException
{
final RuntimeBindingType rtt =
createRuntimeTypeInternal(type, binding_loader);
return (SimpleContentRuntimeBindingType)rtt;
}
private JaxrpcEnumRuntimeBindingType createRuntimeType(JaxrpcEnumType type,
BindingLoader binding_loader)
throws XmlException
{
final RuntimeBindingType rtt =
createRuntimeTypeInternal(type, binding_loader);
return (JaxrpcEnumRuntimeBindingType)rtt;
}
//avoids a cast to deal with overloaded methods
private RuntimeBindingType createRuntimeTypeInternal(BindingType type,
BindingLoader loader)
throws XmlException
{
return createRuntimeType(type, loader);
}
private void addBuiltinType(String xsdType,
JavaTypeName jName,
TypeConverter converter)
{
QName xml_type = new QName(XSD_NS, xsdType);
addBuiltinType(xml_type, jName, converter);
}
private void addBuiltinSoapType(String xsdType,
JavaTypeName jName,
TypeConverter converter)
{
QName xml_type = new QName(SOAPENC_NS, xsdType);
addBuiltinType(xml_type, jName, converter);
}
private void addBuiltinType(QName xml_type,
JavaTypeName jName,
TypeConverter converter)
{
final BindingLoader default_builtin_loader =
BuiltinBindingLoader.getBuiltinBindingLoader(false);
XmlTypeName xName = XmlTypeName.forTypeNamed(xml_type);
final BindingTypeName btname = BindingTypeName.forPair(jName, xName);
BindingType btype = default_builtin_loader.getBindingType(btname);
if (btype == null) {
final BindingLoader jaxrpc_builtin_loader =
BuiltinBindingLoader.getBuiltinBindingLoader(true);
btype = jaxrpc_builtin_loader.getBindingType(btname);
}
if (btype == null) {
throw new AssertionError("failed to find builtin for java:" + jName +
" - xsd:" + xName);
}
assert (btype instanceof BuiltinBindingType) :
"unexpected type: " + btype;
final RuntimeBindingType builtin;
try {
if (xml_type.equals(AnyTypeRuntimeBindingType.ANY_TYPE_NAME)) {
builtin = new AnyTypeRuntimeBindingType((BuiltinBindingType)btype,
converter);
} else {
builtin = new BuiltinRuntimeBindingType((BuiltinBindingType)btype,
converter);
}
}
catch (XmlException e) {
throw new AssertionError(e);
}
initedTypeMap.put(btype, builtin);
}
private void addBuiltinSoapType(String xsdType,
Class javaClass,
TypeConverter converter)
{
final JavaTypeName jName = JavaTypeName.forClassName(javaClass.getName());
addBuiltinSoapType(xsdType, jName, converter);
}
private void addBuiltinType(String xsdType,
Class javaClass,
TypeConverter converter)
{
final JavaTypeName jName = JavaTypeName.forClassName(javaClass.getName());
addBuiltinType(xsdType, jName, converter);
}
private void addBuiltinTypes()
{
addBuiltinType("anyType", Object.class, new ObjectAnyTypeConverter());
final FloatTypeConverter float_conv = new FloatTypeConverter();
addBuiltinType("float", float.class, float_conv);
addBuiltinType("float", Float.class, float_conv);
final DoubleTypeConverter double_conv = new DoubleTypeConverter();
addBuiltinType("double", double.class, double_conv);
addBuiltinType("double", Double.class, double_conv);
final IntegerTypeConverter integer_conv = new IntegerTypeConverter();
final Class bigint = BigInteger.class;
addBuiltinType("integer", bigint, integer_conv);
addBuiltinType("nonPositiveInteger", bigint, integer_conv);
addBuiltinType("negativeInteger", bigint, integer_conv);
addBuiltinType("nonNegativeInteger", bigint, integer_conv);
addBuiltinType("positiveInteger", bigint, integer_conv);
addBuiltinType("unsignedLong", bigint, integer_conv);
final TypeConverter i2iconv = new IntegerToIntTypeConverter();
addBuiltinType("integer", int.class, i2iconv);
addBuiltinType("nonPositiveInteger", int.class, i2iconv);
addBuiltinType("negativeInteger", int.class, i2iconv);
addBuiltinType("nonNegativeInteger", int.class, i2iconv);
addBuiltinType("positiveInteger", int.class, i2iconv);
addBuiltinType("unsignedLong", int.class, i2iconv);
final DecimalTypeConverter decimal_conv = new DecimalTypeConverter();
addBuiltinType("decimal", BigDecimal.class, decimal_conv);
final LongTypeConverter long_conv = new LongTypeConverter();
addBuiltinType("long", long.class, long_conv);
addBuiltinType("long", Long.class, long_conv);
addBuiltinType("unsignedInt", long.class, long_conv);
addBuiltinType("unsignedInt", Long.class, long_conv);
final IntTypeConverter int_conv = new IntTypeConverter();
addBuiltinType("int", int.class, int_conv);
addBuiltinType("int", Integer.class, int_conv);
addBuiltinType("unsignedShort", int.class, int_conv);
addBuiltinType("unsignedShort", Integer.class, int_conv);
final ShortTypeConverter short_conv = new ShortTypeConverter();
addBuiltinType("short", short.class, short_conv);
addBuiltinType("short", Short.class, short_conv);
addBuiltinType("unsignedByte", short.class, short_conv);
addBuiltinType("unsignedByte", Short.class, short_conv);
final ByteTypeConverter byte_conv = new ByteTypeConverter();
addBuiltinType("byte", byte.class, byte_conv);
addBuiltinType("byte", Byte.class, byte_conv);
final BooleanTypeConverter boolean_conv = new BooleanTypeConverter();
addBuiltinType("boolean", boolean.class, boolean_conv);
addBuiltinType("boolean", Boolean.class, boolean_conv);
final AnyUriToUriTypeConverter uri_uri_conv =
new AnyUriToUriTypeConverter();
addBuiltinType("anyURI", java.net.URI.class, uri_uri_conv);
final Class str = String.class;
addBuiltinType("anySimpleType", str, new AnySimpleTypeConverter());
final StringTypeConverter string_conv = new StringTypeConverter();
addBuiltinType("string", str, string_conv);
addBuiltinType("normalizedString", str, string_conv);
addBuiltinType("token", str, string_conv);
addBuiltinType("language", str, string_conv);
addBuiltinType("Name", str, string_conv);
addBuiltinType("NCName", str, string_conv);
addBuiltinType("NMTOKEN", str, string_conv);
addBuiltinType("ID", str, string_conv);
addBuiltinType("IDREF", str, string_conv);
addBuiltinType("ENTITY", str, string_conv);
final TypeConverter collapsing_string_conv =
CollapseStringTypeConverter.getInstance();
addBuiltinType("NOTATION", str, collapsing_string_conv);
addBuiltinType("duration", str, collapsing_string_conv);
addBuiltinType("gDay", str, collapsing_string_conv);
addBuiltinType("gMonth", str, collapsing_string_conv);
addBuiltinType("gMonthDay", str, collapsing_string_conv);
addBuiltinType("gYear", str, collapsing_string_conv);
addBuiltinType("gYearMonth", str, collapsing_string_conv);
final AnyUriToStringTypeConverter uri_conv =
new AnyUriToStringTypeConverter();
addBuiltinType("anyURI", str, uri_conv);
final Class str_array = (new String[0]).getClass();
final StringListArrayConverter string_list_array_conv =
new StringListArrayConverter();
addBuiltinType("ENTITIES", str_array,
string_list_array_conv);
addBuiltinType("IDREFS", str_array,
string_list_array_conv);
addBuiltinType("NMTOKENS", str_array,
string_list_array_conv);
final DurationTypeConverter gduration_conv =
new DurationTypeConverter();
addBuiltinType("duration", GDuration.class, gduration_conv);
final Class calendar_class = java.util.Calendar.class;
final JavaCalendarTypeConverter date_time_conv =
new JavaCalendarTypeConverter(SchemaType.BTC_DATE_TIME);
addBuiltinType("dateTime", calendar_class, date_time_conv);
final JavaDateTypeConverter date_datetime_conv =
new JavaDateTypeConverter(SchemaType.BTC_DATE_TIME);
addBuiltinType("dateTime", java.util.Date.class, date_datetime_conv);
final JavaCalendarTypeConverter time_conv =
new JavaCalendarTypeConverter(SchemaType.BTC_TIME);
addBuiltinType("time", calendar_class, time_conv);
final JavaCalendarTypeConverter date_conv =
new JavaCalendarTypeConverter(SchemaType.BTC_DATE);
addBuiltinType("date", calendar_class, date_conv);
final JavaDateTypeConverter date_date_conv =
new JavaDateTypeConverter(SchemaType.BTC_DATE);
addBuiltinType("date", java.util.Date.class, date_date_conv);
final JavaCalendarTypeConverter gday_conv =
new JavaCalendarTypeConverter(SchemaType.BTC_G_DAY);
addBuiltinType("gDay", calendar_class, gday_conv);
final JavaCalendarTypeConverter gmonth_conv =
new JavaCalendarTypeConverter(SchemaType.BTC_G_MONTH);
addBuiltinType("gMonth", calendar_class, gmonth_conv);
final JavaCalendarTypeConverter gmonth_day_conv =
new JavaCalendarTypeConverter(SchemaType.BTC_G_MONTH_DAY);
addBuiltinType("gMonthDay", calendar_class, gmonth_day_conv);
final JavaCalendarTypeConverter gyear_conv =
new JavaCalendarTypeConverter(SchemaType.BTC_G_YEAR);
addBuiltinType("gYear", calendar_class, gyear_conv);
final JavaCalendarTypeConverter gyearmonth_conv =
new JavaCalendarTypeConverter(SchemaType.BTC_G_YEAR_MONTH);
addBuiltinType("gYearMonth", calendar_class, gyearmonth_conv);
addBuiltinType("gDay",
int.class,
new IntDateTypeConverter(SchemaType.BTC_G_DAY));
addBuiltinType("gMonth",
int.class,
new IntDateTypeConverter(SchemaType.BTC_G_MONTH));
addBuiltinType("gYear",
int.class,
new IntDateTypeConverter(SchemaType.BTC_G_YEAR));
final QNameTypeConverter qname_conv = new QNameTypeConverter();
addBuiltinType("QName", QName.class, qname_conv);
final JavaTypeName byte_array_jname =
JavaTypeName.forArray(JavaTypeName.forString("byte"), 1);
final Base64BinaryTypeConverter base64_conv =
new Base64BinaryTypeConverter();
addBuiltinType("base64Binary", byte_array_jname, base64_conv);
final HexBinaryTypeConverter hexbin_conv = new HexBinaryTypeConverter();
addBuiltinType("hexBinary", byte_array_jname, hexbin_conv);
//TODO: InputStream based hexBinary and base64Binary converters
//SOAPENC additions...
addBuiltinSoapType("float", Float.class, float_conv);
addBuiltinSoapType("double", Double.class, double_conv);
addBuiltinSoapType("integer", bigint, integer_conv);
addBuiltinSoapType("nonPositiveInteger", bigint, integer_conv);
addBuiltinSoapType("negativeInteger", bigint, integer_conv);
addBuiltinSoapType("nonNegativeInteger", bigint, integer_conv);
addBuiltinSoapType("positiveInteger", bigint, integer_conv);
addBuiltinSoapType("unsignedLong", bigint, integer_conv);
addBuiltinSoapType("decimal", BigDecimal.class,
decimal_conv);
addBuiltinSoapType("long", Long.class, long_conv);
addBuiltinSoapType("unsignedInt", Long.class, long_conv);
addBuiltinSoapType("int", Integer.class, int_conv);
addBuiltinSoapType("unsignedShort", Integer.class, int_conv);
addBuiltinSoapType("short", Short.class, short_conv);
addBuiltinSoapType("unsignedByte", Short.class, short_conv);
addBuiltinSoapType("byte", Byte.class, byte_conv);
addBuiltinSoapType("boolean", Boolean.class, boolean_conv);
addBuiltinSoapType("anyURI", java.net.URI.class, uri_uri_conv);
addBuiltinSoapType("string", str, string_conv);
addBuiltinSoapType("normalizedString", str, string_conv);
addBuiltinSoapType("token", str, string_conv);
addBuiltinSoapType("language", str, string_conv);
addBuiltinSoapType("Name", str, string_conv);
addBuiltinSoapType("NCName", str, string_conv);
addBuiltinSoapType("NMTOKEN", str, string_conv);
addBuiltinSoapType("ID", str, string_conv);
addBuiltinSoapType("IDREF", str, string_conv);
addBuiltinSoapType("ENTITY", str, string_conv);
addBuiltinSoapType("NOTATION", str, collapsing_string_conv);
addBuiltinSoapType("duration", str, collapsing_string_conv);
addBuiltinSoapType("gDay", str, collapsing_string_conv);
addBuiltinSoapType("gMonth", str, collapsing_string_conv);
addBuiltinSoapType("gMonthDay", str, collapsing_string_conv);
addBuiltinSoapType("gYear", str, collapsing_string_conv);
addBuiltinSoapType("gYearMonth", str, collapsing_string_conv);
addBuiltinSoapType("anyURI", str, uri_conv);
addBuiltinSoapType("ENTITIES", str_array, string_list_array_conv);
addBuiltinSoapType("IDREFS", str_array, string_list_array_conv);
addBuiltinSoapType("NMTOKENS", str_array, string_list_array_conv);
addBuiltinSoapType("duration", GDuration.class, gduration_conv);
addBuiltinSoapType("dateTime", calendar_class, date_time_conv);
addBuiltinSoapType("dateTime", java.util.Date.class, date_datetime_conv);
addBuiltinSoapType("time", calendar_class, time_conv);
addBuiltinSoapType("date", calendar_class, date_conv);
addBuiltinSoapType("date", java.util.Date.class, date_date_conv);
addBuiltinSoapType("gDay", calendar_class, gday_conv);
addBuiltinSoapType("gMonth", calendar_class, gmonth_conv);
addBuiltinSoapType("gMonthDay", calendar_class, gmonth_day_conv);
addBuiltinSoapType("gYear", calendar_class, gyear_conv);
addBuiltinSoapType("gYearMonth", calendar_class, gyearmonth_conv);
addBuiltinSoapType("QName", QName.class, qname_conv);
addBuiltinSoapType("base64Binary", byte_array_jname, base64_conv);
addBuiltinSoapType("hexBinary", byte_array_jname, hexbin_conv);
}
private static TypeUnmarshaller createSimpleTypeUnmarshaller(SimpleBindingType stype,
BindingLoader loader,
RuntimeBindingTypeTable table)
throws XmlException
{
int curr_ws = XmlWhitespace.WS_UNSPECIFIED;
SimpleBindingType curr = stype;
BuiltinBindingType resolved;
while (true) {
//we want to keep the first whitespace setting as we walk up
if (curr_ws == XmlWhitespace.WS_UNSPECIFIED) {
curr_ws = curr.getWhitespace();
}
BindingTypeName asif_name = curr.getAsIfBindingTypeName();
if (asif_name != null) {
BindingType asif_new = loader.getBindingType(asif_name);
if (asif_new instanceof BuiltinBindingType) {
resolved = (BuiltinBindingType)asif_new;
break;
} else if (asif_new instanceof SimpleBindingType) {
curr = (SimpleBindingType)asif_new;
} else {
String msg = "invalid as-xml type: " + asif_name +
" on type: " + curr.getName();
throw new XmlException(msg);
}
} else {
throw new XmlException("missing as-xml type on " +
curr.getName());
}
}
assert resolved != null;
//special processing for whitespace facets.
//TODO: assert that our type is derived from xsd:string
//for actual ws facet cases
switch (curr_ws) {
case XmlWhitespace.WS_UNSPECIFIED:
break;
case XmlWhitespace.WS_PRESERVE:
return PreserveStringTypeConverter.getInstance();
case XmlWhitespace.WS_REPLACE:
return ReplaceStringTypeConverter.getInstance();
case XmlWhitespace.WS_COLLAPSE:
return CollapseStringTypeConverter.getInstance();
default:
throw new AssertionError("invalid whitespace: " + curr_ws);
}
TypeUnmarshaller um =
table.createRuntimeType(resolved, loader).getUnmarshaller();
if (um != null) return um;
String msg = "unable to get simple type unmarshaller for " + stype +
" resolved to " + resolved;
throw new AssertionError(msg);
}
TypeUnmarshaller createUnmarshaller(BindingType binding_type,
BindingLoader loader)
throws XmlException
{
TypeVisitor type_visitor = new TypeVisitor(this, loader);
binding_type.accept(type_visitor);
final TypeUnmarshaller type_um = type_visitor.getUnmarshaller();
type_um.initialize(this, loader);
return type_um;
}
/**
*
* find marshaller for given type. Can return null if not found
*
* @param type_name
* @param loader
* @return marshaller or null if not found.
* @throws XmlException
*/
private TypeMarshaller createMarshaller(BindingTypeName type_name,
BindingLoader loader)
throws XmlException
{
final BindingType binding_type = loader.getBindingType(type_name);
if (binding_type == null) {
final String msg = "unable to load type for " + type_name;
throw new XmlException(msg);
}
return createMarshaller(binding_type, loader);
}
/**
* find marshaller for given type. Can return null if not found
*
* @param binding_type
* @param loader
* @return marshaller or null if not found.
* @throws XmlException
*/
TypeMarshaller createMarshaller(BindingType binding_type,
BindingLoader loader)
throws XmlException
{
final TypeMarshaller m;
//REVIEW: consider using visitor
if (binding_type instanceof SimpleContentBean) {
SimpleContentBean scb = (SimpleContentBean)binding_type;
final SimpleContentRuntimeBindingType rtt =
createRuntimeType(scb, loader);
m = new SimpleContentBeanMarshaller(rtt);
} else if (binding_type instanceof SimpleBindingType) {
SimpleBindingType stype = (SimpleBindingType)binding_type;
final BindingTypeName asif_name = stype.getAsIfBindingTypeName();
if (asif_name == null)
throw new XmlException("no asif for " + stype);
m = createMarshaller(asif_name, loader);
} else if (binding_type instanceof JaxrpcEnumType) {
JaxrpcEnumType enum_type = (JaxrpcEnumType)binding_type;
final JaxrpcEnumRuntimeBindingType rtt =
createRuntimeType(enum_type, loader);
m = new JaxrpcEnumMarsahller(rtt);
} else if (binding_type instanceof ListArrayType) {
ListArrayType la_type = (ListArrayType)binding_type;
final ListArrayRuntimeBindingType rtt =
createRuntimeType(la_type, loader);
m = new ListArrayConverter(rtt);
} else if (binding_type instanceof BuiltinBindingType) {
final RuntimeBindingType rtt =
createRuntimeType(binding_type, loader);
m = rtt.getMarshaller();
assert m != null;
} else {
//not a known simple type
m = null;
}
return m;
}
private static final class TypeVisitor
implements BindingTypeVisitor
{
private final BindingLoader loader;
private final RuntimeBindingTypeTable typeTable;
private TypeUnmarshaller typeUnmarshaller;
public TypeVisitor(RuntimeBindingTypeTable runtimeBindingTypeTable,
BindingLoader loader)
{
this.typeTable = runtimeBindingTypeTable;
this.loader = loader;
}
public void visit(BuiltinBindingType builtinBindingType)
throws XmlException
{
throw new AssertionError("internal error: no builtin unmarshaller for " +
builtinBindingType);
}
public void visit(ByNameBean byNameBean)
throws XmlException
{
ByNameRuntimeBindingType rtt =
typeTable.createRuntimeType(byNameBean, loader);
typeUnmarshaller = new ByNameUnmarshaller(rtt);
}
public void visit(SimpleContentBean simpleContentBean)
throws XmlException
{
SimpleContentRuntimeBindingType rtt =
typeTable.createRuntimeType(simpleContentBean, loader);
typeUnmarshaller = new SimpleContentUnmarshaller(rtt);
}
public void visit(SimpleBindingType simpleBindingType)
throws XmlException
{
typeUnmarshaller =
typeTable.createSimpleTypeUnmarshaller(simpleBindingType,
loader,
typeTable);
}
public void visit(JaxrpcEnumType jaxrpcEnumType)
throws XmlException
{
JaxrpcEnumRuntimeBindingType rtt =
typeTable.createRuntimeType(jaxrpcEnumType,
loader);
typeUnmarshaller = new JaxrpcEnumUnmarshaller(rtt);
}
public void visit(SimpleDocumentBinding simpleDocumentBinding)
throws XmlException
{
throw new AssertionError("type not allowed here" +
simpleDocumentBinding);
}
public void visit(WrappedArrayType wrappedArrayType)
throws XmlException
{
WrappedArrayRuntimeBindingType rtt =
typeTable.createRuntimeType(wrappedArrayType, loader);
typeUnmarshaller = new WrappedArrayUnmarshaller(rtt);
}
public void visit(SoapArrayType soapArrayType)
throws XmlException
{
SoapArrayRuntimeBindingType rtt =
typeTable.createRuntimeType(soapArrayType, loader);
typeUnmarshaller = new SoapArrayUnmarshaller(rtt);
}
public void visit(ListArrayType listArrayType)
throws XmlException
{
ListArrayRuntimeBindingType rtt =
typeTable.createRuntimeType(listArrayType, loader);
typeUnmarshaller = new ListArrayConverter(rtt);
}
public TypeUnmarshaller getUnmarshaller()
{
assert typeUnmarshaller != null;
return typeUnmarshaller;
}
}
private static final class FactoryTypeVisitor
implements BindingTypeVisitor
{
private RuntimeBindingType runtimeBindingType;
public RuntimeBindingType getRuntimeBindingType()
{
return runtimeBindingType;
}
public void visit(BuiltinBindingType builtinBindingType)
throws XmlException
{
throw new AssertionError("not used");
}
public void visit(ByNameBean byNameBean)
throws XmlException
{
runtimeBindingType = new ByNameRuntimeBindingType(byNameBean);
}
public void visit(SimpleContentBean simpleContentBean)
throws XmlException
{
runtimeBindingType = new SimpleContentRuntimeBindingType(simpleContentBean);
}
public void visit(SimpleBindingType simpleBindingType)
throws XmlException
{
runtimeBindingType = new SimpleRuntimeBindingType(simpleBindingType);
}
public void visit(JaxrpcEnumType jaxrpcEnumType)
throws XmlException
{
runtimeBindingType = new JaxrpcEnumRuntimeBindingType(jaxrpcEnumType);
}
public void visit(SimpleDocumentBinding simpleDocumentBinding)
throws XmlException
{
throw new AssertionError("not valid here: " + simpleDocumentBinding);
}
public void visit(WrappedArrayType wrappedArrayType)
throws XmlException
{
runtimeBindingType = new WrappedArrayRuntimeBindingType(wrappedArrayType);
}
public void visit(SoapArrayType soapArrayType)
throws XmlException
{
runtimeBindingType = new SoapArrayRuntimeBindingType(soapArrayType);
}
public void visit(ListArrayType listArrayType)
throws XmlException
{
runtimeBindingType = new ListArrayRuntimeBindingType(listArrayType);
}
}
}