Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / ucb / source / ucp / ext / ucpext_datasupplier.cxx
blob4fdfef7bbc4903f8c4383db230301e3cc6b6c759
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "ucpext_datasupplier.hxx"
22 #include "ucpext_content.hxx"
23 #include "ucpext_provider.hxx"
25 #include <com/sun/star/deployment/PackageInformationProvider.hpp>
26 #include <com/sun/star/ucb/IllegalIdentifierException.hpp>
27 #include <com/sun/star/ucb/ResultSetException.hpp>
28 #include <ucbhelper/contentidentifier.hxx>
29 #include <ucbhelper/providerhelper.hxx>
30 #include <ucbhelper/content.hxx>
31 #include <ucbhelper/propertyvalueset.hxx>
32 #include <tools/diagnose_ex.h>
33 #include <rtl/ustrbuf.hxx>
34 #include <sal/log.hxx>
36 #include <memory>
37 #include <vector>
40 namespace ucb { namespace ucp { namespace ext
44 using ::com::sun::star::uno::Reference;
45 using ::com::sun::star::uno::UNO_QUERY_THROW;
46 using ::com::sun::star::uno::UNO_SET_THROW;
47 using ::com::sun::star::uno::Exception;
48 using ::com::sun::star::uno::Sequence;
49 using ::com::sun::star::uno::XComponentContext;
50 using ::com::sun::star::ucb::XContent;
51 using ::com::sun::star::ucb::XContentIdentifier;
52 using ::com::sun::star::sdbc::XRow;
53 using ::com::sun::star::ucb::IllegalIdentifierException;
54 using ::com::sun::star::ucb::ResultSetException;
55 using ::com::sun::star::deployment::PackageInformationProvider;
56 using ::com::sun::star::deployment::XPackageInformationProvider;
57 using ::com::sun::star::sdbc::XResultSet;
60 //= ResultListEntry
62 struct ResultListEntry
64 OUString sId;
65 Reference< XContentIdentifier > xId;
66 ::rtl::Reference< Content > pContent;
67 Reference< XRow > xRow;
70 typedef ::std::vector< ResultListEntry > ResultList;
73 //= DataSupplier_Impl
75 struct DataSupplier_Impl
77 ::osl::Mutex m_aMutex;
78 ResultList m_aResults;
79 ::rtl::Reference< Content > m_xContent;
80 Reference< XComponentContext > m_xContext;
82 DataSupplier_Impl( const Reference< XComponentContext >& rxContext, const ::rtl::Reference< Content >& i_rContent )
83 :m_xContent( i_rContent )
84 ,m_xContext( rxContext )
90 //= helper
92 namespace
94 OUString lcl_compose( const OUString& i_rBaseURL, const OUString& i_rRelativeURL )
96 ENSURE_OR_RETURN( !i_rBaseURL.isEmpty(), "illegal base URL", i_rRelativeURL );
98 OUStringBuffer aComposer( i_rBaseURL );
99 if ( !i_rBaseURL.endsWith("/") )
100 aComposer.append( '/' );
101 aComposer.append( i_rRelativeURL );
102 return aComposer.makeStringAndClear();
107 //= DataSupplier
110 DataSupplier::DataSupplier( const Reference< XComponentContext >& rxContext,
111 const ::rtl::Reference< Content >& i_rContent )
112 :m_pImpl( new DataSupplier_Impl( rxContext, i_rContent ) )
117 void DataSupplier::fetchData()
121 const Reference< XPackageInformationProvider > xPackageInfo = PackageInformationProvider::get( m_pImpl->m_xContext );
123 const OUString sContentIdentifier( m_pImpl->m_xContent->getIdentifier()->getContentIdentifier() );
125 switch ( m_pImpl->m_xContent->getExtensionContentType() )
127 case E_ROOT:
129 const Sequence< Sequence< OUString > > aExtensionInfo( xPackageInfo->getExtensionList() );
130 for ( auto const & extInfo : aExtensionInfo )
132 if ( !extInfo.hasElements() )
134 SAL_WARN( "ucb.ucp.ext", "illegal extension info" );
135 continue;
138 const OUString& rLocalId = extInfo[0];
139 ResultListEntry aEntry;
140 aEntry.sId = ContentProvider::getRootURL() + Content::encodeIdentifier( rLocalId ) + "/";
141 m_pImpl->m_aResults.push_back( aEntry );
144 break;
145 case E_EXTENSION_ROOT:
146 case E_EXTENSION_CONTENT:
148 const OUString sPackageLocation( m_pImpl->m_xContent->getPhysicalURL() );
149 ::ucbhelper::Content aWrappedContent( sPackageLocation, getResultSet()->getEnvironment(), m_pImpl->m_xContext );
151 // obtain the properties which our result set is set up for from the wrapped content
152 Sequence< OUString > aPropertyNames { "Title" };
154 const Reference< XResultSet > xFolderContent( aWrappedContent.createCursor( aPropertyNames ), UNO_SET_THROW );
155 const Reference< XRow > xContentRow( xFolderContent, UNO_QUERY_THROW );
156 while ( xFolderContent->next() )
158 ResultListEntry aEntry;
159 aEntry.sId = lcl_compose( sContentIdentifier, xContentRow->getString( 1 ) );
160 m_pImpl->m_aResults.push_back( aEntry );
163 break;
164 default:
165 OSL_FAIL( "DataSupplier::fetchData: unimplemented content type!" );
166 break;
169 catch( const Exception& )
171 DBG_UNHANDLED_EXCEPTION("ucb.ucp.ext");
176 DataSupplier::~DataSupplier()
181 OUString DataSupplier::queryContentIdentifierString( sal_uInt32 i_nIndex )
183 ::osl::Guard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex );
185 if ( i_nIndex < m_pImpl->m_aResults.size() )
187 const OUString sId = m_pImpl->m_aResults[ i_nIndex ].sId;
188 if ( !sId.isEmpty() )
189 return sId;
192 OSL_FAIL( "DataSupplier::queryContentIdentifierString: illegal index, or illegal result entry id!" );
193 return OUString();
197 Reference< XContentIdentifier > DataSupplier::queryContentIdentifier( sal_uInt32 i_nIndex )
199 ::osl::Guard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex );
201 if ( i_nIndex < m_pImpl->m_aResults.size() )
203 Reference< XContentIdentifier > xId( m_pImpl->m_aResults[ i_nIndex ].xId );
204 if ( xId.is() )
205 return xId;
208 OUString sId = queryContentIdentifierString( i_nIndex );
209 if ( !sId.isEmpty() )
211 Reference< XContentIdentifier > xId = new ::ucbhelper::ContentIdentifier( sId );
212 m_pImpl->m_aResults[ i_nIndex ].xId = xId;
213 return xId;
216 return Reference< XContentIdentifier >();
220 Reference< XContent > DataSupplier::queryContent( sal_uInt32 i_nIndex )
222 ::osl::Guard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex );
223 ENSURE_OR_RETURN( i_nIndex < m_pImpl->m_aResults.size(), "illegal index!", nullptr );
226 ::rtl::Reference< Content > pContent( m_pImpl->m_aResults[ i_nIndex ].pContent );
227 if ( pContent.is() )
228 return pContent.get();
230 Reference< XContentIdentifier > xId( queryContentIdentifier( i_nIndex ) );
231 if ( xId.is() )
235 Reference< XContent > xContent( m_pImpl->m_xContent->getProvider()->queryContent( xId ) );
236 pContent.set( dynamic_cast< Content* >( xContent.get() ) );
237 OSL_ENSURE( pContent.is() || !xContent.is(), "DataSupplier::queryContent: invalid content implementation!" );
238 m_pImpl->m_aResults[ i_nIndex ].pContent = pContent;
239 return pContent.get();
242 catch ( const IllegalIdentifierException& )
244 DBG_UNHANDLED_EXCEPTION("ucb.ucp.ext");
248 return Reference< XContent >();
252 bool DataSupplier::getResult( sal_uInt32 i_nIndex )
254 ::osl::ClearableGuard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex );
256 // true if result already present.
257 return m_pImpl->m_aResults.size() > i_nIndex;
261 sal_uInt32 DataSupplier::totalCount()
263 ::osl::ClearableGuard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex );
264 return m_pImpl->m_aResults.size();
268 sal_uInt32 DataSupplier::currentCount()
270 return m_pImpl->m_aResults.size();
274 bool DataSupplier::isCountFinal()
276 return true;
280 Reference< XRow > DataSupplier::queryPropertyValues( sal_uInt32 i_nIndex )
282 ::osl::MutexGuard aGuard( m_pImpl->m_aMutex );
283 ENSURE_OR_RETURN( i_nIndex < m_pImpl->m_aResults.size(), "DataSupplier::queryPropertyValues: illegal index!", nullptr );
285 Reference< XRow > xRow = m_pImpl->m_aResults[ i_nIndex ].xRow;
286 if ( xRow.is() )
287 return xRow;
289 ENSURE_OR_RETURN( queryContent( i_nIndex ).is(), "could not retrieve the content", nullptr );
291 switch ( m_pImpl->m_xContent->getExtensionContentType() )
293 case E_ROOT:
295 const OUString& rId( m_pImpl->m_aResults[ i_nIndex ].sId );
296 const OUString sRootURL( ContentProvider::getRootURL() );
297 OUString sTitle = Content::decodeIdentifier( rId.copy( sRootURL.getLength() ) );
298 if ( sTitle.endsWith("/") )
299 sTitle = sTitle.copy( 0, sTitle.getLength() - 1 );
300 xRow = Content::getArtificialNodePropertyValues( m_pImpl->m_xContext, getResultSet()->getProperties(), sTitle );
302 break;
304 case E_EXTENSION_ROOT:
305 case E_EXTENSION_CONTENT:
307 xRow = m_pImpl->m_aResults[ i_nIndex ].pContent->getPropertyValues(
308 getResultSet()->getProperties(), getResultSet()->getEnvironment() );
310 break;
311 default:
312 OSL_FAIL( "DataSupplier::queryPropertyValues: unhandled case!" );
313 break;
316 m_pImpl->m_aResults[ i_nIndex ].xRow = xRow;
317 return xRow;
321 void DataSupplier::releasePropertyValues( sal_uInt32 i_nIndex )
323 ::osl::Guard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex );
325 if ( i_nIndex < m_pImpl->m_aResults.size() )
326 m_pImpl->m_aResults[ i_nIndex ].xRow.clear();
330 void DataSupplier::close()
335 void DataSupplier::validate()
340 } } } // namespace ucp::ext
343 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */