1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_ucbhelper.hxx"
30 
31 /**************************************************************************
32 								TODO
33  **************************************************************************
34 
35  - This implementation is far away from completion. It has no interface
36    for changes notifications etc.
37 
38  *************************************************************************/
39 #include <com/sun/star/ucb/ListActionType.hpp>
40 #include <com/sun/star/ucb/WelcomeDynamicResultSetStruct.hpp>
41 #include <com/sun/star/ucb/XCachedDynamicResultSetStubFactory.hpp>
42 #include <com/sun/star/ucb/XSourceInitialization.hpp>
43 #include <cppuhelper/interfacecontainer.hxx>
44 #include <ucbhelper/resultsethelper.hxx>
45 
46 #include "osl/diagnose.h"
47 
48 using namespace com::sun::star;
49 
50 //=========================================================================
51 //=========================================================================
52 //
53 // ResultSetImplHelper Implementation.
54 //
55 //=========================================================================
56 //=========================================================================
57 
58 namespace ucbhelper {
59 
60 //=========================================================================
61 ResultSetImplHelper::ResultSetImplHelper(
62     const uno::Reference< lang::XMultiServiceFactory >& rxSMgr )
63 : m_pDisposeEventListeners( 0 ),
64   m_bStatic( sal_False ),
65   m_bInitDone( sal_False ),
66   m_xSMgr( rxSMgr )
67 {
68 }
69 
70 //=========================================================================
71 ResultSetImplHelper::ResultSetImplHelper(
72     const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
73     const com::sun::star::ucb::OpenCommandArgument2& rCommand )
74 : m_pDisposeEventListeners( 0 ),
75   m_bStatic( sal_False ),
76   m_bInitDone( sal_False ),
77   m_aCommand( rCommand ),
78   m_xSMgr( rxSMgr )
79 {
80 }
81 
82 //=========================================================================
83 // virtual
84 ResultSetImplHelper::~ResultSetImplHelper()
85 {
86 	delete m_pDisposeEventListeners;
87 }
88 
89 //=========================================================================
90 //
91 // XInterface methods.
92 //
93 //=========================================================================
94 
95 XINTERFACE_IMPL_4( ResultSetImplHelper,
96 				   lang::XTypeProvider,
97 				   lang::XServiceInfo,
98 				   lang::XComponent, /* base of XDynamicResultSet */
99 				   com::sun::star::ucb::XDynamicResultSet );
100 
101 //=========================================================================
102 //
103 // XTypeProvider methods.
104 //
105 //=========================================================================
106 
107 XTYPEPROVIDER_IMPL_3( ResultSetImplHelper,
108 					  lang::XTypeProvider,
109 				   	  lang::XServiceInfo,
110 					  com::sun::star::ucb::XDynamicResultSet );
111 
112 //=========================================================================
113 //
114 // XServiceInfo methods.
115 //
116 //=========================================================================
117 
118 XSERVICEINFO_NOFACTORY_IMPL_1( ResultSetImplHelper,
119                                rtl::OUString::createFromAscii(
120                                    "ResultSetImplHelper" ),
121                                rtl::OUString::createFromAscii(
122                                    DYNAMICRESULTSET_SERVICE_NAME ) );
123 
124 //=========================================================================
125 //
126 // XComponent methods.
127 //
128 //=========================================================================
129 
130 // virtual
131 void SAL_CALL ResultSetImplHelper::dispose()
132 	throw( uno::RuntimeException )
133 {
134 	osl::MutexGuard aGuard( m_aMutex );
135 
136 	if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() )
137 	{
138 		lang::EventObject aEvt;
139 		aEvt.Source = static_cast< lang::XComponent * >( this );
140 		m_pDisposeEventListeners->disposeAndClear( aEvt );
141 	}
142 }
143 
144 //=========================================================================
145 // virtual
146 void SAL_CALL ResultSetImplHelper::addEventListener(
147         const uno::Reference< lang::XEventListener >& Listener )
148 	throw( uno::RuntimeException )
149 {
150 	osl::MutexGuard aGuard( m_aMutex );
151 
152 	if ( !m_pDisposeEventListeners )
153 		m_pDisposeEventListeners
154             = new cppu::OInterfaceContainerHelper( m_aMutex );
155 
156 	m_pDisposeEventListeners->addInterface( Listener );
157 }
158 
159 //=========================================================================
160 // virtual
161 void SAL_CALL ResultSetImplHelper::removeEventListener(
162         const uno::Reference< lang::XEventListener >& Listener )
163 	throw( uno::RuntimeException )
164 {
165 	osl::MutexGuard aGuard( m_aMutex );
166 
167 	if ( m_pDisposeEventListeners )
168 		m_pDisposeEventListeners->removeInterface( Listener );
169 }
170 
171 //=========================================================================
172 //
173 // XDynamicResultSet methods.
174 //
175 //=========================================================================
176 
177 // virtual
178 uno::Reference< sdbc::XResultSet > SAL_CALL
179 ResultSetImplHelper::getStaticResultSet()
180 	throw( com::sun::star::ucb::ListenerAlreadySetException,
181            uno::RuntimeException )
182 {
183 	osl::MutexGuard aGuard( m_aMutex );
184 
185 	if ( m_xListener.is() )
186 		throw com::sun::star::ucb::ListenerAlreadySetException();
187 
188 	init( sal_True );
189 	return m_xResultSet1;
190 }
191 
192 //=========================================================================
193 // virtual
194 void SAL_CALL ResultSetImplHelper::setListener(
195         const uno::Reference< com::sun::star::ucb::XDynamicResultSetListener >&
196             Listener )
197 	throw( com::sun::star::ucb::ListenerAlreadySetException,
198            uno::RuntimeException )
199 {
200 	osl::ClearableMutexGuard aGuard( m_aMutex );
201 
202 	if ( m_bStatic || m_xListener.is() )
203 		throw com::sun::star::ucb::ListenerAlreadySetException();
204 
205 	m_xListener = Listener;
206 
207 	//////////////////////////////////////////////////////////////////////
208 	// Create "welcome event" and send it to listener.
209 	//////////////////////////////////////////////////////////////////////
210 
211 	// Note: We only have the implementation for a static result set at the
212 	//       moment (src590). The dynamic result sets passed to the listener
213 	//       are a fake. This implementation will never call "notify" at the
214 	//       listener to propagate any changes!!!
215 
216 	init( sal_False );
217 
218 	uno::Any aInfo;
219 	aInfo <<= com::sun::star::ucb::WelcomeDynamicResultSetStruct(
220         m_xResultSet1 /* "old" */,
221         m_xResultSet2 /* "new" */ );
222 
223 	uno::Sequence< com::sun::star::ucb::ListAction > aActions( 1 );
224 	aActions.getArray()[ 0 ]
225         = com::sun::star::ucb::ListAction(
226             0, // Position; not used
227             0, // Count; not used
228             com::sun::star::ucb::ListActionType::WELCOME,
229             aInfo );
230 	aGuard.clear();
231 
232 	Listener->notify(
233         com::sun::star::ucb::ListEvent(
234             static_cast< cppu::OWeakObject * >( this ), aActions ) );
235 }
236 
237 //=========================================================================
238 // virtual
239 sal_Int16 SAL_CALL ResultSetImplHelper::getCapabilities()
240 	throw( uno::RuntimeException )
241 {
242 	// ! com::sun::star::ucb::ContentResultSetCapability::SORTED
243 	return 0;
244 }
245 
246 //=========================================================================
247 // virtual
248 void SAL_CALL ResultSetImplHelper::connectToCache(
249         const uno::Reference< com::sun::star::ucb::XDynamicResultSet > &
250             xCache )
251 	throw( com::sun::star::ucb::ListenerAlreadySetException,
252 		   com::sun::star::ucb::AlreadyInitializedException,
253 		   com::sun::star::ucb::ServiceNotFoundException,
254 		   uno::RuntimeException )
255 {
256 	if ( m_xListener.is() )
257 		throw com::sun::star::ucb::ListenerAlreadySetException();
258 
259 	if ( m_bStatic )
260 		throw com::sun::star::ucb::ListenerAlreadySetException();
261 
262 	uno::Reference< com::sun::star::ucb::XSourceInitialization >
263         xTarget( xCache, uno::UNO_QUERY );
264 	if ( xTarget.is() )
265 	{
266 		uno::Reference<
267             com::sun::star::ucb::XCachedDynamicResultSetStubFactory >
268                 xStubFactory;
269 		try
270 		{
271 			xStubFactory
272                 = uno::Reference<
273                     com::sun::star::ucb::XCachedDynamicResultSetStubFactory >(
274                         m_xSMgr->createInstance(
275                             rtl::OUString::createFromAscii(
276                                 "com.sun.star.ucb.CachedDynamicResultSetStubFactory" ) ),
277 				uno::UNO_QUERY );
278 		}
279 		catch ( uno::Exception const & )
280 		{
281 		}
282 
283 		if ( xStubFactory.is() )
284 		{
285 			xStubFactory->connectToCache(
286 				  				this, xCache, m_aCommand.SortingInfo, 0 );
287 			return;
288 		}
289 	}
290 	throw com::sun::star::ucb::ServiceNotFoundException();
291 }
292 
293 //=========================================================================
294 //
295 // Non-interface methods.
296 //
297 //=========================================================================
298 
299 void ResultSetImplHelper::init( sal_Bool bStatic )
300 {
301 	osl::MutexGuard aGuard( m_aMutex );
302 
303 	if ( !m_bInitDone )
304 	{
305 		if ( bStatic )
306 		{
307 			// virtual... derived class fills m_xResultSet1
308 			initStatic();
309 
310 			OSL_ENSURE( m_xResultSet1.is(),
311 						"ResultSetImplHelper::init - No 1st result set!" );
312 			m_bStatic = sal_True;
313 		}
314 		else
315 		{
316 			// virtual... derived class fills m_xResultSet1 and m_xResultSet2
317 			initDynamic();
318 
319 			OSL_ENSURE( m_xResultSet1.is(),
320 						"ResultSetImplHelper::init - No 1st result set!" );
321 			OSL_ENSURE( m_xResultSet2.is(),
322 						"ResultSetImplHelper::init - No 2nd result set!" );
323 			m_bStatic = sal_False;
324 		}
325 		m_bInitDone = sal_True;
326 	}
327 }
328 
329 } // namespace ucbhelper
330