/src/libreoffice/unoxml/inc/node.hxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
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/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
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 . |
18 | | */ |
19 | | |
20 | | #pragma once |
21 | | |
22 | | #include <libxml/tree.h> |
23 | | |
24 | | #include <sal/types.h> |
25 | | #include <rtl/ref.hxx> |
26 | | #include <rtl/string.hxx> |
27 | | #include <rtl/ustring.hxx> |
28 | | |
29 | | #include <cppuhelper/implbase.hxx> |
30 | | |
31 | | #include <sax/fastattribs.hxx> |
32 | | |
33 | | #include <com/sun/star/uno/Reference.h> |
34 | | #include <com/sun/star/uno/Sequence.h> |
35 | | #include <com/sun/star/xml/dom/XNode.hpp> |
36 | | #include <com/sun/star/xml/dom/XNodeList.hpp> |
37 | | #include <com/sun/star/xml/dom/XNamedNodeMap.hpp> |
38 | | #include <com/sun/star/xml/dom/NodeType.hpp> |
39 | | #include <com/sun/star/xml/dom/events/XEventTarget.hpp> |
40 | | #include <com/sun/star/xml/dom/events/XEvent.hpp> |
41 | | #include <com/sun/star/xml/sax/XDocumentHandler.hpp> |
42 | | #include <com/sun/star/xml/sax/XFastDocumentHandler.hpp> |
43 | | |
44 | | #include <unordered_map> |
45 | | |
46 | | namespace DOM |
47 | | { |
48 | | struct Context |
49 | | { |
50 | | Context( const css::uno::Reference< css::xml::sax::XFastDocumentHandler >& i_xHandler, |
51 | | sax_fastparser::FastTokenHandlerBase* pTokenHandler ) : |
52 | 3.42k | maNamespaces( 1, std::vector<Namespace>() ), |
53 | 3.42k | maNamespaceMap(101), |
54 | 3.42k | mxAttribList(new sax_fastparser::FastAttributeList(pTokenHandler)), |
55 | 3.42k | mxCurrentHandler(i_xHandler), |
56 | 3.42k | mxDocHandler(i_xHandler), |
57 | 3.42k | mxTokenHandler(pTokenHandler) |
58 | 3.42k | {} |
59 | | |
60 | | struct Namespace |
61 | | { |
62 | | OString maPrefix; |
63 | | sal_Int32 mnToken; |
64 | | |
65 | 813k | const OString& getPrefix() const { return maPrefix; } |
66 | | }; |
67 | | |
68 | | typedef std::vector< std::vector<Namespace> > NamespaceVectorType; |
69 | | typedef std::unordered_map< OUString, sal_Int32 > NamespaceMapType; |
70 | | |
71 | | /// outer vector: xml context; inner vector: current NS |
72 | | NamespaceVectorType maNamespaces; |
73 | | NamespaceMapType maNamespaceMap; |
74 | | ::rtl::Reference<sax_fastparser::FastAttributeList> mxAttribList; |
75 | | css::uno::Reference<css::xml::sax::XFastContextHandler> mxCurrentHandler; |
76 | | css::uno::Reference<css::xml::sax::XFastDocumentHandler> mxDocHandler; |
77 | | rtl::Reference<sax_fastparser::FastTokenHandlerBase> mxTokenHandler; |
78 | | }; |
79 | | |
80 | | void pushContext(Context& io_rContext); |
81 | | void popContext(Context& io_rContext); |
82 | | |
83 | | sal_Int32 getTokenWithPrefix( const Context& rContext, const char* xPrefix, const char* xName ); |
84 | | sal_Int32 getToken( const Context& rContext, const char* xName ); |
85 | | |
86 | | /// add namespaces on this node to context |
87 | | void addNamespaces(Context& io_rContext, xmlNodePtr pNode); |
88 | | |
89 | | class CDocument; |
90 | | |
91 | | class SAL_LOPLUGIN_ANNOTATE("crosscast") CNode |
92 | | : public cppu::WeakImplHelper< css::xml::dom::XNode, css::xml::dom::events::XEventTarget > |
93 | | { |
94 | | friend class CDocument; |
95 | | friend class CElement; |
96 | | friend class CAttributesMap; |
97 | | |
98 | | private: |
99 | | bool m_bUnlinked; /// node has been removed from document |
100 | | |
101 | | protected: |
102 | | css::xml::dom::NodeType const m_aNodeType; |
103 | | /// libxml node; NB: not const, because invalidate may reset it to 0! |
104 | | xmlNodePtr m_aNodePtr; |
105 | | |
106 | | ::rtl::Reference< CDocument > const m_xDocument; |
107 | | ::osl::Mutex & m_rMutex; |
108 | | |
109 | | // for initialization by classes derived through ImplInheritanceHelper |
110 | | CNode(CDocument const& rDocument, ::osl::Mutex const& rMutex, |
111 | | css::xml::dom::NodeType const& reNodeType, xmlNodePtr const& rpNode); |
112 | | void invalidate(); |
113 | | |
114 | | void dispatchSubtreeModified(); |
115 | | |
116 | | void checkNoParent(css::uno::Reference< css::xml::dom::XNode >const& xNode); |
117 | | |
118 | | static void checkNoParent(const xmlNodePtr pNode); |
119 | | |
120 | | void checkSameOwner(css::uno::Reference< css::xml::dom::XNode >const& xNode); |
121 | | |
122 | | public: |
123 | | |
124 | | virtual ~CNode() override; |
125 | | |
126 | 11.6M | xmlNodePtr GetNodePtr() { return m_aNodePtr; } |
127 | | |
128 | | virtual CDocument & GetOwnerDocument(); |
129 | | |
130 | | // recursively create SAX events |
131 | | virtual void saxify(const css::uno::Reference< css::xml::sax::XDocumentHandler >& i_xHandler); |
132 | | |
133 | | // recursively create SAX events |
134 | | virtual void fastSaxify( Context& io_rContext ); |
135 | | |
136 | | // constrains child relationship between nodes based on type |
137 | | virtual bool IsChildTypeAllowed(css::xml::dom::NodeType nodeType, |
138 | | css::xml::dom::NodeType const* pReplacedNodeType); |
139 | | |
140 | | // ---- DOM interfaces |
141 | | |
142 | | /** |
143 | | Adds the node newChild to the end of the list of children of this node. |
144 | | */ |
145 | | virtual css::uno::Reference< css::xml::dom::XNode > SAL_CALL |
146 | | appendChild(css::uno::Reference< css::xml::dom::XNode > const& xNewChild) override; |
147 | | |
148 | | /** |
149 | | Returns a duplicate of this node, i.e., serves as a generic copy |
150 | | constructor for nodes. |
151 | | */ |
152 | | virtual css::uno::Reference< css::xml::dom::XNode > SAL_CALL cloneNode(sal_Bool deep) override; |
153 | | |
154 | | /** |
155 | | A NamedNodeMap containing the attributes of this node |
156 | | (if it is an Element) or null otherwise. |
157 | | */ |
158 | | virtual css::uno::Reference< css::xml::dom::XNamedNodeMap > SAL_CALL getAttributes() override; |
159 | | |
160 | | /** |
161 | | A NodeList that contains all children of this node. |
162 | | */ |
163 | | virtual css::uno::Reference< css::xml::dom::XNodeList > SAL_CALL getChildNodes() override; |
164 | | |
165 | | /** |
166 | | The first child of this node. |
167 | | */ |
168 | | virtual css::uno::Reference< css::xml::dom::XNode > SAL_CALL getFirstChild() override; |
169 | | |
170 | | /** |
171 | | The last child of this node. |
172 | | */ |
173 | | virtual css::uno::Reference< css::xml::dom::XNode > SAL_CALL getLastChild() override; |
174 | | |
175 | | /** |
176 | | Returns the local part of the qualified name of this node. |
177 | | */ |
178 | | virtual OUString SAL_CALL getLocalName() override; |
179 | | |
180 | | /** |
181 | | The namespace URI of this node, or null if it is unspecified. |
182 | | */ |
183 | | virtual OUString SAL_CALL getNamespaceURI() override; |
184 | | |
185 | | /** |
186 | | The node immediately following this node. |
187 | | */ |
188 | | virtual css::uno::Reference< css::xml::dom::XNode > SAL_CALL getNextSibling() override; |
189 | | |
190 | | /** |
191 | | The name of this node, depending on its type; see the table above. |
192 | | -- virtual implemented by actual node types |
193 | | */ |
194 | | virtual OUString SAL_CALL getNodeName() override; |
195 | | |
196 | | /** |
197 | | A code representing the type of the underlying object, as defined above. |
198 | | */ |
199 | | virtual css::xml::dom::NodeType SAL_CALL getNodeType() override; |
200 | | |
201 | | /** |
202 | | The value of this node, depending on its type; see the table above. |
203 | | -- virtual implemented by actual node types |
204 | | */ |
205 | | virtual OUString SAL_CALL getNodeValue() override; |
206 | | |
207 | | /** |
208 | | The Document object associated with this node. |
209 | | */ |
210 | | virtual css::uno::Reference< css::xml::dom::XDocument > SAL_CALL getOwnerDocument() override; |
211 | | |
212 | | /** |
213 | | The parent of this node. |
214 | | */ |
215 | | virtual css::uno::Reference< css::xml::dom::XNode > SAL_CALL getParentNode() override; |
216 | | |
217 | | /** |
218 | | The namespace prefix of this node, or null if it is unspecified. |
219 | | */ |
220 | | virtual OUString SAL_CALL getPrefix() override; |
221 | | |
222 | | /** |
223 | | The node immediately preceding this node. |
224 | | */ |
225 | | virtual css::uno::Reference< css::xml::dom::XNode > SAL_CALL getPreviousSibling() override; |
226 | | |
227 | | /** |
228 | | Returns whether this node (if it is an element) has any attributes. |
229 | | */ |
230 | | virtual sal_Bool SAL_CALL hasAttributes() override; |
231 | | |
232 | | /** |
233 | | Returns whether this node has any children. |
234 | | */ |
235 | | virtual sal_Bool SAL_CALL hasChildNodes() override; |
236 | | |
237 | | /** |
238 | | Inserts the node newChild before the existing child node refChild. |
239 | | */ |
240 | | virtual css::uno::Reference< css::xml::dom::XNode > SAL_CALL insertBefore( |
241 | | const css::uno::Reference< css::xml::dom::XNode >& newChild, const css::uno::Reference< css::xml::dom::XNode >& refChild) override; |
242 | | |
243 | | /** |
244 | | Tests whether the DOM implementation implements a specific feature and |
245 | | that feature is supported by this node. |
246 | | */ |
247 | | virtual sal_Bool SAL_CALL isSupported(const OUString& feature, const OUString& ver) override; |
248 | | |
249 | | /** |
250 | | Puts all Text nodes in the full depth of the sub-tree underneath this |
251 | | Node, including attribute nodes, into a "normal" form where only structure |
252 | | (e.g., elements, comments, processing instructions, CDATA sections, and |
253 | | entity references) separates Text nodes, i.e., there are neither adjacent |
254 | | Text nodes nor empty Text nodes. |
255 | | */ |
256 | | virtual void SAL_CALL normalize() override; |
257 | | |
258 | | /** |
259 | | Removes the child node indicated by oldChild from the list of children, |
260 | | and returns it. |
261 | | */ |
262 | | virtual css::uno::Reference< css::xml::dom::XNode > SAL_CALL removeChild(const css::uno::Reference< css::xml::dom::XNode >& oldChild) override; |
263 | | |
264 | | /** |
265 | | Replaces the child node oldChild with newChild in the list of children, |
266 | | and returns the oldChild node. |
267 | | */ |
268 | | virtual css::uno::Reference< css::xml::dom::XNode > SAL_CALL replaceChild( |
269 | | const css::uno::Reference< css::xml::dom::XNode >& newChild, const css::uno::Reference< css::xml::dom::XNode >& oldChild) override; |
270 | | |
271 | | /** |
272 | | The value of this node, depending on its type; see the table above. |
273 | | */ |
274 | | virtual void SAL_CALL setNodeValue(const OUString& nodeValue) override; |
275 | | |
276 | | /** |
277 | | The namespace prefix of this node, or null if it is unspecified. |
278 | | */ |
279 | | virtual void SAL_CALL setPrefix(const OUString& prefix) override; |
280 | | |
281 | | |
282 | | // --- XEventTarget |
283 | | virtual void SAL_CALL addEventListener(const OUString& eventType, |
284 | | const css::uno::Reference< css::xml::dom::events::XEventListener >& listener, |
285 | | sal_Bool useCapture) override; |
286 | | |
287 | | virtual void SAL_CALL removeEventListener(const OUString& eventType, |
288 | | const css::uno::Reference< css::xml::dom::events::XEventListener >& listener, |
289 | | sal_Bool useCapture) override; |
290 | | |
291 | | virtual sal_Bool SAL_CALL dispatchEvent(const css::uno::Reference< css::xml::dom::events::XEvent >& evt) override; |
292 | | }; |
293 | | |
294 | | /// eliminate redundant namespace declarations |
295 | | void nscleanup(const xmlNodePtr aNode, const xmlNodePtr aParent); |
296 | | } |
297 | | |
298 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |