1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: urltransformer.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_framework.hxx"
34 //_________________________________________________________________________________________________________________
36 //_________________________________________________________________________________________________________________
37 #include <services/urltransformer.hxx>
38 #include <threadhelp/resetableguard.hxx>
39 #include <macros/debug.hxx>
42 //_________________________________________________________________________________________________________________
44 //_________________________________________________________________________________________________________________
46 //_________________________________________________________________________________________________________________
47 // includes of other projects
48 //_________________________________________________________________________________________________________________
49 #include <tools/urlobj.hxx>
50 #include <rtl/ustrbuf.hxx>
51 #include <vcl/svapp.hxx>
53 //_________________________________________________________________________________________________________________
55 //_________________________________________________________________________________________________________________
59 using namespace ::osl
;
60 using namespace ::cppu
;
61 using namespace ::com::sun::star::uno
;
62 using namespace ::com::sun::star::lang
;
63 using namespace ::com::sun::star::util
;
65 //_________________________________________________________________________________________________________________
67 //_________________________________________________________________________________________________________________
69 //_________________________________________________________________________________________________________________
70 // non exported definitions
71 //_________________________________________________________________________________________________________________
73 //_________________________________________________________________________________________________________________
75 //_________________________________________________________________________________________________________________
77 //*****************************************************************************************************************
79 //*****************************************************************************************************************
80 URLTransformer::URLTransformer( const Reference
< XMultiServiceFactory
>& xFactory
)
81 // Init baseclasses first
83 // Don't change order of initialization!
84 // ThreadHelpBase is a struct with a mutex as member. We can't use a mutex as member, while
85 // we must garant right initialization and a valid value of this! First initialize
86 // baseclasses and then members. And we need the mutex for other baseclasses !!!
87 : ThreadHelpBase ( &Application::GetSolarMutex() )
90 , m_xFactory ( xFactory
)
92 // Safe impossible cases.
93 // Method not defined for all incoming parameter.
94 LOG_ASSERT( xFactory
.is(), "URLTransformer::URLTransformer()\nInvalid parameter detected!\n" )
97 //*****************************************************************************************************************
99 //*****************************************************************************************************************
100 URLTransformer::~URLTransformer()
104 //*****************************************************************************************************************
105 // XInterface, XTypeProvider, XServiceInfo
106 //*****************************************************************************************************************
108 DEFINE_XINTERFACE_3 ( URLTransformer
,
110 DIRECT_INTERFACE(XTypeProvider
),
111 DIRECT_INTERFACE(XServiceInfo
),
112 DIRECT_INTERFACE(XURLTransformer
)
115 DEFINE_XTYPEPROVIDER_3 ( URLTransformer
,
121 DEFINE_XSERVICEINFO_MULTISERVICE ( URLTransformer
,
123 SERVICENAME_URLTRANSFORMER
,
124 IMPLEMENTATIONNAME_URLTRANSFORMER
127 DEFINE_INIT_SERVICE ( URLTransformer
,
132 //*****************************************************************************************************************
134 //*****************************************************************************************************************
135 sal_Bool SAL_CALL
URLTransformer::parseStrict( URL
& aURL
) throw( RuntimeException
)
137 // Ready for multithreading
138 ResetableGuard
aGuard( m_aLock
);
140 // Safe impossible cases.
141 if (( &aURL
== NULL
) ||
142 ( aURL
.Complete
.getLength() < 1 ) )
147 // Try to extract the protocol
148 sal_Int32 nURLIndex
= aURL
.Complete
.indexOf( sal_Unicode( ':' ));
149 ::rtl::OUString aProtocol
;
152 aProtocol
= aURL
.Complete
.copy( 0, nURLIndex
+1 );
154 // If INetURLObject knows this protocol let it parse
155 if ( INetURLObject::CompareProtocolScheme( aProtocol
) != INET_PROT_NOT_VALID
)
157 // Initialize parser with given URL.
158 INetURLObject
aParser( aURL
.Complete
);
160 // Get all information about this URL.
161 INetProtocol eINetProt
= aParser
.GetProtocol();
162 if ( eINetProt
== INET_PROT_NOT_VALID
)
166 else if ( !aParser
.HasError() )
168 aURL
.Protocol
= INetURLObject::GetScheme( aParser
.GetProtocol() );
169 aURL
.User
= aParser
.GetUser ( INetURLObject::DECODE_WITH_CHARSET
);
170 aURL
.Password
= aParser
.GetPass ( INetURLObject::DECODE_WITH_CHARSET
);
171 aURL
.Server
= aParser
.GetHost ( INetURLObject::DECODE_WITH_CHARSET
);
172 aURL
.Port
= (sal_Int16
)aParser
.GetPort();
174 sal_Int32 nCount
= aParser
.getSegmentCount( false );
177 // Don't add last segment as it is the name!
180 rtl::OUStringBuffer aPath
;
181 for ( sal_Int32 nIndex
= 0; nIndex
< nCount
; nIndex
++ )
183 aPath
.append( sal_Unicode( '/' ));
184 aPath
.append( aParser
.getName( nIndex
, false, INetURLObject::NO_DECODE
));
188 aPath
.append( sal_Unicode( '/' )); // final slash!
190 aURL
.Path
= aPath
.makeStringAndClear();
191 aURL
.Name
= aParser
.getName( INetURLObject::LAST_SEGMENT
, false, INetURLObject::NO_DECODE
);
195 aURL
.Path
= aParser
.GetURLPath( INetURLObject::NO_DECODE
);
196 aURL
.Name
= aParser
.GetName ( );
199 aURL
.Arguments
= aParser
.GetParam ( INetURLObject::NO_DECODE
);
200 aURL
.Mark
= aParser
.GetMark ( INetURLObject::DECODE_WITH_CHARSET
);
202 // INetURLObject supports only an intelligent method of parsing URL's. So write
203 // back Complete to have a valid encoded URL in all cases!
204 aURL
.Complete
= aParser
.GetMainURL( INetURLObject::NO_DECODE
);
205 aURL
.Complete
= aURL
.Complete
.intern();
207 aParser
.SetMark ( ::rtl::OUString() );
208 aParser
.SetParam( ::rtl::OUString() );
210 aURL
.Main
= aParser
.GetMainURL( INetURLObject::NO_DECODE
);
212 // Return "URL is parsed".
218 // Minmal support for unknown protocols. This is mandatory to support the "Protocol Handlers" implemented
220 aURL
.Protocol
= aProtocol
;
221 aURL
.Main
= aURL
.Complete
;
222 aURL
.Path
= aURL
.Complete
.copy( nURLIndex
+1 );;
224 // Return "URL is parsed".
232 //*****************************************************************************************************************
234 //*****************************************************************************************************************
235 sal_Bool SAL_CALL
URLTransformer::parseSmart( URL
& aURL
,
236 const ::rtl::OUString
& sSmartProtocol
) throw( RuntimeException
)
238 // Ready for multithreading
239 ResetableGuard
aGuard( m_aLock
);
240 // Safe impossible cases.
241 if (( &aURL
== NULL
) ||
242 ( aURL
.Complete
.getLength() < 1 ) )
247 // Initialize parser with given URL.
248 INetURLObject aParser
;
250 aParser
.SetSmartProtocol( INetURLObject::CompareProtocolScheme( sSmartProtocol
));
251 bool bOk
= aParser
.SetSmartURL( aURL
.Complete
);
254 // Get all information about this URL.
255 aURL
.Protocol
= INetURLObject::GetScheme( aParser
.GetProtocol() );
256 aURL
.User
= aParser
.GetUser ( INetURLObject::DECODE_WITH_CHARSET
);
257 aURL
.Password
= aParser
.GetPass ( INetURLObject::DECODE_WITH_CHARSET
);
258 aURL
.Server
= aParser
.GetHost ( INetURLObject::DECODE_WITH_CHARSET
);
259 aURL
.Port
= (sal_Int16
)aParser
.GetPort();
261 sal_Int32 nCount
= aParser
.getSegmentCount( false );
264 // Don't add last segment as it is the name!
267 rtl::OUStringBuffer aPath
;
268 for ( sal_Int32 nIndex
= 0; nIndex
< nCount
; nIndex
++ )
270 aPath
.append( sal_Unicode( '/' ));
271 aPath
.append( aParser
.getName( nIndex
, false, INetURLObject::NO_DECODE
));
275 aPath
.append( sal_Unicode( '/' )); // final slash!
277 aURL
.Path
= aPath
.makeStringAndClear();
278 aURL
.Name
= aParser
.getName( INetURLObject::LAST_SEGMENT
, false, INetURLObject::NO_DECODE
);
282 aURL
.Path
= aParser
.GetURLPath( INetURLObject::NO_DECODE
);
283 aURL
.Name
= aParser
.GetName ( );
286 aURL
.Arguments
= aParser
.GetParam ( INetURLObject::NO_DECODE
);
287 aURL
.Mark
= aParser
.GetMark ( INetURLObject::DECODE_WITH_CHARSET
);
289 aURL
.Complete
= aParser
.GetMainURL( INetURLObject::NO_DECODE
);
291 aParser
.SetMark ( ::rtl::OUString() );
292 aParser
.SetParam( ::rtl::OUString() );
294 aURL
.Main
= aParser
.GetMainURL( INetURLObject::NO_DECODE
);
296 // Return "URL is parsed".
301 // Minmal support for unknown protocols. This is mandatory to support the "Protocol Handlers" implemented
303 if ( INetURLObject::CompareProtocolScheme( sSmartProtocol
) == INET_PROT_NOT_VALID
)
305 // Try to extract the protocol
306 sal_Int32 nIndex
= aURL
.Complete
.indexOf( sal_Unicode( ':' ));
307 ::rtl::OUString aProtocol
;
310 aProtocol
= aURL
.Complete
.copy( 0, nIndex
+1 );
312 // If INetURLObject knows this protocol something is wrong as detected before =>
313 // give up and return false!
314 if ( INetURLObject::CompareProtocolScheme( aProtocol
) != INET_PROT_NOT_VALID
)
317 aURL
.Protocol
= aProtocol
;
322 aURL
.Main
= aURL
.Complete
;
323 aURL
.Path
= aURL
.Complete
.copy( nIndex
+1 );
331 //*****************************************************************************************************************
333 //*****************************************************************************************************************
334 sal_Bool SAL_CALL
URLTransformer::assemble( URL
& aURL
) throw( RuntimeException
)
336 // Ready for multithreading
337 ResetableGuard
aGuard( m_aLock
);
339 // Safe impossible cases.
343 // Initialize parser.
344 INetURLObject aParser
;
346 if ( INetURLObject::CompareProtocolScheme( aURL
.Protocol
) != INET_PROT_NOT_VALID
)
348 ::rtl::OUStringBuffer
aCompletePath( aURL
.Path
);
350 // Concat the name if it is provided, just support a final slash
351 if ( aURL
.Name
.getLength() > 0 )
353 sal_Int32 nIndex
= aURL
.Path
.lastIndexOf( sal_Unicode('/') );
354 if ( nIndex
== ( aURL
.Path
.getLength() -1 ))
355 aCompletePath
.append( aURL
.Name
);
358 aCompletePath
.append( sal_Unicode( '/' ) );
359 aCompletePath
.append( aURL
.Name
);
363 bool bResult
= aParser
.ConcatData(
364 INetURLObject::CompareProtocolScheme( aURL
.Protocol
) ,
369 aCompletePath
.makeStringAndClear() );
374 // First parse URL WITHOUT ...
375 aURL
.Main
= aParser
.GetMainURL( INetURLObject::NO_DECODE
);
376 // ...and then WITH parameter and mark.
377 aParser
.SetParam( aURL
.Arguments
);
378 aParser
.SetMark ( aURL
.Mark
, INetURLObject::ENCODE_ALL
);
379 aURL
.Complete
= aParser
.GetMainURL( INetURLObject::NO_DECODE
);
381 // Return "URL is assembled".
384 else if ( aURL
.Protocol
.getLength() > 0 )
386 // Minimal support for unknown protocols
387 ::rtl::OUStringBuffer
aBuffer( aURL
.Protocol
);
388 aBuffer
.append( aURL
.Path
);
389 aURL
.Complete
= aBuffer
.makeStringAndClear();
390 aURL
.Main
= aURL
.Complete
;
397 //*****************************************************************************************************************
399 //*****************************************************************************************************************
400 ::rtl::OUString SAL_CALL
URLTransformer::getPresentation( const URL
& aURL
,
401 sal_Bool bWithPassword
) throw( RuntimeException
)
403 // Ready for multithreading
404 ResetableGuard
aGuard( m_aLock
);
406 // Safe impossible cases.
407 if (( &aURL
== NULL
) ||
408 ( aURL
.Complete
.getLength() < 1 ) ||
409 (( bWithPassword
!= sal_True
) &&
410 ( bWithPassword
!= sal_False
) ) )
412 return ::rtl::OUString();
417 sal_Bool bParseResult
= parseSmart( aTestURL
, aTestURL
.Protocol
);
420 if ( !bWithPassword
&& aTestURL
.Password
.getLength() > 0 )
422 // Exchange password text with other placeholder string
423 aTestURL
.Password
= ::rtl::OUString::createFromAscii( "<******>" );
424 assemble( aTestURL
);
427 // Convert internal URLs to "praesentation"-URLs!
428 rtl::OUString sPraesentationURL
;
429 INetURLObject::translateToExternal( aTestURL
.Complete
, sPraesentationURL
, INetURLObject::DECODE_UNAMBIGUOUS
);
431 return sPraesentationURL
;
434 return ::rtl::OUString();
437 //_________________________________________________________________________________________________________________
439 //_________________________________________________________________________________________________________________
442 } // namespace framework