XMLValidator.cpp
上传用户:huihehuasu
上传日期:2007-01-10
资源大小:6948k
文件大小:13k
源码类别:

xml/soap/webservice

开发平台:

C/C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
  5.  * reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  *
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in
  16.  *    the documentation and/or other materials provided with the
  17.  *    distribution.
  18.  *
  19.  * 3. The end-user documentation included with the redistribution,
  20.  *    if any, must include the following acknowledgment:
  21.  *       "This product includes software developed by the
  22.  *        Apache Software Foundation (http://www.apache.org/)."
  23.  *    Alternately, this acknowledgment may appear in the software itself,
  24.  *    if and wherever such third-party acknowledgments normally appear.
  25.  *
  26.  * 4. The names "Xerces" and "Apache Software Foundation" must
  27.  *    not be used to endorse or promote products derived from this
  28.  *    software without prior written permission. For written
  29.  *    permission, please contact apache@apache.org.
  30.  *
  31.  * 5. Products derived from this software may not be called "Apache",
  32.  *    nor may "Apache" appear in their name, without prior written
  33.  *    permission of the Apache Software Foundation.
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38.  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42.  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44.  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45.  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46.  * SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Software Foundation, and was
  51.  * originally based on software copyright (c) 1999, International
  52.  * Business Machines, Inc., http://www.ibm.com .  For more information
  53.  * on the Apache Software Foundation, please see
  54.  * <http://www.apache.org/>.
  55.  */
  56. /**
  57.   * $Log: XMLValidator.cpp,v $
  58.   * Revision 1.13  2001/11/30 22:18:18  peiyongz
  59.   * cleanUp function made member function
  60.   * cleanUp object moved to file scope
  61.   * double mutex lock removed
  62.   *
  63.   * Revision 1.12  2001/11/28 20:32:49  tng
  64.   * Do not increment the error count if it is a warning.
  65.   *
  66.   * Revision 1.11  2001/10/24 23:46:52  peiyongz
  67.   * [Bug 4342] fix the leak.
  68.   *
  69.   * Revision 1.10  2001/06/04 21:07:34  jberry
  70.   * Increment scanner error count from schema validator, not just in scanner itself.
  71.   *
  72.   * Revision 1.9  2001/05/11 13:25:33  tng
  73.   * Copyright update.
  74.   *
  75.   * Revision 1.8  2001/05/03 19:08:58  knoaman
  76.   * Support Warning/Error/FatalError messaging.
  77.   * Validity constraints errors are treated as errors, with the ability by user to set
  78.   * validity constraints as fatal errors.
  79.   *
  80.   * Revision 1.7  2001/03/21 21:56:02  tng
  81.   * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
  82.   *
  83.   * Revision 1.6  2000/03/28 19:43:17  roddey
  84.   * Fixes for signed/unsigned warnings. New work for two way transcoding
  85.   * stuff.
  86.   *
  87.   * Revision 1.5  2000/03/02 19:54:25  roddey
  88.   * This checkin includes many changes done while waiting for the
  89.   * 1.1.0 code to be finished. I can't list them all here, but a list is
  90.   * available elsewhere.
  91.   *
  92.   * Revision 1.4  2000/02/06 07:47:49  rahulj
  93.   * Year 2K copyright swat.
  94.   *
  95.   * Revision 1.3  1999/12/08 00:15:06  roddey
  96.   * Some small last minute fixes to get into the 3.0.1 build that is going to be
  97.   * going out anyway for platform fixes.
  98.   *
  99.   * Revision 1.2  1999/12/02 19:02:56  roddey
  100.   * Get rid of a few statically defined XMLMutex objects, and lazy eval them
  101.   * using atomic compare and swap. I somehow let it get by me that we don't
  102.   * want any static/global objects at all.
  103.   *
  104.   * Revision 1.1.1.1  1999/11/09 01:08:37  twl
  105.   * Initial checkin
  106.   *
  107.   * Revision 1.3  1999/11/08 20:44:40  rahul
  108.   * Swat for adding in Product name and CVS comment log variable.
  109.   *
  110.   */
  111. // ---------------------------------------------------------------------------
  112. //  Includes
  113. // ---------------------------------------------------------------------------
  114. #include <util/Janitor.hpp>
  115. #include <util/Mutexes.hpp>
  116. #include <util/PlatformUtils.hpp>
  117. #include <util/XMLMsgLoader.hpp>
  118. #include <util/XMLString.hpp>
  119. #include <util/XMLRegisterCleanup.hpp>
  120. #include <framework/XMLErrorReporter.hpp>
  121. #include <framework/XMLValidator.hpp>
  122. #include <internal/XMLScanner.hpp>
  123. // ---------------------------------------------------------------------------
  124. //  Local static functions
  125. // ---------------------------------------------------------------------------
  126. static XMLMutex* sMsgMutex = 0;
  127. static XMLRegisterCleanup msgLoaderCleanup;
  128. static XMLMsgLoader* sMsgLoader = 0;
  129. static XMLRegisterCleanup validatorMutexCleanup;
  130. //
  131. //  We need to fault in this mutex. But, since its used for synchronization
  132. //  itself, we have to do this the low level way using a compare and swap.
  133. //
  134. static XMLMutex& gValidatorMutex()
  135. {
  136.     if (!sMsgMutex)
  137.     {
  138.         XMLMutex* tmpMutex = new XMLMutex;
  139.         if (XMLPlatformUtils::compareAndSwap((void**)&sMsgMutex, tmpMutex, 0))
  140.         {
  141.             // Someone beat us to it, so let's clean up ours
  142.             delete tmpMutex;
  143.         }
  144.         else
  145.         {
  146.             validatorMutexCleanup.registerCleanup(XMLValidator::reinitMsgMutex);
  147.         }
  148.     }
  149.     return *sMsgMutex;
  150. }
  151. static XMLMsgLoader& getMsgLoader()
  152. {
  153. // Lock the mutex
  154. XMLMutexLock lockInit(&gValidatorMutex());
  155.     
  156.     if (!sMsgLoader)
  157. {
  158. sMsgLoader = XMLPlatformUtils::loadMsgSet(XMLUni::fgValidityDomain);
  159. if (!sMsgLoader)
  160. XMLPlatformUtils::panic(XMLPlatformUtils::Panic_CantLoadMsgDomain);
  161.         //
  162.         // Register this XMLMsgLoader for cleanup at Termination.
  163.         //
  164.         msgLoaderCleanup.registerCleanup(XMLValidator::reinitMsgLoader);
  165. }
  166.     return *sMsgLoader;
  167. }
  168. // ---------------------------------------------------------------------------
  169. //  XMLValidator: Error emitting methods
  170. // ---------------------------------------------------------------------------
  171. //
  172. //  These methods are called whenever the scanner wants to emit an error.
  173. //  It handles getting the message loaded, doing token replacement, etc...
  174. //  and then calling the error handler, if its installed.
  175. //
  176. void XMLValidator::emitError(const XMLValid::Codes toEmit)
  177. {
  178.     // Bump the error count if it is not a warning
  179.     if (XMLValid::errorType(toEmit) != XMLErrorReporter::ErrType_Warning)
  180.         fScanner->incrementErrorCount();
  181.     // Call error reporter if we have one
  182.     if (fErrorReporter)
  183.     {
  184.         // Load the message into a local for display
  185.         const unsigned int msgSize = 1023;
  186.         XMLCh errText[msgSize + 1];
  187.         // load the text
  188. if (!getMsgLoader().loadMsg(toEmit, errText, msgSize))
  189. {
  190. // <TBD> Probably should load a default msg here
  191.         }
  192.         //
  193.         //  Create a LastExtEntityInfo structure and get the reader manager
  194.         //  to fill it in for us. This will give us the information about
  195.         //  the last reader on the stack that was an external entity of some
  196.         //  sort (i.e. it will ignore internal entities.
  197.         //
  198.         ReaderMgr::LastExtEntityInfo lastInfo;
  199.         fReaderMgr->getLastExtEntityInfo(lastInfo);
  200.         fErrorReporter->error
  201.         (
  202.             toEmit
  203.             , XMLUni::fgValidityDomain
  204.             , XMLValid::errorType(toEmit)
  205.             , errText
  206.             , lastInfo.systemId
  207.             , lastInfo.publicId
  208.             , lastInfo.lineNumber
  209.             , lastInfo.colNumber
  210.         );
  211.     }
  212.     // Bail out if its fatal an we are to give up on the first fatal error
  213.     if (((XMLValid::isError(toEmit) && fScanner->getValidationConstraintFatal())
  214.          || XMLValid::isFatal(toEmit))
  215.     &&  fScanner->getExitOnFirstFatal()
  216.     &&  !fScanner->getInException())
  217.     {
  218.         throw toEmit;
  219.     }
  220. }
  221. void XMLValidator::emitError(const  XMLValid::Codes toEmit
  222.                             , const XMLCh* const    text1
  223.                             , const XMLCh* const    text2
  224.                             , const XMLCh* const    text3
  225.                             , const XMLCh* const    text4)
  226. {
  227.     // Bump the error count if it is not a warning
  228.     if (XMLValid::errorType(toEmit) != XMLErrorReporter::ErrType_Warning)
  229.         fScanner->incrementErrorCount();
  230.     // Call error reporter if we have one
  231.     if (fErrorReporter)
  232.     {
  233.         //
  234.         //  Load the message into alocal and replace any tokens found in
  235.         //  the text.
  236.         //
  237.         const unsigned int maxChars = 2047;
  238.         XMLCh errText[maxChars + 1];
  239.         // load the text
  240. if (!getMsgLoader().loadMsg(toEmit, errText, maxChars, text1, text2, text3, text4))
  241. {
  242. // <TBD> Should probably load a default message here
  243.         }
  244.         //
  245.         //  Create a LastExtEntityInfo structure and get the reader manager
  246.         //  to fill it in for us. This will give us the information about
  247.         //  the last reader on the stack that was an external entity of some
  248.         //  sort (i.e. it will ignore internal entities.
  249.         //
  250.         ReaderMgr::LastExtEntityInfo lastInfo;
  251.         fReaderMgr->getLastExtEntityInfo(lastInfo);
  252.         fErrorReporter->error
  253.         (
  254.             toEmit
  255.             , XMLUni::fgValidityDomain
  256.             , XMLValid::errorType(toEmit)
  257.             , errText
  258.             , lastInfo.systemId
  259.             , lastInfo.publicId
  260.             , lastInfo.lineNumber
  261.             , lastInfo.colNumber
  262.         );
  263.     }
  264.     // Bail out if its fatal an we are to give up on the first fatal error
  265.     if (((XMLValid::isError(toEmit) && fScanner->getValidationConstraintFatal())
  266.          || XMLValid::isFatal(toEmit))
  267.     &&  fScanner->getExitOnFirstFatal()
  268.     &&  !fScanner->getInException())
  269.     {
  270.         throw toEmit;
  271.     }
  272. }
  273. void XMLValidator::emitError(const  XMLValid::Codes toEmit
  274.                             , const char* const     text1
  275.                             , const char* const     text2
  276.                             , const char* const     text3
  277.                             , const char* const     text4)
  278. {
  279.     // Bump the error count if it is not a warning
  280.     if (XMLValid::errorType(toEmit) != XMLErrorReporter::ErrType_Warning)
  281.         fScanner->incrementErrorCount();
  282.     // Call error reporter if we have one
  283.     if (fErrorReporter)
  284.     {
  285.         //
  286.         //  Load the message into alocal and replace any tokens found in
  287.         //  the text.
  288.         //
  289.         const unsigned int maxChars = 2047;
  290.         XMLCh errText[maxChars + 1];
  291.         // load the text
  292. if (!getMsgLoader().loadMsg(toEmit, errText, maxChars, text1, text2, text3, text4))
  293. {
  294. // <TBD> Should probably load a default message here
  295.         }
  296.         //
  297.         //  Create a LastExtEntityInfo structure and get the reader manager
  298.         //  to fill it in for us. This will give us the information about
  299.         //  the last reader on the stack that was an external entity of some
  300.         //  sort (i.e. it will ignore internal entities.
  301.         //
  302.         ReaderMgr::LastExtEntityInfo lastInfo;
  303.         fReaderMgr->getLastExtEntityInfo(lastInfo);
  304.         fErrorReporter->error
  305.         (
  306.             toEmit
  307.             , XMLUni::fgValidityDomain
  308.             , XMLValid::errorType(toEmit)
  309.             , errText
  310.             , lastInfo.systemId
  311.             , lastInfo.publicId
  312.             , lastInfo.lineNumber
  313.             , lastInfo.colNumber
  314.         );
  315.     }
  316.     // Bail out if its fatal an we are to give up on the first fatal error
  317.     if (((XMLValid::isError(toEmit) && fScanner->getValidationConstraintFatal())
  318.          || XMLValid::isFatal(toEmit))
  319.     &&  fScanner->getExitOnFirstFatal()
  320.     &&  !fScanner->getInException())
  321.     {
  322.         throw toEmit;
  323.     }
  324. }
  325. // ---------------------------------------------------------------------------
  326. //  XMLValidator: Hidden Constructors
  327. // ---------------------------------------------------------------------------
  328. XMLValidator::XMLValidator(XMLErrorReporter* const errReporter) :
  329.     fBufMgr(0)
  330.     , fErrorReporter(errReporter)
  331.     , fReaderMgr(0)
  332.     , fScanner(0)
  333. {
  334. }
  335. // -----------------------------------------------------------------------
  336. //  Notification that lazy data has been deleted
  337. // -----------------------------------------------------------------------
  338. void XMLValidator::reinitMsgMutex()
  339. {
  340.     delete sMsgMutex;
  341.     sMsgMutex = 0;
  342. }
  343. // -----------------------------------------------------------------------
  344. //  Reinitialise the message loader
  345. // -----------------------------------------------------------------------
  346. void XMLValidator::reinitMsgLoader()
  347. {
  348. delete sMsgLoader;
  349. sMsgLoader = 0;
  350. }