1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 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. 14 * 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). 20 * 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. 25 * 26 ************************************************************************/ 27 28 #include <vector> 29 30 #include <ucbhelper/contentidentifier.hxx> 31 #include <ucbhelper/providerhelper.hxx> 32 33 #include <com/sun/star/ucb/OpenMode.hpp> 34 35 #include "gio_datasupplier.hxx" 36 #include "gio_content.hxx" 37 #include "gio_provider.hxx" 38 39 #include <stdio.h> 40 41 using namespace com::sun::star; 42 43 using namespace gio; 44 45 namespace gio 46 { 47 48 typedef std::vector< ResultListEntry* > ResultList; 49 50 DataSupplier::DataSupplier( const uno::Reference< lang::XMultiServiceFactory >& rxSMgr, 51 const uno::Reference< ::gio::Content >& rContent, sal_Int32 nOpenMode ) 52 : mxContent(rContent), m_xSMgr(rxSMgr), mnOpenMode(nOpenMode), mbCountFinal(false) 53 { 54 } 55 56 bool DataSupplier::getData() 57 { 58 if (mbCountFinal) 59 return true; 60 61 GFile *pFile = mxContent->getGFile(); 62 63 GFileEnumerator* pEnumerator = g_file_enumerate_children(pFile, "*", 64 G_FILE_QUERY_INFO_NONE, NULL, NULL); 65 66 if (!pEnumerator) 67 return sal_False; 68 69 GFileInfo *pInfo = NULL; 70 while ((pInfo = g_file_enumerator_next_file (pEnumerator, NULL, NULL))) 71 { 72 switch ( mnOpenMode ) 73 { 74 case ucb::OpenMode::FOLDERS: 75 if (g_file_info_get_file_type(pInfo) != G_FILE_TYPE_DIRECTORY) 76 continue; 77 break; 78 case ucb::OpenMode::DOCUMENTS: 79 if (g_file_info_get_file_type(pInfo) != G_FILE_TYPE_REGULAR) 80 continue; 81 break; 82 case ucb::OpenMode::ALL: 83 default: 84 break; 85 } 86 87 maResults.push_back( new ResultListEntry( pInfo ) ); 88 g_object_unref(pInfo); 89 } 90 91 mbCountFinal = sal_True; 92 93 g_file_enumerator_close(pEnumerator, NULL, NULL); 94 return true; 95 } 96 97 DataSupplier::~DataSupplier() 98 { 99 ResultList::const_iterator it = maResults.begin(); 100 ResultList::const_iterator end = maResults.end(); 101 102 while ( it != end ) 103 { 104 delete (*it); 105 it++; 106 } 107 } 108 109 ::rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex ) 110 { 111 if ( nIndex < maResults.size() ) 112 { 113 ::rtl::OUString aId = maResults[ nIndex ]->aId; 114 if ( aId.getLength() ) 115 { 116 // Already cached. 117 return aId; 118 } 119 } 120 121 if ( getResult( nIndex ) ) 122 { 123 GFile *pFile = mxContent->getGFile(); 124 char* parent = g_file_get_uri(pFile); 125 rtl::OUString aId = rtl::OUString::createFromAscii( parent ); 126 g_free(parent); 127 128 char *escaped_name = 129 g_uri_escape_string( g_file_info_get_name(maResults[ nIndex ]->pInfo) , NULL, false); 130 131 if ( ( aId.lastIndexOf( '/' ) + 1 ) != aId.getLength() ) 132 aId += rtl::OUString::createFromAscii( "/" ); 133 134 aId += rtl::OUString::createFromAscii( escaped_name ); 135 136 g_free( escaped_name ); 137 138 maResults[ nIndex ]->aId = aId; 139 return aId; 140 141 return aId; 142 } 143 144 return ::rtl::OUString(); 145 } 146 147 uno::Reference< ucb::XContentIdentifier > DataSupplier::queryContentIdentifier( sal_uInt32 nIndex ) 148 { 149 if ( nIndex < maResults.size() ) 150 { 151 uno::Reference< ucb::XContentIdentifier > xId = maResults[ nIndex ]->xId; 152 if ( xId.is() ) 153 { 154 // Already cached. 155 return xId; 156 } 157 } 158 159 ::rtl::OUString aId = queryContentIdentifierString( nIndex ); 160 if ( aId.getLength() ) 161 { 162 uno::Reference< ucb::XContentIdentifier > xId = new ucbhelper::ContentIdentifier( aId ); 163 maResults[ nIndex ]->xId = xId; 164 return xId; 165 } 166 167 return uno::Reference< ucb::XContentIdentifier >(); 168 } 169 170 uno::Reference< ucb::XContent > DataSupplier::queryContent( sal_uInt32 nIndex ) 171 { 172 if ( nIndex < maResults.size() ) 173 { 174 uno::Reference< ucb::XContent > xContent = maResults[ nIndex ]->xContent; 175 if ( xContent.is() ) 176 { 177 // Already cached. 178 return xContent; 179 } 180 } 181 182 uno::Reference< ucb::XContentIdentifier > xId = queryContentIdentifier( nIndex ); 183 if ( xId.is() ) 184 { 185 try 186 { 187 uno::Reference< ucb::XContent > xContent = mxContent->getProvider()->queryContent( xId ); 188 maResults[ nIndex ]->xContent = xContent; 189 return xContent; 190 } 191 catch ( ucb::IllegalIdentifierException& ) 192 { 193 } 194 } 195 return uno::Reference< ucb::XContent >(); 196 } 197 198 sal_Bool DataSupplier::getResult( sal_uInt32 nIndex ) 199 { 200 if ( maResults.size() > nIndex ) // Result already present. 201 return sal_True; 202 203 if ( getData() && maResults.size() > nIndex ) 204 return sal_True; 205 206 return sal_False; 207 } 208 209 sal_uInt32 DataSupplier::totalCount() 210 { 211 getData(); 212 return maResults.size(); 213 } 214 215 sal_uInt32 DataSupplier::currentCount() 216 { 217 return maResults.size(); 218 } 219 220 sal_Bool DataSupplier::isCountFinal() 221 { 222 return mbCountFinal; 223 } 224 225 uno::Reference< sdbc::XRow > DataSupplier::queryPropertyValues( sal_uInt32 nIndex ) 226 { 227 if ( nIndex < maResults.size() ) 228 { 229 uno::Reference< sdbc::XRow > xRow = maResults[ nIndex ]->xRow; 230 if ( xRow.is() ) 231 { 232 // Already cached. 233 return xRow; 234 } 235 } 236 237 if ( getResult( nIndex ) ) 238 { 239 uno::Reference< ucb::XContent > xContent( queryContent( nIndex ) ); 240 if ( xContent.is() ) 241 { 242 try 243 { 244 uno::Reference< ucb::XCommandProcessor > xCmdProc( 245 xContent, uno::UNO_QUERY_THROW ); 246 sal_Int32 nCmdId( xCmdProc->createCommandIdentifier() ); 247 ucb::Command aCmd; 248 aCmd.Name = rtl::OUString::createFromAscii( "getPropertyValues" ); 249 aCmd.Handle = -1; 250 aCmd.Argument <<= getResultSet()->getProperties(); 251 uno::Any aResult( xCmdProc->execute( 252 aCmd, nCmdId, getResultSet()->getEnvironment() ) ); 253 uno::Reference< sdbc::XRow > xRow; 254 if ( aResult >>= xRow ) 255 { 256 maResults[ nIndex ]->xRow = xRow; 257 return xRow; 258 } 259 } 260 catch ( uno::Exception const & ) 261 { 262 } 263 } 264 } 265 return uno::Reference< sdbc::XRow >(); 266 } 267 268 void DataSupplier::releasePropertyValues( sal_uInt32 nIndex ) 269 { 270 if ( nIndex < maResults.size() ) 271 maResults[ nIndex ]->xRow = uno::Reference< sdbc::XRow >(); 272 } 273 274 void DataSupplier::close() 275 { 276 } 277 278 void DataSupplier::validate() throw( ucb::ResultSetException ) 279 { 280 } 281 282 } 283