KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > web > php > ScriptEnvironment


1 /*
2  * JBoss, Home of Professional Open Source
3  * Copyright 2006, JBoss Inc., and individual contributors as indicated
4  * by the @authors tag. See the copyright.txt in the distribution for a
5  * full listing of individual contributors.
6  *
7  * This is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * This software is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this software; if not, write to the Free
19  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21  */

22
23 package org.jboss.web.php;
24
25 import java.io.File JavaDoc;
26 import java.io.FileOutputStream JavaDoc;
27 import java.io.IOException JavaDoc;
28 import java.io.InputStream JavaDoc;
29 import java.security.cert.X509Certificate JavaDoc;
30 import java.util.ArrayList JavaDoc;
31 import java.util.Enumeration JavaDoc;
32 import java.util.Hashtable JavaDoc;
33 import java.util.StringTokenizer JavaDoc;
34 import java.util.Vector JavaDoc;
35
36 import javax.servlet.ServletContext JavaDoc;
37 import javax.servlet.http.HttpServletRequest JavaDoc;
38
39 import org.apache.catalina.Globals;
40 import org.apache.catalina.util.IOTools;
41 import org.apache.commons.logging.Log;
42 import org.apache.commons.logging.LogFactory;
43
44
45 /**
46  * Encapsulates the Script Environment and rules to derive
47  * that environment from the servlet container and request information.
48  *
49  * @author Mladen Turk
50  * @version $Revision: 4551 $, $Date: 2006-06-01 19:17:43 +0200 (jeu., 01 juin 2006) $
51  * @since 1.0
52  */

53 public class ScriptEnvironment {
54
55     private static Log log = LogFactory.getLog(ScriptEnvironment.class);
56
57     /**
58      * The Request attribute key for the client certificate chain.
59      */

60     private static final String JavaDoc CERTIFICATE_KEY = "javax.servlet.request.X509Certificate";
61     private static final String JavaDoc CIPHER_SUITE = "javax.servlet.request.cipher_suite";
62     private static final String JavaDoc SSL_SESSION = "javax.servlet.request.ssl_session";
63     private static final String JavaDoc KEY_SIZE = "javax.servlet.request.key_size";
64
65     /** context of the enclosing servlet */
66     private ServletContext JavaDoc context = null;
67
68     /** full path to the script file */
69     private String JavaDoc scriptFullPath = null;
70
71     /** context path of enclosing servlet */
72     private String JavaDoc contextPath = null;
73
74     /** servlet URI of the enclosing servlet */
75     private String JavaDoc servletPath = null;
76
77     /** pathInfo for the current request */
78     private String JavaDoc pathInfo = null;
79
80     /** real file system directory of the enclosing servlet's web app */
81     private String JavaDoc webAppRootDir = null;
82
83     /** tempdir for context - used to expand scripts in unexpanded wars */
84     private File JavaDoc tempDir = null;
85
86     /** derived script environment */
87     private Hashtable JavaDoc env = null;
88
89     /** script's desired working directory */
90     private File JavaDoc workingDirectory = null;
91
92     /** script's desired working directory */
93     private File JavaDoc scriptFile = null;
94
95     /** query parameters */
96     private ArrayList JavaDoc queryParameters = new ArrayList JavaDoc();
97
98     /** whether or not this object is valid or not */
99     private boolean valid = false;
100
101     /** object used to ensure multiple threads don't try to expand same file */
102     private static Object JavaDoc expandFileLock = new Object JavaDoc();
103
104     /**
105      * The Script search path will start at
106      * webAppRootDir + File.separator + scriptPathPrefix
107      * (or webAppRootDir alone if scriptPathPrefix is
108      * null)
109      */

110     private String JavaDoc scriptPathPrefix = null;
111
112     /**
113      * Resolves core information about the php script.
114      *
115      * <p>
116      * Example URI:
117      * <pre> /servlet/scriptGateway/dir1/realScript/pathinfo1 </pre>
118      * <ul>
119      * <li><code>path</code> = $CATALINA_HOME/mywebapp/dir1/realScript
120      * <li><code>scriptName</code> = /servlet/scriptGateway/dir1/realScript
121      * <li><code>fullName</code> = /dir1/realScript
122      * <li><code>name</code> = realScript
123      * </ul>
124      * </p>
125      * <p>
126      * Script search algorithm: search the real path below
127      * &lt;my-webapp-root&gt; and find the first non-directory in
128      * the getPathTranslated("/"), reading/searching from left-to-right.
129      *</p>
130      *<p>
131      * The Script search path will start at
132      * webAppRootDir + File.separator + scriptPathPrefix
133      * (or webAppRootDir alone if scriptPathPrefix is
134      * null).
135      *</p>
136      *<p>
137      * scriptPathPrefix is defined by setting
138      * this servlet's scriptPathPrefix init parameter
139      *
140      *</p>
141      *
142      * @param pathInfo String from HttpServletRequest.getPathInfo()
143      * @param webAppRootDir String from context.getRealPath("/")
144      * @param contextPath String as from
145      * HttpServletRequest.getContextPath()
146      * @param servletPath String as from
147      * HttpServletRequest.getServletPath()
148      * @param scriptPathPrefix Subdirectory of webAppRootDir below which
149      * the web app's Scripts may be stored; can be null.
150      * The Script search path will start at
151      * webAppRootDir + File.separator + scriptPathPrefix
152      * (or webAppRootDir alone if scriptPathPrefix is
153      * null). scriptPathPrefix is defined by setting
154      * the servlet's scriptPathPrefix init parameter.
155      *
156      *
157      * @return
158      * <ul>
159      * <li>
160      * <code>path</code> - full file-system path to valid script file,
161      * or null if no script file was found
162      * <li>
163      * <code>scriptName</code> -
164      * Script variable SCRIPT_NAME; the full URL path
165      * to valid script file or null if no script was
166      * found
167      * <li>
168      * <code>fullName</code> - servlet pathInfo fragment corresponding to
169      * the script itself, or null if not found
170      * <li>
171      * <code>name</code> - simple name (no directories) of the
172      * script, or null if no script was found
173      * </ul>
174      *
175      */

176     protected String JavaDoc[] findScript(String JavaDoc pathInfo, String JavaDoc webAppRootDir,
177                                   String JavaDoc contextPath, String JavaDoc servletPath,
178                                   String JavaDoc scriptPathPrefix)
179     {
180         String JavaDoc path = null;
181         String JavaDoc name = null;
182         String JavaDoc scriptName = null;
183         String JavaDoc fullName = null;
184
185         if ((webAppRootDir != null)
186             && (webAppRootDir.lastIndexOf(File.separator) ==
187                 (webAppRootDir.length() - 1))) {
188                 //strip the trailing "/" from the webAppRootDir
189
webAppRootDir =
190                 webAppRootDir.substring(0, (webAppRootDir.length() - 1));
191         }
192
193         if (scriptPathPrefix != null) {
194             webAppRootDir = webAppRootDir + File.separator
195                 + scriptPathPrefix;
196         }
197         File JavaDoc currentLocation = new File JavaDoc(webAppRootDir);
198         StringTokenizer JavaDoc dirWalker = new StringTokenizer JavaDoc(pathInfo, "/");
199
200         while (!currentLocation.isFile() && dirWalker.hasMoreElements()) {
201             currentLocation = new File JavaDoc(currentLocation,
202                                        (String JavaDoc)dirWalker.nextElement());
203         }
204         if (!currentLocation.isFile()) {
205             return new String JavaDoc[] { null, null, null, null };
206         }
207         else {
208
209             path = currentLocation.getAbsolutePath();
210             name = currentLocation.getName();
211             fullName =
212             currentLocation.getParent().substring(webAppRootDir.length())
213                 + File.separator + name;
214             // NOTE: Original CGI messes the Win path.
215
fullName = fullName.replace(File.separatorChar, '/');
216             if (!fullName.equals(servletPath)) {
217                 if (".".equals(contextPath)) {
218                     scriptName = servletPath + fullName;
219                 }
220                 else {
221                     scriptName = contextPath + servletPath + fullName;
222                 }
223             }
224             else {
225                 // NOTE: set scriptName to fullName
226
scriptName = fullName;
227             }
228
229         }
230
231         return new String JavaDoc[] { path, scriptName, fullName, name };
232     }
233
234     /**
235      * Extracts requested resource from web app archive to context work
236      * directory to enable script to be executed.
237      */

238     protected void expandScript()
239     {
240         StringBuffer JavaDoc srcPath = new StringBuffer JavaDoc();
241         StringBuffer JavaDoc dstPath = new StringBuffer JavaDoc();
242         InputStream JavaDoc is = null;
243
244         // paths depend on mapping
245
if (scriptPathPrefix == null) {
246             srcPath.append(pathInfo);
247             is = context.getResourceAsStream(srcPath.toString());
248             dstPath.append(tempDir);
249             dstPath.append(pathInfo);
250         }
251         else {
252             // essentially same search algorithm as findScript()
253
srcPath.append(scriptPathPrefix);
254             StringTokenizer JavaDoc dirWalker = new StringTokenizer JavaDoc(pathInfo, "/");
255             // start with first element
256
while (dirWalker.hasMoreElements() && (is == null)) {
257                 srcPath.append("/");
258                 srcPath.append(dirWalker.nextElement());
259                 is = context.getResourceAsStream(srcPath.toString());
260             }
261             dstPath.append(tempDir);
262             dstPath.append("/");
263             dstPath.append(srcPath);
264         }
265
266         if (is == null) {
267             // didn't find anything, give up now
268
return;
269         }
270
271         File JavaDoc f = new File JavaDoc(dstPath.toString());
272         if (f.exists()) {
273             // Don't need to expand if it already exists
274
return;
275         }
276
277         // create directories
278
String JavaDoc dirPath = new String JavaDoc(dstPath.toString().substring( 0,
279                                     dstPath.toString().lastIndexOf("/")));
280         File JavaDoc dir = new File JavaDoc(dirPath);
281         dir.mkdirs();
282
283         try {
284             synchronized (expandFileLock) {
285                 // make sure file doesn't exist
286
if (f.exists()) {
287                     return;
288                 }
289
290                 // create file
291
if (!f.createNewFile()) {
292                     return;
293                 }
294                 FileOutputStream JavaDoc fos = new FileOutputStream JavaDoc(f);
295
296                 // copy data
297
IOTools.flow(is, fos);
298                 is.close();
299                 fos.close();
300             }
301         } catch (IOException JavaDoc ioe) {
302             // delete in case file is corrupted
303
if (f.exists()) {
304                 f.delete();
305             }
306         }
307     }
308
309     /**
310      * Constructs the CGI environment to be supplied to the invoked CGI
311      * script; relies heavliy on Servlet API methods and findCGI
312      *
313      * @param req request associated with the CGI
314      * invokation
315      *
316      * @return true if environment was set OK, false if there
317      * was a problem and no environment was set
318      */

319     protected boolean setEnvironment(HttpServletRequest JavaDoc req)
320         throws IOException JavaDoc
321     {
322
323         /*
324          * This method is slightly ugly; c'est la vie.
325          * "You cannot stop [ugliness], you can only hope to contain [it]"
326          * (apologies to Marv Albert regarding MJ)
327          */

328
329         Hashtable JavaDoc envp = new Hashtable JavaDoc();
330
331         // Add the shell environment variables (if any)
332
// envp.putAll(shellEnv);
333

334         // Add the Script environment variables
335
String JavaDoc sPathInfoOrig = null;
336         String JavaDoc sPathTranslatedOrig = null;
337         String JavaDoc sPathInfo = null;
338         String JavaDoc sPathTranslated = null;
339         String JavaDoc sFullPath = null;
340         String JavaDoc sScriptName = null;
341         String JavaDoc sFullName = null;
342         String JavaDoc sName = null;
343         String JavaDoc[] sScriptNames;
344
345
346         sPathInfoOrig = this.pathInfo;
347         sPathInfoOrig = sPathInfoOrig == null ? "" : sPathInfoOrig;
348
349         sPathTranslatedOrig = req.getPathTranslated();
350         sPathTranslatedOrig =
351             sPathTranslatedOrig == null ? "" : sPathTranslatedOrig;
352
353         if (webAppRootDir == null ) {
354             // The app has not been deployed in exploded form
355
webAppRootDir = tempDir.toString();
356             expandScript();
357         }
358
359         sScriptNames = findScript(sPathInfoOrig,
360                                   webAppRootDir,
361                                   contextPath,
362                                   servletPath,
363                                   scriptPathPrefix);
364
365         sFullPath = sScriptNames[0];
366         sScriptName = sScriptNames[1];
367         sFullName = sScriptNames[2];
368         sName = sScriptNames[3];
369
370         if (sFullPath == null
371             || sScriptName == null
372             || sFullName == null
373             || sName == null) {
374             log.error("Invalid script names");
375             return false;
376         }
377
378         envp.put("SERVER_SOFTWARE", "JBossWebServer");
379         envp.put("SERVER_NAME", nullsToBlanks(req.getServerName()));
380         envp.put("GATEWAY_INTERFACE", "CGI/1.1");
381         envp.put("SERVER_PROTOCOL", nullsToBlanks(req.getProtocol()));
382
383         int port = req.getServerPort();
384         Integer JavaDoc sPort = (port == 0 ? new Integer JavaDoc(-1) : new Integer JavaDoc(port));
385         envp.put("SERVER_PORT", sPort.toString());
386
387         /*
388          * Local addres and port
389          */

390         envp.put("LOCAL_NAME", nullsToBlanks(req.getLocalName()));
391         port = req.getLocalPort();
392         Integer JavaDoc iPort = (port == 0 ? new Integer JavaDoc(-1) : new Integer JavaDoc(port));
393         envp.put("LOCAL_PORT", iPort.toString());
394         envp.put("LOCAL_ADDR", nullsToBlanks(req.getLocalAddr()));
395
396         envp.put("REQUEST_METHOD", nullsToBlanks(req.getMethod()));
397
398         /*-
399          * PATH_INFO should be determined by using sFullName:
400          * 1) Let sFullName not end in a "/" (see method findScript)
401          * 2) Let sFullName equal the pathInfo fragment which
402          * corresponds to the actual script.
403          * 3) Thus, PATH_INFO = request.getPathInfo().substring(
404          * sFullName.length())
405          *
406          * (see method findScript, where the real work is done)
407          *
408          */

409         if (pathInfo == null
410             || (pathInfo.substring(sFullName.length()).length() <= 0)) {
411             sPathInfo = "";
412         }
413         else {
414             sPathInfo = pathInfo.substring(sFullName.length());
415         }
416         envp.put("PATH_INFO", sPathInfo);
417
418         /*-
419          * PATH_TRANSLATED must be determined after PATH_INFO (and the
420          * implied real cgi-script) has been taken into account.
421          *
422          * The following example demonstrates:
423          *
424          * servlet info = /servlet/cgigw/dir1/dir2/cgi1/trans1/trans2
425          * cgifullpath = /servlet/cgigw/dir1/dir2/cgi1
426          * path_info = /trans1/trans2
427          * webAppRootDir = servletContext.getRealPath("/")
428          *
429          * path_translated = servletContext.getRealPath("/trans1/trans2")
430          *
431          * That is, PATH_TRANSLATED = webAppRootDir + sPathInfo
432          * (unless sPathInfo is null or blank, then the CGI
433          * specification dictates that the PATH_TRANSLATED metavariable
434          * SHOULD NOT be defined.
435          *
436          */

437         if (sPathInfo != null && !("".equals(sPathInfo))) {
438             sPathTranslated = context.getRealPath(sPathInfo);
439         }
440         else {
441             sPathTranslated = null;
442         }
443         if (sPathTranslated == null || "".equals(sPathTranslated)) {
444             // Nothing.
445
}
446         else {
447             envp.put("PATH_TRANSLATED", nullsToBlanks(sPathTranslated));
448         }
449
450
451         envp.put("SCRIPT_NAME", nullsToBlanks(sScriptName));
452         envp.put("QUERY_STRING", nullsToBlanks(req.getQueryString()));
453         envp.put("REMOTE_HOST", nullsToBlanks(req.getRemoteHost()));
454         envp.put("REMOTE_ADDR", nullsToBlanks(req.getRemoteAddr()));
455         envp.put("AUTH_TYPE", nullsToBlanks(req.getAuthType()));
456         envp.put("REMOTE_USER", nullsToBlanks(req.getRemoteUser()));
457         envp.put("REMOTE_IDENT", ""); //not necessary for full compliance
458
envp.put("CONTENT_TYPE", nullsToBlanks(req.getContentType()));
459
460
461         /* Note CGI spec says CONTENT_LENGTH must be NULL ("") or undefined
462          * if there is no content, so we cannot put 0 or -1 in as per the
463          * Servlet API spec.
464          */

465         int contentLength = req.getContentLength();
466         String JavaDoc sContentLength = (contentLength <= 0 ? "" :
467                                  (new Integer JavaDoc(contentLength)).toString());
468         envp.put("CONTENT_LENGTH", sContentLength);
469
470
471         Enumeration JavaDoc headers = req.getHeaderNames();
472         String JavaDoc header = null;
473
474         while (headers.hasMoreElements()) {
475             header = null;
476             header = ((String JavaDoc)headers.nextElement()).toUpperCase();
477             //REMIND: rewrite multiple headers as if received as single
478
//REMIND: change character set
479
//REMIND: I forgot what the previous REMIND means
480
if ("AUTHORIZATION".equalsIgnoreCase(header) ||
481                 "PROXY_AUTHORIZATION".equalsIgnoreCase(header)) {
482                 //NOOP per CGI specification section 11.2
483
}
484             else {
485                 envp.put("HTTP_" + header.replace('-', '_'),
486                          req.getHeader(header));
487             }
488         }
489
490         scriptFile = new File JavaDoc(sFullPath);
491         scriptFullPath = scriptFile.getCanonicalPath();
492         workingDirectory = new File JavaDoc(scriptFullPath.substring(0,
493                                 scriptFullPath.lastIndexOf(File.separator)));
494
495         envp.put("SCRIPT_FILENAME", scriptFullPath);
496         envp.put("PHP_SELF", nullsToBlanks(sFullName));
497
498         if (req.isSecure()) {
499             envp.put("HTTPS", "ON");
500             envp.put("SSL_CIPHER", req.getAttribute(CIPHER_SUITE));
501             envp.put("SSL_SESSION_ID", req.getAttribute(SSL_SESSION));
502             envp.put("SSL_CIPHER_USEKEYSIZE", String.valueOf(req.getAttribute(KEY_SIZE)));
503             X509Certificate JavaDoc[] certs =
504                 (X509Certificate JavaDoc[])req.getAttribute(CERTIFICATE_KEY);
505             if (certs != null) {
506                 // Well use the first, normaly the client certificate.
507
envp.put("SSL_SERVER_V_START", certs[0].getNotAfter().toString());
508                 envp.put("SSL_SERVER_V_END", certs[0].getNotBefore().toString());
509                 
510                 envp.put("SSL_CLIENT_A_KEY", certs[0].getSigAlgName());
511                 
512                 // Oops getEncoded gives a DER not PEM encoded ... envp.put("SSL_CLIENT_CERT", certs[0].getEncoded());
513

514                 envp.put("SSL_SERVER_M_SERIAL", certs[0].getSerialNumber().toString());
515                 envp.put("SSL_SERVER_M_VERSION", String.valueOf(certs[0].getVersion()));
516
517                 // Subject
518
envp.put("SSL_CLIENT_S_DN", certs[0].getSubjectX500Principal().getName());
519                 // To fill the elements C,ST... Email
520
String JavaDoc pr = certs[0].getSubjectX500Principal().getName();
521                 String JavaDoc prs[] = pr.split(", ");
522                 for (int c = 0; c < prs.length; c++) {
523                     String JavaDoc pprs[] = prs[c].split("=");
524                     envp.put("SSL_CLIENT_S_DN_" + pprs[0], pprs[1]);
525                 }
526
527                 // Issuer
528
envp.put("SSL_CLIENT_I_DN", certs[0].getIssuerX500Principal().getName());
529                 // To fill the elements C,ST... Email Still to TODO.
530
pr = certs[0].getSubjectX500Principal().getName();
531                 prs = pr.split(", ");
532                 for (int c = 0; c < prs.length; c++) {
533                     String JavaDoc pprs[] = prs[c].split("=");
534                     envp.put("SSL_CLIENT_I_DN_" + pprs[0], pprs[1]);
535                 }
536
537
538                 // envp.put("CERT_ISSUER",
539
// nullsToBlanks(certs[c].getIssuerX500Principal().getName()));
540
}
541         }
542
543         this.env = envp;
544         return true;
545     }
546
547
548     /**
549      * Creates a CGIEnvironment and derives the necessary environment,
550      * query parameters, working directory, cgi command, etc.
551      *
552      * @param req HttpServletRequest for information provided by
553      * the Servlet API
554      * @param context ServletContext for information provided by the
555      * Servlet API
556      *
557      */

558     public ScriptEnvironment(HttpServletRequest JavaDoc req,
559                              ServletContext JavaDoc context,
560                              String JavaDoc scriptPathPrefix)
561         throws IOException JavaDoc
562     {
563         this.scriptPathPrefix = scriptPathPrefix;
564         this.context = context;
565         this.webAppRootDir = context.getRealPath("/");
566         this.tempDir = (File JavaDoc)context.getAttribute(Globals.WORK_DIR_ATTR);
567         this.contextPath = req.getContextPath();
568         this.servletPath = req.getServletPath();
569         this.pathInfo = req.getPathInfo();
570         // If getPathInfo() returns null, must be using extension mapping
571
// In this case, pathInfo should be same as servletPath
572
if (this.pathInfo == null) {
573             this.pathInfo = this.servletPath;
574         }
575         this.valid = setEnvironment(req);
576     }
577
578
579     /**
580      * Gets derived script full path
581      *
582      * @return full script path
583      *
584      */

585     public String JavaDoc getFullPath()
586     {
587         return scriptFullPath;
588     }
589
590     /**
591      * Gets derived Script file
592      *
593      * @return Script file
594      *
595      */

596     public File JavaDoc getScriptFile()
597     {
598         return scriptFile;
599     }
600
601     /**
602      * Gets derived Script working directory
603      *
604      * @return working directory
605      *
606      */

607     public File JavaDoc getWorkingDirectory()
608     {
609         return workingDirectory;
610     }
611
612     /**
613      * Gets derived Script environment
614      *
615      * @return Script environment
616      *
617      */

618     public Hashtable JavaDoc getEnvironment()
619     {
620         return env;
621     }
622
623     /**
624      * Gets derived Script query parameters
625      *
626      * @return Script query parameters
627      *
628      */

629     public ArrayList JavaDoc getParameters()
630     {
631         return queryParameters;
632     }
633
634     /**
635      * Gets validity status
636      *
637      * @return true if this environment is valid, false
638      * otherwise
639      *
640      */

641     public boolean isValid()
642     {
643         return valid;
644     }
645
646     /**
647      * Converts null strings to blank strings ("")
648      *
649      * @param s string to be converted if necessary
650      * @return a non-null string, either the original or the empty string
651      * ("") if the original was <code>null</code>
652      */

653     protected String JavaDoc nullsToBlanks(String JavaDoc s)
654     {
655         return nullsToString(s, "");
656     }
657
658     /**
659      * Converts null strings to another string
660      *
661      * @param couldBeNull string to be converted if necessary
662      * @param subForNulls string to return instead of a null string
663      * @return a non-null string, either the original or the substitute
664      * string if the original was <code>null</code>
665      */

666     protected String JavaDoc nullsToString(String JavaDoc couldBeNull,
667                                    String JavaDoc subForNulls)
668     {
669         return (couldBeNull == null ? subForNulls : couldBeNull);
670     }
671
672     /**
673      * Converts blank strings to another string
674      *
675      * @param couldBeBlank string to be converted if necessary
676      * @param subForBlanks string to return instead of a blank string
677      * @return a non-null string, either the original or the substitute
678      * string if the original was <code>null</code> or empty ("")
679      */

680     protected String JavaDoc blanksToString(String JavaDoc couldBeBlank,
681                                     String JavaDoc subForBlanks)
682     {
683         return (("".equals(couldBeBlank) || couldBeBlank == null)
684                 ? subForBlanks
685                 : couldBeBlank);
686     }
687
688     /**
689      * Converts Environment Hastable to String array
690      *
691      * @return Srring array containing name value pairs.
692      * @exception NullPointerException if a hash key has a null value
693      */

694     public String JavaDoc[] getEnvironmentArray()
695         throws NullPointerException JavaDoc
696     {
697         return hashToStringArray(env);
698     }
699
700     /**
701      * Converts a Hashtable to a String array by converting each
702      * key/value pair in the Hashtable to two consecutive Strings
703      *
704      * @param h Hashtable to convert
705      * @return converted string array
706      * @exception NullPointerException if a hash key has a null value
707      */

708     public static String JavaDoc[] hashToStringArray(Hashtable JavaDoc h)
709         throws NullPointerException JavaDoc
710     {
711         Vector JavaDoc v = new Vector JavaDoc();
712         Enumeration JavaDoc e = h.keys();
713         while (e.hasMoreElements()) {
714             String JavaDoc k = e.nextElement().toString();
715             v.add(k);
716             v.add(h.get(k));
717         }
718         String JavaDoc[] strArr = new String JavaDoc[v.size()];
719         v.copyInto(strArr);
720         return strArr;
721     }
722
723 }
724
Popular Tags