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