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