Bump for 3.6-28
[LibreOffice.git] / ucb / source / ucp / ext / ucpext_datasupplier.cxx
blob8425ffe8135b18ae8edf39f3c619b031a7624388
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.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
29 #include "ucpext_datasupplier.hxx"
30 #include "ucpext_content.hxx"
31 #include "ucpext_provider.hxx"
33 /** === begin UNO includes === **/
34 #include <com/sun/star/deployment/XPackageInformationProvider.hpp>
35 /** === end UNO includes === **/
37 #include <ucbhelper/contentidentifier.hxx>
38 #include <comphelper/componentcontext.hxx>
39 #include <ucbhelper/providerhelper.hxx>
40 #include <ucbhelper/content.hxx>
41 #include <ucbhelper/propertyvalueset.hxx>
42 #include <tools/diagnose_ex.h>
43 #include <rtl/ustrbuf.hxx>
45 #include <vector>
46 #include <boost/shared_ptr.hpp>
48 //......................................................................................................................
49 namespace ucb { namespace ucp { namespace ext
51 //......................................................................................................................
53 /** === begin UNO using === **/
54 using ::com::sun::star::uno::Reference;
55 using ::com::sun::star::uno::XInterface;
56 using ::com::sun::star::uno::UNO_QUERY;
57 using ::com::sun::star::uno::UNO_QUERY_THROW;
58 using ::com::sun::star::uno::UNO_SET_THROW;
59 using ::com::sun::star::uno::Exception;
60 using ::com::sun::star::uno::RuntimeException;
61 using ::com::sun::star::uno::Any;
62 using ::com::sun::star::uno::makeAny;
63 using ::com::sun::star::uno::Sequence;
64 using ::com::sun::star::uno::Type;
65 using ::com::sun::star::ucb::XContent;
66 using ::com::sun::star::ucb::XContentIdentifier;
67 using ::com::sun::star::sdbc::XRow;
68 using ::com::sun::star::lang::XMultiServiceFactory;
69 using ::com::sun::star::ucb::IllegalIdentifierException;
70 using ::com::sun::star::ucb::ResultSetException;
71 using ::com::sun::star::deployment::XPackageInformationProvider;
72 using ::com::sun::star::beans::Property;
73 using ::com::sun::star::sdbc::XResultSet;
74 using ::com::sun::star::sdbc::XRow;
75 using ::com::sun::star::ucb::XCommandEnvironment;
76 /** === end UNO using === **/
77 //==================================================================================================================
78 //= ResultListEntry
79 //==================================================================================================================
80 struct ResultListEntry
82 ::rtl::OUString sId;
83 Reference< XContentIdentifier > xId;
84 ::rtl::Reference< Content > pContent;
85 Reference< XRow > xRow;
88 typedef ::std::vector< ResultListEntry > ResultList;
90 //==================================================================================================================
91 //= DataSupplier_Impl
92 //==================================================================================================================
93 struct DataSupplier_Impl
95 ::osl::Mutex m_aMutex;
96 ResultList m_aResults;
97 ::rtl::Reference< Content > m_xContent;
98 Reference< XMultiServiceFactory > m_xSMgr;
99 sal_Int32 m_nOpenMode;
101 DataSupplier_Impl( const Reference< XMultiServiceFactory >& i_rORB, const ::rtl::Reference< Content >& i_rContent,
102 const sal_Int32 i_nOpenMode )
103 :m_xContent( i_rContent )
104 ,m_xSMgr( i_rORB )
105 ,m_nOpenMode( i_nOpenMode )
108 ~DataSupplier_Impl();
111 //------------------------------------------------------------------------------------------------------------------
112 DataSupplier_Impl::~DataSupplier_Impl()
116 //==================================================================================================================
117 //= helper
118 //==================================================================================================================
119 namespace
121 ::rtl::OUString lcl_compose( const ::rtl::OUString& i_rBaseURL, const ::rtl::OUString& i_rRelativeURL )
123 ENSURE_OR_RETURN( !i_rBaseURL.isEmpty(), "illegal base URL", i_rRelativeURL );
125 ::rtl::OUStringBuffer aComposer( i_rBaseURL );
126 if ( i_rBaseURL.getStr()[ i_rBaseURL.getLength() - 1 ] != '/' )
127 aComposer.append( sal_Unicode( '/' ) );
128 aComposer.append( i_rRelativeURL );
129 return aComposer.makeStringAndClear();
134 //==================================================================================================================
135 //= DataSupplier
136 //==================================================================================================================
137 //------------------------------------------------------------------------------------------------------------------
138 DataSupplier::DataSupplier( const Reference< XMultiServiceFactory >& i_rORB,
139 const ::rtl::Reference< Content >& i_rContent,
140 const sal_Int32 i_nOpenMode )
141 :m_pImpl( new DataSupplier_Impl( i_rORB, i_rContent, i_nOpenMode ) )
145 //------------------------------------------------------------------------------------------------------------------
146 void DataSupplier::fetchData()
150 const ::comphelper::ComponentContext aContext( m_pImpl->m_xSMgr );
151 const Reference< XPackageInformationProvider > xPackageInfo(
152 aContext.getSingleton( "com.sun.star.deployment.PackageInformationProvider" ), UNO_QUERY_THROW );
154 const ::rtl::OUString sContentIdentifier( m_pImpl->m_xContent->getIdentifier()->getContentIdentifier() );
156 switch ( m_pImpl->m_xContent->getExtensionContentType() )
158 case E_ROOT:
160 Sequence< Sequence< ::rtl::OUString > > aExtensionInfo( xPackageInfo->getExtensionList() );
161 for ( const Sequence< ::rtl::OUString >* pExtInfo = aExtensionInfo.getConstArray();
162 pExtInfo != aExtensionInfo.getConstArray() + aExtensionInfo.getLength();
163 ++pExtInfo
166 if ( pExtInfo->getLength() <= 0 )
168 SAL_WARN( "ucb.ucp", "illegal extension info" );
169 continue;
172 const ::rtl::OUString& rLocalId = (*pExtInfo)[0];
173 ResultListEntry aEntry;
174 aEntry.sId = ContentProvider::getRootURL() + Content::encodeIdentifier( rLocalId ) + ::rtl::OUString( sal_Unicode( '/' ) );
175 m_pImpl->m_aResults.push_back( aEntry );
178 break;
179 case E_EXTENSION_ROOT:
180 case E_EXTENSION_CONTENT:
182 const ::rtl::OUString sPackageLocation( m_pImpl->m_xContent->getPhysicalURL() );
183 ::ucbhelper::Content aWrappedContent( sPackageLocation, getResultSet()->getEnvironment() );
185 // obtain the properties which our result set is set up for from the wrapped content
186 Sequence< ::rtl::OUString > aPropertyNames(1);
187 aPropertyNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) );
189 const Reference< XResultSet > xFolderContent( aWrappedContent.createCursor( aPropertyNames ), UNO_SET_THROW );
190 const Reference< XRow > xContentRow( xFolderContent, UNO_QUERY_THROW );
191 while ( xFolderContent->next() )
193 ResultListEntry aEntry;
194 aEntry.sId = lcl_compose( sContentIdentifier, xContentRow->getString( 1 ) );
195 m_pImpl->m_aResults.push_back( aEntry );
198 break;
199 default:
200 OSL_FAIL( "DataSupplier::fetchData: unimplemented content type!" );
201 break;
204 catch( const Exception& )
206 DBG_UNHANDLED_EXCEPTION();
210 //------------------------------------------------------------------------------------------------------------------
211 DataSupplier::~DataSupplier()
215 //------------------------------------------------------------------------------------------------------------------
216 ::rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 i_nIndex )
218 ::osl::Guard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex );
220 if ( i_nIndex < m_pImpl->m_aResults.size() )
222 const ::rtl::OUString sId = m_pImpl->m_aResults[ i_nIndex ].sId;
223 if ( !sId.isEmpty() )
224 return sId;
227 OSL_FAIL( "DataSupplier::queryContentIdentifierString: illegal index, or illegal result entry id!" );
228 return ::rtl::OUString();
231 //------------------------------------------------------------------------------------------------------------------
232 Reference< XContentIdentifier > DataSupplier::queryContentIdentifier( sal_uInt32 i_nIndex )
234 ::osl::Guard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex );
236 if ( i_nIndex < m_pImpl->m_aResults.size() )
238 Reference< XContentIdentifier > xId( m_pImpl->m_aResults[ i_nIndex ].xId );
239 if ( xId.is() )
240 return xId;
243 ::rtl::OUString sId = queryContentIdentifierString( i_nIndex );
244 if ( !sId.isEmpty() )
246 Reference< XContentIdentifier > xId = new ::ucbhelper::ContentIdentifier( sId );
247 m_pImpl->m_aResults[ i_nIndex ].xId = xId;
248 return xId;
251 return Reference< XContentIdentifier >();
254 //------------------------------------------------------------------------------------------------------------------
255 Reference< XContent > DataSupplier::queryContent( sal_uInt32 i_nIndex )
257 ::osl::Guard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex );
258 ENSURE_OR_RETURN( i_nIndex < m_pImpl->m_aResults.size(), "illegal index!", NULL );
261 ::rtl::Reference< Content > pContent( m_pImpl->m_aResults[ i_nIndex ].pContent );
262 if ( pContent.is() )
263 return pContent.get();
265 Reference< XContentIdentifier > xId( queryContentIdentifier( i_nIndex ) );
266 if ( xId.is() )
270 Reference< XContent > xContent( m_pImpl->m_xContent->getProvider()->queryContent( xId ) );
271 pContent.set( dynamic_cast< Content* >( xContent.get() ) );
272 OSL_ENSURE( pContent.is() || !xContent.is(), "DataSupplier::queryContent: invalid content implementation!" );
273 m_pImpl->m_aResults[ i_nIndex ].pContent = pContent;
274 return pContent.get();
277 catch ( const IllegalIdentifierException& )
279 DBG_UNHANDLED_EXCEPTION();
283 return Reference< XContent >();
286 //------------------------------------------------------------------------------------------------------------------
287 sal_Bool DataSupplier::getResult( sal_uInt32 i_nIndex )
289 ::osl::ClearableGuard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex );
291 if ( m_pImpl->m_aResults.size() > i_nIndex )
292 // result already present.
293 return sal_True;
295 return sal_False;
298 //------------------------------------------------------------------------------------------------------------------
299 sal_uInt32 DataSupplier::totalCount()
301 ::osl::ClearableGuard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex );
302 return m_pImpl->m_aResults.size();
305 //------------------------------------------------------------------------------------------------------------------
306 sal_uInt32 DataSupplier::currentCount()
308 return m_pImpl->m_aResults.size();
311 //------------------------------------------------------------------------------------------------------------------
312 sal_Bool DataSupplier::isCountFinal()
314 return sal_True;
317 //------------------------------------------------------------------------------------------------------------------
318 Reference< XRow > DataSupplier::queryPropertyValues( sal_uInt32 i_nIndex )
320 ::osl::MutexGuard aGuard( m_pImpl->m_aMutex );
321 ENSURE_OR_RETURN( i_nIndex < m_pImpl->m_aResults.size(), "DataSupplier::queryPropertyValues: illegal index!", NULL );
323 Reference< XRow > xRow = m_pImpl->m_aResults[ i_nIndex ].xRow;
324 if ( xRow.is() )
325 return xRow;
327 ENSURE_OR_RETURN( queryContent( i_nIndex ).is(), "could not retrieve the content", NULL );
329 switch ( m_pImpl->m_xContent->getExtensionContentType() )
331 case E_ROOT:
333 const ::rtl::OUString& rId( m_pImpl->m_aResults[ i_nIndex ].sId );
334 const ::rtl::OUString sRootURL( ContentProvider::getRootURL() );
335 ::rtl::OUString sTitle = Content::decodeIdentifier( rId.copy( sRootURL.getLength() ) );
336 if ( !sTitle.isEmpty() && ( sTitle[ sTitle.getLength() - 1 ] == '/' ) )
337 sTitle = sTitle.copy( 0, sTitle.getLength() - 1 );
338 xRow = Content::getArtificialNodePropertyValues( m_pImpl->m_xSMgr, getResultSet()->getProperties(), sTitle );
340 break;
342 case E_EXTENSION_ROOT:
343 case E_EXTENSION_CONTENT:
345 xRow = m_pImpl->m_aResults[ i_nIndex ].pContent->getPropertyValues(
346 getResultSet()->getProperties(), getResultSet()->getEnvironment() );
348 break;
349 default:
350 OSL_FAIL( "DataSupplier::queryPropertyValues: unhandled case!" );
351 break;
354 m_pImpl->m_aResults[ i_nIndex ].xRow = xRow;
355 return xRow;
358 //------------------------------------------------------------------------------------------------------------------
359 void DataSupplier::releasePropertyValues( sal_uInt32 i_nIndex )
361 ::osl::Guard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex );
363 if ( i_nIndex < m_pImpl->m_aResults.size() )
364 m_pImpl->m_aResults[ i_nIndex ].xRow.clear();
367 //------------------------------------------------------------------------------------------------------------------
368 void DataSupplier::close()
372 //------------------------------------------------------------------------------------------------------------------
373 void DataSupplier::validate() throw( ResultSetException )
377 //......................................................................................................................
378 } } } // namespace ucp::ext
379 //......................................................................................................................
381 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */