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