Added some validation code.
[shibboleth/xmltooling.git] / xmltooling / signature / impl / KeyInfoImpl.cpp
1 /*\r
2 *  Copyright 2001-2006 Internet2\r
3  * \r
4 * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *     http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 /**\r
18  * XMLSecSignatureImpl.cpp\r
19  * \r
20  * Signature class for XMLSec-based signature-handling\r
21  */\r
22 \r
23 #include "internal.h"\r
24 #include "AbstractElementProxy.h"\r
25 #include "exceptions.h"\r
26 #include "io/AbstractXMLObjectMarshaller.h"\r
27 #include "io/AbstractXMLObjectUnmarshaller.h"\r
28 #include "signature/impl/KeyInfoImpl.h"\r
29 #include "util/XMLHelper.h"\r
30 #include "validation/AbstractValidatingXMLObject.h"\r
31 \r
32 #include <typeinfo.h>\r
33 \r
34 using namespace xmltooling;\r
35 using namespace std;\r
36 \r
37 #if defined (_MSC_VER)\r
38     #pragma warning( push )\r
39     #pragma warning( disable : 4250 4251 )\r
40 #endif\r
41 \r
42 namespace xmltooling {\r
43     \r
44     class XMLTOOL_DLLLOCAL KeyInfoImpl\r
45         : public KeyInfo,\r
46             public AbstractDOMCachingXMLObject,\r
47             public AbstractElementProxy,\r
48             public AbstractValidatingXMLObject,\r
49             public AbstractXMLObjectMarshaller,\r
50             public AbstractXMLObjectUnmarshaller\r
51     {\r
52     public:\r
53         virtual ~KeyInfoImpl() {}\r
54 \r
55         KeyInfoImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)\r
56             : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_Id(NULL) {\r
57         }\r
58             \r
59         KeyInfoImpl(const KeyInfoImpl& src)\r
60             : AbstractXMLObject(src),\r
61                 AbstractDOMCachingXMLObject(src),\r
62                 AbstractElementProxy(src),\r
63                 AbstractValidatingXMLObject(src),\r
64                 m_Id(XMLString::replicate(src.m_Id)) {\r
65                     \r
66             for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {\r
67                 getXMLObjects().push_back((*i) ? (*i)->clone() : NULL);\r
68             }\r
69         }\r
70         \r
71         IMPL_XMLOBJECT_CLONE(KeyInfo);\r
72         IMPL_XMLOBJECT_ATTRIB(Id);\r
73 \r
74     protected:\r
75         void marshallAttributes(DOMElement* domElement) const {\r
76             if(getId()) {\r
77                 domElement->setAttributeNS(NULL, ID_ATTRIB_NAME, getId());\r
78                 domElement->setIdAttributeNS(NULL, ID_ATTRIB_NAME);\r
79             }\r
80         }\r
81 \r
82         void marshallElementContent(DOMElement* domElement) const {\r
83             if(getTextContent()) {\r
84                 domElement->appendChild(domElement->getOwnerDocument()->createTextNode(getTextContent()));\r
85             }\r
86         }\r
87 \r
88         void processElementContent(const XMLCh* elementContent) {\r
89             setTextContent(elementContent);\r
90         }\r
91 \r
92         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {\r
93             getXMLObjects().push_back(childXMLObject);\r
94         }\r
95 \r
96         void processAttribute(const DOMAttr* attribute) {\r
97             if (XMLHelper::isNodeNamed(attribute, NULL, ID_ATTRIB_NAME)) {\r
98                 setId(attribute->getValue());\r
99                 static_cast<DOMElement*>(attribute->getParentNode())->setIdAttributeNode(attribute);\r
100             }\r
101         }\r
102     };\r
103     \r
104     class XMLTOOL_DLLLOCAL KeyNameImpl\r
105         : public KeyName,\r
106             public AbstractDOMCachingXMLObject,\r
107             public AbstractValidatingXMLObject,\r
108             public AbstractXMLObjectMarshaller,\r
109             public AbstractXMLObjectUnmarshaller\r
110     {\r
111     public:\r
112         virtual ~KeyNameImpl() {}\r
113 \r
114         KeyNameImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)\r
115             : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_Name(NULL) {\r
116         }\r
117             \r
118         KeyNameImpl(const KeyNameImpl& src)\r
119             : AbstractXMLObject(src),\r
120                 AbstractDOMCachingXMLObject(src),\r
121                 AbstractValidatingXMLObject(src),\r
122                 m_Name(XMLString::replicate(src.m_Name)) {\r
123         }\r
124         \r
125         IMPL_XMLOBJECT_CLONE(KeyName);\r
126         IMPL_XMLOBJECT_CONTENT(Name);\r
127     };\r
128 \r
129     class XMLTOOL_DLLLOCAL MgmtDataImpl\r
130         : public MgmtData,\r
131             public AbstractDOMCachingXMLObject,\r
132             public AbstractValidatingXMLObject,\r
133             public AbstractXMLObjectMarshaller,\r
134             public AbstractXMLObjectUnmarshaller\r
135     {\r
136     public:\r
137         virtual ~MgmtDataImpl() {}\r
138 \r
139         MgmtDataImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)\r
140             : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_Data(NULL) {\r
141         }\r
142             \r
143         MgmtDataImpl(const MgmtDataImpl& src)\r
144             : AbstractXMLObject(src),\r
145                 AbstractDOMCachingXMLObject(src),\r
146                 AbstractValidatingXMLObject(src),\r
147                 m_Data(XMLString::replicate(src.m_Data)) {\r
148         }\r
149         \r
150         IMPL_XMLOBJECT_CLONE(MgmtData);\r
151         IMPL_XMLOBJECT_CONTENT(Data);\r
152     };\r
153 };\r
154 \r
155 #if defined (_MSC_VER)\r
156     #pragma warning( pop )\r
157 #endif\r
158 \r
159 // Builder Implementations\r
160 \r
161 IMPL_XMLOBJECTBUILDER(KeyInfo);\r
162 IMPL_XMLOBJECTBUILDER(KeyName);\r
163 IMPL_XMLOBJECTBUILDER(MgmtData);\r
164 \r
165 // Validators\r
166 \r
167 void KeyInfoSchemaValidator::validate(const XMLObject* xmlObject) const\r
168 {\r
169     const KeyInfo* ptr=dynamic_cast<const KeyInfo*>(xmlObject);\r
170     if (!ptr)\r
171         throw ValidationException("KeyInfoSchemaValidator: unsupported object type ($1)",params(1,typeid(xmlObject).name()));\r
172     if (!ptr->hasChildren())\r
173         throw ValidationException("KeyInfo is empty");\r
174 }\r
175 \r
176 void KeyNameSchemaValidator::validate(const XMLObject* xmlObject) const\r
177 {\r
178     const KeyName* ptr=dynamic_cast<const KeyName*>(xmlObject);\r
179     if (!ptr)\r
180         throw ValidationException("KeyNameSchemaValidator: unsupported object type ($1)",params(1,typeid(xmlObject).name()));\r
181     if (XMLString::stringLen(ptr->getName())==0)\r
182         throw ValidationException("KeyName is empty");\r
183 }\r
184 \r
185 void MgmtDataSchemaValidator::validate(const XMLObject* xmlObject) const\r
186 {\r
187     const MgmtData* ptr=dynamic_cast<const MgmtData*>(xmlObject);\r
188     if (!ptr)\r
189         throw ValidationException("MgmtDataSchemaValidator: unsupported object type ($1)",params(1,typeid(xmlObject).name()));\r
190     if (XMLString::stringLen(ptr->getData())==0)\r
191         throw ValidationException("MgmtData is empty");\r
192 }\r