/*
* Copyright 2013 Guidewire Software, Inc.
*/
package gw.xml;
import gw.internal.xml.XmlMixedContentList;
import gw.internal.xml.XmlTypeInstanceInternals;
import gw.internal.xml.XmlUtil;
import gw.internal.xml.xsd.typeprovider.IXmlSchemaTypeInstanceTypeData;
import gw.internal.xml.xsd.typeprovider.XmlSchemaIndex;
import gw.internal.xml.xsd.typeprovider.XmlSchemaTypeSchemaInfo;
import gw.lang.reflect.IType;
import gw.util.GosuExceptionUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
class XmlTypeInstanceInternalsImpl extends XmlTypeInstanceInternals {
private static final QName XSI_TYPE_ATTRIBUTE_QNAME = new QName( XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type" );
private static final QName XSI_NIL_ATTRIBUTE_QNAME = new QName( XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil" );
@Override
public XmlMixedContentList createContentList( XmlTypeInstance xmlTypeInstance ) {
return new XmlMixedContentList( xmlTypeInstance );
}
public final Set<QName> _getAttributeNames( XmlTypeInstance typeInstance ) {
LinkedHashMap<QName, XmlSimpleValue> attributes = typeInstance._attributes;
return attributes == null ? Collections.<QName>emptySet() : Collections.unmodifiableSet( attributes.keySet() );
}
public XmlSimpleValue _setAttributeSimpleValue( XmlTypeInstance typeInstance, QName attributeName, XmlSimpleValue value ) {
if ( attributeName == null ) {
throw new IllegalArgumentException( "Attribute name cannot be null" );
}
if ( attributeName.getPrefix().equals( XMLConstants.XMLNS_ATTRIBUTE )
|| ( attributeName.getPrefix().equals( XMLConstants.DEFAULT_NS_PREFIX ) && attributeName.getLocalPart().equals( XMLConstants.XMLNS_ATTRIBUTE ) )
|| ( attributeName.getNamespaceURI().equals( XMLConstants.XMLNS_ATTRIBUTE_NS_URI ) ) ) {
throw new XmlException( "Setting xmlns attributes directly is not supported." );
}
if ( typeInstance._type != null && attributeName.equals( XSI_TYPE_ATTRIBUTE_QNAME ) ) {
throw new XmlException( "Setting xsi:type directly is not supported on types other than xs:anyType." );
}
if ( attributeName.equals( XSI_NIL_ATTRIBUTE_QNAME ) ) {
throw new XmlException( "Setting xsi:nil directly is not supported." );
}
XmlUtil.validateQName( attributeName );
XmlSimpleValue oldValue;
if ( value == null ) {
oldValue = typeInstance._attributes == null ? null : typeInstance._attributes.remove( attributeName );
}
else {
if ( typeInstance._attributes == null ) {
typeInstance._attributes = new LinkedHashMap<QName, XmlSimpleValue>();
}
oldValue = typeInstance._attributes.put( attributeName, value );
}
return oldValue;
}
public XmlSimpleValue _setAttributeSimpleValue( XmlTypeInstance typeInstance, String attributeName, XmlSimpleValue value ) {
return typeInstance.setAttributeSimpleValue( new QName( attributeName ), value );
}
public XmlSimpleValue _getAttributeSimpleValue( XmlTypeInstance typeInstance, QName attributeName ) {
LinkedHashMap<QName, XmlSimpleValue> attributes = typeInstance._attributes;
return attributes == null ? null : attributes.get( attributeName );
}
public XmlSimpleValue _getAttributeSimpleValue( XmlTypeInstance typeInstance, String attributeName ) {
return typeInstance.getAttributeSimpleValue( new QName( attributeName ) );
}
public String _getAttributeValue( XmlTypeInstance typeInstance, String attributeName ) {
XmlSimpleValue simpleValue = typeInstance.getAttributeSimpleValue( attributeName );
return simpleValue == null ? null : simpleValue.getStringValue();
}
public String _getAttributeValue( XmlTypeInstance typeInstance, QName attributeName ) {
XmlSimpleValue simpleValue = typeInstance.getAttributeSimpleValue( attributeName );
return simpleValue == null ? null : simpleValue.getStringValue();
}
public String _setAttributeValue( XmlTypeInstance typeInstance, String attributeName, String value ) {
XmlSimpleValue simpleValue = typeInstance.setAttributeSimpleValue( attributeName, XmlSimpleValue.makeStringInstance( value ) );
return simpleValue == null ? null : simpleValue.getStringValue();
}
public String _setAttributeValue( XmlTypeInstance typeInstance, QName attributeName, String value ) {
XmlSimpleValue simpleValue = typeInstance.setAttributeSimpleValue( attributeName, XmlSimpleValue.makeStringInstance( value ) );
return simpleValue == null ? null : simpleValue.getStringValue();
}
public List<XmlElement> _getChildren( XmlTypeInstance typeInstance, QName qname ) {
return getContentList( typeInstance ).getElementsByQName( qname );
}
private XmlMixedContentList getContentList( XmlTypeInstance typeInstance ) {
return typeInstance._children;
}
public List<XmlElement> _removeChildren( XmlTypeInstance typeInstance, QName qname ) {
List<XmlElement> ret = new ArrayList<XmlElement>();
Iterator<IXmlMixedContent> iter = typeInstance._children.iterator();
while ( iter.hasNext() ) {
IXmlMixedContent content = iter.next();
if ( content instanceof XmlElement ) {
XmlElement element = (XmlElement) content;
if ( element.getQName().equals( qname ) ) {
ret.add( element );
iter.remove();
}
}
}
return ret;
}
public List<XmlElement> _getChildrenBySubstitutionGroup( XmlTypeInstance typeInstance, IType type ) {
return getContentList( typeInstance ).getElementsBySubstitutionGroup( type );
}
public List<XmlElement> _removeChildrenBySubstitutionGroup( XmlTypeInstance typeInstance, IType type ) {
return getContentList( typeInstance ).removeElementsBySubstitutionGroup( type );
}
public XmlElement _getChildBySubstitutionGroup( XmlTypeInstance typeInstance, IType type ) {
final List<XmlElement> elementList = _getChildrenBySubstitutionGroup( typeInstance, type );
if ( elementList.isEmpty() ) {
return null;
}
if ( elementList.size() > 1 ) {
throw new MultipleContentMatchesException( "Multiple matches for " + type.getName() );
}
return elementList.get( 0 );
}
public XmlElement _removeChildBySubstitutionGroup( XmlTypeInstance typeInstance, IType type ) {
final XmlElement child = _getChildBySubstitutionGroup( typeInstance, type );
if ( child != null ) {
typeInstance.getChildren().remove( child );
}
return child;
}
public XmlElement _getChild( XmlTypeInstance typeInstance, QName qname ) {
List<XmlElement> elementList = typeInstance.getChildren( qname );
if ( elementList.isEmpty() ) {
return null;
}
else if ( elementList.size() == 1 ) {
return elementList.get( 0 );
}
else {
throw new MultipleContentMatchesException( "Multiple matches for " + qname );
}
}
public XmlElement _removeChild( XmlTypeInstance typeInstance, QName qname ) {
List<XmlElement> elementList = typeInstance.getChildren( qname );
if ( elementList.isEmpty() ) {
return null;
}
else if ( elementList.size() == 1 ) {
XmlElement child = elementList.get( 0 );
typeInstance._children.remove( child );
return child;
}
else {
throw new MultipleContentMatchesException( "Multiple matches for " + qname );
}
}
public List<XmlElement> _getChildren( XmlTypeInstance typeInstance ) {
return typeInstance._children.getAllElements();
}
public void _addChild( XmlTypeInstance typeInstance, XmlElement element ) {
typeInstance._children.add( element );
}
public XmlSimpleValue _getSimpleValue( XmlTypeInstance typeInstance ) {
return typeInstance._simpleValue;
}
public void _setSimpleValue( XmlTypeInstance typeInstance, XmlSimpleValue simpleValue ) {
typeInstance._children.clear();
typeInstance._simpleValue = simpleValue;
}
public String _getText( XmlTypeInstance typeInstance ) {
return typeInstance._simpleValue == null ? "" : typeInstance._simpleValue.getStringValue();
}
public void _setText( XmlTypeInstance typeInstance, String text ) {
if ( text == null ) {
throw new IllegalArgumentException( "text cannot be null" );
}
typeInstance._children.clear();
typeInstance._simpleValue = XmlSimpleValue.makeStringInstance( text );
}
@Override
public IType getType( XmlTypeInstance typeInstance ) {
return typeInstance._type;
}
public XmlSchemaTypeSchemaInfo getSchemaInfo( XmlTypeInstance typeInstance ) {
return typeInstance._schemaInfo;
}
public void clearSimpleValue( XmlTypeInstance typeInstance ) {
typeInstance._simpleValue = null;
}
public XmlTypeInstance create( IType xmlTypeInstanceType, XmlSchemaTypeSchemaInfo schemaInfo, Object[] args ) {
IXmlSchemaTypeInstanceTypeData typeData = (IXmlSchemaTypeInstanceTypeData) xmlTypeInstanceType;
XmlTypeInstance instance;
try {
instance = (XmlTypeInstance) typeData.getConstructorInternal().newInstance( xmlTypeInstanceType, schemaInfo );
}
catch ( Exception ex ) {
throw GosuExceptionUtil.forceThrow( ex );
}
if ( args.length > 0 ) {
xmlTypeInstanceType.getTypeInfo().getProperty( "$Value" ).getAccessor().setValue( instance, args[0] );
}
return instance;
}
public Object getSchemaInfoByType( IType type ) {
return XmlSchemaIndex.getSchemaIndexByType( type ).getSchemaInfoByTypeName( type.getName() );
}
}