/* 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 "complextype.h" using namespace Schema; ComplexType::ComplexType( const TQString &nameSpace ) : mNameSpace( nameSpace ), mType ( 0 ), mContentModel( COMPLEX ), mMixed( false ), mAnonymous( false ), mIsArray( false ), mContentType( 0 ), mTopLevelGroup( ALL ), mCurrentGroup( 0 ), mPreviousGroup( 0 ), mForwardElementRef( false ), mForwardAttributeRef( false ) { mBaseType.typeId = XSDType::ANYTYPE; mBaseType.derivation = Extension; mBaseType.type = 0; } ComplexType::ComplexType() : mType ( 0 ), mContentModel( COMPLEX ), mMixed( false ), mAnonymous( false ), mIsArray( false ), mContentType( 0 ), mTopLevelGroup( ALL ), mCurrentGroup( 0 ), mPreviousGroup( 0 ), mForwardElementRef( false ), mForwardAttributeRef( false ) { mBaseType.typeId = XSDType::ANYTYPE; mBaseType.derivation = Extension; mBaseType.type = 0; } ComplexType::~ComplexType() { } TQString ComplexType::name() const { return mName; } QualifiedName ComplexType::qualifiedName() const { QualifiedName qn( mName ); qn.setNameSpace( mNameSpace ); return qn; } void ComplexType::setDocumentation( const TQString &documentation ) { mDocumentation = documentation; } TQString ComplexType::documentation() const { return mDocumentation; } int ComplexType::type() const { return mType; } int ComplexType::contentModel() const { return mContentModel; } int ComplexType::contentType() const { return mContentType; } bool ComplexType::isSimple() const { return false; } int ComplexType::attributeType( int index ) { return attribute( index )->type(); } TQString ComplexType::attributeName( int index ) { return attribute( index )->name(); } int ComplexType::elementType( int index ) { return element( index )->type(); } TQString ComplexType::elementName( int index ) { return element( index )->name(); } int ComplexType::numElements() const { return mElements.count(); } int ComplexType::numAttributes() const { return mAttributes.count(); } bool ComplexType::isAnonymous() const { return mAnonymous; } void ComplexType::setBaseTypeName( const TQString &baseTypeName ) { mBaseType.name = baseTypeName; } TQString ComplexType::baseTypeName() const { return mBaseType.name; } int ComplexType::baseType() const { return mBaseType.typeId; } int ComplexType::baseDerivation() const { return mBaseType.derivation; } ComplexType::Compositor ComplexType::topLevelGroup() const { return mTopLevelGroup; } ComplexType::Compositor ComplexType::groupType( int groupId ) const { return mGroups[ groupId ].type; } const Element *ComplexType::element( const TQString &name ) { Element::List::ConstIterator it; for ( it = mElements.begin(); it != mElements.end(); ++it ) { if ( (*it).name() == name ) return &(*it); } return 0; } Element *ComplexType::element( int id ) { if ( id < 0 || id >= (int)mElements.count() ) { qDebug( "tried to access non existent element" ); return 0; } Element::List::Iterator it = mElements.begin(); for ( int i = 0; i < (int)mElements.count(); ++i, ++it ) if ( id == i ) return &(*it); return 0; } const Attribute *ComplexType::attribute( const TQString &name ) { Attribute::List::ConstIterator it; for ( it = mAttributes.begin(); it != mAttributes.end(); ++it ) { if ( (*it).name() == name ) return &(*it); } return 0; } Attribute *ComplexType::attribute( int id ) { if ( id < 0 || id >= (int)mAttributes.count() ) { qDebug( "tried to access non existent attributes" ); return 0; } Attribute::List::Iterator it = mAttributes.begin(); for ( int i = 0; i < (int)mAttributes.count(); ++i, ++it ) if ( id == i ) return &(*it); return 0; } void ComplexType::setElements( const Element::List &elements ) { mElements = elements; } Element::List ComplexType::elements() const { return mElements; } void ComplexType::setAttributes( const Attribute::List &attributes ) { mAttributes = attributes; } Attribute::List ComplexType::attributes() const { return mAttributes; } bool ComplexType::isArray() const { return mIsArray; } void ComplexType::setType( int type ) { mType = type; } void ComplexType::setIsArray( bool isArray ) { mIsArray = isArray; } void ComplexType::setBaseType( int type, Derivation derivation, const XSDType *ptr ) { mBaseType.typeId = type; mBaseType.derivation = derivation; mBaseType.type = ptr; } void ComplexType::setAnonymous( bool anonymous ) { mAnonymous = anonymous; } void ComplexType::setName( const TQString &name ) { mName = name; } void ComplexType::setContentType( int contentType ) { mContentType = contentType; } void ComplexType::setContentModel( int model ) { mContentModel = model; if ( mContentModel == MIXED ) { mMixed = true; qDebug( "Mixed content not supported" ); } else mMixed = false; } void ComplexType::addAttribute( const TQString &name, int type_id, bool qualified, const TQString &defaultValue, const TQString &fixedValue, bool use ) { if ( type_id == 0 ) { qDebug( "ComplexType:addAttribute(): No type given for attribute" ); return; } Attribute attribute( name, type_id, qualified, defaultValue, fixedValue, use ); Attribute *attributePtr = (Attribute*)this->attribute( name ); if ( attributePtr ) *attributePtr = attribute; else mAttributes.append( attribute ); } void ComplexType::addAttributeRef( const QualifiedName &name, bool qualified, bool use ) { addAttribute( name.localName(), XSDType::ANYTYPE, qualified, TQString(), TQString(), use ); mForwardAttributeRef = true; } void ComplexType::addElement( const TQString &name, int type_id, int minOccurs, int maxOccurs, bool qualified, const TQString &defaultValue, const TQString &fixedValue, const TQString &documentation ) { if ( type_id == 0 ) { qDebug( "ComplexType:addElement() :No type given for element " ); return; } if ( mTopLevelGroup == ALL && maxOccurs > 1 && mIsArray == false ) { qDebug( "Inside an group elements can occur only once" ); return; } Element element( name, type_id, minOccurs, maxOccurs, qualified, defaultValue, fixedValue ); element.setGroupId( mCurrentGroup ); element.setDocumentation( documentation ); Element *elementPtr = (Element*)this->element( name ); if ( elementPtr ) *elementPtr = element; else mElements.append( element ); } void ComplexType::addElementRef( const QualifiedName &name, int minOccurs, int maxOccurs ) { addElement( name.localName(), XSDType::ANYTYPE, minOccurs, maxOccurs ); mForwardElementRef = true; } void ComplexType::matchElementRef( const TQString &name, Element &element ) { if ( mForwardElementRef ) { Element *elementPtr = (Element*)this->element( name ); if ( elementPtr ) { // these values are specific to the occurrence of the element inside another XML type // so we shouldnt delete them int min = elementPtr->minOccurs(); int max = elementPtr->maxOccurs(); int gId = elementPtr->groupId(); *elementPtr = element; elementPtr->setMinOccurs( min ); elementPtr->setMaxOccurs( max ); elementPtr->setGroupId( gId ); } } } void ComplexType::matchAttributeRef( const TQString &name, Attribute &attribute ) { if ( mForwardAttributeRef ) { Attribute *attributePtr = (Attribute*)this->attribute( name ); if ( attributePtr ) *attributePtr = attribute; } } void ComplexType::setCompositor( Compositor type, bool open, int minOccurs, int maxOccurs ) { if ( open ) { mPreviousGroup = mCurrentGroup++; if ( mPreviousGroup == 0 ) mTopLevelGroup = type; else if ( mTopLevelGroup == this->ALL ) { qDebug( "This cannot occur inside a top level compositor" ); return; } if ( type == this->ALL && mPreviousGroup != 0 ) { qDebug( " can occur only at the top level" ); return; } if ( type == this->ALL && (minOccurs != 1 || maxOccurs != 1) ) { qDebug( " can have min/max of only 1 " ); return; } mGroups.append( CompositorStruct( type, minOccurs, maxOccurs ) ); } else mCurrentGroup = mPreviousGroup; } bool ComplexType::checkOccurrences() { Element::List::ConstIterator it; for ( it = mElements.begin(); it != mElements.end(); ++it ) if ( (*it).occurrence() < (*it).minOccurs() ) return false; return true; } void ComplexType::resetCounters() { Element::List::Iterator it; for ( it = mElements.begin(); it != mElements.end(); ++it ) (*it).setOccurrence( 0 ); }