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/substitutepathvars.hxx" 31 #include <threadhelp/resetableguard.hxx> 32 #include <helper/networkdomain.hxx> 33 #include "services.h" 34 35 //_________________________________________________________________________________________________________________ 36 // interface includes 37 //_________________________________________________________________________________________________________________ 38 #include <com/sun/star/beans/XPropertySet.hpp> 39 40 //_________________________________________________________________________________________________________________ 41 // includes of other projects 42 //_________________________________________________________________________________________________________________ 43 #include <unotools/configitem.hxx> 44 #include <unotools/localfilehelper.hxx> 45 #include <unotools/configmgr.hxx> 46 47 #ifndef _UTL_BOOTSTRAP_HXX_ 48 #include <unotools/bootstrap.hxx> 49 #endif 50 #include <osl/mutex.hxx> 51 #include <osl/file.hxx> 52 #include <osl/security.hxx> 53 #include <osl/socket.hxx> 54 #include <vos/process.hxx> 55 #include <i18npool/mslangid.hxx> 56 #include <tools/urlobj.hxx> 57 #include <tools/resmgr.hxx> 58 #include <tools/debug.hxx> 59 #include <tools/wldcrd.hxx> 60 #include <rtl/ustrbuf.hxx> 61 #include <rtl/bootstrap.hxx> 62 63 #include <comphelper/configurationhelper.hxx> 64 65 #include <string.h> 66 67 //_________________________________________________________________________________________________________________ 68 // Defines 69 //_________________________________________________________________________________________________________________ 70 // 71 72 #define STRPOS_NOTFOUND (sal_Int32)-1 73 74 #define ASCII_STR( val ) rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( val )) 75 76 #define SEARCHPATH_DELIMITER ';' 77 78 // Variable start/end characters 79 #define SIGN_STARTVARIABLE ASCII_STR("$(") 80 #define SIGN_ENDVARIABLE ASCII_STR(")") 81 82 // Length of SUBSTITUTE_... to replace it with real values. 83 #define REPLACELENGTH_INST 7 84 #define REPLACELENGTH_PROG 7 85 #define REPLACELENGTH_USER 7 86 #define REPLACELENGTH_WORK 7 87 #define REPLACELENGTH_HOME 7 88 #define REPLACELENGTH_TEMP 7 89 #define REPLACELENGTH_PATH 7 90 #define REPLACELENGTH_INSTPATH 11 91 #define REPLACELENGTH_PROGPATH 11 92 #define REPLACELENGTH_USERPATH 11 93 #define REPLACELENGTH_INSTURL 10 94 #define REPLACELENGTH_PROGURL 10 95 #define REPLACELENGTH_USERURL 10 96 #define REPLACELENGTH_PATH 7 97 #define REPLACELENGTH_LANG 7 98 #define REPLACELENGTH_LANGID 9 99 #define REPLACELENGTH_VLANG 8 100 #define REPLACELENGTH_WORKDIRURL 13 101 // --> PB 2004-10-27 #i32656# - new variable of hierachy service 102 #define REPLACELENGTH_BASEINSTURL 14 103 #define REPLACELENGTH_USERDATAURL 14 104 // <-- 105 106 // Name of the pre defined path variables 107 #define VARIABLE_INST "$(inst)" 108 #define VARIABLE_PROG "$(prog)" 109 #define VARIABLE_USER "$(user)" 110 #define VARIABLE_WORK "$(work)" 111 #define VARIABLE_HOME "$(home)" 112 #define VARIABLE_TEMP "$(temp)" 113 #define VARIABLE_PATH "$(path)" 114 #define VARIABLE_LANG "$(lang)" 115 #define VARIABLE_LANGID "$(langid)" 116 #define VARIABLE_VLANG "$(vlang)" 117 #define VARIABLE_INSTPATH "$(instpath)" 118 #define VARIABLE_PROGPATH "$(progpath)" 119 #define VARIABLE_USERPATH "$(userpath)" 120 #define VARIABLE_INSTURL "$(insturl)" 121 #define VARIABLE_PROGURL "$(progurl)" 122 #define VARIABLE_USERURL "$(userurl)" 123 #define VARIABLE_WORKDIRURL "$(workdirurl)" 124 // --> PB 2004-10-27 #i32656# - new variable of hierachy service 125 #define VARIABLE_BASEINSTURL "$(baseinsturl)" 126 #define VARIABLE_USERDATAURL "$(userdataurl)" 127 // <-- 128 #define VARIABLE_BRANDBASEURL "$(brandbaseurl)" 129 130 using namespace com::sun::star::uno; 131 using namespace com::sun::star::beans; 132 using namespace com::sun::star::util; 133 using namespace com::sun::star::lang; 134 using namespace com::sun::star::container; 135 136 //_________________________________________________________________________________________________________________ 137 // Namespace 138 //_________________________________________________________________________________________________________________ 139 // 140 141 namespace framework 142 { 143 144 struct FixedVariable 145 { 146 const char* pVarName; 147 PreDefVariable nEnumValue; 148 int nStrLen; 149 bool bAbsPath; 150 }; 151 152 struct TableEntry 153 { 154 const char* pOSString; 155 int nStrLen; 156 }; 157 158 // Table with valid operating system strings 159 // Name of the os as char* and the length 160 // of the string 161 static TableEntry aOSTable[OS_COUNT] = 162 { 163 { "WINDOWS" , 7 }, 164 { "UNIX" , 4 }, 165 { "SOLARIS" , 7 }, 166 { "LINUX" , 5 }, 167 { "" , 0 } // unknown 168 }; 169 170 // Table with valid environment variables 171 // Name of the environment type as a char* and 172 // the length of the string. 173 static TableEntry aEnvTable[ET_COUNT] = 174 { 175 { "HOST" , 4 }, 176 { "YPDOMAIN" , 8 }, 177 { "DNSDOMAIN" , 9 }, 178 { "NTDOMAIN" , 8 }, 179 { "OS" , 2 }, 180 { "" , 0 } // unknown 181 }; 182 183 // Priority table for the environment types. Lower numbers define 184 // a higher priority. Equal numbers has the same priority that means 185 // that the first match wins!! 186 static sal_Int16 aEnvPrioTable[ET_COUNT] = 187 { 188 1, // ET_HOST 189 2, // ET_IPDOMAIN 190 2, // ET_DNSDOMAIN 191 2, // ET_NTDOMAIN 192 3, // ET_OS 193 99, // ET_UNKNOWN 194 }; 195 196 // Table with all fixed/predefined variables supported. 197 static FixedVariable aFixedVarTable[] = 198 { 199 { VARIABLE_INST, PREDEFVAR_INST, REPLACELENGTH_INST, true }, 200 { VARIABLE_PROG, PREDEFVAR_PROG, REPLACELENGTH_PROG, true }, 201 { VARIABLE_USER, PREDEFVAR_USER, REPLACELENGTH_USER, true }, 202 { VARIABLE_WORK, PREDEFVAR_WORK, REPLACELENGTH_WORK, true }, // Special variable (transient)! 203 { VARIABLE_HOME, PREDEFVAR_HOME, REPLACELENGTH_HOME, true }, 204 { VARIABLE_TEMP, PREDEFVAR_TEMP, REPLACELENGTH_TEMP, true }, 205 { VARIABLE_PATH, PREDEFVAR_PATH, REPLACELENGTH_PATH, true }, 206 { VARIABLE_LANG, PREDEFVAR_LANG, REPLACELENGTH_LANG, false }, 207 { VARIABLE_LANGID, PREDEFVAR_LANGID, REPLACELENGTH_LANGID, false }, 208 { VARIABLE_VLANG, PREDEFVAR_VLANG, REPLACELENGTH_VLANG, false }, 209 { VARIABLE_INSTPATH, PREDEFVAR_INSTPATH, REPLACELENGTH_INSTPATH, true }, 210 { VARIABLE_PROGPATH, PREDEFVAR_PROGPATH, REPLACELENGTH_PROGPATH, true }, 211 { VARIABLE_USERPATH, PREDEFVAR_USERPATH, REPLACELENGTH_USERPATH, true }, 212 { VARIABLE_INSTURL, PREDEFVAR_INSTURL, REPLACELENGTH_INSTURL, true }, 213 { VARIABLE_PROGURL, PREDEFVAR_PROGURL, REPLACELENGTH_PROGURL, true }, 214 { VARIABLE_USERURL, PREDEFVAR_USERURL, REPLACELENGTH_USERURL, true }, 215 { VARIABLE_WORKDIRURL, PREDEFVAR_WORKDIRURL, REPLACELENGTH_WORKDIRURL,true }, // Special variable (transient) and don't use for resubstitution! 216 // --> PB 2004-10-27 #i32656# - new variable of hierachy service 217 { VARIABLE_BASEINSTURL, PREDEFVAR_BASEINSTURL, REPLACELENGTH_BASEINSTURL,true }, 218 { VARIABLE_USERDATAURL, PREDEFVAR_USERDATAURL, REPLACELENGTH_USERDATAURL,true }, 219 // <-- 220 { VARIABLE_BRANDBASEURL,PREDEFVAR_BRANDBASEURL, RTL_CONSTASCII_LENGTH(VARIABLE_BRANDBASEURL), true } 221 }; 222 223 //_________________________________________________________________________________________________________________ 224 // Implementation helper classes 225 //_________________________________________________________________________________________________________________ 226 // 227 228 OperatingSystem SubstitutePathVariables_Impl::GetOperatingSystemFromString( const rtl::OUString& aOSString ) 229 { 230 for ( int i = 0; i < OS_COUNT; i++ ) 231 { 232 if ( aOSString.equalsIgnoreAsciiCaseAsciiL( aOSTable[i].pOSString, aOSTable[i].nStrLen )) 233 return (OperatingSystem)i; 234 } 235 236 return OS_UNKNOWN; 237 } 238 239 EnvironmentType SubstitutePathVariables_Impl::GetEnvTypeFromString( const rtl::OUString& aEnvTypeString ) 240 { 241 for ( int i = 0; i < ET_COUNT; i++ ) 242 { 243 if ( aEnvTypeString.equalsIgnoreAsciiCaseAsciiL( aEnvTable[i].pOSString, aEnvTable[i].nStrLen )) 244 return (EnvironmentType)i; 245 } 246 247 return ET_UNKNOWN; 248 } 249 250 SubstitutePathVariables_Impl::SubstitutePathVariables_Impl( const Link& aNotifyLink ) : 251 utl::ConfigItem( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Office.Substitution" ))), 252 m_bYPDomainRetrieved( false ), 253 m_bDNSDomainRetrieved( false ), 254 m_bNTDomainRetrieved( false ), 255 m_bHostRetrieved( false ), 256 m_bOSRetrieved( false ), 257 m_aListenerNotify( aNotifyLink ), 258 m_aSharePointsNodeName( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SharePoints" ))), 259 m_aDirPropertyName( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/Directory" ))), 260 m_aEnvPropertyName( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/Environment" ))), 261 m_aLevelSep( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ))) 262 { 263 // Enable notification mechanism 264 // We need it to get information about changes outside these class on our configuration branch 265 Sequence< rtl::OUString > aNotifySeq( 1 ); 266 aNotifySeq[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SharePoints" )); 267 EnableNotification( aNotifySeq, sal_True ); 268 } 269 270 SubstitutePathVariables_Impl::~SubstitutePathVariables_Impl() 271 { 272 } 273 274 void SubstitutePathVariables_Impl::GetSharePointsRules( SubstituteVariables& aSubstVarMap ) 275 { 276 Sequence< rtl::OUString > aSharePointNames; 277 ReadSharePointsFromConfiguration( aSharePointNames ); 278 279 if ( aSharePointNames.getLength() > 0 ) 280 { 281 sal_Int32 nSharePoints = 0; 282 283 // Read SharePoints container from configuration 284 while ( nSharePoints < aSharePointNames.getLength() ) 285 { 286 rtl::OUString aSharePointNodeName( m_aSharePointsNodeName ); 287 aSharePointNodeName += rtl::OUString::createFromAscii( "/" ); 288 aSharePointNodeName += aSharePointNames[ nSharePoints ]; 289 290 SubstituteRuleVector aRuleSet; 291 ReadSharePointRuleSetFromConfiguration( aSharePointNames[ nSharePoints ], aSharePointNodeName, aRuleSet ); 292 if ( !aRuleSet.empty() ) 293 { 294 // We have at minimum one rule. Filter the correct rule out of the rule set 295 // and put into our SubstituteVariable map 296 SubstituteRule aActiveRule; 297 if ( FilterRuleSet( aRuleSet, aActiveRule )) 298 { 299 // We have found an active rule 300 aActiveRule.aSubstVariable = aSharePointNames[ nSharePoints ]; 301 aSubstVarMap.insert( SubstituteVariables::value_type( 302 aActiveRule.aSubstVariable, aActiveRule )); 303 } 304 } 305 ++nSharePoints; 306 } 307 } 308 } 309 310 void SubstitutePathVariables_Impl::Notify( const com::sun::star::uno::Sequence< rtl::OUString >& /*aPropertyNames*/ ) 311 { 312 // NOT implemented yet! 313 } 314 315 void SubstitutePathVariables_Impl::Commit() 316 { 317 } 318 319 320 //_________________________________________________________________________________________________________________ 321 // private methods 322 //_________________________________________________________________________________________________________________ 323 // 324 325 OperatingSystem SubstitutePathVariables_Impl::GetOperatingSystem() 326 { 327 if ( !m_bOSRetrieved ) 328 { 329 #ifdef SOLARIS 330 m_eOSType = OS_SOLARIS; 331 #elif defined LINUX 332 m_eOSType = OS_LINUX; 333 #elif defined WIN32 334 m_eOSType = OS_WINDOWS; 335 #elif defined UNIX 336 m_eOSType = OS_UNIX; 337 #else 338 m_eOSType = OS_UNKNOWN; 339 #endif 340 m_bOSRetrieved = sal_True; 341 } 342 343 return m_eOSType; 344 } 345 346 const rtl::OUString& SubstitutePathVariables_Impl::GetYPDomainName() 347 { 348 if ( !m_bYPDomainRetrieved ) 349 { 350 m_aYPDomain = NetworkDomain::GetYPDomainName().toAsciiLowerCase(); 351 m_bYPDomainRetrieved = sal_True; 352 } 353 354 return m_aYPDomain; 355 } 356 357 const rtl::OUString& SubstitutePathVariables_Impl::GetDNSDomainName() 358 { 359 if ( !m_bDNSDomainRetrieved ) 360 { 361 rtl::OUString aTemp; 362 osl::SocketAddr aSockAddr; 363 oslSocketResult aResult; 364 365 rtl::OUString aHostName = GetHostName(); 366 osl::SocketAddr::resolveHostname( aHostName, aSockAddr ); 367 aTemp = aSockAddr.getHostname( &aResult ); 368 369 // DNS domain name begins after the first "." 370 sal_Int32 nIndex = aTemp.indexOf( '.' ); 371 if ( nIndex >= 0 && aTemp.getLength() > nIndex+1 ) 372 m_aDNSDomain = aTemp.copy( nIndex+1 ).toAsciiLowerCase(); 373 else 374 m_aDNSDomain = rtl::OUString(); 375 376 m_bDNSDomainRetrieved = sal_True; 377 } 378 379 return m_aDNSDomain; 380 } 381 382 const rtl::OUString& SubstitutePathVariables_Impl::GetNTDomainName() 383 { 384 if ( !m_bNTDomainRetrieved ) 385 { 386 m_aNTDomain = NetworkDomain::GetNTDomainName().toAsciiLowerCase(); 387 m_bNTDomainRetrieved = sal_True; 388 } 389 390 return m_aNTDomain; 391 } 392 393 const rtl::OUString& SubstitutePathVariables_Impl::GetHostName() 394 { 395 if ( !m_bHostRetrieved ) 396 { 397 rtl::OUString aHostName; 398 oslSocketResult aSocketResult; 399 400 m_aHost = osl::SocketAddr::getLocalHostname( &aSocketResult ).toAsciiLowerCase(); 401 } 402 403 return m_aHost; 404 } 405 406 bool SubstitutePathVariables_Impl::FilterRuleSet( const SubstituteRuleVector& aRuleSet, SubstituteRule& aActiveRule ) 407 { 408 bool bResult = sal_False; 409 410 if ( !aRuleSet.empty() ) 411 { 412 const sal_uInt32 nCount = aRuleSet.size(); 413 414 sal_Int16 nPrioCurrentRule = aEnvPrioTable[ ET_UNKNOWN ]; 415 for ( sal_uInt32 nIndex = 0; nIndex < nCount; nIndex++ ) 416 { 417 const SubstituteRule& aRule = aRuleSet[nIndex]; 418 EnvironmentType eEnvType = aRule.aEnvType; 419 420 // Check if environment type has a higher priority than current one! 421 if ( nPrioCurrentRule > aEnvPrioTable[eEnvType] ) 422 { 423 switch ( eEnvType ) 424 { 425 case ET_HOST: 426 { 427 rtl::OUString aHost = GetHostName(); 428 rtl::OUString aHostStr; 429 aRule.aEnvValue >>= aHostStr; 430 aHostStr = aHostStr.toAsciiLowerCase(); 431 432 // Pattern match if domain environment match 433 WildCard aPattern(aHostStr); 434 bool bMatch = aPattern.Matches(aHost); 435 if ( bMatch ) 436 { 437 aActiveRule = aRule; 438 bResult = true; 439 nPrioCurrentRule = aEnvPrioTable[eEnvType]; 440 } 441 } 442 break; 443 444 case ET_YPDOMAIN: 445 case ET_DNSDOMAIN: 446 case ET_NTDOMAIN: 447 { 448 rtl::OUString aDomain; 449 rtl::OUString aDomainStr; 450 aRule.aEnvValue >>= aDomainStr; 451 aDomainStr = aDomainStr.toAsciiLowerCase(); 452 453 // Retrieve the correct domain value 454 if ( eEnvType == ET_YPDOMAIN ) 455 aDomain = GetYPDomainName(); 456 else if ( eEnvType == ET_DNSDOMAIN ) 457 aDomain = GetDNSDomainName(); 458 else 459 aDomain = GetNTDomainName(); 460 461 // Pattern match if domain environment match 462 WildCard aPattern(aDomainStr); 463 bool bMatch = aPattern.Matches(aDomain); 464 if ( bMatch ) 465 { 466 aActiveRule = aRule; 467 bResult = true; 468 nPrioCurrentRule = aEnvPrioTable[eEnvType]; 469 } 470 } 471 break; 472 473 case ET_OS: 474 { 475 // No pattern matching for OS type 476 OperatingSystem eOSType = GetOperatingSystem(); 477 478 sal_Int16 nValue = 0; 479 aRule.aEnvValue >>= nValue; 480 481 bool bUnix = ( eOSType == OS_LINUX ) || ( eOSType == OS_SOLARIS ); 482 OperatingSystem eRuleOSType = (OperatingSystem)nValue; 483 484 // Match if OS identical or rule is set to UNIX and OS is LINUX/SOLARIS! 485 if (( eRuleOSType == eOSType ) || ( eRuleOSType == OS_UNIX && bUnix )) 486 { 487 aActiveRule = aRule; 488 bResult = true; 489 nPrioCurrentRule = aEnvPrioTable[eEnvType]; 490 } 491 } 492 break; 493 494 case ET_UNKNOWN: // nothing to do 495 break; 496 497 default: 498 break; 499 } 500 } 501 } 502 } 503 504 return bResult; 505 } 506 507 void SubstitutePathVariables_Impl::ReadSharePointsFromConfiguration( Sequence< rtl::OUString >& aSharePointsSeq ) 508 { 509 //returns all the names of all share point nodes 510 aSharePointsSeq = GetNodeNames( m_aSharePointsNodeName ); 511 } 512 513 void SubstitutePathVariables_Impl::ReadSharePointRuleSetFromConfiguration( 514 const rtl::OUString& aSharePointName, 515 const rtl::OUString& aSharePointNodeName, 516 SubstituteRuleVector& rRuleSet ) 517 { 518 Sequence< rtl::OUString > aSharePointMappingsNodeNames = GetNodeNames( aSharePointNodeName, utl::CONFIG_NAME_LOCAL_PATH ); 519 520 sal_Int32 nSharePointMapping = 0; 521 while ( nSharePointMapping < aSharePointMappingsNodeNames.getLength() ) 522 { 523 rtl::OUString aSharePointMapping( aSharePointNodeName ); 524 aSharePointMapping += m_aLevelSep; 525 aSharePointMapping += aSharePointMappingsNodeNames[ nSharePointMapping ]; 526 527 // Read SharePointMapping 528 rtl::OUString aDirValue; 529 rtl::OUString aDirProperty( aSharePointMapping ); 530 aDirProperty += m_aDirPropertyName; 531 532 // Read only the directory property 533 Sequence< rtl::OUString > aDirPropertySeq( 1 ); 534 aDirPropertySeq[0] = aDirProperty; 535 536 Sequence< Any > aValueSeq = GetProperties( aDirPropertySeq ); 537 if ( aValueSeq.getLength() == 1 ) 538 aValueSeq[0] >>= aDirValue; 539 540 // Read the environment setting 541 rtl::OUString aEnvUsed; 542 rtl::OUString aEnvProperty( aSharePointMapping ); 543 aEnvProperty += m_aEnvPropertyName; 544 Sequence< rtl::OUString > aEnvironmentVariable = GetNodeNames( aEnvProperty ); 545 546 // Filter the property which has a value set 547 Sequence< rtl::OUString > aEnvUsedPropertySeq( aEnvironmentVariable.getLength() ); 548 549 rtl::OUString aEnvUsePropNameTemplate( aEnvProperty ); 550 aEnvUsePropNameTemplate += m_aLevelSep; 551 552 for ( sal_Int32 nProperty = 0; nProperty < aEnvironmentVariable.getLength(); nProperty++ ) 553 aEnvUsedPropertySeq[nProperty] = rtl::OUString( aEnvUsePropNameTemplate + aEnvironmentVariable[nProperty] ); 554 555 Sequence< Any > aEnvUsedValueSeq; 556 aEnvUsedValueSeq = GetProperties( aEnvUsedPropertySeq ); 557 558 rtl::OUString aEnvUsedValue; 559 for ( sal_Int32 nIndex = 0; nIndex < aEnvironmentVariable.getLength(); nIndex++ ) 560 { 561 if ( aEnvUsedValueSeq[nIndex] >>= aEnvUsedValue ) 562 { 563 aEnvUsed = aEnvironmentVariable[nIndex]; 564 break; 565 } 566 } 567 568 // Decode the environment and optional the operatng system settings 569 Any aEnvValue; 570 EnvironmentType eEnvType = GetEnvTypeFromString( aEnvUsed ); 571 if ( eEnvType == ET_OS ) 572 { 573 OperatingSystem eOSType = GetOperatingSystemFromString( aEnvUsedValue ); 574 aEnvValue <<= (sal_Int16)eOSType; 575 } 576 else 577 aEnvValue <<= aEnvUsedValue; 578 579 // Create rule struct and push it into the rule set 580 SubstituteRule aRule( aSharePointName, aDirValue, aEnvValue, eEnvType ); 581 rRuleSet.push_back( aRule ); 582 583 ++nSharePointMapping; 584 } 585 } 586 587 //***************************************************************************************************************** 588 // XInterface, XTypeProvider, XServiceInfo 589 //***************************************************************************************************************** 590 DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( SubstitutePathVariables , 591 ::cppu::OWeakObject , 592 SERVICENAME_SUBSTITUTEPATHVARIABLES , 593 IMPLEMENTATIONNAME_SUBSTITUTEPATHVARIABLES ) 594 595 DEFINE_INIT_SERVICE ( SubstitutePathVariables, {} ) 596 597 598 SubstitutePathVariables::SubstitutePathVariables( const Reference< XMultiServiceFactory >& xServiceManager ) : 599 ThreadHelpBase(), 600 m_aVarStart( SIGN_STARTVARIABLE ), 601 m_aVarEnd( SIGN_ENDVARIABLE ), 602 m_aImpl( LINK( this, SubstitutePathVariables, implts_ConfigurationNotify )), 603 m_xServiceManager( xServiceManager ) 604 { 605 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "SubstitutePathVariables::SubstitutePathVariables" ); 606 int i; 607 608 SetPredefinedPathVariables( m_aPreDefVars ); 609 m_aImpl.GetSharePointsRules( m_aSubstVarMap ); 610 611 // Init the predefined/fixed variable to index hash map 612 for ( i = 0; i < PREDEFVAR_COUNT; i++ ) 613 { 614 // Store variable name into struct of predefined/fixed variables 615 m_aPreDefVars.m_FixedVarNames[i] = rtl::OUString::createFromAscii( aFixedVarTable[i].pVarName ); 616 617 // Create hash map entry 618 m_aPreDefVarMap.insert( VarNameToIndexMap::value_type( 619 m_aPreDefVars.m_FixedVarNames[i], aFixedVarTable[i].nEnumValue ) ); 620 } 621 622 // Sort predefined/fixed variable to path length 623 for ( i = 0; i < PREDEFVAR_COUNT; i++ ) 624 { 625 if (( i != PREDEFVAR_WORKDIRURL ) && ( i != PREDEFVAR_PATH )) 626 { 627 // Special path variables, don't include into automatic resubstituion search! 628 // $(workdirurl) is not allowed to resubstitute! This variable is the value of path settings entry 629 // and it could be possible that it will be resubstituted by itself!! 630 // Example: WORK_PATH=c:\test, $(workdirurl)=WORK_PATH => WORK_PATH=$(workdirurl) and this cannot be substituted! 631 ReSubstFixedVarOrder aFixedVar; 632 aFixedVar.eVariable = aFixedVarTable[i].nEnumValue; 633 aFixedVar.nVarValueLength = m_aPreDefVars.m_FixedVar[(sal_Int32)aFixedVar.eVariable].getLength(); 634 m_aReSubstFixedVarOrder.push_back( aFixedVar ); 635 } 636 } 637 m_aReSubstFixedVarOrder.sort(); 638 639 // Sort user variables to path length 640 SubstituteVariables::const_iterator pIter; 641 for ( pIter = m_aSubstVarMap.begin(); pIter != m_aSubstVarMap.end(); pIter++ ) 642 { 643 ReSubstUserVarOrder aUserOrderVar; 644 rtl::OUStringBuffer aStrBuffer( pIter->second.aSubstVariable.getLength() ); 645 aStrBuffer.append( m_aVarStart ); 646 aStrBuffer.append( pIter->second.aSubstVariable ); 647 aStrBuffer.append( m_aVarEnd ); 648 aUserOrderVar.aVarName = aStrBuffer.makeStringAndClear(); 649 aUserOrderVar.nVarValueLength = pIter->second.aSubstVariable.getLength(); 650 m_aReSubstUserVarOrder.push_back( aUserOrderVar ); 651 } 652 m_aReSubstUserVarOrder.sort(); 653 } 654 655 SubstitutePathVariables::~SubstitutePathVariables() 656 { 657 } 658 659 // XStringSubstitution 660 rtl::OUString SAL_CALL SubstitutePathVariables::substituteVariables( const ::rtl::OUString& aText, sal_Bool bSubstRequired ) 661 throw ( NoSuchElementException, RuntimeException ) 662 { 663 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "SubstitutePathVariables::substituteVariables" ); 664 ResetableGuard aLock( m_aLock ); 665 return impl_substituteVariable( aText, bSubstRequired ); 666 } 667 668 rtl::OUString SAL_CALL SubstitutePathVariables::reSubstituteVariables( const ::rtl::OUString& aText ) 669 throw ( RuntimeException ) 670 { 671 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "SubstitutePathVariables::reSubstituteVariables" ); 672 ResetableGuard aLock( m_aLock ); 673 return impl_reSubstituteVariables( aText ); 674 } 675 676 rtl::OUString SAL_CALL SubstitutePathVariables::getSubstituteVariableValue( const ::rtl::OUString& aVariable ) 677 throw ( NoSuchElementException, RuntimeException ) 678 { 679 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "SubstitutePathVariables::getSubstituteVariableValue" ); 680 ResetableGuard aLock( m_aLock ); 681 return impl_getSubstituteVariableValue( aVariable ); 682 } 683 684 //_________________________________________________________________________________________________________________ 685 // protected methods 686 //_________________________________________________________________________________________________________________ 687 // 688 689 IMPL_LINK( SubstitutePathVariables, implts_ConfigurationNotify, SubstitutePathNotify*, EMPTYARG ) 690 { 691 /* SAFE AREA ----------------------------------------------------------------------------------------------- */ 692 ResetableGuard aLock( m_aLock ); 693 694 return 0; 695 } 696 697 rtl::OUString SubstitutePathVariables::ConvertOSLtoUCBURL( const rtl::OUString& aOSLCompliantURL ) const 698 { 699 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "SubstitutePathVariables::ConvertOSLtoUCBURL" ); 700 String aResult; 701 rtl::OUString aTemp; 702 703 osl::FileBase::getSystemPathFromFileURL( aOSLCompliantURL, aTemp ); 704 utl::LocalFileHelper::ConvertPhysicalNameToURL( aTemp, aResult ); 705 706 // Not all OSL URL's can be mapped to UCB URL's! 707 if ( aResult.Len() == 0 ) 708 return aOSLCompliantURL; 709 else 710 return rtl::OUString( aResult ); 711 } 712 713 rtl::OUString SubstitutePathVariables::GetWorkPath() const 714 { 715 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "SubstitutePathVariables::GetWorkPath" ); 716 rtl::OUString aWorkPath; 717 ::comphelper::ConfigurationHelper::readDirectKey( 718 m_xServiceManager, 719 ::rtl::OUString::createFromAscii("org.openoffice.Office.Paths"), 720 ::rtl::OUString::createFromAscii("Paths/Work"), 721 ::rtl::OUString::createFromAscii("WritePath"), 722 ::comphelper::ConfigurationHelper::E_READONLY) >>= aWorkPath; 723 return aWorkPath; 724 } 725 726 rtl::OUString SubstitutePathVariables::GetWorkVariableValue() const 727 { 728 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "SubstitutePathVariables::GetWorkVariableValue" ); 729 ::rtl::OUString aWorkPath; 730 ::comphelper::ConfigurationHelper::readDirectKey( 731 m_xServiceManager, 732 ::rtl::OUString::createFromAscii("org.openoffice.Office.Paths"), 733 ::rtl::OUString::createFromAscii("Variables"), 734 ::rtl::OUString::createFromAscii("Work"), 735 ::comphelper::ConfigurationHelper::E_READONLY) >>= aWorkPath; 736 737 // fallback to $HOME in case platform dependend config layer does not return 738 // an usuable work dir value. 739 if (aWorkPath.getLength() < 1) 740 { 741 osl::Security aSecurity; 742 aSecurity.getHomeDir( aWorkPath ); 743 } 744 return ConvertOSLtoUCBURL( aWorkPath ); 745 } 746 747 rtl::OUString SubstitutePathVariables::GetHomeVariableValue() const 748 { 749 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "SubstitutePathVariables::GetHomeVariableValue" ); 750 osl::Security aSecurity; 751 rtl::OUString aHomePath; 752 753 aSecurity.getHomeDir( aHomePath ); 754 return ConvertOSLtoUCBURL( aHomePath ); 755 } 756 757 rtl::OUString SubstitutePathVariables::GetPathVariableValue() const 758 { 759 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "SubstitutePathVariables::GetPathVariableValue" ); 760 const int PATH_EXTEND_FACTOR = 120; 761 762 rtl::OUString aRetStr; 763 const char* pEnv = getenv( "PATH" ); 764 765 if ( pEnv ) 766 { 767 rtl::OUString aTmp; 768 rtl::OUString aPathList( pEnv, strlen( pEnv ), gsl_getSystemTextEncoding() ); 769 rtl::OUStringBuffer aPathStrBuffer( aPathList.getLength() * PATH_EXTEND_FACTOR / 100 ); 770 771 bool bAppendSep = false; 772 sal_Int32 nToken = 0; 773 do 774 { 775 ::rtl::OUString sToken = aPathList.getToken(0, SAL_PATHSEPARATOR, nToken); 776 if (sToken.getLength()) 777 { 778 osl::FileBase::getFileURLFromSystemPath( sToken, aTmp ); 779 if ( bAppendSep ) 780 aPathStrBuffer.appendAscii( ";" ); // Office uses ';' as path separator 781 aPathStrBuffer.append( aTmp ); 782 bAppendSep = true; 783 } 784 } 785 while(nToken>=0); 786 787 aRetStr = aPathStrBuffer.makeStringAndClear(); 788 } 789 790 return aRetStr; 791 } 792 793 rtl::OUString SubstitutePathVariables::impl_substituteVariable( const ::rtl::OUString& rText, bool bSubstRequired ) 794 throw ( NoSuchElementException, RuntimeException ) 795 { 796 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "SubstitutePathVariables::impl_substituteVariable" ); 797 // This is maximal recursive depth supported! 798 const sal_Int32 nMaxRecursiveDepth = 8; 799 800 rtl::OUString aWorkText = rText; 801 rtl::OUString aResult; 802 803 // Use vector with strings to detect endless recursions! 804 std::vector< rtl::OUString > aEndlessRecursiveDetector; 805 806 // Search for first occure of "$(...". 807 sal_Int32 nDepth = 0; 808 sal_Int32 bSubstitutionCompleted = sal_False; 809 sal_Int32 nPosition = aWorkText.indexOf( m_aVarStart ); // = first position of "$(" in string 810 sal_Int32 nLength = 0; // = count of letters from "$(" to ")" in string 811 bool bVarNotSubstituted = false; 812 813 // Have we found any variable like "$(...)"? 814 if ( nPosition != STRPOS_NOTFOUND ) 815 { 816 // Yes; Get length of found variable. 817 // If no ")" was found - nLength is set to 0 by default! see before. 818 sal_Int32 nEndPosition = aWorkText.indexOf( m_aVarEnd, nPosition ); 819 if ( nEndPosition != STRPOS_NOTFOUND ) 820 nLength = nEndPosition - nPosition + 1; 821 } 822 823 // Is there something to replace ? 824 bool bWorkRetrieved = false; 825 bool bWorkDirURLRetrieved = false; 826 while ( !bSubstitutionCompleted && nDepth < nMaxRecursiveDepth ) 827 { 828 while ( ( nPosition != STRPOS_NOTFOUND ) && ( nLength > 3 ) ) // "$(" ")" 829 { 830 // YES; Get the next variable for replace. 831 sal_Int32 nReplaceLength = 0; 832 rtl::OUString aReplacement; 833 rtl::OUString aSubString = aWorkText.copy( nPosition, nLength ); 834 rtl::OUString aSubVarString; 835 836 // Path variables are not case sensitive! 837 aSubVarString = aSubString.toAsciiLowerCase(); 838 VarNameToIndexMap::const_iterator pNTOIIter = m_aPreDefVarMap.find( aSubVarString ); 839 if ( pNTOIIter != m_aPreDefVarMap.end() ) 840 { 841 // Fixed/Predefined variable found 842 PreDefVariable nIndex = (PreDefVariable)pNTOIIter->second; 843 844 // Determine variable value and length from array/table 845 if ( nIndex == PREDEFVAR_WORK && !bWorkRetrieved ) 846 { 847 // Transient value, retrieve it again 848 m_aPreDefVars.m_FixedVar[ (PreDefVariable)nIndex ] = GetWorkVariableValue(); 849 bWorkRetrieved = true; 850 } 851 else if ( nIndex == PREDEFVAR_WORKDIRURL && !bWorkDirURLRetrieved ) 852 { 853 // Transient value, retrieve it again 854 m_aPreDefVars.m_FixedVar[ (PreDefVariable)nIndex ] = GetWorkPath(); 855 bWorkDirURLRetrieved = true; 856 } 857 858 // Check preconditions to substitue path variables. 859 // 1. A path variable can only be substituted if it follows a SEARCHPATH_DELIMITER ';'! 860 // 2. It's located exactly at the start of the string being substituted! 861 if (( aFixedVarTable[ int( nIndex ) ].bAbsPath && (( nPosition == 0 ) || (( nPosition > 0 ) && ( aWorkText[nPosition-1] == ';')))) || 862 ( !aFixedVarTable[ int( nIndex ) ].bAbsPath )) 863 { 864 aReplacement = m_aPreDefVars.m_FixedVar[ (PreDefVariable)nIndex ]; 865 nReplaceLength = nLength; 866 } 867 } 868 else 869 { 870 // Extract the variable name and try to find in the user defined variable set 871 rtl::OUString aVarName = aSubString.copy( 2, nLength-3 ); 872 SubstituteVariables::const_iterator pIter = m_aSubstVarMap.find( aVarName ); 873 if ( pIter != m_aSubstVarMap.end() ) 874 { 875 // Found. 876 aReplacement = pIter->second.aSubstValue; 877 nReplaceLength = nLength; 878 } 879 } 880 881 // Have we found something to replace? 882 if ( nReplaceLength > 0 ) 883 { 884 // Yes ... then do it. 885 aWorkText = aWorkText.replaceAt( nPosition, nReplaceLength, aReplacement ); 886 } 887 else 888 { 889 // Variable not known 890 bVarNotSubstituted = false; 891 nPosition += nLength; 892 } 893 894 // Step after replaced text! If no text was replaced (unknown variable!), 895 // length of aReplacement is 0 ... and we don't step then. 896 nPosition += aReplacement.getLength(); 897 898 // We must control index in string before call something at OUString! 899 // The OUString-implementation don't do it for us :-( but the result is not defined otherwise. 900 if ( nPosition + 1 > aWorkText.getLength() ) 901 { 902 // Position is out of range. Break loop! 903 nPosition = STRPOS_NOTFOUND; 904 nLength = 0; 905 } 906 else 907 { 908 // Else; Position is valid. Search for next variable to replace. 909 nPosition = aWorkText.indexOf( m_aVarStart, nPosition ); 910 // Have we found any variable like "$(...)"? 911 if ( nPosition != STRPOS_NOTFOUND ) 912 { 913 // Yes; Get length of found variable. If no ")" was found - nLength must set to 0! 914 nLength = 0; 915 sal_Int32 nEndPosition = aWorkText.indexOf( m_aVarEnd, nPosition ); 916 if ( nEndPosition != STRPOS_NOTFOUND ) 917 nLength = nEndPosition - nPosition + 1; 918 } 919 } 920 } 921 922 nPosition = aWorkText.indexOf( m_aVarStart ); 923 if ( nPosition == -1 ) 924 { 925 bSubstitutionCompleted = sal_True; 926 break; // All variables are substituted 927 } 928 else 929 { 930 // Check for recursion 931 const sal_uInt32 nCount = aEndlessRecursiveDetector.size(); 932 for ( sal_uInt32 i=0; i < nCount; i++ ) 933 { 934 if ( aEndlessRecursiveDetector[i] == aWorkText ) 935 { 936 if ( bVarNotSubstituted ) 937 break; // Not all variables could be substituted! 938 else 939 { 940 nDepth = nMaxRecursiveDepth; 941 break; // Recursion detected! 942 } 943 } 944 } 945 946 aEndlessRecursiveDetector.push_back( aWorkText ); 947 948 // Initialize values for next 949 sal_Int32 nEndPosition = aWorkText.indexOf( m_aVarEnd, nPosition ); 950 if ( nEndPosition != STRPOS_NOTFOUND ) 951 nLength = nEndPosition - nPosition + 1; 952 bVarNotSubstituted = sal_False; 953 ++nDepth; 954 } 955 } 956 957 // Fill return value with result 958 if ( bSubstitutionCompleted ) 959 { 960 // Substitution successfull! 961 aResult = aWorkText; 962 } 963 else 964 { 965 // Substitution not successfull! 966 if ( nDepth == nMaxRecursiveDepth ) 967 { 968 // recursion depth reached! 969 if ( bSubstRequired ) 970 { 971 rtl::OUString aMsg( RTL_CONSTASCII_USTRINGPARAM( "Endless recursion detected. Cannot substitute variables!" )); 972 throw NoSuchElementException( aMsg, (cppu::OWeakObject *)this ); 973 } 974 else 975 aResult = rText; 976 } 977 else 978 { 979 // variable in text but unknwon! 980 if ( bSubstRequired ) 981 { 982 rtl::OUString aMsg( RTL_CONSTASCII_USTRINGPARAM( "Unknown variable found!" )); 983 throw NoSuchElementException( aMsg, (cppu::OWeakObject *)this ); 984 } 985 else 986 aResult = aWorkText; 987 } 988 } 989 990 return aResult; 991 } 992 993 rtl::OUString SubstitutePathVariables::impl_reSubstituteVariables( const ::rtl::OUString& rURL ) 994 throw ( RuntimeException ) 995 { 996 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "SubstitutePathVariables::impl_reSubstituteVariables" ); 997 rtl::OUString aURL; 998 999 INetURLObject aUrl( rURL ); 1000 if ( !aUrl.HasError() ) 1001 aURL = aUrl.GetMainURL( INetURLObject::NO_DECODE ); 1002 else 1003 { 1004 // Convert a system path to a UCB compliant URL before resubstitution 1005 rtl::OUString aTemp; 1006 if ( osl::FileBase::getFileURLFromSystemPath( rURL, aTemp ) == osl::FileBase::E_None ) 1007 { 1008 aTemp = ConvertOSLtoUCBURL( aTemp ); 1009 if ( aTemp.getLength() ) 1010 aURL = INetURLObject( aTemp ).GetMainURL( INetURLObject::NO_DECODE ); 1011 else 1012 return rURL; 1013 } 1014 else 1015 { 1016 // rURL is not a valid URL nor a osl system path. Give up and return error! 1017 return rURL; 1018 } 1019 } 1020 1021 // Due to a recursive definition this code must exchange variables with variables! 1022 bool bResubstitutionCompleted = false; 1023 bool bVariableFound = false; 1024 1025 // Get transient predefined path variable $(work) value before starting resubstitution 1026 m_aPreDefVars.m_FixedVar[ PREDEFVAR_WORK ] = GetWorkVariableValue(); 1027 1028 while ( !bResubstitutionCompleted ) 1029 { 1030 ReSubstFixedVarOrderVector::const_iterator pIterFixed; 1031 for ( pIterFixed = m_aReSubstFixedVarOrder.begin(); pIterFixed != m_aReSubstFixedVarOrder.end(); pIterFixed++ ) 1032 { 1033 rtl::OUString aValue = m_aPreDefVars.m_FixedVar[ (sal_Int32)pIterFixed->eVariable ]; 1034 sal_Int32 nPos = aURL.indexOf( aValue ); 1035 if ( nPos >= 0 ) 1036 { 1037 bool bMatch = true; 1038 if ( pIterFixed->eVariable == PREDEFVAR_LANG || 1039 pIterFixed->eVariable == PREDEFVAR_LANGID || 1040 pIterFixed->eVariable == PREDEFVAR_VLANG ) 1041 { 1042 // Special path variables as they can occur in the middle of a path. Only match if they 1043 // describe a whole directory and not only a substring of a directory! 1044 const sal_Unicode* pStr = aURL.getStr(); 1045 1046 if ( nPos > 0 ) 1047 bMatch = ( aURL[ nPos-1 ] == '/' ); 1048 1049 if ( bMatch ) 1050 { 1051 if ( nPos + aValue.getLength() < aURL.getLength() ) 1052 bMatch = ( pStr[ nPos + aValue.getLength() ] == '/' ); 1053 } 1054 } 1055 1056 if ( bMatch ) 1057 { 1058 rtl::OUStringBuffer aStrBuffer( aURL.getLength() ); 1059 aStrBuffer.append( aURL.copy( 0, nPos ) ); 1060 aStrBuffer.append( m_aPreDefVars.m_FixedVarNames[ (sal_Int32)pIterFixed->eVariable ] ); // Get the variable name for struct var name array! 1061 aStrBuffer.append( aURL.copy( nPos + aValue.getLength(), ( aURL.getLength() - ( nPos + aValue.getLength() )) )); 1062 aURL = aStrBuffer.makeStringAndClear(); 1063 bVariableFound = true; // Resubstitution not finished yet! 1064 break; 1065 } 1066 } 1067 } 1068 1069 // This part can be iteratered more than one time as variables can contain variables again! 1070 ReSubstUserVarOrderVector::const_iterator pIterUser; 1071 for ( pIterUser = m_aReSubstUserVarOrder.begin(); pIterUser != m_aReSubstUserVarOrder.end(); pIterUser++ ) 1072 { 1073 rtl::OUString aVarValue = pIterUser->aVarName; 1074 sal_Int32 nPos = aURL.indexOf( aVarValue ); 1075 if ( nPos >= 0 ) 1076 { 1077 rtl::OUStringBuffer aStrBuffer( aURL.getLength() ); 1078 aStrBuffer.append( aURL.copy( 0, nPos ) ); 1079 aStrBuffer.append( m_aVarStart ); 1080 aStrBuffer.append( aVarValue ); 1081 aStrBuffer.append( m_aVarEnd ); 1082 aStrBuffer.append( aURL.copy( nPos + aVarValue.getLength(), ( aURL.getLength() - ( nPos + aVarValue.getLength() )) )); 1083 aURL = aStrBuffer.makeStringAndClear(); 1084 bVariableFound = true; // Resubstitution not finished yet! 1085 } 1086 } 1087 1088 if ( !bVariableFound ) 1089 bResubstitutionCompleted = true; 1090 else 1091 bVariableFound = sal_False; // Next resubstitution 1092 } 1093 1094 return aURL; 1095 } 1096 1097 // This method support both request schemes "$("<varname>")" or "<varname>". 1098 ::rtl::OUString SubstitutePathVariables::impl_getSubstituteVariableValue( const ::rtl::OUString& rVariable ) 1099 throw ( NoSuchElementException, RuntimeException ) 1100 { 1101 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "SubstitutePathVariables::impl_getSubstituteVariableValue" ); 1102 rtl::OUString aVariable; 1103 1104 sal_Int32 nPos = rVariable.indexOf( m_aVarStart ); 1105 if ( nPos == -1 ) 1106 { 1107 // Prepare variable name before hash map access 1108 rtl::OUStringBuffer aStrBuffer( rVariable.getLength() + m_aVarStart.getLength() + m_aVarEnd.getLength() ); 1109 aStrBuffer.append( m_aVarStart ); 1110 aStrBuffer.append( rVariable ); 1111 aStrBuffer.append( m_aVarEnd ); 1112 aVariable = aStrBuffer.makeStringAndClear(); 1113 } 1114 1115 VarNameToIndexMap::const_iterator pNTOIIter = m_aPreDefVarMap.find( ( nPos == -1 ) ? aVariable : rVariable ); 1116 1117 // Fixed/Predefined variable 1118 if ( pNTOIIter != m_aPreDefVarMap.end() ) 1119 { 1120 PreDefVariable nIndex = (PreDefVariable)pNTOIIter->second; 1121 return m_aPreDefVars.m_FixedVar[(sal_Int32)nIndex]; 1122 } 1123 else 1124 { 1125 // Prepare variable name before hash map access 1126 if ( nPos >= 0 ) 1127 { 1128 if ( rVariable.getLength() > 3 ) 1129 aVariable = rVariable.copy( 2, rVariable.getLength() - 3 ); 1130 else 1131 { 1132 rtl::OUString aExceptionText( RTL_CONSTASCII_USTRINGPARAM( "Unknown variable!" )); 1133 throw NoSuchElementException(); 1134 } 1135 } 1136 else 1137 aVariable = rVariable; 1138 1139 // User defined variable 1140 SubstituteVariables::const_iterator pIter = m_aSubstVarMap.find( aVariable ); 1141 if ( pIter != m_aSubstVarMap.end() ) 1142 { 1143 // found! 1144 return pIter->second.aSubstValue; 1145 } 1146 1147 rtl::OUString aExceptionText( RTL_CONSTASCII_USTRINGPARAM( "Unknown variable!" )); 1148 throw NoSuchElementException( aExceptionText, (cppu::OWeakObject *)this ); 1149 } 1150 } 1151 1152 void SubstitutePathVariables::SetPredefinedPathVariables( PredefinedPathVariables& aPreDefPathVariables ) 1153 { 1154 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "SubstitutePathVariables::SetPredefinedPathVariables" ); 1155 Any aAny; 1156 ::rtl::OUString aOfficePath; 1157 ::rtl::OUString aUserPath; 1158 ::rtl::OUString aTmp; 1159 ::rtl::OUString aTmp2; 1160 String aResult; 1161 1162 // Get inspath and userpath from bootstrap mechanism in every case as file URL 1163 ::utl::Bootstrap::PathStatus aState; 1164 ::rtl::OUString sVal ; 1165 1166 aState = utl::Bootstrap::locateBaseInstallation( sVal ); 1167 if( aState==::utl::Bootstrap::PATH_EXISTS ) { 1168 aPreDefPathVariables.m_FixedVar[ PREDEFVAR_INSTPATH ] = ConvertOSLtoUCBURL( sVal ); 1169 } 1170 else { 1171 LOG_ERROR( "SubstitutePathVariables::SetPredefinedPathVariables", "Bootstrap code has no value for instpath!"); 1172 } 1173 1174 aState = utl::Bootstrap::locateUserData( sVal ); 1175 //There can be the valid case that there is no user installation. For example, "unopkg sync" 1176 //is currently (OOo3.4) run as part of the setup. Then no user installation is required. 1177 //Therefore we do not assert here. 1178 if( aState == ::utl::Bootstrap::PATH_EXISTS ) { 1179 aPreDefPathVariables.m_FixedVar[ PREDEFVAR_USERPATH ] = ConvertOSLtoUCBURL( sVal ); 1180 } 1181 1182 // Set $(inst), $(instpath), $(insturl) 1183 aPreDefPathVariables.m_FixedVar[ PREDEFVAR_INSTURL ] = aPreDefPathVariables.m_FixedVar[ PREDEFVAR_INSTPATH ]; 1184 aPreDefPathVariables.m_FixedVar[ PREDEFVAR_INST ] = aPreDefPathVariables.m_FixedVar[ PREDEFVAR_INSTPATH ]; 1185 // --> PB 2004-10-27 #i32656# - new variable of hierachy service 1186 aPreDefPathVariables.m_FixedVar[ PREDEFVAR_BASEINSTURL ]= aPreDefPathVariables.m_FixedVar[ PREDEFVAR_INSTPATH ]; 1187 // <-- 1188 1189 // Set $(user), $(userpath), $(userurl) 1190 aPreDefPathVariables.m_FixedVar[ PREDEFVAR_USERURL ] = aPreDefPathVariables.m_FixedVar[ PREDEFVAR_USERPATH ]; 1191 aPreDefPathVariables.m_FixedVar[ PREDEFVAR_USER ] = aPreDefPathVariables.m_FixedVar[ PREDEFVAR_USERPATH ]; 1192 // --> PB 2004-11-11 #i32656# - new variable of hierachy service 1193 aPreDefPathVariables.m_FixedVar[ PREDEFVAR_USERDATAURL ]= aPreDefPathVariables.m_FixedVar[ PREDEFVAR_USERPATH ]; 1194 // <-- 1195 1196 // Detect the program directory 1197 // Set $(prog), $(progpath), $(progurl) 1198 INetURLObject aProgObj( 1199 aPreDefPathVariables.m_FixedVar[ PREDEFVAR_INSTPATH ] ); 1200 if ( !aProgObj.HasError() && aProgObj.insertName( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("program")) ) ) 1201 { 1202 aPreDefPathVariables.m_FixedVar[ PREDEFVAR_PROGPATH ] = aProgObj.GetMainURL(INetURLObject::NO_DECODE); 1203 aPreDefPathVariables.m_FixedVar[ PREDEFVAR_PROGURL ] = aPreDefPathVariables.m_FixedVar[ PREDEFVAR_PROGPATH ]; 1204 aPreDefPathVariables.m_FixedVar[ PREDEFVAR_PROG ] = aPreDefPathVariables.m_FixedVar[ PREDEFVAR_PROGPATH ]; 1205 } 1206 1207 // Detect the language type of the current office 1208 aPreDefPathVariables.m_eLanguageType = LANGUAGE_ENGLISH_US; 1209 rtl::OUString aLocaleStr; 1210 if ( utl::ConfigManager::GetConfigManager()->GetDirectConfigProperty( utl::ConfigManager::LOCALE ) >>= aLocaleStr ) 1211 aPreDefPathVariables.m_eLanguageType = MsLangId::convertIsoStringToLanguage( aLocaleStr ); 1212 else 1213 { 1214 LOG_ERROR( "SubstitutePathVariables::SetPredefinedPathVariables", "Wrong Any type for language!" ); 1215 } 1216 1217 // Set $(lang) 1218 aPreDefPathVariables.m_FixedVar[ PREDEFVAR_LANG ] = ConvertOSLtoUCBURL( 1219 rtl::OUString::createFromAscii( ResMgr::GetLang( aPreDefPathVariables.m_eLanguageType, 0 ) )); 1220 1221 // Set $(vlang) 1222 aPreDefPathVariables.m_FixedVar[ PREDEFVAR_VLANG ] = aLocaleStr; 1223 1224 // Set $(langid) 1225 aPreDefPathVariables.m_FixedVar[ PREDEFVAR_LANGID ] = rtl::OUString::valueOf( (sal_Int32)aPreDefPathVariables.m_eLanguageType ); 1226 1227 // Set the other pre defined path variables 1228 // Set $(work) 1229 aPreDefPathVariables.m_FixedVar[ PREDEFVAR_WORK ] = GetWorkVariableValue(); 1230 aPreDefPathVariables.m_FixedVar[ PREDEFVAR_HOME ] = GetHomeVariableValue(); 1231 1232 // Set $(workdirurl) this is the value of the path PATH_WORK which doesn't make sense 1233 // anymore because the path settings service has this value! It can deliver this value more 1234 // quickly than the substitution service! 1235 aPreDefPathVariables.m_FixedVar[ PREDEFVAR_WORKDIRURL ] = GetWorkPath(); 1236 1237 // Set $(path) variable 1238 aPreDefPathVariables.m_FixedVar[ PREDEFVAR_PATH ] = GetPathVariableValue(); 1239 1240 // Set $(temp) 1241 osl::FileBase::getTempDirURL( aTmp ); 1242 aPreDefPathVariables.m_FixedVar[ PREDEFVAR_TEMP ] = ConvertOSLtoUCBURL( aTmp ); 1243 1244 aPreDefPathVariables.m_FixedVar[PREDEFVAR_BRANDBASEURL] = rtl::OUString( 1245 RTL_CONSTASCII_USTRINGPARAM("$BRAND_BASE_DIR")); 1246 rtl::Bootstrap::expandMacros( 1247 aPreDefPathVariables.m_FixedVar[PREDEFVAR_BRANDBASEURL]); 1248 } 1249 1250 } // namespace framework 1251