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