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 //*****************************************************************************************************************
URLTransformer(const Reference<XMultiServiceFactory> &)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 //*****************************************************************************************************************
~URLTransformer()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 {
lcl_ParserHelper(INetURLObject & _rParser,URL & _rURL,bool _bUseIntern)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 //*****************************************************************************************************************
parseStrict(URL & aURL)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 // Minimal 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 //*****************************************************************************************************************
parseSmart(URL & aURL,const::rtl::OUString & sSmartProtocol)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 // Minimal 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 //*****************************************************************************************************************
assemble(URL & aURL)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 //*****************************************************************************************************************
getPresentation(const URL & aURL,sal_Bool bWithPassword)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