Line data Source code
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 : #include "xmlImportDocumentHandler.hxx"
21 : #include <com/sun/star/sdb/CommandType.hpp>
22 : #include <com/sun/star/chart2/data/DatabaseDataProvider.hpp>
23 : #include <com/sun/star/chart2/data/XDataReceiver.hpp>
24 : #include <com/sun/star/chart/XComplexDescriptionAccess.hpp>
25 : #include <com/sun/star/chart/ChartDataRowSource.hpp>
26 : #include <com/sun/star/reflection/ProxyFactory.hpp>
27 : #include <comphelper/sequence.hxx>
28 : #include <comphelper/sequenceashashmap.hxx>
29 : #include <comphelper/documentconstants.hxx>
30 : #include <comphelper/namedvaluecollection.hxx>
31 : #include <xmloff/attrlist.hxx>
32 : #include <xmloff/xmltoken.hxx>
33 : #include <xmloff/xmlement.hxx>
34 : #include <xmloff/xmluconv.hxx>
35 : #include <xmloff/xmltkmap.hxx>
36 : #include <xmloff/xmlnmspe.hxx>
37 :
38 : #include "xmlHelper.hxx"
39 : #include "xmlEnums.hxx"
40 :
41 : #include <connectivity/dbtools.hxx>
42 :
43 : namespace rptxml
44 : {
45 : using namespace ::com::sun::star;
46 : using namespace ::xmloff::token;
47 :
48 : OUString lcl_createAttribute(const xmloff::token::XMLTokenEnum& _eNamespace,const xmloff::token::XMLTokenEnum& _eAttribute);
49 :
50 0 : ImportDocumentHandler::ImportDocumentHandler(uno::Reference< uno::XComponentContext > const & context)
51 : :m_bImportedChart( false )
52 0 : ,m_xContext(context)
53 : {
54 0 : }
55 : // -----------------------------------------------------------------------------
56 0 : ImportDocumentHandler::~ImportDocumentHandler()
57 : {
58 0 : if ( m_xProxy.is() )
59 : {
60 0 : m_xProxy->setDelegator( NULL );
61 0 : m_xProxy.clear();
62 : }
63 0 : }
64 0 : IMPLEMENT_GET_IMPLEMENTATION_ID(ImportDocumentHandler)
65 0 : IMPLEMENT_FORWARD_REFCOUNT( ImportDocumentHandler, ImportDocumentHandler_BASE )
66 : //------------------------------------------------------------------------
67 0 : OUString SAL_CALL ImportDocumentHandler::getImplementationName( ) throw(uno::RuntimeException)
68 : {
69 0 : return getImplementationName_Static();
70 : }
71 :
72 : //------------------------------------------------------------------------
73 0 : sal_Bool SAL_CALL ImportDocumentHandler::supportsService( const OUString& ServiceName ) throw(uno::RuntimeException)
74 : {
75 0 : return ::comphelper::existsValue(ServiceName,getSupportedServiceNames_static());
76 : }
77 :
78 : //------------------------------------------------------------------------
79 0 : uno::Sequence< OUString > SAL_CALL ImportDocumentHandler::getSupportedServiceNames( ) throw(uno::RuntimeException)
80 : {
81 0 : uno::Sequence< OUString > aSupported;
82 0 : if ( m_xServiceInfo.is() )
83 0 : aSupported = m_xServiceInfo->getSupportedServiceNames();
84 0 : return ::comphelper::concatSequences(getSupportedServiceNames_static(),aSupported);
85 : }
86 :
87 : //------------------------------------------------------------------------
88 0 : OUString ImportDocumentHandler::getImplementationName_Static( ) throw(uno::RuntimeException)
89 : {
90 0 : return OUString("com.sun.star.comp.report.ImportDocumentHandler");
91 : }
92 :
93 : //------------------------------------------------------------------------
94 0 : uno::Sequence< OUString > ImportDocumentHandler::getSupportedServiceNames_static( ) throw(uno::RuntimeException)
95 : {
96 0 : uno::Sequence< OUString > aSupported(1);
97 0 : aSupported[0] = OUString("com.sun.star.report.ImportDocumentHandler");
98 0 : return aSupported;
99 : }
100 :
101 : //------------------------------------------------------------------------
102 0 : uno::Reference< uno::XInterface > SAL_CALL ImportDocumentHandler::create( const uno::Reference< uno::XComponentContext >& _rxContext )
103 : {
104 0 : return *(new ImportDocumentHandler( _rxContext ));
105 : }
106 : // xml::sax::XDocumentHandler:
107 0 : void SAL_CALL ImportDocumentHandler::startDocument() throw (uno::RuntimeException, xml::sax::SAXException)
108 : {
109 0 : m_xDelegatee->startDocument();
110 0 : }
111 :
112 0 : void SAL_CALL ImportDocumentHandler::endDocument() throw (uno::RuntimeException, xml::sax::SAXException)
113 : {
114 0 : m_xDelegatee->endDocument();
115 0 : uno::Reference< chart2::data::XDataReceiver > xReceiver(m_xModel,uno::UNO_QUERY_THROW);
116 0 : if ( xReceiver.is() && m_bImportedChart )
117 : {
118 : // this fills the chart again
119 0 : ::comphelper::NamedValueCollection aArgs;
120 0 : aArgs.put( "CellRangeRepresentation", OUString("all") );
121 0 : aArgs.put( "HasCategories", uno::makeAny( sal_True ) );
122 0 : aArgs.put( "FirstCellAsLabel", uno::makeAny( sal_True ) );
123 0 : aArgs.put( "DataRowSource", uno::makeAny( chart::ChartDataRowSource_COLUMNS ) );
124 :
125 0 : uno::Reference< chart::XComplexDescriptionAccess > xDataProvider(m_xModel->getDataProvider(),uno::UNO_QUERY);
126 0 : if ( xDataProvider.is() )
127 : {
128 0 : const uno::Sequence< OUString > aColumnNames = xDataProvider->getColumnDescriptions();
129 0 : aArgs.put( "ColumnDescriptions", uno::makeAny( aColumnNames ) );
130 : }
131 :
132 0 : xReceiver->attachDataProvider( m_xDatabaseDataProvider.get() );
133 0 : xReceiver->setArguments( aArgs.getPropertyValues() );
134 0 : }
135 0 : }
136 :
137 0 : void SAL_CALL ImportDocumentHandler::startElement(const OUString & _sName, const uno::Reference< xml::sax::XAttributeList > & _xAttrList) throw (uno::RuntimeException, xml::sax::SAXException)
138 : {
139 0 : uno::Reference< xml::sax::XAttributeList > xNewAttribs = _xAttrList;
140 0 : bool bExport = true;
141 0 : if ( _sName == "office:report" )
142 : {
143 0 : const sal_Int16 nLength = (_xAttrList.is()) ? _xAttrList->getLength() : 0;
144 0 : static const OUString s_sTRUE = ::xmloff::token::GetXMLToken(XML_TRUE);
145 : try
146 : {
147 0 : for(sal_Int16 i = 0; i < nLength; ++i)
148 : {
149 0 : OUString sLocalName;
150 0 : const OUString sAttrName = _xAttrList->getNameByIndex( i );
151 0 : const sal_Int32 nColonPos = sAttrName.indexOf( sal_Unicode(':') );
152 0 : if( -1L == nColonPos )
153 0 : sLocalName = sAttrName;
154 : else
155 0 : sLocalName = sAttrName.copy( nColonPos + 1L );
156 0 : const OUString sValue = _xAttrList->getValueByIndex( i );
157 :
158 0 : switch( m_pReportElemTokenMap->Get( XML_NAMESPACE_REPORT, sLocalName ) )
159 : {
160 : case XML_TOK_COMMAND_TYPE:
161 : {
162 0 : sal_uInt16 nRet = static_cast<sal_uInt16>(sdb::CommandType::COMMAND);
163 0 : const SvXMLEnumMapEntry* aXML_EnumMap = OXMLHelper::GetCommandTypeOptions();
164 0 : SvXMLUnitConverter::convertEnum( nRet, sValue, aXML_EnumMap );
165 0 : m_xDatabaseDataProvider->setCommandType(nRet);
166 : }
167 0 : break;
168 : case XML_TOK_COMMAND:
169 0 : m_xDatabaseDataProvider->setCommand(sValue);
170 0 : break;
171 : case XML_TOK_FILTER:
172 0 : m_xDatabaseDataProvider->setFilter(sValue);
173 0 : break;
174 : case XML_TOK_ESCAPE_PROCESSING:
175 0 : m_xDatabaseDataProvider->setEscapeProcessing(sValue == s_sTRUE);
176 0 : break;
177 : default:
178 0 : break;
179 : }
180 0 : }
181 : }
182 0 : catch(uno::Exception&)
183 : {
184 : }
185 0 : m_xDelegatee->startElement(lcl_createAttribute(XML_NP_OFFICE,XML_CHART),NULL);
186 0 : bExport = false;
187 0 : m_bImportedChart = true;
188 : }
189 0 : else if ( _sName == "rpt:master-detail-field" )
190 : {
191 0 : const sal_Int16 nLength = (_xAttrList.is()) ? _xAttrList->getLength() : 0;
192 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
193 0 : ::std::auto_ptr<SvXMLTokenMap> pMasterElemTokenMap( OXMLHelper::GetSubDocumentElemTokenMap());
194 : SAL_WNODEPRECATED_DECLARATIONS_POP
195 : try
196 : {
197 0 : OUString sMasterField,sDetailField;
198 0 : for(sal_Int16 i = 0; i < nLength; ++i)
199 : {
200 0 : OUString sLocalName;
201 0 : const OUString sAttrName = _xAttrList->getNameByIndex( i );
202 0 : const sal_Int32 nColonPos = sAttrName.indexOf( sal_Unicode(':') );
203 0 : if( -1L == nColonPos )
204 0 : sLocalName = sAttrName;
205 : else
206 0 : sLocalName = sAttrName.copy( nColonPos + 1L );
207 0 : const OUString sValue = _xAttrList->getValueByIndex( i );
208 :
209 0 : switch( pMasterElemTokenMap->Get( XML_NAMESPACE_REPORT, sLocalName ) )
210 : {
211 : case XML_TOK_MASTER:
212 0 : sMasterField = sValue;
213 0 : break;
214 : case XML_TOK_SUB_DETAIL:
215 0 : sDetailField = sValue;
216 0 : break;
217 : }
218 0 : }
219 0 : if ( sDetailField.isEmpty() )
220 0 : sDetailField = sMasterField;
221 0 : m_aMasterFields.push_back(sMasterField);
222 0 : m_aDetailFields.push_back(sDetailField);
223 : }
224 0 : catch(uno::Exception&)
225 : {
226 : OSL_FAIL("Exception catched while filling the report definition props");
227 : }
228 0 : bExport = false;
229 : }
230 0 : else if ( _sName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("rpt:detail"))
231 0 : || _sName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("rpt:formatted-text"))
232 0 : || _sName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("rpt:master-detail-fields"))
233 0 : || _sName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("rpt:report-component"))
234 0 : || _sName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("rpt:report-element")))
235 0 : bExport = false;
236 0 : else if ( _sName == "chart:plot-area" )
237 : {
238 0 : sal_Bool bHasCategories = sal_True;
239 0 : const sal_Int16 nLength = (_xAttrList.is()) ? _xAttrList->getLength() : 0;
240 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
241 0 : ::std::auto_ptr<SvXMLTokenMap> pMasterElemTokenMap( OXMLHelper::GetSubDocumentElemTokenMap());
242 : SAL_WNODEPRECATED_DECLARATIONS_POP
243 0 : for(sal_Int16 i = 0; i < nLength; ++i)
244 : {
245 0 : OUString sLocalName;
246 0 : const OUString sAttrName = _xAttrList->getNameByIndex( i );
247 0 : const sal_Int32 nColonPos = sAttrName.indexOf( sal_Unicode(':') );
248 0 : if( -1L == nColonPos )
249 0 : sLocalName = sAttrName;
250 : else
251 0 : sLocalName = sAttrName.copy( nColonPos + 1L );
252 0 : if ( sLocalName == "data-source-has-labels" )
253 : {
254 0 : const OUString sValue = _xAttrList->getValueByIndex( i );
255 0 : bHasCategories = sValue.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("both"));
256 0 : break;
257 : }
258 0 : }
259 0 : beans::PropertyValue* pArgIter = m_aArguments.getArray();
260 0 : beans::PropertyValue* pArgEnd = pArgIter + m_aArguments.getLength();
261 0 : for(;pArgIter != pArgEnd;++pArgIter)
262 : {
263 0 : if ( pArgIter->Name == "HasCategories" )
264 : {
265 0 : pArgIter->Value <<= bHasCategories;
266 0 : break;
267 : }
268 : }
269 :
270 0 : SvXMLAttributeList* pList = new SvXMLAttributeList();
271 0 : xNewAttribs = pList;
272 0 : pList->AppendAttributeList(_xAttrList);
273 0 : pList->AddAttribute(OUString("table:cell-range-address"),OUString("local-table.$A$1:.$Z$65536"));
274 :
275 : }
276 :
277 0 : if ( bExport )
278 0 : m_xDelegatee->startElement(_sName,xNewAttribs);
279 0 : }
280 :
281 0 : void SAL_CALL ImportDocumentHandler::endElement(const OUString & _sName) throw (uno::RuntimeException, xml::sax::SAXException)
282 : {
283 0 : bool bExport = true;
284 0 : OUString sNewName = _sName;
285 0 : if ( _sName == "office:report" )
286 : {
287 0 : sNewName = lcl_createAttribute(XML_NP_OFFICE,XML_CHART);
288 : }
289 0 : else if ( _sName == "rpt:master-detail-fields" )
290 : {
291 0 : if ( !m_aMasterFields.empty() )
292 0 : m_xDatabaseDataProvider->setMasterFields(uno::Sequence< OUString>(&*m_aMasterFields.begin(),m_aMasterFields.size()));
293 0 : if ( !m_aDetailFields.empty() )
294 0 : m_xDatabaseDataProvider->setDetailFields(uno::Sequence< OUString>(&*m_aDetailFields.begin(),m_aDetailFields.size()));
295 0 : bExport = false;
296 : }
297 0 : else if ( _sName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("rpt:detail"))
298 0 : || _sName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("rpt:formatted-text"))
299 0 : || _sName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("rpt:master-detail-field"))
300 0 : || _sName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("rpt:report-component"))
301 0 : || _sName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("rpt:report-element")))
302 0 : bExport = false;
303 :
304 0 : if ( bExport )
305 0 : m_xDelegatee->endElement(sNewName);
306 0 : }
307 :
308 0 : void SAL_CALL ImportDocumentHandler::characters(const OUString & aChars) throw (uno::RuntimeException, xml::sax::SAXException)
309 : {
310 0 : m_xDelegatee->characters(aChars);
311 0 : }
312 :
313 0 : void SAL_CALL ImportDocumentHandler::ignorableWhitespace(const OUString & aWhitespaces) throw (uno::RuntimeException, xml::sax::SAXException)
314 : {
315 0 : m_xDelegatee->ignorableWhitespace(aWhitespaces);
316 0 : }
317 :
318 0 : void SAL_CALL ImportDocumentHandler::processingInstruction(const OUString & aTarget, const OUString & aData) throw (uno::RuntimeException, xml::sax::SAXException)
319 : {
320 0 : m_xDelegatee->processingInstruction(aTarget,aData);
321 0 : }
322 :
323 0 : void SAL_CALL ImportDocumentHandler::setDocumentLocator(const uno::Reference< xml::sax::XLocator > & xLocator) throw (uno::RuntimeException, xml::sax::SAXException)
324 : {
325 0 : m_xDelegatee->setDocumentLocator(xLocator);
326 0 : }
327 0 : void SAL_CALL ImportDocumentHandler::initialize( const uno::Sequence< uno::Any >& _aArguments ) throw (uno::Exception, uno::RuntimeException)
328 : {
329 0 : ::osl::MutexGuard aGuard(m_aMutex);
330 0 : comphelper::SequenceAsHashMap aArgs(_aArguments);
331 0 : m_xDelegatee = aArgs.getUnpackedValueOrDefault("DocumentHandler",m_xDelegatee);
332 0 : m_xModel = aArgs.getUnpackedValueOrDefault("Model",m_xModel);
333 :
334 : OSL_ENSURE(m_xDelegatee.is(),"No document handler avialable!");
335 0 : if ( !m_xDelegatee.is() || !m_xModel.is() )
336 0 : throw uno::Exception();
337 :
338 0 : m_xDatabaseDataProvider.set(m_xModel->getDataProvider(),uno::UNO_QUERY);
339 0 : if ( !m_xDatabaseDataProvider.is() )
340 : {
341 0 : const static OUString s_sDatabaseDataProvider("com.sun.star.chart2.data.DatabaseDataProvider");
342 0 : m_xDatabaseDataProvider.set(m_xContext->getServiceManager()->createInstanceWithContext(s_sDatabaseDataProvider
343 0 : ,m_xContext),uno::UNO_QUERY);
344 0 : if ( !m_xDatabaseDataProvider.is() )
345 0 : throw uno::Exception();
346 :
347 0 : m_xDatabaseDataProvider->setRowLimit(10);
348 :
349 0 : uno::Reference< chart2::data::XDataReceiver > xReceiver(m_xModel,uno::UNO_QUERY_THROW);
350 0 : xReceiver->attachDataProvider(m_xDatabaseDataProvider.get());
351 : }
352 :
353 0 : m_aArguments = m_xDatabaseDataProvider->detectArguments(NULL);
354 :
355 0 : uno::Reference< reflection::XProxyFactory > xProxyFactory = reflection::ProxyFactory::create( m_xContext );
356 0 : m_xProxy = xProxyFactory->createProxy(m_xDelegatee.get());
357 0 : ::comphelper::query_aggregation(m_xProxy,m_xDelegatee);
358 0 : m_xTypeProvider.set(m_xDelegatee,uno::UNO_QUERY);
359 0 : m_xServiceInfo.set(m_xDelegatee,uno::UNO_QUERY);
360 :
361 : // set ourself as delegator
362 0 : m_xProxy->setDelegator( *this );
363 :
364 0 : m_pReportElemTokenMap.reset(OXMLHelper::GetReportElemTokenMap());
365 0 : }
366 : // --------------------------------------------------------------------------------
367 0 : uno::Any SAL_CALL ImportDocumentHandler::queryInterface( const uno::Type& _rType ) throw (uno::RuntimeException)
368 : {
369 0 : uno::Any aReturn = ImportDocumentHandler_BASE::queryInterface(_rType);
370 0 : return aReturn.hasValue() ? aReturn : (m_xProxy.is() ? m_xProxy->queryAggregation(_rType) : aReturn);
371 : }
372 : // --------------------------------------------------------------------------------
373 0 : uno::Sequence< uno::Type > SAL_CALL ImportDocumentHandler::getTypes( ) throw (uno::RuntimeException)
374 : {
375 0 : if ( m_xTypeProvider.is() )
376 : return ::comphelper::concatSequences(
377 : ImportDocumentHandler_BASE::getTypes(),
378 0 : m_xTypeProvider->getTypes()
379 0 : );
380 0 : return ImportDocumentHandler_BASE::getTypes();
381 : }
382 :
383 : // -----------------------------------------------------------------------------
384 : } // namespace rptxml
385 : // -----------------------------------------------------------------------------
386 :
387 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|