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 //=========================================================================
makeCanonicalFileURL(rtl::OUString & rURL)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
OfficeInstallationDirectories(const uno::Reference<uno::XComponentContext> & xCtx)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
~OfficeInstallationDirectories()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
getOfficeInstallationDirectoryURL()125 OfficeInstallationDirectories::getOfficeInstallationDirectoryURL()
126 throw ( uno::RuntimeException )
127 {
128 initDirs();
129 return rtl::OUString( *m_pOfficeBrandDir );
130 }
131
132 //=========================================================================
133 // virtual
134 rtl::OUString SAL_CALL
getOfficeUserDataDirectoryURL()135 OfficeInstallationDirectories::getOfficeUserDataDirectoryURL()
136 throw ( uno::RuntimeException )
137 {
138 initDirs();
139 return rtl::OUString( *m_pUserDir );
140 }
141
142
143 //=========================================================================
144 // virtual
145 rtl::OUString SAL_CALL
makeRelocatableURL(const rtl::OUString & URL)146 OfficeInstallationDirectories::makeRelocatableURL( const rtl::OUString& URL )
147 throw ( uno::RuntimeException )
148 {
149 if ( !URL.isEmpty() )
150 {
151 initDirs();
152
153 rtl::OUString aCanonicalURL( URL );
154 makeCanonicalFileURL( aCanonicalURL );
155
156 sal_Int32 nIndex = aCanonicalURL.indexOf( *m_pOfficeBrandDir );
157 if ( nIndex != -1 )
158 {
159 return rtl::OUString(
160 URL.replaceAt( nIndex,
161 m_pOfficeBrandDir->getLength(),
162 m_aOfficeBrandDirMacro ) );
163 }
164 else
165 {
166 nIndex = aCanonicalURL.indexOf( *m_pOfficeBaseDir );
167 if ( nIndex != -1 )
168 {
169 return rtl::OUString(
170 URL.replaceAt( nIndex,
171 m_pOfficeBaseDir->getLength(),
172 m_aOfficeBaseDirMacro ) );
173 }
174 else
175 {
176 nIndex = aCanonicalURL.indexOf( *m_pUserDir );
177 if ( nIndex != -1 )
178 {
179 return rtl::OUString(
180 URL.replaceAt( nIndex,
181 m_pUserDir->getLength(),
182 m_aUserDirMacro ) );
183 }
184 }
185 }
186 }
187 return rtl::OUString( URL );
188 }
189
190 //=========================================================================
191 // virtual
192 rtl::OUString SAL_CALL
makeAbsoluteURL(const rtl::OUString & URL)193 OfficeInstallationDirectories::makeAbsoluteURL( const rtl::OUString& URL )
194 throw ( uno::RuntimeException )
195 {
196 if ( !URL.isEmpty() )
197 {
198 sal_Int32 nIndex = URL.indexOf( m_aOfficeBrandDirMacro );
199 if ( nIndex != -1 )
200 {
201 initDirs();
202
203 return rtl::OUString(
204 URL.replaceAt( nIndex,
205 m_aOfficeBrandDirMacro.getLength(),
206 *m_pOfficeBrandDir ) );
207 }
208 else
209 {
210 nIndex = URL.indexOf( m_aOfficeBaseDirMacro );
211 if ( nIndex != -1 )
212 {
213 initDirs();
214
215 return rtl::OUString(
216 URL.replaceAt( nIndex,
217 m_aOfficeBaseDirMacro.getLength(),
218 *m_pOfficeBaseDir ) );
219 }
220 else
221 {
222 nIndex = URL.indexOf( m_aUserDirMacro );
223 if ( nIndex != -1 )
224 {
225 initDirs();
226
227 return rtl::OUString(
228 URL.replaceAt( nIndex,
229 m_aUserDirMacro.getLength(),
230 *m_pUserDir ) );
231 }
232 }
233 }
234 }
235 return rtl::OUString( URL );
236 }
237
238 //=========================================================================
239 // lang::XServiceInfo
240 //=========================================================================
241
242 // virtual
243 rtl::OUString SAL_CALL
getImplementationName()244 OfficeInstallationDirectories::getImplementationName()
245 throw ( uno::RuntimeException )
246 {
247 return getImplementationName_static();
248 }
249
250 //=========================================================================
251 // virtual
252 sal_Bool SAL_CALL
supportsService(const rtl::OUString & ServiceName)253 OfficeInstallationDirectories::supportsService( const rtl::OUString& ServiceName )
254 throw ( uno::RuntimeException )
255 {
256 const uno::Sequence< rtl::OUString > & aNames
257 = getSupportedServiceNames();
258 const rtl::OUString * p = aNames.getConstArray();
259 for ( sal_Int32 nPos = 0; nPos < aNames.getLength(); nPos++ )
260 {
261 if ( p[ nPos ].equals( ServiceName ) )
262 return sal_True;
263 }
264 return sal_False;
265
266 }
267
268 //=========================================================================
269 // virtual
270 uno::Sequence< ::rtl::OUString > SAL_CALL
getSupportedServiceNames()271 OfficeInstallationDirectories::getSupportedServiceNames()
272 throw ( uno::RuntimeException )
273 {
274 return getSupportedServiceNames_static();
275 }
276
277 //=========================================================================
278 // static
279 rtl::OUString SAL_CALL
getImplementationName_static()280 OfficeInstallationDirectories::getImplementationName_static()
281 {
282 return rtl::OUString(
283 RTL_CONSTASCII_USTRINGPARAM(
284 "com.sun.star.comp.util.OfficeInstallationDirectories" ) );
285 }
286
287 //=========================================================================
288 // static
289 uno::Sequence< ::rtl::OUString > SAL_CALL
getSupportedServiceNames_static()290 OfficeInstallationDirectories::getSupportedServiceNames_static()
291 {
292 const rtl::OUString aServiceName(
293 RTL_CONSTASCII_USTRINGPARAM(
294 "com.sun.star.util.OfficeInstallationDirectories" ) );
295 return uno::Sequence< rtl::OUString >( &aServiceName, 1 );
296 }
297
298 //=========================================================================
299 // static
getSingletonName_static()300 rtl::OUString SAL_CALL OfficeInstallationDirectories::getSingletonName_static()
301 {
302 return rtl::OUString(
303 RTL_CONSTASCII_USTRINGPARAM(
304 "com.sun.star.util.theOfficeInstallationDirectories" ) );
305 }
306
307 //=========================================================================
308 // static
309 uno::Reference< uno::XInterface > SAL_CALL
Create(const uno::Reference<uno::XComponentContext> & rxContext)310 OfficeInstallationDirectories::Create(
311 const uno::Reference< uno::XComponentContext > & rxContext )
312 {
313 return static_cast< cppu::OWeakObject * >(
314 new OfficeInstallationDirectories( rxContext ) );
315 }
316
317 //=========================================================================
318 // non-UNO
319 //=========================================================================
320
initDirs()321 void OfficeInstallationDirectories::initDirs()
322 {
323 if ( m_pOfficeBrandDir == 0 )
324 {
325 osl::MutexGuard aGuard( m_aMutex );
326 if ( m_pOfficeBrandDir == 0 )
327 {
328 m_pOfficeBrandDir = new rtl::OUString;
329 m_pOfficeBaseDir = new rtl::OUString;
330 m_pUserDir = new rtl::OUString;
331
332 uno::Reference< util::XMacroExpander > xExpander;
333
334 m_xCtx->getValueByName(
335 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
336 "/singletons/com.sun.star.util.theMacroExpander" ) ) )
337 >>= xExpander;
338
339 OSL_ENSURE( xExpander.is(),
340 "Unable to obtain macro expander singleton!" );
341
342 if ( xExpander.is() )
343 {
344 *m_pOfficeBrandDir =
345 xExpander->expandMacros(
346 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "$OOO_BASE_DIR" ) ) );
347
348 OSL_ENSURE( !m_pOfficeBrandDir->isEmpty(),
349 "Unable to obtain office brand installation directory!" );
350
351 makeCanonicalFileURL( *m_pOfficeBrandDir );
352
353 *m_pOfficeBaseDir = *m_pOfficeBrandDir;
354 // xExpander->expandMacros(
355 // rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
356 // "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE( "bootstrap" ) ":BaseInstallation}" ) ) );
357
358 // OSL_ENSURE( m_pOfficeBaseDir->getLength() > 0,
359 // "Unable to obtain office base installation directory!" );
360
361 makeCanonicalFileURL( *m_pOfficeBaseDir );
362
363 *m_pUserDir =
364 xExpander->expandMacros(
365 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
366 "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE( "bootstrap" ) ":UserInstallation}" ) ) );
367
368 OSL_ENSURE( !m_pUserDir->isEmpty(),
369 "Unable to obtain office user data directory!" );
370
371 makeCanonicalFileURL( *m_pUserDir );
372 }
373 }
374 }
375 }
376
createRegistryInfo_OfficeInstallationDirectories()377 void createRegistryInfo_OfficeInstallationDirectories()
378 {
379 static ::comphelper::module::OSingletonRegistration< OfficeInstallationDirectories > aAutoRegistration;
380 }
381