Reworked int/bool attribute handling.
authorcantor <cantor@de75baf8-a10c-0410-a50a-987c0e22f00f>
Mon, 3 Jul 2006 22:15:19 +0000 (22:15 +0000)
committercantor <cantor@de75baf8-a10c-0410-a50a-987c0e22f00f>
Mon, 3 Jul 2006 22:15:19 +0000 (22:15 +0000)
git-svn-id: https://svn.middleware.georgetown.edu/cpp-xmltooling/trunk@125 de75baf8-a10c-0410-a50a-987c0e22f00f

xmltooling/base.h
xmltooling/util/XMLConstants.cpp
xmltooling/util/XMLConstants.h

index 6a5ce17..9c9cb97 100644 (file)
     public: \
         XMLTOOLING_DOXYGEN(proper attribute name) \
         static const XMLCh upcased##_ATTRIB_NAME[]; \
-        XMLTOOLING_DOXYGEN(Returns the proper attribute.) \
-        virtual int get##proper() const=0; \
+        XMLTOOLING_DOXYGEN(Returns the proper attribute after a NULL indicator.) \
+        virtual std::pair<bool,int> get##proper() const=0; \
+        XMLTOOLING_DOXYGEN(Sets the proper attribute using a string value.) \
+        virtual void set##proper(const XMLCh* proper)=0; \
         XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
         virtual void set##proper(int proper)=0
 
     public: \
         XMLTOOLING_DOXYGEN(proper attribute name) \
         static const XMLCh upcased##_ATTRIB_NAME[]; \
-        XMLTOOLING_DOXYGEN(Returns the proper attribute.) \
-        virtual bool proper() const=0; \
+        XMLTOOLING_DOXYGEN(Returns the proper attribute after a NULL indicator.) \
+        virtual std::pair<bool,bool> proper() const=0; \
+        XMLTOOLING_DOXYGEN(Sets the proper attribute using an enumerated value.) \
+        virtual void proper(xmltooling::XMLConstants::xmltooling_bool_t value)=0; \
         XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
-        virtual void proper(bool value)=0
+        void proper(bool value) { \
+            proper(value ? xmltooling::XMLConstants::XML_BOOL_ONE : xmltooling::XMLConstants::XML_BOOL_ZERO); \
+        } \
+        XMLTOOLING_DOXYGEN(Sets the proper attribute using a string constant.) \
+        void set##proper(const XMLCh* value) { \
+            if (value) { \
+                switch (*value) { \
+                    case chLatin_t: \
+                        proper(xmltooling::XMLConstants::XML_BOOL_TRUE); \
+                        break; \
+                    case chLatin_f: \
+                        proper(xmltooling::XMLConstants::XML_BOOL_FALSE); \
+                        break; \
+                    case chDigit_1: \
+                        proper(xmltooling::XMLConstants::XML_BOOL_ONE); \
+                        break; \
+                    case chDigit_0: \
+                        proper(xmltooling::XMLConstants::XML_BOOL_ZERO); \
+                        break; \
+                    default: \
+                        proper(xmltooling::XMLConstants::XML_BOOL_NULL); \
+                } \
+            } \
+            else \
+                proper(xmltooling::XMLConstants::XML_BOOL_NULL); \
+        }
 
 /**
  * Implements get/set methods and a private member for a typed XML attribute.
  */
 #define IMPL_INTEGER_ATTRIB(proper) \
     protected: \
-        int m_##proper; \
+        XMLCh* m_##proper; \
     public: \
-        int get##proper() const { \
-            return m_##proper; \
+        pair<bool,int> get##proper() const { \
+            return make_pair((m_##proper!=NULL),XMLString::parseInt(m_##proper)); \
+        } \
+        void set##proper(const XMLCh* proper) { \
+            m_##proper = prepareForAssignment(m_##proper,proper); \
         } \
         void set##proper(int proper) { \
-            if (m_##proper != proper) { \
-                releaseThisandParentDOM(); \
-                m_##proper = proper; \
-            } \
+            char buf##proper[64]; \
+            sprintf(buf##proper,"%d",proper); \
+            auto_ptr_XMLCh wide##proper(buf##proper); \
+            set##proper(wide##proper.get()); \
         }
 
 /**
  */
 #define IMPL_BOOLEAN_ATTRIB(proper) \
     protected: \
-        bool m_##proper; \
+        XMLConstants::xmltooling_bool_t m_##proper; \
     public: \
-        bool proper() const { \
-            return m_##proper; \
+        pair<bool,bool> proper() const { \
+            return make_pair( \
+                (m_##proper!=XMLConstants::XML_BOOL_NULL), \
+                (m_##proper==XMLConstants::XML_BOOL_TRUE || m_##proper==XMLConstants::XML_BOOL_ONE) \
+                ); \
         } \
-        void proper(bool value) { \
+        void proper(XMLConstants::xmltooling_bool_t value) { \
             if (m_##proper != value) { \
                 releaseThisandParentDOM(); \
                 m_##proper = value; \
  * @param namespaceURI  the XML namespace of the attribute
  */
 #define MARSHALL_STRING_ATTRIB(proper,ucase,namespaceURI) \
-    if(get##proper()) { \
-        domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, get##proper()); \
+    if (m_##proper) { \
+        domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper); \
     }
 
 /**
  * @param namespaceURI  the XML namespace of the attribute
  */
 #define MARSHALL_DATETIME_ATTRIB(proper,ucase,namespaceURI) \
-    if(get##proper()) { \
-        domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, get##proper()->getRawData()); \
+    if (m_##proper) { \
+        domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper->getRawData()); \
     }
 
 /**
  * @param namespaceURI  the XML namespace of the attribute
  */
 #define MARSHALL_INTEGER_ATTRIB(proper,ucase,namespaceURI) \
-    char buf##proper[64]; \
-    sprintf(buf##proper,"%d",get##proper()); \
-    auto_ptr_XMLCh wide##proper(buf##proper); \
-    domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, wide##proper.get())
+    if (m_##proper) { \
+        domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper); \
+    }
 
 /**
  * Implements marshalling for a boolean attribute
  * @param namespaceURI  the XML namespace of the attribute
  */
 #define MARSHALL_BOOLEAN_ATTRIB(proper,ucase,namespaceURI) \
-    XMLCh flag##proper[2]; \
-    flag##proper[0]=m_##proper ? chDigit_1 : chDigit_0; \
-    flag##proper[1]=chNull; \
-    domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, flag##proper)
+    switch (m_##proper) { \
+        case XMLConstants::XML_BOOL_TRUE: \
+            domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, XMLConstants::XML_TRUE); \
+            break; \
+        case XMLConstants::XML_BOOL_ONE: \
+            domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, XMLConstants::XML_ONE); \
+            break; \
+        case XMLConstants::XML_BOOL_FALSE: \
+            domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, XMLConstants::XML_FALSE); \
+            break; \
+        case XMLConstants::XML_BOOL_ZERO: \
+            domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, XMLConstants::XML_ZERO); \
+            break; \
+    }
 
 /**
  * Implements marshalling for a QName attribute
  * @param namespaceURI  the XML namespace of the attribute
  */
 #define MARSHALL_QNAME_ATTRIB(proper,ucase,namespaceURI) \
-    if(get##proper()) { \
-        auto_ptr_XMLCh qstr(get##proper()->toString().c_str()); \
+    if (m_##proper) { \
+        auto_ptr_XMLCh qstr(m_##proper->toString().c_str()); \
         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, qstr.get()); \
     }
 
  * @param namespaceURI  the XML namespace of the attribute
  */
 #define MARSHALL_ID_ATTRIB(proper,ucase,namespaceURI) \
-    if(get##proper()) { \
-        domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, get##proper()); \
+    if (m_##proper) { \
+        domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper); \
         domElement->setIdAttributeNS(namespaceURI, ucase##_ATTRIB_NAME); \
     }
 
  * @param namespaceURI  the XML namespace of the attribute
  */
 #define PROC_INTEGER_ATTRIB(proper,ucase,namespaceURI) \
-    if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
-        set##proper(XMLString::parseInt(attribute->getValue())); \
-        return; \
-    }
+    PROC_STRING_ATTRIB(proper,ucase,namespaceURI)
 
 /**
  * Implements unmarshalling process branch for a boolean attribute
  * @param namespaceURI  the XML namespace of the attribute
  */
 #define PROC_BOOLEAN_ATTRIB(proper,ucase,namespaceURI) \
-    if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
-        const XMLCh* value=attribute->getValue(); \
-        if (value) { \
-            if (*value==chLatin_t || *value==chDigit_1) \
-                m_##proper=true; \
-            else if (*value==chLatin_f || *value==chDigit_0) \
-                m_##proper=false; \
-        } \
-        return; \
-    }
+    PROC_STRING_ATTRIB(proper,ucase,namespaceURI)
 
 /**
  * Implements unmarshalling process branch for typed child collection element
  * @param proper    the proper name to label the element's content
  */
 #define DECL_INTEGER_CONTENT(proper) \
-    XMLTOOLING_DOXYGEN(Returns proper.) \
-    int get##proper() const { \
-        return XMLString::parseInt(getTextContent()); \
+    XMLTOOLING_DOXYGEN(Returns proper in integer form after a NULL indicator.) \
+    std::pair<bool,int> get##proper() const { \
+        return std::make_pair((getTextContent()!=NULL), XMLString::parseInt(getTextContent())); \
     } \
-    XMLTOOLING_DOXYGEN(Sets or clears proper.) \
+    XMLTOOLING_DOXYGEN(Sets proper.) \
     void set##proper(int proper) { \
         char buf[64]; \
         sprintf(buf,"%d",proper); \
         xmltooling::auto_ptr_XMLCh widebuf(buf); \
         setTextContent(widebuf.get()); \
+    } \
+    XMLTOOLING_DOXYGEN(Sets or clears proper.) \
+    void set##proper(const XMLCh* proper) { \
+        setTextContent(proper); \
     }
 
 /**
         throw xmltooling::ValidationException(#cname" must have "#proper".")
 
 /**
+ * Validator code that checks for a required integer attribute
+ * 
+ * @param cname     the name of the XMLObject specialization
+ * @param proper    the proper name of the attribute, content, or singleton member 
+ */
+#define XMLOBJECTVALIDATOR_REQUIRE_INTEGER(cname,proper) \
+    if (!ptr->get##proper().first) \
+        throw xmltooling::ValidationException(#cname" must have "#proper".")
+
+/**
  * Validator code that checks for one of a pair of
  * required attributes, content, or singletons.
  * 
index a5974b9..847acb6 100644 (file)
@@ -25,7 +25,6 @@
 #include "util/XMLConstants.h"\r
 #include <xercesc/util/XMLUniDefs.hpp>\r
 \r
-using namespace xercesc;\r
 using namespace xmltooling;\r
     \r
 const XMLCh XMLConstants::XML_NS[] = // http://www.w3.org/XML/1998/namespace\r
@@ -90,3 +89,11 @@ const XMLCh XMLConstants::XMLTOOLING_NS[] = // http://www.opensaml.org/xmltoolin
   chLatin_o, chLatin_r, chLatin_g, chForwardSlash,\r
   chLatin_x, chLatin_m, chLatin_l, chLatin_t, chLatin_o, chLatin_o, chLatin_l, chLatin_i, chLatin_n, chLatin_g, chNull\r
 };\r
+\r
+const XMLCh XMLConstants::XML_TRUE[] = { chLatin_t, chLatin_r, chLatin_u, chLatin_e, chNull };\r
+\r
+const XMLCh XMLConstants::XML_FALSE[] = { chLatin_f, chLatin_a, chLatin_l, chLatin_s, chLatin_e, chNull };\r
+\r
+const XMLCh XMLConstants::XML_ONE[] = { chDigit_1, chNull };\r
+\r
+const XMLCh XMLConstants::XML_ZERO[] = { chDigit_0, chNull };\r
index 1faf640..028c4b3 100644 (file)
@@ -70,6 +70,27 @@ namespace xmltooling {
         \r
         /**  XML Tooling namespace ("http://www.opensaml.org/xmltooling") */\r
         static const XMLCh XMLTOOLING_NS[];\r
+\r
+        /**  XML "true" boolean constant */\r
+        static const XMLCh XML_TRUE[];\r
+\r
+        /**  XML "false" boolean constant */\r
+        static const XMLCh XML_FALSE[];\r
+\r
+        /**  XML "1" boolean constant */\r
+        static const XMLCh XML_ONE[];\r
+\r
+        /**  XML "0" boolean constant */\r
+        static const XMLCh XML_ZERO[];\r
+        \r
+        /** Enumerations of the different values of a boolean attribute or element */\r
+        enum xmltooling_bool_t {\r
+            XML_BOOL_NULL,\r
+            XML_BOOL_TRUE,\r
+            XML_BOOL_FALSE,\r
+            XML_BOOL_ONE,\r
+            XML_BOOL_ZERO\r
+        };\r
     };\r
 \r
 };\r