1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <cppuhelper/implbase.hxx>
21 #include <cppuhelper/supportsservice.hxx>
22 #include <tools/urlobj.hxx>
23 #include <rtl/ustrbuf.hxx>
25 #include <com/sun/star/util/XURLTransformer.hpp>
26 #include <com/sun/star/util/URL.hpp>
27 #include <com/sun/star/lang/XServiceInfo.hpp>
28 #include <com/sun/star/uno/XComponentContext.hpp>
32 class URLTransformer
: public ::cppu::WeakImplHelper
< css::util::XURLTransformer
, css::lang::XServiceInfo
>
37 virtual OUString SAL_CALL
getImplementationName() override
39 return "com.sun.star.comp.framework.URLTransformer";
42 virtual sal_Bool SAL_CALL
supportsService(OUString
const & ServiceName
) override
44 return cppu::supportsService(this, ServiceName
);
47 virtual css::uno::Sequence
<OUString
> SAL_CALL
getSupportedServiceNames() override
49 return {"com.sun.star.util.URLTransformer"};
52 virtual sal_Bool SAL_CALL
parseStrict( css::util::URL
& aURL
) override
;
54 virtual sal_Bool SAL_CALL
parseSmart( css::util::URL
& aURL
, const OUString
& sSmartProtocol
) override
;
56 virtual sal_Bool SAL_CALL
assemble( css::util::URL
& aURL
) override
;
58 virtual OUString SAL_CALL
getPresentation( const css::util::URL
& aURL
, sal_Bool bWithPassword
) override
;
61 void lcl_ParserHelper(INetURLObject
& _rParser
, css::util::URL
& _rURL
)
63 // Get all information about this URL.
64 _rURL
.Protocol
= INetURLObject::GetScheme( _rParser
.GetProtocol() );
65 _rURL
.User
= _rParser
.GetUser ( INetURLObject::DecodeMechanism::WithCharset
);
66 _rURL
.Password
= _rParser
.GetPass ( INetURLObject::DecodeMechanism::WithCharset
);
67 _rURL
.Server
= _rParser
.GetHost ( INetURLObject::DecodeMechanism::WithCharset
);
68 _rURL
.Port
= static_cast<sal_Int16
>(_rParser
.GetPort());
70 sal_Int32 nCount
= _rParser
.getSegmentCount( false );
73 // Don't add last segment as it is the name!
76 OUStringBuffer
aPath(128);
77 for ( sal_Int32 nIndex
= 0; nIndex
< nCount
; nIndex
++ )
80 + _rParser
.getName( nIndex
, false, INetURLObject::DecodeMechanism::NONE
));
84 aPath
.append( '/' ); // final slash!
86 _rURL
.Path
= aPath
.makeStringAndClear();
87 _rURL
.Name
= _rParser
.getName( INetURLObject::LAST_SEGMENT
, false, INetURLObject::DecodeMechanism::NONE
);
91 _rURL
.Path
= _rParser
.GetURLPath( INetURLObject::DecodeMechanism::NONE
);
92 _rURL
.Name
= _rParser
.GetLastName();
95 _rURL
.Arguments
= _rParser
.GetParam();
96 _rURL
.Mark
= _rParser
.GetMark( INetURLObject::DecodeMechanism::WithCharset
);
98 // INetURLObject supports only an intelligent method of parsing URL's. So write
99 // back Complete to have a valid encoded URL in all cases!
100 _rURL
.Complete
= _rParser
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
102 _rParser
.SetMark( u
"" );
103 _rParser
.SetParam( u
"" );
105 _rURL
.Main
= _rParser
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
109 sal_Bool SAL_CALL
URLTransformer::parseStrict( css::util::URL
& aURL
)
111 // Safe impossible cases.
112 if ( aURL
.Complete
.isEmpty() )
116 // Try to extract the protocol
117 sal_Int32 nURLIndex
= aURL
.Complete
.indexOf( ':' );
118 if ( nURLIndex
<= 1 )
121 std::u16string_view aProtocol
= aURL
.Complete
.subView( 0, nURLIndex
+1 );
123 // If INetURLObject knows this protocol let it parse
124 if ( INetURLObject::CompareProtocolScheme( aProtocol
) != INetProtocol::NotValid
)
126 // Initialize parser with given URL.
127 INetURLObject
aParser( aURL
.Complete
);
129 // Get all information about this URL.
130 INetProtocol eINetProt
= aParser
.GetProtocol();
131 if ( eINetProt
== INetProtocol::NotValid
)
135 else if ( !aParser
.HasError() )
137 lcl_ParserHelper(aParser
,aURL
);
138 // Return "URL is parsed".
144 // Minimal support for unknown protocols. This is mandatory to support the "Protocol Handlers" implemented
146 aURL
.Protocol
= aProtocol
;
147 aURL
.Main
= aURL
.Complete
;
148 aURL
.Path
= aURL
.Complete
.copy( nURLIndex
+1 );
150 // Return "URL is parsed".
159 sal_Bool SAL_CALL
URLTransformer::parseSmart( css::util::URL
& aURL
,
160 const OUString
& sSmartProtocol
)
162 // Safe impossible cases.
163 if ( aURL
.Complete
.isEmpty() )
168 // Initialize parser with given URL.
169 INetURLObject aParser
;
171 aParser
.SetSmartProtocol( INetURLObject::CompareProtocolScheme( sSmartProtocol
));
172 bool bOk
= aParser
.SetSmartURL( aURL
.Complete
);
175 lcl_ParserHelper(aParser
,aURL
);
176 // Return "URL is parsed".
181 // Minimal support for unknown protocols. This is mandatory to support the "Protocol Handlers" implemented
183 if ( INetURLObject::CompareProtocolScheme( sSmartProtocol
) == INetProtocol::NotValid
)
185 // Try to extract the protocol
186 sal_Int32 nIndex
= aURL
.Complete
.indexOf( ':' );
189 OUString aProtocol
= aURL
.Complete
.copy( 0, nIndex
+1 );
191 // If INetURLObject knows this protocol something is wrong as detected before =>
192 // give up and return false!
193 if ( INetURLObject::CompareProtocolScheme( aProtocol
) != INetProtocol::NotValid
)
196 aURL
.Protocol
= aProtocol
;
201 aURL
.Main
= aURL
.Complete
;
202 aURL
.Path
= aURL
.Complete
.copy( nIndex
+1 );
211 sal_Bool SAL_CALL
URLTransformer::assemble( css::util::URL
& aURL
)
213 // Initialize parser.
214 INetURLObject aParser
;
216 if ( INetURLObject::CompareProtocolScheme( aURL
.Protocol
) != INetProtocol::NotValid
)
218 OUStringBuffer
aCompletePath( aURL
.Path
);
220 // Concat the name if it is provided, just support a final slash
221 if ( !aURL
.Name
.isEmpty() )
223 sal_Int32 nIndex
= aURL
.Path
.lastIndexOf( '/' );
224 if ( nIndex
== ( aURL
.Path
.getLength() -1 ))
225 aCompletePath
.append( aURL
.Name
);
228 aCompletePath
.append( "/" + aURL
.Name
);
232 bool bResult
= aParser
.ConcatData(
233 INetURLObject::CompareProtocolScheme( aURL
.Protocol
) ,
243 // First parse URL WITHOUT ...
244 aURL
.Main
= aParser
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
245 // ...and then WITH parameter and mark.
246 aParser
.SetParam( aURL
.Arguments
);
247 aParser
.SetMark ( aURL
.Mark
, INetURLObject::EncodeMechanism::All
);
248 aURL
.Complete
= aParser
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
250 // Return "URL is assembled".
253 else if ( !aURL
.Protocol
.isEmpty() )
255 // Minimal support for unknown protocols
256 aURL
.Complete
= aURL
.Protocol
+ aURL
.Path
;
257 aURL
.Main
= aURL
.Complete
;
266 OUString SAL_CALL
URLTransformer::getPresentation( const css::util::URL
& aURL
,
267 sal_Bool bWithPassword
)
269 // Safe impossible cases.
270 if ( aURL
.Complete
.isEmpty() )
276 css::util::URL aTestURL
= aURL
;
277 bool bParseResult
= parseSmart( aTestURL
, aTestURL
.Protocol
);
280 if ( !bWithPassword
&& !aTestURL
.Password
.isEmpty() )
282 // Exchange password text with other placeholder string
283 aTestURL
.Password
= "<******>";
284 assemble( aTestURL
);
287 // Convert internal URLs to "praesentation"-URLs!
288 OUString sPraesentationURL
;
289 INetURLObject::translateToExternal( aTestURL
.Complete
, sPraesentationURL
, INetURLObject::DecodeMechanism::Unambiguous
);
291 return sPraesentationURL
;
299 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
300 com_sun_star_comp_framework_URLTransformer_get_implementation(
301 css::uno::XComponentContext
*,
302 css::uno::Sequence
<css::uno::Any
> const &)
304 return cppu::acquire(new URLTransformer());
307 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */