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