/* * Copyright 2013 Guidewire Software, Inc. */ package gw.internal.xml.xsd.typeprovider.simplevaluefactory; import gw.internal.xml.XmlDeserializationContext; import gw.internal.xml.XmlSerializationContext; import gw.internal.xml.XmlSimpleValueBase; import gw.internal.xml.xsd.typeprovider.XmlSchemaIndex; import gw.internal.xml.xsd.typeprovider.XmlSchemaPropertySpec; import gw.internal.xml.xsd.typeprovider.XmlSchemaTypeSchemaInfo; import gw.lang.reflect.IPropertyAccessor; import gw.lang.reflect.IType; import gw.lang.reflect.TypeSystem; import gw.xml.XmlElement; import gw.xml.XmlSimpleValue; import gw.xml.XmlSimpleValueException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.xml.namespace.QName; public class IDREFSimpleValueFactory extends XmlSimpleValueFactory { @Override public IType getGosuValueType() { return TypeSystem.get( XmlElement.class ); } @Override protected XmlSimpleValue _gosuValueToStorageValue( Object gosuValue ) { return new Value( (XmlElement) gosuValue ); } @Override protected XmlSimpleValue _deserialize( XmlDeserializationContext context, String stringValue, boolean isDefault ) { final Value value = new Value( null ); context.addIdref( stringValue, value ); return value; // will get filled in with actual element later } public class Value extends XmlSimpleValueBase { private XmlElement _value; public Value( XmlElement value ) { setElement( value ); } @Override public IType getGosuValueType() { return IDREFSimpleValueFactory.this.getGosuValueType(); } @Override public XmlElement _getGosuValue() { if ( _value == null ) { throw new XmlSimpleValueException( "Unresolved IDREF. Attempt to deserialize IDREF outside of parse operation." ); } return _value; } @Override public String _getStringValue( boolean isEnumCode ) { final List<IPropertyAccessor> accessors = getIdAccessors(_value); if (accessors == null) { XmlSimpleValue simpleValue = _value.getSimpleValue(); if ( simpleValue instanceof IDSimpleValueFactory.Value ) { return ( (IDSimpleValueFactory.Value) simpleValue )._getGosuValue(); } for ( QName attrName : _value.getAttributeNames() ) { XmlSimpleValue val = _value.getAttributeSimpleValue( attrName ); if ( val instanceof IDSimpleValueFactory.Value ) { return ( (IDSimpleValueFactory.Value) val )._getGosuValue(); } } throw new XmlSimpleValueException( "The schema does not define an ID member for element nor does element have ID " + _value.getQName() ); } else { return (String) accessors.get( 0 ).getValue( _value.getTypeInstance() ); } } @Override public String _serialize( XmlSerializationContext context ) { String idValue = _getStringValue( false ); return context.makeUniqueId( _value, idValue ); } @Override public List<QName> _getQNames() { return Collections.emptyList(); } public void setElement( XmlElement element ) { if ( element != null ) { final List<IPropertyAccessor> accessors = getIdAccessors(element); if (accessors != null) { for ( IPropertyAccessor accessor : accessors) { if ( accessor.getValue( element.getTypeInstance() ) == null ) { accessor.setValue( element.getTypeInstance(), "ID" ); } } } } _value = element; } private List<IPropertyAccessor> getIdAccessors( XmlElement element ) { List<IPropertyAccessor> accessors = new ArrayList<IPropertyAccessor>(); final XmlSchemaTypeSchemaInfo schemaInfo = XmlSchemaIndex.getSchemaInfoByType( element.getTypeInstance().getIntrinsicType() ); for ( XmlSchemaPropertySpec property : schemaInfo.getProperties() ) { if ( property.getSimpleValueFactory() instanceof IDSimpleValueFactory ) { String propertyName = property.getSimpleTypePropertyName(); accessors.add( element.getTypeInstance().getIntrinsicType().getTypeInfo().getProperty( propertyName ).getAccessor() ); } } return accessors.isEmpty() ? null : accessors; } } }