/* This file is part of KDE Schema Parser Copyright (c) 2005 Tobias Koenig based on wsdlpull parser by Vivek Krishna This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include "fileprovider.h" #include "parser.h" using namespace Schema; const TQString soapEncUri = "http://schemas.xmlsoap.org/soap/encoding/"; const TQString wsdlUri = "http://schemas.xmlsoap.org/wsdl/"; Parser::Parser( const TQString &nameSpace ) : mNameSpace( nameSpace ) { mElementQualified = false; mAttributeQualified = false; } Parser::~Parser() { clear(); } Types Parser::types() const { Types types; SimpleType::List simpleTypes; ComplexType::List complexTypes; for ( int i = 0; i < numTypes(); i++ ) { const XSDType *pType = type( i + XSDType::ANYURI + 1 ); if ( pType != 0 ) { if ( pType->isSimple() ) { const SimpleType *simpleType = static_cast( pType ); SimpleType type = *simpleType; type.setBaseTypeName( mTypesTable.typeName( type.baseType() ) ); type.setListTypeName( mTypesTable.typeName( type.listType() ) ); simpleTypes.append( type ); } else { const ComplexType *complexType = static_cast( pType ); ComplexType type = *complexType; type.setBaseTypeName( mTypesTable.typeName( type.baseType() ) ); Schema::Element::List elements = type.elements(); Schema::Element::List::Iterator elemIt; for ( elemIt = elements.begin(); elemIt != elements.end(); ++elemIt ) (*elemIt).setTypeName( mTypesTable.typeName( (*elemIt).type() ) ); type.setElements( elements ); Schema::Attribute::List attributes = type.attributes(); Schema::Attribute::List::Iterator attrIt; for ( attrIt = attributes.begin(); attrIt != attributes.end(); ++attrIt ) (*attrIt).setTypeName( mTypesTable.typeName( (*attrIt).type() ) ); type.setAttributes( attributes ); complexTypes.append( type ); } } } Element::List elements; for ( uint i = 0; i < mElements.count(); ++i ) { Element element = *mElements[ i ]; element.setTypeName( mTypesTable.typeName( element.type() ) ); elements.append( element ); } types.setSimpleTypes( simpleTypes ); types.setComplexTypes( complexTypes ); types.setElements( elements ); return types; } void Parser::clear() { mTypesTable.clear(); mImportedSchemas.clear(); for ( uint i = 0; i < mElements.count(); ++i ) delete mElements[ i ]; for ( uint i = 0; i < mAttributes.count(); ++i ) delete mAttributes[ i ]; } void Parser::setSchemaBaseUrl( const TQString &url ) { mSchemaBaseUrl = url; } void Parser::parseNameSpace( const TQDomElement &element ) { TQDomNamedNodeMap attributes = element.attributes(); for ( uint i = 0; i < attributes.count(); ++i ) { TQDomNode node = attributes.item( i ); TQDomAttr attribute = node.toAttr(); if ( attribute.name().startsWith( "xmlns:" ) ) mNameSpaceMap.insert( attribute.value(), attribute.name().mid( 6 ) ); } } bool Parser::parseSchemaTag( const TQDomElement &root ) { QualifiedName name = root.tagName(); if ( name.localName() != "schema" ) return false; if ( root.hasAttribute( "targetNamespace" ) ) mNameSpace = root.attribute( "targetNamespace" ); if ( root.hasAttribute( "elementFormDefault" ) ) { const TQString value = root.attribute( "elementFormDefault" ); if ( value == "unqualified" ) mElementQualified = false; else if ( value == "qualified" ) mElementQualified = true; } mTypesTable.setTargetNamespace( mNameSpace ); /* for (i = xParser->getNamespaceCount(xParser->getDepth()) - 1; i > xParser->getNamespaceCount(xParser->getDepth() - 1) - 1; i--) if (xParser->getNamespaceUri(i) == mNameSpace) m_tnsPrefix = xParser->getNamespacePrefix(i); */ TQDomNode node = root.firstChild(); while ( !node.isNull() ) { TQDomElement element = node.toElement(); if ( !element.isNull() ) { QualifiedName name = element.tagName(); if ( name.localName() == "import" ) { parseImport( element ); } else if ( name.localName() == "element" ) { parseElement( element ); } else if ( name.localName() == "complexType" ) { XSDType *type = parseComplexType( element ); mTypesTable.addType( type ); } else if ( name.localName() == "simpleType" ) { XSDType *type = parseSimpleType( element ); mTypesTable.addType( type ); } else if ( name.localName() == "attribute" ) { parseAttribute( element ); } else if ( name.localName() == "annotation" ) { parseAnnotation( element ); } else if ( name.localName() == "import" ) { // TODO } else if ( name.localName() == "include" ) { // TODO } } node = node.nextSibling(); } if ( shouldResolve() ) { resolveForwardElementRefs(); resolveForwardAttributeRefs(); resolveForwardDerivations(); } return true; } void Parser::parseImport( const TQDomElement &element ) { TQString location = element.attribute( "schemaLocation" ); if ( !location.isEmpty() ) { // don't import a schema twice if ( mImportedSchemas.contains( location ) ) return; else mImportedSchemas.append( location ); importSchema( location ); } } void Parser::parseAnnotation( const TQDomElement& ) { } void Parser::parseAnnotation( const TQDomElement &element, TQString &documentation ) { TQDomNode node = element.firstChild(); while ( !node.isNull() ) { TQDomElement childElement = node.toElement(); if ( !childElement.isNull() ) { QualifiedName name = childElement.tagName(); if ( name.localName() == "documentation" ) documentation = childElement.text().stripWhiteSpace(); } node = node.nextSibling(); } } void Parser::parseAnnotation( const TQDomElement &element, ComplexType *complexType ) { TQDomNode node = element.firstChild(); while ( !node.isNull() ) { TQDomElement childElement = node.toElement(); if ( !childElement.isNull() ) { QualifiedName name = childElement.tagName(); if ( name.localName() == "documentation" ) complexType->setDocumentation( childElement.text().stripWhiteSpace() ); } node = node.nextSibling(); } } void Parser::parseAnnotation( const TQDomElement &element, SimpleType *simpleType ) { TQDomNode node = element.firstChild(); while ( !node.isNull() ) { TQDomElement childElement = node.toElement(); if ( !childElement.isNull() ) { QualifiedName name = childElement.tagName(); if ( name.localName() == "documentation" ) simpleType->setDocumentation( childElement.text().stripWhiteSpace() ); } node = node.nextSibling(); } } XSDType *Parser::parseComplexType( const TQDomElement &element ) { ComplexType *newType = new ComplexType( mNameSpace ); newType->setName( element.attribute( "name" ) ); if ( element.hasAttribute( "mixed" ) ) newType->setContentModel( newType->MIXED ); TQDomNode node = element.firstChild(); while ( !node.isNull() ) { TQDomElement childElement = node.toElement(); if ( !childElement.isNull() ) { QualifiedName name = childElement.tagName(); if ( name.localName() == "all" ) { all( childElement, newType ); } else if ( name.localName() == "sequence" ) { cs( childElement, newType ); } else if ( name.localName() == "choice" ) { cs( childElement, newType ); } else if ( name.localName() == "attribute" ) { addAttribute( childElement, newType ); } else if ( name.localName() == "anyAttribute" ) { addAnyAttribute( childElement, newType ); } else if ( name.localName() == "complexContent" ) { parseComplexContent( childElement, newType ); } else if ( name.localName() == "simpleContent" ) { parseSimpleContent( childElement, newType ); } else if ( name.localName() == "annotation" ) { parseAnnotation( childElement, newType ); } } node = node.nextSibling(); } return newType; } void Parser::all( const TQDomElement &element, ComplexType * ct ) { int min, max; TQString tmp; min = element.attribute( "minOccurs", "1" ).toInt(); max = element.attribute( "maxOccurs", "1" ).toInt(); ct->setCompositor( ct->ALL, true, min, max ); TQDomNode node = element.firstChild(); while ( !node.isNull() ) { TQDomElement childElement = node.toElement(); if ( !childElement.isNull() ) { QualifiedName name = childElement.tagName(); if ( name.localName() == "element" ) { addElement( childElement, ct ); } else if ( name.localName() == "annotation" ) { parseAnnotation( childElement, ct ); } } node = node.nextSibling(); } /* if (xParser->getName() == "all" && xParser->getEventType() == xParser->END_TAG) ct->setCompositor(ct->ALL, false); */ return; } void Parser::cs( const TQDomElement &element, ComplexType *ct ) { int min = 1, max = 1; QualifiedName name = element.tagName(); if ( name.localName() == "choice" || name.localName() == "sequence" ) { min = element.attribute( "minOccurs", "1" ).toInt(); TQString value = element.attribute( "maxOccurs", "1" ); if ( value == "unbounded" ) max = UNBOUNDED; else max = value.toInt(); if ( name.localName() == "choice" ) ct->setCompositor( ct->CHOICE, true, min, max ); else ct->setCompositor( ct->SEQ, true, min, max ); TQDomNode node = element.firstChild(); while ( !node.isNull() ) { TQDomElement childElement = node.toElement(); if ( !childElement.isNull() ) { QualifiedName csName = childElement.tagName(); if ( csName.localName() == "element" ) addElement( childElement, ct ); else if ( csName.localName() == "any" ) addAny( childElement, ct ); else if ( csName.localName() == "choice" ) cs( childElement, ct ); else if ( csName.localName() == "sequence" ) cs( childElement, ct ); } node = node.nextSibling(); } if ( name.localName() == "choice") ct->setCompositor( ct->CHOICE, false ); else ct->setCompositor( ct->SEQ, false ); } return; } void Parser::addElement( const TQDomElement &element, ComplexType *cType ) { TQString name, fixedValue, defaultValue, documentation; QualifiedName refName; int type_id = 0, minOccurs = 1, maxOccurs = 1; bool qualified = false, added = false, nill = false; XSDType *elemType; name = element.attribute( "name" ); QualifiedName typeName = element.attribute( "type" ); // typeName.setNamespace(xParser->getNamespace(typeName.getPrefix())); type_id = typeId( typeName, true ); if ( element.hasAttribute( "form" ) ) { if ( element.attribute( "form" ) == "qualified" ) qualified = true; else if ( element.attribute( "form" ) == "unqualified" ) qualified = false; } if ( element.hasAttribute( "ref" ) ) { refName = element.attribute( "ref" ); // refName.setNamespace(xParser->getNamespace(refName.getPrefix())); Element *e = 0; if ( refName.nameSpace() == mNameSpace ) e = this->element( elementId( refName ) ); if ( e == 0 ) { added = true; mForwardElementRef.append( refName ); } else { name = e->name(); type_id = e->type(); qualified = e->isQualified(); defaultValue = e->defaultValue(); fixedValue = e->fixedValue(); } } minOccurs = element.attribute( "minOccurs", "1" ).toInt(); TQString value = element.attribute( "maxOccurs", "1" ); if ( value == "unbounded" ) maxOccurs = UNBOUNDED; else maxOccurs = value.toInt(); defaultValue = element.attribute( "default" ); fixedValue = element.attribute( "fixed" ); if ( element.hasAttribute( "nillable" ) ) nill = true; TQDomNode node = element.firstChild(); while ( !node.isNull() ) { TQDomElement childElement = node.toElement(); if ( !childElement.isNull() ) { QualifiedName childName = childElement.tagName(); if ( childName.localName() == "complexType" ) { elemType = parseComplexType( childElement ); // create an anonymous type ComplexType *ct = (ComplexType *) elemType; if ( ct->numElements() == 1 && ct->elementType( 0 ) == XSDType::ANY && ct->elementName( 0 ) == "any" ) { // if the complex type is then we dont need a type for it. // make the tqparent's type as XSDType::ANY delete ct; type_id = XSDType::ANY; } else { elemType->setName( name ); type_id = mTypesTable.addType( elemType ); } } else if ( childName.localName() == "simpleType" ) { elemType = parseSimpleType( childElement ); //create an anonymous type type_id = mTypesTable.addType( elemType ); } else if ( childName.localName() == "annotation" ) { parseAnnotation( childElement, documentation ); } } node = node.nextSibling(); } if ( nill && type_id == 0 ) type_id = XSDType::ANYTYPE; if ( !added ) { cType->addElement( name, type_id, minOccurs, maxOccurs, qualified, defaultValue, fixedValue, documentation ); } else { cType->addElementRef( refName, minOccurs, maxOccurs ); } } void Parser::addAny( const TQDomElement &element, ComplexType *cType ) { TQString ns, any( "any" ); int type_id = XSDType::ANY, min = 1, max = 1; ns = element.attribute( "namespace" ); min = element.attribute( "minOccurs", "1" ).toInt(); TQString value = element.attribute( "maxOccurs", "1" ); if ( value == "unbounded" ) max = UNBOUNDED; else max = value.toInt(); cType->addElement( any, type_id, min, max, false, ns ); } void Parser::addAnyAttribute( const TQDomElement &element, ComplexType *cType ) { TQString ns, anyAttribute( "anyAttribute" ); ns = element.attribute( "namespace" ); cType->addAttribute( anyAttribute, XSDType::ANY, false, ns ); } void Parser::addAttribute( const TQDomElement &element, ComplexType *cType ) { TQString name, fixedVal, defaultVal; int type_id = 0; bool qualified = false, use = false, added = false; QualifiedName refAttribute; name = element.attribute( "name" ); if ( element.hasAttribute( "type" ) ) { QualifiedName typeName = element.attribute( "type" ); // typeName.setNamespace(xParser->getNamespace(typeName.getPrefix())); type_id = typeId( typeName, true ); } if ( element.hasAttribute( "form" ) ) { if ( element.attribute( "form" ) == "qualified" ) qualified = true; else if ( element.attribute( "form" ) == "unqualified" ) qualified = false; } if ( element.hasAttribute( "ref" ) ) { refAttribute = element.attribute( "ref" ); // refAttribute.setNamespace(xParser->getNamespace(refAttribute.getPrefix())); Attribute *attribute = 0; if ( refAttribute.nameSpace() == mNameSpace ) attribute = this->attribute( attributeId( refAttribute ) ); if ( attribute == 0 ) { added = true; mForwardAttributeRef.append( refAttribute ); } else { name = attribute->name(); type_id = attribute->type(); qualified = attribute->isQualified(); defaultVal = attribute->defaultValue(); fixedVal = attribute->fixedValue(); } } defaultVal = element.attribute( "default" ); fixedVal = element.attribute( "fixed" ); if ( element.hasAttribute( "use" ) ) { if ( element.attribute( "use" ) == "optional" ) use = false; else if ( element.attribute( "use" ) == "required" ) use = true; } TQDomNode node = element.firstChild(); while ( !node.isNull() ) { TQDomElement childElement = node.toElement(); if ( !childElement.isNull() ) { QualifiedName childName = childElement.tagName(); if ( childName.localName() == "simpleType" ) { XSDType *elemType = parseSimpleType( childElement ); elemType->setName( name ); type_id = mTypesTable.addType( elemType ); } else if ( childName.localName() == "annotation" ) { // TKO: we have to pass it to the element here... parseAnnotation( childElement ); } } node = node.nextSibling(); } if ( !added ) cType->addAttribute( name, type_id, qualified, defaultVal, fixedVal, use ); else cType->addAttributeRef( refAttribute, qualified, use ); } XSDType *Parser::parseSimpleType( const TQDomElement &element ) { SimpleType *st = new SimpleType( mNameSpace ); int basetype_id = XSDType::INVALID; st->setName( element.attribute( "name" ) ); TQDomNode node = element.firstChild(); while ( !node.isNull() ) { TQDomElement childElement = node.toElement(); if ( !childElement.isNull() ) { QualifiedName name = childElement.tagName(); if ( name.localName() == "restriction" ) { st->setSubType( SimpleType::TypeRestriction ); QualifiedName typeName( childElement.attribute( "base" ) ); // typeName.setNamespace(xParser->getNamespace(typeName.getPrefix())); st->setBaseType( basetype_id = typeId( typeName, true ) ); parseRestriction( childElement, st ); } else if ( name.localName() == "union" ) { st->setSubType( SimpleType::TypeUnion ); qDebug( "simpletype::union not supported" ); } else if ( name.localName() == "list" ) { st->setSubType( SimpleType::TypeList ); if ( childElement.hasAttribute( "itemType" ) ) { QualifiedName typeName( childElement.attribute( "itemType" ) ); int type = typeId( typeName, true ); st->setListType( type ); } else { // TODO: add support for anonymous types } } else if ( name.localName() == "annotation" ) { parseAnnotation( childElement, st ); } } node = node.nextSibling(); } return st; } void Parser::parseRestriction( const TQDomElement &element, SimpleType *st ) { if ( st->baseType() == 0 ) qDebug( ":unkown BaseType" ); TQDomNode node = element.firstChild(); while ( !node.isNull() ) { TQDomElement childElement = node.toElement(); if ( !childElement.isNull() ) { if ( !st->isValidFacet( childElement.tagName() ) ) { qDebug( ": %s is not a valid facet for the simple type", childElement.tagName().latin1() ); continue; } st->setFacetValue( childElement.attribute( "value" ) ); } node = node.nextSibling(); } } void Parser::parseComplexContent( const TQDomElement &element, ComplexType *ct ) { QualifiedName typeName; if ( element.attribute( "mixed" ) == "true" ) { qDebug( ": No support for mixed=true" ); return; } ct->setContentModel( ct->COMPLEX ); TQDomNode node = element.firstChild(); while ( !node.isNull() ) { TQDomElement childElement = node.toElement(); if ( !childElement.isNull() ) { QualifiedName name = childElement.tagName(); if ( name.localName() == "restriction" || name.localName() == "extension" ) { typeName = childElement.attribute( "base" ); // typeName.setNamespace(xParser->getNamespace(typeName.getPrefix())); ComplexType::Derivation type = ( name.localName() == "restriction" ? ComplexType::Restriction : ComplexType::Extension ); if ( this->type( typeName ) != 0 ) { // type already known ct->setBaseType( typeId( typeName, true ), type, this->type( typeName ) ); } else { ForwardDerivation entry; entry.type = ct->qualifiedName(); entry.baseType = typeName; entry.derivation = type; mForwardDerivations.append( entry ); } // if the base soapenc:Array, then read only the arrayType attribute and nothing else if ( typeName.localName() == "Array" ) { TQDomElement arrayElement = childElement.firstChild().toElement(); ct->setIsArray( true ); QualifiedName arrayType( arrayElement.attribute( "arrayType" ) ); // arrayType.setNamespace(xParser->getNamespace(arrayType.getPrefix())); ct->addElement( "item", typeId( arrayType, true ), 0, UNBOUNDED ); } else { TQDomNode childNode = childElement.firstChild(); while ( !childNode.isNull() ) { TQDomElement ctElement = childNode.toElement(); if ( !ctElement.isNull() ) { QualifiedName name = ctElement.tagName(); if ( name.localName() == "all" ) { all( ctElement, ct ); } else if ( name.localName() == "sequence" ) { cs( ctElement, ct ); } else if ( name.localName() == "choice" ) { cs( ctElement, ct ); } else if ( name.localName() == "attribute" ) { addAttribute( ctElement, ct ); } else if ( name.localName() == "anyAttribute" ) { addAnyAttribute( ctElement, ct ); } } childNode = childNode.nextSibling(); } } } } node = node.nextSibling(); } } void Parser::parseSimpleContent( const TQDomElement &element, ComplexType *ct ) { ct->setContentModel( ct->SIMPLE ); const TQDomElement childElement = element.firstChild().toElement(); QualifiedName name = childElement.tagName(); if ( name.localName() == "restriction" ) { SimpleType *st = new SimpleType( mNameSpace ); if ( childElement.hasAttribute( "base" ) ) { int basetype_id = 0; QualifiedName typeName( childElement.attribute( "base" ) ); // typeName.setNamespace(xParser->getNamespace(typeName.getPrefix())); st->setBaseType( basetype_id = typeId( typeName, true ) ); } parseRestriction( childElement, st ); int typeId = mTypesTable.addType( st ); if ( typeId == 0 ) { qDebug( "Could not add type in types table" ); return; } ct->setContentType( typeId ); } else if ( name.localName() == "extension" ) { // This extension does not use the full model that can come in ComplexContent. // It uses the simple model. No particle allowed, only attributes if ( childElement.hasAttribute( "base" ) ) { int basetype_id = 0; QualifiedName typeName( childElement.attribute( "base" ) ); // typeName.setNamespace(xParser->getNamespace(typeName.getPrefix())); ct->setContentType( basetype_id = typeId( typeName, true ) ); TQDomNode childNode = childElement.firstChild(); while ( !childNode.isNull() ) { TQDomElement ctElement = childNode.toElement(); if ( !ctElement.isNull() ) { QualifiedName name = ctElement.tagName(); if ( name.localName() == "attribute" ) addAttribute( ctElement, ct ); } childNode = childNode.nextSibling(); } } } } bool Parser::isBasicType( int type ) const { if ( type > XSDType::ANYURI ) return false; else return true; } void Parser::parseElement( const TQDomElement &element ) { ComplexType *ct = new ComplexType( mNameSpace ); addElement( element, ct ); ComplexType *elementType = (ComplexType*)type( ct->element( 0 )->name() ); if ( elementType ) { elementType->setDocumentation( ct->element( 0 )->documentation() ); } Element *elementPtr = new Element(); *elementPtr = (*ct->element( 0 )); delete ct; mElements.append( elementPtr ); } void Parser::parseAttribute( const TQDomElement &element ) { ComplexType *ct = new ComplexType( mNameSpace ); addAttribute( element, ct ); Attribute *attributePtr = new Attribute(); *attributePtr = (*ct->attribute( 0 )); delete ct; mAttributes.append( attributePtr ); } int Parser::addExternalElement( const TQString &name, int localTypeId ) { Element *element = new Element( name, localTypeId ); mElements.append( element ); return mElements.count() - 1; } int Parser::typeId( const QualifiedName &type, bool create ) { QualifiedName typeName( type ); TQString typens = typeName.nameSpace(); if ( typens.isEmpty() ) typeName.setNameSpace( typens = mNameSpace ); if ( typens == mNameSpace || typens == SchemaUri ) { return mTypesTable.typeId( typeName, create ); } else { return mTypesTable.addExternalTypeId( typeName, 0 ); } } TQString Parser::typeName( int id ) const { return mTypesTable.typeName( id ); } bool Parser::finalize() { if ( mTypesTable.detectUndefinedTypes() ) return false; else return true; } void Parser::resolveForwardElementRefs() { if ( mForwardElementRef.isEmpty() ) return; QualifiedName::List::ConstIterator it; for ( it = mForwardElementRef.begin(); it != mForwardElementRef.end(); ++it ) { Element *e = element( elementId( *it ) ); if ( e ) mTypesTable.resolveForwardElementRefs( (*it).localName(), *e ); else qDebug( "Could not resolve element reference %s ", (*it).localName().latin1() ); } } void Parser::resolveForwardAttributeRefs() { if ( mForwardAttributeRef.isEmpty() ) return; QualifiedName::List::ConstIterator it; for ( it = mForwardAttributeRef.begin(); it != mForwardAttributeRef.end(); ++it ) { Attribute *a = attribute( attributeId( *it ) ); if ( a ) mTypesTable.resolveForwardAttributeRefs( (*it).localName(), *a ); else qDebug( "Could not resolve attribute reference %s ", (*it).localName().latin1() ); } } void Parser::resolveForwardDerivations() { if ( mForwardDerivations.isEmpty() ) return; int id; ComplexType *type = 0; TQValueList::ConstIterator it; for ( it = mForwardDerivations.begin(); it != mForwardDerivations.end(); ++it ) { if ( ( id = typeId( (*it).type, false ) ) == 0 ) continue; else type = (ComplexType*)mTypesTable.typePtr( id ); if ( type ) type->setBaseType( typeId( (*it).baseType, true ), (*it).derivation, this->type( (*it).baseType ) ); } mForwardDerivations.clear(); } int Parser::elementId( const QualifiedName &type ) { QualifiedName typeName( type ); TQString typens = typeName.nameSpace(); if ( typens.isEmpty() ) typeName.setNameSpace( typens = mNameSpace ); int i = 0; // check if it is a global element for ( i = 0; i < (int)mElements.count(); i++ ) if ( mElements[ i ]->name() == typeName.localName() ) return i; return -1; } int Parser::elementType( const QualifiedName &type ) { int id = elementId( type ); if ( id == -1 ) return 0; Element *e = element( id ); if ( e != 0 ) return e->type(); else return 0; } Element *Parser::element( const QualifiedName &name ) const { QualifiedName elementName( name ); TQString typens = elementName.nameSpace(); if ( typens.isEmpty() ) elementName.setNameSpace( typens = mNameSpace ); if ( typens == mNameSpace || typens == SchemaUri ) { int i = 0; // check if it is a global element for ( i = 0; i < (int)mElements.count(); i++ ) if ( mElements[ i ]->name() == elementName.localName() ) return mElements[ i ]; return 0; } return 0; } Element *Parser::element( int id ) const { if ( id >= 0 && id < (int)mElements.count() ) return mElements[ id ]; else return 0; } Element::PtrList Parser::elements() const { return mElements; } int Parser::attributeId( const QualifiedName &type ) const { QualifiedName typeName( type ); TQString typens = typeName.nameSpace(); if ( typens.isEmpty() ) typeName.setNameSpace( typens = mNameSpace ); if ( typens != mNameSpace && typens != SchemaUri ) { qDebug( "Namespace does not match" ); return -1; } // check if it is a global attribute for ( int i = 0; i < (int)mAttributes.count(); i++ ) if ( mAttributes[ i ]->name() == typeName.localName() ) return i; return -1; } int Parser::attributeType( const QualifiedName &type ) { int attId = attributeId( type ); if ( attId == -1 ) return 0; Attribute *a = attribute( attId ); if ( a != 0 ) return a->type(); else return 0; } Attribute *Parser::attribute( int id ) const { if ( id >= 0 && id < (int)mAttributes.count() ) return mAttributes[ id ]; else return 0; } Attribute *Parser::attribute( const QualifiedName &name ) const { int id = attributeId( name ); if ( id != -1 ) return mAttributes[ id ]; else return 0; } TQString Parser::targetNamespace() const { return mNameSpace; } const XSDType *Parser::type( int id ) const { return (const XSDType *)mTypesTable.typePtr( id ); } const XSDType *Parser::type( const QualifiedName &type ) { int id; if ( ( id = typeId( type, false ) ) == 0 ) return 0; else return (const XSDType *)mTypesTable.typePtr( id ); } int Parser::numTypes() const { return mTypesTable.numTypes(); } int Parser::numElements() const { return mElements.count(); } int Parser::numAttributes() const { return mAttributes.count(); } bool Parser::shouldResolve() { return true; } void Parser::importSchema( const TQString &location ) { FileProvider provider; TQString fileName; TQString schemaLocation( location ); TQUrl url( location ); TQDir dir( location ); if ( (url.protocol().isEmpty() || url.protocol() == "file") && dir.isRelative() ) schemaLocation = mSchemaBaseUrl + "/" + location; if ( provider.get( schemaLocation, fileName ) ) { TQFile file( fileName ); if ( !file.open( IO_ReadOnly ) ) { qDebug( "Unable to open file %s", file.name().latin1() ); return; } TQDomDocument doc( "kwsdl" ); TQString errorMsg; int errorLine, errorColumn; bool ok = doc.setContent( &file, true, &errorMsg, &errorLine, &errorColumn ); if ( !ok ) { qDebug( "Error[%d:%d] %s", errorLine, errorColumn, errorMsg.latin1() ); return; } TQDomNodeList nodes = doc.elementsByTagName( "schema" ); if ( nodes.count() > 0 ) { TQDomElement schemaElement = nodes.item( 0 ).toElement(); parseSchemaTag( schemaElement ); } else { qDebug( "No schema tag found in schema file" ); } file.close(); provider.cleanUp(); } }