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