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