text: /*
   * 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.
   */
  
  #include "DOMConfigurationImpl.hpp"
  #include "DOMStringListImpl.hpp"
  #include <xercesc/dom/DOMErrorHandler.hpp>
  #include <xercesc/util/XMLString.hpp>
  #include <xercesc/util/XMLUniDefs.hpp>
  #include <xercesc/dom/DOMException.hpp>
  
  namespace XERCES_CPP_NAMESPACE {
  
  const unsigned short DOMConfigurationImpl::fDEFAULT_VALUES = 0x2596;
  
  DOMConfigurationImpl::DOMConfigurationImpl(MemoryManager* const manager): featureValues(fDEFAULT_VALUES),
                                                fErrorHandler(0), fSchemaType(0), fSchemaLocation(0),
                                                fSupportedParameters(0), fMemoryManager(manager)
  {
      fSupportedParameters=new (fMemoryManager) DOMStringListImpl(17, fMemoryManager);
      fSupportedParameters->add(XMLUni::fgDOMErrorHandler);
      fSupportedParameters->add(XMLUni::fgDOMSchemaType);
      fSupportedParameters->add(XMLUni::fgDOMSchemaLocation);
      fSupportedParameters->add(XMLUni::fgDOMCanonicalForm);
      fSupportedParameters->add(XMLUni::fgDOMCDATASections);
      fSupportedParameters->add(XMLUni::fgDOMComments);
      fSupportedParameters->add(XMLUni::fgDOMDatatypeNormalization);
      fSupportedParameters->add(XMLUni::fgDOMWRTDiscardDefaultContent);
      fSupportedParameters->add(XMLUni::fgDOMEntities);
      fSupportedParameters->add(XMLUni::fgDOMInfoset);
      fSupportedParameters->add(XMLUni::fgDOMNamespaces);
      fSupportedParameters->add(XMLUni::fgDOMNamespaceDeclarations);
      fSupportedParameters->add(XMLUni::fgDOMNormalizeCharacters);
      fSupportedParameters->add(XMLUni::fgDOMSplitCDATASections);
      fSupportedParameters->add(XMLUni::fgDOMValidate);
      fSupportedParameters->add(XMLUni::fgDOMValidateIfSchema);
      fSupportedParameters->add(XMLUni::fgDOMElementContentWhitespace);
  }
  
  DOMConfigurationImpl::~DOMConfigurationImpl() {
      delete fSupportedParameters;
  }
                                          
  void DOMConfigurationImpl::setParameter(const XMLCh* name, const void* value) {
      if(!canSetParameter(name, value)) {
          throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, fMemoryManager);
      }
  
      if(XMLString::compareIStringASCII(name, XMLUni::fgDOMErrorHandler)==0) {
          fErrorHandler = (DOMErrorHandler*)value;
      } else if (XMLString::compareIStringASCII(name, XMLUni::fgDOMSchemaType)==0) {
          fSchemaType = (XMLCh*)value;
      } else if (XMLString::compareIStringASCII(name, XMLUni::fgDOMSchemaLocation)==0) {
          fSchemaLocation = (XMLCh*)value;
      } else {  // canSetParameter above should take care of this case
          throw DOMException(DOMException::NOT_FOUND_ERR, 0, fMemoryManager);
      }
  
  }
  
  void DOMConfigurationImpl::setParameter(const XMLCh* name, bool value) {
      if(!canSetParameter(name, value)) {
          throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, fMemoryManager);
      }
  
      DOMConfigurationFeature whichFlag = getFeatureFlag(name);
      if(value) {
          featureValues |= whichFlag;
      } else {
          featureValues &= ~whichFlag;
      }
  
  }
  
  // --------------------------------------
  // Getter Methods
  // --------------------------------------
  
  const void* DOMConfigurationImpl::getParameter(const XMLCh* name) const {
      DOMConfigurationFeature whichFlag;
      try {
          whichFlag = getFeatureFlag(name);
          if(featureValues & whichFlag) {
              return (void*)true;
          } else {
              return (void*)false;
          }
     } catch (DOMException&) {
          // must not be a boolean parameter
          if(XMLString::compareIStringASCII(name, XMLUni::fgDOMErrorHandler)==0) {
              return fErrorHandler;
          } else if (XMLString::compareIStringASCII(name, XMLUni::fgDOMSchemaType)==0) {
              return fSchemaType;
          } else if (XMLString::compareIStringASCII(name, XMLUni::fgDOMSchemaLocation)==0) {
              return fSchemaLocation;
          } else {
              throw DOMException(DOMException::NOT_FOUND_ERR, 0, fMemoryManager);
          }
      }
  
  }
  
  // -----------------------------------------
  // Query Methods
  // -----------------------------------------
  
  bool DOMConfigurationImpl::canSetParameter(const XMLCh* name, const void* /*value*/) const {
  
      /**
       * canSetParameter(name, value) returns false in two conditions:
       *  1) if a [required] feature has no supporting code, then return false in 
       *     both the true and false outcomes (This is in order to be either fully 
       *     spec compliant, or not at all)
       *  2) if an [optional] feature has no supporting code, then return false
       **/ 
      
      if(XMLString::compareIStringASCII(name, XMLUni::fgDOMErrorHandler)==0) {
          return true;                               // required //
      } else if (XMLString::compareIStringASCII(name, XMLUni::fgDOMSchemaType)==0) {
          return false;                            // optional //
      } else if (XMLString::compareIStringASCII(name, XMLUni::fgDOMSchemaLocation)==0) {
          return false;                            // optional //
      } 
      return false;
  }
  
  bool DOMConfigurationImpl::canSetParameter(const XMLCh* name, bool booleanValue) const {
      /**
       * canSetParameter(name, value) returns false in two conditions:
       *  1) if a [required] feature has no supporting code, then return false in 
       *     both the true and false outcomes (This is in order to be either fully 
       *     spec compliant, or not at all)
       *  2) if an [optional] feature has no supporting code, then return false
       **/ 
      
      DOMConfigurationFeature whichFlag = getFeatureFlag(name);
      switch (whichFlag) {
          case FEATURE_CANONICAL_FORM: 
              if(booleanValue) return false;      // optional //
              else             return true;       // required // 
          case FEATURE_CDATA_SECTIONS: 
              return true;
          case FEATURE_COMMENTS:  
              return true;
          case FEATURE_DATATYPE_NORMALIZATION:  
              if(booleanValue) return false;       // required //
              else             return true;        // required //
          case FEATURE_DISCARD_DEFAULT_CONTENT:  
              if(booleanValue) return false;       // required //
              else             return true;        // required //
          case FEATURE_ENTITIES:  
              if(booleanValue) return true;       // required //
              else             return true;       // required //
          case FEATURE_INFOSET:  
              if(booleanValue) return false;       // required //
              else             return true;       // no effect//
          case FEATURE_NAMESPACES:  
              return true;       
          case FEATURE_NAMESPACE_DECLARATIONS:  
              if(booleanValue) return true;      // optional //
              else             return false;       // required //
          case FEATURE_NORMALIZE_CHARACTERS:  
              if(booleanValue) return false;      // optional //
              else             return true;       // required //
          case FEATURE_SPLIT_CDATA_SECTIONS:  
              //we dont report an error in the false case so we cant claim we do it
              if(booleanValue) return false;       // required //
              else             return false;       // required //
          case FEATURE_VALIDATE:  
              if(booleanValue) return false;      // optional //
              else             return true;       // required //
          case FEATURE_VALIDATE_IF_SCHEMA:  
              if(booleanValue) return false;      // optional //
              else             return true;       // required //
            
          case FEATURE_ELEMENT_CONTENT_WHITESPACE:  
              if(booleanValue) return true;       // required //
              else             return false;      // optional //
      }
  	// should never be here
      return false;
  }
  
  const DOMStringList* DOMConfigurationImpl::getParameterNames() const
  {
      return fSupportedParameters;
  }
  
  // -------------------------------------------
  // Impl methods
  // -------------------------------------------
  
  DOMConfigurationImpl::DOMConfigurationFeature DOMConfigurationImpl::getFeatureFlag(const XMLCh* name) const {
      if(XMLString::compareIStringASCII(name, XMLUni::fgDOMCanonicalForm)==0) {
          return FEATURE_CANONICAL_FORM;
      } else if (XMLString::compareIStringASCII(name, XMLUni::fgDOMCDATASections )==0) {
          return FEATURE_CDATA_SECTIONS;
      } else if (XMLString::compareIStringASCII(name, XMLUni::fgDOMComments)==0) {
          return FEATURE_COMMENTS;
      } else if (XMLString::compareIStringASCII(name, XMLUni::fgDOMDatatypeNormalization)==0)  {
          return FEATURE_DATATYPE_NORMALIZATION;
      } else if (XMLString::compareIStringASCII(name, XMLUni::fgDOMWRTDiscardDefaultContent)==0) {
          return FEATURE_DISCARD_DEFAULT_CONTENT;
      } else if (XMLString::compareIStringASCII(name, XMLUni::fgDOMEntities)==0) {
          return FEATURE_ENTITIES;
      } else if (XMLString::compareIStringASCII(name, XMLUni::fgDOMInfoset)==0)  {
          return FEATURE_INFOSET;
      } else if (XMLString::compareIStringASCII(name, XMLUni::fgDOMNamespaces)==0) {
          return FEATURE_NAMESPACES;
      } else if (XMLString::compareIStringASCII(name, XMLUni::fgDOMNamespaceDeclarations)==0) {
          return FEATURE_NAMESPACE_DECLARATIONS;
      } else if (XMLString::compareIStringASCII(name, XMLUni::fgDOMNormalizeCharacters)==0) {
          return FEATURE_NORMALIZE_CHARACTERS;
      } else if (XMLString::compareIStringASCII(name, XMLUni::fgDOMSplitCDATASections)==0) {
          return FEATURE_SPLIT_CDATA_SECTIONS;
      } else if (XMLString::compareIStringASCII(name, XMLUni::fgDOMValidate)==0) {
          return FEATURE_VALIDATE;
      } else if (XMLString::compareIStringASCII(name, XMLUni::fgDOMValidateIfSchema)==0) {
          return FEATURE_VALIDATE_IF_SCHEMA;
      } else if (XMLString::compareIStringASCII(name, XMLUni::fgDOMElementContentWhitespace)==0) {
          return FEATURE_ELEMENT_CONTENT_WHITESPACE;
      } else {
          throw DOMException(DOMException::NOT_FOUND_ERR, 0, fMemoryManager);
      }
          
  }
  
  DOMErrorHandler* DOMConfigurationImpl::getErrorHandler() const {
      return fErrorHandler;
  }
  
  const XMLCh* DOMConfigurationImpl::getSchemaType() const {
      return fSchemaType;
  }
  
  const XMLCh* DOMConfigurationImpl::getSchemaLocation() const {
      return fSchemaLocation;
  }
  
  void DOMConfigurationImpl::setErrorHandler(DOMErrorHandler *erHandler) {
      fErrorHandler = erHandler;
  }
  
  void DOMConfigurationImpl::setSchemaType(const XMLCh* st) {
      fSchemaType = st;
  }
  
  void DOMConfigurationImpl::setSchemaLocation(const XMLCh* sl) {
      fSchemaLocation = sl;
  }
  
  
  }
  
  
  /**
   * End of file DOMConfigurationImpl.cpp
   */
  