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 hierarchy 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 hierarchy 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 hierarchy 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
GetOperatingSystemFromString(const rtl::OUString & aOSString)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
GetEnvTypeFromString(const rtl::OUString & aEnvTypeString)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
SubstitutePathVariables_Impl(const Link & aNotifyLink)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
~SubstitutePathVariables_Impl()270 SubstitutePathVariables_Impl::~SubstitutePathVariables_Impl()
271 {
272 }
273
GetSharePointsRules(SubstituteVariables & aSubstVarMap)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
Notify(const com::sun::star::uno::Sequence<rtl::OUString> &)310 void SubstitutePathVariables_Impl::Notify( const com::sun::star::uno::Sequence< rtl::OUString >& /*aPropertyNames*/ )
311 {
312 // NOT implemented yet!
313 }
314
Commit()315 void SubstitutePathVariables_Impl::Commit()
316 {
317 }
318
319
320 //_________________________________________________________________________________________________________________
321 // private methods
322 //_________________________________________________________________________________________________________________
323 //
324
GetOperatingSystem()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
GetYPDomainName()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
GetDNSDomainName()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
GetNTDomainName()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
GetHostName()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
FilterRuleSet(const SubstituteRuleVector & aRuleSet,SubstituteRule & aActiveRule)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
ReadSharePointsFromConfiguration(Sequence<rtl::OUString> & aSharePointsSeq)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
ReadSharePointRuleSetFromConfiguration(const rtl::OUString & aSharePointName,const rtl::OUString & aSharePointNodeName,SubstituteRuleVector & rRuleSet)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 //*****************************************************************************************************************
DEFINE_XSERVICEINFO_ONEINSTANCESERVICE(SubstitutePathVariables,::cppu::OWeakObject,SERVICENAME_SUBSTITUTEPATHVARIABLES,IMPLEMENTATIONNAME_SUBSTITUTEPATHVARIABLES)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
~SubstitutePathVariables()655 SubstitutePathVariables::~SubstitutePathVariables()
656 {
657 }
658
659 // XStringSubstitution
substituteVariables(const::rtl::OUString & aText,sal_Bool bSubstRequired)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
reSubstituteVariables(const::rtl::OUString & aText)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
getSubstituteVariableValue(const::rtl::OUString & aVariable)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
IMPL_LINK(SubstitutePathVariables,implts_ConfigurationNotify,SubstitutePathNotify *,EMPTYARG)689 IMPL_LINK( SubstitutePathVariables, implts_ConfigurationNotify, SubstitutePathNotify*, EMPTYARG )
690 {
691 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
692 ResetableGuard aLock( m_aLock );
693
694 return 0;
695 }
696
ConvertOSLtoUCBURL(const rtl::OUString & aOSLCompliantURL) const697 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
GetWorkPath() const713 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
GetWorkVariableValue() const726 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
GetHomeVariableValue() const747 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
GetPathVariableValue() const757 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
impl_substituteVariable(const::rtl::OUString & rText,bool bSubstRequired)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 successful!
961 aResult = aWorkText;
962 }
963 else
964 {
965 // Substitution not successful!
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 unknown!
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
impl_reSubstituteVariables(const::rtl::OUString & rURL)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>".
impl_getSubstituteVariableValue(const::rtl::OUString & rVariable)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
SetPredefinedPathVariables(PredefinedPathVariables & aPreDefPathVariables)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 hierarchy 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 hierarchy 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("$OOO_BASE_DIR"));
1246 rtl::Bootstrap::expandMacros(
1247 aPreDefPathVariables.m_FixedVar[PREDEFVAR_BRANDBASEURL]);
1248 }
1249
1250 } // namespace framework
1251