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