src/xmlpatterns/api/qxmlschemavalidator.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     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   \sa QXmlSchema, {xmlpatterns/schema}{XML Schema Validation Example}
       
    75 */
       
    76 
       
    77 /*!
       
    78   Constructs a schema validator.
       
    79   The schema used for validation must be referenced in the XML instance document
       
    80   via the \c xsi:schemaLocation or \c xsi:noNamespaceSchemaLocation attribute.
       
    81  */
       
    82 QXmlSchemaValidator::QXmlSchemaValidator()
       
    83     : d(new QXmlSchemaValidatorPrivate(QXmlSchema()))
       
    84 {
       
    85 }
       
    86 
       
    87 /*!
       
    88   Constructs a schema validator that will use \a schema for validation.
       
    89   If an empty \l {QXmlSchema} schema is passed to the validator, the schema used
       
    90   for validation must be referenced in the XML instance document
       
    91   via the \c xsi:schemaLocation or \c xsi:noNamespaceSchemaLocation attribute.
       
    92  */
       
    93 QXmlSchemaValidator::QXmlSchemaValidator(const QXmlSchema &schema)
       
    94     : d(new QXmlSchemaValidatorPrivate(schema))
       
    95 {
       
    96 }
       
    97 
       
    98 /*!
       
    99   Destroys this QXmlSchemaValidator.
       
   100  */
       
   101 QXmlSchemaValidator::~QXmlSchemaValidator()
       
   102 {
       
   103     delete d;
       
   104 }
       
   105 
       
   106 /*!
       
   107   Sets the \a schema that shall be used for further validation.
       
   108   If the schema is empty, the schema used for validation must be referenced
       
   109   in the XML instance document via the \c xsi:schemaLocation or
       
   110   \c xsi:noNamespaceSchemaLocation attribute.
       
   111  */
       
   112 void QXmlSchemaValidator::setSchema(const QXmlSchema &schema)
       
   113 {
       
   114     d->setSchema(schema);
       
   115 }
       
   116 
       
   117 /*!
       
   118   Validates the XML instance document read from \a data with the
       
   119   given \a documentUri against the schema.
       
   120 
       
   121   Returns \c true if the XML instance document is valid according to the
       
   122   schema, \c false otherwise.
       
   123 
       
   124   Example:
       
   125 
       
   126   \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 2
       
   127  */
       
   128 bool QXmlSchemaValidator::validate(const QByteArray &data, const QUrl &documentUri) const
       
   129 {
       
   130     QByteArray localData(data);
       
   131 
       
   132     QBuffer buffer(&localData);
       
   133     buffer.open(QIODevice::ReadOnly);
       
   134 
       
   135     return validate(&buffer, documentUri);
       
   136 }
       
   137 
       
   138 /*!
       
   139   Validates the XML instance document read from \a source against the schema.
       
   140 
       
   141   Returns \c true if the XML instance document is valid according to the
       
   142   schema, \c false otherwise.
       
   143 
       
   144   Example:
       
   145 
       
   146   \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 0
       
   147  */
       
   148 bool QXmlSchemaValidator::validate(const QUrl &source) const
       
   149 {
       
   150     d->m_context->setMessageHandler(messageHandler());
       
   151     d->m_context->setUriResolver(uriResolver());
       
   152     d->m_context->setNetworkAccessManager(networkAccessManager());
       
   153 
       
   154     const QPatternist::AutoPtr<QNetworkReply> reply(QPatternist::AccelTreeResourceLoader::load(source, d->m_context->networkAccessManager(),
       
   155                                                                                                d->m_context, QPatternist::AccelTreeResourceLoader::ContinueOnError));
       
   156     if (reply)
       
   157         return validate(reply.data(), source);
       
   158     else
       
   159         return false;
       
   160 }
       
   161 
       
   162 /*!
       
   163   Validates the XML instance document read from \a source with the
       
   164   given \a documentUri against the schema.
       
   165 
       
   166   Returns \c true if the XML instance document is valid according to the
       
   167   schema, \c false otherwise.
       
   168 
       
   169   Example:
       
   170 
       
   171   \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 1
       
   172  */
       
   173 bool QXmlSchemaValidator::validate(QIODevice *source, const QUrl &documentUri) const
       
   174 {
       
   175     if (!source) {
       
   176         qWarning("A null QIODevice pointer cannot be passed.");
       
   177         return false;
       
   178     }
       
   179 
       
   180     if (!source->isReadable()) {
       
   181         qWarning("The device must be readable.");
       
   182         return false;
       
   183     }
       
   184 
       
   185     const QUrl normalizedUri = QPatternist::XPathHelper::normalizeQueryURI(documentUri);
       
   186 
       
   187     d->m_context->setMessageHandler(messageHandler());
       
   188     d->m_context->setUriResolver(uriResolver());
       
   189     d->m_context->setNetworkAccessManager(networkAccessManager());
       
   190 
       
   191     QPatternist::NetworkAccessDelegator::Ptr delegator(new QPatternist::NetworkAccessDelegator(d->m_context->networkAccessManager(),
       
   192                                                                                                d->m_context->networkAccessManager()));
       
   193 
       
   194     QPatternist::AccelTreeResourceLoader loader(d->m_context->namePool(), delegator, QPatternist::AccelTreeBuilder<true>::SourceLocationsFeature);
       
   195 
       
   196     QPatternist::Item item;
       
   197     try {
       
   198         item = loader.openDocument(source, normalizedUri, d->m_context);
       
   199     } catch (QPatternist::Exception exception) {
       
   200         return false;
       
   201     }
       
   202 
       
   203     QXmlNodeModelIndex index = item.asNode();
       
   204     const QAbstractXmlNodeModel *model = item.asNode().model();
       
   205 
       
   206     QPatternist::XsdValidatedXmlNodeModel *validatedModel = new QPatternist::XsdValidatedXmlNodeModel(model);
       
   207 
       
   208     QPatternist::XsdValidatingInstanceReader reader(validatedModel, normalizedUri, d->m_context);
       
   209     if (d->m_schema)
       
   210         reader.addSchema(d->m_schema, d->m_schemaDocumentUri);
       
   211     try {
       
   212         reader.read();
       
   213     } catch (QPatternist::Exception exception) {
       
   214         return false;
       
   215     }
       
   216 
       
   217     return true;
       
   218 }
       
   219 
       
   220 /*!
       
   221   Returns the name pool used by this QXmlSchemaValidator for constructing \l
       
   222   {QXmlName} {names}. There is no setter for the name pool, because
       
   223   mixing name pools causes errors due to name confusion.
       
   224  */
       
   225 QXmlNamePool QXmlSchemaValidator::namePool() const
       
   226 {
       
   227     return d->m_namePool;
       
   228 }
       
   229 
       
   230 /*!
       
   231   Returns the schema that is used for validation.
       
   232  */
       
   233 QXmlSchema QXmlSchemaValidator::schema() const
       
   234 {
       
   235     return d->m_originalSchema;
       
   236 }
       
   237 
       
   238 /*!
       
   239   Changes the \l {QAbstractMessageHandler}{message handler} for this
       
   240   QXmlSchemaValidator to \a handler. The schema validator sends all parsing and
       
   241   validation messages to this message handler. QXmlSchemaValidator does not take
       
   242   ownership of \a handler.
       
   243 
       
   244   Normally, the default message handler is sufficient. It writes
       
   245   compile and validation messages to \e stderr. The default message
       
   246   handler includes color codes if \e stderr can render colors.
       
   247 
       
   248   When QXmlSchemaValidator calls QAbstractMessageHandler::message(),
       
   249   the arguments are as follows:
       
   250 
       
   251   \table
       
   252   \header
       
   253     \o message() argument
       
   254     \o Semantics
       
   255   \row
       
   256     \o QtMsgType type
       
   257     \o Only QtWarningMsg and QtFatalMsg are used. The former
       
   258        identifies a warning, while the latter identifies an error.
       
   259   \row
       
   260     \o const QString & description
       
   261     \o An XHTML document which is the actual message. It is translated
       
   262        into the current language.
       
   263   \row
       
   264     \o const QUrl &identifier
       
   265     \o Identifies the error with a URI, where the fragment is
       
   266        the error code, and the rest of the URI is the error namespace.
       
   267   \row
       
   268     \o const QSourceLocation & sourceLocation
       
   269     \o Identifies where the error occurred.
       
   270   \endtable
       
   271 
       
   272  */
       
   273 void QXmlSchemaValidator::setMessageHandler(QAbstractMessageHandler *handler)
       
   274 {
       
   275     d->m_userMessageHandler = handler;
       
   276 }
       
   277 
       
   278 /*!
       
   279     Returns the message handler that handles parsing and validation
       
   280     messages for this QXmlSchemaValidator.
       
   281  */
       
   282 QAbstractMessageHandler *QXmlSchemaValidator::messageHandler() const
       
   283 {
       
   284     if (d->m_userMessageHandler)
       
   285         return d->m_userMessageHandler;
       
   286 
       
   287     return d->m_messageHandler.data()->value;
       
   288 }
       
   289 
       
   290 /*!
       
   291   Sets the URI resolver to \a resolver. QXmlSchemaValidator does not take
       
   292   ownership of \a resolver.
       
   293 
       
   294   \sa uriResolver()
       
   295  */
       
   296 void QXmlSchemaValidator::setUriResolver(const QAbstractUriResolver *resolver)
       
   297 {
       
   298     d->m_uriResolver = resolver;
       
   299 }
       
   300 
       
   301 /*!
       
   302   Returns the schema's URI resolver. If no URI resolver has been set,
       
   303   QtXmlPatterns will use the URIs in instance documents as they are.
       
   304 
       
   305   The URI resolver provides a level of abstraction, or \e{polymorphic
       
   306   URIs}. A resolver can rewrite \e{logical} URIs to physical ones, or
       
   307   it can translate obsolete or invalid URIs to valid ones.
       
   308 
       
   309   When QtXmlPatterns calls QAbstractUriResolver::resolve() the
       
   310   absolute URI is the URI mandated by the schema specification, and the
       
   311   relative URI is the URI specified by the user.
       
   312 
       
   313   \sa setUriResolver()
       
   314  */
       
   315 const QAbstractUriResolver *QXmlSchemaValidator::uriResolver() const
       
   316 {
       
   317     return d->m_uriResolver;
       
   318 }
       
   319 
       
   320 /*!
       
   321   Sets the network manager to \a manager.
       
   322   QXmlSchemaValidator does not take ownership of \a manager.
       
   323 
       
   324   \sa networkAccessManager()
       
   325  */
       
   326 void QXmlSchemaValidator::setNetworkAccessManager(QNetworkAccessManager *manager)
       
   327 {
       
   328     d->m_userNetworkAccessManager = manager;
       
   329 }
       
   330 
       
   331 /*!
       
   332   Returns the network manager, or 0 if it has not been set.
       
   333 
       
   334   \sa setNetworkAccessManager()
       
   335  */
       
   336 QNetworkAccessManager *QXmlSchemaValidator::networkAccessManager() const
       
   337 {
       
   338     if (d->m_userNetworkAccessManager)
       
   339         return d->m_userNetworkAccessManager;
       
   340 
       
   341     return d->m_networkAccessManager.data()->value;
       
   342 }
       
   343 
       
   344 QT_END_NAMESPACE