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