/* * Copyright 2013 Guidewire Software, Inc. */ package gw.internal.xml.xsd.typeprovider; import gw.internal.xml.xsd.typeprovider.schema.XmlSchemaComplexContent; import gw.internal.xml.xsd.typeprovider.schema.XmlSchemaComplexContentRestriction; import gw.internal.xml.xsd.typeprovider.schema.XmlSchemaComplexType; import gw.internal.xml.xsd.typeprovider.schema.XmlSchemaType; import gw.internal.xml.xsd.typeprovider.simplevaluefactory.XmlSimpleValueFactory; import gw.internal.xml.xsd.typeprovider.validator.XmlSimpleValueValidator; import gw.lang.reflect.IType; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.xml.namespace.QName; public final class XmlSchemaTypeSchemaInfo extends XmlSchemaSimpleValueProvider { private final XmlSchemaTypeInstanceTypeData _typeData; private final List<XmlSchemaPropertySpec> _properties = new ArrayList<XmlSchemaPropertySpec>( 0 ); private final Map<QName, XmlSchemaPropertySpec> _propertyNameByElementName = new HashMap<QName, XmlSchemaPropertySpec>(); private final LinkedHashMap<QName, XmlSchemaPropertySpec> _propertyNameByAttributeName = new LinkedHashMap<QName, XmlSchemaPropertySpec>(); private final XmlSimpleValueFactory _xmlSimpleValueFactory; private final XmlSimpleValueValidator _validator; private final boolean _hasSimpleContent; private final boolean _isComplexRestriction; private final boolean _mixed; public XmlSchemaTypeSchemaInfo( XmlSchemaTypeInstanceTypeData type, XmlSimpleValueFactory xmlSimpleValueFactory, XmlSimpleValueValidator validator ) { if ( ( xmlSimpleValueFactory == null ) != ( validator == null ) ) { throw new RuntimeException( "Expected either a factory and a validator, or neither" ); } _hasSimpleContent = validator != null; _typeData = type; _xmlSimpleValueFactory = xmlSimpleValueFactory; _validator = validator; boolean isComplexRestriction = false; boolean mixed = false; if ( _typeData.getXsdType() instanceof XmlSchemaComplexType ) { XmlSchemaComplexType complexType = (XmlSchemaComplexType) _typeData.getXsdType(); if ( complexType.isMixed() ) { mixed = true; } if ( complexType.getContentModel() instanceof XmlSchemaComplexContent ) { XmlSchemaComplexContent complexContent = (XmlSchemaComplexContent) complexType.getContentModel(); if ( complexContent.getContent() instanceof XmlSchemaComplexContentRestriction ) { isComplexRestriction = true; } } } _mixed = mixed; _isComplexRestriction = isComplexRestriction; } public boolean hasSimpleContent() { return _hasSimpleContent; } public XmlSimpleValueFactory getSimpleValueFactory() { return _xmlSimpleValueFactory; } public XmlSimpleValueValidator getValidator() { return _validator; } public void addProperty( XmlSchemaPropertySpec prop ) { _properties.add( prop ); if ( prop.getPropertyType() == XmlSchemaPropertyType.ELEMENT ) { XmlSchemaPropertySpec oldValue = _propertyNameByElementName.put( prop.getQName(), prop ); if ( oldValue != null && ! oldValue.equals( prop ) ) { // should not happen due to earlier checks in XmlSchemaGosuTypeInfoClass... throw new RuntimeException( "Ambiguous schema: Found element " + prop + " and " + oldValue ); } } else if ( prop.getPropertyType() == XmlSchemaPropertyType.ATTRIBUTE ) { XmlSchemaPropertySpec oldValue = _propertyNameByAttributeName.put( prop.getQName(), prop ); if ( oldValue != null && ! oldValue.equals( prop ) ) { // should not happen due to earlier checks in XmlSchemaGosuTypeInfoClass... throw new RuntimeException( "Ambiguous schema: Found attribute " + prop + " and " + oldValue ); } } else { throw new RuntimeException( "Unknown property type: " + prop.getPropertyType() ); } } public XmlSchemaTypeSchemaInfo getSuperElementInfo() { IType type = _typeData.getType(); XmlSchemaTypeSchemaInfo superElementInfo = null; if ( type.getSupertype() != null ) { superElementInfo = XmlSchemaIndex.getSchemaInfoByType( type.getSupertype() ); } return superElementInfo; } public List<XmlSchemaPropertySpec> getProperties() { return Collections.unmodifiableList( _properties ); } public XmlSchemaPropertySpec getPropertyByAttributeName( QName attributeName ) { XmlSchemaPropertySpec property = _propertyNameByAttributeName.get( attributeName ); if ( property == null ) { XmlSchemaTypeSchemaInfo superElementInfo = getSuperElementInfo(); if ( superElementInfo != null ) { property = superElementInfo.getPropertyByAttributeName( attributeName ); } } return property; } public XmlSchemaPropertySpec getPropertyByElementName( QName elementName ) { XmlSchemaPropertySpec property = _propertyNameByElementName.get( elementName ); if ( property == null ) { XmlSchemaTypeSchemaInfo superElementInfo = getSuperElementInfo(); if ( superElementInfo != null ) { property = superElementInfo.getPropertyByElementName( elementName ); } } return property; } public XmlSchemaType getXsdType() { return _typeData.getXsdType(); } /** * Returns an ordered set of attribute names. * @return an ordered set of attribute names */ public Set<QName> getAttributeNames() { return _propertyNameByAttributeName.keySet(); } public IXmlSchemaTypeInstanceTypeData getTypeData() { return _typeData; } public boolean isComplexRestriction() { return _isComplexRestriction; } public boolean isMixed() { return _mixed; } }