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 #include <com/sun/star/beans/PropertyValue.hpp>
20 #include <ReportEngineJFree.hxx>
21 #include <comphelper/documentconstants.hxx>
22 #include <comphelper/storagehelper.hxx>
23 #include <connectivity/dbtools.hxx>
24 #include <comphelper/mimeconfighelper.hxx>
25 #include <comphelper/string.hxx>
26 #include <cppuhelper/supportsservice.hxx>
27 #include <com/sun/star/beans/PropertyAttribute.hpp>
28 #include <com/sun/star/beans/NamedValue.hpp>
29 #include <com/sun/star/frame/Desktop.hpp>
30 #include <com/sun/star/frame/XComponentLoader.hpp>
31 #include <com/sun/star/frame/FrameSearchFlag.hpp>
32 #include <com/sun/star/embed/XTransactedObject.hpp>
33 #include <com/sun/star/sdb/XCompletedExecution.hpp>
34 #include <com/sun/star/sdb/XSingleSelectQueryAnalyzer.hpp>
35 #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
36 #include <com/sun/star/sdb/CommandType.hpp>
37
38 #include <com/sun/star/task/XInteractionHandler.hpp>
39 #include <com/sun/star/task/XJob.hpp>
40
41 #include <unotools/useroptions.hxx>
42 #include <unotools/tempfile.hxx>
43 #include <unotools/sharedunocomponent.hxx>
44
45 #include <Tools.hxx>
46 #include <strings.hxx>
47 #include <strings.hrc>
48 #include <core_resource.hxx>
49
50 #include <connectivity/CommonTools.hxx>
51 #include <rtl/ustrbuf.hxx>
52 #include <sfx2/docfilt.hxx>
53
54 namespace reportdesign
55 {
56
57 using namespace com::sun::star;
58 using namespace comphelper;
59
60
OReportEngineJFree(const uno::Reference<uno::XComponentContext> & context)61 OReportEngineJFree::OReportEngineJFree( const uno::Reference< uno::XComponentContext >& context)
62 :ReportEngineBase(m_aMutex)
63 ,ReportEnginePropertySet(context,IMPLEMENTS_PROPERTY_SET,uno::Sequence< OUString >())
64 ,m_xContext(context)
65 ,m_nMaxRows(0)
66 {
67 }
68
69 // TODO: VirtualFunctionFinder: This is virtual function!
70
~OReportEngineJFree()71 OReportEngineJFree::~OReportEngineJFree()
72 {
73 }
74
IMPLEMENT_FORWARD_XINTERFACE2(OReportEngineJFree,ReportEngineBase,ReportEnginePropertySet)75 IMPLEMENT_FORWARD_XINTERFACE2(OReportEngineJFree,ReportEngineBase,ReportEnginePropertySet)
76
77 void SAL_CALL OReportEngineJFree::dispose()
78 {
79 ReportEnginePropertySet::dispose();
80 cppu::WeakComponentImplHelperBase::dispose();
81 m_xActiveConnection.clear();
82 }
83
getImplementationName_Static()84 OUString OReportEngineJFree::getImplementationName_Static( )
85 {
86 return "com.sun.star.comp.report.OReportEngineJFree";
87 }
88
89
getImplementationName()90 OUString SAL_CALL OReportEngineJFree::getImplementationName( )
91 {
92 return getImplementationName_Static();
93 }
94
getSupportedServiceNames_Static()95 uno::Sequence< OUString > OReportEngineJFree::getSupportedServiceNames_Static( )
96 {
97 uno::Sequence< OUString > aServices { "com.sun.star.report.ReportEngine" };
98
99 return aServices;
100 }
101
create(uno::Reference<uno::XComponentContext> const & xContext)102 uno::Reference< uno::XInterface > OReportEngineJFree::create(uno::Reference< uno::XComponentContext > const & xContext)
103 {
104 return *(new OReportEngineJFree(xContext));
105 }
106
107
getSupportedServiceNames()108 uno::Sequence< OUString > SAL_CALL OReportEngineJFree::getSupportedServiceNames( )
109 {
110 return getSupportedServiceNames_Static();
111 }
112
supportsService(const OUString & ServiceName)113 sal_Bool SAL_CALL OReportEngineJFree::supportsService(const OUString& ServiceName)
114 {
115 return cppu::supportsService(this, ServiceName);
116 }
117
118 // XReportEngine
119 // Attributes
getReportDefinition()120 uno::Reference< report::XReportDefinition > SAL_CALL OReportEngineJFree::getReportDefinition()
121 {
122 ::osl::MutexGuard aGuard(m_aMutex);
123 return m_xReport;
124 }
125
setReportDefinition(const uno::Reference<report::XReportDefinition> & _report)126 void SAL_CALL OReportEngineJFree::setReportDefinition( const uno::Reference< report::XReportDefinition >& _report )
127 {
128 if ( !_report.is() )
129 throw lang::IllegalArgumentException();
130 BoundListeners l;
131 {
132 ::osl::MutexGuard aGuard(m_aMutex);
133 if ( m_xReport != _report )
134 {
135 prepareSet(PROPERTY_REPORTDEFINITION, uno::makeAny(m_xReport), uno::makeAny(_report), &l);
136 m_xReport = _report;
137 }
138 }
139 l.notify();
140 }
141
getStatusIndicator()142 uno::Reference< task::XStatusIndicator > SAL_CALL OReportEngineJFree::getStatusIndicator()
143 {
144 ::osl::MutexGuard aGuard(m_aMutex);
145 return m_StatusIndicator;
146 }
147
setStatusIndicator(const uno::Reference<task::XStatusIndicator> & _statusindicator)148 void SAL_CALL OReportEngineJFree::setStatusIndicator( const uno::Reference< task::XStatusIndicator >& _statusindicator )
149 {
150 set(PROPERTY_STATUSINDICATOR,_statusindicator,m_StatusIndicator);
151 }
152
getNewOutputName()153 OUString OReportEngineJFree::getNewOutputName()
154 {
155 ::osl::MutexGuard aGuard(m_aMutex);
156 ::connectivity::checkDisposed(ReportEngineBase::rBHelper.bDisposed);
157 if ( !m_xReport.is() || !m_xActiveConnection.is() )
158 throw lang::IllegalArgumentException();
159
160 static const char s_sMediaType[] = "MediaType";
161
162 MimeConfigurationHelper aConfighelper(m_xContext);
163 const OUString sMimeType = m_xReport->getMimeType();
164 std::shared_ptr<const SfxFilter> pFilter = SfxFilter::GetDefaultFilter( aConfighelper.GetDocServiceNameFromMediaType(sMimeType) );
165 OUString sExt(".rpt");
166 if ( pFilter )
167 sExt = ::comphelper::string::stripStart(pFilter->GetDefaultExtension(), '*');
168
169 uno::Reference< embed::XStorage > xTemp = OStorageHelper::GetTemporaryStorage(/*sFileTemp,embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE,*/ m_xContext);
170 utl::DisposableComponent aTemp(xTemp);
171 uno::Sequence< beans::PropertyValue > aEmpty;
172 uno::Reference< beans::XPropertySet> xStorageProp(xTemp,uno::UNO_QUERY);
173 if ( xStorageProp.is() )
174 {
175 xStorageProp->setPropertyValue( s_sMediaType, uno::makeAny(sMimeType));
176 }
177 m_xReport->storeToStorage(xTemp,aEmpty); // store to temp file because it may contain information which isn't in the database yet.
178
179 uno::Sequence< beans::NamedValue > aConvertedProperties(8);
180 sal_Int32 nPos = 0;
181 aConvertedProperties[nPos].Name = "InputStorage";
182 aConvertedProperties[nPos++].Value <<= xTemp;
183 aConvertedProperties[nPos].Name = "OutputStorage";
184
185 OUString sFileURL;
186 OUString sName = m_xReport->getCaption();
187 if ( sName.isEmpty() )
188 sName = m_xReport->getName();
189 {
190 ::utl::TempFile aTestFile(sName, false, &sExt);
191 if ( !aTestFile.IsValid() )
192 {
193 sName = RptResId(RID_STR_REPORT);
194 ::utl::TempFile aFile(sName, false, &sExt);
195 sFileURL = aFile.GetURL();
196 }
197 else
198 sFileURL = aTestFile.GetURL();
199 }
200
201 uno::Reference< embed::XStorage > xOut = OStorageHelper::GetStorageFromURL(sFileURL,embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE, m_xContext);
202 utl::DisposableComponent aOut(xOut);
203 xStorageProp.set(xOut,uno::UNO_QUERY);
204 if ( xStorageProp.is() )
205 {
206 xStorageProp->setPropertyValue( s_sMediaType, uno::makeAny(sMimeType));
207 }
208
209 aConvertedProperties[nPos++].Value <<= xOut;
210
211 aConvertedProperties[nPos].Name = PROPERTY_REPORTDEFINITION;
212 aConvertedProperties[nPos++].Value <<= m_xReport;
213
214 aConvertedProperties[nPos].Name = PROPERTY_ACTIVECONNECTION;
215 aConvertedProperties[nPos++].Value <<= m_xActiveConnection;
216
217 aConvertedProperties[nPos].Name = PROPERTY_MAXROWS;
218 aConvertedProperties[nPos++].Value <<= m_nMaxRows;
219
220 // some meta data
221 SvtUserOptions aUserOpts;
222 OUStringBuffer sAuthor(aUserOpts.GetFirstName());
223 sAuthor.append(" ");
224 sAuthor.append(aUserOpts.GetLastName());
225 aConvertedProperties[nPos].Name = "Author";
226 aConvertedProperties[nPos++].Value <<= sAuthor.makeStringAndClear();
227
228 aConvertedProperties[nPos].Name = "Title";
229 aConvertedProperties[nPos++].Value <<= m_xReport->getCaption();
230
231 OUString sOutputName;
232
233 // create job factory and initialize
234 const OUString sReportEngineServiceName = ::dbtools::getDefaultReportEngineServiceName(m_xContext);
235 uno::Reference<task::XJob> xJob(m_xContext->getServiceManager()->createInstanceWithContext(sReportEngineServiceName,m_xContext),uno::UNO_QUERY_THROW);
236 if ( !m_xReport->getCommand().isEmpty() )
237 {
238 xJob->execute(aConvertedProperties);
239 if ( xStorageProp.is() )
240 {
241 sOutputName = sFileURL;
242 }
243 }
244
245 uno::Reference<embed::XTransactedObject> xTransact(xOut,uno::UNO_QUERY);
246 if ( !sOutputName.isEmpty() && xTransact.is() )
247 xTransact->commit();
248
249 if ( sOutputName.isEmpty() )
250 throw lang::IllegalArgumentException();
251
252 return sOutputName;
253 }
254
255 // Methods
createDocumentModel()256 uno::Reference< frame::XModel > SAL_CALL OReportEngineJFree::createDocumentModel( )
257 {
258 return createDocumentAlive(nullptr,true);
259 }
260
createDocumentAlive(const uno::Reference<frame::XFrame> & _frame)261 uno::Reference< frame::XModel > SAL_CALL OReportEngineJFree::createDocumentAlive( const uno::Reference< frame::XFrame >& _frame )
262 {
263 return createDocumentAlive(_frame,false);
264 }
265
createDocumentAlive(const uno::Reference<frame::XFrame> & _frame,bool _bHidden)266 uno::Reference< frame::XModel > OReportEngineJFree::createDocumentAlive( const uno::Reference< frame::XFrame >& _frame,bool _bHidden )
267 {
268 uno::Reference< frame::XModel > xModel;
269 OUString sOutputName = getNewOutputName(); // starts implicitly the report generator
270 if ( !sOutputName.isEmpty() )
271 {
272 ::osl::MutexGuard aGuard(m_aMutex);
273 ::connectivity::checkDisposed(ReportEngineBase::rBHelper.bDisposed);
274 uno::Reference<frame::XComponentLoader> xFrameLoad(_frame,uno::UNO_QUERY);
275 if ( !xFrameLoad.is() )
276 {
277 // if there is no frame given, find the right
278 xFrameLoad = frame::Desktop::create(m_xContext);
279 sal_Int32 const nFrameSearchFlag = frame::FrameSearchFlag::TASKS | frame::FrameSearchFlag::CREATE;
280 uno::Reference< frame::XFrame> xFrame = uno::Reference< frame::XFrame>(xFrameLoad,uno::UNO_QUERY_THROW)->findFrame("_blank",nFrameSearchFlag);
281 xFrameLoad.set( xFrame,uno::UNO_QUERY);
282 }
283
284 if ( xFrameLoad.is() )
285 {
286 uno::Sequence < beans::PropertyValue > aArgs( _bHidden ? 3 : 2 );
287 sal_Int32 nLen = 0;
288 aArgs[nLen].Name = "AsTemplate";
289 aArgs[nLen++].Value <<= false;
290
291 aArgs[nLen].Name = "ReadOnly";
292 aArgs[nLen++].Value <<= true;
293
294 if ( _bHidden )
295 {
296 aArgs[nLen].Name = "Hidden";
297 aArgs[nLen++].Value <<= true;
298 }
299
300 xModel.set( xFrameLoad->loadComponentFromURL(
301 sOutputName,
302 OUString(), // empty frame name
303 0,
304 aArgs
305 ),uno::UNO_QUERY);
306 }
307 }
308 return xModel;
309 }
310
createDocument()311 util::URL SAL_CALL OReportEngineJFree::createDocument( )
312 {
313 util::URL aRet;
314 uno::Reference< frame::XModel > xModel = createDocumentModel();
315 if ( xModel.is() )
316 {
317 ::osl::MutexGuard aGuard(m_aMutex);
318 ::connectivity::checkDisposed(ReportEngineBase::rBHelper.bDisposed);
319 }
320 return aRet;
321 }
322
interrupt()323 void SAL_CALL OReportEngineJFree::interrupt( )
324 {
325 ::osl::MutexGuard aGuard(m_aMutex);
326 ::connectivity::checkDisposed(ReportEngineBase::rBHelper.bDisposed);
327 }
328
getPropertySetInfo()329 uno::Reference< beans::XPropertySetInfo > SAL_CALL OReportEngineJFree::getPropertySetInfo( )
330 {
331 return ReportEnginePropertySet::getPropertySetInfo();
332 }
333
setPropertyValue(const OUString & aPropertyName,const uno::Any & aValue)334 void SAL_CALL OReportEngineJFree::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue )
335 {
336 ReportEnginePropertySet::setPropertyValue( aPropertyName, aValue );
337 }
338
getPropertyValue(const OUString & PropertyName)339 uno::Any SAL_CALL OReportEngineJFree::getPropertyValue( const OUString& PropertyName )
340 {
341 return ReportEnginePropertySet::getPropertyValue( PropertyName);
342 }
343
addPropertyChangeListener(const OUString & aPropertyName,const uno::Reference<beans::XPropertyChangeListener> & xListener)344 void SAL_CALL OReportEngineJFree::addPropertyChangeListener( const OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& xListener )
345 {
346 ReportEnginePropertySet::addPropertyChangeListener( aPropertyName, xListener );
347 }
348
removePropertyChangeListener(const OUString & aPropertyName,const uno::Reference<beans::XPropertyChangeListener> & aListener)349 void SAL_CALL OReportEngineJFree::removePropertyChangeListener( const OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& aListener )
350 {
351 ReportEnginePropertySet::removePropertyChangeListener( aPropertyName, aListener );
352 }
353
addVetoableChangeListener(const OUString & PropertyName,const uno::Reference<beans::XVetoableChangeListener> & aListener)354 void SAL_CALL OReportEngineJFree::addVetoableChangeListener( const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener )
355 {
356 ReportEnginePropertySet::addVetoableChangeListener( PropertyName, aListener );
357 }
358
removeVetoableChangeListener(const OUString & PropertyName,const uno::Reference<beans::XVetoableChangeListener> & aListener)359 void SAL_CALL OReportEngineJFree::removeVetoableChangeListener( const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener )
360 {
361 ReportEnginePropertySet::removeVetoableChangeListener( PropertyName, aListener );
362 }
363
getActiveConnection()364 uno::Reference< sdbc::XConnection > SAL_CALL OReportEngineJFree::getActiveConnection()
365 {
366 return m_xActiveConnection;
367 }
368
setActiveConnection(const uno::Reference<sdbc::XConnection> & _activeconnection)369 void SAL_CALL OReportEngineJFree::setActiveConnection( const uno::Reference< sdbc::XConnection >& _activeconnection )
370 {
371 if ( !_activeconnection.is() )
372 throw lang::IllegalArgumentException();
373 set(PROPERTY_ACTIVECONNECTION,_activeconnection,m_xActiveConnection);
374 }
375
getMaxRows()376 ::sal_Int32 SAL_CALL OReportEngineJFree::getMaxRows()
377 {
378 ::osl::MutexGuard aGuard(m_aMutex);
379 return m_nMaxRows;
380 }
381
setMaxRows(::sal_Int32 MaxRows)382 void SAL_CALL OReportEngineJFree::setMaxRows( ::sal_Int32 MaxRows )
383 {
384 set(PROPERTY_MAXROWS,MaxRows,m_nMaxRows);
385 }
386
387 } // namespace reportdesign
388
389
390 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
391