xref: /trunk/main/comphelper/source/officeinstdir/officeinstallationdirectories.cxx (revision 9c15e1abd703a7953928d7a80655ae1a76a41f6d)
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_comphelper.hxx"
26 
27 #include "comphelper_module.hxx"
28 
29 /**************************************************************************
30                                 TODO
31  **************************************************************************
32 
33  *************************************************************************/
34 
35 #include "osl/file.hxx"
36 #include "com/sun/star/beans/XPropertySet.hpp"
37 #include "com/sun/star/util/XMacroExpander.hpp"
38 
39 #include "officeinstallationdirectories.hxx"
40 
41 using namespace com::sun::star;
42 
43 using namespace comphelper;
44 
45 //=========================================================================
46 // helpers
47 //=========================================================================
48 
49 //=========================================================================
50 static bool makeCanonicalFileURL( rtl::OUString & rURL )
51 {
52     OSL_ENSURE( rURL.matchAsciiL( "file:", sizeof( "file:" ) - 1 , 0 ) ,
53                 "File URL expected!" );
54 
55     rtl::OUString aNormalizedURL;
56     if ( osl::FileBase::getAbsoluteFileURL( rtl::OUString(),
57                                             rURL,
58                                             aNormalizedURL )
59             == osl::DirectoryItem::E_None )
60     {
61         osl::DirectoryItem aDirItem;
62         if ( osl::DirectoryItem::get( aNormalizedURL, aDirItem )
63                 == osl::DirectoryItem::E_None )
64         {
65             osl::FileStatus aFileStatus( FileStatusMask_FileURL );
66 
67             if ( aDirItem.getFileStatus( aFileStatus )
68                     == osl::DirectoryItem::E_None )
69             {
70                 aNormalizedURL = aFileStatus.getFileURL();
71 
72                 if ( !aNormalizedURL.isEmpty() )
73                 {
74                     if ( aNormalizedURL
75                             .getStr()[ aNormalizedURL.getLength() - 1 ]
76                                 != sal_Unicode( '/' ) )
77                         rURL = aNormalizedURL;
78                     else
79                         rURL = aNormalizedURL
80                                 .copy( 0, aNormalizedURL.getLength() - 1 );
81 
82                     return true;
83                 }
84             }
85         }
86     }
87     return false;
88 }
89 
90 //=========================================================================
91 //=========================================================================
92 //
93 // OfficeInstallationDirectories Implementation.
94 //
95 //=========================================================================
96 //=========================================================================
97 
98 OfficeInstallationDirectories::OfficeInstallationDirectories(
99         const uno::Reference< uno::XComponentContext > & xCtx )
100 : m_aOfficeBrandDirMacro( RTL_CONSTASCII_USTRINGPARAM( "$(brandbaseurl)" ) ),
101   m_aOfficeBaseDirMacro( RTL_CONSTASCII_USTRINGPARAM( "$(baseinsturl)" ) ),
102   m_aUserDirMacro( RTL_CONSTASCII_USTRINGPARAM( "$(userdataurl)" ) ),
103   m_xCtx( xCtx ),
104   m_pOfficeBrandDir( 0 ),
105   m_pOfficeBaseDir( 0 ),
106   m_pUserDir( 0 )
107 {
108 }
109 
110 //=========================================================================
111 // virtual
112 OfficeInstallationDirectories::~OfficeInstallationDirectories()
113 {
114     delete m_pOfficeBrandDir;
115     delete m_pOfficeBaseDir;
116     delete m_pUserDir;
117 }
118 
119 //=========================================================================
120 // util::XOfficeInstallationDirectories
121 //=========================================================================
122 
123 // virtual
124 rtl::OUString SAL_CALL
125 OfficeInstallationDirectories::getOfficeInstallationDirectoryURL()
126 {
127     initDirs();
128     return rtl::OUString( *m_pOfficeBrandDir );
129 }
130 
131 //=========================================================================
132 // virtual
133 rtl::OUString SAL_CALL
134 OfficeInstallationDirectories::getOfficeUserDataDirectoryURL()
135 {
136     initDirs();
137     return rtl::OUString( *m_pUserDir );
138 }
139 
140 
141 //=========================================================================
142 // virtual
143 rtl::OUString SAL_CALL
144 OfficeInstallationDirectories::makeRelocatableURL( const rtl::OUString& URL )
145 {
146     if ( !URL.isEmpty() )
147     {
148         initDirs();
149 
150         rtl::OUString aCanonicalURL( URL );
151         makeCanonicalFileURL( aCanonicalURL );
152 
153         sal_Int32 nIndex = aCanonicalURL.indexOf( *m_pOfficeBrandDir );
154         if ( nIndex  != -1 )
155         {
156             return rtl::OUString(
157                 URL.replaceAt( nIndex,
158                                m_pOfficeBrandDir->getLength(),
159                                m_aOfficeBrandDirMacro ) );
160         }
161         else
162         {
163             nIndex = aCanonicalURL.indexOf( *m_pOfficeBaseDir );
164             if ( nIndex  != -1 )
165             {
166                 return rtl::OUString(
167                     URL.replaceAt( nIndex,
168                                    m_pOfficeBaseDir->getLength(),
169                                    m_aOfficeBaseDirMacro ) );
170             }
171             else
172             {
173                 nIndex = aCanonicalURL.indexOf( *m_pUserDir );
174                 if ( nIndex  != -1 )
175                 {
176                     return rtl::OUString(
177                         URL.replaceAt( nIndex,
178                                        m_pUserDir->getLength(),
179                                        m_aUserDirMacro ) );
180                 }
181             }
182         }
183     }
184     return rtl::OUString( URL );
185 }
186 
187 //=========================================================================
188 // virtual
189 rtl::OUString SAL_CALL
190 OfficeInstallationDirectories::makeAbsoluteURL( const rtl::OUString& URL )
191 {
192     if ( !URL.isEmpty() )
193     {
194         sal_Int32 nIndex = URL.indexOf( m_aOfficeBrandDirMacro );
195         if ( nIndex != -1 )
196         {
197             initDirs();
198 
199             return rtl::OUString(
200                 URL.replaceAt( nIndex,
201                                m_aOfficeBrandDirMacro.getLength(),
202                                *m_pOfficeBrandDir ) );
203         }
204         else
205         {
206             nIndex = URL.indexOf( m_aOfficeBaseDirMacro );
207             if ( nIndex != -1 )
208             {
209                 initDirs();
210 
211                 return rtl::OUString(
212                     URL.replaceAt( nIndex,
213                                    m_aOfficeBaseDirMacro.getLength(),
214                                    *m_pOfficeBaseDir ) );
215             }
216             else
217             {
218                 nIndex = URL.indexOf( m_aUserDirMacro );
219                 if ( nIndex != -1 )
220                 {
221                     initDirs();
222 
223                     return rtl::OUString(
224                         URL.replaceAt( nIndex,
225                                        m_aUserDirMacro.getLength(),
226                                        *m_pUserDir ) );
227                 }
228             }
229         }
230     }
231     return rtl::OUString( URL );
232 }
233 
234 //=========================================================================
235 // lang::XServiceInfo
236 //=========================================================================
237 
238 // virtual
239 rtl::OUString SAL_CALL
240 OfficeInstallationDirectories::getImplementationName()
241 {
242     return getImplementationName_static();
243 }
244 
245 //=========================================================================
246 // virtual
247 sal_Bool SAL_CALL
248 OfficeInstallationDirectories::supportsService( const rtl::OUString& ServiceName )
249 {
250     const uno::Sequence< rtl::OUString > & aNames
251         = getSupportedServiceNames();
252     const rtl::OUString * p = aNames.getConstArray();
253     for ( sal_Int32 nPos = 0; nPos < aNames.getLength(); nPos++ )
254     {
255         if ( p[ nPos ].equals( ServiceName ) )
256             return sal_True;
257     }
258     return sal_False;
259 
260 }
261 
262 //=========================================================================
263 // virtual
264 uno::Sequence< ::rtl::OUString > SAL_CALL
265 OfficeInstallationDirectories::getSupportedServiceNames()
266 {
267     return getSupportedServiceNames_static();
268 }
269 
270 //=========================================================================
271 // static
272 rtl::OUString SAL_CALL
273 OfficeInstallationDirectories::getImplementationName_static()
274 {
275     return rtl::OUString(
276         RTL_CONSTASCII_USTRINGPARAM(
277             "com.sun.star.comp.util.OfficeInstallationDirectories" ) );
278 }
279 
280 //=========================================================================
281 // static
282 uno::Sequence< ::rtl::OUString > SAL_CALL
283 OfficeInstallationDirectories::getSupportedServiceNames_static()
284 {
285     const rtl::OUString aServiceName(
286         RTL_CONSTASCII_USTRINGPARAM(
287             "com.sun.star.util.OfficeInstallationDirectories" ) );
288     return uno::Sequence< rtl::OUString >( &aServiceName, 1 );
289 }
290 
291 //=========================================================================
292 // static
293 rtl::OUString SAL_CALL OfficeInstallationDirectories::getSingletonName_static()
294 {
295     return rtl::OUString(
296         RTL_CONSTASCII_USTRINGPARAM(
297             "com.sun.star.util.theOfficeInstallationDirectories" ) );
298 }
299 
300 //=========================================================================
301 // static
302 uno::Reference< uno::XInterface > SAL_CALL
303 OfficeInstallationDirectories::Create(
304         const uno::Reference< uno::XComponentContext > & rxContext )
305 {
306     return static_cast< cppu::OWeakObject * >(
307         new OfficeInstallationDirectories( rxContext ) );
308 }
309 
310 //=========================================================================
311 // non-UNO
312 //=========================================================================
313 
314 void OfficeInstallationDirectories::initDirs()
315 {
316     if ( m_pOfficeBrandDir == 0 )
317     {
318         osl::MutexGuard aGuard( m_aMutex );
319         if ( m_pOfficeBrandDir == 0 )
320         {
321             m_pOfficeBrandDir = new rtl::OUString;
322             m_pOfficeBaseDir  = new rtl::OUString;
323             m_pUserDir        = new rtl::OUString;
324 
325             uno::Reference< util::XMacroExpander > xExpander;
326 
327             m_xCtx->getValueByName(
328                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
329                     "/singletons/com.sun.star.util.theMacroExpander" ) ) )
330             >>= xExpander;
331 
332             OSL_ENSURE( xExpander.is(),
333                         "Unable to obtain macro expander singleton!" );
334 
335             if ( xExpander.is() )
336             {
337                 *m_pOfficeBrandDir =
338                     xExpander->expandMacros(
339                          rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "$OOO_BASE_DIR" ) ) );
340 
341                 OSL_ENSURE( !m_pOfficeBrandDir->isEmpty(),
342                             "Unable to obtain office brand installation directory!" );
343 
344                 makeCanonicalFileURL( *m_pOfficeBrandDir );
345 
346                 *m_pOfficeBaseDir = *m_pOfficeBrandDir;
347                 //     xExpander->expandMacros(
348                 //         rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
349                 //             "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE( "bootstrap" ) ":BaseInstallation}" ) ) );
350 
351                 // OSL_ENSURE( m_pOfficeBaseDir->getLength() > 0,
352                 //             "Unable to obtain office base installation directory!" );
353 
354                 makeCanonicalFileURL( *m_pOfficeBaseDir );
355 
356                 *m_pUserDir =
357                     xExpander->expandMacros(
358                         rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
359                             "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE( "bootstrap" ) ":UserInstallation}" ) ) );
360 
361                 OSL_ENSURE( !m_pUserDir->isEmpty(),
362                             "Unable to obtain office user data directory!" );
363 
364                 makeCanonicalFileURL( *m_pUserDir );
365             }
366         }
367     }
368 }
369 
370 void createRegistryInfo_OfficeInstallationDirectories()
371 {
372     static ::comphelper::module::OSingletonRegistration< OfficeInstallationDirectories > aAutoRegistration;
373 }
374