KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > util > env > Env


1 /*
2  * Copyright 2004 Apache Software Foundation
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12  * implied.
13  *
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 package org.apache.avalon.util.env ;
19
20
21 import java.io.File JavaDoc ;
22 import java.io.IOException JavaDoc ;
23 import java.io.BufferedReader JavaDoc ;
24 import java.io.InputStreamReader JavaDoc ;
25
26 import java.util.Properties JavaDoc ;
27 import java.util.Enumeration JavaDoc ;
28
29
30 /**
31  * Encapsulates operating system and shell specific access to environment
32  * variables.
33  *
34  * TODO cleanup exception handling which is now in an odd state (constructors)
35  * need to be added and or changed.
36  *
37  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
38  * @version $Revision: 1.8 $
39  */

40 public class Env extends Properties JavaDoc
41 {
42     /** os.name System property */
43     public static final String JavaDoc OSNAME = System.getProperty( "os.name" ) ;
44     /** user.name System property */
45     public static final String JavaDoc USERNAME = System.getProperty( "user.name" ) ;
46
47     /** the user's platform specific shell executable */
48     private static String JavaDoc s_shell = null ;
49     /** the last Env instance created */
50     private static Env s_lastEnv = null ;
51     
52
53     /**
54      * Creates a snapshot of the current shell environment variables for a user.
55      *
56      * @throws EnvAccessException if there is an error accessing the environment
57      */

58     public Env() throws EnvAccessException
59     {
60         Properties JavaDoc l_props = getEnvVariables() ;
61         Enumeration JavaDoc l_list = l_props.propertyNames() ;
62         
63         while ( l_list.hasMoreElements() )
64         {
65             String JavaDoc l_key = ( String JavaDoc ) l_list.nextElement() ;
66             setProperty( l_key, l_props.getProperty( l_key ) ) ;
67         }
68
69     s_lastEnv = this ;
70     }
71
72
73     /**
74      * Gets a copy of the last Env instance without parsing the user's shell
75      * environment. Use this method if you do not want to reparse the
76      * environment every time an environment variable is accessed. If an
77      * environment has not been created yet one is created then cloned
78      * and a copy is returned instead of returning null.
79      *
80      * @return a copy of the last Env object created
81      */

82     Env getLastEnv() throws EnvAccessException
83     {
84         if ( s_lastEnv == null )
85         {
86             s_lastEnv = new Env() ;
87         }
88
89         // return cloned copy so there is no cross interference
90
return ( Env ) s_lastEnv.clone() ;
91     }
92     
93
94     /**
95      * Gets the value of a shell environment variable.
96      *
97      * @param a_name the name of variable
98      * @return the String representation of an environment variable value
99      * @throws Exception if there is a problem accessing the environment
100      */

101     public static String JavaDoc getEnvVariable( String JavaDoc a_name )
102         throws EnvAccessException
103     {
104         String JavaDoc l_osName = System.getProperty( "os.name" ) ;
105         
106         if ( isUnix() )
107         {
108             Properties JavaDoc l_props = getUnixShellVariables() ;
109             return l_props.getProperty( a_name ) ;
110         }
111         else if ( -1 != l_osName.indexOf( "Windows" ) )
112         {
113               if ( null == s_shell )
114               {
115                 if ( -1 != l_osName.indexOf( "98" ) ||
116                   -1 != l_osName.indexOf( "95" ) )
117                 {
118                     s_shell = "command.exe" ;
119                 }
120                 else
121                 {
122                     s_shell = "cmd.exe" ;
123                 }
124               }
125             return getWindowsShellVariable( a_name ) ;
126         }
127         
128         throw new EnvAccessException( a_name,
129             "Unrecognized operating system: " + l_osName ) ;
130     }
131
132     
133     /**
134      * Checks to see if the operating system is a UNIX variant.
135      *
136      * @return true of the OS is a UNIX variant, false otherwise
137      */

138     public static boolean isUnix()
139     {
140         if ( -1 != OSNAME.indexOf( "Linux" ) ||
141              -1 != OSNAME.indexOf( "SunOS" ) ||
142              -1 != OSNAME.indexOf( "Solaris" ) ||
143              -1 != OSNAME.indexOf( "MPE/iX" ) ||
144              -1 != OSNAME.indexOf( "AIX" ) ||
145              -1 != OSNAME.indexOf( "FreeBSD" ) ||
146              -1 != OSNAME.indexOf( "Irix" ) ||
147              -1 != OSNAME.indexOf( "Digital Unix" ) ||
148              -1 != OSNAME.indexOf( "HP-UX" ) ||
149              -1 != OSNAME.indexOf( "Mac OS X" ) )
150         {
151             return true ;
152         }
153         
154         return false ;
155     }
156     
157     
158     /**
159      * Checks to see if the operating system is a Windows variant.
160      *
161      * @return true of the OS is a Windows variant, false otherwise
162      */

163     public static boolean isWindows()
164     {
165         if ( -1 != OSNAME.indexOf( "Windows" ) )
166         {
167             return true ;
168         }
169         
170         return false ;
171     }
172     
173     /**
174      * Checks to see if the operating system is NetWare.
175      *
176      * @return true of the OS is NetWare, false otherwise
177      */

178     public static boolean isNetWare()
179     {
180         if ( -1 != OSNAME.indexOf( "netware" ) )
181         {
182             return true ;
183         }
184         
185         return false ;
186     }
187     
188     /**
189      * Checks to see if the operating system is OpenVMS.
190      *
191      * @return true of the OS is a NetWare variant, false otherwise
192      */

193     public static boolean isOpenVMS()
194     {
195         if ( -1 != OSNAME.indexOf( "openvms" ) )
196         {
197             return true ;
198         }
199         
200         return false ;
201     }
202     
203     /**
204      * Gets all environment variables within a Properties instance where the
205      * key is the environment variable name and value is the value of the
206      * property.
207      *
208      * @return the environment variables and values as Properties
209      */

210     public static Properties JavaDoc getEnvVariables() throws EnvAccessException
211     {
212         if ( isUnix() )
213         {
214             return getUnixShellVariables() ;
215         }
216         
217         if ( isWindows() )
218         {
219             return getWindowsShellVariables() ;
220         }
221         
222         throw new EnvAccessException(
223             new UnsupportedOperationException JavaDoc( "Environment operations not "
224             + "supported on unrecognized operatings system" ) ) ;
225     }
226
227     
228     /**
229      * Gets the user's shell executable.
230      *
231      * @return the shell executable for the user
232      * @throws EnvAccessException the there is a problem accessing shell
233      * information
234      */

235     public static String JavaDoc getUserShell() throws EnvAccessException
236     {
237         if ( -1 != OSNAME.indexOf( "Mac OS X" ) )
238         {
239             return getMacUserShell() ;
240         }
241         
242         /*
243         if ( isUnix() )
244         {
245             return getUnixUserShell() ;
246         }
247         */

248         
249         if ( isWindows() )
250         {
251             return getWindowsUserShell() ;
252         }
253         
254         throw new EnvAccessException(
255             new UnsupportedOperationException JavaDoc( "Environment operations not "
256                 + "supported on unrecognized operatings system" ) ) ;
257     }
258
259
260     // ------------------------------------------------------------------------
261
// Private UNIX Shell Operations
262
// ------------------------------------------------------------------------
263

264     
265     /**
266      * Gets the default login shell used by a mac user.
267      *
268      * @return the Mac user's default shell as referenced by cmd:
269      * 'nidump passwd /'
270      */

271     private static String JavaDoc getMacUserShell() throws EnvAccessException
272     {
273         Process JavaDoc l_proc = null ;
274         BufferedReader JavaDoc l_in = null ;
275         
276         if ( null != s_shell )
277         {
278             return s_shell ;
279         }
280
281         try
282         {
283             String JavaDoc l_entry = null ;
284             String JavaDoc [] l_args = { "nidump", "passwd", "/" } ;
285             l_proc = Runtime.getRuntime().exec( l_args ) ;
286             l_in = new BufferedReader JavaDoc(
287                     new InputStreamReader JavaDoc( l_proc.getInputStream() ) ) ;
288             
289             while ( null != ( l_entry = l_in.readLine() ) )
290             {
291                 // Skip entries other than the one for this username
292
if ( ! l_entry.startsWith( USERNAME ) )
293                 {
294                     continue ;
295                 }
296         
297                 // Get the shell part of the passwd entry
298
int l_index = l_entry.lastIndexOf( ':' ) ;
299
300                 if ( l_index == -1 )
301                 {
302                     throw new EnvAccessException(
303                         "passwd database contains malformed user entry for "
304                         + USERNAME ) ;
305                 }
306         
307                 s_shell = l_entry.substring( l_index + 1 ) ;
308                 return s_shell ;
309             }
310             
311             l_proc.waitFor() ;
312             l_in.close() ;
313         }
314         catch( Throwable JavaDoc t )
315         {
316             t.printStackTrace() ;
317             throw new EnvAccessException( t ) ;
318         }
319         finally
320         {
321             if ( l_proc != null )
322             {
323                 l_proc.destroy() ;
324             }
325             
326             try
327             {
328                 if ( null != l_in )
329                 {
330                     l_in.close() ;
331                 }
332             }
333             catch( IOException JavaDoc e )
334             {
335                 // do nothing
336
}
337         }
338         
339         throw new EnvAccessException( "User " + USERNAME
340             + " does not seem to exist in the passwd database" ) ;
341     }
342     
343     
344     /**
345      * Adds a set of Windows variables to a set of properties.
346      */

347     private static Properties JavaDoc getUnixShellVariables()
348         throws EnvAccessException
349     {
350         Process JavaDoc l_proc = null ;
351         Properties JavaDoc l_props = new Properties JavaDoc() ;
352
353         // Read from process here
354
BufferedReader JavaDoc l_in = null ;
355     
356         // fire up the shell and get echo'd results on stdout
357
try
358         {
359             String JavaDoc [] l_args = { getUnixEnv() } ;
360             l_proc = Runtime.getRuntime().exec( l_args ) ;
361             l_in = new BufferedReader JavaDoc(
362                     new InputStreamReader JavaDoc( l_proc.getInputStream() ) ) ;
363             
364             String JavaDoc l_line = null ;
365             while ( null != ( l_line = l_in.readLine() ) )
366             {
367                 int l_idx = l_line.indexOf( '=') ;
368                 
369                 if ( -1 == l_idx )
370                 {
371                     if( l_line.length()!=0)
372                     {
373                         System.err.println(
374                           "Skipping line - could not find '=' in"
375                           + " line: '" + l_line + "'" );
376                     }
377                     continue ;
378                 }
379                 
380                 String JavaDoc l_name = l_line.substring( 0, l_idx ) ;
381                 String JavaDoc l_value = l_line.substring( l_idx + 1, l_line.length() );
382                 l_props.setProperty( l_name, l_value ) ;
383             }
384             
385             l_proc.waitFor() ;
386             l_in.close() ;
387         }
388         catch( Throwable JavaDoc t )
389         {
390             throw new EnvAccessException( "NA", t ) ;
391         }
392         finally
393         {
394             l_proc.destroy() ;
395             
396             try
397             {
398                 if ( null != l_in )
399                 {
400                     l_in.close() ;
401                 }
402             }
403             catch( IOException JavaDoc e )
404             {
405             }
406         }
407         
408         // Check that we exited normally before returning an invalid output
409
if ( 0 != l_proc.exitValue() )
410         {
411             throw new EnvAccessException(
412               "Environment process failed "
413               + " with non-zero exit code of "
414               + l_proc.exitValue() ) ;
415         }
416         
417         return l_props ;
418     }
419     
420     
421     /**
422      * Gets the UNIX env executable path.
423      *
424      * @return the absolute path to the env program
425      * @throws EnvAccessException if it cannot be found
426      */

427     private static String JavaDoc getUnixEnv() throws EnvAccessException
428     {
429         File JavaDoc l_env = new File JavaDoc( "/bin/env" ) ;
430         
431         if( l_env.exists() && l_env.canRead() && l_env.isFile() )
432         {
433             return l_env.getAbsolutePath() ;
434         }
435         
436         l_env = new File JavaDoc( "/usr/bin/env" ) ;
437         if ( l_env.exists() && l_env.canRead() && l_env.isFile() )
438         {
439             return l_env.getAbsolutePath() ;
440         }
441         
442         throw new EnvAccessException(
443                 "Could not find the UNIX env executable" ) ;
444     }
445     
446     
447     // ------------------------------------------------------------------------
448
// Private Windows Shell Operations
449
// ------------------------------------------------------------------------
450

451     
452     /**
453      * Gets the shell used by the Windows user.
454      *
455      * @return the shell: cmd.exe or command.exe.
456      */

457     private static String JavaDoc getWindowsUserShell()
458     {
459         if ( null != s_shell )
460         {
461             return s_shell ;
462         }
463         
464         if ( -1 != OSNAME.indexOf( "98" ) || -1 != OSNAME.indexOf( "95" ) )
465         {
466             s_shell = "command.exe" ;
467             return s_shell ;
468         }
469
470         s_shell = "cmd.exe" ;
471         return s_shell ;
472     }
473     
474     
475     /**
476      * Adds a set of Windows variables to a set of properties.
477      */

478     private static Properties JavaDoc getWindowsShellVariables()
479         throws EnvAccessException
480     {
481         String JavaDoc l_line = null ;
482         Process JavaDoc l_proc = null ;
483         BufferedReader JavaDoc l_in = null ;
484         Properties JavaDoc l_props = new Properties JavaDoc() ;
485         StringBuffer JavaDoc l_cmd = new StringBuffer JavaDoc() ;
486
487         // build the command based on the shell used: cmd.exe or command.exe
488
if ( -1 != OSNAME.indexOf( "98" ) || -1 != OSNAME.indexOf( "95" ) )
489         {
490             l_cmd.append( "command.exe /C SET" ) ;
491         }
492         else
493         {
494             l_cmd.append( "cmd.exe /C SET" ) ;
495         }
496         
497         // fire up the shell and get echo'd results on stdout
498
try
499         {
500             l_proc = Runtime.getRuntime().exec( l_cmd.toString() ) ;
501             l_in = new BufferedReader JavaDoc(
502                     new InputStreamReader JavaDoc( l_proc.getInputStream() ) ) ;
503             while ( null != ( l_line = l_in.readLine() ) )
504             {
505                 int l_idx = l_line.indexOf( '=') ;
506                 
507                 if ( -1 == l_idx )
508                 {
509                     System.err.println( "Skipping line - could not find '=' in"
510                             + " line: '" + l_line + "'" ) ;
511                     continue ;
512                 }
513                 
514                 String JavaDoc l_name = l_line.substring( 0, l_idx ) ;
515                 String JavaDoc l_value = l_line.substring( l_idx + 1, l_line.length() );
516                 l_props.setProperty( l_name, l_value ) ;
517             }
518             
519             l_proc.waitFor() ;
520             l_in.close() ;
521         }
522         catch( Throwable JavaDoc t )
523         {
524             t.printStackTrace() ;
525             throw new EnvAccessException( t ) ;
526         }
527         finally
528         {
529             l_proc.destroy() ;
530             
531             try
532             {
533                 if ( null != l_in )
534                 {
535                     l_in.close() ;
536                 }
537             }
538             catch( IOException JavaDoc e )
539             {
540                 
541             }
542         }
543         
544         if ( 0 != l_proc.exitValue() )
545         {
546             throw new EnvAccessException( "Environment process failed"
547                     + " with non-zero exit code of " + l_proc.exitValue() ) ;
548         }
549         
550         return l_props ;
551     }
552
553
554     /**
555      * Gets the value for a windows command shell environment variable.
556      *
557      * @param a_name the name of the variable
558      * @return the value of the variable
559      * @throws EnvAccessException if there is an error accessing the value
560      */

561     private static String JavaDoc getWindowsShellVariable( String JavaDoc a_name )
562         throws EnvAccessException
563     {
564         String JavaDoc l_value = null ;
565         Process JavaDoc l_proc = null ;
566         BufferedReader JavaDoc l_in = null ;
567
568         StringBuffer JavaDoc l_cmd = new StringBuffer JavaDoc( getWindowsUserShell() ) ;
569         l_cmd.append( " /C echo %" ) ;
570         l_cmd.append( a_name ) ;
571         l_cmd.append( '%' ) ;
572
573         // fire up the shell and get echo'd results on stdout
574
try
575         {
576             l_proc = Runtime.getRuntime().exec( l_cmd.toString() ) ;
577             l_in = new BufferedReader JavaDoc(
578                     new InputStreamReader JavaDoc( l_proc.getInputStream() ) ) ;
579             l_value = l_in.readLine() ;
580             l_proc.waitFor() ;
581             l_in.close() ;
582         }
583         catch( Throwable JavaDoc t )
584         {
585             throw new EnvAccessException( a_name, t ) ;
586         }
587         finally
588         {
589             l_proc.destroy() ;
590             
591             try
592             {
593                 if ( null != l_in )
594                 {
595                     l_in.close() ;
596                 }
597             }
598             catch( IOException JavaDoc e )
599             {
600                 // ignore
601
}
602         }
603         
604         if ( 0 == l_proc.exitValue() )
605         {
606             // Handle situations where the env property does not exist.
607
if ( l_value.startsWith( "%") && l_value.endsWith( "%" ) )
608             {
609                 return null ;
610             }
611             
612             return l_value ;
613         }
614         
615         throw new EnvAccessException(
616           a_name,
617           "Environment process failed"
618             + " with non-zero exit code of "
619             + l_proc.exitValue() ) ;
620     }
621 }
622
Popular Tags