2 * Copyright 2001-2010 Internet2
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 * DOM-based property set implementation.
24 #include "util/DOMPropertySet.h"
27 #include <xmltooling/util/NDC.h>
28 #include <xmltooling/util/XMLConstants.h>
30 using namespace shibsp;
31 using namespace xmltooling;
32 using namespace xercesc;
35 PropertySet::PropertySet()
39 PropertySet::~PropertySet()
43 DOMPropertySet::DOMPropertySet() : m_parent(nullptr), m_root(nullptr)
47 DOMPropertySet::~DOMPropertySet()
49 for (map<string,pair<char*,const XMLCh*> >::iterator i=m_map.begin(); i!=m_map.end(); i++)
50 XMLString::release(&(i->second.first));
51 for_each(m_nested.begin(),m_nested.end(),cleanup_pair<string,DOMPropertySet>());
54 const PropertySet* DOMPropertySet::getParent() const
59 void DOMPropertySet::setParent(const PropertySet* parent)
64 const DOMElement* DOMPropertySet::getElement() const
69 void DOMPropertySet::load(
72 DOMNodeFilter* filter,
73 const std::map<std::string,std::string>* remapper
83 log = &Category::getInstance(SHIBSP_LOGCAT".PropertySet");
85 // Process each attribute as a property.
86 DOMNamedNodeMap* attrs=m_root->getAttributes();
87 for (XMLSize_t i=0; i<attrs->getLength(); i++) {
88 DOMNode* a=attrs->item(i);
89 if (!XMLString::compareString(a->getNamespaceURI(),xmlconstants::XMLNS_NS))
91 char* val=XMLString::transcode(a->getNodeValue());
93 auto_ptr_char ns(a->getNamespaceURI());
94 auto_ptr_char name(a->getLocalName());
95 const char* realname=name.get();
96 map<string,string>::const_iterator remap;
98 remap=remapper->find(realname);
99 if (remap!=remapper->end()) {
100 log->warn("deprecation - remapping property (%s) to (%s)",realname,remap->second.c_str());
101 realname=remap->second.c_str();
105 if (remapper && (remap=remapper->find(ns.get()))!=remapper->end())
106 m_map[string("{") + remap->second.c_str() + '}' + realname]=pair<char*,const XMLCh*>(val,a->getNodeValue());
108 m_map[string("{") + ns.get() + '}' + realname]=pair<char*,const XMLCh*>(val,a->getNodeValue());
109 log->debug("added property {%s}%s (%s)",ns.get(),realname,val);
112 m_map[realname]=pair<char*,const XMLCh*>(val,a->getNodeValue());
113 log->debug("added property %s (%s)",realname,val);
118 // Process non-excluded elements as nested sets.
119 DOMTreeWalker* walker=
120 static_cast<DOMDocumentTraversal*>(
121 m_root->getOwnerDocument())->createTreeWalker(const_cast<DOMElement*>(m_root),DOMNodeFilter::SHOW_ELEMENT,filter,false
123 e=static_cast<DOMElement*>(walker->firstChild());
125 auto_ptr_char ns(e->getNamespaceURI());
126 auto_ptr_char name(e->getLocalName());
127 const char* realname=name.get();
128 map<string,string>::const_iterator remap;
130 remap=remapper->find(realname);
131 if (remap!=remapper->end()) {
132 log->warn("deprecation - remapping nested property set (%s) to (%s)",realname,remap->second.c_str());
133 realname=remap->second.c_str();
138 if (remapper && (remap=remapper->find(ns.get()))!=remapper->end())
139 key=string("{") + remap->second.c_str() + '}' + realname;
141 key=string("{") + ns.get() + '}' + realname;
145 if (m_nested.find(key)!=m_nested.end())
146 log->warn("load() skipping duplicate property set: %s",key.c_str());
148 DOMPropertySet* set=new DOMPropertySet();
149 set->load(e,log,filter,remapper);
151 log->debug("added nested property set: %s",key.c_str());
153 e=static_cast<DOMElement*>(walker->nextSibling());
158 pair<bool,bool> DOMPropertySet::getBool(const char* name, const char* ns) const
160 map<string,pair<char*,const XMLCh*> >::const_iterator i;
163 i=m_map.find(string("{") + ns + '}' + name);
168 return make_pair(true,(!strcmp(i->second.first,"true") || !strcmp(i->second.first,"1")));
170 return m_parent->getBool(name,ns);
171 return make_pair(false,false);
174 pair<bool,const char*> DOMPropertySet::getString(const char* name, const char* ns) const
176 pair<bool,const char*> ret(false,nullptr);
177 map<string,pair<char*,const XMLCh*> >::const_iterator i;
180 i=m_map.find(string("{") + ns + '}' + name);
185 return pair<bool,const char*>(true,i->second.first);
187 return m_parent->getString(name,ns);
188 return pair<bool,const char*>(false,nullptr);
191 pair<bool,const XMLCh*> DOMPropertySet::getXMLString(const char* name, const char* ns) const
193 map<string,pair<char*,const XMLCh*> >::const_iterator i;
196 i=m_map.find(string("{") + ns + '}' + name);
201 return make_pair(true,i->second.second);
203 return m_parent->getXMLString(name,ns);
204 return pair<bool,const XMLCh*>(false,nullptr);
207 pair<bool,unsigned int> DOMPropertySet::getUnsignedInt(const char* name, const char* ns) const
209 map<string,pair<char*,const XMLCh*> >::const_iterator i;
212 i=m_map.find(string("{") + ns + '}' + name);
217 return pair<bool,unsigned int>(true,strtol(i->second.first,nullptr,10));
219 return m_parent->getUnsignedInt(name,ns);
220 return pair<bool,unsigned int>(false,0);
223 pair<bool,int> DOMPropertySet::getInt(const char* name, const char* ns) const
225 map<string,pair<char*,const XMLCh*> >::const_iterator i;
228 i=m_map.find(string("{") + ns + '}' + name);
233 return pair<bool,int>(true,atoi(i->second.first));
235 return m_parent->getInt(name,ns);
236 return pair<bool,int>(false,0);
239 void DOMPropertySet::getAll(std::map<std::string,const char*>& properties) const
242 m_parent->getAll(properties);
243 for (map< string,pair<char*,const XMLCh*> >::const_iterator i = m_map.begin(); i != m_map.end(); ++i)
244 properties[i->first] = i->second.first;
247 const PropertySet* DOMPropertySet::getPropertySet(const char* name, const char* ns) const
249 map<string,DOMPropertySet*>::const_iterator i;
252 i=m_nested.find(string("{") + ns + '}' + name);
254 i=m_nested.find(name);
256 return (i!=m_nested.end()) ? i->second : (m_parent ? m_parent->getPropertySet(name,ns) : nullptr);