/* * Copyright 2013 Guidewire Software, Inc. */ package gw.internal.xml.ws.server.marshal; import gw.internal.schema.gw.xsd.w3c.xmlschema.Enumeration; import gw.internal.schema.gw.xsd.w3c.xmlschema.Restriction; import gw.internal.schema.gw.xsd.w3c.xmlschema.SimpleType; import gw.internal.schema.gw.xsd.w3c.xmlschema.types.complex.LocalElement; import gw.internal.xml.IXmlLoggerFactory; import gw.internal.xml.config.XmlServices; import gw.internal.xml.ws.server.WsiServiceInfo; import gw.lang.reflect.IEnumConstant; import gw.lang.reflect.IEnumType; import gw.lang.reflect.IEnumValue; import gw.lang.reflect.IType; import gw.lang.reflect.java.IJavaType; import gw.lang.reflect.java.JavaTypes; import gw.xml.XmlElement; import gw.xml.XmlSchemaAccess; import java.lang.reflect.Field; import java.math.BigInteger; import java.util.ArrayList; import java.util.Collections; import java.util.Map; import java.util.Set; public class EnumMarshalInfo extends MarshalInfo { private final IEnumType _type; private boolean _isComponent; public EnumMarshalInfo(IEnumType type, boolean isComponent ) { super( type ); _type = type; _isComponent = isComponent; } @Override public Map<String,Set<XmlSchemaAccess>> getAllSchemas() { return Collections.emptyMap(); } @Override public void addType( LocalElement element, WsiServiceInfo createInfo ) throws Exception { if ( _isComponent ) { element.setNillable$( true ); } else { element.setMinOccurs$( BigInteger.ZERO ); } SimpleType simpleType = createInfo.getSimpleTypeIfNeededFor(_type); if (simpleType != null) { Restriction restriction = new Restriction(); restriction.setBase$(XS_STRING_QNAME); ArrayList<Enumeration> enumerations = new ArrayList<Enumeration>(); for (IEnumValue value : _type.getEnumValues()) { Enumeration enumEL = new Enumeration(); enumEL.setValue$(value.getCode()); enumerations.add(enumEL); } restriction.setEnumeration$(enumerations); simpleType.setRestriction$(restriction); } element.setType$( createInfo.getQName(_type) ); } @Override public Object unmarshal(XmlElement componentElement, UnmarshalContext context) { if (_type instanceof IJavaType) { // java enums try { IJavaType jtype = (IJavaType) _type; Class clazz = jtype.getBackingClass(); for (Field field : clazz.getDeclaredFields()) { if (field.getName().equalsIgnoreCase(componentElement.getText())) { return field.get(null); } } throw new RuntimeException("invalid " + _type + " '" + componentElement.getText() + ""); } catch (Throwable e) { XmlServices.getLogger(IXmlLoggerFactory.Category.XmlUnMarshal).error("Exception on " + _type + " '" + componentElement.getText() + "", e); } } IEnumValue value = _type.getEnumValue(componentElement.getText()); if (value == null) { throw new RuntimeException("invalid " + _type + " '" + componentElement.getText() + ""); } return value; } @Override public void marshal(XmlElement returnEl, IType type, Object obj, MarshalContext context) { if (_type instanceof IJavaType) { // java enums try { IJavaType jtype = (IJavaType) _type; Class clazz = jtype.getBackingClass(); for (Field field : clazz.getDeclaredFields()) { if (field.get(null).equals(obj)) { returnEl.setText(field.getName()); return; } } XmlServices.getLogger(IXmlLoggerFactory.Category.XmlMarshal).error("Couldn't find " + _type + ": " + obj); } catch (Throwable e) { XmlServices.getLogger(IXmlLoggerFactory.Category.XmlUnMarshal).error("Exception on " + _type + ": " + obj, e); } } else { // typelists, gosu enums returnEl.setText(((IEnumConstant)obj).getCode()); } } }