Version 4.3.0.0.beta1, tag libreoffice-4.3.0.0.beta1
[LibreOffice.git] / ucb / source / ucp / webdav-neon / NeonPropFindRequest.cxx
blobc5945f27600c36bd154e5c860804e8dc697e45ae
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "osl/diagnose.h"
31 #include "rtl/strbuf.hxx"
32 #include "NeonTypes.hxx"
33 #include "DAVException.hxx"
34 #include "DAVProperties.hxx"
35 #include "NeonPropFindRequest.hxx"
36 #include "LinkSequence.hxx"
37 #include "LockSequence.hxx"
38 #include "LockEntrySequence.hxx"
39 #include "UCBDeadPropertyValue.hxx"
41 using namespace com::sun::star::uno;
42 using namespace com::sun::star::ucb;
43 using namespace std;
44 using namespace webdav_ucp;
47 namespace
49 // strip "DAV:" namespace from XML snippets to avoid
50 // parser error (undeclared namespace) later on.
51 OString stripDavNamespace( const OString & in )
53 const OString inXML( in.toAsciiLowerCase() );
55 OStringBuffer buf;
56 sal_Int32 start = 0;
57 sal_Int32 end = inXML.indexOf( "dav:" );
58 while ( end != -1 )
60 if ( inXML[ end - 1 ] == '<' ||
61 inXML[ end - 1 ] == '/' )
63 // copy from original buffer - preserve case.
64 buf.append( in.copy( start, end - start ) );
66 else
68 // copy from original buffer - preserve case.
69 buf.append( in.copy( start, end - start + 4 ) );
71 start = end + 4;
72 end = inXML.indexOf( "dav:", start );
74 buf.append( inXML.copy( start ) );
76 return OString( buf.makeStringAndClear() );
80 extern "C" int NPFR_propfind_iter( void* userdata,
81 const NeonPropName* pname,
82 const char* value,
83 const HttpStatus* status )
86 HTTP Response Status Classes:
88 - 1: Informational - Request received, continuing process
90 - 2: Success - The action was successfully received,
91 understood, and accepted
93 - 3: Redirection - Further action must be taken in order to
94 complete the request
96 - 4: Client Error - The request contains bad syntax or cannot
97 be fulfilled
99 - 5: Server Error - The server failed to fulfill an apparently
100 valid request
103 if ( status->klass > 2 )
104 return 0; // Error getting this property. Go on.
106 // Create & set the PropertyValue
107 DAVPropertyValue thePropertyValue;
108 thePropertyValue.IsCaseSensitive = true;
110 OSL_ENSURE( pname->nspace, "NPFR_propfind_iter - No namespace!" );
112 DAVProperties::createUCBPropName( pname->nspace,
113 pname->name,
114 thePropertyValue.Name );
115 bool bHasValue = false;
116 if ( DAVProperties::isUCBDeadProperty( *pname ) )
118 // DAV dead property added by WebDAV UCP?
119 if ( UCBDeadPropertyValue::createFromXML(
120 value, thePropertyValue.Value ) )
122 OSL_ENSURE( thePropertyValue.Value.hasValue(),
123 "NPFR_propfind_iter - No value!" );
124 bHasValue = true;
128 if ( !bHasValue )
130 if ( rtl_str_compareIgnoreAsciiCase(
131 pname->name, "resourcetype" ) == 0 )
133 OString aValue( value );
134 aValue = aValue.trim(); // #107358# remove leading/trailing spaces
135 if ( !aValue.isEmpty() )
137 aValue = stripDavNamespace( aValue ).toAsciiLowerCase();
138 if ( aValue.startsWith("<collection") )
140 thePropertyValue.Value
141 <<= OUString("collection");
145 if ( !thePropertyValue.Value.hasValue() )
147 // Take over the value exactly as supplied by the server.
148 thePropertyValue.Value <<= OUString::createFromAscii( value );
151 else if ( rtl_str_compareIgnoreAsciiCase(
152 pname->name, "supportedlock" ) == 0 )
154 Sequence< LockEntry > aEntries;
155 LockEntrySequence::createFromXML(
156 stripDavNamespace( value ), aEntries );
157 thePropertyValue.Value <<= aEntries;
159 else if ( rtl_str_compareIgnoreAsciiCase(
160 pname->name, "lockdiscovery" ) == 0 )
162 Sequence< Lock > aLocks;
163 LockSequence::createFromXML(
164 stripDavNamespace( value ), aLocks );
165 thePropertyValue.Value <<= aLocks;
167 else if ( rtl_str_compareIgnoreAsciiCase( pname->name, "source" ) == 0 )
169 Sequence< Link > aLinks;
170 LinkSequence::createFromXML(
171 stripDavNamespace( value ), aLinks );
172 thePropertyValue.Value <<= aLinks;
174 else
176 thePropertyValue.Value
177 <<= OStringToOUString( value, RTL_TEXTENCODING_UTF8 );
181 // Add the newly created PropertyValue
182 DAVResource* theResource = static_cast< DAVResource * >( userdata );
183 theResource->properties.push_back( thePropertyValue );
185 return 0; // Go on.
188 extern "C" void NPFR_propfind_results( void* userdata,
189 const ne_uri* uri,
190 const NeonPropFindResultSet* set )
192 // @@@ href is not the uri! DAVResource ctor wants uri!
194 DAVResource theResource(
195 OStringToOUString( uri->path, RTL_TEXTENCODING_UTF8 ) );
197 ne_propset_iterate( set, NPFR_propfind_iter, &theResource );
199 // Add entry to resources list.
200 vector< DAVResource > * theResources
201 = static_cast< vector< DAVResource > * >( userdata );
202 theResources->push_back( theResource );
205 extern "C" int NPFR_propnames_iter( void* userdata,
206 const NeonPropName* pname,
207 const char* /*value*/,
208 const HttpStatus* /*status*/ )
210 OUString aFullName;
211 DAVProperties::createUCBPropName( pname->nspace,
212 pname->name,
213 aFullName );
215 DAVResourceInfo* theResource = static_cast< DAVResourceInfo * >( userdata );
216 theResource->properties.push_back( aFullName );
217 return 0;
220 extern "C" void NPFR_propnames_results( void* userdata,
221 const ne_uri* uri,
222 const NeonPropFindResultSet* results )
224 // @@@ href is not the uri! DAVResourceInfo ctor wants uri!
225 // Create entry for the resource.
226 DAVResourceInfo theResource(
227 OStringToOUString( uri->path, RTL_TEXTENCODING_UTF8 ) );
229 // Fill entry.
230 ne_propset_iterate( results, NPFR_propnames_iter, &theResource );
232 // Add entry to resources list.
233 vector< DAVResourceInfo > * theResources
234 = static_cast< vector< DAVResourceInfo > * >( userdata );
235 theResources->push_back( theResource );
238 extern osl::Mutex aGlobalNeonMutex;
240 NeonPropFindRequest::NeonPropFindRequest( HttpSession* inSession,
241 const char* inPath,
242 const Depth inDepth,
243 const vector< OUString >& inPropNames,
244 vector< DAVResource >& ioResources,
245 int & nError )
247 // Generate the list of properties we're looking for
248 int thePropCount = inPropNames.size();
249 if ( thePropCount > 0 )
251 NeonPropName* thePropNames = new NeonPropName[ thePropCount + 1 ];
252 int theIndex;
254 for ( theIndex = 0; theIndex < thePropCount; theIndex ++ )
256 // Split fullname into namespace and name!
257 DAVProperties::createNeonPropName(
258 inPropNames[ theIndex ], thePropNames[ theIndex ] );
260 thePropNames[ theIndex ].nspace = NULL;
261 thePropNames[ theIndex ].name = NULL;
264 osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex );
265 nError = ne_simple_propfind( inSession,
266 inPath,
267 inDepth,
268 thePropNames,
269 NPFR_propfind_results,
270 &ioResources );
273 for ( theIndex = 0; theIndex < thePropCount; theIndex ++ )
274 free( (void *)thePropNames[ theIndex ].name );
276 delete [] thePropNames;
278 else
280 // ALLPROP
281 osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex );
282 nError = ne_simple_propfind( inSession,
283 inPath,
284 inDepth,
285 NULL, // 0 == allprop
286 NPFR_propfind_results,
287 &ioResources );
290 // #87585# - Sometimes neon lies (because some servers lie).
291 if ( ( nError == NE_OK ) && ioResources.empty() )
292 nError = NE_ERROR;
295 NeonPropFindRequest::NeonPropFindRequest(
296 HttpSession* inSession,
297 const char* inPath,
298 const Depth inDepth,
299 std::vector< DAVResourceInfo > & ioResInfo,
300 int & nError )
303 osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex );
304 nError = ne_propnames( inSession,
305 inPath,
306 inDepth,
307 NPFR_propnames_results,
308 &ioResInfo );
311 // #87585# - Sometimes neon lies (because some servers lie).
312 if ( ( nError == NE_OK ) && ioResInfo.empty() )
313 nError = NE_ERROR;
316 NeonPropFindRequest::~NeonPropFindRequest( )
320 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */