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

xml/soap/webservice

开发平台:

C/C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 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: ValueStore.cpp,v $
  58.  * Revision 1.3  2001/12/06 17:03:37  knoaman
  59.  * Identity Constraint: fix for xpath expressions containing union operator(s).
  60.  *
  61.  * Revision 1.2  2001/11/20 20:32:52  knoaman
  62.  * Bypass validating element's simple content if it's empty and element is nillable.
  63.  *
  64.  * Revision 1.1  2001/11/02 14:08:40  knoaman
  65.  * Add support for identity constraints.
  66.  *
  67.  */
  68. // ---------------------------------------------------------------------------
  69. //  Includes
  70. // ---------------------------------------------------------------------------
  71. #include <internal/XMLScanner.hpp>
  72. #include <validators/schema/identity/ValueStore.hpp>
  73. #include <validators/schema/identity/IC_Field.hpp>
  74. #include <validators/schema/identity/IC_KeyRef.hpp>
  75. #include <validators/schema/identity/ValueStoreCache.hpp>
  76. // ---------------------------------------------------------------------------
  77. //  ValueStore: Constructors and Destructor
  78. // ---------------------------------------------------------------------------
  79. ValueStore::ValueStore(IdentityConstraint* const ic,
  80.                        XMLScanner* const scanner)
  81.     : fDoReportError(false)
  82.     , fValuesCount(0)
  83.     , fIdentityConstraint(ic)
  84.     , fValueTuples(0)
  85.     , fKeyValueStore(0)
  86.     , fScanner(scanner)
  87. {
  88. fDoReportError = (scanner && scanner->getDoValidation());
  89. }
  90. ValueStore::~ValueStore()
  91. {
  92.     delete fValueTuples;
  93. }
  94. // ---------------------------------------------------------------------------
  95. //  ValueStore: Helper methods
  96. // ---------------------------------------------------------------------------
  97. void ValueStore::addValue(IC_Field* const field,
  98.                           DatatypeValidator* const dv,
  99.                           const XMLCh* const value) {
  100.     if (!field->getMayMatch() && fDoReportError) {
  101.         fScanner->getValidator()->emitError(XMLValid::IC_FieldMultipleMatch);
  102.     }
  103.     // do we even know this field?
  104.     int index = fValues.indexOf(field);
  105.     if (index == -1) {
  106.         if (fDoReportError) {
  107.            fScanner->getValidator()->emitError(XMLValid::IC_UnknownField);
  108.         }
  109.         return;
  110.     }
  111.     // store value
  112.     if (!fValues.getDatatypeValidatorAt(index) &&
  113.         !fValues.getValueAt(index)) {
  114.         fValuesCount++;
  115.     }
  116.     fValues.put(field, dv, value);
  117.     if (fValuesCount == (int) fValues.size()) {
  118.         // is this value as a group duplicated?
  119.         if (contains(&fValues)) {
  120.             duplicateValue();
  121.         }
  122.         // store values
  123.         if (!fValueTuples) {
  124.             fValueTuples = new RefVectorOf<FieldValueMap>(4);
  125.         }
  126.         fValueTuples->addElement(new FieldValueMap(fValues));
  127.     }
  128. }
  129. void ValueStore::append(const ValueStore* const other) {
  130.     if (!other->fValueTuples) {
  131.         return;
  132.     }
  133.     unsigned int tupleSize = other->fValueTuples->size();
  134.     for (unsigned int i=0; i<tupleSize; i++) {
  135.     FieldValueMap* valueMap = other->fValueTuples->elementAt(i);
  136.         if (!contains(valueMap)) {
  137.             if (!fValueTuples) {
  138.                 fValueTuples = new RefVectorOf<FieldValueMap>(4);
  139.             }
  140.             fValueTuples->addElement(new FieldValueMap(*valueMap));
  141.         }
  142.     }
  143. }
  144. void ValueStore::startValueScope() {
  145.     fValuesCount = 0;
  146.     int count = fIdentityConstraint->getFieldCount();
  147.     for (int i = 0; i < count; i++) {
  148.         fValues.put(fIdentityConstraint->getFieldAt(i), 0, 0);
  149.     }
  150. }
  151. void ValueStore::endValueScope() {
  152.     if (fValuesCount == 0) {
  153.         if (fIdentityConstraint->getType() == IdentityConstraint::KEY && fDoReportError) {
  154.             fScanner->getValidator()->emitError(XMLValid::IC_AbsentKeyValue,
  155.                 fIdentityConstraint->getElementName());
  156.         }
  157.         return;
  158.     }
  159.     // do we have enough values?
  160.     if ((fValuesCount != fIdentityConstraint->getFieldCount()) && fDoReportError) {
  161.         switch (fIdentityConstraint->getType()) {
  162.         case IdentityConstraint::UNIQUE:
  163.             {
  164. fScanner->getValidator()->emitError(XMLValid::IC_UniqueNotEnoughValues,
  165.                     fIdentityConstraint->getElementName());
  166.                 break;
  167.             }
  168.         case IdentityConstraint::KEY:
  169.             {
  170. fScanner->getValidator()->emitError(XMLValid::IC_KeyNotEnoughValues,
  171.                     fIdentityConstraint->getElementName(), fIdentityConstraint->getIdentityConstraintName());
  172.                 break;
  173.             }
  174.         case IdentityConstraint::KEYREF:
  175.             {
  176. fScanner->getValidator()->emitError(XMLValid::IC_KeyRefNotEnoughValues,
  177.                     fIdentityConstraint->getElementName(), fIdentityConstraint->getIdentityConstraintName());
  178.                 break;
  179.             }
  180.         }
  181.     }
  182. }
  183. bool ValueStore::contains(const FieldValueMap* const other) {
  184.     if (fValueTuples) {
  185.         unsigned int otherSize = other->size();
  186.         unsigned int tupleSize = fValueTuples->size();
  187.         for (unsigned int i=0; i<tupleSize; i++) {
  188.             FieldValueMap* valueMap = fValueTuples->elementAt(i);
  189.             if (otherSize == valueMap->size()) {
  190.                 bool matchFound = true;
  191.                 for (unsigned int j=0; j<otherSize; j++) {
  192.                     if (!isDuplicateOf(valueMap->getDatatypeValidatorAt(j), valueMap->getValueAt(j),
  193.                                        other->getDatatypeValidatorAt(j), other->getValueAt(j))) {
  194.                         matchFound = false;
  195.                         break;
  196.                     }
  197.                 }
  198.                 if (matchFound) { // found it
  199.                     return true;
  200.                 }
  201.             }
  202.         }
  203.     }
  204.     
  205.     return false;
  206. }
  207. bool ValueStore::isDuplicateOf(DatatypeValidator* const dv1, const XMLCh* const val1,
  208.                                DatatypeValidator* const dv2, const XMLCh* const val2) {
  209.     // if either validator's null, fall back on string comparison
  210.     if(!dv1 || !dv2) {
  211.         return ((XMLString::compareString(val1, val2)) == 0);
  212.     }
  213.     unsigned int val1Len = XMLString::stringLen(val1);
  214.     unsigned int val2Len = XMLString::stringLen(val2);
  215.     if (!val1Len && !val2Len) {
  216.         if (dv1 == dv2) {
  217.             return true;
  218.         }
  219.         return false;
  220.     }
  221.     if (!val1Len || !val2Len) {
  222.         return false;
  223.     }
  224.     // are the validators equal?
  225.     // As always we are obliged to compare by reference...
  226.     if (dv1 == dv2) {
  227.         return ((dv1->compare(val1, val2)) == 0);
  228.     } 
  229.     // see if this.fValidator is derived from value.fValidator:
  230.     DatatypeValidator* tempVal = dv1;
  231.     for(; !tempVal || tempVal == dv2; tempVal = tempVal->getBaseValidator());
  232.     if (tempVal) { // was derived!
  233.         return ((dv2->compare(val1, val2)) == 0);
  234.     }
  235.     // see if value.fValidator is derived from this.fValidator:
  236.     for(tempVal = dv2; !tempVal || tempVal == dv1; tempVal = tempVal->getBaseValidator());
  237.     if(tempVal) { // was derived!
  238.         return ((dv1->compare(val1, val2)) == 0);
  239.     }
  240.     // if we're here it means the types weren't related.  Must fall back to strings:
  241.     return ((XMLString::compareString(val1, val2)) == 0); 
  242. }
  243. // ---------------------------------------------------------------------------
  244. //  ValueStore: Docuement handling methods
  245. // ---------------------------------------------------------------------------
  246. void ValueStore::endDcocumentFragment(ValueStoreCache* const valueStoreCache) {
  247.     if (fIdentityConstraint->getType() == IdentityConstraint::KEYREF) {
  248.         // verify references
  249.         // get the key store corresponding (if it exists):
  250.         fKeyValueStore = valueStoreCache->getGlobalValueStoreFor(((IC_KeyRef*) fIdentityConstraint)->getKey());
  251.         if (!fKeyValueStore) {
  252.             if (fDoReportError) {
  253.                 fScanner->getValidator()->emitError(XMLValid::IC_KeyRefOutOfScope,
  254.                     fIdentityConstraint->getIdentityConstraintName());
  255.             }
  256.             return;
  257.         }
  258.         unsigned int count = (fValueTuples) ? fValueTuples->size() : 0;
  259.         for (unsigned int i = 0; i < count; i++) {
  260.             FieldValueMap* valueMap = fValueTuples->elementAt(i);
  261.             if (!fKeyValueStore->contains(valueMap) && fDoReportError) {
  262.                 fScanner->getValidator()->emitError(XMLValid::IC_KeyNotFound,
  263.                     fIdentityConstraint->getElementName());
  264.             }
  265.         }
  266.     }
  267. }
  268. // ---------------------------------------------------------------------------
  269. //  ValueStore: Error reporting methods
  270. // ---------------------------------------------------------------------------
  271. void ValueStore::reportNilError(IdentityConstraint* const ic) {
  272.     if (fDoReportError && ic->getType() == IdentityConstraint::KEY) {
  273.         fScanner->getValidator()->emitError(XMLValid::IC_KeyMatchesNillable, 
  274.                                             ic->getElementName());
  275.     }
  276. }
  277. void ValueStore::duplicateValue() {
  278.     if (fDoReportError) {
  279.         switch (fIdentityConstraint->getType()) {
  280.         case IdentityConstraint::UNIQUE:
  281.             {
  282.                 fScanner->getValidator()->emitError(XMLValid::IC_DuplicateUnique,
  283.                     fIdentityConstraint->getElementName());
  284.                 break;
  285.             }
  286.         case IdentityConstraint::KEY:
  287.             {
  288.                 fScanner->getValidator()->emitError(XMLValid::IC_DuplicateKey,
  289.                     fIdentityConstraint->getElementName());
  290.                 break;
  291.             }
  292.         }
  293.     }
  294. }
  295. /**
  296.   * End of file ValueStore.cpp
  297.   */