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
;
44 using namespace webdav_ucp
;
46 using ::rtl::OUString
;
48 using ::rtl::OStringToOUString
;
50 // -------------------------------------------------------------------
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
;
61 sal_Int32 end
= inXML
.indexOf( "dav:" );
64 if ( inXML
[ end
- 1 ] == '<' ||
65 inXML
[ end
- 1 ] == '/' )
67 // copy from original buffer - preserve case.
68 buf
.append( in
.copy( start
, end
- start
) );
72 // copy from original buffer - preserve case.
73 buf
.append( in
.copy( start
, end
- start
+ 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
,
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
101 - 4: Client Error - The request contains bad syntax or cannot
104 - 5: Server Error - The server failed to fulfill an apparently
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
,
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!" );
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
;
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
);
194 // -------------------------------------------------------------------
195 extern "C" void NPFR_propfind_results( void* userdata
,
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*/ )
218 DAVProperties::createUCBPropName( pname
->nspace
,
222 DAVResourceInfo
* theResource
= static_cast< DAVResourceInfo
* >( userdata
);
223 theResource
->properties
.push_back( aFullName
);
227 // -------------------------------------------------------------------
228 extern "C" void NPFR_propnames_results( void* userdata
,
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
) );
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 // -------------------------------------------------------------------
250 // -------------------------------------------------------------------
252 NeonPropFindRequest::NeonPropFindRequest( HttpSession
* inSession
,
255 const vector
< OUString
>& inPropNames
,
256 vector
< DAVResource
>& ioResources
,
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 ];
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
,
281 NPFR_propfind_results
,
285 for ( theIndex
= 0; theIndex
< thePropCount
; theIndex
++ )
286 free( (void *)thePropNames
[ theIndex
].name
);
288 delete [] thePropNames
;
293 osl::Guard
< osl::Mutex
> theGlobalGuard( aGlobalNeonMutex
);
294 nError
= ne_simple_propfind( inSession
,
297 NULL
, // 0 == allprop
298 NPFR_propfind_results
,
302 // #87585# - Sometimes neon lies (because some servers lie).
303 if ( ( nError
== NE_OK
) && ioResources
.empty() )
307 // -------------------------------------------------------------------
309 // - obtains property names
310 // -------------------------------------------------------------------
312 NeonPropFindRequest::NeonPropFindRequest(
313 HttpSession
* inSession
,
316 std::vector
< DAVResourceInfo
> & ioResInfo
,
320 osl::Guard
< osl::Mutex
> theGlobalGuard( aGlobalNeonMutex
);
321 nError
= ne_propnames( inSession
,
324 NPFR_propnames_results
,
328 // #87585# - Sometimes neon lies (because some servers lie).
329 if ( ( nError
== NE_OK
) && ioResInfo
.empty() )
333 // -------------------------------------------------------------------
335 // -------------------------------------------------------------------
336 NeonPropFindRequest::~NeonPropFindRequest( )
340 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */