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 {
127 initDirs();
128 return rtl::OUString( *m_pOfficeBrandDir );
129 }
130
131 //=========================================================================
132 // virtual
133 rtl::OUString SAL_CALL
getOfficeUserDataDirectoryURL()134 OfficeInstallationDirectories::getOfficeUserDataDirectoryURL()
135 {
136 initDirs();
137 return rtl::OUString( *m_pUserDir );
138 }
139
140
141 //=========================================================================
142 // virtual
143 rtl::OUString SAL_CALL
makeRelocatableURL(const rtl::OUString & URL)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
makeAbsoluteURL(const rtl::OUString & URL)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
getImplementationName()240 OfficeInstallationDirectories::getImplementationName()
241 {
242 return getImplementationName_static();
243 }
244
245 //=========================================================================
246 // virtual
247 sal_Bool SAL_CALL
supportsService(const rtl::OUString & ServiceName)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
getSupportedServiceNames()265 OfficeInstallationDirectories::getSupportedServiceNames()
266 {
267 return getSupportedServiceNames_static();
268 }
269
270 //=========================================================================
271 // static
272 rtl::OUString SAL_CALL
getImplementationName_static()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
getSupportedServiceNames_static()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
getSingletonName_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
Create(const uno::Reference<uno::XComponentContext> & rxContext)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
initDirs()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
createRegistryInfo_OfficeInstallationDirectories()370 void createRegistryInfo_OfficeInstallationDirectories()
371 {
372 static ::comphelper::module::OSingletonRegistration< OfficeInstallationDirectories > aAutoRegistration;
373 }
374