util/src/xmlpatterns/api/qxmlschemavalidator.cpp
changeset 7 f7bc934e204c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qxmlschemavalidator.h"
       
    43 #include "qxmlschemavalidator_p.h"
       
    44 
       
    45 #include "qacceltreeresourceloader_p.h"
       
    46 #include "qxmlschema.h"
       
    47 #include "qxmlschema_p.h"
       
    48 #include "qxsdvalidatinginstancereader_p.h"
       
    49 
       
    50 #include <QtCore/QBuffer>
       
    51 #include <QtCore/QIODevice>
       
    52 #include <QtCore/QUrl>
       
    53 
       
    54 QT_BEGIN_NAMESPACE
       
    55 
       
    56 /*!
       
    57   \class QXmlSchemaValidator
       
    58 
       
    59   \brief The QXmlSchemaValidator class validates XML instance documents against a W3C XML Schema.
       
    60 
       
    61   \reentrant
       
    62   \since 4.6
       
    63   \ingroup xml-tools
       
    64 
       
    65   The QXmlSchemaValidator class loads, parses an XML instance document and validates it
       
    66   against a W3C XML Schema that has been compiled with \l{QXmlSchema}.
       
    67 
       
    68   The following example shows how to load a XML Schema from a local
       
    69   file, check whether it is a valid schema document and use it for validation
       
    70   of an XML instance document:
       
    71 
       
    72   \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 3
       
    73 
       
    74   \section1 XML Schema Version
       
    75 
       
    76   This class implements schema validation according to the \l{XML Schema} 1.0
       
    77   specification.
       
    78 
       
    79   \sa QXmlSchema, {xmlpatterns/schema}{XML Schema Validation Example}
       
    80 */
       
    81 
       
    82 /*!
       
    83   Constructs a schema validator.
       
    84   The schema used for validation must be referenced in the XML instance document
       
    85   via the \c xsi:schemaLocation or \c xsi:noNamespaceSchemaLocation attribute.
       
    86  */
       
    87 QXmlSchemaValidator::QXmlSchemaValidator()
       
    88     : d(new QXmlSchemaValidatorPrivate(QXmlSchema()))
       
    89 {
       
    90 }
       
    91 
       
    92 /*!
       
    93   Constructs a schema validator that will use \a schema for validation.
       
    94   If an empty \l {QXmlSchema} schema is passed to the validator, the schema used
       
    95   for validation must be referenced in the XML instance document
       
    96   via the \c xsi:schemaLocation or \c xsi:noNamespaceSchemaLocation attribute.
       
    97  */
       
    98 QXmlSchemaValidator::QXmlSchemaValidator(const QXmlSchema &schema)
       
    99     : d(new QXmlSchemaValidatorPrivate(schema))
       
   100 {
       
   101 }
       
   102 
       
   103 /*!
       
   104   Destroys this QXmlSchemaValidator.
       
   105  */
       
   106 QXmlSchemaValidator::~QXmlSchemaValidator()
       
   107 {
       
   108     delete d;
       
   109 }
       
   110 
       
   111 /*!
       
   112   Sets the \a schema that shall be used for further validation.
       
   113   If the schema is empty, the schema used for validation must be referenced
       
   114   in the XML instance document via the \c xsi:schemaLocation or
       
   115   \c xsi:noNamespaceSchemaLocation attribute.
       
   116  */
       
   117 void QXmlSchemaValidator::setSchema(const QXmlSchema &schema)
       
   118 {
       
   119     d->setSchema(schema);
       
   120 }
       
   121 
       
   122 /*!
       
   123   Validates the XML instance document read from \a data with the
       
   124   given \a documentUri against the schema.
       
   125 
       
   126   Returns \c true if the XML instance document is valid according to the
       
   127   schema, \c false otherwise.
       
   128 
       
   129   Example:
       
   130 
       
   131   \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 2
       
   132  */
       
   133 bool QXmlSchemaValidator::validate(const QByteArray &data, const QUrl &documentUri) const
       
   134 {
       
   135     QByteArray localData(data);
       
   136 
       
   137     QBuffer buffer(&localData);
       
   138     buffer.open(QIODevice::ReadOnly);
       
   139 
       
   140     return validate(&buffer, documentUri);
       
   141 }
       
   142 
       
   143 /*!
       
   144   Validates the XML instance document read from \a source against the schema.
       
   145 
       
   146   Returns \c true if the XML instance document is valid according to the
       
   147   schema, \c false otherwise.
       
   148 
       
   149   Example:
       
   150 
       
   151   \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 0
       
   152  */
       
   153 bool QXmlSchemaValidator::validate(const QUrl &source) const
       
   154 {
       
   155     d->m_context->setMessageHandler(messageHandler());
       
   156     d->m_context->setUriResolver(uriResolver());
       
   157     d->m_context->setNetworkAccessManager(networkAccessManager());
       
   158 
       
   159     const QPatternist::AutoPtr<QNetworkReply> reply(QPatternist::AccelTreeResourceLoader::load(source, d->m_context->networkAccessManager(),
       
   160                                                                                                d->m_context, QPatternist::AccelTreeResourceLoader::ContinueOnError));
       
   161     if (reply)
       
   162         return validate(reply.data(), source);
       
   163     else
       
   164         return false;
       
   165 }
       
   166 
       
   167 /*!
       
   168   Validates the XML instance document read from \a source with the
       
   169   given \a documentUri against the schema.
       
   170 
       
   171   Returns \c true if the XML instance document is valid according to the
       
   172   schema, \c false otherwise.
       
   173 
       
   174   Example:
       
   175 
       
   176   \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 1
       
   177  */
       
   178 bool QXmlSchemaValidator::validate(QIODevice *source, const QUrl &documentUri) const
       
   179 {
       
   180     if (!source) {
       
   181         qWarning("A null QIODevice pointer cannot be passed.");
       
   182         return false;
       
   183     }
       
   184 
       
   185     if (!source->isReadable()) {
       
   186         qWarning("The device must be readable.");
       
   187         return false;
       
   188     }
       
   189 
       
   190     const QUrl normalizedUri = QPatternist::XPathHelper::normalizeQueryURI(documentUri);
       
   191 
       
   192     d->m_context->setMessageHandler(messageHandler());
       
   193     d->m_context->setUriResolver(uriResolver());
       
   194     d->m_context->setNetworkAccessManager(networkAccessManager());
       
   195 
       
   196     QPatternist::NetworkAccessDelegator::Ptr delegator(new QPatternist::NetworkAccessDelegator(d->m_context->networkAccessManager(),
       
   197                                                                                                d->m_context->networkAccessManager()));
       
   198 
       
   199     QPatternist::AccelTreeResourceLoader loader(d->m_context->namePool(), delegator, QPatternist::AccelTreeBuilder<true>::SourceLocationsFeature);
       
   200 
       
   201     QPatternist::Item item;
       
   202     try {
       
   203         item = loader.openDocument(source, normalizedUri, d->m_context);
       
   204     } catch (QPatternist::Exception exception) {
       
   205         return false;
       
   206     }
       
   207 
       
   208     QXmlNodeModelIndex index = item.asNode();
       
   209     const QAbstractXmlNodeModel *model = item.asNode().model();
       
   210 
       
   211     QPatternist::XsdValidatedXmlNodeModel *validatedModel = new QPatternist::XsdValidatedXmlNodeModel(model);
       
   212 
       
   213     QPatternist::XsdValidatingInstanceReader reader(validatedModel, normalizedUri, d->m_context);
       
   214     if (d->m_schema)
       
   215         reader.addSchema(d->m_schema, d->m_schemaDocumentUri);
       
   216     try {
       
   217         reader.read();
       
   218     } catch (QPatternist::Exception exception) {
       
   219         return false;
       
   220     }
       
   221 
       
   222     return true;
       
   223 }
       
   224 
       
   225 /*!
       
   226   Returns the name pool used by this QXmlSchemaValidator for constructing \l
       
   227   {QXmlName} {names}. There is no setter for the name pool, because
       
   228   mixing name pools causes errors due to name confusion.
       
   229  */
       
   230 QXmlNamePool QXmlSchemaValidator::namePool() const
       
   231 {
       
   232     return d->m_namePool;
       
   233 }
       
   234 
       
   235 /*!
       
   236   Returns the schema that is used for validation.
       
   237  */
       
   238 QXmlSchema QXmlSchemaValidator::schema() const
       
   239 {
       
   240     return d->m_originalSchema;
       
   241 }
       
   242 
       
   243 /*!
       
   244   Changes the \l {QAbstractMessageHandler}{message handler} for this
       
   245   QXmlSchemaValidator to \a handler. The schema validator sends all parsing and
       
   246   validation messages to this message handler. QXmlSchemaValidator does not take
       
   247   ownership of \a handler.
       
   248 
       
   249   Normally, the default message handler is sufficient. It writes
       
   250   compile and validation messages to \e stderr. The default message
       
   251   handler includes color codes if \e stderr can render colors.
       
   252 
       
   253   When QXmlSchemaValidator calls QAbstractMessageHandler::message(),
       
   254   the arguments are as follows:
       
   255 
       
   256   \table
       
   257   \header
       
   258     \o message() argument
       
   259     \o Semantics
       
   260   \row
       
   261     \o QtMsgType type
       
   262     \o Only QtWarningMsg and QtFatalMsg are used. The former
       
   263        identifies a warning, while the latter identifies an error.
       
   264   \row
       
   265     \o const QString & description
       
   266     \o An XHTML document which is the actual message. It is translated
       
   267        into the current language.
       
   268   \row
       
   269     \o const QUrl &identifier
       
   270     \o Identifies the error with a URI, where the fragment is
       
   271        the error code, and the rest of the URI is the error namespace.
       
   272   \row
       
   273     \o const QSourceLocation & sourceLocation
       
   274     \o Identifies where the error occurred.
       
   275   \endtable
       
   276 
       
   277  */
       
   278 void QXmlSchemaValidator::setMessageHandler(QAbstractMessageHandler *handler)
       
   279 {
       
   280     d->m_userMessageHandler = handler;
       
   281 }
       
   282 
       
   283 /*!
       
   284     Returns the message handler that handles parsing and validation
       
   285     messages for this QXmlSchemaValidator.
       
   286  */
       
   287 QAbstractMessageHandler *QXmlSchemaValidator::messageHandler() const
       
   288 {
       
   289     if (d->m_userMessageHandler)
       
   290         return d->m_userMessageHandler;
       
   291 
       
   292     return d->m_messageHandler.data()->value;
       
   293 }
       
   294 
       
   295 /*!
       
   296   Sets the URI resolver to \a resolver. QXmlSchemaValidator does not take
       
   297   ownership of \a resolver.
       
   298 
       
   299   \sa uriResolver()
       
   300  */
       
   301 void QXmlSchemaValidator::setUriResolver(const QAbstractUriResolver *resolver)
       
   302 {
       
   303     d->m_uriResolver = resolver;
       
   304 }
       
   305 
       
   306 /*!
       
   307   Returns the schema's URI resolver. If no URI resolver has been set,
       
   308   QtXmlPatterns will use the URIs in instance documents as they are.
       
   309 
       
   310   The URI resolver provides a level of abstraction, or \e{polymorphic
       
   311   URIs}. A resolver can rewrite \e{logical} URIs to physical ones, or
       
   312   it can translate obsolete or invalid URIs to valid ones.
       
   313 
       
   314   When QtXmlPatterns calls QAbstractUriResolver::resolve() the
       
   315   absolute URI is the URI mandated by the schema specification, and the
       
   316   relative URI is the URI specified by the user.
       
   317 
       
   318   \sa setUriResolver()
       
   319  */
       
   320 const QAbstractUriResolver *QXmlSchemaValidator::uriResolver() const
       
   321 {
       
   322     return d->m_uriResolver;
       
   323 }
       
   324 
       
   325 /*!
       
   326   Sets the network manager to \a manager.
       
   327   QXmlSchemaValidator does not take ownership of \a manager.
       
   328 
       
   329   \sa networkAccessManager()
       
   330  */
       
   331 void QXmlSchemaValidator::setNetworkAccessManager(QNetworkAccessManager *manager)
       
   332 {
       
   333     d->m_userNetworkAccessManager = manager;
       
   334 }
       
   335 
       
   336 /*!
       
   337   Returns the network manager, or 0 if it has not been set.
       
   338 
       
   339   \sa setNetworkAccessManager()
       
   340  */
       
   341 QNetworkAccessManager *QXmlSchemaValidator::networkAccessManager() const
       
   342 {
       
   343     if (d->m_userNetworkAccessManager)
       
   344         return d->m_userNetworkAccessManager;
       
   345 
       
   346     return d->m_networkAccessManager.data()->value;
       
   347 }
       
   348 
       
   349 QT_END_NAMESPACE