1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef DOM_NODE_HXX 25 #define DOM_NODE_HXX 26 27 #include <hash_map> 28 29 #include <libxml/tree.h> 30 31 #include <sal/types.h> 32 #include <rtl/ref.hxx> 33 #include <rtl/string.hxx> 34 #include <rtl/ustring.hxx> 35 36 #include <cppuhelper/implbase3.hxx> 37 38 #include <sax/fastattribs.hxx> 39 40 #include <com/sun/star/uno/Reference.h> 41 #include <com/sun/star/uno/Sequence.h> 42 #include <com/sun/star/lang/XUnoTunnel.hpp> 43 #include <com/sun/star/xml/dom/XNode.hpp> 44 #include <com/sun/star/xml/dom/XNodeList.hpp> 45 #include <com/sun/star/xml/dom/XNamedNodeMap.hpp> 46 #include <com/sun/star/xml/dom/NodeType.hpp> 47 #include <com/sun/star/xml/dom/events/XEventTarget.hpp> 48 #include <com/sun/star/xml/dom/events/XEvent.hpp> 49 #include <com/sun/star/xml/dom/DOMException.hpp> 50 #include <com/sun/star/xml/sax/XDocumentHandler.hpp> 51 #include <com/sun/star/xml/sax/XFastDocumentHandler.hpp> 52 53 54 using ::rtl::OUString; 55 using ::rtl::OString; 56 using namespace sax_fastparser; 57 using namespace com::sun::star::uno; 58 using namespace com::sun::star::xml::sax; 59 using namespace com::sun::star::xml::dom; 60 using namespace com::sun::star::xml::dom::events; 61 using com::sun::star::lang::XUnoTunnel; 62 63 64 namespace DOM 65 { 66 struct Context 67 { ContextDOM::Context68 Context( const Reference< XFastDocumentHandler >& i_xHandler, 69 const Reference< XFastTokenHandler >& i_xTokenHandler ) : 70 maNamespaces( 1, std::vector<Namespace>() ), 71 maNamespaceMap(101), 72 mxAttribList(new FastAttributeList(i_xTokenHandler)), 73 mxCurrentHandler(i_xHandler, UNO_QUERY_THROW), 74 mxDocHandler(i_xHandler), 75 mxTokenHandler(i_xTokenHandler) 76 {} 77 78 struct Namespace 79 { 80 OString maPrefix; 81 sal_Int32 mnToken; 82 OUString maNamespaceURL; 83 getPrefixDOM::Context::Namespace84 const OString& getPrefix() const { return maPrefix; } 85 }; 86 87 typedef std::vector< std::vector<Namespace> > NamespaceVectorType; 88 typedef std::hash_map< OUString, 89 sal_Int32, 90 rtl::OUStringHash > NamespaceMapType; 91 92 /// outer vector: xml context; inner vector: current NS 93 NamespaceVectorType maNamespaces; 94 NamespaceMapType maNamespaceMap; 95 ::rtl::Reference<FastAttributeList> mxAttribList; 96 Reference<XFastContextHandler> mxCurrentHandler; 97 Reference<XFastDocumentHandler> mxDocHandler; 98 Reference<XFastTokenHandler> mxTokenHandler; 99 }; 100 101 void pushContext(Context& io_rContext); 102 void popContext(Context& io_rContext); 103 104 sal_Int32 getTokenWithPrefix( const Context& rContext, const sal_Char* xPrefix, const sal_Char* xName ); 105 sal_Int32 getToken( const Context& rContext, const sal_Char* xName ); 106 107 /// add namespaces on this node to context 108 void addNamespaces(Context& io_rContext, xmlNodePtr pNode); 109 110 class CDocument; 111 112 class CNode : public cppu::WeakImplHelper3< XNode, XUnoTunnel, XEventTarget > 113 { 114 friend class CDocument; 115 friend class CElement; 116 friend class CAttributesMap; 117 118 private: 119 bool m_bUnlinked; /// node has been removed from document 120 121 protected: 122 NodeType const m_aNodeType; 123 /// libxml node; NB: not const, because invalidate may reset it to 0! 124 xmlNodePtr m_aNodePtr; 125 126 ::rtl::Reference< CDocument > const m_xDocument; 127 ::osl::Mutex & m_rMutex; 128 129 // for initialization by classes derived through ImplInheritanceHelper 130 CNode(CDocument const& rDocument, ::osl::Mutex const& rMutex, 131 NodeType const& reNodeType, xmlNodePtr const& rpNode); 132 void invalidate(); 133 134 void dispatchSubtreeModified(); 135 136 public: 137 138 virtual ~CNode(); 139 140 static CNode * GetImplementation(::com::sun::star::uno::Reference< 141 ::com::sun::star::uno::XInterface> const& xNode); 142 GetNodePtr()143 xmlNodePtr GetNodePtr() { return m_aNodePtr; } 144 145 virtual CDocument & GetOwnerDocument(); 146 147 // recursively create SAX events 148 virtual void saxify(const Reference< XDocumentHandler >& i_xHandler); 149 150 // recursively create SAX events 151 virtual void fastSaxify( Context& io_rContext ); 152 153 // constrains child relationship between nodes based on type 154 virtual bool IsChildTypeAllowed(NodeType const nodeType); 155 156 // ---- DOM interfaces 157 158 /** 159 Adds the node newChild to the end of the list of children of this node. 160 */ 161 virtual Reference< XNode > SAL_CALL 162 appendChild(Reference< XNode > const& xNewChild) 163 throw (RuntimeException, DOMException); 164 165 /** 166 Returns a duplicate of this node, i.e., serves as a generic copy 167 constructor for nodes. 168 */ 169 virtual Reference< XNode > SAL_CALL cloneNode(sal_Bool deep) 170 throw (RuntimeException); 171 172 /** 173 A NamedNodeMap containing the attributes of this node 174 (if it is an Element) or null otherwise. 175 */ 176 virtual Reference< XNamedNodeMap > SAL_CALL getAttributes() 177 throw (RuntimeException); 178 179 /** 180 A NodeList that contains all children of this node. 181 */ 182 virtual Reference< XNodeList > SAL_CALL getChildNodes() 183 throw (RuntimeException); 184 185 /** 186 The first child of this node. 187 */ 188 virtual Reference< XNode > SAL_CALL getFirstChild() 189 throw (RuntimeException); 190 191 /** 192 The last child of this node. 193 */ 194 virtual Reference< XNode > SAL_CALL getLastChild() 195 throw (RuntimeException); 196 197 /** 198 Returns the local part of the qualified name of this node. 199 */ 200 virtual OUString SAL_CALL getLocalName() 201 throw (RuntimeException); 202 203 /** 204 The namespace URI of this node, or null if it is unspecified. 205 */ 206 virtual OUString SAL_CALL getNamespaceURI() 207 throw (RuntimeException); 208 209 /** 210 The node immediately following this node. 211 */ 212 virtual Reference< XNode > SAL_CALL getNextSibling() 213 throw (RuntimeException); 214 215 /** 216 The name of this node, depending on its type; see the table above. 217 -- virtual implemented by actual node types 218 */ 219 virtual OUString SAL_CALL getNodeName() 220 throw (RuntimeException); 221 222 /** 223 A code representing the type of the underlying object, as defined above. 224 */ 225 virtual NodeType SAL_CALL getNodeType() 226 throw (RuntimeException); 227 228 /** 229 The value of this node, depending on its type; see the table above. 230 -- virtual implemented by actual node types 231 */ 232 virtual OUString SAL_CALL getNodeValue() 233 throw (RuntimeException); 234 235 /** 236 The Document object associated with this node. 237 */ 238 virtual Reference< XDocument > SAL_CALL getOwnerDocument() 239 throw (RuntimeException); 240 241 /** 242 The parent of this node. 243 */ 244 virtual Reference< XNode > SAL_CALL getParentNode() 245 throw (RuntimeException); 246 247 /** 248 The namespace prefix of this node, or null if it is unspecified. 249 */ 250 virtual OUString SAL_CALL getPrefix() 251 throw (RuntimeException); 252 253 /** 254 The node immediately preceding this node. 255 */ 256 virtual Reference< XNode > SAL_CALL getPreviousSibling() 257 throw (RuntimeException); 258 259 /** 260 Returns whether this node (if it is an element) has any attributes. 261 */ 262 virtual sal_Bool SAL_CALL hasAttributes() 263 throw (RuntimeException); 264 265 /** 266 Returns whether this node has any children. 267 */ 268 virtual sal_Bool SAL_CALL hasChildNodes() 269 throw (RuntimeException); 270 271 /** 272 Inserts the node newChild before the existing child node refChild. 273 */ 274 virtual Reference< XNode > SAL_CALL insertBefore( 275 const Reference< XNode >& newChild, const Reference< XNode >& refChild) 276 throw (RuntimeException, DOMException); 277 278 /** 279 Tests whether the DOM implementation implements a specific feature and 280 that feature is supported by this node. 281 */ 282 virtual sal_Bool SAL_CALL isSupported(const OUString& feature, const OUString& ver) 283 throw (RuntimeException); 284 285 /** 286 Puts all Text nodes in the full depth of the sub-tree underneath this 287 Node, including attribute nodes, into a "normal" form where only structure 288 (e.g., elements, comments, processing instructions, CDATA sections, and 289 entity references) separates Text nodes, i.e., there are neither adjacent 290 Text nodes nor empty Text nodes. 291 */ 292 virtual void SAL_CALL normalize() 293 throw (RuntimeException); 294 295 /** 296 Removes the child node indicated by oldChild from the list of children, 297 and returns it. 298 */ 299 virtual Reference< XNode > SAL_CALL removeChild(const Reference< XNode >& oldChild) 300 throw (RuntimeException, DOMException); 301 302 /** 303 Replaces the child node oldChild with newChild in the list of children, 304 and returns the oldChild node. 305 */ 306 virtual Reference< XNode > SAL_CALL replaceChild( 307 const Reference< XNode >& newChild, const Reference< XNode >& oldChild) 308 throw (RuntimeException, DOMException); 309 310 /** 311 The value of this node, depending on its type; see the table above. 312 */ 313 virtual void SAL_CALL setNodeValue(const OUString& nodeValue) 314 throw (RuntimeException, DOMException); 315 316 /** 317 The namespace prefix of this node, or null if it is unspecified. 318 */ 319 virtual void SAL_CALL setPrefix(const OUString& prefix) 320 throw (RuntimeException, DOMException); 321 322 323 // --- XEventTarget 324 virtual void SAL_CALL addEventListener(const OUString& eventType, 325 const Reference< XEventListener >& listener, 326 sal_Bool useCapture) 327 throw (RuntimeException); 328 329 virtual void SAL_CALL removeEventListener(const OUString& eventType, 330 const Reference< XEventListener >& listener, 331 sal_Bool useCapture) 332 throw (RuntimeException); 333 334 virtual sal_Bool SAL_CALL dispatchEvent(const Reference< XEvent >& evt) 335 throw(RuntimeException, EventException); 336 337 // --- XUnoTunnel 338 virtual ::sal_Int64 SAL_CALL 339 getSomething(Sequence< ::sal_Int8 > const& rId) 340 throw (RuntimeException); 341 }; 342 343 /// eliminate redundant namespace declarations 344 void nscleanup(const xmlNodePtr aNode, const xmlNodePtr aParent); 345 } 346 347 #endif 348