1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <element.hxx>
24 #include <boost/shared_ptr.hpp>
26 #include <rtl/ustrbuf.hxx>
28 #include <com/sun/star/xml/sax/FastToken.hpp>
30 #include <comphelper/attributelist.hxx>
34 #include <elementlist.hxx>
35 #include <attributesmap.hxx>
36 #include <document.hxx>
38 #include "../events/mutationevent.hxx"
44 CElement::CElement(CDocument
const& rDocument
, ::osl::Mutex
const& rMutex
,
45 xmlNodePtr
const pNode
)
46 : CElement_Base(rDocument
, rMutex
, NodeType_ELEMENT_NODE
, pNode
)
50 void CElement::saxify(const Reference
< XDocumentHandler
>& i_xHandler
)
52 if (!i_xHandler
.is()) throw RuntimeException();
53 comphelper::AttributeList
*pAttrs
=
54 new comphelper::AttributeList();
56 // add namespace definitions to attributes
57 for (xmlNsPtr pNs
= m_aNodePtr
->nsDef
; pNs
!= 0; pNs
= pNs
->next
) {
58 const xmlChar
*pPrefix
= pNs
->prefix
;
59 OUString
prefix(reinterpret_cast<const sal_Char
*>(pPrefix
),
60 strlen(reinterpret_cast<const char*>(pPrefix
)),
61 RTL_TEXTENCODING_UTF8
);
62 OUString name
= (prefix
.isEmpty())
63 ? OUString( "xmlns" ) : OUString( "xmlns:" ) + prefix
;
64 const xmlChar
*pHref
= pNs
->href
;
65 OUString
val(reinterpret_cast<const sal_Char
*>(pHref
),
66 strlen(reinterpret_cast<const char*>(pHref
)),
67 RTL_TEXTENCODING_UTF8
);
68 pAttrs
->AddAttribute(name
, type
, val
);
71 for (xmlAttrPtr pAttr
= m_aNodePtr
->properties
;
72 pAttr
!= 0; pAttr
= pAttr
->next
) {
73 ::rtl::Reference
<CNode
> const pNode
= GetOwnerDocument().GetCNode(
74 reinterpret_cast<xmlNodePtr
>(pAttr
));
75 OSL_ENSURE(pNode
!= 0, "CNode::get returned 0");
76 OUString prefix
= pNode
->getPrefix();
77 OUString name
= (prefix
.isEmpty())
78 ? pNode
->getLocalName()
79 : prefix
+ OUString(static_cast<sal_Unicode
>(':')) + pNode
->getLocalName();
80 OUString val
= pNode
->getNodeValue();
81 pAttrs
->AddAttribute(name
, type
, val
);
83 OUString prefix
= getPrefix();
84 OUString name
= (prefix
.isEmpty())
86 : prefix
+ OUString(static_cast<sal_Unicode
>(':')) + getLocalName();
87 Reference
< XAttributeList
> xAttrList(pAttrs
);
88 i_xHandler
->startElement(name
, xAttrList
);
90 for (xmlNodePtr pChild
= m_aNodePtr
->children
;
91 pChild
!= 0; pChild
= pChild
->next
) {
92 ::rtl::Reference
<CNode
> const pNode(
93 GetOwnerDocument().GetCNode(pChild
));
94 OSL_ENSURE(pNode
!= 0, "CNode::get returned 0");
95 pNode
->saxify(i_xHandler
);
97 i_xHandler
->endElement(name
);
100 void CElement::fastSaxify( Context
& i_rContext
)
102 if (!i_rContext
.mxDocHandler
.is()) throw RuntimeException();
103 pushContext(i_rContext
);
104 addNamespaces(i_rContext
,m_aNodePtr
);
107 i_rContext
.mxAttribList
->clear();
108 for (xmlAttrPtr pAttr
= m_aNodePtr
->properties
;
109 pAttr
!= 0; pAttr
= pAttr
->next
) {
110 ::rtl::Reference
<CNode
> const pNode
= GetOwnerDocument().GetCNode(
111 reinterpret_cast<xmlNodePtr
>(pAttr
));
112 OSL_ENSURE(pNode
!= 0, "CNode::get returned 0");
114 const xmlChar
* xName
= pAttr
->name
;
115 sal_Int32 nAttributeToken
=FastToken::DONTKNOW
;
117 if( pAttr
->ns
&& strlen((char*)pAttr
->ns
->prefix
) )
118 nAttributeToken
= getTokenWithPrefix( i_rContext
,
119 (sal_Char
*)pAttr
->ns
->prefix
,
122 nAttributeToken
= getToken( i_rContext
, (sal_Char
*)xName
);
124 if( nAttributeToken
!= FastToken::DONTKNOW
)
125 i_rContext
.mxAttribList
->add( nAttributeToken
,
126 OUStringToOString(pNode
->getNodeValue(),
127 RTL_TEXTENCODING_UTF8
));
130 const xmlChar
* xPrefix
= m_aNodePtr
->ns
? m_aNodePtr
->ns
->prefix
: (const xmlChar
*)"";
131 const xmlChar
* xName
= m_aNodePtr
->name
;
132 sal_Int32 nElementToken
=FastToken::DONTKNOW
;
133 if( strlen((char*)xPrefix
) )
134 nElementToken
= getTokenWithPrefix( i_rContext
, (sal_Char
*)xPrefix
, (sal_Char
*)xName
);
136 nElementToken
= getToken( i_rContext
, (sal_Char
*)xName
);
138 Reference
<XFastContextHandler
> xParentHandler(i_rContext
.mxCurrentHandler
);
141 Reference
< XFastAttributeList
> xAttr( i_rContext
.mxAttribList
.get() );
142 if( nElementToken
== FastToken::DONTKNOW
)
144 const OUString aNamespace
;
145 const OUString
aElementName( (sal_Char
*)xPrefix
,
146 strlen((char*)xPrefix
),
147 RTL_TEXTENCODING_UTF8
);
149 if( xParentHandler
.is() )
150 i_rContext
.mxCurrentHandler
= xParentHandler
->createUnknownChildContext( aNamespace
, aElementName
, xAttr
);
152 i_rContext
.mxCurrentHandler
= i_rContext
.mxDocHandler
->createUnknownChildContext( aNamespace
, aElementName
, xAttr
);
154 if( i_rContext
.mxCurrentHandler
.is() )
155 i_rContext
.mxCurrentHandler
->startUnknownElement( aNamespace
, aElementName
, xAttr
);
159 if( xParentHandler
.is() )
160 i_rContext
.mxCurrentHandler
= xParentHandler
->createFastChildContext( nElementToken
, xAttr
);
162 i_rContext
.mxCurrentHandler
= i_rContext
.mxDocHandler
->createFastChildContext( nElementToken
, xAttr
);
164 if( i_rContext
.mxCurrentHandler
.is() )
165 i_rContext
.mxCurrentHandler
->startFastElement( nElementToken
, xAttr
);
172 for (xmlNodePtr pChild
= m_aNodePtr
->children
;
173 pChild
!= 0; pChild
= pChild
->next
) {
174 ::rtl::Reference
<CNode
> const pNode(
175 GetOwnerDocument().GetCNode(pChild
));
176 OSL_ENSURE(pNode
!= 0, "CNode::get returned 0");
177 pNode
->fastSaxify(i_rContext
);
180 if( i_rContext
.mxCurrentHandler
.is() ) try
182 if( nElementToken
!= FastToken::DONTKNOW
)
183 i_rContext
.mxCurrentHandler
->endFastElement( nElementToken
);
186 const OUString aNamespace
;
187 const OUString
aElementName( (sal_Char
*)xPrefix
,
188 strlen((char*)xPrefix
),
189 RTL_TEXTENCODING_UTF8
);
191 i_rContext
.mxCurrentHandler
->endUnknownElement( aNamespace
, aElementName
);
197 // restore after children have been processed
198 i_rContext
.mxCurrentHandler
= xParentHandler
;
199 popContext(i_rContext
);
202 bool CElement::IsChildTypeAllowed(NodeType
const nodeType
)
205 case NodeType_ELEMENT_NODE
:
206 case NodeType_TEXT_NODE
:
207 case NodeType_COMMENT_NODE
:
208 case NodeType_PROCESSING_INSTRUCTION_NODE
:
209 case NodeType_CDATA_SECTION_NODE
:
210 case NodeType_ENTITY_REFERENCE_NODE
:
212 case NodeType_ATTRIBUTE_NODE
:
213 /* this is not relly allowed by the DOM spec, but this
214 implementation has evidently supported it (by special case
215 handling, so the attribute does not actually become a child)
216 so allow it for backward compatiblity */
225 Retrieves an attribute value by name.
226 return empty string if attribute is not set
228 OUString SAL_CALL
CElement::getAttribute(OUString
const& name
)
229 throw (RuntimeException
)
231 ::osl::MutexGuard
const g(m_rMutex
);
233 if (0 == m_aNodePtr
) {
237 OString o1
= OUStringToOString(name
, RTL_TEXTENCODING_UTF8
);
238 ::boost::shared_ptr
<xmlChar
const> const pValue(
239 xmlGetProp(m_aNodePtr
, (xmlChar
*)o1
.getStr()), xmlFree
);
240 OUString
const ret( (pValue
)
241 ? OUString(reinterpret_cast<sal_Char
const*>(pValue
.get()),
242 strlen(reinterpret_cast<char const*>(pValue
.get())),
243 RTL_TEXTENCODING_UTF8
)
249 Retrieves an attribute node by name.
251 Reference
< XAttr
> SAL_CALL
CElement::getAttributeNode(OUString
const& name
)
252 throw (RuntimeException
)
254 ::osl::MutexGuard
const g(m_rMutex
);
256 if (0 == m_aNodePtr
) {
259 OString o1
= OUStringToOString(name
, RTL_TEXTENCODING_UTF8
);
260 xmlChar
const*const pName
=
261 reinterpret_cast<xmlChar
const*>(o1
.getStr());
262 xmlAttrPtr
const pAttr
= xmlHasProp(m_aNodePtr
, pName
);
266 Reference
< XAttr
> const xRet(
267 static_cast< XNode
* >(GetOwnerDocument().GetCNode(
268 reinterpret_cast<xmlNodePtr
>(pAttr
)).get()),
274 Retrieves an Attr node by local name and namespace URI.
276 Reference
< XAttr
> SAL_CALL
CElement::getAttributeNodeNS(
277 const OUString
& namespaceURI
, const OUString
& localName
)
278 throw (RuntimeException
)
280 ::osl::MutexGuard
const g(m_rMutex
);
282 if (0 == m_aNodePtr
) {
285 OString o1
= OUStringToOString(localName
, RTL_TEXTENCODING_UTF8
);
286 xmlChar
const*const pName
=
287 reinterpret_cast<xmlChar
const*>(o1
.getStr());
288 OString o2
= OUStringToOString(namespaceURI
, RTL_TEXTENCODING_UTF8
);
289 xmlChar
const*const pNS
=
290 reinterpret_cast<xmlChar
const*>(o2
.getStr());
291 xmlAttrPtr
const pAttr
= xmlHasNsProp(m_aNodePtr
, pName
, pNS
);
295 Reference
< XAttr
> const xRet(
296 static_cast< XNode
* >(GetOwnerDocument().GetCNode(
297 reinterpret_cast<xmlNodePtr
>(pAttr
)).get()),
303 Retrieves an attribute value by local name and namespace URI.
304 return empty string if attribute is not set
307 CElement::getAttributeNS(
308 OUString
const& namespaceURI
, OUString
const& localName
)
309 throw (RuntimeException
)
311 ::osl::MutexGuard
const g(m_rMutex
);
313 if (0 == m_aNodePtr
) {
316 OString o1
= OUStringToOString(localName
, RTL_TEXTENCODING_UTF8
);
317 xmlChar
const*const pName
=
318 reinterpret_cast<xmlChar
const*>(o1
.getStr());
319 OString o2
= OUStringToOString(namespaceURI
, RTL_TEXTENCODING_UTF8
);
320 xmlChar
const*const pNS
=
321 reinterpret_cast<xmlChar
const*>(o2
.getStr());
322 ::boost::shared_ptr
<xmlChar
const> const pValue(
323 xmlGetNsProp(m_aNodePtr
, pName
, pNS
), xmlFree
);
327 OUString
const ret(reinterpret_cast<sal_Char
const*>(pValue
.get()),
328 strlen(reinterpret_cast<char const*>(pValue
.get())),
329 RTL_TEXTENCODING_UTF8
);
334 Returns a NodeList of all descendant Elements with a given tag name,
335 in the order in which they are
336 encountered in a preorder traversal of this Element tree.
338 Reference
< XNodeList
> SAL_CALL
339 CElement::getElementsByTagName(OUString
const& rLocalName
)
340 throw (RuntimeException
)
342 ::osl::MutexGuard
const g(m_rMutex
);
344 Reference
< XNodeList
> const xList(
345 new CElementList(this, m_rMutex
, rLocalName
));
350 Returns a NodeList of all the descendant Elements with a given local
351 name and namespace URI in the order in which they are encountered in
352 a preorder traversal of this Element tree.
354 Reference
< XNodeList
> SAL_CALL
355 CElement::getElementsByTagNameNS(
356 OUString
const& rNamespaceURI
, OUString
const& rLocalName
)
357 throw (RuntimeException
)
359 ::osl::MutexGuard
const g(m_rMutex
);
361 Reference
< XNodeList
> const xList(
362 new CElementList(this, m_rMutex
, rLocalName
, &rNamespaceURI
));
367 The name of the element.
369 OUString SAL_CALL
CElement::getTagName()
370 throw (RuntimeException
)
372 ::osl::MutexGuard
const g(m_rMutex
);
374 if (0 == m_aNodePtr
) {
377 OUString
const ret((sal_Char
*)m_aNodePtr
->name
,
378 strlen((char*)m_aNodePtr
->name
), RTL_TEXTENCODING_UTF8
);
384 Returns true when an attribute with a given name is specified on this
385 element or has a default value, false otherwise.
387 sal_Bool SAL_CALL
CElement::hasAttribute(OUString
const& name
)
388 throw (RuntimeException
)
390 ::osl::MutexGuard
const g(m_rMutex
);
392 OString o1
= OUStringToOString(name
, RTL_TEXTENCODING_UTF8
);
393 xmlChar
*xName
= (xmlChar
*)o1
.getStr();
394 return (m_aNodePtr
!= NULL
&& xmlHasProp(m_aNodePtr
, xName
) != NULL
);
398 Returns true when an attribute with a given local name and namespace
399 URI is specified on this element or has a default value, false otherwise.
401 sal_Bool SAL_CALL
CElement::hasAttributeNS(
402 OUString
const& namespaceURI
, OUString
const& localName
)
403 throw (RuntimeException
)
405 ::osl::MutexGuard
const g(m_rMutex
);
407 OString o1
= OUStringToOString(localName
, RTL_TEXTENCODING_UTF8
);
408 xmlChar
*xName
= (xmlChar
*)o1
.getStr();
409 OString o2
= OUStringToOString(namespaceURI
, RTL_TEXTENCODING_UTF8
);
410 xmlChar
*xNs
= (xmlChar
*)o2
.getStr();
411 return (m_aNodePtr
!= NULL
&& xmlHasNsProp(m_aNodePtr
, xName
, xNs
) != NULL
);
415 Removes an attribute by name.
417 void SAL_CALL
CElement::removeAttribute(OUString
const& name
)
418 throw (RuntimeException
, DOMException
)
420 ::osl::MutexGuard
const g(m_rMutex
);
422 if (0 == m_aNodePtr
) {
425 OString o1
= OUStringToOString(name
, RTL_TEXTENCODING_UTF8
);
426 xmlChar
const*const pName
=
427 reinterpret_cast<xmlChar
const*>(o1
.getStr());
428 xmlAttrPtr
const pAttr
= xmlHasProp(m_aNodePtr
, pName
);
429 if (0 == xmlUnsetProp(m_aNodePtr
, pName
)) {
430 ::rtl::Reference
<CNode
> const pCNode(GetOwnerDocument().GetCNode(
431 reinterpret_cast<xmlNodePtr
>(pAttr
), false));
433 pCNode
->invalidate(); // freed by xmlUnsetProp
439 Removes an attribute by local name and namespace URI.
441 void SAL_CALL
CElement::removeAttributeNS(
442 OUString
const& namespaceURI
, OUString
const& localName
)
443 throw (RuntimeException
, DOMException
)
445 ::osl::MutexGuard
const g(m_rMutex
);
447 if (0 == m_aNodePtr
) {
450 OString o1
= OUStringToOString(localName
, RTL_TEXTENCODING_UTF8
);
451 xmlChar
const*const pName
=
452 reinterpret_cast<xmlChar
const*>(o1
.getStr());
453 OString o2
= OUStringToOString(namespaceURI
, RTL_TEXTENCODING_UTF8
);
454 xmlChar
const*const pURI
=
455 reinterpret_cast<xmlChar
const*>(o2
.getStr());
457 xmlSearchNsByHref(m_aNodePtr
->doc
, m_aNodePtr
, pURI
);
458 xmlAttrPtr
const pAttr
= xmlHasNsProp(m_aNodePtr
, pName
, pURI
);
459 if (0 == xmlUnsetNsProp(m_aNodePtr
, pNs
, pName
)) {
460 ::rtl::Reference
<CNode
> const pCNode(GetOwnerDocument().GetCNode(
461 reinterpret_cast<xmlNodePtr
>(pAttr
), false));
463 pCNode
->invalidate(); // freed by xmlUnsetNsProp
469 Removes the specified attribute node.
471 Reference
< XAttr
> SAL_CALL
472 CElement::removeAttributeNode(Reference
< XAttr
> const& oldAttr
)
473 throw (RuntimeException
, DOMException
)
475 ::osl::MutexGuard
const g(m_rMutex
);
477 if (0 == m_aNodePtr
) {
481 ::rtl::Reference
<CNode
> const pCNode(
482 CNode::GetImplementation(Reference
<XNode
>(oldAttr
.get())));
483 if (!pCNode
.is()) { throw RuntimeException(); }
485 xmlNodePtr
const pNode
= pCNode
->GetNodePtr();
486 xmlAttrPtr
const pAttr
= (xmlAttrPtr
) pNode
;
487 if (!pAttr
) { throw RuntimeException(); }
489 if (pAttr
->parent
!= m_aNodePtr
)
492 e
.Code
= DOMExceptionType_HIERARCHY_REQUEST_ERR
;
495 if (pAttr
->doc
!= m_aNodePtr
->doc
)
498 e
.Code
= DOMExceptionType_WRONG_DOCUMENT_ERR
;
502 Reference
< XAttr
> aAttr
;
503 if (!oldAttr
->getNamespaceURI().isEmpty()) {
504 OUStringBuffer
qname(oldAttr
->getPrefix());
505 if (0 != qname
.getLength()) {
506 qname
.append(sal_Unicode(':'));
508 qname
.append(oldAttr
->getName());
509 aAttr
= GetOwnerDocument().createAttributeNS(
510 oldAttr
->getNamespaceURI(), qname
.makeStringAndClear());
512 aAttr
= GetOwnerDocument().createAttribute(oldAttr
->getName());
514 aAttr
->setValue(oldAttr
->getValue());
515 xmlRemoveProp(pAttr
);
516 pCNode
->invalidate(); // freed by xmlRemoveProp
522 Adds a new attribute node.
525 CElement::setAttributeNode_Impl_Lock(
526 Reference
< XAttr
> const& xNewAttr
, bool const bNS
)
528 if (xNewAttr
->getOwnerDocument() != getOwnerDocument()) {
530 e
.Code
= DOMExceptionType_WRONG_DOCUMENT_ERR
;
534 ::osl::ClearableMutexGuard
guard(m_rMutex
);
536 if (0 == m_aNodePtr
) {
537 throw RuntimeException();
540 // get the implementation
541 CAttr
*const pCAttr
= dynamic_cast<CAttr
*>(
542 CNode::GetImplementation(xNewAttr
));
543 if (!pCAttr
) { throw RuntimeException(); }
544 xmlAttrPtr
const pAttr
=
545 reinterpret_cast<xmlAttrPtr
>(pCAttr
->GetNodePtr());
546 if (!pAttr
) { throw RuntimeException(); }
548 // check whether the attribute is not in use by another element
551 e
.Code
= DOMExceptionType_INUSE_ATTRIBUTE_ERR
;
555 xmlAttrPtr res
= NULL
;
556 xmlChar
const*const pContent(
557 (pAttr
->children
) ? pAttr
->children
->content
: 0);
560 xmlNsPtr
const pNs( pCAttr
->GetNamespace(m_aNodePtr
) );
561 res
= xmlNewNsProp(m_aNodePtr
, pNs
, pAttr
->name
, pContent
);
563 res
= xmlNewProp(m_aNodePtr
, pAttr
->name
, pContent
);
566 // get the new attr node
567 Reference
< XAttr
> const xAttr(
568 static_cast< XNode
* >(GetOwnerDocument().GetCNode(
569 reinterpret_cast<xmlNodePtr
>(res
)).get()),
572 // attribute addition event
573 // dispatch DOMAttrModified event
574 Reference
< XDocumentEvent
> docevent(getOwnerDocument(), UNO_QUERY
);
575 Reference
< XMutationEvent
> event(docevent
->createEvent(
576 "DOMAttrModified"), UNO_QUERY
);
577 event
->initMutationEvent("DOMAttrModified",
578 sal_True
, sal_False
, Reference
< XNode
>(xAttr
, UNO_QUERY
),
579 OUString(), xAttr
->getValue(), xAttr
->getName(),
580 AttrChangeType_ADDITION
);
582 guard
.clear(); // release mutex before calling event handlers
584 dispatchEvent(Reference
< XEvent
>(event
, UNO_QUERY
));
585 dispatchSubtreeModified();
591 CElement::setAttributeNode(const Reference
< XAttr
>& newAttr
)
592 throw (RuntimeException
, DOMException
)
594 return setAttributeNode_Impl_Lock(newAttr
, false);
598 Adds a new attribute.
601 CElement::setAttributeNodeNS(const Reference
< XAttr
>& newAttr
)
602 throw (RuntimeException
, DOMException
)
604 return setAttributeNode_Impl_Lock(newAttr
, true);
608 Adds a new attribute.
611 CElement::setAttribute(OUString
const& name
, OUString
const& value
)
612 throw (RuntimeException
, DOMException
)
614 ::osl::ClearableMutexGuard
guard(m_rMutex
);
616 OString o1
= OUStringToOString(name
, RTL_TEXTENCODING_UTF8
);
617 xmlChar
*xName
= (xmlChar
*)o1
.getStr();
618 OString o2
= OUStringToOString(value
, RTL_TEXTENCODING_UTF8
);
619 xmlChar
*xValue
= (xmlChar
*)o2
.getStr();
621 if (0 == m_aNodePtr
) {
622 throw RuntimeException();
625 AttrChangeType aChangeType
= AttrChangeType_MODIFICATION
;
626 ::boost::shared_ptr
<xmlChar
const> const pOld(
627 xmlGetProp(m_aNodePtr
, xName
), xmlFree
);
629 aChangeType
= AttrChangeType_ADDITION
;
630 xmlNewProp(m_aNodePtr
, xName
, xValue
);
632 oldValue
= OUString(reinterpret_cast<sal_Char
const*>(pOld
.get()),
633 strlen(reinterpret_cast<char const*>(pOld
.get())),
634 RTL_TEXTENCODING_UTF8
);
635 xmlSetProp(m_aNodePtr
, xName
, xValue
);
638 // dispatch DOMAttrModified event
639 Reference
< XDocumentEvent
> docevent(getOwnerDocument(), UNO_QUERY
);
640 Reference
< XMutationEvent
> event(docevent
->createEvent(
641 "DOMAttrModified"), UNO_QUERY
);
642 event
->initMutationEvent("DOMAttrModified",
644 Reference
< XNode
>(getAttributeNode(name
), UNO_QUERY
),
645 oldValue
, value
, name
, aChangeType
);
647 guard
.clear(); // release mutex before calling event handlers
648 dispatchEvent(Reference
< XEvent
>(event
, UNO_QUERY
));
649 dispatchSubtreeModified();
653 Adds a new attribute.
656 CElement::setAttributeNS(OUString
const& namespaceURI
,
657 OUString
const& qualifiedName
, OUString
const& value
)
658 throw (RuntimeException
, DOMException
)
660 if (namespaceURI
.isEmpty()) throw RuntimeException();
662 ::osl::ClearableMutexGuard
guard(m_rMutex
);
664 OString o1
, o2
, o3
, o4
, o5
;
665 xmlChar
*xPrefix
= NULL
;
666 xmlChar
*xLName
= NULL
;
667 o1
= OUStringToOString(qualifiedName
, RTL_TEXTENCODING_UTF8
);
668 xmlChar
*xQName
= (xmlChar
*)o1
.getStr();
669 sal_Int32 idx
= qualifiedName
.indexOf(':');
672 o2
= OUStringToOString(
673 qualifiedName
.copy(0,idx
),
674 RTL_TEXTENCODING_UTF8
);
675 xPrefix
= (xmlChar
*)o2
.getStr();
676 o3
= OUStringToOString(
677 qualifiedName
.copy(idx
+1),
678 RTL_TEXTENCODING_UTF8
);
679 xLName
= (xmlChar
*)o3
.getStr();
681 xPrefix
= (xmlChar
*)"";
684 o4
= OUStringToOString(namespaceURI
, RTL_TEXTENCODING_UTF8
);
685 o5
= OUStringToOString(value
, RTL_TEXTENCODING_UTF8
);
686 xmlChar
*xURI
= (xmlChar
*)o4
.getStr();
687 xmlChar
*xValue
= (xmlChar
*)o5
.getStr();
689 if (0 == m_aNodePtr
) {
690 throw RuntimeException();
693 //find the right namespace
694 xmlNsPtr pNs
= xmlSearchNs(m_aNodePtr
->doc
, m_aNodePtr
, xPrefix
);
695 // if no namespace found, create a new one
697 pNs
= xmlNewNs(m_aNodePtr
, xURI
, xPrefix
);
700 if (strcmp((char*)pNs
->href
, (char*)xURI
) != 0) {
701 // ambiguous ns prefix
702 throw RuntimeException();
705 // found namespace matches
708 AttrChangeType aChangeType
= AttrChangeType_MODIFICATION
;
709 ::boost::shared_ptr
<xmlChar
const> const pOld(
710 xmlGetNsProp(m_aNodePtr
, xLName
, pNs
->href
), xmlFree
);
712 aChangeType
= AttrChangeType_ADDITION
;
713 xmlNewNsProp(m_aNodePtr
, pNs
, xLName
, xValue
);
715 oldValue
= OUString(reinterpret_cast<sal_Char
const*>(pOld
.get()),
716 strlen(reinterpret_cast<char const*>(pOld
.get())),
717 RTL_TEXTENCODING_UTF8
);
718 xmlSetNsProp(m_aNodePtr
, pNs
, xLName
, xValue
);
720 // dispatch DOMAttrModified event
721 Reference
< XDocumentEvent
> docevent(getOwnerDocument(), UNO_QUERY
);
722 Reference
< XMutationEvent
> event(docevent
->createEvent(
723 "DOMAttrModified"), UNO_QUERY
);
724 event
->initMutationEvent(
725 "DOMAttrModified", sal_True
, sal_False
,
726 Reference
< XNode
>(getAttributeNodeNS(namespaceURI
, OUString((char*)xLName
, strlen((char*)xLName
), RTL_TEXTENCODING_UTF8
)), UNO_QUERY
),
727 oldValue
, value
, qualifiedName
, aChangeType
);
729 guard
.clear(); // release mutex before calling event handlers
730 dispatchEvent(Reference
< XEvent
>(event
, UNO_QUERY
));
731 dispatchSubtreeModified();
734 Reference
< XNamedNodeMap
> SAL_CALL
735 CElement::getAttributes() throw (RuntimeException
)
737 ::osl::MutexGuard
const g(m_rMutex
);
739 Reference
< XNamedNodeMap
> const xMap(
740 new CAttributesMap(this, m_rMutex
));
744 OUString SAL_CALL
CElement::getNodeName()throw (RuntimeException
)
746 return getLocalName();
749 OUString SAL_CALL
CElement::getLocalName()throw (RuntimeException
)
751 ::osl::MutexGuard
const g(m_rMutex
);
754 if (m_aNodePtr
!= NULL
)
756 const xmlChar
* xName
= m_aNodePtr
->name
;
757 aName
= OUString((const sal_Char
*)xName
, strlen((const char*)xName
), RTL_TEXTENCODING_UTF8
);
762 OUString SAL_CALL
CElement::getNodeValue() throw (RuntimeException
)
767 void SAL_CALL
CElement::setElementName(const OUString
& aName
)
768 throw (RuntimeException
, DOMException
)
770 if (aName
.isEmpty() || (0 <= aName
.indexOf(':')))
773 e
.Code
= DOMExceptionType_INVALID_CHARACTER_ERR
;
777 ::osl::MutexGuard
const g(m_rMutex
);
779 if (0 == m_aNodePtr
) {
780 throw RuntimeException();
782 OString oName
= OUStringToOString(aName
, RTL_TEXTENCODING_UTF8
);
783 xmlChar
*xName
= (xmlChar
*)oName
.getStr();
784 xmlNodeSetName(m_aNodePtr
, xName
);
789 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */