diff options
Diffstat (limited to 'kode/kwsdl/schema')
-rw-r--r-- | kode/kwsdl/schema/Makefile.am | 15 | ||||
-rw-r--r-- | kode/kwsdl/schema/attribute.cpp | 80 | ||||
-rw-r--r-- | kode/kwsdl/schema/attribute.h | 68 | ||||
-rw-r--r-- | kode/kwsdl/schema/complextype.cpp | 403 | ||||
-rw-r--r-- | kode/kwsdl/schema/complextype.h | 181 | ||||
-rw-r--r-- | kode/kwsdl/schema/element.cpp | 130 | ||||
-rw-r--r-- | kode/kwsdl/schema/element.h | 89 | ||||
-rw-r--r-- | kode/kwsdl/schema/fileprovider.cpp | 105 | ||||
-rw-r--r-- | kode/kwsdl/schema/fileprovider.h | 55 | ||||
-rw-r--r-- | kode/kwsdl/schema/parser.cpp | 1095 | ||||
-rw-r--r-- | kode/kwsdl/schema/parser.h | 139 | ||||
-rw-r--r-- | kode/kwsdl/schema/qualifiedname.cpp | 78 | ||||
-rw-r--r-- | kode/kwsdl/schema/qualifiedname.h | 59 | ||||
-rw-r--r-- | kode/kwsdl/schema/simpletype.cpp | 301 | ||||
-rw-r--r-- | kode/kwsdl/schema/simpletype.h | 163 | ||||
-rw-r--r-- | kode/kwsdl/schema/types.cpp | 54 | ||||
-rw-r--r-- | kode/kwsdl/schema/types.h | 51 | ||||
-rw-r--r-- | kode/kwsdl/schema/typestable.cpp | 251 | ||||
-rw-r--r-- | kode/kwsdl/schema/typestable.h | 89 | ||||
-rw-r--r-- | kode/kwsdl/schema/xsdtype.h | 114 |
20 files changed, 3520 insertions, 0 deletions
diff --git a/kode/kwsdl/schema/Makefile.am b/kode/kwsdl/schema/Makefile.am new file mode 100644 index 000000000..9b98340f4 --- /dev/null +++ b/kode/kwsdl/schema/Makefile.am @@ -0,0 +1,15 @@ +INCLUDES = -I$(top_srcdir) -I.. -I$(top_srcdir)/libkdepim $(all_includes) + +lib_LTLIBRARIES = libschema.la + +libschema_la_SOURCES = attribute.cpp complextype.cpp element.cpp fileprovider.cpp \ + parser.cpp qualifiedname.cpp simpletype.cpp types.cpp typestable.cpp +libschema_la_LDFLAGS = $(all_libraries) -version-info 1:0:0 -no-undefined +libschema_la_LIBADD = -lqt-mt -lkdecore -lkio + +#bin_PROGRAMS = schematest +#schematest_LDFLAGS = $(all_libraries) $(KDE_RPATH) +#schematest_SOURCES = main.cpp +#schematest_LDADD = libschema.la + +METASOURCES = AUTO diff --git a/kode/kwsdl/schema/attribute.cpp b/kode/kwsdl/schema/attribute.cpp new file mode 100644 index 000000000..9be9be790 --- /dev/null +++ b/kode/kwsdl/schema/attribute.cpp @@ -0,0 +1,80 @@ +/* + This file is part of KDE Schema Parser + + Copyright (c) 2005 Tobias Koenig <tokoe@kde.org> + 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 "attribute.h" + +using namespace Schema; + + +Attribute::Attribute( const QString &name, int type, bool qualified, + const QString &defaultValue, const QString &fixedValue, + bool use ) + : mName( name ), mType( type ), mQualified( qualified ), + mDefaultValue( defaultValue ), mFixedValue( fixedValue ), + mUse( use ) +{ +} + +Attribute::Attribute() + : mType( 0 ), mQualified( false ), mUse( false ) +{ +} + +QString Attribute::name() const +{ + return mName; +} + +int Attribute::type() const +{ + return mType; +} + +void Attribute::setTypeName( const QString &typeName ) +{ + mTypeName = typeName; +} + +QString Attribute::typeName() const +{ + return mTypeName; +} + +QString Attribute::defaultValue() const +{ + return mDefaultValue; +} + +QString Attribute::fixedValue() const +{ + return mFixedValue; +} + +bool Attribute::isQualified() const +{ + return mQualified; +} + +bool Attribute::isUsed() const +{ + return mUse; +} diff --git a/kode/kwsdl/schema/attribute.h b/kode/kwsdl/schema/attribute.h new file mode 100644 index 000000000..62db99d7d --- /dev/null +++ b/kode/kwsdl/schema/attribute.h @@ -0,0 +1,68 @@ +/* + This file is part of KDE Schema Parser + + Copyright (c) 2005 Tobias Koenig <tokoe@kde.org> + 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. + */ + +#ifndef SCHEMA_ATTRIBUTE_H +#define SCHEMA_ATTRIBUTE_H + +#include <qstring.h> +#include <qvaluelist.h> + +namespace Schema { + +class Attribute +{ + public: + typedef QValueList<Attribute> List; + typedef QValueList<Attribute*> PtrList; + + Attribute(); + + Attribute( const QString &name, int type, bool qualified = false, + const QString &defaultValue = QString(), + const QString &fixedValue = QString(), + bool use = true ); + + QString name() const; + int type() const; + + void setTypeName( const QString &typeName ); + QString typeName() const; + + QString defaultValue() const; + QString fixedValue() const; + + bool isQualified() const; + bool isUsed() const; + + private: + QString mName; + int mType; + QString mTypeName; + bool mQualified; + QString mDefaultValue; + QString mFixedValue; + bool mUse; +}; + +} + +#endif diff --git a/kode/kwsdl/schema/complextype.cpp b/kode/kwsdl/schema/complextype.cpp new file mode 100644 index 000000000..418fdf92f --- /dev/null +++ b/kode/kwsdl/schema/complextype.cpp @@ -0,0 +1,403 @@ +/* + This file is part of KDE Schema Parser + + Copyright (c) 2005 Tobias Koenig <tokoe@kde.org> + 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 QString &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() +{ +} + +QString ComplexType::name() const +{ + return mName; +} + +QualifiedName ComplexType::qualifiedName() const +{ + QualifiedName qn( mName ); + qn.setNameSpace( mNameSpace ); + return qn; +} + +void ComplexType::setDocumentation( const QString &documentation ) +{ + mDocumentation = documentation; +} + +QString 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(); +} + +QString ComplexType::attributeName( int index ) +{ + return attribute( index )->name(); +} + +int ComplexType::elementType( int index ) +{ + return element( index )->type(); +} + +QString 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 QString &baseTypeName ) +{ + mBaseType.name = baseTypeName; +} + +QString 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 QString &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 QString &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 QString &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 QString &name, int type_id, bool qualified, + const QString &defaultValue, const QString &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, QString(), QString(), use ); + mForwardAttributeRef = true; +} + + +void ComplexType::addElement( const QString &name, int type_id, int minOccurs, + int maxOccurs, bool qualified, + const QString &defaultValue, const QString &fixedValue, + const QString &documentation ) +{ + if ( type_id == 0 ) { + qDebug( "ComplexType:addElement() :No type given for element " ); + return; + } + + if ( mTopLevelGroup == ALL && maxOccurs > 1 && mIsArray == false ) { + qDebug( "Inside an <all> 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 QString &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 QString &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 <all> compositor" ); + return; + } + + if ( type == this->ALL && mPreviousGroup != 0 ) { + qDebug( "<all> can occur only at the top level" ); + return; + } + + if ( type == this->ALL && (minOccurs != 1 || maxOccurs != 1) ) { + qDebug( "<all> 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 ); +} diff --git a/kode/kwsdl/schema/complextype.h b/kode/kwsdl/schema/complextype.h new file mode 100644 index 000000000..8664e007a --- /dev/null +++ b/kode/kwsdl/schema/complextype.h @@ -0,0 +1,181 @@ +/* + This file is part of KDE Schema Parser + + Copyright (c) 2005 Tobias Koenig <tokoe@kde.org> + 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. + */ + +#ifndef SCHEMA_COMPLEXTYPE_H +#define SCHEMA_COMPLEXTYPE_H + +#include <qstring.h> + +#include "attribute.h" +#include "element.h" +#include "qualifiedname.h" +#include "xsdtype.h" + +namespace Schema { + +class ComplexType : public XSDType +{ + public: + typedef QValueList<ComplexType> List; + + typedef enum { + SEQ = 0, + CHOICE, + ALL + } Compositor; + + typedef enum { + Restriction, + Extension + } Derivation; + + ComplexType(); + ComplexType( const QString& ); + ~ComplexType(); + + void setName( const QString &name ); + QString name() const; + + QualifiedName qualifiedName() const; + + void setDocumentation( const QString &documentation ); + QString documentation() const; + + void setType( int type ); + int type() const; + + void setContentType( int contentType ); + int contentType() const; + + void setContentModel( int model ); + int contentModel() const; + + bool isSimple() const; + + int attributeType( int index ); + QString attributeName( int index ); + + int elementType( int index ); + QString elementName( int index ); + + int numElements() const; + int numAttributes() const; + + void setAnonymous( bool anonymous ); + bool isAnonymous() const; + + void setBaseType( int type, Derivation derivation, const XSDType *ptr ); + void setBaseTypeName( const QString &baseTypeName ); + + int baseType() const; + int baseDerivation() const; + QString baseTypeName() const; + + Compositor topLevelGroup() const; + Compositor groupType( int groupId ) const; + + const Element *element( const QString &name ); + const Attribute *attribute( const QString &name ); + Element *element( int id ); + Attribute *attribute( int id ); + + void setElements( const Element::List &elements ); + Element::List elements() const; + + void setAttributes( const Attribute::List &attributes ); + Attribute::List attributes() const; + + void setIsArray( bool isArray ); + bool isArray() const; + + void setCompositor( Compositor type, bool open = true, int minOccurs = 1, int maxOccurs = 1 ); + + void addAttribute( const QString &name, int type_id, bool qualified = false, + const QString &defaultValue = QString(), + const QString &fixedValue = QString(), + bool use = false ); + void addAttributeRef( const QualifiedName &name, bool qualified, bool use ); + + void addElement( const QString &name, int type_id, int minOccurs = 1, + int maxOccurs = 1, bool qualified = false, + const QString &defaultValue = QString(), + const QString &fixedValue = QString(), + const QString &documentation = QString() ); + void addElementRef( const QualifiedName &name, int minOccurs, int maxOccurs ); + + void matchAttributeRef( const QString &name, Attribute &attribute ); + void matchElementRef( const QString &name, Element &element ); + + bool checkOccurrences(); + void resetCounters(); + + private: + QString mName; + QString mNameSpace; + QString mDocumentation; + int mType; + + Element::List mElements; + Attribute::List mAttributes; + + int mContentModel; + bool mMixed; + bool mAnonymous; + bool mIsArray; + int mContentType; + + struct + { + int typeId; + Derivation derivation; + const XSDType *type; + QString name; + } mBaseType; + + struct CompositorStruct + { + CompositorStruct() + { + } + + CompositorStruct( Compositor _type, int min = 1, int max = 1 ) + : type( _type ), minOccurs( min ), maxOccurs( max ) + { + } + + Compositor type; + int minOccurs; + int maxOccurs; + }; + + QValueList<struct CompositorStruct> mGroups; + + Compositor mTopLevelGroup; + int mCurrentGroup; + int mPreviousGroup; + bool mForwardElementRef; + bool mForwardAttributeRef; +}; + +} + +#endif diff --git a/kode/kwsdl/schema/element.cpp b/kode/kwsdl/schema/element.cpp new file mode 100644 index 000000000..bfb745e2b --- /dev/null +++ b/kode/kwsdl/schema/element.cpp @@ -0,0 +1,130 @@ +/* + This file is part of KDE Schema Parser + + Copyright (c) 2005 Tobias Koenig <tokoe@kde.org> + 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 "element.h" + +using namespace Schema; + + +Element::Element() + : mType( 0 ), mMinOccurs( 1 ), mMaxOccurs( 1 ), mQualified( false ), + mOccurrence( 0 ) +{ +} + +Element::Element( const QString &name, int type, int minOccurs, int maxOccurs, + bool qualified, const QString &defaultValue, const QString &fixedValue ) + : mName( name ), mType( type ), mMinOccurs( minOccurs ), mMaxOccurs( maxOccurs ), + mQualified( qualified ), mDefaultValue( defaultValue ), mFixedValue( fixedValue ), + mOccurrence( 0 ) +{ +} + +QString Element::name() const +{ + return mName; +} + +void Element::setType( int type ) +{ + mType = type; +} + +int Element::type() const +{ + return mType; +} + +void Element::setTypeName( const QString &typeName ) +{ + mTypeName = typeName; +} + +QString Element::typeName() const +{ + return mTypeName; +} + +void Element::setDocumentation( const QString &documentation ) +{ + mDocumentation = documentation; +} + +QString Element::documentation() const +{ + return mDocumentation; +} + +void Element::setGroupId( int group ) +{ + mGroupId = group; +} + +int Element::groupId() const +{ + return mGroupId; +} + +void Element::setMinOccurs( int minOccurs ) +{ + mMinOccurs = minOccurs; +} + +int Element::minOccurs() const +{ + return mMinOccurs; +} + +void Element::setMaxOccurs( int maxOccurs ) +{ + mMaxOccurs = maxOccurs; +} + +int Element::maxOccurs() const +{ + return mMaxOccurs; +} + +QString Element::defaultValue() const +{ + return mDefaultValue; +} + +QString Element::fixedValue() const +{ + return mFixedValue; +} + +bool Element::isQualified() const +{ + return mQualified; +} + +void Element::setOccurrence( int occurrence ) +{ + mOccurrence = occurrence; +} + +int Element::occurrence() const +{ + return mOccurrence; +} diff --git a/kode/kwsdl/schema/element.h b/kode/kwsdl/schema/element.h new file mode 100644 index 000000000..6335693f6 --- /dev/null +++ b/kode/kwsdl/schema/element.h @@ -0,0 +1,89 @@ +/* + This file is part of KDE Schema Parser + + Copyright (c) 2005 Tobias Koenig <tokoe@kde.org> + 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. + */ + +#ifndef SCHEMA_ELEMENT_H +#define SCHEMA_ELEMENT_H + +#include <qstring.h> +#include <qvaluelist.h> + +#define UNBOUNDED 1000 + +namespace Schema { + +class Element +{ + public: + typedef QValueList<Element> List; + typedef QValueList<Element*> PtrList; + + Element(); + + Element( const QString &name, int type, int minOccurs = 1, int maxOccurs = 1, + bool qualified = false, const QString &defaultValue = QString(), + const QString &fixedValue = QString() ); + + QString name() const; + + void setType( int id ); + int type() const; + + void setTypeName( const QString &typeName ); + QString typeName() const; + + void setDocumentation( const QString &documentation ); + QString documentation() const; + + void setGroupId( int group ); + int groupId() const; + + void setMinOccurs( int minOccurs ); + int minOccurs() const; + + void setMaxOccurs( int maxOccurs ); + int maxOccurs() const; + + QString defaultValue() const; + QString fixedValue() const; + + bool isQualified() const; + + void setOccurrence( int occurrence ); + int occurrence() const; + + private: + QString mName; + int mType; + QString mTypeName; + QString mDocumentation; + int mMinOccurs; + int mMaxOccurs; + bool mQualified; + QString mDefaultValue; + QString mFixedValue; + int mGroupId; + int mOccurrence; +}; + +} + +#endif diff --git a/kode/kwsdl/schema/fileprovider.cpp b/kode/kwsdl/schema/fileprovider.cpp new file mode 100644 index 000000000..642592bf4 --- /dev/null +++ b/kode/kwsdl/schema/fileprovider.cpp @@ -0,0 +1,105 @@ +/* + This file is part of KDE Schema Parser + + Copyright (c) 2005 Tobias Koenig <tokoe@kde.org> + + 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 <unistd.h> + +#include <qapplication.h> +#include <qeventloop.h> +#include <qfile.h> + +#include <kio/job.h> +#include <ktempfile.h> + +#include "fileprovider.h" + +using namespace Schema; + +FileProvider::FileProvider() + : QObject( 0 ), mBlocked( false ) +{ +} + +bool FileProvider::get( const QString &url, QString &target ) +{ + if ( !mFileName.isEmpty() ) + cleanUp(); + + if ( target.isEmpty() ) { + KTempFile tmpFile; + target = tmpFile.name(); + mFileName = target; + } + + mData.truncate( 0 ); + + qDebug( "Downloading external schema '%s'", url.latin1() ); + + KIO::TransferJob* job = KIO::get( KURL( url ), false, false ); + connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ), + this, SLOT( slotData( KIO::Job*, const QByteArray& ) ) ); + connect( job, SIGNAL( result( KIO::Job* ) ), + this, SLOT( slotResult( KIO::Job* ) ) ); + + mBlocked = true; + while ( mBlocked ) { + qApp->eventLoop()->processEvents( QEventLoop::ExcludeUserInput ); + usleep( 500 ); + } + + return true; +} + +void FileProvider::cleanUp() +{ + ::unlink( QFile::encodeName( mFileName ) ); + mFileName = QString(); +} + +void FileProvider::slotData( KIO::Job*, const QByteArray &data ) +{ + unsigned int oldSize = mData.size(); + mData.resize( oldSize + data.size() ); + memcpy( mData.data() + oldSize, data.data(), data.size() ); +} + +void FileProvider::slotResult( KIO::Job *job ) +{ + if ( job->error() ) { + qDebug( "%s", job->errorText().latin1() ); + return; + } + + QFile file( mFileName ); + if ( !file.open( IO_WriteOnly ) ) { + qDebug( "Unable to create temporary file" ); + return; + } + + qDebug( "Download successful" ); + file.writeBlock( mData ); + file.close(); + + mData.truncate( 0 ); + + mBlocked = false; +} + +#include "fileprovider.moc" diff --git a/kode/kwsdl/schema/fileprovider.h b/kode/kwsdl/schema/fileprovider.h new file mode 100644 index 000000000..8b2903c50 --- /dev/null +++ b/kode/kwsdl/schema/fileprovider.h @@ -0,0 +1,55 @@ +/* + This file is part of KDE Schema Parser + + Copyright (c) 2005 Tobias Koenig <tokoe@kde.org> + + 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. + */ + +#ifndef SCHEMA_FILEPROVIDER_H +#define SCHEMA_FILEPROVIDER_H + +#include <qobject.h> + +namespace KIO { +class Job; +} + +namespace Schema { + +class FileProvider : QObject +{ + Q_OBJECT + + public: + FileProvider(); + + bool get( const QString &url, QString &target ); + void cleanUp(); + + private slots: + void slotData( KIO::Job*, const QByteArray& ); + void slotResult( KIO::Job* ); + + private: + QString mFileName; + QByteArray mData; + bool mBlocked; +}; + +} + +#endif diff --git a/kode/kwsdl/schema/parser.cpp b/kode/kwsdl/schema/parser.cpp new file mode 100644 index 000000000..ec0daabe4 --- /dev/null +++ b/kode/kwsdl/schema/parser.cpp @@ -0,0 +1,1095 @@ +/* + This file is part of KDE Schema Parser + + Copyright (c) 2005 Tobias Koenig <tokoe@kde.org> + 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 <qdir.h> +#include <qfile.h> +#include <qurl.h> + +#include "fileprovider.h" +#include "parser.h" + +using namespace Schema; + +const QString soapEncUri = "http://schemas.xmlsoap.org/soap/encoding/"; +const QString wsdlUri = "http://schemas.xmlsoap.org/wsdl/"; + + +Parser::Parser( const QString &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<const SimpleType*>( 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<const ComplexType*>( 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 QString &url ) +{ + mSchemaBaseUrl = url; +} + +void Parser::parseNameSpace( const QDomElement &element ) +{ + QDomNamedNodeMap attributes = element.attributes(); + for ( uint i = 0; i < attributes.count(); ++i ) { + QDomNode node = attributes.item( i ); + QDomAttr attribute = node.toAttr(); + + if ( attribute.name().startsWith( "xmlns:" ) ) + mNameSpaceMap.insert( attribute.value(), attribute.name().mid( 6 ) ); + } +} + +bool Parser::parseSchemaTag( const QDomElement &root ) +{ + QualifiedName name = root.tagName(); + if ( name.localName() != "schema" ) + return false; + + if ( root.hasAttribute( "targetNamespace" ) ) + mNameSpace = root.attribute( "targetNamespace" ); + + if ( root.hasAttribute( "elementFormDefault" ) ) { + const QString 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); +*/ + + QDomNode node = root.firstChild(); + while ( !node.isNull() ) { + QDomElement 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 QDomElement &element ) +{ + QString 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 QDomElement& ) +{ +} + +void Parser::parseAnnotation( const QDomElement &element, QString &documentation ) +{ + QDomNode node = element.firstChild(); + while ( !node.isNull() ) { + QDomElement 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 QDomElement &element, ComplexType *complexType ) +{ + QDomNode node = element.firstChild(); + while ( !node.isNull() ) { + QDomElement 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 QDomElement &element, SimpleType *simpleType ) +{ + QDomNode node = element.firstChild(); + while ( !node.isNull() ) { + QDomElement 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 QDomElement &element ) +{ + ComplexType *newType = new ComplexType( mNameSpace ); + + newType->setName( element.attribute( "name" ) ); + if ( element.hasAttribute( "mixed" ) ) + newType->setContentModel( newType->MIXED ); + + QDomNode node = element.firstChild(); + while ( !node.isNull() ) { + QDomElement 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 QDomElement &element, ComplexType * ct ) +{ + int min, max; + QString tmp; + + min = element.attribute( "minOccurs", "1" ).toInt(); + max = element.attribute( "maxOccurs", "1" ).toInt(); + ct->setCompositor( ct->ALL, true, min, max ); + + QDomNode node = element.firstChild(); + while ( !node.isNull() ) { + QDomElement 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 QDomElement &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(); + QString 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 ); + + QDomNode node = element.firstChild(); + while ( !node.isNull() ) { + QDomElement 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 QDomElement &element, ComplexType *cType ) +{ + QString 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(); + QString 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; + + QDomNode node = element.firstChild(); + while ( !node.isNull() ) { + QDomElement 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 <any> then we dont need a type for it. + // make the parent'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 QDomElement &element, ComplexType *cType ) +{ + QString ns, any( "any" ); + int type_id = XSDType::ANY, min = 1, max = 1; + + ns = element.attribute( "namespace" ); + min = element.attribute( "minOccurs", "1" ).toInt(); + QString 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 QDomElement &element, ComplexType *cType ) +{ + QString ns, anyAttribute( "anyAttribute" ); + + ns = element.attribute( "namespace" ); + + cType->addAttribute( anyAttribute, XSDType::ANY, false, ns ); +} + +void Parser::addAttribute( const QDomElement &element, ComplexType *cType ) +{ + QString 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; + } + + QDomNode node = element.firstChild(); + while ( !node.isNull() ) { + QDomElement 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 QDomElement &element ) +{ + SimpleType *st = new SimpleType( mNameSpace ); + + int basetype_id = XSDType::INVALID; + + st->setName( element.attribute( "name" ) ); + + QDomNode node = element.firstChild(); + while ( !node.isNull() ) { + QDomElement 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 QDomElement &element, SimpleType *st ) +{ + if ( st->baseType() == 0 ) + qDebug( "<restriction>:unkown BaseType" ); + + QDomNode node = element.firstChild(); + while ( !node.isNull() ) { + QDomElement childElement = node.toElement(); + if ( !childElement.isNull() ) { + + if ( !st->isValidFacet( childElement.tagName() ) ) { + qDebug( "<restriction>: %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 QDomElement &element, ComplexType *ct ) +{ + QualifiedName typeName; + + if ( element.attribute( "mixed" ) == "true" ) { + qDebug( "<complexContent>: No support for mixed=true" ); + return; + } + + ct->setContentModel( ct->COMPLEX ); + + QDomNode node = element.firstChild(); + while ( !node.isNull() ) { + QDomElement 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" ) { + QDomElement 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 { + QDomNode childNode = childElement.firstChild(); + while ( !childNode.isNull() ) { + QDomElement 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 QDomElement &element, ComplexType *ct ) +{ + ct->setContentModel( ct->SIMPLE ); + + const QDomElement 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 ) ); + + QDomNode childNode = childElement.firstChild(); + while ( !childNode.isNull() ) { + QDomElement 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 QDomElement &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 QDomElement &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 QString &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 ); + + QString 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 ); + } +} + +QString 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; + + QValueList<ForwardDerivation>::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 ); + + QString 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 ); + + QString 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 ); + + QString 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; +} + +QString 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 QString &location ) +{ + FileProvider provider; + QString fileName; + QString schemaLocation( location ); + + QUrl url( location ); + QDir dir( location ); + + if ( (url.protocol().isEmpty() || url.protocol() == "file") && dir.isRelative() ) + schemaLocation = mSchemaBaseUrl + "/" + location; + + if ( provider.get( schemaLocation, fileName ) ) { + QFile file( fileName ); + if ( !file.open( IO_ReadOnly ) ) { + qDebug( "Unable to open file %s", file.name().latin1() ); + return; + } + + QDomDocument doc( "kwsdl" ); + QString 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; + } + + QDomNodeList nodes = doc.elementsByTagName( "schema" ); + if ( nodes.count() > 0 ) { + QDomElement schemaElement = nodes.item( 0 ).toElement(); + parseSchemaTag( schemaElement ); + } else { + qDebug( "No schema tag found in schema file" ); + } + + file.close(); + + provider.cleanUp(); + } +} diff --git a/kode/kwsdl/schema/parser.h b/kode/kwsdl/schema/parser.h new file mode 100644 index 000000000..afaf3dae6 --- /dev/null +++ b/kode/kwsdl/schema/parser.h @@ -0,0 +1,139 @@ +/* + This file is part of KDE Schema Parser + + Copyright (c) 2005 Tobias Koenig <tokoe@kde.org> + 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. + */ + +#ifndef SCHEMA_PARSER_H +#define SCHEMA_PARSER_H + +#include <qdom.h> +#include <qvaluelist.h> + +#include "types.h" +#include "typestable.h" + +namespace Schema { + +class Parser +{ + public: + Parser( const QString &nameSpace = QString() ); + + ~Parser(); + + Types types() const; + + void clear(); + void setSchemaBaseUrl( const QString& ); + + void parseNameSpace( const QDomElement &element ); + bool parseSchemaTag( const QDomElement &element ); + + const XSDType *type( const QualifiedName &type ); + const XSDType *type( int id ) const; + int numTypes() const; + + QString typeName( int id ) const; + + Element *element( const QualifiedName &element ) const; + Element *element( int id ) const; + Element::PtrList elements() const; + int numElements() const; + + Attribute *attribute( const QualifiedName &attribute ) const; + Attribute *attribute( int id ) const; + int numAttributes() const; + + QString targetNamespace() const; + + int typeId( const QualifiedName &name, bool create = false ); + + bool isBasicType( int sType ) const; + + bool finalize(); + + int elementId( const QualifiedName &type ); + int elementType( const QualifiedName &type ); + int attributeId( const QualifiedName &type ) const; + int attributeType( const QualifiedName &type ); + + private: + void parseImport( const QDomElement& ); + void parseElement( const QDomElement& ); + void parseAttribute( const QDomElement& ); + + void parseAnnotation( const QDomElement& ); + void parseAnnotation( const QDomElement&, QString& ); + void parseAnnotation( const QDomElement&, ComplexType* ); + void parseAnnotation( const QDomElement&, SimpleType* ); + XSDType *parseComplexType( const QDomElement& ); + + void all( const QDomElement&, ComplexType* ); + void cs( const QDomElement&, ComplexType* ); + + void addElement( const QDomElement&, ComplexType* ); + + void addAttribute( const QDomElement&, ComplexType* ); + void addAny( const QDomElement&, ComplexType* ); + void addAnyAttribute( const QDomElement&, ComplexType* ); + int addExternalElement( const QString&, int ); + + XSDType *parseSimpleType( const QDomElement& ); + void parseRestriction( const QDomElement&, SimpleType* ); + void parseComplexContent( const QDomElement&, ComplexType* ); + void parseSimpleContent( const QDomElement&, ComplexType* ); + + + void resolveForwardElementRefs(); + void resolveForwardAttributeRefs(); + void resolveForwardDerivations(); + bool shouldResolve(); + + void importSchema( const QString &location ); + + bool mElementQualified; + bool mAttributeQualified; + QMap<QString, QString> mNameSpaceMap; + QString mNameSpace; + QString mPrefix; + + TypesTable mTypesTable; + Element::PtrList mElements; + Attribute::PtrList mAttributes; + + QualifiedName::List mForwardElementRef; + QualifiedName::List mForwardAttributeRef; + + typedef struct { + QualifiedName type; + QualifiedName baseType; + ComplexType::Derivation derivation; + } ForwardDerivation; + + QValueList<ForwardDerivation> mForwardDerivations; + QStringList mImportedSchemas; + QString mSchemaBaseUrl; +}; + +} + +#endif + + diff --git a/kode/kwsdl/schema/qualifiedname.cpp b/kode/kwsdl/schema/qualifiedname.cpp new file mode 100644 index 000000000..5b19f1669 --- /dev/null +++ b/kode/kwsdl/schema/qualifiedname.cpp @@ -0,0 +1,78 @@ +/* + This file is part of KDE Schema Parser + + Copyright (c) 2005 Tobias Koenig <tokoe@kde.org> + 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 "qualifiedname.h" + +using namespace Schema; + +QualifiedName::QualifiedName( const QString &name ) +{ + parse( name ); +} + +QualifiedName::QualifiedName() +{ +} + +void QualifiedName::operator=( const QString &name ) +{ + parse( name ); +} + +QString QualifiedName::localName() const +{ + return mLocalName; +} + +QString QualifiedName::prefix() const +{ + return mPrefix; +} + +void QualifiedName::setNameSpace( const QString &nameSpace ) +{ + mNameSpace = nameSpace; +} + +QString QualifiedName::nameSpace() const +{ + return mNameSpace; +} + +bool QualifiedName::operator==( const QualifiedName &qn ) const +{ + return (qn.nameSpace() == mNameSpace && qn.localName() == mLocalName ); +} + +void QualifiedName::parse( const QString &str ) +{ + int pos = str.find( ':' ); + if ( pos != -1 ) { + mPrefix = str.left( pos ); + mLocalName = str.mid( pos + 1 ); + } else + mLocalName = str; + + if ( mLocalName.endsWith( "[]" ) ) + mLocalName.truncate( mLocalName.length() - 2 ); +} + diff --git a/kode/kwsdl/schema/qualifiedname.h b/kode/kwsdl/schema/qualifiedname.h new file mode 100644 index 000000000..5b2f59bcd --- /dev/null +++ b/kode/kwsdl/schema/qualifiedname.h @@ -0,0 +1,59 @@ +/* + This file is part of KDE Schema Parser + + Copyright (c) 2005 Tobias Koenig <tokoe@kde.org> + 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. + */ + +#ifndef SCHEMA_QUALIFIEDNAME_H +#define SCHEMA_QUALIFIEDNAME_H + +#include <qstring.h> +#include <qvaluelist.h> + +namespace Schema { + +class QualifiedName +{ + public: + typedef QValueList<QualifiedName> List; + + QualifiedName(); + QualifiedName( const QString &name ); + + void operator=( const QString &name ); + + QString localName() const; + QString prefix() const; + + void setNameSpace( const QString &nameSpace ); + QString nameSpace() const; + + bool operator==( const QualifiedName& ) const; + + private: + void parse( const QString& ); + + QString mNameSpace; + QString mLocalName; + QString mPrefix; +}; + +} + +#endif diff --git a/kode/kwsdl/schema/simpletype.cpp b/kode/kwsdl/schema/simpletype.cpp new file mode 100644 index 000000000..6943563f4 --- /dev/null +++ b/kode/kwsdl/schema/simpletype.cpp @@ -0,0 +1,301 @@ +/* + This file is part of KDE Schema Parser + + Copyright (c) 2005 Tobias Koenig <tokoe@kde.org> + 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 "simpletype.h" + +using namespace Schema; + +SimpleType::SimpleType() + : mBaseType( 0 ), mContentModel( SIMPLE ), + mRestriction( false ), mFacetId( NONE ), mAnonymous( false ), + mSubType( TypeRestriction ), mListType( INVALID ) +{ +} + +SimpleType::SimpleType( const QString &nameSpace ) + : mNameSpace( nameSpace ), mBaseType( 0 ), mContentModel( SIMPLE ), + mRestriction( false ), mFacetId( NONE ), mAnonymous( false ), + mSubType( TypeRestriction ), mListType( INVALID ) +{ +} + +SimpleType::~SimpleType() +{ +} + +void SimpleType::setName( const QString &name ) +{ + mName = name; +} + +QString SimpleType::name() const +{ + return mName; +} + +QualifiedName SimpleType::qualifiedName() const +{ + QualifiedName qn( mName ); + qn.setNameSpace( mNameSpace ); + return qn; +} + +void SimpleType::setDocumentation( const QString &documentation ) +{ + mDocumentation = documentation; +} + +QString SimpleType::documentation() const +{ + return mDocumentation; +} + +void SimpleType::setType( int type ) +{ + mType = type; +} + +int SimpleType::type() const +{ + return mType; +} + +void SimpleType::setBaseType( int baseType ) +{ + mBaseType = baseType; + mRestriction = true; +} + +int SimpleType::baseType() const +{ + return mBaseType; +} + +void SimpleType::setBaseTypeName( const QString &baseTypeName ) +{ + mBaseTypeName = baseTypeName; +} + +QString SimpleType::baseTypeName() const +{ + return mBaseTypeName; +} + +void SimpleType::setSubType( SubType subType ) +{ + mSubType = subType; +} + +SimpleType::SubType SimpleType::subType() const +{ + return mSubType; +} + +void SimpleType::setListType( int listType ) +{ + mListType = listType; +} + +int SimpleType::listType() const +{ + return mListType; +} + +void SimpleType::setListTypeName( const QString &name ) +{ + mListTypeName = name; +} + +QString SimpleType::listTypeName() const +{ + return mListTypeName; +} + +void SimpleType::setContentModel( int contentModel ) +{ + mContentModel = contentModel; +} + +int SimpleType::contentModel() const +{ + return mContentModel; +} + +void SimpleType::setAnonymous( bool anonymous ) +{ + mAnonymous = anonymous; +} + +bool SimpleType::isAnonymous() const +{ + return mAnonymous; +} + +bool SimpleType::isValidFacet( const QString &facet ) +{ + if ( mBaseType == 0 ) { + qDebug( "isValidFacet:Unknown base type" ); + return false; + } + + if ( facet == "length" ) + mFacetId |= LENGTH; + else if ( facet == "minLength" ) + mFacetId |= MINLEN; + else if ( facet == "maxLength" ) + mFacetId |= MAXLEN; + else if ( facet == "enumeration" ) + mFacetId |= ENUM; + else if ( facet == "whiteSpace" ) + mFacetId |= WSP; + else if ( facet == "pattern" ) + mFacetId |= PATTERN; + else if ( facet == "maxInclusive" ) + mFacetId |= MAXINC; + else if ( facet == "maxExclusive" ) + mFacetId |= MAXEX; + else if ( facet == "minInclusive" ) + mFacetId |= MININC; + else if ( facet == "minExclusive" ) + mFacetId |= MINEX; + else if ( facet == "totalDigits" ) + mFacetId |= TOT; + else if ( facet == "fractionDigits" ) + mFacetId |= FRAC; + else { + mFacetId = NONE; + return false; + } + + return true; +} + +void SimpleType::setFacetValue( const QString &value ) +{ + int number = -1; + + if ( mFacetId & ENUM ) { + mEnums.append( value ); + } else if ( mFacetId & PATTERN ) { + mFacetValue.pattern = value; + } else if ( mFacetId & WSP ) { + if ( value == "preserve" ) + mFacetValue.wsp = PRESERVE; + else if ( value == "collapse" ) + mFacetValue.wsp = COLLAPSE; + else if ( value == "replace" ) + mFacetValue.wsp = REPLACE; + else { + qDebug( "Invalid facet value for whitespace" ); + return; + } + } else { + number = value.toInt(); + } + + if ( mFacetId & MAXEX ) { + mFacetValue.valRange.maxex = number; + } else if ( mFacetId & MAXINC ) { + mFacetValue.valRange.maxinc = number; + } else if ( mFacetId & MININC ) { + mFacetValue.valRange.mininc = number; + } else if ( mFacetId & MINEX ) { + mFacetValue.valRange.minex = number; + } else if ( mFacetId & MAXEX ) { + mFacetValue.valRange.maxex = number; + } else if ( mFacetId & LENGTH ) { + mFacetValue.length = number; + } else if ( mFacetId & MINLEN ) { + mFacetValue.lenRange.minlen = number; + } else if ( mFacetId & MAXLEN ) { + mFacetValue.lenRange.maxlen = number; + } else if ( mFacetId & TOT ) { + mFacetValue.tot = number; + } else if ( mFacetId & FRAC ) { + mFacetValue.frac = number; + } +} + +int SimpleType::facetType() const +{ + return mFacetId; +} + +int SimpleType::facetLength() const +{ + return mFacetValue.length; +} + +int SimpleType::facetMinimumLength() const +{ + return mFacetValue.lenRange.minlen; +} + +int SimpleType::facetMaximumLength() const +{ + return mFacetValue.lenRange.maxlen; +} + +QStringList SimpleType::facetEnums() const +{ + return mEnums; +} + +SimpleType::WhiteSpaceType SimpleType::facetWhiteSpace() const +{ + return mFacetValue.wsp; +} + +int SimpleType::facetMinimumInclusive() const +{ + return mFacetValue.valRange.mininc; +} + +int SimpleType::facetMaximumInclusive() const +{ + return mFacetValue.valRange.maxinc; +} + +int SimpleType::facetMinimumExclusive() const +{ + return mFacetValue.valRange.minex; +} + +int SimpleType::facetMaximumExclusive() const +{ + return mFacetValue.valRange.maxex; +} + +int SimpleType::facetTotalDigits() const +{ + return mFacetValue.tot; +} + +int SimpleType::facetFractionDigits() const +{ + return mFacetValue.frac; +} + +QString SimpleType::facetPattern() const +{ + return mFacetValue.pattern; +} diff --git a/kode/kwsdl/schema/simpletype.h b/kode/kwsdl/schema/simpletype.h new file mode 100644 index 000000000..12d129a48 --- /dev/null +++ b/kode/kwsdl/schema/simpletype.h @@ -0,0 +1,163 @@ +/* + This file is part of KDE Schema Parser + + Copyright (c) 2005 Tobias Koenig <tokoe@kde.org> + 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. + */ + +#ifndef SCHEMA_SIMPLETYPE_H +#define SCHEMA_SIMPLETYPE_H + +#include <qstringlist.h> + +#include "qualifiedname.h" +#include "xsdtype.h" + +namespace Schema { + +class SimpleType : public XSDType +{ + public: + typedef QValueList<SimpleType> List; + + enum FacetType + { + NONE = 0, + LENGTH = 1, + MINLEN = 2, + MAXLEN = 4, + ENUM = 8, + WSP = 16, + MAXINC = 32, + MININC = 64, + MAXEX = 128, + MINEX = 256, + TOT = 512, + FRAC = 1024, + PATTERN = 2048 + }; + + enum WhiteSpaceType + { + PRESERVE, + REPLACE, + COLLAPSE + }; + + enum SubType + { + TypeRestriction, + TypeList, + TypeUnion + }; + + SimpleType(); + SimpleType( const QString &nameSpace ); + ~SimpleType(); + + void setName( const QString &name ); + QString name() const; + + QualifiedName qualifiedName() const; + + void setDocumentation( const QString &documentation ); + QString documentation() const; + + void setType( int type ); + int type() const; + + void setBaseType( int baseType ); + int baseType() const; + + void setBaseTypeName( const QString &baseTypeName ); + QString baseTypeName() const; + + void setSubType( SubType subType ); + SubType subType() const; + + void setListType( int listType ); + void setListTypeName( const QString &name ); + + int listType() const; + QString listTypeName() const; + + void setContentModel( int contentModel ); + int contentModel() const; + + void setAnonymous( bool anonymous ); + bool isAnonymous() const; + + bool isValidFacet( const QString &facet ); + void setFacetValue( const QString &value ); + + int facetType() const; + + int facetLength() const; + int facetMinimumLength() const; + int facetMaximumLength() const; + QStringList facetEnums() const; + WhiteSpaceType facetWhiteSpace() const; + int facetMinimumInclusive() const; + int facetMaximumInclusive() const; + int facetMinimumExclusive() const; + int facetMaximumExclusive() const; + int facetTotalDigits() const; + int facetFractionDigits() const; + QString facetPattern() const; + + private: + QString mName; + QString mNameSpace; + QString mDocumentation; + int mType; + int mBaseType; + QString mBaseTypeName; + int mContentModel; + bool mRestriction; + int mFacetId; + bool mAnonymous; + QStringList mEnums; + SubType mSubType; + + int mListType; + QString mListTypeName; + + typedef struct + { + int length; + struct + { + int minlen, maxlen; + } lenRange; + WhiteSpaceType wsp; + struct + { + int maxinc, mininc, maxex, minex; + } valRange; + int tot; + int frac; + QString pattern; + } FacetValueType; + + + FacetValueType mFacetValue; +}; + +} + +#endif diff --git a/kode/kwsdl/schema/types.cpp b/kode/kwsdl/schema/types.cpp new file mode 100644 index 000000000..dc750e450 --- /dev/null +++ b/kode/kwsdl/schema/types.cpp @@ -0,0 +1,54 @@ +/* + This file is part of KDE Schema Parser + + Copyright (c) 2005 Tobias Koenig <tokoe@kde.org> + + 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 "types.h" + +using namespace Schema; + +void Types::setSimpleTypes( const SimpleType::List &simpleTypes ) +{ + mSimpleTypes = simpleTypes; +} + +SimpleType::List Types::simpleTypes() const +{ + return mSimpleTypes; +} + +void Types::setComplexTypes( const ComplexType::List &complexTypes ) +{ + mComplexTypes = complexTypes; +} + +ComplexType::List Types::complexTypes() const +{ + return mComplexTypes; +} + +void Types::setElements( const Element::List &elements ) +{ + mElements = elements; +} + +Element::List Types::elements() const +{ + return mElements; +} diff --git a/kode/kwsdl/schema/types.h b/kode/kwsdl/schema/types.h new file mode 100644 index 000000000..97b3b5dc7 --- /dev/null +++ b/kode/kwsdl/schema/types.h @@ -0,0 +1,51 @@ +/* + This file is part of KDE Schema Parser + + Copyright (c) 2005 Tobias Koenig <tokoe@kde.org> + + 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. + */ + +#ifndef SCHEMA_TYPES_H +#define SCHEMA_TYPES_H + +#include "complextype.h" +#include "element.h" +#include "simpletype.h" + +namespace Schema { + +class Types +{ + public: + void setSimpleTypes( const SimpleType::List &simpleTypes ); + SimpleType::List simpleTypes() const; + + void setComplexTypes( const ComplexType::List &complexTypes ); + ComplexType::List complexTypes() const; + + void setElements( const Element::List &elements ); + Element::List elements() const; + + private: + SimpleType::List mSimpleTypes; + ComplexType::List mComplexTypes; + Element::List mElements; +}; + +} + +#endif diff --git a/kode/kwsdl/schema/typestable.cpp b/kode/kwsdl/schema/typestable.cpp new file mode 100644 index 000000000..8e0e66dd0 --- /dev/null +++ b/kode/kwsdl/schema/typestable.cpp @@ -0,0 +1,251 @@ +/* + This file is part of KDE Schema Parser + + Copyright (c) 2005 Tobias Koenig <tokoe@kde.org> + 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 "typestable.h" + +#include <kdebug.h> + +using namespace Schema; + +TypesTable::TypesTable() +{ + mCurrentId = XSDType::ANYURI + 1; + +//map of simple types + mBasicTypes["string"] = XSDType::STRING; + mBasicTypes["integer"] = XSDType::INTEGER; + mBasicTypes["int"] = XSDType::INT; + mBasicTypes["byte"] = XSDType::BYTE; + mBasicTypes["unsignedByte"] = XSDType::UBYTE; + mBasicTypes["positiveInteger"] = XSDType::POSINT; + mBasicTypes["unsignedInt"] = XSDType::UINT; + mBasicTypes["long"] = XSDType::LONG; + mBasicTypes["unsignedLong"] = XSDType::ULONG; + mBasicTypes["short"] = XSDType::SHORT; + mBasicTypes["unsignedShort"] = XSDType::USHORT; + mBasicTypes["decimal"] = XSDType::DECIMAL; + mBasicTypes["float"] = XSDType::FLOAT; + mBasicTypes["double"] = XSDType::DOUBLE; + mBasicTypes["boolean"] = XSDType::BOOLEAN; + mBasicTypes["time"] = XSDType::TIME; + mBasicTypes["dateTime"] = XSDType::DATETIME; + mBasicTypes["date"] = XSDType::DATE; + mBasicTypes["token"] = XSDType::TOKEN; + mBasicTypes["QName"] = XSDType::QNAME; + mBasicTypes["NCName"] = XSDType::NCNAME; + mBasicTypes["NMTOKEN"] = XSDType::NMTOKEN; + mBasicTypes["NMTOKENS"] = XSDType::NMTOKENS; + mBasicTypes["base64Binary"] = XSDType::BASE64BIN; + mBasicTypes["hexBinary"] = XSDType::HEXBIN; + mBasicTypes["anyType"] = XSDType::ANYTYPE; + mBasicTypes["any"] = XSDType::ANY; + mBasicTypes["anyURI"] = XSDType::ANYURI; +} + +TypesTable::~TypesTable() +{ + clear(); +} + +void TypesTable::clear() +{ + QMap<QString, int>::Iterator it; + for ( it = mUserTypes.begin(); it != mUserTypes.end(); ++it ) + delete typePtr( it.data() ); + + mUserTypes.clear(); + mTypes.clear(); +} + +int TypesTable::numExtRefs() const +{ + return mExternRefs.count(); +} + +QualifiedName TypesTable::extRefName( int index ) const +{ + return mExternRefs[ index ].qname; +} + +int TypesTable::extRefType( int index ) const +{ + return mExternRefs[ index ].localTypeId; +} + +int TypesTable::addType( XSDType *type ) +{ + QualifiedName qn = type->qualifiedName(); + QString type_name( qn.localName() ); + + int i = 0; + + if ( type_name.isEmpty() ) { + // create an anonymous type name + type_name.sprintf( "type%d", mTypes.count() ); + type->setName( type_name ); + type->setAnonymous( true ); //auto generated name + } + + // add the typename and its id to the map + if ( (i = mUserTypes[type_name]) != 0 ) { + // this type was refernced earlier. + mTypes[i - (XSDType::ANYURI + 1)] = type; + type->setType( i ); + return i; + } else { + mUserTypes[ type_name ] = mCurrentId; + type->setType( mCurrentId ); + mTypes.append( type ); + mCurrentId++; + return mCurrentId - 1; + } +} + +int TypesTable::typeId( const QualifiedName &name, bool create ) +{ + int typeId; + + if ( name.nameSpace() == SchemaUri ) { // this is one of the basic types + typeId = mBasicTypes[ name.localName() ]; + if ( typeId == 0 ) // if this is a basic type which is not mapped, treat as string + typeId = XSDType::STRING; + } else if ( name.nameSpace() == mNameSpace ) + typeId = mUserTypes[ name.localName() ]; + else { // the type does not belong to this schema + return 0; + } + + if ( typeId == 0 && create ) { + // handle forward reference + // create an id and return its value + mUserTypes[name.localName()] = mCurrentId; + mTypes.append( 0 ); + mCurrentId++; + typeId = mCurrentId - 1; + } + + return typeId; +} + +QString TypesTable::typeName( int id ) const +{ + if ( id < 0 ) + return QString(); + + QMap<QString, int>::ConstIterator it; + + if ( id >= 0 && id <= XSDType::ANYURI ) { + for ( it = mBasicTypes.begin(); it != mBasicTypes.end(); ++it ) + if ( id == it.data() ) + return it.key(); + } + + for ( it = mUserTypes.begin(); it != mUserTypes.end(); ++it ) + if ( id == it.data() ) + return it.key(); + + return "<unknown type>"; +} + +int TypesTable::addExternalTypeId( const QualifiedName &type, XSDType *pType ) +{ + for ( int i = 0; i < (int)mExternRefs.count(); i++ ) + if ( mExternRefs[i].qname == type ) + return mExternRefs[i].localTypeId; + + struct ExternRef ref; + ref.qname = (pType) ? pType->qualifiedName() : type; + ref.localTypeId = mCurrentId; + mExternRefs.append( ref ); + + mTypes.append( pType ); + mCurrentId++; + + return ref.localTypeId; +} + +// adds a type into a type table for a given type id +// used for types present in imported schemas but referenced in current schema +int TypesTable::addExtType( XSDType *type, int localId ) +{ + int index = localId - XSDType::ANYURI - 1; + if ( index >= (int)mTypes.count() ) + return 0; + + mTypes[ index ] = type; + return localId; +} + +bool TypesTable::detectUndefinedTypes() +{ + for ( int i = 0; i < (int)mTypes.count(); i++ ) + if ( mTypes[i] == 0 ) + return true; + + return false; +} + +void TypesTable::resolveForwardElementRefs( const QString &name, Element &element ) +{ + for ( int i = 0; i < (int)mTypes.count(); i++ ) + if ( mTypes[i] != 0 ) { + if ( !mTypes[i]->isSimple() ) { + ComplexType *ct = (ComplexType*)mTypes[i]; + ct->matchElementRef( name, element ); + } + } +} + +void TypesTable::resolveForwardAttributeRefs( const QString &name, Attribute &attribute ) +{ + for ( int i = 0; i < (int)mTypes.count(); i++ ) + if ( mTypes[i] != 0 ) { + if ( !mTypes[i]->isSimple() ) { + ComplexType *ct = (ComplexType*)mTypes[i]; + ct->matchAttributeRef( name, attribute ); + } + } +} + +XSDType *TypesTable::typePtr( int id ) const +{ + // this is a basic XSD type + if ( id < XSDType::ANYURI + 1 || id > XSDType::ANYURI + (int)mTypes.count() ) + return 0; + + return mTypes[ id - (SimpleType::ANYURI + 1) ]; +} + +int TypesTable::numTypes() const +{ + return mTypes.count(); +} + +void TypesTable::setTargetNamespace( const QString &nameSpace ) +{ + mNameSpace = nameSpace; +} + +QString TypesTable::targetNamespace() const +{ + return mNameSpace; +} diff --git a/kode/kwsdl/schema/typestable.h b/kode/kwsdl/schema/typestable.h new file mode 100644 index 000000000..6dfa378ed --- /dev/null +++ b/kode/kwsdl/schema/typestable.h @@ -0,0 +1,89 @@ +/* + This file is part of KDE Schema Parser + + Copyright (c) 2005 Tobias Koenig <tokoe@kde.org> + 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. + */ + +#ifndef SCHEMA_TYPESTABLE_H +#define SCHEMA_TYPESTABLE_H + +#include <qmap.h> +#include <qstring.h> + +#include "complextype.h" +#include "simpletype.h" + +namespace Schema { + +class TypesTable +{ + public: + TypesTable(); + ~TypesTable(); + + void clear(); + + int addType( XSDType *type ); + int addExtType( XSDType *type, int id ); + + int typeId( const QualifiedName &name, bool create = false ); + + QString typeName( int id ) const; + + int addExternalTypeId( const QualifiedName &type, XSDType *type ); + + int numExtRefs() const; + QualifiedName extRefName( int index ) const; + int extRefType( int index ) const; + + void resolveForwardElementRefs( const QString &name, Element &element ); + void resolveForwardAttributeRefs( const QString &name, Attribute &attribute ); + + XSDType *typePtr( int id ) const; + + int numTypes() const; + + bool detectUndefinedTypes(); + + void setTargetNamespace( const QString &nameSpace ); + QString targetNamespace() const; + + private: + QValueList<XSDType*> mTypes; + + //maintains a map of all user defined type names and their ids + QMap<QString, int> mUserTypes; + QMap<QString, int> mBasicTypes; + + int mCurrentId; + + QString mNameSpace; + + struct ExternRef + { + int localTypeId; + QualifiedName qname; + }; + + QValueList<struct ExternRef> mExternRefs; +}; + +} + +#endif diff --git a/kode/kwsdl/schema/xsdtype.h b/kode/kwsdl/schema/xsdtype.h new file mode 100644 index 000000000..b1bc4a7f8 --- /dev/null +++ b/kode/kwsdl/schema/xsdtype.h @@ -0,0 +1,114 @@ +/* + This file is part of KDE Schema Parser + + Copyright (c) 2005 Tobias Koenig <tokoe@kde.org> + 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. + */ + +#ifndef SCHEMA_XSDTYPE_H +#define SCHEMA_XSDTYPE_H + +#include <qstring.h> +#include <qvaluelist.h> +#include <qmap.h> + +#include "qualifiedname.h" + +namespace Schema { + +const QString SchemaUri = "http://www.w3.org/2001/XMLSchema"; + +class XSDType +{ + public: + typedef QValueList<const XSDType*> List; + + enum + { + SIMPLE = 0, + COMPLEX, + MIXED + }; + + enum + { + INVALID = 0, + STRING = 1, + INTEGER, + INT, + BYTE, + UBYTE, + POSINT, + UINT, + LONG, + ULONG, + SHORT, + USHORT, + DECIMAL, + FLOAT, + DOUBLE, + BOOLEAN, + TIME, + DATETIME, + DATE, + TOKEN, + QNAME, + NCNAME, + NMTOKEN, + NMTOKENS, + BASE64BIN, + HEXBIN, + ANY, + ANYTYPE, + ANYURI + }; + + XSDType( const QString& ) + { + }; + + XSDType() + { + }; + + virtual ~XSDType() + { + }; + + virtual QString name() const = 0; + virtual QualifiedName qualifiedName() const = 0; + virtual QString documentation() const = 0; + virtual int contentModel() const = 0; + virtual int type() const = 0; + virtual bool isAnonymous() const = 0; + + virtual bool isSimple() const + { + return true; + } + + virtual void setName( const QString& ) = 0; + virtual void setDocumentation( const QString& ) = 0; + virtual void setContentModel( int ) = 0; + virtual void setType( int ) = 0; + virtual void setAnonymous( bool ) = 0; +}; + +} + +#endif |