Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 : :
29 : : #include "ucpext_datasupplier.hxx"
30 : : #include "ucpext_content.hxx"
31 : : #include "ucpext_provider.hxx"
32 : :
33 : : #include <com/sun/star/deployment/XPackageInformationProvider.hpp>
34 : :
35 : : #include <ucbhelper/contentidentifier.hxx>
36 : : #include <comphelper/componentcontext.hxx>
37 : : #include <ucbhelper/providerhelper.hxx>
38 : : #include <ucbhelper/content.hxx>
39 : : #include <ucbhelper/propertyvalueset.hxx>
40 : : #include <tools/diagnose_ex.h>
41 : : #include <rtl/ustrbuf.hxx>
42 : :
43 : : #include <vector>
44 : : #include <boost/shared_ptr.hpp>
45 : :
46 : : //......................................................................................................................
47 : : namespace ucb { namespace ucp { namespace ext
48 : : {
49 : : //......................................................................................................................
50 : :
51 : : /** === begin UNO using === **/
52 : : using ::com::sun::star::uno::Reference;
53 : : using ::com::sun::star::uno::XInterface;
54 : : using ::com::sun::star::uno::UNO_QUERY;
55 : : using ::com::sun::star::uno::UNO_QUERY_THROW;
56 : : using ::com::sun::star::uno::UNO_SET_THROW;
57 : : using ::com::sun::star::uno::Exception;
58 : : using ::com::sun::star::uno::RuntimeException;
59 : : using ::com::sun::star::uno::Any;
60 : : using ::com::sun::star::uno::makeAny;
61 : : using ::com::sun::star::uno::Sequence;
62 : : using ::com::sun::star::uno::Type;
63 : : using ::com::sun::star::ucb::XContent;
64 : : using ::com::sun::star::ucb::XContentIdentifier;
65 : : using ::com::sun::star::sdbc::XRow;
66 : : using ::com::sun::star::lang::XMultiServiceFactory;
67 : : using ::com::sun::star::ucb::IllegalIdentifierException;
68 : : using ::com::sun::star::ucb::ResultSetException;
69 : : using ::com::sun::star::deployment::XPackageInformationProvider;
70 : : using ::com::sun::star::beans::Property;
71 : : using ::com::sun::star::sdbc::XResultSet;
72 : : using ::com::sun::star::sdbc::XRow;
73 : : using ::com::sun::star::ucb::XCommandEnvironment;
74 : : /** === end UNO using === **/
75 : : //==================================================================================================================
76 : : //= ResultListEntry
77 : : //==================================================================================================================
78 : 0 : struct ResultListEntry
79 : : {
80 : : ::rtl::OUString sId;
81 : : Reference< XContentIdentifier > xId;
82 : : ::rtl::Reference< Content > pContent;
83 : : Reference< XRow > xRow;
84 : : };
85 : :
86 : : typedef ::std::vector< ResultListEntry > ResultList;
87 : :
88 : : //==================================================================================================================
89 : : //= DataSupplier_Impl
90 : : //==================================================================================================================
91 : : struct DataSupplier_Impl
92 : : {
93 : : ::osl::Mutex m_aMutex;
94 : : ResultList m_aResults;
95 : : ::rtl::Reference< Content > m_xContent;
96 : : Reference< XMultiServiceFactory > m_xSMgr;
97 : : sal_Int32 m_nOpenMode;
98 : :
99 : 0 : DataSupplier_Impl( const Reference< XMultiServiceFactory >& i_rORB, const ::rtl::Reference< Content >& i_rContent,
100 : : const sal_Int32 i_nOpenMode )
101 : : :m_xContent( i_rContent )
102 : : ,m_xSMgr( i_rORB )
103 : 0 : ,m_nOpenMode( i_nOpenMode )
104 : : {
105 : 0 : }
106 : : ~DataSupplier_Impl();
107 : : };
108 : :
109 : : //------------------------------------------------------------------------------------------------------------------
110 : 0 : DataSupplier_Impl::~DataSupplier_Impl()
111 : : {
112 : 0 : }
113 : :
114 : : //==================================================================================================================
115 : : //= helper
116 : : //==================================================================================================================
117 : : namespace
118 : : {
119 : 0 : ::rtl::OUString lcl_compose( const ::rtl::OUString& i_rBaseURL, const ::rtl::OUString& i_rRelativeURL )
120 : : {
121 : 0 : ENSURE_OR_RETURN( !i_rBaseURL.isEmpty(), "illegal base URL", i_rRelativeURL );
122 : :
123 : 0 : ::rtl::OUStringBuffer aComposer( i_rBaseURL );
124 : 0 : if ( i_rBaseURL.getStr()[ i_rBaseURL.getLength() - 1 ] != '/' )
125 : 0 : aComposer.append( sal_Unicode( '/' ) );
126 : 0 : aComposer.append( i_rRelativeURL );
127 : 0 : return aComposer.makeStringAndClear();
128 : : }
129 : : }
130 : :
131 : :
132 : : //==================================================================================================================
133 : : //= DataSupplier
134 : : //==================================================================================================================
135 : : //------------------------------------------------------------------------------------------------------------------
136 : 0 : DataSupplier::DataSupplier( const Reference< XMultiServiceFactory >& i_rORB,
137 : : const ::rtl::Reference< Content >& i_rContent,
138 : : const sal_Int32 i_nOpenMode )
139 : 0 : :m_pImpl( new DataSupplier_Impl( i_rORB, i_rContent, i_nOpenMode ) )
140 : : {
141 : 0 : }
142 : :
143 : : //------------------------------------------------------------------------------------------------------------------
144 : 0 : void DataSupplier::fetchData()
145 : : {
146 : : try
147 : : {
148 : 0 : const ::comphelper::ComponentContext aContext( m_pImpl->m_xSMgr );
149 : : const Reference< XPackageInformationProvider > xPackageInfo(
150 : 0 : aContext.getSingleton( "com.sun.star.deployment.PackageInformationProvider" ), UNO_QUERY_THROW );
151 : :
152 : 0 : const ::rtl::OUString sContentIdentifier( m_pImpl->m_xContent->getIdentifier()->getContentIdentifier() );
153 : :
154 : 0 : switch ( m_pImpl->m_xContent->getExtensionContentType() )
155 : : {
156 : : case E_ROOT:
157 : : {
158 : 0 : Sequence< Sequence< ::rtl::OUString > > aExtensionInfo( xPackageInfo->getExtensionList() );
159 : 0 : for ( const Sequence< ::rtl::OUString >* pExtInfo = aExtensionInfo.getConstArray();
160 : 0 : pExtInfo != aExtensionInfo.getConstArray() + aExtensionInfo.getLength();
161 : : ++pExtInfo
162 : : )
163 : : {
164 : 0 : if ( pExtInfo->getLength() <= 0 )
165 : : {
166 : : SAL_WARN( "ucb.ucp", "illegal extension info" );
167 : 0 : continue;
168 : : }
169 : :
170 : 0 : const ::rtl::OUString& rLocalId = (*pExtInfo)[0];
171 : 0 : ResultListEntry aEntry;
172 : 0 : aEntry.sId = ContentProvider::getRootURL() + Content::encodeIdentifier( rLocalId ) + ::rtl::OUString( sal_Unicode( '/' ) );
173 : 0 : m_pImpl->m_aResults.push_back( aEntry );
174 : 0 : }
175 : : }
176 : 0 : break;
177 : : case E_EXTENSION_ROOT:
178 : : case E_EXTENSION_CONTENT:
179 : : {
180 : 0 : const ::rtl::OUString sPackageLocation( m_pImpl->m_xContent->getPhysicalURL() );
181 : 0 : ::ucbhelper::Content aWrappedContent( sPackageLocation, getResultSet()->getEnvironment() );
182 : :
183 : : // obtain the properties which our result set is set up for from the wrapped content
184 : 0 : Sequence< ::rtl::OUString > aPropertyNames(1);
185 : 0 : aPropertyNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) );
186 : :
187 : 0 : const Reference< XResultSet > xFolderContent( aWrappedContent.createCursor( aPropertyNames ), UNO_SET_THROW );
188 : 0 : const Reference< XRow > xContentRow( xFolderContent, UNO_QUERY_THROW );
189 : 0 : while ( xFolderContent->next() )
190 : : {
191 : 0 : ResultListEntry aEntry;
192 : 0 : aEntry.sId = lcl_compose( sContentIdentifier, xContentRow->getString( 1 ) );
193 : 0 : m_pImpl->m_aResults.push_back( aEntry );
194 : 0 : }
195 : : }
196 : 0 : break;
197 : : default:
198 : : OSL_FAIL( "DataSupplier::fetchData: unimplemented content type!" );
199 : 0 : break;
200 : 0 : }
201 : : }
202 : 0 : catch( const Exception& )
203 : : {
204 : : DBG_UNHANDLED_EXCEPTION();
205 : : }
206 : 0 : }
207 : :
208 : : //------------------------------------------------------------------------------------------------------------------
209 : 0 : DataSupplier::~DataSupplier()
210 : : {
211 : 0 : }
212 : :
213 : : //------------------------------------------------------------------------------------------------------------------
214 : 0 : ::rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 i_nIndex )
215 : : {
216 : 0 : ::osl::Guard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex );
217 : :
218 : 0 : if ( i_nIndex < m_pImpl->m_aResults.size() )
219 : : {
220 : 0 : const ::rtl::OUString sId = m_pImpl->m_aResults[ i_nIndex ].sId;
221 : 0 : if ( !sId.isEmpty() )
222 : 0 : return sId;
223 : : }
224 : :
225 : : OSL_FAIL( "DataSupplier::queryContentIdentifierString: illegal index, or illegal result entry id!" );
226 : 0 : return ::rtl::OUString();
227 : : }
228 : :
229 : : //------------------------------------------------------------------------------------------------------------------
230 : 0 : Reference< XContentIdentifier > DataSupplier::queryContentIdentifier( sal_uInt32 i_nIndex )
231 : : {
232 : 0 : ::osl::Guard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex );
233 : :
234 : 0 : if ( i_nIndex < m_pImpl->m_aResults.size() )
235 : : {
236 : 0 : Reference< XContentIdentifier > xId( m_pImpl->m_aResults[ i_nIndex ].xId );
237 : 0 : if ( xId.is() )
238 : 0 : return xId;
239 : : }
240 : :
241 : 0 : ::rtl::OUString sId = queryContentIdentifierString( i_nIndex );
242 : 0 : if ( !sId.isEmpty() )
243 : : {
244 : 0 : Reference< XContentIdentifier > xId = new ::ucbhelper::ContentIdentifier( sId );
245 : 0 : m_pImpl->m_aResults[ i_nIndex ].xId = xId;
246 : 0 : return xId;
247 : : }
248 : :
249 : 0 : return Reference< XContentIdentifier >();
250 : : }
251 : :
252 : : //------------------------------------------------------------------------------------------------------------------
253 : 0 : Reference< XContent > DataSupplier::queryContent( sal_uInt32 i_nIndex )
254 : : {
255 : 0 : ::osl::Guard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex );
256 : 0 : ENSURE_OR_RETURN( i_nIndex < m_pImpl->m_aResults.size(), "illegal index!", NULL );
257 : :
258 : :
259 : 0 : ::rtl::Reference< Content > pContent( m_pImpl->m_aResults[ i_nIndex ].pContent );
260 : 0 : if ( pContent.is() )
261 : 0 : return pContent.get();
262 : :
263 : 0 : Reference< XContentIdentifier > xId( queryContentIdentifier( i_nIndex ) );
264 : 0 : if ( xId.is() )
265 : : {
266 : : try
267 : : {
268 : 0 : Reference< XContent > xContent( m_pImpl->m_xContent->getProvider()->queryContent( xId ) );
269 : 0 : pContent.set( dynamic_cast< Content* >( xContent.get() ) );
270 : : OSL_ENSURE( pContent.is() || !xContent.is(), "DataSupplier::queryContent: invalid content implementation!" );
271 : 0 : m_pImpl->m_aResults[ i_nIndex ].pContent = pContent;
272 : 0 : return pContent.get();
273 : :
274 : : }
275 : 0 : catch ( const IllegalIdentifierException& )
276 : : {
277 : : DBG_UNHANDLED_EXCEPTION();
278 : : }
279 : : }
280 : :
281 : 0 : return Reference< XContent >();
282 : : }
283 : :
284 : : //------------------------------------------------------------------------------------------------------------------
285 : 0 : sal_Bool DataSupplier::getResult( sal_uInt32 i_nIndex )
286 : : {
287 : 0 : ::osl::ClearableGuard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex );
288 : :
289 : 0 : if ( m_pImpl->m_aResults.size() > i_nIndex )
290 : : // result already present.
291 : 0 : return sal_True;
292 : :
293 : 0 : return sal_False;
294 : : }
295 : :
296 : : //------------------------------------------------------------------------------------------------------------------
297 : 0 : sal_uInt32 DataSupplier::totalCount()
298 : : {
299 : 0 : ::osl::ClearableGuard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex );
300 : 0 : return m_pImpl->m_aResults.size();
301 : : }
302 : :
303 : : //------------------------------------------------------------------------------------------------------------------
304 : 0 : sal_uInt32 DataSupplier::currentCount()
305 : : {
306 : 0 : return m_pImpl->m_aResults.size();
307 : : }
308 : :
309 : : //------------------------------------------------------------------------------------------------------------------
310 : 0 : sal_Bool DataSupplier::isCountFinal()
311 : : {
312 : 0 : return sal_True;
313 : : }
314 : :
315 : : //------------------------------------------------------------------------------------------------------------------
316 : 0 : Reference< XRow > DataSupplier::queryPropertyValues( sal_uInt32 i_nIndex )
317 : : {
318 : 0 : ::osl::MutexGuard aGuard( m_pImpl->m_aMutex );
319 : 0 : ENSURE_OR_RETURN( i_nIndex < m_pImpl->m_aResults.size(), "DataSupplier::queryPropertyValues: illegal index!", NULL );
320 : :
321 : 0 : Reference< XRow > xRow = m_pImpl->m_aResults[ i_nIndex ].xRow;
322 : 0 : if ( xRow.is() )
323 : 0 : return xRow;
324 : :
325 : 0 : ENSURE_OR_RETURN( queryContent( i_nIndex ).is(), "could not retrieve the content", NULL );
326 : :
327 : 0 : switch ( m_pImpl->m_xContent->getExtensionContentType() )
328 : : {
329 : : case E_ROOT:
330 : : {
331 : 0 : const ::rtl::OUString& rId( m_pImpl->m_aResults[ i_nIndex ].sId );
332 : 0 : const ::rtl::OUString sRootURL( ContentProvider::getRootURL() );
333 : 0 : ::rtl::OUString sTitle = Content::decodeIdentifier( rId.copy( sRootURL.getLength() ) );
334 : 0 : if ( !sTitle.isEmpty() && ( sTitle[ sTitle.getLength() - 1 ] == '/' ) )
335 : 0 : sTitle = sTitle.copy( 0, sTitle.getLength() - 1 );
336 : 0 : xRow = Content::getArtificialNodePropertyValues( m_pImpl->m_xSMgr, getResultSet()->getProperties(), sTitle );
337 : : }
338 : 0 : break;
339 : :
340 : : case E_EXTENSION_ROOT:
341 : : case E_EXTENSION_CONTENT:
342 : : {
343 : 0 : xRow = m_pImpl->m_aResults[ i_nIndex ].pContent->getPropertyValues(
344 : 0 : getResultSet()->getProperties(), getResultSet()->getEnvironment() );
345 : : }
346 : 0 : break;
347 : : default:
348 : : OSL_FAIL( "DataSupplier::queryPropertyValues: unhandled case!" );
349 : 0 : break;
350 : : }
351 : :
352 : 0 : m_pImpl->m_aResults[ i_nIndex ].xRow = xRow;
353 : 0 : return xRow;
354 : : }
355 : :
356 : : //------------------------------------------------------------------------------------------------------------------
357 : 0 : void DataSupplier::releasePropertyValues( sal_uInt32 i_nIndex )
358 : : {
359 : 0 : ::osl::Guard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex );
360 : :
361 : 0 : if ( i_nIndex < m_pImpl->m_aResults.size() )
362 : 0 : m_pImpl->m_aResults[ i_nIndex ].xRow.clear();
363 : 0 : }
364 : :
365 : : //------------------------------------------------------------------------------------------------------------------
366 : 0 : void DataSupplier::close()
367 : : {
368 : 0 : }
369 : :
370 : : //------------------------------------------------------------------------------------------------------------------
371 : 0 : void DataSupplier::validate() throw( ResultSetException )
372 : : {
373 : 0 : }
374 : :
375 : : //......................................................................................................................
376 : : } } } // namespace ucp::ext
377 : : //......................................................................................................................
378 : :
379 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|