xref: /AOO41X/main/framework/source/services/urltransformer.cxx (revision 6d739b60ff8f4ed2134ae1442e284f9da90334b4)
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             // 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 //*****************************************************************************************************************
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         // 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 //*****************************************************************************************************************
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