Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include "DomExport.hxx"
31 : :
32 : : #include <xmloff/nmspmap.hxx>
33 : : #include <xmloff/xmlexp.hxx>
34 : : #include "xmloff/xmlerror.hxx"
35 : :
36 : : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
37 : : #include <com/sun/star/uno/Reference.hxx>
38 : : #include <com/sun/star/uno/Sequence.hxx>
39 : : #include <com/sun/star/xml/dom/XAttr.hpp>
40 : : #include <com/sun/star/xml/dom/XDocumentBuilder.hpp>
41 : : #include <com/sun/star/xml/dom/XNode.hpp>
42 : : #include <com/sun/star/xml/dom/XElement.hpp>
43 : : #include <com/sun/star/xml/dom/XEntity.hpp>
44 : : #include <com/sun/star/xml/dom/XNotation.hpp>
45 : : #include <com/sun/star/xml/sax/XAttributeList.hpp>
46 : : #include <com/sun/star/xml/dom/NodeType.hpp>
47 : : #include <com/sun/star/xml/dom/XNamedNodeMap.hpp>
48 : :
49 : : #include <rtl/ustring.hxx>
50 : : #include <rtl/ustrbuf.hxx>
51 : : #include <tools/debug.hxx>
52 : :
53 : :
54 : : #include <vector>
55 : :
56 : :
57 : : using com::sun::star::lang::XMultiServiceFactory;
58 : : using com::sun::star::uno::Reference;
59 : : using com::sun::star::uno::Sequence;
60 : : using com::sun::star::uno::UNO_QUERY;
61 : : using com::sun::star::uno::UNO_QUERY_THROW;
62 : : using std::vector;
63 : :
64 : : using namespace com::sun::star::xml::dom;
65 : :
66 : : using rtl::OUString;
67 : : using rtl::OUStringBuffer;
68 : :
69 : :
70 : : class DomVisitor
71 : : {
72 : : public:
73 : 0 : DomVisitor() {}
74 [ # # ]: 0 : virtual ~DomVisitor() {}
75 : 0 : virtual void element( const Reference<XElement>& ) {}
76 : 0 : virtual void character( const Reference<XCharacterData>& ) {}
77 : 0 : virtual void attribute( const Reference<XAttr>& ) {}
78 : 0 : virtual void cdata( const Reference<XCDATASection>& ) {}
79 : 0 : virtual void comment( const Reference<XComment>& ) {}
80 : 0 : virtual void documentFragment( const Reference<XDocumentFragment>& ) {}
81 : 0 : virtual void document( const Reference<XDocument>& ) {}
82 : 0 : virtual void documentType( const Reference<XDocumentType>& ) {}
83 : 0 : virtual void entity( const Reference<XEntity>& ) {}
84 : 0 : virtual void entityReference( const Reference<XEntityReference>& ) {}
85 : 0 : virtual void notation( const Reference<XNotation>& ) {}
86 : 0 : virtual void processingInstruction( const Reference<XProcessingInstruction>& ) {}
87 : 0 : virtual void endElement( const Reference<XElement>& ) {}
88 : : };
89 : :
90 : : void visit( DomVisitor&, const Reference<XDocument>& );
91 : : void visit( DomVisitor&, const Reference<XNode>& );
92 : :
93 : :
94 : :
95 : 0 : void visitNode( DomVisitor& rVisitor, const Reference<XNode>& xNode )
96 : : {
97 [ # # # # : 0 : switch( xNode->getNodeType() )
# # # # #
# # # # ]
98 : : {
99 : : case NodeType_ATTRIBUTE_NODE:
100 [ # # ]: 0 : rVisitor.attribute( Reference<XAttr>( xNode, UNO_QUERY_THROW ) );
101 : 0 : break;
102 : : case NodeType_CDATA_SECTION_NODE:
103 [ # # ]: 0 : rVisitor.cdata( Reference<XCDATASection>( xNode, UNO_QUERY_THROW ) );
104 : 0 : break;
105 : : case NodeType_COMMENT_NODE:
106 [ # # ]: 0 : rVisitor.comment( Reference<XComment>( xNode, UNO_QUERY_THROW ) );
107 : 0 : break;
108 : : case NodeType_DOCUMENT_FRAGMENT_NODE:
109 [ # # ]: 0 : rVisitor.documentFragment( Reference<XDocumentFragment>( xNode, UNO_QUERY_THROW ) );
110 : 0 : break;
111 : : case NodeType_DOCUMENT_NODE:
112 [ # # ]: 0 : rVisitor.document( Reference<XDocument>( xNode, UNO_QUERY_THROW ) );
113 : 0 : break;
114 : : case NodeType_DOCUMENT_TYPE_NODE:
115 [ # # ]: 0 : rVisitor.documentType( Reference<XDocumentType>( xNode, UNO_QUERY_THROW ) );
116 : 0 : break;
117 : : case NodeType_ELEMENT_NODE:
118 [ # # ]: 0 : rVisitor.element( Reference<XElement>( xNode, UNO_QUERY_THROW ) );
119 : 0 : break;
120 : : case NodeType_ENTITY_NODE:
121 [ # # ]: 0 : rVisitor.entity( Reference<XEntity>( xNode, UNO_QUERY_THROW ) );
122 : 0 : break;
123 : : case NodeType_ENTITY_REFERENCE_NODE:
124 [ # # ]: 0 : rVisitor.entityReference( Reference<XEntityReference>( xNode, UNO_QUERY_THROW ) );
125 : 0 : break;
126 : : case NodeType_NOTATION_NODE:
127 [ # # ]: 0 : rVisitor.notation( Reference<XNotation>( xNode, UNO_QUERY_THROW ) );
128 : 0 : break;
129 : : case NodeType_PROCESSING_INSTRUCTION_NODE:
130 [ # # ]: 0 : rVisitor.processingInstruction( Reference<XProcessingInstruction>( xNode, UNO_QUERY_THROW ) );
131 : 0 : break;
132 : : case NodeType_TEXT_NODE:
133 [ # # ]: 0 : rVisitor.character( Reference<XCharacterData>( xNode, UNO_QUERY_THROW ) );
134 : 0 : break;
135 : : default:
136 : : OSL_FAIL( "unknown DOM node type" );
137 : 0 : break;
138 : : }
139 : 0 : }
140 : :
141 : 0 : void visit( DomVisitor& rVisitor, const Reference<XDocument>& xDocument )
142 : : {
143 [ # # ]: 0 : visit( rVisitor, Reference<XNode>( xDocument, UNO_QUERY_THROW ) );
144 : 0 : }
145 : :
146 : 0 : void visit( DomVisitor& rVisitor, const Reference<XNode>& xNode )
147 : : {
148 : 0 : visitNode( rVisitor, xNode );
149 [ # # ]: 0 : for( Reference<XNode> xChild = xNode->getFirstChild();
[ # # # # ]
[ # # ]
150 : 0 : xChild.is();
151 [ # # ][ # # ]: 0 : xChild = xChild->getNextSibling() )
152 : : {
153 [ # # ]: 0 : visit( rVisitor, xChild );
154 : 0 : }
155 [ # # ]: 0 : if( xNode->getNodeType() == NodeType_ELEMENT_NODE )
156 [ # # ]: 0 : rVisitor.endElement( Reference<XElement>( xNode, UNO_QUERY_THROW ) );
157 : 0 : }
158 : :
159 : :
160 : :
161 : : class DomExport: public DomVisitor
162 : : {
163 : : SvXMLExport& mrExport;
164 : : vector<SvXMLNamespaceMap> maNamespaces;
165 : :
166 : : void pushNamespace();
167 : : void popNamespace();
168 : : void addNamespace( const OUString& sPrefix, const OUString& sURI );
169 : : OUString qualifiedName( const OUString& sPrefix, const OUString& sURI,
170 : : const OUString& sLocalName );
171 : : OUString qualifiedName( const Reference<XElement>& );
172 : : OUString qualifiedName( const Reference<XAttr>& );
173 : : void addAttribute( const Reference<XAttr>& );
174 : :
175 : : public:
176 : :
177 : : DomExport( SvXMLExport& rExport );
178 : : virtual ~DomExport();
179 : :
180 : : virtual void element( const Reference<XElement>& );
181 : : virtual void endElement( const Reference<XElement>& );
182 : : virtual void character( const Reference<XCharacterData>& );
183 : : };
184 : :
185 : 0 : DomExport::DomExport( SvXMLExport& rExport ) :
186 [ # # ]: 0 : mrExport( rExport )
187 : : {
188 [ # # ]: 0 : maNamespaces.push_back( rExport.GetNamespaceMap() );
189 : 0 : }
190 : :
191 : 0 : DomExport::~DomExport()
192 : : {
193 : : DBG_ASSERT( maNamespaces.size() == 1, "namespace missing" );
194 : 0 : maNamespaces.clear();
195 [ # # ]: 0 : }
196 : :
197 : 0 : void DomExport::pushNamespace()
198 : : {
199 [ # # ][ # # ]: 0 : SvXMLNamespaceMap const aMap(maNamespaces.back());
200 [ # # ][ # # ]: 0 : maNamespaces.push_back(aMap);
201 : 0 : }
202 : :
203 : 0 : void DomExport::popNamespace()
204 : : {
205 : 0 : maNamespaces.pop_back();
206 : 0 : }
207 : :
208 : 0 : void DomExport::addNamespace( const OUString& sPrefix, const OUString& sURI )
209 : : {
210 : 0 : SvXMLNamespaceMap& rMap = maNamespaces.back();
211 : 0 : sal_uInt16 nKey = rMap.GetKeyByPrefix( sPrefix );
212 : :
213 : : // we need to register the namespace, if either the prefix isn't known or
214 : : // is used for a different namespace
215 [ # # ]: 0 : if( nKey == XML_NAMESPACE_UNKNOWN ||
[ # # # # ]
216 : 0 : rMap.GetNameByKey( nKey ) != sURI )
217 : : {
218 : : // add prefix to map, and add declaration
219 : 0 : rMap.Add( sPrefix, sURI );
220 : : mrExport.AddAttribute(
221 : : OUString( RTL_CONSTASCII_USTRINGPARAM( "xmlns:" ) ) + sPrefix,
222 [ # # ]: 0 : sURI );
223 : : }
224 : 0 : }
225 : :
226 : 0 : OUString DomExport::qualifiedName( const OUString& sPrefix,
227 : : const OUString& sURI,
228 : : const OUString& sLocalName )
229 : : {
230 : 0 : OUStringBuffer sBuffer;
231 [ # # ][ # # ]: 0 : if( !sPrefix.isEmpty() && !sURI.isEmpty() )
[ # # ]
232 : : {
233 [ # # ]: 0 : addNamespace( sPrefix, sURI );
234 [ # # ]: 0 : sBuffer.append( sPrefix );
235 [ # # ]: 0 : sBuffer.append( sal_Unicode( ':' ) );
236 : : }
237 [ # # ]: 0 : sBuffer.append( sLocalName );
238 [ # # ]: 0 : return sBuffer.makeStringAndClear();
239 : : }
240 : :
241 : 0 : OUString DomExport::qualifiedName( const Reference<XElement>& xElement )
242 : : {
243 [ # # ][ # # ]: 0 : return qualifiedName( xElement->getPrefix(), xElement->getNamespaceURI(),
244 [ # # ][ # # ]: 0 : xElement->getNodeName() );
[ # # ]
245 : : }
246 : :
247 : 0 : OUString DomExport::qualifiedName( const Reference<XAttr>& xAttr )
248 : : {
249 [ # # ][ # # ]: 0 : return qualifiedName( xAttr->getPrefix(), xAttr->getNamespaceURI(),
250 [ # # ][ # # ]: 0 : xAttr->getNodeName() );
[ # # ]
251 : : }
252 : :
253 : 0 : void DomExport::addAttribute( const Reference<XAttr>& xAttribute )
254 : : {
255 : : mrExport.AddAttribute( qualifiedName( xAttribute ),
256 [ # # ][ # # ]: 0 : xAttribute->getNodeValue() );
257 : 0 : }
258 : :
259 : 0 : void DomExport::element( const Reference<XElement>& xElement )
260 : : {
261 [ # # ]: 0 : pushNamespace();
262 : :
263 : : // write attributes
264 [ # # ][ # # ]: 0 : Reference<XNamedNodeMap> xAttributes = xElement->getAttributes();
265 [ # # ][ # # ]: 0 : sal_Int32 nLength = xAttributes.is() ? xAttributes->getLength() : 0;
[ # # ]
266 [ # # ]: 0 : for( sal_Int32 n = 0; n < nLength; n++ )
267 : : {
268 [ # # ][ # # ]: 0 : addAttribute( Reference<XAttr>( xAttributes->item( n ), UNO_QUERY_THROW ) );
[ # # ][ # # ]
269 : : }
270 : :
271 : : // write name
272 [ # # ][ # # ]: 0 : mrExport.StartElement( qualifiedName( xElement ), sal_False );
273 : 0 : }
274 : :
275 : 0 : void DomExport::endElement( const Reference<XElement>& xElement )
276 : : {
277 [ # # ]: 0 : mrExport.EndElement( qualifiedName( xElement ), sal_False );
278 : 0 : popNamespace();
279 : 0 : }
280 : :
281 : 0 : void DomExport::character( const Reference<XCharacterData>& xChars )
282 : : {
283 [ # # ]: 0 : mrExport.Characters( xChars->getNodeValue() );
284 : 0 : }
285 : :
286 : :
287 : 0 : void exportDom( SvXMLExport& rExport, const Reference<XDocument>& xDocument )
288 : : {
289 [ # # ]: 0 : DomExport aDomExport( rExport );
290 [ # # ]: 0 : visit( aDomExport, xDocument );
291 : 0 : }
292 : :
293 : 0 : void exportDom( SvXMLExport& rExport, const Reference<XNode>& xNode )
294 : : {
295 [ # # ]: 0 : DomExport aDomExport( rExport );
296 [ # # ]: 0 : visit( aDomExport, xNode );
297 : 0 : }
298 : :
299 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|