LCOV - code coverage report
Current view: top level - libreoffice/ucb/source/ucp/webdav-neon - NeonPropFindRequest.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 100 0.0 %
Date: 2012-12-27 Functions: 0 8 0.0 %
Legend: Lines: hit not hit

          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: */

Generated by: LCOV version 1.10