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 164 /** 165 Returns a duplicate of this node, i.e., serves as a generic copy 166 constructor for nodes. 167 */ 168 virtual Reference< XNode > SAL_CALL cloneNode(sal_Bool deep); 169 170 /** 171 A NamedNodeMap containing the attributes of this node 172 (if it is an Element) or null otherwise. 173 */ 174 virtual Reference< XNamedNodeMap > SAL_CALL getAttributes(); 175 176 /** 177 A NodeList that contains all children of this node. 178 */ 179 virtual Reference< XNodeList > SAL_CALL getChildNodes(); 180 181 /** 182 The first child of this node. 183 */ 184 virtual Reference< XNode > SAL_CALL getFirstChild(); 185 186 /** 187 The last child of this node. 188 */ 189 virtual Reference< XNode > SAL_CALL getLastChild(); 190 191 /** 192 Returns the local part of the qualified name of this node. 193 */ 194 virtual OUString SAL_CALL getLocalName(); 195 196 /** 197 The namespace URI of this node, or null if it is unspecified. 198 */ 199 virtual OUString SAL_CALL getNamespaceURI(); 200 201 /** 202 The node immediately following this node. 203 */ 204 virtual Reference< XNode > SAL_CALL getNextSibling(); 205 206 /** 207 The name of this node, depending on its type; see the table above. 208 -- virtual implemented by actual node types 209 */ 210 virtual OUString SAL_CALL getNodeName(); 211 212 /** 213 A code representing the type of the underlying object, as defined above. 214 */ 215 virtual NodeType SAL_CALL getNodeType(); 216 217 /** 218 The value of this node, depending on its type; see the table above. 219 -- virtual implemented by actual node types 220 */ 221 virtual OUString SAL_CALL getNodeValue(); 222 223 /** 224 The Document object associated with this node. 225 */ 226 virtual Reference< XDocument > SAL_CALL getOwnerDocument(); 227 228 /** 229 The parent of this node. 230 */ 231 virtual Reference< XNode > SAL_CALL getParentNode(); 232 233 /** 234 The namespace prefix of this node, or null if it is unspecified. 235 */ 236 virtual OUString SAL_CALL getPrefix(); 237 238 /** 239 The node immediately preceding this node. 240 */ 241 virtual Reference< XNode > SAL_CALL getPreviousSibling(); 242 243 /** 244 Returns whether this node (if it is an element) has any attributes. 245 */ 246 virtual sal_Bool SAL_CALL hasAttributes(); 247 248 /** 249 Returns whether this node has any children. 250 */ 251 virtual sal_Bool SAL_CALL hasChildNodes(); 252 253 /** 254 Inserts the node newChild before the existing child node refChild. 255 */ 256 virtual Reference< XNode > SAL_CALL insertBefore( 257 const Reference< XNode >& newChild, const Reference< XNode >& refChild); 258 259 /** 260 Tests whether the DOM implementation implements a specific feature and 261 that feature is supported by this node. 262 */ 263 virtual sal_Bool SAL_CALL isSupported(const OUString& feature, const OUString& ver); 264 265 /** 266 Puts all Text nodes in the full depth of the sub-tree underneath this 267 Node, including attribute nodes, into a "normal" form where only structure 268 (e.g., elements, comments, processing instructions, CDATA sections, and 269 entity references) separates Text nodes, i.e., there are neither adjacent 270 Text nodes nor empty Text nodes. 271 */ 272 virtual void SAL_CALL normalize(); 273 274 /** 275 Removes the child node indicated by oldChild from the list of children, 276 and returns it. 277 */ 278 virtual Reference< XNode > SAL_CALL removeChild(const Reference< XNode >& oldChild); 279 280 /** 281 Replaces the child node oldChild with newChild in the list of children, 282 and returns the oldChild node. 283 */ 284 virtual Reference< XNode > SAL_CALL replaceChild( 285 const Reference< XNode >& newChild, const Reference< XNode >& oldChild); 286 287 /** 288 The value of this node, depending on its type; see the table above. 289 */ 290 virtual void SAL_CALL setNodeValue(const OUString& nodeValue); 291 292 /** 293 The namespace prefix of this node, or null if it is unspecified. 294 */ 295 virtual void SAL_CALL setPrefix(const OUString& prefix); 296 297 298 // --- XEventTarget 299 virtual void SAL_CALL addEventListener(const OUString& eventType, 300 const Reference< XEventListener >& listener, 301 sal_Bool useCapture); 302 303 virtual void SAL_CALL removeEventListener(const OUString& eventType, 304 const Reference< XEventListener >& listener, 305 sal_Bool useCapture); 306 307 virtual sal_Bool SAL_CALL dispatchEvent(const Reference< XEvent >& evt); 308 309 // --- XUnoTunnel 310 virtual ::sal_Int64 SAL_CALL 311 getSomething(Sequence< ::sal_Int8 > const& rId); 312 }; 313 314 /// eliminate redundant namespace declarations 315 void nscleanup(const xmlNodePtr aNode, const xmlNodePtr aParent); 316 } 317 318 #endif 319