Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
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.
15 : : *
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).
21 : : *
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.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
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"
40 : :
41 : : using namespace com::sun::star::uno;
42 : : using namespace com::sun::star::ucb;
43 : : using namespace std;
44 : : using namespace webdav_ucp;
45 : :
46 : : using ::rtl::OUString;
47 : : using ::rtl::OString;
48 : : using ::rtl::OStringToOUString;
49 : :
50 : : // -------------------------------------------------------------------
51 : : namespace
52 : : {
53 : : // strip "DAV:" namespace from XML snippets to avoid
54 : : // parser error (undeclared namespace) later on.
55 : 0 : rtl::OString stripDavNamespace( const rtl::OString & in )
56 : : {
57 : 0 : const rtl::OString inXML( in.toAsciiLowerCase() );
58 : :
59 : 0 : rtl::OStringBuffer buf;
60 : 0 : sal_Int32 start = 0;
61 : 0 : sal_Int32 end = inXML.indexOf( "dav:" );
62 [ # # ]: 0 : while ( end != -1 )
63 : : {
64 [ # # # # ]: 0 : if ( inXML[ end - 1 ] == '<' ||
[ # # ]
65 : 0 : inXML[ end - 1 ] == '/' )
66 : : {
67 : : // copy from original buffer - preserve case.
68 [ # # ]: 0 : buf.append( in.copy( start, end - start ) );
69 : : }
70 : : else
71 : : {
72 : : // copy from original buffer - preserve case.
73 [ # # ]: 0 : buf.append( in.copy( start, end - start + 4 ) );
74 : : }
75 : 0 : start = end + 4;
76 : 0 : end = inXML.indexOf( "dav:", start );
77 : : }
78 [ # # ]: 0 : buf.append( inXML.copy( start ) );
79 : :
80 : 0 : return rtl::OString( buf.makeStringAndClear() );
81 : : }
82 : : }
83 : :
84 : : // -------------------------------------------------------------------
85 : 0 : extern "C" int NPFR_propfind_iter( void* userdata,
86 : : const NeonPropName* pname,
87 : : const char* value,
88 : : const HttpStatus* status )
89 : : {
90 : : /*
91 : : HTTP Response Status Classes:
92 : :
93 : : - 1: Informational - Request received, continuing process
94 : :
95 : : - 2: Success - The action was successfully received,
96 : : understood, and accepted
97 : :
98 : : - 3: Redirection - Further action must be taken in order to
99 : : complete the request
100 : :
101 : : - 4: Client Error - The request contains bad syntax or cannot
102 : : be fulfilled
103 : :
104 : : - 5: Server Error - The server failed to fulfill an apparently
105 : : valid request
106 : : */
107 : :
108 [ # # ]: 0 : if ( status->klass > 2 )
109 : 0 : return 0; // Error getting this property. Go on.
110 : :
111 : : // Create & set the PropertyValue
112 : 0 : DAVPropertyValue thePropertyValue;
113 : 0 : thePropertyValue.IsCaseSensitive = true;
114 : :
115 : : OSL_ENSURE( pname->nspace, "NPFR_propfind_iter - No namespace!" );
116 : :
117 : : DAVProperties::createUCBPropName( pname->nspace,
118 : : pname->name,
119 [ # # ]: 0 : thePropertyValue.Name );
120 : 0 : bool bHasValue = false;
121 [ # # ][ # # ]: 0 : if ( DAVProperties::isUCBDeadProperty( *pname ) )
122 : : {
123 : : // DAV dead property added by WebDAV UCP?
124 [ # # # # ]: 0 : if ( UCBDeadPropertyValue::createFromXML(
125 : 0 : value, thePropertyValue.Value ) )
126 : : {
127 : : OSL_ENSURE( thePropertyValue.Value.hasValue(),
128 : : "NPFR_propfind_iter - No value!" );
129 : 0 : bHasValue = true;
130 : : }
131 : : }
132 : :
133 [ # # ]: 0 : if ( !bHasValue )
134 : : {
135 [ # # ]: 0 : if ( rtl_str_compareIgnoreAsciiCase(
136 : 0 : pname->name, "resourcetype" ) == 0 )
137 : : {
138 : 0 : OString aValue( value );
139 : 0 : aValue = aValue.trim(); // #107358# remove leading/trailing spaces
140 [ # # ]: 0 : if ( !aValue.isEmpty() )
141 : : {
142 [ # # ]: 0 : aValue = stripDavNamespace( aValue ).toAsciiLowerCase();
143 [ # # ]: 0 : if ( aValue.compareTo(
144 : 0 : RTL_CONSTASCII_STRINGPARAM( "<collection" ) ) == 0 )
145 : : {
146 : : thePropertyValue.Value
147 [ # # ]: 0 : <<= OUString("collection");
148 : : }
149 : : }
150 : :
151 [ # # ]: 0 : if ( !thePropertyValue.Value.hasValue() )
152 : : {
153 : : // Take over the value exactly as supplied by the server.
154 [ # # ]: 0 : thePropertyValue.Value <<= OUString::createFromAscii( value );
155 : 0 : }
156 : : }
157 [ # # ]: 0 : else if ( rtl_str_compareIgnoreAsciiCase(
158 : 0 : pname->name, "supportedlock" ) == 0 )
159 : : {
160 [ # # ]: 0 : Sequence< LockEntry > aEntries;
161 : : LockEntrySequence::createFromXML(
162 [ # # ][ # # ]: 0 : stripDavNamespace( value ), aEntries );
163 [ # # ][ # # ]: 0 : thePropertyValue.Value <<= aEntries;
164 : : }
165 [ # # ]: 0 : else if ( rtl_str_compareIgnoreAsciiCase(
166 : 0 : pname->name, "lockdiscovery" ) == 0 )
167 : : {
168 [ # # ]: 0 : Sequence< Lock > aLocks;
169 : : LockSequence::createFromXML(
170 [ # # ][ # # ]: 0 : stripDavNamespace( value ), aLocks );
171 [ # # ][ # # ]: 0 : thePropertyValue.Value <<= aLocks;
172 : : }
173 [ # # ]: 0 : else if ( rtl_str_compareIgnoreAsciiCase( pname->name, "source" ) == 0 )
174 : : {
175 [ # # ]: 0 : Sequence< Link > aLinks;
176 : : LinkSequence::createFromXML(
177 [ # # ][ # # ]: 0 : stripDavNamespace( value ), aLinks );
178 [ # # ][ # # ]: 0 : thePropertyValue.Value <<= aLinks;
179 : : }
180 : : else
181 : : {
182 : : thePropertyValue.Value
183 [ # # ][ # # ]: 0 : <<= OStringToOUString( value, RTL_TEXTENCODING_UTF8 );
184 : : }
185 : : }
186 : :
187 : : // Add the newly created PropertyValue
188 : 0 : DAVResource* theResource = static_cast< DAVResource * >( userdata );
189 [ # # ]: 0 : theResource->properties.push_back( thePropertyValue );
190 : :
191 : 0 : return 0; // Go on.
192 : : }
193 : :
194 : : // -------------------------------------------------------------------
195 : 0 : extern "C" void NPFR_propfind_results( void* userdata,
196 : : const ne_uri* uri,
197 : : const NeonPropFindResultSet* set )
198 : : {
199 : : // @@@ href is not the uri! DAVResource ctor wants uri!
200 : :
201 : : DAVResource theResource(
202 [ # # ][ # # ]: 0 : OStringToOUString( uri->path, RTL_TEXTENCODING_UTF8 ) );
203 : :
204 [ # # ]: 0 : ne_propset_iterate( set, NPFR_propfind_iter, &theResource );
205 : :
206 : : // Add entry to resources list.
207 : : vector< DAVResource > * theResources
208 : 0 : = static_cast< vector< DAVResource > * >( userdata );
209 [ # # ]: 0 : theResources->push_back( theResource );
210 : 0 : }
211 : : // -------------------------------------------------------------------
212 : 0 : extern "C" int NPFR_propnames_iter( void* userdata,
213 : : const NeonPropName* pname,
214 : : const char* /*value*/,
215 : : const HttpStatus* /*status*/ )
216 : : {
217 : 0 : OUString aFullName;
218 : : DAVProperties::createUCBPropName( pname->nspace,
219 : : pname->name,
220 [ # # ]: 0 : aFullName );
221 : :
222 : 0 : DAVResourceInfo* theResource = static_cast< DAVResourceInfo * >( userdata );
223 [ # # ]: 0 : theResource->properties.push_back( aFullName );
224 : 0 : return 0;
225 : : }
226 : :
227 : : // -------------------------------------------------------------------
228 : 0 : extern "C" void NPFR_propnames_results( void* userdata,
229 : : const ne_uri* uri,
230 : : const NeonPropFindResultSet* results )
231 : : {
232 : : // @@@ href is not the uri! DAVResourceInfo ctor wants uri!
233 : : // Create entry for the resource.
234 : : DAVResourceInfo theResource(
235 [ # # ][ # # ]: 0 : OStringToOUString( uri->path, RTL_TEXTENCODING_UTF8 ) );
236 : :
237 : : // Fill entry.
238 [ # # ]: 0 : ne_propset_iterate( results, NPFR_propnames_iter, &theResource );
239 : :
240 : : // Add entry to resources list.
241 : : vector< DAVResourceInfo > * theResources
242 : 0 : = static_cast< vector< DAVResourceInfo > * >( userdata );
243 [ # # ]: 0 : theResources->push_back( theResource );
244 : 0 : }
245 : :
246 : : extern osl::Mutex aGlobalNeonMutex;
247 : :
248 : : // -------------------------------------------------------------------
249 : : // Constructor
250 : : // -------------------------------------------------------------------
251 : :
252 : 0 : NeonPropFindRequest::NeonPropFindRequest( HttpSession* inSession,
253 : : const char* inPath,
254 : : const Depth inDepth,
255 : : const vector< OUString >& inPropNames,
256 : : vector< DAVResource >& ioResources,
257 : : int & nError )
258 : : {
259 : : // Generate the list of properties we're looking for
260 : 0 : int thePropCount = inPropNames.size();
261 [ # # ]: 0 : if ( thePropCount > 0 )
262 : : {
263 : 0 : NeonPropName* thePropNames = new NeonPropName[ thePropCount + 1 ];
264 : : int theIndex;
265 : :
266 [ # # ]: 0 : for ( theIndex = 0; theIndex < thePropCount; theIndex ++ )
267 : : {
268 : : // Split fullname into namespace and name!
269 : : DAVProperties::createNeonPropName(
270 : 0 : inPropNames[ theIndex ], thePropNames[ theIndex ] );
271 : : }
272 : 0 : thePropNames[ theIndex ].nspace = NULL;
273 : 0 : thePropNames[ theIndex ].name = NULL;
274 : :
275 : : {
276 [ # # ]: 0 : osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex );
277 : : nError = ne_simple_propfind( inSession,
278 : : inPath,
279 : : inDepth,
280 : : thePropNames,
281 : : NPFR_propfind_results,
282 [ # # ][ # # ]: 0 : &ioResources );
283 : : }
284 : :
285 [ # # ]: 0 : for ( theIndex = 0; theIndex < thePropCount; theIndex ++ )
286 : 0 : free( (void *)thePropNames[ theIndex ].name );
287 : :
288 [ # # ]: 0 : delete [] thePropNames;
289 : : }
290 : : else
291 : : {
292 : : // ALLPROP
293 [ # # ]: 0 : 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 [ # # ][ # # ]: 0 : &ioResources );
300 : : }
301 : :
302 : : // #87585# - Sometimes neon lies (because some servers lie).
303 [ # # ][ # # ]: 0 : if ( ( nError == NE_OK ) && ioResources.empty() )
[ # # ]
304 : 0 : nError = NE_ERROR;
305 : 0 : }
306 : :
307 : : // -------------------------------------------------------------------
308 : : // Constructor
309 : : // - obtains property names
310 : : // -------------------------------------------------------------------
311 : :
312 : 0 : NeonPropFindRequest::NeonPropFindRequest(
313 : : HttpSession* inSession,
314 : : const char* inPath,
315 : : const Depth inDepth,
316 : : std::vector< DAVResourceInfo > & ioResInfo,
317 : : int & nError )
318 : : {
319 : : {
320 [ # # ]: 0 : osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex );
321 : : nError = ne_propnames( inSession,
322 : : inPath,
323 : : inDepth,
324 : : NPFR_propnames_results,
325 [ # # ][ # # ]: 0 : &ioResInfo );
326 : : }
327 : :
328 : : // #87585# - Sometimes neon lies (because some servers lie).
329 [ # # ][ # # ]: 0 : if ( ( nError == NE_OK ) && ioResInfo.empty() )
[ # # ]
330 : 0 : nError = NE_ERROR;
331 : 0 : }
332 : :
333 : : // -------------------------------------------------------------------
334 : : // Destructor
335 : : // -------------------------------------------------------------------
336 : 0 : NeonPropFindRequest::~NeonPropFindRequest( )
337 : : {
338 : 0 : }
339 : :
340 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|