1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: directory.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_ucb.hxx"
34 * This file pinched from webdavdatasupplier (etc.)
35 * cut & paste + new getData impl. & collate ResultSet code.
38 #include <osl/diagnose.h>
39 #include <com/sun/star/ucb/OpenMode.hpp>
40 #include <ucbhelper/contentidentifier.hxx>
41 #include <ucbhelper/providerhelper.hxx>
43 #include "directory.hxx"
45 #include <libgnomevfs/gnome-vfs-utils.h>
46 #include <libgnomevfs/gnome-vfs-directory.h>
48 using namespace com::sun::star
;
51 // DynamicResultSet Implementation.
53 DynamicResultSet::DynamicResultSet(
54 const uno::Reference
< lang::XMultiServiceFactory
>& rxSMgr
,
55 const rtl::Reference
< Content
>& rxContent
,
56 const ucb::OpenCommandArgument2
& rCommand
,
57 const uno::Reference
< ucb::XCommandEnvironment
>& rxEnv
)
58 : ResultSetImplHelper( rxSMgr
, rCommand
),
59 m_xContent( rxContent
),
63 void DynamicResultSet::initStatic()
66 = new ::ucbhelper::ResultSet( m_xSMgr
,
67 m_aCommand
.Properties
,
68 new DataSupplier( m_xSMgr
,
73 void DynamicResultSet::initDynamic()
76 m_xResultSet2
= m_xResultSet1
;
79 //=========================================================================
82 // DataSupplier Implementation.
86 struct ResultListEntry
89 uno::Reference
< ucb::XContentIdentifier
> xId
;
90 uno::Reference
< ucb::XContent
> xContent
;
91 uno::Reference
< sdbc::XRow
> xRow
;
92 GnomeVFSFileInfo aInfo
;
94 ResultListEntry( const GnomeVFSFileInfo
*fileInfo
)
96 gnome_vfs_file_info_copy (&aInfo
, fileInfo
);
101 gnome_vfs_file_info_clear (&aInfo
);
105 //=========================================================================
109 //=========================================================================
111 typedef std::vector
< ResultListEntry
* > ResultList
;
113 //=========================================================================
115 // struct DataSupplier_Impl.
117 //=========================================================================
119 struct gvfs::DataSupplier_Impl
122 ResultList m_aResults
;
123 rtl::Reference
< Content
> m_xContent
;
124 uno::Reference
< lang::XMultiServiceFactory
> m_xSMgr
;
125 sal_Int32 m_nOpenMode
;
126 sal_Bool m_bCountFinal
;
129 const uno::Reference
< lang::XMultiServiceFactory
>& rxSMgr
,
130 const rtl::Reference
< Content
>& rContent
,
131 sal_Int32 nOpenMode
)
132 : m_xContent( rContent
), m_xSMgr( rxSMgr
),
133 m_nOpenMode( nOpenMode
), m_bCountFinal( sal_False
) {}
136 ResultList::const_iterator it
= m_aResults
.begin();
137 ResultList::const_iterator end
= m_aResults
.end();
147 DataSupplier::DataSupplier(
148 const uno::Reference
< lang::XMultiServiceFactory
>& rxSMgr
,
149 const rtl::Reference
< Content
>& rContent
,
150 sal_Int32 nOpenMode
)
151 : m_pImpl( new DataSupplier_Impl( rxSMgr
, rContent
, nOpenMode
) )
155 //=========================================================================
157 DataSupplier::~DataSupplier()
163 rtl::OUString
DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex
)
165 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
167 if ( nIndex
< m_pImpl
->m_aResults
.size() ) {
168 rtl::OUString aId
= m_pImpl
->m_aResults
[ nIndex
]->aId
;
169 if ( aId
.getLength() ) // cached
173 if ( getResult( nIndex
) ) {
174 rtl::OUString aId
= m_pImpl
->m_xContent
->getOUURI();
177 escaped_name
= gnome_vfs_escape_string( m_pImpl
->m_aResults
[ nIndex
]->aInfo
.name
);
179 if ( ( aId
.lastIndexOf( '/' ) + 1 ) != aId
.getLength() )
180 aId
+= rtl::OUString::createFromAscii( "/" );
182 aId
+= rtl::OUString::createFromAscii( escaped_name
);
184 g_free( escaped_name
);
186 m_pImpl
->m_aResults
[ nIndex
]->aId
= aId
;
190 return rtl::OUString();
194 uno::Reference
< ucb::XContentIdentifier
>
195 DataSupplier::queryContentIdentifier( sal_uInt32 nIndex
)
197 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
199 if ( nIndex
< m_pImpl
->m_aResults
.size() ) {
200 uno::Reference
< ucb::XContentIdentifier
> xId
201 = m_pImpl
->m_aResults
[ nIndex
]->xId
;
202 if ( xId
.is() ) // Already cached.
206 rtl::OUString aId
= queryContentIdentifierString( nIndex
);
207 if ( aId
.getLength() ) {
208 uno::Reference
< ucb::XContentIdentifier
> xId
209 = new ::ucbhelper::ContentIdentifier( aId
);
210 m_pImpl
->m_aResults
[ nIndex
]->xId
= xId
;
214 return uno::Reference
< ucb::XContentIdentifier
>();
218 uno::Reference
< ucb::XContent
>
219 DataSupplier::queryContent( sal_uInt32 nIndex
)
221 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
223 if ( nIndex
< m_pImpl
->m_aResults
.size() ) {
224 uno::Reference
< ucb::XContent
> xContent
225 = m_pImpl
->m_aResults
[ nIndex
]->xContent
;
226 if ( xContent
.is() ) // Already cached.
230 uno::Reference
< ucb::XContentIdentifier
> xId
231 = queryContentIdentifier( nIndex
);
236 // It would be really nice to propagate this information
237 // to the Content, but we can't then register it with the
238 // ContentProvider, and the ucbhelper hinders here.
239 uno::Reference
< ucb::XContent
> xContent
240 = m_pImpl
->m_xContent
->getProvider()->queryContent( xId
);
241 m_pImpl
->m_aResults
[ nIndex
]->xContent
= xContent
;
245 catch ( ucb::IllegalIdentifierException
& ) {
248 return uno::Reference
< ucb::XContent
>();
252 sal_Bool
DataSupplier::getResult( sal_uInt32 nIndex
)
254 osl::ClearableGuard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
256 if ( m_pImpl
->m_aResults
.size() > nIndex
) // Result already present.
259 if ( getData() && m_pImpl
->m_aResults
.size() > nIndex
)
266 sal_uInt32
DataSupplier::totalCount()
270 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
272 return m_pImpl
->m_aResults
.size();
276 sal_uInt32
DataSupplier::currentCount()
278 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
279 return m_pImpl
->m_aResults
.size();
283 sal_Bool
DataSupplier::isCountFinal()
285 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
286 return m_pImpl
->m_bCountFinal
;
290 uno::Reference
< sdbc::XRow
> DataSupplier::queryPropertyValues( sal_uInt32 nIndex
)
292 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
294 if ( nIndex
< m_pImpl
->m_aResults
.size() ) {
295 uno::Reference
< sdbc::XRow
> xRow
= m_pImpl
->m_aResults
[ nIndex
]->xRow
;
296 if ( xRow
.is() ) // Already cached.
300 if ( getResult( nIndex
) ) {
301 // Inefficient - but we can't create xContent's sensibly
302 // nor can we do the property code sensibly cleanly staticaly.
303 Content
*pContent
= static_cast< ::gvfs::Content
* >(queryContent( nIndex
).get());
305 uno::Reference
< sdbc::XRow
> xRow
=
306 pContent
->getPropertyValues( getResultSet()->getProperties(),
307 getResultSet()->getEnvironment() );
309 m_pImpl
->m_aResults
[ nIndex
]->xRow
= xRow
;
314 return uno::Reference
< sdbc::XRow
>();
318 void DataSupplier::releasePropertyValues( sal_uInt32 nIndex
)
320 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
322 if ( nIndex
< m_pImpl
->m_aResults
.size() )
323 m_pImpl
->m_aResults
[ nIndex
]->xRow
= uno::Reference
< sdbc::XRow
>();
327 void DataSupplier::close()
332 void DataSupplier::validate()
333 throw( ucb::ResultSetException
)
337 sal_Bool
DataSupplier::getData()
339 osl::ClearableGuard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
341 if ( !m_pImpl
->m_bCountFinal
) {
342 GnomeVFSResult result
;
343 GnomeVFSDirectoryHandle
*dirHandle
= NULL
;
346 Authentication
aAuth( getResultSet()->getEnvironment() );
347 char *uri
= m_pImpl
->m_xContent
->getURI();
348 result
= gnome_vfs_directory_open
349 ( &dirHandle
, uri
, GNOME_VFS_FILE_INFO_DEFAULT
);
351 if (result
!= GNOME_VFS_OK
) {
353 g_warning ("Failed open of '%s' with '%s'",
354 uri
, gnome_vfs_result_to_string( result
));
364 GnomeVFSFileInfo
*pFileInfo
= gnome_vfs_file_info_new();
365 while ((result
= gnome_vfs_directory_read_next (dirHandle
, pFileInfo
)) == GNOME_VFS_OK
) {
366 if( !pFileInfo
->name
||
367 pFileInfo
->name
[0] == '\0' ||
368 ( pFileInfo
->name
[0] == '.' &&
369 ( pFileInfo
->name
[1] == '\0' ||
370 ( pFileInfo
->name
[1] == '.' && pFileInfo
->name
[2] == '\0' ) ) ) )
373 switch ( m_pImpl
->m_nOpenMode
) {
374 case ucb::OpenMode::FOLDERS
:
375 if ( !(pFileInfo
->valid_fields
& GNOME_VFS_FILE_INFO_FIELDS_TYPE
) ||
376 pFileInfo
->type
!= GNOME_VFS_FILE_TYPE_DIRECTORY
)
380 case ucb::OpenMode::DOCUMENTS
:
381 if ( !(pFileInfo
->valid_fields
& GNOME_VFS_FILE_INFO_FIELDS_TYPE
) ||
382 pFileInfo
->type
!= GNOME_VFS_FILE_TYPE_REGULAR
)
386 case ucb::OpenMode::ALL
:
391 m_pImpl
->m_aResults
.push_back( new ResultListEntry( pFileInfo
) );
395 g_warning ("Got %d directory entries", result
);
398 m_pImpl
->m_bCountFinal
= sal_True
;
400 // Callback possible, because listeners may be informed!
402 getResultSet()->rowCountFinal();
404 if (result
!= GNOME_VFS_ERROR_EOF
) {
406 g_warning( "Failed read_next '%s'",
407 gnome_vfs_result_to_string( result
) );
412 result
= gnome_vfs_directory_close (dirHandle
);
413 if (result
!= GNOME_VFS_OK
) {
415 g_warning( "Failed close '%s'",
416 gnome_vfs_result_to_string( result
) );