LCOV - code coverage report
Current view: top level - framework/source/services - urltransformer.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 55 123 44.7 %
Date: 2015-06-13 12:38:46 Functions: 8 12 66.7 %
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             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <services.h>
      21             : 
      22             : #include <cppuhelper/implbase2.hxx>
      23             : #include <cppuhelper/supportsservice.hxx>
      24             : #include <tools/urlobj.hxx>
      25             : #include <rtl/ref.hxx>
      26             : #include <rtl/ustrbuf.hxx>
      27             : 
      28             : #include <com/sun/star/util/XURLTransformer.hpp>
      29             : #include <com/sun/star/util/URL.hpp>
      30             : #include <com/sun/star/lang/XServiceInfo.hpp>
      31             : #include <com/sun/star/uno/XComponentContext.hpp>
      32             : 
      33             : namespace {
      34             : 
      35             : class URLTransformer : public ::cppu::WeakImplHelper2< css::util::XURLTransformer, css::lang::XServiceInfo>
      36             : {
      37             : public:
      38      258325 :     URLTransformer() {}
      39             : 
      40      516394 :     virtual ~URLTransformer() {}
      41             : 
      42           1 :     virtual OUString SAL_CALL getImplementationName()
      43             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
      44             :     {
      45           1 :         return OUString("com.sun.star.comp.framework.URLTransformer");
      46             :     }
      47             : 
      48           0 :     virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName)
      49             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
      50             :     {
      51           0 :         return cppu::supportsService(this, ServiceName);
      52             :     }
      53             : 
      54           1 :     virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames()
      55             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
      56             :     {
      57           1 :         css::uno::Sequence< OUString > aRet(1);
      58           1 :         aRet[0] = "com.sun.star.util.URLTransformer";
      59           1 :         return aRet;
      60             :     }
      61             : 
      62             :     virtual sal_Bool SAL_CALL parseStrict( css::util::URL& aURL )
      63             :         throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
      64             : 
      65             :     virtual sal_Bool SAL_CALL parseSmart( css::util::URL& aURL, const OUString& sSmartProtocol )
      66             :         throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
      67             : 
      68             :     virtual sal_Bool SAL_CALL assemble( css::util::URL& aURL )
      69             :         throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
      70             : 
      71             :     virtual OUString SAL_CALL getPresentation( const css::util::URL& aURL, sal_Bool bWithPassword )
      72             :         throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
      73             : };
      74             : 
      75             : namespace
      76             : {
      77      385087 :     void lcl_ParserHelper(INetURLObject& _rParser, css::util::URL& _rURL,bool _bUseIntern)
      78             :     {
      79             :         // Get all information about this URL.
      80      385087 :         _rURL.Protocol  = INetURLObject::GetScheme( _rParser.GetProtocol() );
      81      385087 :         _rURL.User      = _rParser.GetUser  ( INetURLObject::DECODE_WITH_CHARSET );
      82      385087 :         _rURL.Password  = _rParser.GetPass  ( INetURLObject::DECODE_WITH_CHARSET );
      83      385087 :         _rURL.Server        = _rParser.GetHost  ( INetURLObject::DECODE_WITH_CHARSET );
      84      385087 :         _rURL.Port      = (sal_Int16)_rParser.GetPort();
      85             : 
      86      385087 :         sal_Int32 nCount = _rParser.getSegmentCount( false );
      87      385087 :         if ( nCount > 0 )
      88             :         {
      89             :             // Don't add last segment as it is the name!
      90        7532 :             --nCount;
      91             : 
      92        7532 :             OUStringBuffer aPath;
      93       69675 :             for ( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
      94             :             {
      95       62143 :                 aPath.append( '/');
      96       62143 :                 aPath.append( _rParser.getName( nIndex, false, INetURLObject::NO_DECODE ));
      97             :             }
      98             : 
      99        7532 :             if ( nCount > 0 )
     100        7532 :                 aPath.append( '/' ); // final slash!
     101             : 
     102        7532 :             _rURL.Path = aPath.makeStringAndClear();
     103        7532 :             _rURL.Name = _rParser.getName( INetURLObject::LAST_SEGMENT, false, INetURLObject::NO_DECODE );
     104             :         }
     105             :         else
     106             :         {
     107      377555 :             _rURL.Path       = _rParser.GetURLPath( INetURLObject::NO_DECODE           );
     108      377555 :             _rURL.Name      = _rParser.GetName  (                                    );
     109             :         }
     110             : 
     111      385087 :         _rURL.Arguments  = _rParser.GetParam  ( INetURLObject::NO_DECODE           );
     112      385087 :         _rURL.Mark      = _rParser.GetMark  ( INetURLObject::DECODE_WITH_CHARSET );
     113             : 
     114             :         // INetURLObject supports only an intelligent method of parsing URL's. So write
     115             :         // back Complete to have a valid encoded URL in all cases!
     116      385087 :         _rURL.Complete  = _rParser.GetMainURL( INetURLObject::NO_DECODE           );
     117      385087 :         if ( _bUseIntern )
     118           0 :             _rURL.Complete   = _rURL.Complete.intern();
     119             : 
     120      385087 :         _rParser.SetMark    ( OUString() );
     121      385087 :         _rParser.SetParam( OUString() );
     122             : 
     123      385087 :         _rURL.Main       = _rParser.GetMainURL( INetURLObject::NO_DECODE           );
     124      385087 :     }
     125             : }
     126             : 
     127             : //  XURLTransformer
     128      460956 : sal_Bool SAL_CALL URLTransformer::parseStrict( css::util::URL& aURL ) throw( css::uno::RuntimeException, std::exception )
     129             : {
     130             :     // Safe impossible cases.
     131      460956 :     if ( aURL.Complete.isEmpty() )
     132             :     {
     133           7 :         return sal_False;
     134             :     }
     135             :     // Try to extract the protocol
     136      460949 :     sal_Int32 nURLIndex = aURL.Complete.indexOf( ':' );
     137      460949 :     OUString aProtocol;
     138      460949 :     if ( nURLIndex > 1 )
     139             :     {
     140      460949 :         aProtocol = aURL.Complete.copy( 0, nURLIndex+1 );
     141             : 
     142             :         // If INetURLObject knows this protocol let it parse
     143      460949 :         if ( INetURLObject::CompareProtocolScheme( aProtocol ) != INetProtocol::NotValid )
     144             :         {
     145             :             // Initialize parser with given URL.
     146      385087 :             INetURLObject aParser( aURL.Complete );
     147             : 
     148             :             // Get all information about this URL.
     149      385087 :             INetProtocol eINetProt = aParser.GetProtocol();
     150      385087 :             if ( eINetProt == INetProtocol::NotValid )
     151             :             {
     152           0 :                 return sal_False;
     153             :             }
     154      385087 :             else if ( !aParser.HasError() )
     155             :             {
     156      385087 :                 lcl_ParserHelper(aParser,aURL,false);
     157             :                 // Return "URL is parsed".
     158      385087 :                 return sal_True;
     159           0 :             }
     160             :         }
     161             :         else
     162             :         {
     163             :             // Minmal support for unknown protocols. This is mandatory to support the "Protocol Handlers" implemented
     164             :             // in framework!
     165       75862 :             aURL.Protocol   = aProtocol;
     166       75862 :             aURL.Main       = aURL.Complete;
     167       75862 :             aURL.Path       = aURL.Complete.copy( nURLIndex+1 );;
     168             : 
     169             :             // Return "URL is parsed".
     170       75862 :             return sal_True;
     171             :         }
     172             :     }
     173             : 
     174           0 :     return sal_False;
     175             : }
     176             : 
     177             : //  XURLTransformer
     178             : 
     179           0 : sal_Bool SAL_CALL URLTransformer::parseSmart( css::util::URL& aURL,
     180             :                                                 const   OUString&    sSmartProtocol  ) throw( css::uno::RuntimeException, std::exception )
     181             : {
     182             :     // Safe impossible cases.
     183           0 :     if ( aURL.Complete.isEmpty() )
     184             :     {
     185           0 :         return sal_False;
     186             :     }
     187             : 
     188             :     // Initialize parser with given URL.
     189           0 :     INetURLObject aParser;
     190             : 
     191           0 :     aParser.SetSmartProtocol( INetURLObject::CompareProtocolScheme( sSmartProtocol ));
     192           0 :     bool bOk = aParser.SetSmartURL( aURL.Complete );
     193           0 :     if ( bOk )
     194             :     {
     195           0 :         lcl_ParserHelper(aParser,aURL,true);
     196             :         // Return "URL is parsed".
     197           0 :         return sal_True;
     198             :     }
     199             :     else
     200             :     {
     201             :         // Minmal support for unknown protocols. This is mandatory to support the "Protocol Handlers" implemented
     202             :         // in framework!
     203           0 :         if ( INetURLObject::CompareProtocolScheme( sSmartProtocol ) == INetProtocol::NotValid )
     204             :         {
     205             :             // Try to extract the protocol
     206           0 :             sal_Int32 nIndex = aURL.Complete.indexOf( ':' );
     207           0 :             OUString aProtocol;
     208           0 :             if ( nIndex > 1 )
     209             :             {
     210           0 :                 aProtocol = aURL.Complete.copy( 0, nIndex+1 );
     211             : 
     212             :                 // If INetURLObject knows this protocol something is wrong as detected before =>
     213             :                 // give up and return false!
     214           0 :                 if ( INetURLObject::CompareProtocolScheme( aProtocol ) != INetProtocol::NotValid )
     215           0 :                     return sal_False;
     216             :                 else
     217           0 :                     aURL.Protocol = aProtocol;
     218             :             }
     219             :             else
     220           0 :                 return sal_False;
     221             : 
     222           0 :             aURL.Main = aURL.Complete;
     223           0 :             aURL.Path = aURL.Complete.copy( nIndex+1 );
     224           0 :             return sal_True;
     225             :         }
     226             :         else
     227           0 :             return sal_False;
     228           0 :     }
     229             : }
     230             : 
     231             : //  XURLTransformer
     232           0 : sal_Bool SAL_CALL URLTransformer::assemble( css::util::URL& aURL ) throw( css::uno::RuntimeException, std::exception )
     233             : {
     234             :     // Initialize parser.
     235           0 :     INetURLObject aParser;
     236             : 
     237           0 :     if ( INetURLObject::CompareProtocolScheme( aURL.Protocol ) != INetProtocol::NotValid )
     238             :     {
     239           0 :         OUStringBuffer aCompletePath( aURL.Path );
     240             : 
     241             :         // Concat the name if it is provided, just support a final slash
     242           0 :         if ( !aURL.Name.isEmpty() )
     243             :         {
     244           0 :             sal_Int32 nIndex = aURL.Path.lastIndexOf( '/' );
     245           0 :             if ( nIndex == ( aURL.Path.getLength() -1 ))
     246           0 :                 aCompletePath.append( aURL.Name );
     247             :             else
     248             :             {
     249           0 :                 aCompletePath.append( '/' );
     250           0 :                 aCompletePath.append( aURL.Name );
     251             :             }
     252             :         }
     253             : 
     254             :         bool bResult = aParser.ConcatData(
     255             :                             INetURLObject::CompareProtocolScheme( aURL.Protocol )   ,
     256             :                              aURL.User                                              ,
     257             :                             aURL.Password                                           ,
     258             :                             aURL.Server                                             ,
     259             :                              aURL.Port                                              ,
     260           0 :                             aCompletePath.makeStringAndClear()                          );
     261             : 
     262           0 :         if ( !bResult )
     263           0 :             return sal_False;
     264             : 
     265             :         // First parse URL WITHOUT ...
     266           0 :         aURL.Main = aParser.GetMainURL( INetURLObject::NO_DECODE );
     267             :         // ...and then WITH parameter and mark.
     268           0 :         aParser.SetParam( aURL.Arguments);
     269           0 :         aParser.SetMark ( aURL.Mark, INetURLObject::ENCODE_ALL );
     270           0 :         aURL.Complete = aParser.GetMainURL( INetURLObject::NO_DECODE );
     271             : 
     272             :         // Return "URL is assembled".
     273           0 :         return sal_True;
     274             :     }
     275           0 :     else if ( !aURL.Protocol.isEmpty() )
     276             :     {
     277             :         // Minimal support for unknown protocols
     278           0 :         OUStringBuffer aBuffer( aURL.Protocol );
     279           0 :         aBuffer.append( aURL.Path );
     280           0 :         aURL.Complete   = aBuffer.makeStringAndClear();
     281           0 :         aURL.Main       = aURL.Complete;
     282           0 :         return sal_True;
     283             :     }
     284             : 
     285           0 :     return sal_False;
     286             : }
     287             : 
     288             : //  XURLTransformer
     289             : 
     290           0 : OUString SAL_CALL URLTransformer::getPresentation( const css::util::URL& aURL,
     291             :                                                             sal_Bool    bWithPassword   ) throw( css::uno::RuntimeException, std::exception )
     292             : {
     293             :     // Safe impossible cases.
     294           0 :     if  (( aURL.Complete.isEmpty()                      )   ||
     295           0 :             (( bWithPassword            !=  sal_True    )   &&
     296             :              ( bWithPassword            !=  sal_False   )       ) )
     297             :     {
     298           0 :         return OUString();
     299             :     }
     300             : 
     301             :     // Check given URL
     302           0 :     css::util::URL aTestURL = aURL;
     303           0 :     bool bParseResult = parseSmart( aTestURL, aTestURL.Protocol );
     304           0 :     if ( bParseResult )
     305             :     {
     306           0 :         if ( !bWithPassword && !aTestURL.Password.isEmpty() )
     307             :         {
     308             :             // Exchange password text with other placeholder string
     309           0 :             aTestURL.Password = "<******>";
     310           0 :             assemble( aTestURL );
     311             :         }
     312             : 
     313             :         // Convert internal URLs to "praesentation"-URLs!
     314           0 :         OUString sPraesentationURL;
     315           0 :         INetURLObject::translateToExternal( aTestURL.Complete, sPraesentationURL, INetURLObject::DECODE_UNAMBIGUOUS );
     316             : 
     317           0 :         return sPraesentationURL;
     318             :     }
     319             :     else
     320           0 :         return OUString();
     321             : }
     322             : 
     323             : }
     324             : 
     325             : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
     326      258325 : com_sun_star_comp_framework_URLTransformer_get_implementation(
     327             :     css::uno::XComponentContext *,
     328             :     css::uno::Sequence<css::uno::Any> const &)
     329             : {
     330      258325 :     return cppu::acquire(new URLTransformer());
     331             : }
     332             : 
     333             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11