1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_framework.hxx" 30 31 //_________________________________________________________________________________________________________________ 32 // my own includes 33 //_________________________________________________________________________________________________________________ 34 #include <services/urltransformer.hxx> 35 #include <threadhelp/resetableguard.hxx> 36 #include <macros/debug.hxx> 37 #include <services.h> 38 39 //_________________________________________________________________________________________________________________ 40 // interface includes 41 //_________________________________________________________________________________________________________________ 42 43 //_________________________________________________________________________________________________________________ 44 // includes of other projects 45 //_________________________________________________________________________________________________________________ 46 #include <tools/urlobj.hxx> 47 #include <rtl/ustrbuf.hxx> 48 #include <vcl/svapp.hxx> 49 50 //_________________________________________________________________________________________________________________ 51 // namespace 52 //_________________________________________________________________________________________________________________ 53 54 namespace framework{ 55 56 using namespace ::osl ; 57 using namespace ::cppu ; 58 using namespace ::com::sun::star::uno ; 59 using namespace ::com::sun::star::lang ; 60 using namespace ::com::sun::star::util ; 61 62 //_________________________________________________________________________________________________________________ 63 // non exported const 64 //_________________________________________________________________________________________________________________ 65 66 //_________________________________________________________________________________________________________________ 67 // non exported definitions 68 //_________________________________________________________________________________________________________________ 69 70 //_________________________________________________________________________________________________________________ 71 // declarations 72 //_________________________________________________________________________________________________________________ 73 74 //***************************************************************************************************************** 75 // constructor 76 //***************************************************************************************************************** 77 URLTransformer::URLTransformer( const Reference< XMultiServiceFactory >& /*xFactory*/ ) 78 { 79 // Safe impossible cases. 80 // Method not defined for all incoming parameter. 81 //LOG_ASSERT( xFactory.is(), "URLTransformer::URLTransformer()\nInvalid parameter detected!\n" ) 82 } 83 84 //***************************************************************************************************************** 85 // destructor 86 //***************************************************************************************************************** 87 URLTransformer::~URLTransformer() 88 { 89 } 90 91 //***************************************************************************************************************** 92 // XInterface, XTypeProvider, XServiceInfo 93 //***************************************************************************************************************** 94 95 DEFINE_XSERVICEINFO_MULTISERVICE ( URLTransformer , 96 OWeakObject , 97 SERVICENAME_URLTRANSFORMER , 98 IMPLEMENTATIONNAME_URLTRANSFORMER 99 ) 100 101 DEFINE_INIT_SERVICE ( URLTransformer, 102 { 103 } 104 ) 105 106 namespace 107 { 108 void lcl_ParserHelper(INetURLObject& _rParser,URL& _rURL,bool _bUseIntern) 109 { 110 // Get all information about this URL. 111 _rURL.Protocol = INetURLObject::GetScheme( _rParser.GetProtocol() ); 112 _rURL.User = _rParser.GetUser ( INetURLObject::DECODE_WITH_CHARSET ); 113 _rURL.Password = _rParser.GetPass ( INetURLObject::DECODE_WITH_CHARSET ); 114 _rURL.Server = _rParser.GetHost ( INetURLObject::DECODE_WITH_CHARSET ); 115 _rURL.Port = (sal_Int16)_rParser.GetPort(); 116 117 sal_Int32 nCount = _rParser.getSegmentCount( false ); 118 if ( nCount > 0 ) 119 { 120 // Don't add last segment as it is the name! 121 --nCount; 122 123 rtl::OUStringBuffer aPath; 124 for ( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ ) 125 { 126 aPath.append( sal_Unicode( '/' )); 127 aPath.append( _rParser.getName( nIndex, false, INetURLObject::NO_DECODE )); 128 } 129 130 if ( nCount > 0 ) 131 aPath.append( sal_Unicode( '/' )); // final slash! 132 133 _rURL.Path = aPath.makeStringAndClear(); 134 _rURL.Name = _rParser.getName( INetURLObject::LAST_SEGMENT, false, INetURLObject::NO_DECODE ); 135 } 136 else 137 { 138 _rURL.Path = _rParser.GetURLPath( INetURLObject::NO_DECODE ); 139 _rURL.Name = _rParser.GetName ( ); 140 } 141 142 _rURL.Arguments = _rParser.GetParam ( INetURLObject::NO_DECODE ); 143 _rURL.Mark = _rParser.GetMark ( INetURLObject::DECODE_WITH_CHARSET ); 144 145 // INetURLObject supports only an intelligent method of parsing URL's. So write 146 // back Complete to have a valid encoded URL in all cases! 147 _rURL.Complete = _rParser.GetMainURL( INetURLObject::NO_DECODE ); 148 if ( _bUseIntern ) 149 _rURL.Complete = _rURL.Complete.intern(); 150 151 _rParser.SetMark ( ::rtl::OUString() ); 152 _rParser.SetParam( ::rtl::OUString() ); 153 154 _rURL.Main = _rParser.GetMainURL( INetURLObject::NO_DECODE ); 155 } 156 } 157 //***************************************************************************************************************** 158 // XURLTransformer 159 //***************************************************************************************************************** 160 sal_Bool SAL_CALL URLTransformer::parseStrict( URL& aURL ) throw( RuntimeException ) 161 { 162 // Safe impossible cases. 163 if (( &aURL == NULL ) || 164 ( aURL.Complete.getLength() < 1 ) ) 165 { 166 return sal_False; 167 } 168 // Try to extract the protocol 169 sal_Int32 nURLIndex = aURL.Complete.indexOf( sal_Unicode( ':' )); 170 ::rtl::OUString aProtocol; 171 if ( nURLIndex > 1 ) 172 { 173 aProtocol = aURL.Complete.copy( 0, nURLIndex+1 ); 174 175 // If INetURLObject knows this protocol let it parse 176 if ( INetURLObject::CompareProtocolScheme( aProtocol ) != INET_PROT_NOT_VALID ) 177 { 178 // Initialize parser with given URL. 179 INetURLObject aParser( aURL.Complete ); 180 181 // Get all information about this URL. 182 INetProtocol eINetProt = aParser.GetProtocol(); 183 if ( eINetProt == INET_PROT_NOT_VALID ) 184 { 185 return sal_False; 186 } 187 else if ( !aParser.HasError() ) 188 { 189 lcl_ParserHelper(aParser,aURL,false); 190 // Return "URL is parsed". 191 return sal_True; 192 } 193 } 194 else 195 { 196 // Minmal support for unknown protocols. This is mandatory to support the "Protocol Handlers" implemented 197 // in framework! 198 aURL.Protocol = aProtocol; 199 aURL.Main = aURL.Complete; 200 aURL.Path = aURL.Complete.copy( nURLIndex+1 );; 201 202 // Return "URL is parsed". 203 return sal_True; 204 } 205 } 206 207 return sal_False; 208 } 209 210 //***************************************************************************************************************** 211 // XURLTransformer 212 //***************************************************************************************************************** 213 sal_Bool SAL_CALL URLTransformer::parseSmart( URL& aURL , 214 const ::rtl::OUString& sSmartProtocol ) throw( RuntimeException ) 215 { 216 // Safe impossible cases. 217 if (( &aURL == NULL ) || 218 ( aURL.Complete.getLength() < 1 ) ) 219 { 220 return sal_False; 221 } 222 223 // Initialize parser with given URL. 224 INetURLObject aParser; 225 226 aParser.SetSmartProtocol( INetURLObject::CompareProtocolScheme( sSmartProtocol )); 227 bool bOk = aParser.SetSmartURL( aURL.Complete ); 228 if ( bOk ) 229 { 230 lcl_ParserHelper(aParser,aURL,true); 231 // Return "URL is parsed". 232 return sal_True; 233 } 234 else 235 { 236 // Minmal support for unknown protocols. This is mandatory to support the "Protocol Handlers" implemented 237 // in framework! 238 if ( INetURLObject::CompareProtocolScheme( sSmartProtocol ) == INET_PROT_NOT_VALID ) 239 { 240 // Try to extract the protocol 241 sal_Int32 nIndex = aURL.Complete.indexOf( sal_Unicode( ':' )); 242 ::rtl::OUString aProtocol; 243 if ( nIndex > 1 ) 244 { 245 aProtocol = aURL.Complete.copy( 0, nIndex+1 ); 246 247 // If INetURLObject knows this protocol something is wrong as detected before => 248 // give up and return false! 249 if ( INetURLObject::CompareProtocolScheme( aProtocol ) != INET_PROT_NOT_VALID ) 250 return sal_False; 251 else 252 aURL.Protocol = aProtocol; 253 } 254 else 255 return sal_False; 256 257 aURL.Main = aURL.Complete; 258 aURL.Path = aURL.Complete.copy( nIndex+1 ); 259 return sal_True; 260 } 261 else 262 return sal_False; 263 } 264 } 265 266 //***************************************************************************************************************** 267 // XURLTransformer 268 //***************************************************************************************************************** 269 sal_Bool SAL_CALL URLTransformer::assemble( URL& aURL ) throw( RuntimeException ) 270 { 271 // Safe impossible cases. 272 if ( &aURL == NULL ) 273 return sal_False ; 274 275 // Initialize parser. 276 INetURLObject aParser; 277 278 if ( INetURLObject::CompareProtocolScheme( aURL.Protocol ) != INET_PROT_NOT_VALID ) 279 { 280 ::rtl::OUStringBuffer aCompletePath( aURL.Path ); 281 282 // Concat the name if it is provided, just support a final slash 283 if ( aURL.Name.getLength() > 0 ) 284 { 285 sal_Int32 nIndex = aURL.Path.lastIndexOf( sal_Unicode('/') ); 286 if ( nIndex == ( aURL.Path.getLength() -1 )) 287 aCompletePath.append( aURL.Name ); 288 else 289 { 290 aCompletePath.append( sal_Unicode( '/' ) ); 291 aCompletePath.append( aURL.Name ); 292 } 293 } 294 295 bool bResult = aParser.ConcatData( 296 INetURLObject::CompareProtocolScheme( aURL.Protocol ) , 297 aURL.User , 298 aURL.Password , 299 aURL.Server , 300 aURL.Port , 301 aCompletePath.makeStringAndClear() ); 302 303 if ( !bResult ) 304 return sal_False; 305 306 // First parse URL WITHOUT ... 307 aURL.Main = aParser.GetMainURL( INetURLObject::NO_DECODE ); 308 // ...and then WITH parameter and mark. 309 aParser.SetParam( aURL.Arguments); 310 aParser.SetMark ( aURL.Mark, INetURLObject::ENCODE_ALL ); 311 aURL.Complete = aParser.GetMainURL( INetURLObject::NO_DECODE ); 312 313 // Return "URL is assembled". 314 return sal_True; 315 } 316 else if ( aURL.Protocol.getLength() > 0 ) 317 { 318 // Minimal support for unknown protocols 319 ::rtl::OUStringBuffer aBuffer( aURL.Protocol ); 320 aBuffer.append( aURL.Path ); 321 aURL.Complete = aBuffer.makeStringAndClear(); 322 aURL.Main = aURL.Complete; 323 return sal_True; 324 } 325 326 return sal_False; 327 } 328 329 //***************************************************************************************************************** 330 // XURLTransformer 331 //***************************************************************************************************************** 332 ::rtl::OUString SAL_CALL URLTransformer::getPresentation( const URL& aURL , 333 sal_Bool bWithPassword ) throw( RuntimeException ) 334 { 335 // Safe impossible cases. 336 if (( &aURL == NULL ) || 337 ( aURL.Complete.getLength() < 1 ) || 338 (( bWithPassword != sal_True ) && 339 ( bWithPassword != sal_False ) ) ) 340 { 341 return ::rtl::OUString(); 342 } 343 344 // Check given URL 345 URL aTestURL = aURL; 346 sal_Bool bParseResult = parseSmart( aTestURL, aTestURL.Protocol ); 347 if ( bParseResult ) 348 { 349 if ( !bWithPassword && aTestURL.Password.getLength() > 0 ) 350 { 351 // Exchange password text with other placeholder string 352 aTestURL.Password = ::rtl::OUString::createFromAscii( "<******>" ); 353 assemble( aTestURL ); 354 } 355 356 // Convert internal URLs to "praesentation"-URLs! 357 rtl::OUString sPraesentationURL; 358 INetURLObject::translateToExternal( aTestURL.Complete, sPraesentationURL, INetURLObject::DECODE_UNAMBIGUOUS ); 359 360 return sPraesentationURL; 361 } 362 else 363 return ::rtl::OUString(); 364 } 365 366 //_________________________________________________________________________________________________________________ 367 // debug methods 368 //_________________________________________________________________________________________________________________ 369 370 371 } // namespace framework 372 373