xref: /aoo41x/main/unoxml/source/dom/element.cxx (revision b862c97c)
1e9cbe144SAndrew Rist /**************************************************************
2e9cbe144SAndrew Rist  *
3e9cbe144SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4e9cbe144SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5e9cbe144SAndrew Rist  * distributed with this work for additional information
6e9cbe144SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7e9cbe144SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8e9cbe144SAndrew Rist  * "License"); you may not use this file except in compliance
9e9cbe144SAndrew Rist  * with the License.  You may obtain a copy of the License at
10e9cbe144SAndrew Rist  *
11e9cbe144SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12e9cbe144SAndrew Rist  *
13e9cbe144SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14e9cbe144SAndrew Rist  * software distributed under the License is distributed on an
15e9cbe144SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16e9cbe144SAndrew Rist  * KIND, either express or implied.  See the License for the
17e9cbe144SAndrew Rist  * specific language governing permissions and limitations
18e9cbe144SAndrew Rist  * under the License.
19e9cbe144SAndrew Rist  *
20e9cbe144SAndrew Rist  *************************************************************/
21e9cbe144SAndrew Rist 
22e9cbe144SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include <element.hxx>
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include <string.h>
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include <boost/shared_ptr.hpp>
29cdf0e10cSrcweir 
30cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include <com/sun/star/xml/sax/FastToken.hdl>
33cdf0e10cSrcweir 
34cdf0e10cSrcweir #include <comphelper/attributelist.hxx>
35cdf0e10cSrcweir 
36cdf0e10cSrcweir #include <node.hxx>
37cdf0e10cSrcweir #include <attr.hxx>
38cdf0e10cSrcweir #include <elementlist.hxx>
39cdf0e10cSrcweir #include <attributesmap.hxx>
40cdf0e10cSrcweir #include <document.hxx>
41cdf0e10cSrcweir 
42cdf0e10cSrcweir #include "../events/mutationevent.hxx"
43cdf0e10cSrcweir 
44cdf0e10cSrcweir 
45cdf0e10cSrcweir namespace DOM
46cdf0e10cSrcweir {
47cdf0e10cSrcweir 
CElement(CDocument const & rDocument,::osl::Mutex const & rMutex,xmlNodePtr const pNode)48cdf0e10cSrcweir     CElement::CElement(CDocument const& rDocument, ::osl::Mutex const& rMutex,
49cdf0e10cSrcweir             xmlNodePtr const pNode)
50cdf0e10cSrcweir         : CElement_Base(rDocument, rMutex, NodeType_ELEMENT_NODE, pNode)
51cdf0e10cSrcweir     {
52cdf0e10cSrcweir     }
53cdf0e10cSrcweir 
saxify(const Reference<XDocumentHandler> & i_xHandler)54cdf0e10cSrcweir     void CElement::saxify(const Reference< XDocumentHandler >& i_xHandler)
55cdf0e10cSrcweir     {
56cdf0e10cSrcweir         if (!i_xHandler.is()) throw RuntimeException();
57cdf0e10cSrcweir         comphelper::AttributeList *pAttrs =
58cdf0e10cSrcweir             new comphelper::AttributeList();
59cdf0e10cSrcweir         OUString type = OUString::createFromAscii("");
60cdf0e10cSrcweir         // add namespace definitions to attributes
61cdf0e10cSrcweir         for (xmlNsPtr pNs = m_aNodePtr->nsDef; pNs != 0; pNs = pNs->next) {
62cdf0e10cSrcweir             const xmlChar *pPrefix = pNs->prefix;
63cdf0e10cSrcweir             OUString prefix(reinterpret_cast<const sal_Char*>(pPrefix),
64cdf0e10cSrcweir                 strlen(reinterpret_cast<const char*>(pPrefix)),
65cdf0e10cSrcweir                 RTL_TEXTENCODING_UTF8);
66cdf0e10cSrcweir             OUString name = (prefix.equalsAscii(""))
67cdf0e10cSrcweir                 ? OUString::createFromAscii("xmlns")
68cdf0e10cSrcweir                 : OUString::createFromAscii("xmlns:") + prefix;
69cdf0e10cSrcweir             const xmlChar *pHref = pNs->href;
70cdf0e10cSrcweir             OUString val(reinterpret_cast<const sal_Char*>(pHref),
71cdf0e10cSrcweir                 strlen(reinterpret_cast<const char*>(pHref)),
72cdf0e10cSrcweir                 RTL_TEXTENCODING_UTF8);
73cdf0e10cSrcweir             pAttrs->AddAttribute(name, type, val);
74cdf0e10cSrcweir         }
75cdf0e10cSrcweir         // add attributes
76cdf0e10cSrcweir         for (xmlAttrPtr pAttr = m_aNodePtr->properties;
77cdf0e10cSrcweir                         pAttr != 0; pAttr = pAttr->next) {
78cdf0e10cSrcweir             ::rtl::Reference<CNode> const pNode = GetOwnerDocument().GetCNode(
79cdf0e10cSrcweir                     reinterpret_cast<xmlNodePtr>(pAttr));
80cdf0e10cSrcweir             OSL_ENSURE(pNode != 0, "CNode::get returned 0");
81cdf0e10cSrcweir             OUString prefix = pNode->getPrefix();
82cdf0e10cSrcweir             OUString name = (prefix.getLength() == 0)
83cdf0e10cSrcweir                 ? pNode->getLocalName()
84cdf0e10cSrcweir                 : prefix + OUString(static_cast<sal_Unicode>(':')) + pNode->getLocalName();
85cdf0e10cSrcweir             OUString val  = pNode->getNodeValue();
86cdf0e10cSrcweir             pAttrs->AddAttribute(name, type, val);
87cdf0e10cSrcweir         }
88cdf0e10cSrcweir         OUString prefix = getPrefix();
89cdf0e10cSrcweir         OUString name = (prefix.getLength() == 0)
90cdf0e10cSrcweir             ? getLocalName()
91cdf0e10cSrcweir             : prefix + OUString(static_cast<sal_Unicode>(':')) + getLocalName();
92cdf0e10cSrcweir         Reference< XAttributeList > xAttrList(pAttrs);
93cdf0e10cSrcweir         i_xHandler->startElement(name, xAttrList);
94cdf0e10cSrcweir         // recurse
95cdf0e10cSrcweir         for (xmlNodePtr pChild = m_aNodePtr->children;
96cdf0e10cSrcweir                         pChild != 0; pChild = pChild->next) {
97cdf0e10cSrcweir             ::rtl::Reference<CNode> const pNode(
98cdf0e10cSrcweir                     GetOwnerDocument().GetCNode(pChild));
99cdf0e10cSrcweir             OSL_ENSURE(pNode != 0, "CNode::get returned 0");
100cdf0e10cSrcweir             pNode->saxify(i_xHandler);
101cdf0e10cSrcweir         }
102cdf0e10cSrcweir         i_xHandler->endElement(name);
103cdf0e10cSrcweir     }
104cdf0e10cSrcweir 
fastSaxify(Context & i_rContext)105cdf0e10cSrcweir     void CElement::fastSaxify( Context& i_rContext )
106cdf0e10cSrcweir     {
107cdf0e10cSrcweir         if (!i_rContext.mxDocHandler.is()) throw RuntimeException();
108cdf0e10cSrcweir         pushContext(i_rContext);
109cdf0e10cSrcweir         addNamespaces(i_rContext,m_aNodePtr);
110cdf0e10cSrcweir 
111cdf0e10cSrcweir         // add attributes
112cdf0e10cSrcweir         i_rContext.mxAttribList->clear();
113cdf0e10cSrcweir         for (xmlAttrPtr pAttr = m_aNodePtr->properties;
114cdf0e10cSrcweir                         pAttr != 0; pAttr = pAttr->next) {
115cdf0e10cSrcweir             ::rtl::Reference<CNode> const pNode = GetOwnerDocument().GetCNode(
116cdf0e10cSrcweir                     reinterpret_cast<xmlNodePtr>(pAttr));
117cdf0e10cSrcweir             OSL_ENSURE(pNode != 0, "CNode::get returned 0");
118cdf0e10cSrcweir 
119cdf0e10cSrcweir             const xmlChar* xName = pAttr->name;
120cdf0e10cSrcweir             sal_Int32 nAttributeToken=FastToken::DONTKNOW;
121cdf0e10cSrcweir 
122cdf0e10cSrcweir             if( pAttr->ns && strlen((char*)pAttr->ns->prefix) )
123cdf0e10cSrcweir                 nAttributeToken = getTokenWithPrefix( i_rContext,
124cdf0e10cSrcweir                                                       (sal_Char*)pAttr->ns->prefix,
125cdf0e10cSrcweir                                                       (sal_Char*)xName );
126cdf0e10cSrcweir             else
127cdf0e10cSrcweir                 nAttributeToken = getToken( i_rContext, (sal_Char*)xName );
128cdf0e10cSrcweir 
129cdf0e10cSrcweir             if( nAttributeToken != FastToken::DONTKNOW )
130cdf0e10cSrcweir                 i_rContext.mxAttribList->add( nAttributeToken,
131cdf0e10cSrcweir                                               OUStringToOString(pNode->getNodeValue(),
132cdf0e10cSrcweir                                                                 RTL_TEXTENCODING_UTF8));
133cdf0e10cSrcweir         }
134cdf0e10cSrcweir 
135cdf0e10cSrcweir         const xmlChar* xPrefix = m_aNodePtr->ns ? m_aNodePtr->ns->prefix : (const xmlChar*)"";
136cdf0e10cSrcweir         const xmlChar* xName = m_aNodePtr->name;
137cdf0e10cSrcweir         sal_Int32 nElementToken=FastToken::DONTKNOW;
138cdf0e10cSrcweir         if( strlen((char*)xPrefix) )
139cdf0e10cSrcweir             nElementToken = getTokenWithPrefix( i_rContext, (sal_Char*)xPrefix, (sal_Char*)xName );
140cdf0e10cSrcweir         else
141cdf0e10cSrcweir             nElementToken = getToken( i_rContext, (sal_Char*)xName );
142cdf0e10cSrcweir 
143cdf0e10cSrcweir         Reference<XFastContextHandler> xParentHandler(i_rContext.mxCurrentHandler);
144cdf0e10cSrcweir         try
145cdf0e10cSrcweir         {
146cdf0e10cSrcweir             Reference< XFastAttributeList > xAttr( i_rContext.mxAttribList.get() );
147cdf0e10cSrcweir             if( nElementToken == FastToken::DONTKNOW )
148cdf0e10cSrcweir             {
149cdf0e10cSrcweir                 const OUString aNamespace;
150cdf0e10cSrcweir                 const OUString aElementName( (sal_Char*)xPrefix,
151cdf0e10cSrcweir                                              strlen((char*)xPrefix),
152cdf0e10cSrcweir                                              RTL_TEXTENCODING_UTF8 );
153cdf0e10cSrcweir 
154cdf0e10cSrcweir                 if( xParentHandler.is() )
155cdf0e10cSrcweir                     i_rContext.mxCurrentHandler = xParentHandler->createUnknownChildContext( aNamespace, aElementName, xAttr );
156cdf0e10cSrcweir                 else
157cdf0e10cSrcweir                     i_rContext.mxCurrentHandler = i_rContext.mxDocHandler->createUnknownChildContext( aNamespace, aElementName, xAttr );
158cdf0e10cSrcweir 
159cdf0e10cSrcweir                 if( i_rContext.mxCurrentHandler.is() )
160cdf0e10cSrcweir                     i_rContext.mxCurrentHandler->startUnknownElement( aNamespace, aElementName, xAttr );
161cdf0e10cSrcweir             }
162cdf0e10cSrcweir             else
163cdf0e10cSrcweir             {
164cdf0e10cSrcweir                 if( xParentHandler.is() )
165cdf0e10cSrcweir                     i_rContext.mxCurrentHandler = xParentHandler->createFastChildContext( nElementToken, xAttr );
166cdf0e10cSrcweir                 else
167cdf0e10cSrcweir                     i_rContext.mxCurrentHandler = i_rContext.mxDocHandler->createFastChildContext( nElementToken, xAttr );
168cdf0e10cSrcweir 
169cdf0e10cSrcweir                 if( i_rContext.mxCurrentHandler.is() )
170cdf0e10cSrcweir                     i_rContext.mxCurrentHandler->startFastElement( nElementToken, xAttr );
171cdf0e10cSrcweir             }
172cdf0e10cSrcweir         }
173cdf0e10cSrcweir         catch( Exception& )
174cdf0e10cSrcweir         {}
175cdf0e10cSrcweir 
176cdf0e10cSrcweir         // recurse
177cdf0e10cSrcweir         for (xmlNodePtr pChild = m_aNodePtr->children;
178cdf0e10cSrcweir                         pChild != 0; pChild = pChild->next) {
179cdf0e10cSrcweir             ::rtl::Reference<CNode> const pNode(
180cdf0e10cSrcweir                     GetOwnerDocument().GetCNode(pChild));
181cdf0e10cSrcweir             OSL_ENSURE(pNode != 0, "CNode::get returned 0");
182cdf0e10cSrcweir             pNode->fastSaxify(i_rContext);
183cdf0e10cSrcweir         }
184cdf0e10cSrcweir 
185cdf0e10cSrcweir 		if( i_rContext.mxCurrentHandler.is() ) try
186cdf0e10cSrcweir 		{
187cdf0e10cSrcweir 			if( nElementToken != FastToken::DONTKNOW )
188cdf0e10cSrcweir 				i_rContext.mxCurrentHandler->endFastElement( nElementToken );
189cdf0e10cSrcweir 			else
190cdf0e10cSrcweir             {
191cdf0e10cSrcweir                 const OUString aNamespace;
192cdf0e10cSrcweir                 const OUString aElementName( (sal_Char*)xPrefix,
193cdf0e10cSrcweir                                              strlen((char*)xPrefix),
194cdf0e10cSrcweir                                              RTL_TEXTENCODING_UTF8 );
195cdf0e10cSrcweir 
196cdf0e10cSrcweir 				i_rContext.mxCurrentHandler->endUnknownElement( aNamespace, aElementName );
197cdf0e10cSrcweir             }
198cdf0e10cSrcweir 		}
199cdf0e10cSrcweir 		catch( Exception& )
200cdf0e10cSrcweir 		{}
201cdf0e10cSrcweir 
202cdf0e10cSrcweir         // restore after children have been processed
203cdf0e10cSrcweir         i_rContext.mxCurrentHandler = xParentHandler;
204cdf0e10cSrcweir         popContext(i_rContext);
205cdf0e10cSrcweir     }
206cdf0e10cSrcweir 
IsChildTypeAllowed(NodeType const nodeType)207cdf0e10cSrcweir     bool CElement::IsChildTypeAllowed(NodeType const nodeType)
208cdf0e10cSrcweir     {
209cdf0e10cSrcweir         switch (nodeType) {
210cdf0e10cSrcweir             case NodeType_ELEMENT_NODE:
211cdf0e10cSrcweir             case NodeType_TEXT_NODE:
212cdf0e10cSrcweir             case NodeType_COMMENT_NODE:
213cdf0e10cSrcweir             case NodeType_PROCESSING_INSTRUCTION_NODE:
214cdf0e10cSrcweir             case NodeType_CDATA_SECTION_NODE:
215cdf0e10cSrcweir             case NodeType_ENTITY_REFERENCE_NODE:
216cdf0e10cSrcweir                 return true;
217cdf0e10cSrcweir             case NodeType_ATTRIBUTE_NODE:
218cdf0e10cSrcweir                 /* this is not relly allowed by the DOM spec, but this
219cdf0e10cSrcweir                    implementation has evidently supported it (by special case
220cdf0e10cSrcweir                    handling, so the attribute does not actually become a child)
221cdf0e10cSrcweir                    so allow it for backward compatiblity */
222cdf0e10cSrcweir                 return true;
223cdf0e10cSrcweir             default:
224cdf0e10cSrcweir                 return false;
225cdf0e10cSrcweir         }
226cdf0e10cSrcweir     }
227cdf0e10cSrcweir 
228cdf0e10cSrcweir 
229cdf0e10cSrcweir     /**
230cdf0e10cSrcweir 		Retrieves an attribute value by name.
231cdf0e10cSrcweir 		return empty string if attribute is not set
232cdf0e10cSrcweir     */
getAttribute(OUString const & name)233cdf0e10cSrcweir     OUString SAL_CALL CElement::getAttribute(OUString const& name)
234cdf0e10cSrcweir         throw (RuntimeException)
235cdf0e10cSrcweir     {
236cdf0e10cSrcweir         ::osl::MutexGuard const g(m_rMutex);
237cdf0e10cSrcweir 
238cdf0e10cSrcweir         if (0 == m_aNodePtr) {
239cdf0e10cSrcweir             return ::rtl::OUString();
240cdf0e10cSrcweir         }
241cdf0e10cSrcweir         // search properties
242cdf0e10cSrcweir         OString o1 = OUStringToOString(name, RTL_TEXTENCODING_UTF8);
243cdf0e10cSrcweir         ::boost::shared_ptr<xmlChar const> const pValue(
244cdf0e10cSrcweir             xmlGetProp(m_aNodePtr, (xmlChar*)o1.getStr()), xmlFree);
245cdf0e10cSrcweir         OUString const ret( (pValue)
246cdf0e10cSrcweir             ?   OUString(reinterpret_cast<sal_Char const*>(pValue.get()),
247cdf0e10cSrcweir                         strlen(reinterpret_cast<char const*>(pValue.get())),
248cdf0e10cSrcweir                         RTL_TEXTENCODING_UTF8)
249cdf0e10cSrcweir             :   OUString() );
250cdf0e10cSrcweir         return ret;
251cdf0e10cSrcweir     }
252cdf0e10cSrcweir 
253cdf0e10cSrcweir     /**
254cdf0e10cSrcweir     Retrieves an attribute node by name.
255cdf0e10cSrcweir     */
getAttributeNode(OUString const & name)256cdf0e10cSrcweir     Reference< XAttr > SAL_CALL CElement::getAttributeNode(OUString const& name)
257cdf0e10cSrcweir         throw (RuntimeException)
258cdf0e10cSrcweir     {
259cdf0e10cSrcweir         ::osl::MutexGuard const g(m_rMutex);
260cdf0e10cSrcweir 
261cdf0e10cSrcweir         if (0 == m_aNodePtr) {
262cdf0e10cSrcweir             return 0;
263cdf0e10cSrcweir         }
264cdf0e10cSrcweir         OString o1 = OUStringToOString(name, RTL_TEXTENCODING_UTF8);
265cdf0e10cSrcweir         xmlChar const*const pName =
266cdf0e10cSrcweir             reinterpret_cast<xmlChar const*>(o1.getStr());
267cdf0e10cSrcweir         xmlAttrPtr const pAttr = xmlHasProp(m_aNodePtr, pName);
268cdf0e10cSrcweir         if (0 == pAttr) {
269cdf0e10cSrcweir             return 0;
270cdf0e10cSrcweir         }
271cdf0e10cSrcweir         Reference< XAttr > const xRet(
272cdf0e10cSrcweir             static_cast< XNode* >(GetOwnerDocument().GetCNode(
273cdf0e10cSrcweir                     reinterpret_cast<xmlNodePtr>(pAttr)).get()),
274cdf0e10cSrcweir             UNO_QUERY_THROW);
275cdf0e10cSrcweir         return xRet;
276cdf0e10cSrcweir     }
277cdf0e10cSrcweir 
278cdf0e10cSrcweir     /**
279cdf0e10cSrcweir     Retrieves an Attr node by local name and namespace URI.
280cdf0e10cSrcweir     */
getAttributeNodeNS(const OUString & namespaceURI,const OUString & localName)281cdf0e10cSrcweir     Reference< XAttr > SAL_CALL CElement::getAttributeNodeNS(
282cdf0e10cSrcweir             const OUString& namespaceURI, const OUString& localName)
283cdf0e10cSrcweir         throw (RuntimeException)
284cdf0e10cSrcweir     {
285cdf0e10cSrcweir         ::osl::MutexGuard const g(m_rMutex);
286cdf0e10cSrcweir 
287cdf0e10cSrcweir         if (0 == m_aNodePtr) {
288cdf0e10cSrcweir             return 0;
289cdf0e10cSrcweir         }
290cdf0e10cSrcweir         OString o1 = OUStringToOString(localName, RTL_TEXTENCODING_UTF8);
291cdf0e10cSrcweir         xmlChar const*const pName =
292cdf0e10cSrcweir             reinterpret_cast<xmlChar const*>(o1.getStr());
293cdf0e10cSrcweir         OString o2 = OUStringToOString(namespaceURI, RTL_TEXTENCODING_UTF8);
294cdf0e10cSrcweir         xmlChar const*const pNS =
295cdf0e10cSrcweir             reinterpret_cast<xmlChar const*>(o2.getStr());
296cdf0e10cSrcweir         xmlAttrPtr const pAttr = xmlHasNsProp(m_aNodePtr, pName, pNS);
297cdf0e10cSrcweir         if (0 == pAttr) {
298cdf0e10cSrcweir             return 0;
299cdf0e10cSrcweir         }
300cdf0e10cSrcweir         Reference< XAttr > const xRet(
301cdf0e10cSrcweir             static_cast< XNode* >(GetOwnerDocument().GetCNode(
302cdf0e10cSrcweir                     reinterpret_cast<xmlNodePtr>(pAttr)).get()),
303cdf0e10cSrcweir             UNO_QUERY_THROW);
304cdf0e10cSrcweir         return xRet;
305cdf0e10cSrcweir     }
306cdf0e10cSrcweir 
307cdf0e10cSrcweir     /**
308cdf0e10cSrcweir     Retrieves an attribute value by local name and namespace URI.
309cdf0e10cSrcweir 	return empty string if attribute is not set
310cdf0e10cSrcweir     */
311cdf0e10cSrcweir     OUString SAL_CALL
getAttributeNS(OUString const & namespaceURI,OUString const & localName)312cdf0e10cSrcweir     CElement::getAttributeNS(
313cdf0e10cSrcweir             OUString const& namespaceURI, OUString const& localName)
314cdf0e10cSrcweir         throw (RuntimeException)
315cdf0e10cSrcweir     {
316cdf0e10cSrcweir         ::osl::MutexGuard const g(m_rMutex);
317cdf0e10cSrcweir 
318cdf0e10cSrcweir         if (0 == m_aNodePtr) {
319cdf0e10cSrcweir             return ::rtl::OUString();
320cdf0e10cSrcweir         }
321cdf0e10cSrcweir         OString o1 = OUStringToOString(localName, RTL_TEXTENCODING_UTF8);
322cdf0e10cSrcweir         xmlChar const*const pName =
323cdf0e10cSrcweir             reinterpret_cast<xmlChar const*>(o1.getStr());
324cdf0e10cSrcweir         OString o2 = OUStringToOString(namespaceURI, RTL_TEXTENCODING_UTF8);
325cdf0e10cSrcweir         xmlChar const*const pNS =
326cdf0e10cSrcweir             reinterpret_cast<xmlChar const*>(o2.getStr());
327cdf0e10cSrcweir         ::boost::shared_ptr<xmlChar const> const pValue(
328cdf0e10cSrcweir                 xmlGetNsProp(m_aNodePtr, pName, pNS), xmlFree);
329cdf0e10cSrcweir         if (0 == pValue) {
330cdf0e10cSrcweir             return ::rtl::OUString();
331cdf0e10cSrcweir         }
332cdf0e10cSrcweir         OUString const ret(reinterpret_cast<sal_Char const*>(pValue.get()),
333cdf0e10cSrcweir                         strlen(reinterpret_cast<char const*>(pValue.get())),
334cdf0e10cSrcweir                         RTL_TEXTENCODING_UTF8);
335cdf0e10cSrcweir         return ret;
336cdf0e10cSrcweir     }
337cdf0e10cSrcweir 
338cdf0e10cSrcweir     /**
339cdf0e10cSrcweir     Returns a NodeList of all descendant Elements with a given tag name,
340cdf0e10cSrcweir     in the order in which they are
341cdf0e10cSrcweir     encountered in a preorder traversal of this Element tree.
342cdf0e10cSrcweir     */
343cdf0e10cSrcweir     Reference< XNodeList > SAL_CALL
getElementsByTagName(OUString const & rLocalName)344cdf0e10cSrcweir     CElement::getElementsByTagName(OUString const& rLocalName)
345cdf0e10cSrcweir         throw (RuntimeException)
346cdf0e10cSrcweir     {
347cdf0e10cSrcweir         ::osl::MutexGuard const g(m_rMutex);
348cdf0e10cSrcweir 
349cdf0e10cSrcweir         Reference< XNodeList > const xList(
350cdf0e10cSrcweir                 new CElementList(this, m_rMutex, rLocalName));
351cdf0e10cSrcweir         return xList;
352cdf0e10cSrcweir     }
353cdf0e10cSrcweir 
354cdf0e10cSrcweir     /**
355cdf0e10cSrcweir     Returns a NodeList of all the descendant Elements with a given local
356cdf0e10cSrcweir     name and namespace URI in the order in which they are encountered in
357cdf0e10cSrcweir     a preorder traversal of this Element tree.
358cdf0e10cSrcweir     */
359cdf0e10cSrcweir     Reference< XNodeList > SAL_CALL
getElementsByTagNameNS(OUString const & rNamespaceURI,OUString const & rLocalName)360cdf0e10cSrcweir     CElement::getElementsByTagNameNS(
361cdf0e10cSrcweir             OUString const& rNamespaceURI, OUString const& rLocalName)
362cdf0e10cSrcweir         throw (RuntimeException)
363cdf0e10cSrcweir     {
364cdf0e10cSrcweir         ::osl::MutexGuard const g(m_rMutex);
365cdf0e10cSrcweir 
366cdf0e10cSrcweir         Reference< XNodeList > const xList(
367cdf0e10cSrcweir             new CElementList(this, m_rMutex, rLocalName, &rNamespaceURI));
368cdf0e10cSrcweir         return xList;
369cdf0e10cSrcweir     }
370cdf0e10cSrcweir 
371cdf0e10cSrcweir     /**
372cdf0e10cSrcweir     The name of the element.
373cdf0e10cSrcweir     */
getTagName()374cdf0e10cSrcweir     OUString SAL_CALL CElement::getTagName()
375cdf0e10cSrcweir         throw (RuntimeException)
376cdf0e10cSrcweir     {
377cdf0e10cSrcweir         ::osl::MutexGuard const g(m_rMutex);
378cdf0e10cSrcweir 
379cdf0e10cSrcweir         if (0 == m_aNodePtr) {
380cdf0e10cSrcweir             return ::rtl::OUString();
381cdf0e10cSrcweir         }
382cdf0e10cSrcweir         OUString const ret((sal_Char*)m_aNodePtr->name,
383cdf0e10cSrcweir                 strlen((char*)m_aNodePtr->name), RTL_TEXTENCODING_UTF8);
384cdf0e10cSrcweir         return ret;
385cdf0e10cSrcweir     }
386cdf0e10cSrcweir 
387cdf0e10cSrcweir 
388cdf0e10cSrcweir     /**
389cdf0e10cSrcweir     Returns true when an attribute with a given name is specified on this
390cdf0e10cSrcweir     element or has a default value, false otherwise.
391cdf0e10cSrcweir     */
hasAttribute(OUString const & name)392cdf0e10cSrcweir     sal_Bool SAL_CALL CElement::hasAttribute(OUString const& name)
393cdf0e10cSrcweir         throw (RuntimeException)
394cdf0e10cSrcweir     {
395cdf0e10cSrcweir         ::osl::MutexGuard const g(m_rMutex);
396cdf0e10cSrcweir 
397cdf0e10cSrcweir         OString o1 = OUStringToOString(name, RTL_TEXTENCODING_UTF8);
398cdf0e10cSrcweir         xmlChar *xName = (xmlChar*)o1.getStr();
399cdf0e10cSrcweir         return (m_aNodePtr != NULL && xmlHasProp(m_aNodePtr, xName) != NULL);
400cdf0e10cSrcweir     }
401cdf0e10cSrcweir 
402cdf0e10cSrcweir     /**
403cdf0e10cSrcweir     Returns true when an attribute with a given local name and namespace
404cdf0e10cSrcweir     URI is specified on this element or has a default value, false otherwise.
405cdf0e10cSrcweir     */
hasAttributeNS(OUString const & namespaceURI,OUString const & localName)406cdf0e10cSrcweir     sal_Bool SAL_CALL CElement::hasAttributeNS(
407cdf0e10cSrcweir             OUString const& namespaceURI, OUString const& localName)
408cdf0e10cSrcweir         throw (RuntimeException)
409cdf0e10cSrcweir     {
410cdf0e10cSrcweir         ::osl::MutexGuard const g(m_rMutex);
411cdf0e10cSrcweir 
412cdf0e10cSrcweir         OString o1 = OUStringToOString(localName, RTL_TEXTENCODING_UTF8);
413cdf0e10cSrcweir         xmlChar *xName = (xmlChar*)o1.getStr();
414cdf0e10cSrcweir         OString o2 = OUStringToOString(namespaceURI, RTL_TEXTENCODING_UTF8);
415cdf0e10cSrcweir         xmlChar *xNs = (xmlChar*)o2.getStr();
416cdf0e10cSrcweir         return (m_aNodePtr != NULL && xmlHasNsProp(m_aNodePtr, xName, xNs) != NULL);
417cdf0e10cSrcweir     }
418cdf0e10cSrcweir 
419cdf0e10cSrcweir     /**
420cdf0e10cSrcweir     Removes an attribute by name.
421cdf0e10cSrcweir     */
removeAttribute(OUString const & name)422cdf0e10cSrcweir     void SAL_CALL CElement::removeAttribute(OUString const& name)
423cdf0e10cSrcweir         throw (RuntimeException, DOMException)
424cdf0e10cSrcweir     {
425cdf0e10cSrcweir         ::osl::MutexGuard const g(m_rMutex);
426cdf0e10cSrcweir 
427cdf0e10cSrcweir         if (0 == m_aNodePtr) {
428cdf0e10cSrcweir             return;
429cdf0e10cSrcweir         }
430cdf0e10cSrcweir         OString o1 = OUStringToOString(name, RTL_TEXTENCODING_UTF8);
431cdf0e10cSrcweir         xmlChar const*const pName =
432cdf0e10cSrcweir             reinterpret_cast<xmlChar const*>(o1.getStr());
433cdf0e10cSrcweir         xmlAttrPtr const pAttr = xmlHasProp(m_aNodePtr, pName);
434cdf0e10cSrcweir         if (0 == xmlUnsetProp(m_aNodePtr, pName)) {
435cdf0e10cSrcweir             ::rtl::Reference<CNode> const pCNode(GetOwnerDocument().GetCNode(
436cdf0e10cSrcweir                     reinterpret_cast<xmlNodePtr>(pAttr), false));
437cdf0e10cSrcweir             if (pCNode.is()) {
438cdf0e10cSrcweir                 pCNode->invalidate(); // freed by xmlUnsetProp
439cdf0e10cSrcweir             }
440cdf0e10cSrcweir         }
441cdf0e10cSrcweir     }
442cdf0e10cSrcweir 
443cdf0e10cSrcweir     /**
444cdf0e10cSrcweir     Removes an attribute by local name and namespace URI.
445cdf0e10cSrcweir     */
removeAttributeNS(OUString const & namespaceURI,OUString const & localName)446cdf0e10cSrcweir     void SAL_CALL CElement::removeAttributeNS(
447cdf0e10cSrcweir             OUString const& namespaceURI, OUString const& localName)
448cdf0e10cSrcweir         throw (RuntimeException, DOMException)
449cdf0e10cSrcweir     {
450cdf0e10cSrcweir         ::osl::MutexGuard const g(m_rMutex);
451cdf0e10cSrcweir 
452cdf0e10cSrcweir         if (0 == m_aNodePtr) {
453cdf0e10cSrcweir             return;
454cdf0e10cSrcweir         }
455cdf0e10cSrcweir         OString o1 = OUStringToOString(localName, RTL_TEXTENCODING_UTF8);
456cdf0e10cSrcweir         xmlChar const*const pName =
457cdf0e10cSrcweir             reinterpret_cast<xmlChar const*>(o1.getStr());
458cdf0e10cSrcweir         OString o2 = OUStringToOString(namespaceURI, RTL_TEXTENCODING_UTF8);
459cdf0e10cSrcweir         xmlChar const*const pURI =
460cdf0e10cSrcweir             reinterpret_cast<xmlChar const*>(o2.getStr());
461cdf0e10cSrcweir         xmlNsPtr const pNs =
462cdf0e10cSrcweir             xmlSearchNsByHref(m_aNodePtr->doc, m_aNodePtr, pURI);
463cdf0e10cSrcweir         xmlAttrPtr const pAttr = xmlHasNsProp(m_aNodePtr, pName, pURI);
464cdf0e10cSrcweir         if (0 == xmlUnsetNsProp(m_aNodePtr, pNs, pName)) {
465cdf0e10cSrcweir             ::rtl::Reference<CNode> const pCNode(GetOwnerDocument().GetCNode(
466cdf0e10cSrcweir                     reinterpret_cast<xmlNodePtr>(pAttr), false));
467cdf0e10cSrcweir             if (pCNode.is()) {
468cdf0e10cSrcweir                 pCNode->invalidate(); // freed by xmlUnsetNsProp
469cdf0e10cSrcweir             }
470cdf0e10cSrcweir         }
471cdf0e10cSrcweir     }
472cdf0e10cSrcweir 
473cdf0e10cSrcweir     /**
474cdf0e10cSrcweir     Removes the specified attribute node.
475cdf0e10cSrcweir     */
476cdf0e10cSrcweir     Reference< XAttr > SAL_CALL
removeAttributeNode(Reference<XAttr> const & oldAttr)477cdf0e10cSrcweir     CElement::removeAttributeNode(Reference< XAttr > const& oldAttr)
478cdf0e10cSrcweir         throw (RuntimeException, DOMException)
479cdf0e10cSrcweir     {
480cdf0e10cSrcweir         ::osl::MutexGuard const g(m_rMutex);
481cdf0e10cSrcweir 
482cdf0e10cSrcweir         if (0 == m_aNodePtr) {
483cdf0e10cSrcweir             return 0;
484cdf0e10cSrcweir         }
485cdf0e10cSrcweir 
486cdf0e10cSrcweir         ::rtl::Reference<CNode> const pCNode(
487cdf0e10cSrcweir             CNode::GetImplementation(Reference<XNode>(oldAttr.get())));
488cdf0e10cSrcweir         if (!pCNode.is()) { throw RuntimeException(); }
489cdf0e10cSrcweir 
490cdf0e10cSrcweir         xmlNodePtr const pNode = pCNode->GetNodePtr();
491cdf0e10cSrcweir         xmlAttrPtr const pAttr = (xmlAttrPtr) pNode;
492cdf0e10cSrcweir         if (!pAttr) { throw RuntimeException(); }
493cdf0e10cSrcweir 
494cdf0e10cSrcweir         if (pAttr->parent != m_aNodePtr)
495cdf0e10cSrcweir         {
496cdf0e10cSrcweir             DOMException e;
497cdf0e10cSrcweir             e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR;
498cdf0e10cSrcweir             throw e;
499cdf0e10cSrcweir         }
500cdf0e10cSrcweir         if (pAttr->doc != m_aNodePtr->doc)
501cdf0e10cSrcweir         {
502cdf0e10cSrcweir             DOMException e;
503cdf0e10cSrcweir             e.Code = DOMExceptionType_WRONG_DOCUMENT_ERR;
504cdf0e10cSrcweir             throw e;
505cdf0e10cSrcweir         }
506cdf0e10cSrcweir 
507cdf0e10cSrcweir         Reference< XAttr > aAttr;
508cdf0e10cSrcweir         if (oldAttr->getNamespaceURI().getLength() > 0) {
509cdf0e10cSrcweir             ::rtl::OUStringBuffer qname(oldAttr->getPrefix());
510cdf0e10cSrcweir             if (0 != qname.getLength()) {
511cdf0e10cSrcweir                 qname.append(sal_Unicode(':'));
512cdf0e10cSrcweir             }
513cdf0e10cSrcweir             qname.append(oldAttr->getName());
514cdf0e10cSrcweir             aAttr = GetOwnerDocument().createAttributeNS(
515cdf0e10cSrcweir                 oldAttr->getNamespaceURI(), qname.makeStringAndClear());
516cdf0e10cSrcweir         } else {
517cdf0e10cSrcweir             aAttr = GetOwnerDocument().createAttribute(oldAttr->getName());
518cdf0e10cSrcweir         }
519cdf0e10cSrcweir         aAttr->setValue(oldAttr->getValue());
520cdf0e10cSrcweir         xmlRemoveProp(pAttr);
521cdf0e10cSrcweir         pCNode->invalidate(); // freed by xmlRemoveProp
522cdf0e10cSrcweir 
523cdf0e10cSrcweir         return aAttr;
524cdf0e10cSrcweir     }
525cdf0e10cSrcweir 
526cdf0e10cSrcweir     /**
527cdf0e10cSrcweir     Adds a new attribute node.
528cdf0e10cSrcweir     */
529cdf0e10cSrcweir     Reference< XAttr >
setAttributeNode_Impl_Lock(Reference<XAttr> const & xNewAttr,bool const bNS)530cdf0e10cSrcweir     CElement::setAttributeNode_Impl_Lock(
531cdf0e10cSrcweir             Reference< XAttr > const& xNewAttr, bool const bNS)
532cdf0e10cSrcweir     {
533cdf0e10cSrcweir         if (xNewAttr->getOwnerDocument() != getOwnerDocument()) {
534cdf0e10cSrcweir             DOMException e;
535cdf0e10cSrcweir             e.Code = DOMExceptionType_WRONG_DOCUMENT_ERR;
536cdf0e10cSrcweir             throw e;
537cdf0e10cSrcweir         }
538cdf0e10cSrcweir 
539cdf0e10cSrcweir         ::osl::ClearableMutexGuard guard(m_rMutex);
540cdf0e10cSrcweir 
541cdf0e10cSrcweir         if (0 == m_aNodePtr) {
542cdf0e10cSrcweir             throw RuntimeException();
543cdf0e10cSrcweir         }
544cdf0e10cSrcweir 
545cdf0e10cSrcweir         // get the implementation
546cdf0e10cSrcweir         CAttr *const pCAttr = dynamic_cast<CAttr*>(
547cdf0e10cSrcweir                 CNode::GetImplementation(xNewAttr));
548cdf0e10cSrcweir         if (!pCAttr) { throw RuntimeException(); }
549cdf0e10cSrcweir         xmlAttrPtr const pAttr =
550cdf0e10cSrcweir             reinterpret_cast<xmlAttrPtr>(pCAttr->GetNodePtr());
551cdf0e10cSrcweir         if (!pAttr) { throw RuntimeException(); }
552cdf0e10cSrcweir 
553cdf0e10cSrcweir         // check whether the attribute is not in use by another element
554cdf0e10cSrcweir         if (pAttr->parent) {
555cdf0e10cSrcweir             DOMException e;
556cdf0e10cSrcweir             e.Code = DOMExceptionType_INUSE_ATTRIBUTE_ERR;
557cdf0e10cSrcweir             throw e;
558cdf0e10cSrcweir         }
559cdf0e10cSrcweir 
560cdf0e10cSrcweir         xmlAttrPtr res = NULL;
561cdf0e10cSrcweir         xmlChar const*const pContent(
562cdf0e10cSrcweir                 (pAttr->children) ? pAttr->children->content : 0);
563cdf0e10cSrcweir 
564cdf0e10cSrcweir         if (bNS) {
565cdf0e10cSrcweir             xmlNsPtr const pNs( pCAttr->GetNamespace(m_aNodePtr) );
566cdf0e10cSrcweir             res = xmlNewNsProp(m_aNodePtr, pNs, pAttr->name, pContent);
567cdf0e10cSrcweir         } else {
568cdf0e10cSrcweir             res = xmlNewProp(m_aNodePtr, pAttr->name, pContent);
569cdf0e10cSrcweir         }
570cdf0e10cSrcweir 
571cdf0e10cSrcweir         // get the new attr node
572cdf0e10cSrcweir         Reference< XAttr > const xAttr(
573cdf0e10cSrcweir             static_cast< XNode* >(GetOwnerDocument().GetCNode(
574cdf0e10cSrcweir                     reinterpret_cast<xmlNodePtr>(res)).get()),
575cdf0e10cSrcweir             UNO_QUERY_THROW);
576cdf0e10cSrcweir 
577cdf0e10cSrcweir         // attribute adition event
578cdf0e10cSrcweir         // dispatch DOMAttrModified event
579cdf0e10cSrcweir         Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
580cdf0e10cSrcweir         Reference< XMutationEvent > event(docevent->createEvent(
581cdf0e10cSrcweir             OUString::createFromAscii("DOMAttrModified")), UNO_QUERY);
582cdf0e10cSrcweir         event->initMutationEvent(OUString::createFromAscii("DOMAttrModified"),
583cdf0e10cSrcweir             sal_True, sal_False, Reference< XNode >(xAttr, UNO_QUERY),
584cdf0e10cSrcweir             OUString(), xAttr->getValue(), xAttr->getName(),
585cdf0e10cSrcweir             AttrChangeType_ADDITION);
586cdf0e10cSrcweir 
587cdf0e10cSrcweir         guard.clear(); // release mutex before calling event handlers
588cdf0e10cSrcweir 
589cdf0e10cSrcweir         dispatchEvent(Reference< XEvent >(event, UNO_QUERY));
590cdf0e10cSrcweir         dispatchSubtreeModified();
591cdf0e10cSrcweir 
592cdf0e10cSrcweir         return xAttr;
593cdf0e10cSrcweir     }
594cdf0e10cSrcweir 
595cdf0e10cSrcweir     Reference< XAttr >
setAttributeNode(const Reference<XAttr> & newAttr)596cdf0e10cSrcweir     CElement::setAttributeNode(const Reference< XAttr >& newAttr)
597cdf0e10cSrcweir         throw (RuntimeException, DOMException)
598cdf0e10cSrcweir     {
599cdf0e10cSrcweir         return setAttributeNode_Impl_Lock(newAttr, false);
600cdf0e10cSrcweir     }
601cdf0e10cSrcweir 
602cdf0e10cSrcweir     /**
603cdf0e10cSrcweir     Adds a new attribute.
604cdf0e10cSrcweir     */
605cdf0e10cSrcweir     Reference< XAttr >
setAttributeNodeNS(const Reference<XAttr> & newAttr)606cdf0e10cSrcweir     CElement::setAttributeNodeNS(const Reference< XAttr >& newAttr)
607cdf0e10cSrcweir         throw (RuntimeException, DOMException)
608cdf0e10cSrcweir     {
609cdf0e10cSrcweir         return setAttributeNode_Impl_Lock(newAttr, true);
610cdf0e10cSrcweir     }
611cdf0e10cSrcweir 
612cdf0e10cSrcweir     /**
613cdf0e10cSrcweir     Adds a new attribute.
614cdf0e10cSrcweir     */
615cdf0e10cSrcweir     void SAL_CALL
setAttribute(OUString const & name,OUString const & value)616cdf0e10cSrcweir     CElement::setAttribute(OUString const& name, OUString const& value)
617cdf0e10cSrcweir         throw (RuntimeException, DOMException)
618cdf0e10cSrcweir     {
619cdf0e10cSrcweir         ::osl::ClearableMutexGuard guard(m_rMutex);
620cdf0e10cSrcweir 
621cdf0e10cSrcweir         OString o1 = OUStringToOString(name, RTL_TEXTENCODING_UTF8);
622cdf0e10cSrcweir         xmlChar *xName = (xmlChar*)o1.getStr();
623cdf0e10cSrcweir         OString o2 = OUStringToOString(value, RTL_TEXTENCODING_UTF8);
624cdf0e10cSrcweir         xmlChar *xValue = (xmlChar*)o2.getStr();
625cdf0e10cSrcweir 
626cdf0e10cSrcweir         if (0 == m_aNodePtr) {
627cdf0e10cSrcweir             throw RuntimeException();
628cdf0e10cSrcweir         }
629cdf0e10cSrcweir         OUString oldValue;
630cdf0e10cSrcweir         AttrChangeType aChangeType = AttrChangeType_MODIFICATION;
631cdf0e10cSrcweir         ::boost::shared_ptr<xmlChar const> const pOld(
632cdf0e10cSrcweir             xmlGetProp(m_aNodePtr, xName), xmlFree);
633*b862c97cSHerbert Dürr         if( !bool(pOld)) {
634cdf0e10cSrcweir             aChangeType = AttrChangeType_ADDITION;
635cdf0e10cSrcweir             xmlNewProp(m_aNodePtr, xName, xValue);
636cdf0e10cSrcweir         } else {
637cdf0e10cSrcweir             oldValue = OUString(reinterpret_cast<sal_Char const*>(pOld.get()),
638cdf0e10cSrcweir                         strlen(reinterpret_cast<char const*>(pOld.get())),
639cdf0e10cSrcweir                         RTL_TEXTENCODING_UTF8);
640cdf0e10cSrcweir             xmlSetProp(m_aNodePtr, xName, xValue);
641cdf0e10cSrcweir         }
642cdf0e10cSrcweir 
643cdf0e10cSrcweir         // dispatch DOMAttrModified event
644cdf0e10cSrcweir         Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
645cdf0e10cSrcweir         Reference< XMutationEvent > event(docevent->createEvent(
646cdf0e10cSrcweir             OUString::createFromAscii("DOMAttrModified")), UNO_QUERY);
647cdf0e10cSrcweir         event->initMutationEvent(OUString::createFromAscii("DOMAttrModified"),
648cdf0e10cSrcweir             sal_True, sal_False,
649cdf0e10cSrcweir             Reference< XNode >(getAttributeNode(name), UNO_QUERY),
650cdf0e10cSrcweir             oldValue, value, name, aChangeType);
651cdf0e10cSrcweir 
652cdf0e10cSrcweir         guard.clear(); // release mutex before calling event handlers
653cdf0e10cSrcweir         dispatchEvent(Reference< XEvent >(event, UNO_QUERY));
654cdf0e10cSrcweir         dispatchSubtreeModified();
655cdf0e10cSrcweir     }
656cdf0e10cSrcweir 
657cdf0e10cSrcweir     /**
658cdf0e10cSrcweir     Adds a new attribute.
659cdf0e10cSrcweir     */
660cdf0e10cSrcweir     void SAL_CALL
setAttributeNS(OUString const & namespaceURI,OUString const & qualifiedName,OUString const & value)661cdf0e10cSrcweir     CElement::setAttributeNS(OUString const& namespaceURI,
662cdf0e10cSrcweir             OUString const& qualifiedName, OUString const& value)
663cdf0e10cSrcweir         throw (RuntimeException, DOMException)
664cdf0e10cSrcweir     {
665cdf0e10cSrcweir         if (namespaceURI.getLength() == 0) throw RuntimeException();
666cdf0e10cSrcweir 
667cdf0e10cSrcweir         ::osl::ClearableMutexGuard guard(m_rMutex);
668cdf0e10cSrcweir 
669cdf0e10cSrcweir         OString o1, o2, o3, o4, o5;
670cdf0e10cSrcweir         xmlChar *xPrefix = NULL;
671cdf0e10cSrcweir         xmlChar *xLName = NULL;
672cdf0e10cSrcweir         o1 = OUStringToOString(qualifiedName, RTL_TEXTENCODING_UTF8);
673cdf0e10cSrcweir         xmlChar *xQName = (xmlChar*)o1.getStr();
674cdf0e10cSrcweir         sal_Int32 idx = qualifiedName.indexOf(':');
675cdf0e10cSrcweir         if (idx != -1)
676cdf0e10cSrcweir         {
677cdf0e10cSrcweir             o2 = OUStringToOString(
678cdf0e10cSrcweir                 qualifiedName.copy(0,idx),
679cdf0e10cSrcweir                 RTL_TEXTENCODING_UTF8);
680cdf0e10cSrcweir             xPrefix = (xmlChar*)o2.getStr();
681cdf0e10cSrcweir             o3 = OUStringToOString(
682cdf0e10cSrcweir                 qualifiedName.copy(idx+1),
683cdf0e10cSrcweir                 RTL_TEXTENCODING_UTF8);
684cdf0e10cSrcweir             xLName = (xmlChar*)o3.getStr();
685cdf0e10cSrcweir         }  else {
686cdf0e10cSrcweir             xPrefix = (xmlChar*)"";
687cdf0e10cSrcweir             xLName = xQName;
688cdf0e10cSrcweir         }
689cdf0e10cSrcweir         o4 = OUStringToOString(namespaceURI, RTL_TEXTENCODING_UTF8);
690cdf0e10cSrcweir         o5 = OUStringToOString(value, RTL_TEXTENCODING_UTF8);
691cdf0e10cSrcweir         xmlChar *xURI= (xmlChar*)o4.getStr();
692cdf0e10cSrcweir         xmlChar *xValue = (xmlChar*)o5.getStr();
693cdf0e10cSrcweir 
694cdf0e10cSrcweir         if (0 == m_aNodePtr) {
695cdf0e10cSrcweir             throw RuntimeException();
696cdf0e10cSrcweir         }
697cdf0e10cSrcweir 
698cdf0e10cSrcweir         //find the right namespace
699cdf0e10cSrcweir         xmlNsPtr pNs = xmlSearchNs(m_aNodePtr->doc, m_aNodePtr, xPrefix);
700cdf0e10cSrcweir         // if no namespace found, create a new one
701cdf0e10cSrcweir         if (pNs == NULL) {
702cdf0e10cSrcweir             pNs = xmlNewNs(m_aNodePtr, xURI, xPrefix);
703cdf0e10cSrcweir         }
704cdf0e10cSrcweir 
705cdf0e10cSrcweir         if (strcmp((char*)pNs->href, (char*)xURI) != 0) {
706cdf0e10cSrcweir             // ambiguous ns prefix
707cdf0e10cSrcweir             throw RuntimeException();
708cdf0e10cSrcweir         }
709cdf0e10cSrcweir 
710cdf0e10cSrcweir         // found namespace matches
711cdf0e10cSrcweir 
712cdf0e10cSrcweir         OUString oldValue;
713cdf0e10cSrcweir         AttrChangeType aChangeType = AttrChangeType_MODIFICATION;
714cdf0e10cSrcweir         ::boost::shared_ptr<xmlChar const> const pOld(
715cdf0e10cSrcweir                 xmlGetNsProp(m_aNodePtr, xLName, pNs->href), xmlFree);
716*b862c97cSHerbert Dürr         if( !bool(pOld)) {
717cdf0e10cSrcweir             aChangeType = AttrChangeType_ADDITION;
718cdf0e10cSrcweir             xmlNewNsProp(m_aNodePtr, pNs, xLName, xValue);
719cdf0e10cSrcweir         } else {
720cdf0e10cSrcweir             oldValue = OUString(reinterpret_cast<sal_Char const*>(pOld.get()),
721cdf0e10cSrcweir                         strlen(reinterpret_cast<char const*>(pOld.get())),
722cdf0e10cSrcweir                         RTL_TEXTENCODING_UTF8);
723cdf0e10cSrcweir             xmlSetNsProp(m_aNodePtr, pNs, xLName, xValue);
724cdf0e10cSrcweir         }
725cdf0e10cSrcweir         // dispatch DOMAttrModified event
726cdf0e10cSrcweir         Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
727cdf0e10cSrcweir         Reference< XMutationEvent > event(docevent->createEvent(
728cdf0e10cSrcweir             OUString::createFromAscii("DOMAttrModified")), UNO_QUERY);
729cdf0e10cSrcweir         event->initMutationEvent(
730cdf0e10cSrcweir             OUString::createFromAscii("DOMAttrModified"),
731cdf0e10cSrcweir             sal_True, sal_False,
732cdf0e10cSrcweir             Reference< XNode >(getAttributeNodeNS(namespaceURI, OUString((char*)xLName, strlen((char*)xLName), RTL_TEXTENCODING_UTF8)), UNO_QUERY),
733cdf0e10cSrcweir             oldValue, value, qualifiedName, aChangeType);
734cdf0e10cSrcweir 
735cdf0e10cSrcweir         guard.clear(); // release mutex before calling event handlers
736cdf0e10cSrcweir         dispatchEvent(Reference< XEvent >(event, UNO_QUERY));
737cdf0e10cSrcweir         dispatchSubtreeModified();
738cdf0e10cSrcweir     }
739cdf0e10cSrcweir 
740cdf0e10cSrcweir     Reference< XNamedNodeMap > SAL_CALL
getAttributes()741cdf0e10cSrcweir     CElement::getAttributes() throw (RuntimeException)
742cdf0e10cSrcweir     {
743cdf0e10cSrcweir         ::osl::MutexGuard const g(m_rMutex);
744cdf0e10cSrcweir 
745cdf0e10cSrcweir         Reference< XNamedNodeMap > const xMap(
746cdf0e10cSrcweir                 new CAttributesMap(this, m_rMutex));
747cdf0e10cSrcweir         return xMap;
748cdf0e10cSrcweir     }
749cdf0e10cSrcweir 
getNodeName()750cdf0e10cSrcweir     OUString SAL_CALL CElement::getNodeName()throw (RuntimeException)
751cdf0e10cSrcweir     {
752cdf0e10cSrcweir         return getLocalName();
753cdf0e10cSrcweir     }
754cdf0e10cSrcweir 
getLocalName()755cdf0e10cSrcweir     OUString SAL_CALL CElement::getLocalName()throw (RuntimeException)
756cdf0e10cSrcweir     {
757cdf0e10cSrcweir         ::osl::MutexGuard const g(m_rMutex);
758cdf0e10cSrcweir 
759cdf0e10cSrcweir         OUString aName;
760cdf0e10cSrcweir         if (m_aNodePtr != NULL)
761cdf0e10cSrcweir         {
762cdf0e10cSrcweir             const xmlChar* xName = m_aNodePtr->name;
763cdf0e10cSrcweir             aName = OUString((const sal_Char*)xName, strlen((const char*)xName), RTL_TEXTENCODING_UTF8);
764cdf0e10cSrcweir         }
765cdf0e10cSrcweir         return aName;
766cdf0e10cSrcweir     }
767cdf0e10cSrcweir 
getNodeValue()768cdf0e10cSrcweir     OUString SAL_CALL CElement::getNodeValue() throw (RuntimeException)
769cdf0e10cSrcweir     {
770cdf0e10cSrcweir         return OUString();
771cdf0e10cSrcweir     }
772cdf0e10cSrcweir 
setElementName(const OUString & aName)773cdf0e10cSrcweir     void SAL_CALL CElement::setElementName(const OUString& aName)
774cdf0e10cSrcweir         throw (RuntimeException, DOMException)
775cdf0e10cSrcweir     {
776cdf0e10cSrcweir         if ((aName.getLength() <= 0) ||
777cdf0e10cSrcweir             (0 <= aName.indexOf(OUString::createFromAscii(":"))))
778cdf0e10cSrcweir         {
779cdf0e10cSrcweir             DOMException e;
780cdf0e10cSrcweir             e.Code = DOMExceptionType_INVALID_CHARACTER_ERR;
781cdf0e10cSrcweir             throw e;
782cdf0e10cSrcweir         }
783cdf0e10cSrcweir 
784cdf0e10cSrcweir         ::osl::MutexGuard const g(m_rMutex);
785cdf0e10cSrcweir 
786cdf0e10cSrcweir         if (0 == m_aNodePtr) {
787cdf0e10cSrcweir             throw RuntimeException();
788cdf0e10cSrcweir         }
789cdf0e10cSrcweir         OString oName = OUStringToOString(aName, RTL_TEXTENCODING_UTF8);
790cdf0e10cSrcweir         xmlChar *xName = (xmlChar*)oName.getStr();
791cdf0e10cSrcweir         xmlNodeSetName(m_aNodePtr, xName);
792cdf0e10cSrcweir     }
793cdf0e10cSrcweir 
794cdf0e10cSrcweir }
795