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