433 lines
18 KiB
C++
433 lines
18 KiB
C++
/*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership.
|
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
* (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
/*
|
|
* $Id: SchemaValidator.hpp 744929 2009-02-16 14:53:58Z borisk $
|
|
*/
|
|
|
|
#if !defined(XERCESC_INCLUDE_GUARD_SCHEMAVALIDATOR_HPP)
|
|
#define XERCESC_INCLUDE_GUARD_SCHEMAVALIDATOR_HPP
|
|
|
|
#include <xercesc/framework/XMLValidator.hpp>
|
|
#include <xercesc/framework/XMLBuffer.hpp>
|
|
#include <xercesc/util/ValueStackOf.hpp>
|
|
#include <xercesc/validators/common/ContentSpecNode.hpp>
|
|
#include <xercesc/validators/schema/SchemaGrammar.hpp>
|
|
#include <xercesc/validators/schema/XSDErrorReporter.hpp>
|
|
|
|
XERCES_CPP_NAMESPACE_BEGIN
|
|
|
|
class GrammarResolver;
|
|
class DatatypeValidator;
|
|
class SchemaElementDecl;
|
|
|
|
//
|
|
// This is a derivative of the abstract validator interface. This class
|
|
// implements a validator that supports standard XML Schema semantics.
|
|
// This class handles scanning the of the schema, and provides
|
|
// the standard validation services against the Schema info it found.
|
|
//
|
|
class VALIDATORS_EXPORT SchemaValidator : public XMLValidator
|
|
{
|
|
public:
|
|
// -----------------------------------------------------------------------
|
|
// Constructors and Destructor
|
|
// -----------------------------------------------------------------------
|
|
SchemaValidator
|
|
(
|
|
XMLErrorReporter* const errReporter = 0
|
|
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
|
|
);
|
|
virtual ~SchemaValidator();
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Implementation of the XMLValidator interface
|
|
// -----------------------------------------------------------------------
|
|
virtual bool checkContent
|
|
(
|
|
XMLElementDecl* const elemDecl
|
|
, QName** const children
|
|
, XMLSize_t childCount
|
|
, XMLSize_t* indexFailingChild
|
|
);
|
|
|
|
virtual void faultInAttr
|
|
(
|
|
XMLAttr& toFill
|
|
, const XMLAttDef& attDef
|
|
) const;
|
|
|
|
virtual void preContentValidation(bool reuseGrammar,
|
|
bool validateDefAttr = false);
|
|
|
|
virtual void postParseValidation();
|
|
|
|
virtual void reset();
|
|
|
|
virtual bool requiresNamespaces() const;
|
|
|
|
virtual void validateAttrValue
|
|
(
|
|
const XMLAttDef* attDef
|
|
, const XMLCh* const attrValue
|
|
, bool preValidation = false
|
|
, const XMLElementDecl* elemDecl = 0
|
|
);
|
|
|
|
virtual void validateElement
|
|
(
|
|
const XMLElementDecl* elemDef
|
|
);
|
|
|
|
virtual Grammar* getGrammar() const;
|
|
virtual void setGrammar(Grammar* aGrammar);
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Virtual DTD handler interface.
|
|
// -----------------------------------------------------------------------
|
|
virtual bool handlesDTD() const;
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Virtual Schema handler interface. handlesSchema() always return false.
|
|
// -----------------------------------------------------------------------
|
|
virtual bool handlesSchema() const;
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Schema Validator methods
|
|
// -----------------------------------------------------------------------
|
|
void normalizeWhiteSpace(DatatypeValidator* dV, const XMLCh* const value, XMLBuffer& toFill);
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Setter methods
|
|
// -----------------------------------------------------------------------
|
|
void setGrammarResolver(GrammarResolver* grammarResolver);
|
|
|
|
void setXsiType(const XMLCh* const prefix
|
|
, const XMLCh* const localPart
|
|
, const unsigned int uriId);
|
|
|
|
void setNillable(bool isNil);
|
|
void setErrorReporter(XMLErrorReporter* const errorReporter);
|
|
void setExitOnFirstFatal(const bool newValue);
|
|
void setDatatypeBuffer(const XMLCh* const value);
|
|
void clearDatatypeBuffer();
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Getter methods
|
|
// -----------------------------------------------------------------------
|
|
ComplexTypeInfo* getCurrentTypeInfo() const;
|
|
DatatypeValidator *getCurrentDatatypeValidator() const;
|
|
DatatypeValidator *getMostRecentAttrValidator() const;
|
|
bool getErrorOccurred() const;
|
|
bool getIsElemSpecified() const;
|
|
const XMLCh* getNormalizedValue() const;
|
|
|
|
private:
|
|
// -----------------------------------------------------------------------
|
|
// Unimplemented constructors and operators
|
|
// -----------------------------------------------------------------------
|
|
SchemaValidator(const SchemaValidator&);
|
|
SchemaValidator& operator=(const SchemaValidator&);
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Element Consitency Checking methods
|
|
// -----------------------------------------------------------------------
|
|
void checkRefElementConsistency(SchemaGrammar* const currentGrammar,
|
|
const ComplexTypeInfo* const curTypeInfo,
|
|
const XercesGroupInfo* const curGroup = 0);
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Particle Derivation Checking methods
|
|
// -----------------------------------------------------------------------
|
|
void checkParticleDerivation(SchemaGrammar* const currentGrammar,
|
|
const ComplexTypeInfo* const typeInfo);
|
|
void checkParticleDerivationOk(SchemaGrammar* const currentGrammar,
|
|
ContentSpecNode* const curNode,
|
|
const int derivedScope,
|
|
ContentSpecNode* const baseNode,
|
|
const int baseScope,
|
|
const ComplexTypeInfo* const baseInfo = 0,
|
|
const bool toCheckOccurrence = true);
|
|
ContentSpecNode* checkForPointlessOccurrences(ContentSpecNode* const specNode,
|
|
const ContentSpecNode::NodeTypes nodeType,
|
|
ValueVectorOf<ContentSpecNode*>* const nodes);
|
|
void gatherChildren(const ContentSpecNode::NodeTypes parentNodeType,
|
|
ContentSpecNode* const specNode,
|
|
ValueVectorOf<ContentSpecNode*>* const nodes);
|
|
bool isOccurrenceRangeOK(const int min1, const int max1, const int min2, const int max2);
|
|
void checkNSCompat(const ContentSpecNode* const derivedSpecNode,
|
|
const ContentSpecNode* const baseSpecNode,
|
|
const bool toCheckOccurence);
|
|
bool wildcardEltAllowsNamespace(const ContentSpecNode* const baseSpecNode,
|
|
const unsigned int derivedURI);
|
|
void checkNameAndTypeOK(SchemaGrammar* const currentGrammar,
|
|
const ContentSpecNode* const derivedSpecNode,
|
|
const int derivedScope,
|
|
const ContentSpecNode* const baseSpecNode,
|
|
const int baseScope,
|
|
const ComplexTypeInfo* const baseInfo = 0);
|
|
SchemaElementDecl* findElement(const int scope,
|
|
const unsigned int uriIndex,
|
|
const XMLCh* const name,
|
|
SchemaGrammar* const grammar,
|
|
const ComplexTypeInfo* const typeInfo = 0);
|
|
void checkICRestriction(const SchemaElementDecl* const derivedElemDecl,
|
|
const SchemaElementDecl* const baseElemDecl,
|
|
const XMLCh* const derivedElemName,
|
|
const XMLCh* const baseElemName);
|
|
void checkTypesOK(const SchemaElementDecl* const derivedElemDecl,
|
|
const SchemaElementDecl* const baseElemDecl,
|
|
const XMLCh* const derivedElemName);
|
|
void checkRecurseAsIfGroup(SchemaGrammar* const currentGrammar,
|
|
ContentSpecNode* const derivedSpecNode,
|
|
const int derivedScope,
|
|
const ContentSpecNode* const baseSpecNode,
|
|
const int baseScope,
|
|
ValueVectorOf<ContentSpecNode*>* const nodes,
|
|
const ComplexTypeInfo* const baseInfo);
|
|
void checkRecurse(SchemaGrammar* const currentGrammar,
|
|
const ContentSpecNode* const derivedSpecNode,
|
|
const int derivedScope,
|
|
ValueVectorOf<ContentSpecNode*>* const derivedNodes,
|
|
const ContentSpecNode* const baseSpecNode,
|
|
const int baseScope,
|
|
ValueVectorOf<ContentSpecNode*>* const baseNodes,
|
|
const ComplexTypeInfo* const baseInfo,
|
|
const bool toLax = false);
|
|
void checkNSSubset(const ContentSpecNode* const derivedSpecNode,
|
|
const ContentSpecNode* const baseSpecNode);
|
|
bool checkNSSubsetChoiceRoot(const ContentSpecNode* const derivedSpecNode,
|
|
const ContentSpecNode* const baseSpecNode);
|
|
bool checkNSSubsetChoice(const ContentSpecNode* const derivedSpecNode,
|
|
const ContentSpecNode* const baseSpecNode);
|
|
bool isWildCardEltSubset(const ContentSpecNode* const derivedSpecNode,
|
|
const ContentSpecNode* const baseSpecNode);
|
|
void checkNSRecurseCheckCardinality(SchemaGrammar* const currentGrammar,
|
|
const ContentSpecNode* const derivedSpecNode,
|
|
ValueVectorOf<ContentSpecNode*>* const derivedNodes,
|
|
const int derivedScope,
|
|
ContentSpecNode* const baseSpecNode,
|
|
const bool toCheckOccurence);
|
|
void checkRecurseUnordered(SchemaGrammar* const currentGrammar,
|
|
const ContentSpecNode* const derivedSpecNode,
|
|
ValueVectorOf<ContentSpecNode*>* const derivedNodes,
|
|
const int derivedScope,
|
|
ContentSpecNode* const baseSpecNode,
|
|
ValueVectorOf<ContentSpecNode*>* const baseNodes,
|
|
const int baseScope,
|
|
const ComplexTypeInfo* const baseInfo);
|
|
void checkMapAndSum(SchemaGrammar* const currentGrammar,
|
|
const ContentSpecNode* const derivedSpecNode,
|
|
ValueVectorOf<ContentSpecNode*>* const derivedNodes,
|
|
const int derivedScope,
|
|
ContentSpecNode* const baseSpecNode,
|
|
ValueVectorOf<ContentSpecNode*>* const baseNodes,
|
|
const int baseScope,
|
|
const ComplexTypeInfo* const baseInfo);
|
|
ContentSpecNode* getNonUnaryGroup(ContentSpecNode* const pNode);
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Private data members
|
|
//
|
|
// -----------------------------------------------------------------------
|
|
// The following comes from or set by the Scanner
|
|
// fSchemaGrammar
|
|
// The current schema grammar used by the validator
|
|
//
|
|
// fGrammarResolver
|
|
// All the schema grammar stored
|
|
//
|
|
// fXsiType
|
|
// Store the Schema Type Attribute Value if schema type is specified
|
|
//
|
|
// fNil
|
|
// Indicates if Nillable has been set
|
|
// -----------------------------------------------------------------------
|
|
// The following used internally in the validator
|
|
//
|
|
// fCurrentDatatypeValidator
|
|
// The validator used for validating the content of elements
|
|
// with simple types
|
|
//
|
|
// fDatatypeBuffer
|
|
// Buffer for simple type element string content
|
|
//
|
|
// fTrailing
|
|
// Previous chunk had a trailing space
|
|
//
|
|
// fSeenNonWhiteSpace
|
|
// Seen a non-whitespace character in the previous chunk
|
|
//
|
|
// fSeenId
|
|
// Indicate if an attribute of ID type has been seen already, reset per element.
|
|
//
|
|
// fSchemaErrorReporter
|
|
// Report schema process errors
|
|
//
|
|
// fTypeStack
|
|
// Stack of complex type declarations.
|
|
//
|
|
// fMostRecentAttrValidator
|
|
// DatatypeValidator that validated attribute most recently processed
|
|
//
|
|
// fErrorOccurred
|
|
// whether an error occurred in the most recent operation
|
|
// -----------------------------------------------------------------------
|
|
MemoryManager* fMemoryManager;
|
|
SchemaGrammar* fSchemaGrammar;
|
|
GrammarResolver* fGrammarResolver;
|
|
QName* fXsiType;
|
|
bool fNil;
|
|
DatatypeValidator* fCurrentDatatypeValidator;
|
|
XMLBuffer* fNotationBuf;
|
|
XMLBuffer fDatatypeBuffer;
|
|
// Only for 3.0.1.
|
|
//
|
|
union
|
|
{
|
|
bool old;
|
|
unsigned char flags; // fTrailing - big 0; fSeenNonWhiteSpace - bit 1
|
|
} fTrailingSeenNonWhiteSpace;
|
|
bool fSeenId;
|
|
XSDErrorReporter fSchemaErrorReporter;
|
|
ValueStackOf<ComplexTypeInfo*>* fTypeStack;
|
|
DatatypeValidator * fMostRecentAttrValidator;
|
|
bool fErrorOccurred;
|
|
bool fElemIsSpecified;
|
|
};
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// SchemaValidator: Setter methods
|
|
// ---------------------------------------------------------------------------
|
|
inline void SchemaValidator::setGrammarResolver(GrammarResolver* grammarResolver) {
|
|
fGrammarResolver = grammarResolver;
|
|
}
|
|
|
|
inline void SchemaValidator::setXsiType(const XMLCh* const prefix
|
|
, const XMLCh* const localPart
|
|
, const unsigned int uriId)
|
|
{
|
|
delete fXsiType;
|
|
fXsiType = new (fMemoryManager) QName(prefix, localPart, uriId, fMemoryManager);
|
|
}
|
|
|
|
inline void SchemaValidator::setNillable(bool isNil) {
|
|
fNil = isNil;
|
|
}
|
|
|
|
inline void SchemaValidator::setExitOnFirstFatal(const bool newValue) {
|
|
|
|
fSchemaErrorReporter.setExitOnFirstFatal(newValue);
|
|
}
|
|
|
|
inline void SchemaValidator::setDatatypeBuffer(const XMLCh* const value)
|
|
{
|
|
fDatatypeBuffer.append(value);
|
|
}
|
|
|
|
inline void SchemaValidator::clearDatatypeBuffer()
|
|
{
|
|
fDatatypeBuffer.reset();
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// SchemaValidator: Getter methods
|
|
// ---------------------------------------------------------------------------
|
|
inline ComplexTypeInfo* SchemaValidator::getCurrentTypeInfo() const {
|
|
if (fTypeStack->empty())
|
|
return 0;
|
|
return fTypeStack->peek();
|
|
}
|
|
|
|
inline DatatypeValidator * SchemaValidator::getCurrentDatatypeValidator() const
|
|
{
|
|
return fCurrentDatatypeValidator;
|
|
}
|
|
inline DatatypeValidator *SchemaValidator::getMostRecentAttrValidator() const
|
|
{
|
|
return fMostRecentAttrValidator;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Virtual interface
|
|
// ---------------------------------------------------------------------------
|
|
inline Grammar* SchemaValidator::getGrammar() const {
|
|
return fSchemaGrammar;
|
|
}
|
|
|
|
inline void SchemaValidator::setGrammar(Grammar* aGrammar) {
|
|
fSchemaGrammar = (SchemaGrammar*) aGrammar;
|
|
}
|
|
|
|
inline void SchemaValidator::setErrorReporter(XMLErrorReporter* const errorReporter) {
|
|
|
|
XMLValidator::setErrorReporter(errorReporter);
|
|
fSchemaErrorReporter.setErrorReporter(errorReporter);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// SchemaValidator: DTD handler interface
|
|
// ---------------------------------------------------------------------------
|
|
inline bool SchemaValidator::handlesDTD() const
|
|
{
|
|
// No DTD scanning
|
|
return false;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// SchemaValidator: Schema handler interface
|
|
// ---------------------------------------------------------------------------
|
|
inline bool SchemaValidator::handlesSchema() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// SchemaValidator: Particle derivation checking
|
|
// ---------------------------------------------------------------------------
|
|
inline bool
|
|
SchemaValidator::isOccurrenceRangeOK(const int min1, const int max1,
|
|
const int min2, const int max2) {
|
|
|
|
if (min1 >= min2 &&
|
|
(max2 == SchemaSymbols::XSD_UNBOUNDED ||
|
|
(max1 != SchemaSymbols::XSD_UNBOUNDED && max1 <= max2))) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
inline bool SchemaValidator::getErrorOccurred() const
|
|
{
|
|
return fErrorOccurred;
|
|
}
|
|
|
|
inline bool SchemaValidator::getIsElemSpecified() const
|
|
{
|
|
return fElemIsSpecified;
|
|
}
|
|
|
|
inline const XMLCh* SchemaValidator::getNormalizedValue() const
|
|
{
|
|
return fDatatypeBuffer.getRawBuffer();
|
|
}
|
|
|
|
XERCES_CPP_NAMESPACE_END
|
|
|
|
#endif
|