Bump for 3.6-28
[LibreOffice.git] / ucb / source / ucp / webdav / NeonPropFindRequest.cxx
blob7bba69d63984c290c92311dad42c823a4cc2c5fc
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;
46 using ::rtl::OUString;
47 using ::rtl::OString;
48 using ::rtl::OStringToOUString;
50 // -------------------------------------------------------------------
51 namespace
53 // strip "DAV:" namespace from XML snippets to avoid
54 // parser error (undeclared namespace) later on.
55 rtl::OString stripDavNamespace( const rtl::OString & in )
57 const rtl::OString inXML( in.toAsciiLowerCase() );
59 rtl::OStringBuffer buf;
60 sal_Int32 start = 0;
61 sal_Int32 end = inXML.indexOf( "dav:" );
62 while ( end != -1 )
64 if ( inXML[ end - 1 ] == '<' ||
65 inXML[ end - 1 ] == '/' )
67 // copy from original buffer - preserve case.
68 buf.append( in.copy( start, end - start ) );
70 else
72 // copy from original buffer - preserve case.
73 buf.append( in.copy( start, end - start + 4 ) );
75 start = end + 4;
76 end = inXML.indexOf( "dav:", start );
78 buf.append( inXML.copy( start ) );
80 return rtl::OString( buf.makeStringAndClear() );
84 // -------------------------------------------------------------------
85 extern "C" int NPFR_propfind_iter( void* userdata,
86 const NeonPropName* pname,
87 const char* value,
88 const HttpStatus* status )
91 HTTP Response Status Classes:
93 - 1: Informational - Request received, continuing process
95 - 2: Success - The action was successfully received,
96 understood, and accepted
98 - 3: Redirection - Further action must be taken in order to
99 complete the request
101 - 4: Client Error - The request contains bad syntax or cannot
102 be fulfilled
104 - 5: Server Error - The server failed to fulfill an apparently
105 valid request
108 if ( status->klass > 2 )
109 return 0; // Error getting this property. Go on.
111 // Create & set the PropertyValue
112 DAVPropertyValue thePropertyValue;
113 thePropertyValue.IsCaseSensitive = true;
115 OSL_ENSURE( pname->nspace, "NPFR_propfind_iter - No namespace!" );
117 DAVProperties::createUCBPropName( pname->nspace,
118 pname->name,
119 thePropertyValue.Name );
120 bool bHasValue = false;
121 if ( DAVProperties::isUCBDeadProperty( *pname ) )
123 // DAV dead property added by WebDAV UCP?
124 if ( UCBDeadPropertyValue::createFromXML(
125 value, thePropertyValue.Value ) )
127 OSL_ENSURE( thePropertyValue.Value.hasValue(),
128 "NPFR_propfind_iter - No value!" );
129 bHasValue = true;
133 if ( !bHasValue )
135 if ( rtl_str_compareIgnoreAsciiCase(
136 pname->name, "resourcetype" ) == 0 )
138 OString aValue( value );
139 aValue = aValue.trim(); // #107358# remove leading/trailing spaces
140 if ( !aValue.isEmpty() )
142 aValue = stripDavNamespace( aValue ).toAsciiLowerCase();
143 if ( aValue.compareTo(
144 RTL_CONSTASCII_STRINGPARAM( "<collection" ) ) == 0 )
146 thePropertyValue.Value
147 <<= OUString("collection");
151 if ( !thePropertyValue.Value.hasValue() )
153 // Take over the value exactly as supplied by the server.
154 thePropertyValue.Value <<= OUString::createFromAscii( value );
157 else if ( rtl_str_compareIgnoreAsciiCase(
158 pname->name, "supportedlock" ) == 0 )
160 Sequence< LockEntry > aEntries;
161 LockEntrySequence::createFromXML(
162 stripDavNamespace( value ), aEntries );
163 thePropertyValue.Value <<= aEntries;
165 else if ( rtl_str_compareIgnoreAsciiCase(
166 pname->name, "lockdiscovery" ) == 0 )
168 Sequence< Lock > aLocks;
169 LockSequence::createFromXML(
170 stripDavNamespace( value ), aLocks );
171 thePropertyValue.Value <<= aLocks;
173 else if ( rtl_str_compareIgnoreAsciiCase( pname->name, "source" ) == 0 )
175 Sequence< Link > aLinks;
176 LinkSequence::createFromXML(
177 stripDavNamespace( value ), aLinks );
178 thePropertyValue.Value <<= aLinks;
180 else
182 thePropertyValue.Value
183 <<= OStringToOUString( value, RTL_TEXTENCODING_UTF8 );
187 // Add the newly created PropertyValue
188 DAVResource* theResource = static_cast< DAVResource * >( userdata );
189 theResource->properties.push_back( thePropertyValue );
191 return 0; // Go on.
194 // -------------------------------------------------------------------
195 extern "C" void NPFR_propfind_results( void* userdata,
196 const ne_uri* uri,
197 const NeonPropFindResultSet* set )
199 // @@@ href is not the uri! DAVResource ctor wants uri!
201 DAVResource theResource(
202 OStringToOUString( uri->path, RTL_TEXTENCODING_UTF8 ) );
204 ne_propset_iterate( set, NPFR_propfind_iter, &theResource );
206 // Add entry to resources list.
207 vector< DAVResource > * theResources
208 = static_cast< vector< DAVResource > * >( userdata );
209 theResources->push_back( theResource );
211 // -------------------------------------------------------------------
212 extern "C" int NPFR_propnames_iter( void* userdata,
213 const NeonPropName* pname,
214 const char* /*value*/,
215 const HttpStatus* /*status*/ )
217 OUString aFullName;
218 DAVProperties::createUCBPropName( pname->nspace,
219 pname->name,
220 aFullName );
222 DAVResourceInfo* theResource = static_cast< DAVResourceInfo * >( userdata );
223 theResource->properties.push_back( aFullName );
224 return 0;
227 // -------------------------------------------------------------------
228 extern "C" void NPFR_propnames_results( void* userdata,
229 const ne_uri* uri,
230 const NeonPropFindResultSet* results )
232 // @@@ href is not the uri! DAVResourceInfo ctor wants uri!
233 // Create entry for the resource.
234 DAVResourceInfo theResource(
235 OStringToOUString( uri->path, RTL_TEXTENCODING_UTF8 ) );
237 // Fill entry.
238 ne_propset_iterate( results, NPFR_propnames_iter, &theResource );
240 // Add entry to resources list.
241 vector< DAVResourceInfo > * theResources
242 = static_cast< vector< DAVResourceInfo > * >( userdata );
243 theResources->push_back( theResource );
246 extern osl::Mutex aGlobalNeonMutex;
248 // -------------------------------------------------------------------
249 // Constructor
250 // -------------------------------------------------------------------
252 NeonPropFindRequest::NeonPropFindRequest( HttpSession* inSession,
253 const char* inPath,
254 const Depth inDepth,
255 const vector< OUString >& inPropNames,
256 vector< DAVResource >& ioResources,
257 int & nError )
259 // Generate the list of properties we're looking for
260 int thePropCount = inPropNames.size();
261 if ( thePropCount > 0 )
263 NeonPropName* thePropNames = new NeonPropName[ thePropCount + 1 ];
264 int theIndex;
266 for ( theIndex = 0; theIndex < thePropCount; theIndex ++ )
268 // Split fullname into namespace and name!
269 DAVProperties::createNeonPropName(
270 inPropNames[ theIndex ], thePropNames[ theIndex ] );
272 thePropNames[ theIndex ].nspace = NULL;
273 thePropNames[ theIndex ].name = NULL;
276 osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex );
277 nError = ne_simple_propfind( inSession,
278 inPath,
279 inDepth,
280 thePropNames,
281 NPFR_propfind_results,
282 &ioResources );
285 for ( theIndex = 0; theIndex < thePropCount; theIndex ++ )
286 free( (void *)thePropNames[ theIndex ].name );
288 delete [] thePropNames;
290 else
292 // ALLPROP
293 osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex );
294 nError = ne_simple_propfind( inSession,
295 inPath,
296 inDepth,
297 NULL, // 0 == allprop
298 NPFR_propfind_results,
299 &ioResources );
302 // #87585# - Sometimes neon lies (because some servers lie).
303 if ( ( nError == NE_OK ) && ioResources.empty() )
304 nError = NE_ERROR;
307 // -------------------------------------------------------------------
308 // Constructor
309 // - obtains property names
310 // -------------------------------------------------------------------
312 NeonPropFindRequest::NeonPropFindRequest(
313 HttpSession* inSession,
314 const char* inPath,
315 const Depth inDepth,
316 std::vector< DAVResourceInfo > & ioResInfo,
317 int & nError )
320 osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex );
321 nError = ne_propnames( inSession,
322 inPath,
323 inDepth,
324 NPFR_propnames_results,
325 &ioResInfo );
328 // #87585# - Sometimes neon lies (because some servers lie).
329 if ( ( nError == NE_OK ) && ioResInfo.empty() )
330 nError = NE_ERROR;
333 // -------------------------------------------------------------------
334 // Destructor
335 // -------------------------------------------------------------------
336 NeonPropFindRequest::~NeonPropFindRequest( )
340 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */