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>
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 //==================================================================================================================
79 //==================================================================================================================
80 struct ResultListEntry
83 Reference
< XContentIdentifier
> xId
;
84 ::rtl::Reference
< Content
> pContent
;
85 Reference
< XRow
> xRow
;
88 typedef ::std::vector
< ResultListEntry
> ResultList
;
90 //==================================================================================================================
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
)
105 ,m_nOpenMode( i_nOpenMode
)
108 ~DataSupplier_Impl();
111 //------------------------------------------------------------------------------------------------------------------
112 DataSupplier_Impl::~DataSupplier_Impl()
116 //==================================================================================================================
118 //==================================================================================================================
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 //==================================================================================================================
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() )
160 Sequence
< Sequence
< ::rtl::OUString
> > aExtensionInfo( xPackageInfo
->getExtensionList() );
161 for ( const Sequence
< ::rtl::OUString
>* pExtInfo
= aExtensionInfo
.getConstArray();
162 pExtInfo
!= aExtensionInfo
.getConstArray() + aExtensionInfo
.getLength();
166 if ( pExtInfo
->getLength() <= 0 )
168 SAL_WARN( "ucb.ucp", "illegal extension info" );
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
);
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
);
200 OSL_FAIL( "DataSupplier::fetchData: unimplemented content type!" );
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() )
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
);
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
;
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
);
263 return pContent
.get();
265 Reference
< XContentIdentifier
> xId( queryContentIdentifier( i_nIndex
) );
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.
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()
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
;
327 ENSURE_OR_RETURN( queryContent( i_nIndex
).is(), "could not retrieve the content", NULL
);
329 switch ( m_pImpl
->m_xContent
->getExtensionContentType() )
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
);
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() );
350 OSL_FAIL( "DataSupplier::queryPropertyValues: unhandled case!" );
354 m_pImpl
->m_aResults
[ i_nIndex
].xRow
= 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: */