KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > quercus > env > Env


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.quercus.env;
31
32 import com.caucho.quercus.*;
33 import com.caucho.quercus.expr.Expr;
34 import com.caucho.quercus.function.Marshal;
35 import com.caucho.quercus.function.MarshalFactory;
36 import com.caucho.quercus.lib.VariableModule;
37 import com.caucho.quercus.lib.string.StringModule;
38 import com.caucho.quercus.module.ModuleContext;
39 import com.caucho.quercus.module.ModuleStartupListener;
40 import com.caucho.quercus.page.QuercusPage;
41 import com.caucho.quercus.program.AbstractFunction;
42 import com.caucho.quercus.program.ClassDef;
43 import com.caucho.quercus.program.JavaClassDef;
44 import com.caucho.quercus.program.QuercusProgram;
45 import com.caucho.quercus.resources.StreamContextResource;
46 import com.caucho.util.Alarm;
47 import com.caucho.util.IntMap;
48 import com.caucho.util.L10N;
49 import com.caucho.util.LruCache;
50 import com.caucho.vfs.ByteToChar;
51 import com.caucho.vfs.Path;
52 import com.caucho.vfs.ReadStream;
53 import com.caucho.vfs.WriteStream;
54
55 import javax.script.ScriptContext;
56 import javax.servlet.http.Cookie JavaDoc;
57 import javax.servlet.http.HttpServletRequest JavaDoc;
58 import javax.servlet.http.HttpServletResponse JavaDoc;
59 import javax.servlet.http.HttpSession JavaDoc;
60 import javax.sql.DataSource JavaDoc;
61 import java.io.Closeable JavaDoc;
62 import java.io.IOException JavaDoc;
63 import java.lang.ref.SoftReference JavaDoc;
64 import java.lang.ref.WeakReference JavaDoc;
65 import java.lang.reflect.Array JavaDoc;
66 import java.sql.Connection JavaDoc;
67 import java.util.ArrayList JavaDoc;
68 import java.util.Collections JavaDoc;
69 import java.util.HashMap JavaDoc;
70 import java.util.HashSet JavaDoc;
71 import java.util.Map JavaDoc;
72 import java.util.logging.Level JavaDoc;
73 import java.util.logging.Logger JavaDoc;
74
75 /**
76  * Represents the Quercus environment.
77  */

78 public class Env {
79   private static final L10N L = new L10N(Env.class);
80   private static final Logger JavaDoc log
81     = Logger.getLogger(Env.class.getName());
82
83   public static final int B_ERROR = 0;
84   public static final int B_WARNING = 1;
85   public static final int B_PARSE = 2;
86   public static final int B_NOTICE = 3;
87   public static final int B_CORE_ERROR = 4;
88   public static final int B_CORE_WARNING = 5;
89   public static final int B_COMPILE_ERROR = 6;
90   public static final int B_COMPILE_WARNING = 7;
91   public static final int B_USER_ERROR = 8;
92   public static final int B_USER_WARNING = 9;
93   public static final int B_USER_NOTICE = 10;
94   public static final int B_STRICT = 11;
95
96   public static final int E_ERROR = 1 << B_ERROR;
97   public static final int E_WARNING = 1 << B_WARNING;
98   public static final int E_PARSE = 1 << B_PARSE;
99   public static final int E_NOTICE = 1 << B_NOTICE;
100   public static final int E_CORE_ERROR = 1 << B_CORE_ERROR;
101   public static final int E_CORE_WARNING = 1 << B_CORE_WARNING;
102   public static final int E_COMPILE_ERROR = 1 << B_COMPILE_ERROR;
103   public static final int E_COMPILE_WARNING = 1 << B_COMPILE_WARNING;
104   public static final int E_USER_ERROR = 1 << B_USER_ERROR;
105   public static final int E_USER_WARNING = 1 << B_USER_WARNING;
106   public static final int E_USER_NOTICE = 1 << B_USER_NOTICE;
107   public static final int E_ALL = 2048 - 1;
108   public static final int E_STRICT = 1 << B_STRICT;
109
110   public static final int E_DEFAULT = E_ALL & ~E_NOTICE;
111
112   private static final int _SERVER = 1;
113   private static final int _GET = 2;
114   private static final int _POST = 3;
115   private static final int _COOKIE = 4;
116   private static final int _GLOBAL = 5;
117   private static final int _REQUEST = 6;
118   private static final int _SESSION = 7;
119   private static final int HTTP_GET_VARS = 8;
120   private static final int HTTP_POST_VARS = 9;
121   private static final int HTTP_COOKIE_VARS = 10;
122   private static final int PHP_SELF = 11;
123   private static final int _FILES = 12;
124   private static final int HTTP_POST_FILES = 13;
125   private static final int _ENV = 14;
126   private static final int HTTP_SERVER_VARS = 15;
127
128   private static final IntMap SPECIAL_VARS = new IntMap();
129
130   private static final StringValue PHP_SELF_STRING
131     = new StringValueImpl("PHP_SELF");
132
133   private static final StringValue UTF8_STRING
134     = new StringValueImpl("utf-8");
135
136   private static final
137     LruCache<ClassKey,SoftReference JavaDoc<QuercusClass>> _classCache
138     = new LruCache<ClassKey,SoftReference JavaDoc<QuercusClass>>(4096);
139
140   private static final
141     LruCache<IncludeKey,SoftReference JavaDoc<IncludeCache>> _includeCache
142     = new LruCache<IncludeKey,SoftReference JavaDoc<IncludeCache>>(4096);
143
144   private static ThreadLocal JavaDoc<Env> _env = new ThreadLocal JavaDoc<Env>();
145
146   protected Quercus _quercus;
147   private QuercusPage _page;
148
149   private Value _this = NullThisValue.NULL;
150
151   private ArrayList JavaDoc<SoftReference JavaDoc<Closeable JavaDoc>> _closeList
152     = new ArrayList JavaDoc<SoftReference JavaDoc<Closeable JavaDoc>>();
153   
154   private ArrayList JavaDoc<Shutdown JavaDoc> _shutdownList
155     = new ArrayList JavaDoc<Shutdown JavaDoc>();
156
157   private HashMap JavaDoc<String JavaDoc, Var> _globalMap
158     = new HashMap JavaDoc<String JavaDoc, Var>(1024);
159   
160   private HashMap JavaDoc<String JavaDoc, Var> _staticMap
161     = new HashMap JavaDoc<String JavaDoc, Var>();
162   
163   private HashMap JavaDoc<String JavaDoc, Var> _map = _globalMap;
164
165   private DefinitionState _defState;
166
167   private HashMap JavaDoc<String JavaDoc, Value> _constMap
168     = new HashMap JavaDoc<String JavaDoc, Value>(1024);
169
170   private HashMap JavaDoc<String JavaDoc, Value> _lowerConstMap
171     = new HashMap JavaDoc<String JavaDoc, Value>(1024);
172
173   /*
174   private HashMap<String, AbstractFunction> _funMap
175     = new HashMap<String, AbstractFunction>(8192, 0.5F);
176
177   private HashMap<String, AbstractFunction> _lowerFunMap
178     = new HashMap<String, AbstractFunction>(8192, 0.5F);
179   */

180
181   /*
182   private HashMap<String, ClassDef> _classDefMap
183     = new HashMap<String, ClassDef>();
184
185   private HashMap<String, ClassDef> _lowerClassDefMap
186     = new HashMap<String, ClassDef>();
187   */

188
189   private HashMap JavaDoc<String JavaDoc, QuercusClass> _classMap
190     = new HashMap JavaDoc<String JavaDoc, QuercusClass>();
191
192   private HashMap JavaDoc<String JavaDoc, QuercusClass> _lowerClassMap
193     = new HashMap JavaDoc<String JavaDoc, QuercusClass>();
194
195   private HashMap JavaDoc<String JavaDoc, StringValue> _iniMap;
196
197   // specialMap is used for implicit resources like the mysql link
198
private HashMap JavaDoc<String JavaDoc, Object JavaDoc> _specialMap
199     = new HashMap JavaDoc<String JavaDoc, Object JavaDoc>();
200
201   private String JavaDoc _prevIncludePath = ".";
202   private String JavaDoc _includePath;
203   private ArrayList JavaDoc<String JavaDoc> _includePathList;
204   private HashMap JavaDoc<Path,ArrayList JavaDoc<Path>> _includePathMap;
205
206   private HashSet JavaDoc<Path> _includeSet = new HashSet JavaDoc<Path>();
207   
208   private HashMap JavaDoc<StringValue,Path> _lookupCache
209     = new HashMap JavaDoc<StringValue,Path>();
210
211   private HashMap JavaDoc<ConnectionEntry,ConnectionEntry> _connMap
212     = new HashMap JavaDoc<ConnectionEntry,ConnectionEntry>();
213
214   private AbstractFunction _autoload;
215
216   private long _startTime;
217   private long _timeLimit = 600000L;
218
219   private Expr [] _callStack = new Expr[256];
220   private Value [] _callThisStack = new Value[256];
221   private int _callStackTop;
222
223   private Value [] _functionArgs;
224
225   private Path _selfPath;
226   private Path _pwd;
227   private Path _uploadPath;
228   private ArrayList JavaDoc<Path> _removePaths;
229
230   private final boolean _isStrict;
231
232   private HttpServletRequest JavaDoc _request;
233   private HttpServletResponse JavaDoc _response;
234
235   private ArrayValue _post;
236   private ArrayValue _files;
237   private SessionArrayValue _session;
238   private HttpSession JavaDoc _javaSession;
239
240   private ScriptContext _scriptContext;
241
242   private WriteStream _originalOut;
243   private OutputBuffer _outputBuffer;
244
245   private WriteStream _out;
246
247   private LocaleInfo _locale;
248
249   private Callback [] _prevErrorHandlers = new Callback[B_STRICT + 1];
250   private Callback [] _errorHandlers = new Callback[B_STRICT + 1];
251
252   private Callback _prevExceptionHandler;
253   private Callback _exceptionHandler;
254
255   private SessionCallback _sessionCallback;
256
257   private StreamContextResource _defaultStreamContext;
258
259   // XXX: need to look this up from the module itself
260
private int _errorMask = E_DEFAULT;
261
262   private int _objectId = 0;
263
264   private Logger JavaDoc _logger;
265
266   public Env(Quercus quercus,
267              QuercusPage page,
268              WriteStream out,
269              HttpServletRequest JavaDoc request,
270              HttpServletResponse JavaDoc response)
271   {
272     _quercus = quercus;
273
274     _isStrict = quercus.isStrict();
275
276     _page = page;
277
278     // XXX: grab initial from page
279
_defState = new DefinitionState(quercus);
280     
281     _originalOut = out;
282     _out = out;
283
284     _request = request;
285     _response = response;
286
287     if (page != null) {
288       _page.init(this);
289
290       importPage(_page);
291     }
292
293     setPwd(_quercus.getPwd());
294
295     if (_page != null) {
296       _selfPath = _page.getSelfPath(null);
297
298       // php/0b32
299
_includeSet.add(_selfPath);
300     }
301
302     if (_request != null && _request.getMethod().equals("POST")) {
303       _post = new ArrayValueImpl();
304       _files = new ArrayValueImpl();
305       Post.fillPost(this,
306                     _post,
307                     _files,
308                     _request,
309                     getIniBoolean("magic_quotes_gpc"));
310     }
311
312     /*
313     Cluster cluster = Cluster.getLocal();
314
315     if (cluster != null) {
316       ClusterServer selfServer = cluster.getSelfServer();
317
318       if (selfServer != null)
319         setIni("caucho.server_id", selfServer.getId());
320     }
321     */

322
323     _startTime = Alarm.getCurrentTime();
324   }
325
326   public Env(Quercus quercus)
327   {
328     this(quercus, null, null, null, null);
329   }
330
331   public static Env getInstance()
332   {
333     return _env.get();
334   }
335
336   //
337
// i18n
338
//
339

340   /**
341    * Returns the encoding used for scripts.
342    */

343   public String JavaDoc getScriptEncoding()
344   {
345     StringValue encoding = getIni("unicode.script_encoding");
346
347     if (encoding == null)
348       encoding = getIni("unicode.fallback");
349
350     if (encoding != null)
351       return encoding.toString();
352     else
353       return getQuercus().getScriptEncoding();
354   }
355
356   /**
357    * Returns the encoding used for runtime conversions, e.g. files
358    */

359   public StringValue getRuntimeEncoding()
360   {
361     StringValue encoding = getIni("unicode.runtime_encoding");
362
363     if (encoding == null)
364       encoding = getIni("unicode.fallback_encoding");
365
366     if (encoding != null)
367       return encoding;
368     else
369       return UTF8_STRING;
370   }
371
372   /**
373    * Sets the encoding used for runtime conversions.
374    */

375   public Value setRuntimeEncoding(String JavaDoc encoding)
376   {
377     return setIni("unicode.runtime_encoding", encoding);
378   }
379
380   /**
381    * Returns the encoding used for input, i.e. post
382    */

383   public StringValue getHttpInputEncoding()
384   {
385     StringValue encoding = getIni("unicode.http_input_encoding");
386
387     if (encoding == null)
388       encoding = getIni("unicode.fallback_encoding");
389
390     if (encoding != null)
391       return encoding;
392     else
393       return UTF8_STRING;
394   }
395
396   /**
397    * Returns the encoding used for output
398    */

399   public StringValue getOutputEncoding()
400   {
401     StringValue encoding = getIni("unicode.output_encoding");
402
403     if (encoding == null)
404       encoding = getIni("unicode.fallback_encoding");
405
406     if (encoding != null)
407       return encoding;
408     else
409       return UTF8_STRING;
410   }
411
412   public void setScriptContext(ScriptContext context)
413   {
414     _scriptContext = context;
415   }
416
417   /**
418    * Returns true for strict mode.
419    */

420   public final boolean isStrict()
421   {
422     return _isStrict;
423   }
424   
425   public void start()
426   {
427     _env.set(this);
428
429     // quercus/1b06
430
String JavaDoc encoding = getOutputEncoding().toString();
431     String JavaDoc type = getIni("default_mimetype").toString();
432     
433     if ("".equals(type) || _response == null) {
434     }
435     else if (! "".equals(encoding))
436       _response.setContentType(type + "; charset=" + encoding);
437     else
438       _response.setContentType(type);
439
440     if (_out != null) {
441       try {
442     _out.setEncoding(encoding);
443       } catch (Exception JavaDoc e) {
444     log.log(Level.WARNING, e.toString(), e);
445       }
446     }
447     
448     HashSet JavaDoc<ModuleStartupListener> listeners =
449       _quercus.getModuleStartupListeners();
450
451     for (ModuleStartupListener listener : listeners)
452       listener.startup(this);
453   }
454
455   /**
456    * add resource to _closeList
457    */

458   public void addClose(Closeable JavaDoc closeable)
459   {
460     _closeList.add(new SoftReference JavaDoc<Closeable JavaDoc>(closeable));
461   }
462
463   /**
464    * remove resource from _resourceList
465    *
466    * @param resource
467    */

468   public void removeClose(Closeable JavaDoc closeable)
469   {
470     for (int i = _closeList.size() - 1; i >= 0; i--) {
471       SoftReference JavaDoc<Closeable JavaDoc> ref = _closeList.get(i);
472
473       Closeable JavaDoc res = ref.get();
474
475       if (closeable.equals(res)) {
476         _closeList.remove(i);
477         break;
478       }
479     }
480   }
481
482   /**
483    * Returns the owning PHP engine.
484    */

485   public Quercus getQuercus()
486   {
487     return _quercus;
488   }
489
490   /**
491    * Returns the owning PHP engine.
492    */

493   public ModuleContext getModuleContext()
494   {
495     return _quercus.getModuleContext();
496   }
497
498   /**
499    * Returns the configured database.
500    */

501   public DataSource JavaDoc getDatabase()
502   {
503     return _quercus.getDatabase();
504   }
505
506   /**
507    * Returns the configured database.
508    */

509   public Connection JavaDoc getConnection(String JavaDoc driver, String JavaDoc url,
510                                   String JavaDoc userName, String JavaDoc password)
511     throws Exception JavaDoc
512   {
513     DataSource JavaDoc database = _quercus.getDatabase();
514
515     if (database != null) {
516       ConnectionEntry entry = new ConnectionEntry();
517       entry.init(database, null, null);
518
519       ConnectionEntry oldEntry = _connMap.get(entry);
520
521       if (oldEntry != null)
522     return oldEntry.getConnection();
523
524       entry.setConnection(database.getConnection());
525       _connMap.put(entry, entry);
526       
527       return entry.getConnection();
528     }
529
530     database = _quercus.findDatabase(driver, url);
531     
532     ConnectionEntry entry = new ConnectionEntry();
533     entry.init(database, userName, password);
534
535     ConnectionEntry oldEntry = _connMap.get(entry);
536
537     if (oldEntry != null)
538       return oldEntry.getConnection();
539
540     if (userName == null || userName.equals(""))
541       entry.setConnection(database.getConnection());
542     else
543       entry.setConnection(database.getConnection(userName, password));
544       
545     _connMap.put(entry, entry);
546       
547     return entry.getConnection();
548   }
549
550   /**
551    * Returns the configured database.
552    */

553   public DataSource JavaDoc getDataSource(String JavaDoc driver, String JavaDoc url)
554     throws Exception JavaDoc
555   {
556     DataSource JavaDoc database = _quercus.getDatabase();
557
558     if (database != null)
559       return database;
560     else
561       return _quercus.findDatabase(driver, url);
562   }
563
564   /**
565    * Sets the time limit.
566    */

567   public void setTimeLimit(long ms)
568   {
569     if (ms <= 0)
570       ms = Long.MAX_VALUE / 2;
571
572     _timeLimit = ms;
573   }
574
575   /**
576    * Checks for the program timeout.
577    */

578   public final void checkTimeout()
579   {
580     long now = Alarm.getCurrentTime();
581
582     if (_startTime + _timeLimit < now)
583       throw new QuercusRuntimeException(L.l("script timed out"));
584   }
585
586   /**
587    * Returns the writer.
588    */

589   public WriteStream getOut()
590   {
591     return _out;
592   }
593
594   /**
595    * Returns the writer.
596    */

597   public WriteStream getOriginalOut()
598   {
599     return _originalOut;
600   }
601
602   /**
603    * Flushes the output buffer.
604    */

605   public final void flush()
606   {
607     try {
608       getOut().flush();
609     } catch (IOException JavaDoc e) {
610       throw new QuercusModuleException(e);
611     }
612   }
613
614   /**
615    * Prints a string
616    */

617   public final void print(String JavaDoc v)
618   {
619     try {
620       getOut().print(v);
621     } catch (IOException JavaDoc e) {
622       throw new QuercusModuleException(e);
623     }
624   }
625
626   /**
627    * Prints a character buffer.
628    */

629   public final void print(char []buffer, int offset, int length)
630   {
631     try {
632       getOut().print(buffer, offset, length);
633     } catch (IOException JavaDoc e) {
634       throw new QuercusModuleException(e);
635     }
636   }
637
638   /**
639    * Prints a char
640    */

641   public final void print(char v)
642   {
643     try {
644       getOut().print(v);
645     } catch (IOException JavaDoc e) {
646       throw new QuercusModuleException(e);
647     }
648   }
649
650   /**
651    * Prints a long
652    */

653   public final void print(long v)
654   {
655     try {
656       getOut().print(v);
657     } catch (IOException JavaDoc e) {
658       throw new QuercusModuleException(e);
659     }
660   }
661
662   /**
663    * Prints a double
664    */

665   public final void print(double v)
666   {
667     try {
668       long longV = (long) v;
669       
670       if (v == longV)
671     getOut().print(longV);
672       else
673     getOut().print(v);
674     } catch (IOException JavaDoc e) {
675       throw new QuercusModuleException(e);
676     }
677   }
678
679   /**
680    * Prints an object
681    */

682   public final void print(Object JavaDoc v)
683   {
684     try {
685       getOut().print(v);
686     } catch (IOException JavaDoc e) {
687       throw new QuercusModuleException(e);
688     }
689   }
690
691   /**
692    * Prints a value
693    */

694   public final void print(Value v)
695   {
696     v.print(this);
697   }
698
699   /**
700    * Prints a string
701    */

702   public final void println()
703   {
704     try {
705       getOut().println();
706     } catch (IOException JavaDoc e) {
707       throw new QuercusModuleException(e);
708     }
709   }
710
711   /**
712    * Prints a string
713    */

714   public final void println(String JavaDoc v)
715   {
716     try {
717       getOut().println(v);
718     } catch (IOException JavaDoc e) {
719       throw new QuercusModuleException(e);
720     }
721   }
722
723   /**
724    * Prints a string
725    */

726   public final void println(Value v)
727   {
728     try {
729       v.print(this);
730       getOut().println();
731     } catch (IOException JavaDoc e) {
732       throw new QuercusModuleException(e);
733     }
734   }
735
736   /**
737    * Prints and object.
738    */

739   public final void println(Object JavaDoc v)
740   {
741     try {
742       getOut().println(v);
743     } catch (IOException JavaDoc e) {
744       throw new QuercusModuleException(e);
745     }
746   }
747
748   /**
749    * Prints a byte buffer.
750    */

751   public final void write(byte []buffer, int offset, int length)
752   {
753     try {
754       getOut().write(buffer, offset, length);
755     } catch (IOException JavaDoc e) {
756       throw new QuercusModuleException(e);
757     }
758   }
759
760   /**
761    * Returns the current output buffer.
762    */

763   public OutputBuffer getOutputBuffer()
764   {
765     return _outputBuffer;
766   }
767
768   /**
769    * Returns the writer.
770    */

771   public void pushOutputBuffer(Callback callback, int chunkSize, boolean erase)
772   {
773     if (_outputBuffer == null) {
774       _outputBuffer =
775         new OutputBuffer(_outputBuffer, this, callback, chunkSize, erase);
776     }
777     else
778       _outputBuffer =
779         new OutputBuffer(_outputBuffer, this, callback, chunkSize, erase);
780
781     _out = _outputBuffer.getOut();
782   }
783
784   /**
785    * Pops the output buffer
786    */

787   public boolean popOutputBuffer()
788   {
789     OutputBuffer outputBuffer = _outputBuffer;
790
791     if (outputBuffer == null)
792       return false;
793
794     outputBuffer.close();
795
796     _outputBuffer = outputBuffer.getNext();
797
798     if (_outputBuffer != null)
799       _out = _outputBuffer.getOut();
800     else {
801       _out = _originalOut;
802     }
803
804     return true;
805   }
806
807   /**
808    * Returns the current directory.
809    */

810   public Path getPwd()
811   {
812     return _pwd;
813   }
814
815   /**
816    * Returns the current directory.
817    */

818   public Path getWorkDir()
819   {
820     return _quercus.getWorkDir();
821   }
822
823   /**
824    * Sets the current directory.
825    */

826   public void setPwd(Path path)
827   {
828     _pwd = path;
829     _lookupCache.clear();
830   }
831
832   /**
833    * Returns the initial directory.
834    */

835   public Path getSelfPath()
836   {
837     return _selfPath;
838   }
839
840   /**
841    * Returns the initial directory.
842    */

843   public Path getSelfDirectory()
844   {
845     return _selfPath.getParent();
846   }
847
848   /**
849    * Sets the initial directory.
850    */

851   public void setSelfPath(Path path)
852   {
853     _selfPath = path;
854   }
855
856   /**
857    * Returns the upload directory.
858    */

859   public Path getUploadDirectory()
860   {
861     if (_uploadPath == null) {
862       String JavaDoc realPath = getRequest().getRealPath("WEB-INF/upload");
863
864       _uploadPath = getPwd().lookup(realPath);
865
866       try {
867         if (! _uploadPath.isDirectory())
868           _uploadPath.mkdirs();
869       }
870       catch (IOException JavaDoc e) {
871         log.log(Level.FINE, e.toString(), e);
872       }
873
874       _uploadPath = _uploadPath.createRoot();
875     }
876
877     return _uploadPath;
878   }
879
880   /**
881    * Adds an auto-remove path.
882    */

883   public void addRemovePath(Path path)
884   {
885     if (_removePaths == null)
886       _removePaths = new ArrayList JavaDoc<Path>();
887
888     _removePaths.add(path);
889   }
890
891   /**
892    * Returns the request.
893    */

894   public HttpServletRequest JavaDoc getRequest()
895   {
896     return _request;
897   }
898
899   /**
900    * Returns the most recently modified time of all of the {@link Path}'s that
901    * have been used for this Env, or 0 if that cannot be determined.
902    */

903   /*
904   public long getLastModified()
905   {
906     long lastModified = 0;
907
908     if (_page != null) {
909       Path pagePath = _page.getSelfPath(this);
910
911       if (pagePath != null)
912         lastModified = pagePath.getLastModified();
913     }
914
915     for (Path includePath : _includeSet) {
916       long includeLastModified = includePath.getLastModified();
917
918       if (lastModified < includeLastModified)
919         lastModified = includeLastModified;
920     }
921
922     return lastModified;
923   }
924   */

925
926   /**
927    * Returns the response.
928    */

929   public HttpServletResponse JavaDoc getResponse()
930   {
931     return _response;
932   }
933
934   /**
935    * Sets the session callback.
936    */

937   public void setSessionCallback(SessionCallback callback)
938   {
939     _sessionCallback = callback;
940   }
941
942   /**
943    * Gets the session callback.
944    */

945   public SessionCallback getSessionCallback()
946   {
947     return _sessionCallback;
948   }
949
950   /**
951    * Returns the session.
952    */

953   public SessionArrayValue getSession()
954   {
955     return _session;
956   }
957
958   /**
959    * Returns the Java Http session.
960    */

961   public HttpSession JavaDoc getJavaSession()
962   {
963     return _javaSession;
964   }
965
966   /**
967    * Sets the session.
968    */

969   public void setSession(SessionArrayValue session)
970   {
971     _session = session;
972
973     if (session != null) {
974       Value var = getGlobalVar("_SESSION");
975       
976       if (! (var instanceof SessionVar)) {
977     var = new SessionVar();
978     setGlobalValue("_SESSION", var);
979       }
980
981       var.set(session);
982
983       setGlobalValue("HTTP_SESSION_VARS", session);
984
985       session.addUse();
986     }
987     else {
988       // php/1k0v
989
Value v = getGlobalVar("_SESSION");
990
991       if (v != null)
992         v.set(UnsetValue.UNSET);
993
994       v = getGlobalVar("HTTP_SESSION_VARS");
995
996       if (v != null)
997         v.set(UnsetValue.UNSET);
998     }
999   }
1000
1001  /**
1002   * Returns a new session id.
1003   */

1004  public String JavaDoc generateSessionId()
1005  {
1006    String JavaDoc sessionId =
1007      _quercus.getQuercusSessionManager().createSessionId(this);
1008
1009    if (_javaSession != null)
1010      sessionId = _javaSession.getId().substring(0, 3) + sessionId.substring(3);
1011
1012    return sessionId;
1013  }
1014
1015  /**
1016   * Create the session.
1017   */

1018  public SessionArrayValue createSession(String JavaDoc sessionId, boolean create)
1019  {
1020    long now = Alarm.getCurrentTime();
1021
1022    SessionCallback callback = getSessionCallback();
1023
1024    _javaSession = _request.getSession(true);
1025
1026    if (create && _javaSession.getId().length() >= 3 && sessionId.length() >= 3)
1027      sessionId = _javaSession.getId().substring(0, 3) + sessionId.substring(3);
1028
1029    SessionArrayValue session = _quercus.loadSession(this, sessionId);
1030
1031    if (callback != null) {
1032      StringValue value = callback.read(this, sessionId);
1033
1034      if (value != null && value.length() != 0) {
1035        Value unserialize = VariableModule.unserialize(this, value);
1036
1037        if (unserialize instanceof ArrayValue) {
1038          ArrayValue arrayValue = (ArrayValue) unserialize;
1039
1040          session.reset(now);
1041          session.putAll(arrayValue);
1042        }
1043      }
1044    }
1045
1046    setSession(session);
1047
1048    return session;
1049  }
1050
1051  /**
1052   * Destroy the session.
1053   */

1054  public void destroySession(String JavaDoc sessionId)
1055  {
1056    SessionCallback callback = getSessionCallback();
1057
1058    if (callback != null) {
1059      callback.destroy(this, sessionId);
1060    }
1061    else {
1062      _quercus.destroySession(sessionId);
1063    }
1064
1065    setSession(null);
1066  }
1067
1068  /**
1069   * Returns the logger used for syslog.
1070   */

1071  public Logger JavaDoc getLogger()
1072  {
1073    if (_logger == null)
1074      _logger = Logger.getLogger("quercus.quercus");
1075
1076    return _logger;
1077  }
1078
1079  /**
1080   * Returns the configuration value of an init var.
1081   */

1082  public Value getConfigVar(String JavaDoc var)
1083  {
1084    return _quercus.getIni(var);
1085  }
1086
1087  /**
1088   * Sets an ini value.
1089   */

1090  public Value setIni(String JavaDoc var, String JavaDoc value)
1091  {
1092    StringValue oldValue = getIni(var);
1093
1094    if (_iniMap == null)
1095      _iniMap = new HashMap JavaDoc<String JavaDoc, StringValue>();
1096
1097    _iniMap.put(var, new StringValueImpl(value));
1098
1099    return oldValue;
1100  }
1101
1102  /**
1103   * Sets an ini value.
1104   */

1105  public Value setIni(String JavaDoc var, StringValue value)
1106  {
1107    StringValue oldValue = getIni(var);
1108
1109    if (_iniMap == null)
1110      _iniMap = new HashMap JavaDoc<String JavaDoc, StringValue>();
1111
1112    _iniMap.put(var, value);
1113
1114    return oldValue;
1115  }
1116
1117  /**
1118   * Sets a boolean ini value.
1119   */

1120  public Value setIniBoolean(String JavaDoc var, Value value)
1121  {
1122    // XXX: needs testing and correlation with Quercus.setIni
1123

1124    if (value instanceof StringValue) {
1125      if ("off".equalsIgnoreCase(value.toString()))
1126        return setIni(var, "");
1127
1128      if ("on".equalsIgnoreCase(value.toString()))
1129        return setIni(var, "1");
1130    }
1131
1132    return setIni(var, value.toBoolean() ? "1" : "");
1133  }
1134
1135  /**
1136   * Returns an ini value.
1137   */

1138  public StringValue getIni(String JavaDoc var)
1139  {
1140    StringValue value = null;
1141
1142    if (_iniMap != null)
1143      value = _iniMap.get(var);
1144
1145    if (value != null)
1146      return value;
1147
1148    value = _quercus.getIni(var);
1149
1150    return value;
1151  }
1152
1153  /**
1154   * Returns an ini value.
1155   */

1156  public boolean getIniBoolean(String JavaDoc var)
1157  {
1158    Value value = getIni(var);
1159
1160    if (value != null)
1161      return value.toBoolean();
1162    else
1163      return false;
1164  }
1165
1166  /**
1167   * Returns an ini value as a long.
1168   */

1169  public long getIniLong(String JavaDoc var)
1170  {
1171    Value value = getIni(var);
1172
1173    if (value != null)
1174      return value.toLong();
1175    else
1176      return 0;
1177  }
1178
1179  /**
1180   * Returns an ini value as a string.
1181   */

1182  public String JavaDoc getIniString(String JavaDoc var)
1183  {
1184    Value value = getIni(var);
1185
1186    if (value != null)
1187      return value.toString();
1188    else
1189      return null;
1190  }
1191
1192  /**
1193   * Returns the ByteToChar converter.
1194   */

1195  public ByteToChar getByteToChar()
1196  {
1197    return ByteToChar.create();
1198  }
1199
1200  /**
1201   * Returns the 'this' value.
1202   */

1203  public Value getThis()
1204  {
1205    return _this;
1206  }
1207
1208  /**
1209   * Sets the 'this' value, returning the old value.
1210   */

1211  public Value setThis(Value value)
1212  {
1213    Value oldThis = _this;
1214
1215    _this = value.toValue();
1216
1217    return oldThis;
1218  }
1219
1220  /**
1221   * Gets a value.
1222   */

1223  public Value getValue(String JavaDoc name)
1224  {
1225    Var var = getRef(name);
1226
1227    if (var != null)
1228      return var.toValue();
1229    else
1230      return NullValue.NULL;
1231  }
1232
1233  /**
1234   * Gets a special value, a special value is used to store and retrieve module
1235   * specific values in the env using a unique name.
1236   */

1237  public <T> T getSpecialValue(String JavaDoc name)
1238  {
1239    return (T) _specialMap.get(name);
1240  }
1241
1242  /**
1243   * Gets a global
1244   */

1245  public Value getGlobalValue(String JavaDoc name)
1246  {
1247    Var var = getGlobalRef(name);
1248
1249    if (var != null)
1250      return var.toValue();
1251    else
1252      return NullValue.NULL;
1253  }
1254
1255  /**
1256   * Gets a variable
1257   *
1258   * @param name the variable name
1259   * @param var the current value of the variable
1260   */

1261  public final Var getVar(String JavaDoc name, Value value)
1262  {
1263    if (value != null)
1264      return (Var) value;
1265    
1266    Var var = _map.get(name);
1267
1268    if (var != null)
1269      return var;
1270
1271    var = getRef(name);
1272
1273    if (var == null) {
1274      var = new Var();
1275
1276      if (_map == _globalMap)
1277        var.setGlobal();
1278
1279      _map.put(name, var);
1280    }
1281
1282    return var;
1283  }
1284
1285  /**
1286   * Gets a variable
1287   *
1288   * @param name the variable name
1289   * @param value the current value of the variable
1290   */

1291  public final Var getGlobalVar(String JavaDoc name, Value value)
1292  {
1293    if (value != null)
1294      return (Var) value;
1295
1296    Var var = _globalMap.get(name);
1297
1298    if (var != null)
1299      return var;
1300
1301    var = getSpecialRef(name);
1302
1303    if (var == null) {
1304      var = new Var();
1305      var.setGlobal();
1306    }
1307    
1308    _globalMap.put(name, var);
1309
1310    return var;
1311  }
1312
1313  /**
1314   * Gets a static variable name.
1315   */

1316  public final String JavaDoc createStaticName()
1317  {
1318    return _quercus.createStaticName();
1319  }
1320
1321  /**
1322   * Gets a static variable
1323   *
1324   * @param name the variable name
1325   */

1326  public final Var getStaticVar(String JavaDoc name)
1327  {
1328    Var var = _staticMap.get(name);
1329
1330    if (var == null) {
1331      var = new Var();
1332      var.setGlobal();
1333      _staticMap.put(name, var);
1334    }
1335
1336    return var;
1337  }
1338
1339  /**
1340   * Unsets variable
1341   *
1342   * @param name the variable name
1343   */

1344  public final Var unsetVar(String JavaDoc name)
1345  {
1346    _map.remove(name);
1347
1348    return null;
1349  }
1350
1351  /**
1352   * Gets a variable
1353   *
1354   * @param name the variable name
1355   * @param value the current value of the variable
1356   */

1357  public final Var setVar(String JavaDoc name, Value value)
1358  {
1359    Var var;
1360
1361    if (value instanceof Var) {
1362      var = (Var) value;
1363
1364      if (_map == _globalMap)
1365        var.setGlobal();
1366    }
1367    else
1368      var = new Var(value.toValue());
1369
1370    _map.put(name, var);
1371
1372    return var;
1373  }
1374
1375  /**
1376   * Unsets variable
1377   *
1378   * @param name the variable name
1379   */

1380  public final Var unsetLocalVar(String JavaDoc name)
1381  {
1382    _map.remove(name);
1383
1384    return null;
1385  }
1386
1387  /**
1388   * Unsets variable
1389   *
1390   * @param name the variable name
1391   */

1392  public final Var unsetGlobalVar(String JavaDoc name)
1393  {
1394    _globalMap.remove(name);
1395
1396    return null;
1397  }
1398
1399  /**
1400   * Gets a local
1401   *
1402   * @param var the current value of the variable
1403   */

1404  public static final Value getLocalVar(Value var)
1405  {
1406    if (var == null)
1407      var = new Var();
1408
1409    return var;
1410  }
1411
1412  /**
1413   * Gets a local value
1414   *
1415   * @param var the current value of the variable
1416   */

1417  public static final Value getLocalValue(Value var)
1418  {
1419    if (var != null)
1420      return var;
1421    else
1422      return NullValue.NULL;
1423  }
1424
1425  /**
1426   * Gets a local
1427   *
1428   * @param var the current value of the variable
1429   */

1430  public static final Value setLocalVar(Value var, Value value)
1431  {
1432    value = value.toValue();
1433
1434    if (var instanceof Var)
1435      var.set(value);
1436
1437    return value;
1438  }
1439
1440  /**
1441   * Gets a value.
1442   */

1443  public Var getRef(String JavaDoc name)
1444  {
1445    Var var = _map.get(name);
1446
1447    if (var == null) {
1448      var = getSpecialRef(name);
1449
1450      if (var != null) {
1451        var.setGlobal();
1452        _globalMap.put(name, var);
1453
1454        var = _map.get(name);
1455      }
1456    }
1457
1458    return var;
1459  }
1460
1461  /**
1462   * Gets a global value.
1463   */

1464  public Var getGlobalRef(String JavaDoc name)
1465  {
1466    Var var = _globalMap.get(name);
1467
1468    if (var == null) {
1469      var = getSpecialRef(name);
1470      if (var == null)
1471    var = new Var();
1472      
1473      _globalMap.put(name, var);
1474    }
1475
1476    return var;
1477  }
1478
1479  /**
1480   * Gets a value.
1481   */

1482  public Var getSpecialRef(String JavaDoc name)
1483  {
1484    Var var = null;
1485
1486    switch (SPECIAL_VARS.get(name)) {
1487    case _ENV: {
1488      var = new Var();
1489
1490      _globalMap.put(name, var);
1491
1492      var.set(new ArrayValueImpl());
1493
1494      return var;
1495    }
1496
1497    case HTTP_POST_VARS:
1498      if (! getIniBoolean("register_long_arrays"))
1499    return null;
1500    case _POST: {
1501      var = new Var();
1502
1503      _globalMap.put(name, var);
1504
1505      ArrayValue post = new ArrayValueImpl();
1506
1507      var.set(post);
1508
1509      if (_request == null)
1510        return null;
1511
1512      if (! "POST".equals(_request.getMethod()))
1513        return var;
1514
1515      if (_post != null) {
1516        for (Map.Entry<Value, Value> entry : _post.entrySet()) {
1517          post.put(entry.getKey(), entry.getValue());
1518        }
1519      }
1520
1521      // commented out: don't add non-POST parameters to $_POST
1522
/*
1523      try {
1524    _request.setCharacterEncoding(getHttpInputEncoding().toString());
1525      } catch (Exception e) {
1526    log.log(Level.FINE, e.toString(), e);
1527      }
1528
1529      ArrayList<String> keys = new ArrayList<String>();
1530      if (_request.getParameterMap() != null)
1531    keys.addAll(_request.getParameterMap().keySet());
1532
1533      Collections.sort(keys);
1534
1535      for (String key : keys) {
1536        String []value = _request.getParameterValues(key);
1537
1538        Post.addFormValue(post, key, value, getIniBoolean("magic_quotes_gpc"));
1539      }
1540      */

1541    }
1542    break;
1543
1544
1545    case HTTP_POST_FILES:
1546      if (! getIniBoolean("register_long_arrays"))
1547    return null;
1548    case _FILES: {
1549      var = new Var();
1550
1551      _globalMap.put(name, var);
1552
1553      ArrayValue files = new ArrayValueImpl();
1554
1555      if (_files != null) {
1556        for (Map.Entry<Value, Value> entry : _files.entrySet()) {
1557          files.put(entry.getKey(), entry.getValue());
1558        }
1559      }
1560
1561      var.set(files);
1562    }
1563    break;
1564
1565    case HTTP_GET_VARS:
1566      if (! getIniBoolean("register_long_arrays"))
1567    return null;
1568      
1569    case _GET: {
1570      var = new Var();
1571
1572      ArrayValue array = new ArrayValueImpl();
1573
1574      var.set(array);
1575
1576      _globalMap.put(name, var);
1577
1578      try {
1579    _request.setCharacterEncoding(getHttpInputEncoding().toString());
1580      } catch (Exception JavaDoc e) {
1581    log.log(Level.FINE, e.toString(), e);
1582      }
1583
1584      String JavaDoc queryString = _request.getQueryString();
1585
1586      if (queryString == null)
1587    return var;
1588
1589      StringModule.parse_str(this, queryString, var);
1590
1591      return var;
1592    }
1593      
1594    case _REQUEST: {
1595      var = new Var();
1596
1597      ArrayValue array = new ArrayValueImpl();
1598
1599      var.set(array);
1600
1601      _globalMap.put(name, var);
1602
1603      try {
1604    _request.setCharacterEncoding(getHttpInputEncoding().toString());
1605      } catch (Exception JavaDoc e) {
1606    log.log(Level.FINE, e.toString(), e);
1607      }
1608      
1609      ArrayList JavaDoc<String JavaDoc> keys = new ArrayList JavaDoc<String JavaDoc>();
1610      keys.addAll(_request.getParameterMap().keySet());
1611
1612      Collections.sort(keys);
1613
1614      for (String JavaDoc key : keys) {
1615        String JavaDoc []value = _request.getParameterValues(key);
1616
1617        Post.addFormValue(array,
1618              key,
1619              value,
1620              getIniBoolean("magic_quotes_gpc"));
1621      }
1622
1623      if (name.equals("_REQUEST") && _post != null) {
1624        for (Map.Entry<Value, Value> entry : _post.entrySet()) {
1625          array.put(entry.getKey(), entry.getValue().copy());
1626        }
1627      }
1628
1629      Cookie JavaDoc []cookies = _request.getCookies();
1630      for (int i = 0; cookies != null && i < cookies.length; i++) {
1631    Post.addFormValue(array,
1632              cookies[i].getName(),
1633              new String JavaDoc[] { cookies[i].getValue() },
1634              getIniBoolean("magic_quotes_gpc"));
1635      }
1636
1637      return var;
1638    }
1639
1640    case HTTP_SERVER_VARS:
1641      if (! getIniBoolean("register_long_arrays"))
1642    return null;
1643    case _SERVER: {
1644      var = new Var();
1645
1646      _globalMap.put(name, var);
1647
1648      var.set(new ServerArrayValue(this));
1649
1650      return var;
1651    }
1652
1653    case _GLOBAL: {
1654      var = new Var();
1655
1656      _globalMap.put(name, var);
1657
1658      var.set(new GlobalArrayValue(this));
1659
1660      return var;
1661    }
1662
1663    case HTTP_COOKIE_VARS:
1664      if (! getIniBoolean("register_long_arrays"))
1665    return null;
1666    case _COOKIE: {
1667      var = new Var();
1668      _globalMap.put(name, var);
1669
1670      ArrayValue array = new ArrayValueImpl();
1671
1672      Cookie JavaDoc []cookies = _request.getCookies();
1673      if (cookies != null) {
1674        for (int i = 0; i < cookies.length; i++) {
1675          Cookie JavaDoc cookie = cookies[i];
1676
1677          String JavaDoc value = decodeValue(cookie.getValue());
1678
1679          StringValue valueAsValue;
1680
1681      // PHP 6 removes magic_quotes
1682
/*
1683          if (getIniBoolean("magic_quotes_gpc"))
1684            valueAsValue = StringModule.addslashes(value);
1685          else
1686      */

1687      valueAsValue = new StringValueImpl(value);
1688
1689          array.append(new StringValueImpl(cookie.getName()), valueAsValue);
1690        }
1691      }
1692
1693      var.set(array);
1694
1695      _globalMap.put(name, var);
1696
1697      return var;
1698    }
1699
1700    case PHP_SELF: {
1701      var = new Var();
1702      _globalMap.put(name, var);
1703
1704      var.set(getGlobalVar("_SERVER").get(PHP_SELF_STRING));
1705
1706      return var;
1707    }
1708
1709    default: {
1710      if (_scriptContext != null) {
1711    Object JavaDoc value = _scriptContext.getAttribute(name);
1712
1713    if (value != null) {
1714      var = new Var();
1715      _globalMap.put(name, var);
1716
1717      var.set(wrapJava(value));
1718
1719      return var;
1720    }
1721      }
1722    }
1723    }
1724
1725    return var;
1726  }
1727
1728  private static String JavaDoc decodeValue(String JavaDoc s)
1729  {
1730    int len = s.length();
1731    StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
1732
1733    for (int i = 0; i < len; i++) {
1734      char ch = s.charAt(i);
1735
1736      if (ch == '%' && i + 2 < len) {
1737        int d1 = s.charAt(i + 1);
1738        int d2 = s.charAt(i + 2);
1739
1740        int v = 0;
1741
1742        if ('0' <= d1 && d1 <= '9')
1743          v = 16 * (d1 - '0');
1744        else if ('a' <= d1 && d1 <= 'f')
1745          v = 16 * (d1 - 'a' + 10);
1746        else if ('A' <= d1 && d1 <= 'F')
1747          v = 16 * (d1 - 'A' + 10);
1748        else {
1749          sb.append('%');
1750          continue;
1751        }
1752
1753        if ('0' <= d2 && d2 <= '9')
1754          v += (d2 - '0');
1755        else if ('a' <= d2 && d2 <= 'f')
1756          v += (d2 - 'a' + 10);
1757        else if ('A' <= d2 && d2 <= 'F')
1758          v += (d2 - 'A' + 10);
1759        else {
1760          sb.append('%');
1761          continue;
1762        }
1763
1764        i += 2;
1765        sb.append((char) v);
1766      }
1767      else
1768        sb.append(ch);
1769    }
1770
1771    return sb.toString();
1772  }
1773
1774  /**
1775   * Gets a value.
1776   */

1777  public Var getVar(String JavaDoc name)
1778  {
1779    Var var = _map.get(name);
1780
1781    if (var != null)
1782      return var;
1783    
1784    var = getRef(name);
1785
1786    if (var == null) {
1787      var = new Var();
1788
1789      if (_map == _globalMap) {
1790        // php/379c
1791
var.setGlobal();
1792      }
1793
1794      _map.put(name, var);
1795    }
1796
1797    return var;
1798  }
1799
1800  /**
1801   * Gets a value.
1802   */

1803  public Var getGlobalVar(String JavaDoc name)
1804  {
1805    Var var = getGlobalRef(name);
1806
1807    if (var == null) {
1808      var = new Var();
1809      var.setGlobal();
1810      _globalMap.put(name, var);
1811    }
1812
1813    return var;
1814  }
1815
1816  public boolean isGlobalEnv()
1817  {
1818    return _map == _globalMap;
1819  }
1820
1821  /**
1822   * Sets a value.
1823   */

1824  public Value setValue(String JavaDoc name, Value value)
1825  {
1826    if (value instanceof Var)
1827      _map.put(name, (Var) value);
1828    else {
1829      Var var = getVar(name);
1830      var.set(value);
1831    }
1832
1833    return value;
1834  }
1835
1836  /**
1837   * Sets a special value, a special value is used to store and retrieve module
1838   * specific values in the env using a unique name.
1839   */

1840  public Object JavaDoc setSpecialValue(String JavaDoc name, Object JavaDoc value)
1841  {
1842    _specialMap.put(name, value);
1843
1844    return value;
1845  }
1846
1847  /**
1848   * Sets a value.
1849   */

1850  public Value setGlobalValue(String JavaDoc name, Value value)
1851  {
1852    if (value instanceof Var)
1853      _globalMap.put(name, (Var) value);
1854    else {
1855      Var var = getGlobalVar(name);
1856      var.set(value);
1857    }
1858
1859    return value;
1860  }
1861
1862  /**
1863   * Sets the calling function expression.
1864   */

1865  public void pushCall(Expr call, Value obj)
1866  {
1867    if (_callStack.length <= _callStackTop) {
1868      Expr []newStack = new Expr[2 * _callStack.length];
1869      System.arraycopy(_callStack, 0, newStack, 0, _callStack.length);
1870      _callStack = newStack;
1871      
1872      Value []newThisStack = new Value[2 * _callThisStack.length];
1873      System.arraycopy(_callThisStack,
1874               0, newThisStack,
1875               0, _callThisStack.length);
1876      _callThisStack = newThisStack;
1877    }
1878
1879    _callStack[_callStackTop] = call;
1880    _callThisStack[_callStackTop] = obj;
1881
1882    _callStackTop++;
1883  }
1884
1885  /**
1886   * Pops the top call.
1887   */

1888  public Expr popCall()
1889  {
1890    return _callStack[--_callStackTop];
1891  }
1892
1893  /**
1894   * Returns the stack depth.
1895   */

1896  public int getCallDepth()
1897  {
1898    return _callStackTop;
1899  }
1900  
1901  /**
1902   * Pops the top call.
1903   */

1904  public Expr peekCall(int depth)
1905  {
1906    if (_callStackTop - depth > 0)
1907      return _callStack[_callStackTop - depth - 1];
1908    else
1909      return null;
1910  }
1911  
1912  /**
1913   * Pops the top call.
1914   */

1915  public Value peekCallThis(int depth)
1916  {
1917    if (_callStackTop - depth > 0)
1918      return _callThisStack[_callStackTop - depth - 1];
1919    else
1920      return null;
1921  }
1922
1923  /**
1924   * Pushes a new environment.
1925   */

1926  public HashMap JavaDoc<String JavaDoc, Var> pushEnv(HashMap JavaDoc<String JavaDoc, Var> map)
1927  {
1928    HashMap JavaDoc<String JavaDoc, Var> oldEnv = _map;
1929
1930    _map = map;
1931
1932    return oldEnv;
1933  }
1934
1935  /**
1936   * Restores the old environment.
1937   */

1938  public void popEnv(HashMap JavaDoc<String JavaDoc, Var> oldEnv)
1939  {
1940    _map = oldEnv;
1941  }
1942
1943  /**
1944   * Returns the current environment.
1945   */

1946  public HashMap JavaDoc<String JavaDoc, Var> getEnv()
1947  {
1948    return _map;
1949  }
1950
1951  /**
1952   * Returns the current environment.
1953   */

1954  public HashMap JavaDoc<String JavaDoc, Var> getGlobalEnv()
1955  {
1956    return _globalMap;
1957  }
1958
1959  /**
1960   * Pushes a new environment.
1961   */

1962  public final Value []setFunctionArgs(Value []args)
1963  {
1964    Value []oldArgs = _functionArgs;
1965
1966    Value []newArgs = new Value[args.length];
1967
1968    for (int i = 0; args != null && i < args.length; i++) {
1969      // php/3715, 3768
1970
newArgs[i] = args[i].toValue().toArgValue();
1971    }
1972
1973    _functionArgs = newArgs;
1974
1975    return oldArgs;
1976  }
1977
1978  /**
1979   * Pushes a new environment.
1980   */

1981  public final Value []setFunctionArgsNoCopy(Value []args)
1982  {
1983    Value []oldArgs = _functionArgs;
1984
1985    for (int i = 0; args != null && i < args.length; i++)
1986      args[i] = args[i].toValue();
1987
1988    _functionArgs = args;
1989
1990    return oldArgs;
1991  }
1992
1993  /**
1994   * Pushes a new environment.
1995   */

1996  public final void restoreFunctionArgs(Value []args)
1997  {
1998    _functionArgs = args;
1999  }
2000
2001  /**
2002   * Returns the function args.
2003   */

2004  public final Value []getFunctionArgs()
2005  {
2006    return _functionArgs;
2007  }
2008
2009  /**
2010   * Removes a specialValue
2011   */

2012  public Object JavaDoc removeSpecialValue(String JavaDoc name)
2013  {
2014    return _specialMap.remove(name);
2015  }
2016
2017  /**
2018   * Returns a constant.
2019   */

2020  public Value getConstant(String JavaDoc name)
2021  {
2022    Value value = getConstantImpl(name);
2023
2024    if (value != null)
2025      return value;
2026
2027    /* XXX:
2028       notice(L.l("Converting undefined constant '{0}' to string.",
2029       name));
2030    */

2031
2032    value = new StringValueImpl(name);
2033
2034    return value;
2035  }
2036
2037  /**
2038   * Returns true if the constant is defined.
2039   */

2040  public boolean isDefined(String JavaDoc name)
2041  {
2042    return getConstantImpl(name) != null;
2043  }
2044
2045  /**
2046   * Returns a constant.
2047   */

2048  private Value getConstantImpl(String JavaDoc name)
2049  {
2050    Value value = _constMap.get(name);
2051
2052    if (value != null)
2053      return value;
2054
2055    value = _quercus.getConstant(name);
2056    if (value != null)
2057      return value;
2058
2059    if (_lowerConstMap != null) {
2060      value = _lowerConstMap.get(name.toLowerCase());
2061
2062      if (value != null)
2063    return value;
2064    }
2065
2066    return null;
2067  }
2068  
2069  /**
2070   * Removes a constant.
2071   */

2072  public Value removeConstant(String JavaDoc name)
2073  {
2074    return _constMap.remove(name);
2075  }
2076
2077  /**
2078   * Sets a constant.
2079   */

2080  public Value addConstant(String JavaDoc name,
2081                           Value value,
2082                           boolean isCaseInsensitive)
2083  {
2084    Value oldValue = _constMap.get(name);
2085
2086    if (oldValue != null)
2087      return oldValue;
2088
2089    _constMap.put(name, value);
2090
2091    if (_lowerConstMap != null && isCaseInsensitive)
2092      _lowerConstMap.put(name.toLowerCase(), value);
2093
2094    return value;
2095  }
2096
2097  /**
2098   * Returns an array of the defined functions.
2099   */

2100  public ArrayValue getDefinedConstants()
2101  {
2102    ArrayValue result = new ArrayValueImpl();
2103
2104    for (Map.Entry<String JavaDoc, Value> entry : _quercus.getConstMap().entrySet()) {
2105      result.put(new StringValueImpl(entry.getKey()), entry.getValue());
2106    }
2107
2108    for (Map.Entry<String JavaDoc, Value> entry : _constMap.entrySet()) {
2109      result.put(new StringValueImpl(entry.getKey()), entry.getValue());
2110    }
2111
2112    return result;
2113  }
2114
2115  /**
2116   * Returns true if an extension is loaded.
2117   */

2118  public boolean isExtensionLoaded(String JavaDoc name)
2119  {
2120    return getQuercus().isExtensionLoaded(name);
2121  }
2122
2123  /**
2124   * Returns true if an extension is loaded.
2125   */

2126  public HashSet JavaDoc<String JavaDoc> getLoadedExtensions()
2127  {
2128    return getQuercus().getLoadedExtensions();
2129  }
2130
2131  /**
2132   * Returns true if an extension is loaded.
2133   */

2134  public Value getExtensionFuncs(String JavaDoc name)
2135  {
2136    return getQuercus().getExtensionFuncs(name);
2137  }
2138
2139  /**
2140   * Returns the default stream resource.
2141   */

2142  public StreamContextResource getDefaultStreamContext()
2143  {
2144    if (_defaultStreamContext == null)
2145      _defaultStreamContext = new StreamContextResource();
2146
2147    return _defaultStreamContext;
2148  }
2149
2150  /**
2151   * Returns an array of the defined functions.
2152   */

2153  /*
2154  public ArrayValue getDefinedFunctions()
2155  {
2156    ArrayValue result = new ArrayValueImpl();
2157
2158    ArrayValue internal = _quercus.getDefinedFunctions();
2159    ArrayValue user = new ArrayValueImpl();
2160
2161    result.put(new StringValueImpl("internal"), internal);
2162    result.put(new StringValueImpl("user"), user);
2163
2164    for (String name : _funMap.keySet()) {
2165      StringValue key = new StringValueImpl(name);
2166
2167      if (! internal.contains(key).isset())
2168        user.put(name);
2169    }
2170
2171    return result;
2172  }
2173  */

2174  
2175  public ArrayValue getDefinedFunctions()
2176  {
2177    return _defState.getDefinedFunctions();
2178  }
2179
2180  /**
2181   * Finds the java reflection method for the function with the given name.
2182   *
2183   * @param name the method name
2184   * @return the found method or null if no method found.
2185   */

2186  /*
2187  public AbstractFunction findFunction(String name)
2188  {
2189    AbstractFunction fun = _funMap.get(name);
2190
2191    if (fun != null)
2192      return fun;
2193    
2194    if (! isStrict()) {
2195      fun = _lowerFunMap.get(name.toLowerCase());
2196
2197      if (fun != null) {
2198    _funMap.put(name, fun);
2199
2200    return fun;
2201      }
2202    }
2203
2204    fun = findFunctionImpl(name);
2205
2206    if (fun != null) {
2207      _funMap.put(name, fun);
2208
2209      return fun;
2210    }
2211    else
2212      return null;
2213  }
2214  */

2215  public AbstractFunction findFunction(String JavaDoc name)
2216  {
2217    return _defState.findFunction(name);
2218  }
2219
2220  /**
2221   * Finds the java reflection method for the function with the given name.
2222   *
2223   * @param name the method name
2224   * @return the found method or null if no method found.
2225   */

2226  /*
2227  public AbstractFunction getFunction(String name)
2228  {
2229    AbstractFunction fun = _funMap.get(name);
2230
2231    if (fun != null)
2232      return fun;
2233    
2234    fun = findFunction(name);
2235    
2236    if (fun != null) {
2237      return fun;
2238    }
2239
2240    throw errorException(L.l("'{0}' is an unknown function.", name));
2241  }
2242  */

2243  public AbstractFunction getFunction(String JavaDoc name)
2244  {
2245    AbstractFunction fun = _defState.findFunction(name);
2246
2247    if (fun != null)
2248      return fun;
2249    else
2250      throw errorException(L.l("'{0}' is an unknown function", name));
2251  }
2252
2253  /**
2254   * Finds the java reflection method for the function with the given name.
2255   *
2256   * @param name the method name
2257   * @return the found method or null if no method found.
2258   */

2259  public AbstractFunction getFunction(Value name)
2260  {
2261    name = name.toValue();
2262
2263    if (name instanceof CallbackFunction)
2264      return ((CallbackFunction) name).getFunction();
2265
2266    AbstractFunction fun = _defState.findFunction(name.toString());
2267
2268    if (fun != null)
2269      return fun;
2270
2271    throw errorException(L.l("'{0}' is an unknown function.", name));
2272  }
2273
2274  /**
2275   * Finds the java reflection method for the function with the given name.
2276   *
2277   * @param name the method name
2278   * @return the found method or null if no method found.
2279   */

2280  /*
2281  private AbstractFunction findFunctionImpl(String name)
2282  {
2283    AbstractFunction fun = null;
2284
2285    fun = _quercus.findFunction(name);
2286    if (fun != null)
2287      return fun;
2288
2289    return fun;
2290  }
2291  */

2292
2293  /**
2294   * Adds a function, e.g. from an include.
2295   */

2296  /*
2297  public Value addFunction(String name, AbstractFunction fun)
2298  {
2299    AbstractFunction oldFun = findFunction(name);
2300
2301    if (oldFun != null) {
2302      throw new QuercusException(L.l("can't redefine function {0}", name));
2303    }
2304
2305    _funMap.put(name, fun);
2306
2307    if (! isStrict())
2308      _lowerFunMap.put(name.toLowerCase(), fun);
2309
2310    return BooleanValue.TRUE;
2311  }
2312  */

2313
2314  public DefinitionState getDefinitionState()
2315  {
2316    return _defState;
2317  }
2318  
2319  public Value addFunction(String JavaDoc name, AbstractFunction fun)
2320  {
2321    return _defState.addFunction(name, fun);
2322  }
2323
2324  /**
2325   * Adds a function from a compiled include
2326   *
2327   * @param name the function name, must be an intern() string
2328   * @param lowerName the function name, must be an intern() string
2329   */

2330  public Value addFunctionFromPage(String JavaDoc name, String JavaDoc lowerName, AbstractFunction fun)
2331  {
2332    // XXX: skip the old function check since the include for compiled
2333
// pages is already verified. Might have a switch here?
2334
/*
2335    AbstractFunction oldFun = _lowerFunMap.get(lowerName);
2336
2337    if (oldFun == null)
2338      oldFun = _quercus.findLowerFunctionImpl(lowerName);
2339
2340    if (oldFun != null) {
2341      throw new QuercusException(L.l("can't redefine function {0}", name));
2342    }
2343
2344    _funMap.put(name, fun);
2345
2346    if (! isStrict())
2347      _lowerFunMap.put(lowerName, fun);
2348    */

2349
2350    return BooleanValue.TRUE;
2351  }
2352
2353  /**
2354   * Finds the java reflection method for the function with the given name.
2355   *
2356   * @param className the class name
2357   * @param methodName the method name
2358   * @return the found method or null if no method found.
2359   */

2360  public AbstractFunction findMethod(String JavaDoc className, String JavaDoc methodName)
2361  {
2362    QuercusClass cl = findClass(className);
2363
2364    if (cl == null) {
2365      error(L.l("'{0}' is an unknown class.", className));
2366      return null;
2367    }
2368
2369    AbstractFunction fun = cl.findFunction(methodName);
2370
2371    if (fun == null && ! isStrict())
2372      fun = cl.findFunctionLowerCase(methodName.toLowerCase());
2373
2374    if (fun == null) {
2375      error(L.l("'{0}::{1}' is an unknown method.",
2376                className, methodName));
2377      return null;
2378    }
2379
2380    return fun;
2381  }
2382
2383  /**
2384   * Compiles and calluates the given code
2385   *
2386   * @param code the code to calluate
2387   * @return the result
2388   */

2389  public Value evalCode(String JavaDoc code)
2390    throws IOException JavaDoc
2391  {
2392    if (log.isLoggable(Level.FINER))
2393      log.finer(code);
2394
2395    Quercus quercus = getQuercus();
2396
2397    QuercusProgram program = quercus.parseEvalExpr(code);
2398
2399    Value value = program.execute(this);
2400
2401    return value;
2402  }
2403
2404  /**
2405   * Evaluates the named function.
2406   *
2407   * @param name the function name
2408   * @return the function value
2409   */

2410  public Value call(String JavaDoc name)
2411  {
2412    AbstractFunction fun = findFunction(name);
2413
2414    if (fun == null)
2415      return error(L.l("'{0}' is an unknown function.", name));
2416
2417    return fun.call(this);
2418  }
2419
2420  /**
2421   * Evaluates the named function.
2422   *
2423   * @param name the function name
2424   * @param a0 the first argument
2425   * @return the function value
2426   */

2427  public Value call(String JavaDoc name, Value a0)
2428  {
2429    AbstractFunction fun = findFunction(name);
2430
2431    if (fun == null)
2432      return error(L.l("'{0}' is an unknown function.", name));
2433
2434    return fun.call(this, a0);
2435  }
2436
2437  /**
2438   * Evaluates the named function.
2439   *
2440   * @param name the function name
2441   * @param a0 the first argument
2442   * @param a1 the second argument
2443   * @return the function value
2444   */

2445  public Value call(String JavaDoc name, Value a0, Value a1)
2446  {
2447    return getFunction(name).call(this, a0, a1);
2448  }
2449
2450  /**
2451   * Evaluates the named function.
2452   *
2453   * @param name the function name
2454   * @param a0 the first argument
2455   * @param a1 the second argument
2456   * @param a2 the third argument
2457   * @return the function value
2458   */

2459  public Value call(String JavaDoc name, Value a0, Value a1, Value a2)
2460  {
2461    return getFunction(name).call(this, a0, a1, a2);
2462  }
2463
2464  /**
2465   * Evaluates the named function.
2466   *
2467   * @param name the function name
2468   * @param a0 the first argument
2469   * @param a1 the second argument
2470   * @param a2 the third argument
2471   * @param a3 the fourth argument
2472   * @return the function value
2473   */

2474  public Value call(String JavaDoc name, Value a0, Value a1, Value a2, Value a3)
2475  {
2476    return getFunction(name).call(this, a0, a1, a2, a3);
2477  }
2478
2479  /**
2480   * Evaluates the named function.
2481   *
2482   * @param name the function name
2483   * @param a0 the first argument
2484   * @param a1 the second argument
2485   * @param a2 the third argument
2486   * @param a3 the fourth argument
2487   * @param a4 the fifth argument
2488   * @return the function value
2489   */

2490  public Value call(String JavaDoc name, Value a0, Value a1,
2491                    Value a2, Value a3, Value a4)
2492  {
2493    return getFunction(name).call(this, a0, a1, a2, a3, a4);
2494  }
2495
2496  /**
2497   * Evaluates the named function.
2498   *
2499   * @param name the function name
2500   * @param args the arguments
2501   * @return the function value
2502   */

2503  public Value call(String JavaDoc name, Value []args)
2504  {
2505    return getFunction(name).call(this, args);
2506  }
2507
2508  /**
2509   * Evaluates the named function.
2510   *
2511   * @param name the function name
2512   * @return the function value
2513   */

2514  public Value callRef(String JavaDoc name)
2515  {
2516    AbstractFunction fun = findFunction(name);
2517
2518    if (fun == null)
2519      return error(L.l("'{0}' is an unknown function.", name));
2520
2521    return fun.callRef(this);
2522  }
2523
2524  /**
2525   * EvalRefuates the named function.
2526   *
2527   * @param name the function name
2528   * @param a0 the first argument
2529   * @return the function value
2530   */

2531  public Value callRef(String JavaDoc name, Value a0)
2532  {
2533    AbstractFunction fun = findFunction(name);
2534
2535    if (fun == null)
2536      return error(L.l("'{0}' is an unknown function.", name));
2537
2538    return fun.callRef(this, a0);
2539  }
2540
2541  /**
2542   * EvalRefuates the named function.
2543   *
2544   * @param name the function name
2545   * @param a0 the first argument
2546   * @param a1 the second argument
2547   * @return the function value
2548   */

2549  public Value callRef(String JavaDoc name, Value a0, Value a1)
2550  {
2551    AbstractFunction fun = findFunction(name);
2552
2553    if (fun == null)
2554      return error(L.l("'{0}' is an unknown function.", name));
2555
2556    return fun.callRef(this, a0, a1);
2557  }
2558
2559  /**
2560   * EvalRefuates the named function.
2561   *
2562   * @param name the function name
2563   * @param a0 the first argument
2564   * @param a1 the second argument
2565   * @param a2 the third argument
2566   * @return the function value
2567   */

2568  public Value callRef(String JavaDoc name, Value a0, Value a1, Value a2)
2569  {
2570    AbstractFunction fun = findFunction(name);
2571
2572    if (fun == null)
2573      return error(L.l("'{0}' is an unknown function.", name));
2574
2575    return fun.callRef(this, a0, a1, a2);
2576  }
2577
2578  /**
2579   * Evaluates the named function.
2580   *
2581   * @param name the function name
2582   * @param a0 the first argument
2583   * @param a1 the second argument
2584   * @param a2 the third argument
2585   * @param a3 the fourth argument
2586   * @return the function value
2587   */

2588  public Value callRef(String JavaDoc name, Value a0, Value a1, Value a2, Value a3)
2589  {
2590    AbstractFunction fun = findFunction(name);
2591
2592    if (fun == null)
2593      return error(L.l("'{0}' is an unknown function.", name));
2594
2595    return fun.callRef(this, a0, a1, a2, a3);
2596  }
2597
2598  /**
2599   * Evaluates the named function.
2600   *
2601   * @param name the function name
2602   * @param a0 the first argument
2603   * @param a1 the second argument
2604   * @param a2 the third argument
2605   * @param a3 the fourth argument
2606   * @param a4 the fifth argument
2607   * @return the function value
2608   */

2609  public Value callRef(String JavaDoc name, Value a0, Value a1,
2610                       Value a2, Value a3, Value a4)
2611  {
2612    AbstractFunction fun = findFunction(name);
2613
2614    if (fun == null)
2615      return error(L.l("'{0}' is an unknown function.", name));
2616
2617    return fun.callRef(this, a0, a1, a2, a3, a4);
2618  }
2619
2620  /**
2621   * Evaluates the named function.
2622   *
2623   * @param name the function name
2624   * @param args the arguments
2625   * @return the function value
2626   */

2627  public Value callRef(String JavaDoc name, Value []args)
2628  {
2629    AbstractFunction fun = findFunction(name);
2630
2631    if (fun == null)
2632      return error(L.l("'{0}' is an unknown function.", name));
2633
2634    return fun.callRef(this, args);
2635  }
2636
2637  /**
2638   * Adds a class, e.g. from an include.
2639   */

2640  public void addClassDef(String JavaDoc name, ClassDef cl)
2641  {
2642    _defState.addClassDef(name, cl);
2643  }
2644
2645  public ClassDef findClassDef(String JavaDoc name)
2646  {
2647    return _defState.findClassDef(name);
2648  }
2649
2650  /**
2651   * Creates a stdClass object.
2652   */

2653  public ObjectValue createObject()
2654  {
2655    try {
2656      return (ObjectValue) _quercus.getStdClass().newInstance(this);
2657    }
2658    catch (Throwable JavaDoc e) {
2659      throw new QuercusModuleException(e);
2660    }
2661  }
2662
2663  /**
2664   * Creates a string from a byte.
2665   */

2666  public Value createString(byte []buffer, int offset, int length)
2667  {
2668    return new StringValueImpl(new String JavaDoc(buffer, offset, length));
2669  }
2670
2671  /**
2672   * Generate an object id.
2673   */

2674  public int generateId()
2675  {
2676    return ++_objectId;
2677  }
2678
2679  /**
2680   * Returns a Java class defintion.
2681   */

2682  public JavaClassDef getJavaClassDefinition(String JavaDoc className)
2683  {
2684    JavaClassDef def = _quercus.getJavaClassDefinition(className);
2685
2686    def.init();
2687
2688    return def;
2689  }
2690
2691  /**
2692   * Returns a PHP value for a Java object
2693   */

2694  public Value wrapJava(Object JavaDoc obj)
2695  {
2696    return wrapJava(obj, null, false);
2697  }
2698
2699  /**
2700   * Returns a PHP value for a Java object
2701   *
2702   * @param isNullAsFalse what to return if <i>obj</i> is null, if true return
2703   * {@link BooleanValue.FALSE} otherwise return {@link NullValue.NULL)
2704   */

2705  public Value wrapJava(Object JavaDoc obj, boolean isNullAsFalse)
2706  {
2707    return wrapJava(obj, null, isNullAsFalse);
2708  }
2709
2710  /**
2711   * Returns a PHP value for a Java object
2712   *
2713   * @param isNullAsFalse what to return if <i>obj</i> is null, if true return
2714   * {@link BooleanValue.FALSE} otherwise return {@link NullValue.NULL)
2715   */

2716  public Value wrapJava(Object JavaDoc obj, JavaClassDef def, boolean isNullAsFalse)
2717  {
2718    if (obj == null) {
2719      if (isNullAsFalse)
2720        return BooleanValue.FALSE;
2721      else
2722        return NullValue.NULL;
2723    }
2724
2725    if (obj instanceof Value)
2726      return (Value) obj;
2727
2728    if (def == null)
2729      def = getJavaClassDefinition(obj.getClass().getName());
2730    else if (def.getType() != obj.getClass()) {
2731      // XXX: what if types are incompatible, does it matter?
2732
// if it doesn;'t matter, simplikfy this to one if with no else
2733
def = getJavaClassDefinition(obj.getClass().getName());
2734    }
2735
2736    if (def.isArray()) {
2737      ArrayValueImpl arrayValueImpl = new ArrayValueImpl();
2738
2739      Class JavaDoc componentClass = def.getType().getComponentType();
2740
2741      MarshalFactory factory = _quercus.getModuleContext().getMarshalFactory();
2742      Marshal componentClassMarshal = factory.create(componentClass);
2743
2744      int length = Array.getLength(obj);
2745      
2746      for (int i = 0; i < length; i++) {
2747        arrayValueImpl.put(componentClassMarshal.unmarshal(this, Array.get(obj, i)));
2748      }
2749
2750      return arrayValueImpl;
2751    }
2752    else {
2753      return def.wrap(this, obj);
2754    }
2755  }
2756
2757  /**
2758   * Finds the class with the given name.
2759   *
2760   * @param name the class name
2761   * @return the found class or null if no class found.
2762   */

2763  public QuercusClass findClass(String JavaDoc name)
2764  {
2765    return findClass(name, true);
2766  }
2767
2768  /**
2769   * Finds the class with the given name.
2770   *
2771   * @param name the class name
2772   * @param useAutoload use autoload to locate the class if necessary
2773   * @return the found class or null if no class found.
2774   */

2775  public QuercusClass findClass(String JavaDoc name, boolean useAutoload)
2776  {
2777    QuercusClass cl = _classMap.get(name);
2778
2779    if (cl != null)
2780      return cl;
2781
2782    if (_lowerClassMap != null)
2783      cl = _lowerClassMap.get(name.toLowerCase());
2784
2785    if (cl != null)
2786      return cl;
2787
2788    cl = createClassImpl(name, useAutoload);
2789
2790    if (cl != null) {
2791      _classMap.put(name, cl);
2792
2793      if (_lowerClassMap != null)
2794    _lowerClassMap.put(name.toLowerCase(), cl);
2795
2796      return cl;
2797    }
2798    else
2799      return null;
2800  }
2801
2802  /**
2803   * Finds the class with the given name.
2804   *
2805   * @param name the class name
2806   * @param useAutoload use autoload to locate the class if necessary
2807   * @return the found class or null if no class found.
2808   */

2809  private QuercusClass createClassImpl(String JavaDoc name, boolean useAutoload)
2810  {
2811    ClassDef classDef = _defState.findClassDef(name);
2812
2813    if (classDef != null) {
2814      String JavaDoc parentName = classDef.getParentName();
2815
2816      QuercusClass parent = null;
2817
2818      if (parentName != null)
2819        parent = findClass(parentName);
2820
2821      if (parentName == null || parent instanceof QuercusClass)
2822        return createQuercusClass(classDef, (QuercusClass) parent);
2823      else
2824        return null; // php/
2825
}
2826
2827    ClassDef staticClass = _quercus.findClass(name);
2828    if (staticClass != null)
2829      return createQuercusClass(staticClass, null); // XXX: cache
2830

2831    if (useAutoload) {
2832      if (_autoload == null)
2833        _autoload = findFunction("__autoload");
2834      
2835      if (_autoload != null) {
2836    _autoload.call(this, new StringValueImpl(name));
2837    return createClassImpl(name, false);
2838      }
2839    }
2840
2841
2842    return null;
2843  }
2844
2845  /**
2846   * Returns the declared classes.
2847   *
2848   * @return an array of the declared classes()
2849   */

2850  public Value getDeclaredClasses()
2851  {
2852    return _defState.getDeclaredClasses();
2853  }
2854
2855  /**
2856   * Finds the class with the given name.
2857   *
2858   * @param name the class name
2859   * @return the found class or null if no class found.
2860   */

2861  public QuercusClass findAbstractClass(String JavaDoc name)
2862  {
2863    QuercusClass cl = findClass(name, true);
2864
2865    if (cl != null)
2866      return cl;
2867
2868    throw errorException(L.l("'{0}' is an unknown class name.", name));
2869    /*
2870    // return _quercus.findJavaClassWrapper(name);
2871
2872    return null;
2873    */

2874  }
2875
2876  /**
2877   * Finds the class with the given name.
2878   *
2879   * @param name the class name
2880   * @return the found class or null if no class found.
2881   */

2882  public QuercusClass getClass(String JavaDoc name)
2883  {
2884    QuercusClass cl = findClass(name);
2885
2886    if (cl != null)
2887      return cl;
2888    else
2889      throw errorException(L.l("'{0}' is an unknown class.", name));
2890  }
2891
2892  private QuercusClass createQuercusClass(ClassDef def, QuercusClass parent)
2893  {
2894    ClassKey key = new ClassKey(def, parent);
2895
2896    SoftReference JavaDoc<QuercusClass> qClassRef = _classCache.get(key);
2897    QuercusClass qClass;
2898
2899    if (qClassRef != null) {
2900      qClass = qClassRef.get();
2901
2902      if (qClass != null) {
2903        qClass.init(this);
2904        return qClass;
2905      }
2906    }
2907
2908    qClass = new QuercusClass(def, parent);
2909    qClass.validate(this);
2910
2911    _classCache.put(key, new SoftReference JavaDoc<QuercusClass>(qClass));
2912
2913    qClass.init(this);
2914
2915    return qClass;
2916  }
2917
2918  /**
2919   * Finds the class and method.
2920   *
2921   * @param className the class name
2922   * @param methodName the method name
2923   * @return the found method or null if no method found.
2924   */

2925  public AbstractFunction findFunction(String JavaDoc className, String JavaDoc methodName)
2926  {
2927    QuercusClass cl = findClass(className);
2928
2929    if (cl == null)
2930      throw new QuercusRuntimeException(L.l("'{0}' is an unknown class",
2931                                            className));
2932
2933    return cl.findFunction(methodName);
2934  }
2935
2936  /**
2937   * Returns the appropriate callback.
2938   */

2939  public Callback createCallback(Value value)
2940  {
2941    if (value == null || value.isNull())
2942      return null;
2943
2944    value = value.toValue();
2945
2946    if (value instanceof Callback)
2947      return (Callback) value;
2948
2949    else if (value instanceof StringValue)
2950      return new CallbackFunction(this, value.toString());
2951
2952    else if (value instanceof ArrayValue) {
2953      Value obj = value.get(LongValue.ZERO);
2954      Value name = value.get(LongValue.ONE);
2955
2956      if (! (name instanceof StringValue))
2957        throw new IllegalStateException JavaDoc(L.l("unknown callback name {0}", name));
2958
2959      if (obj instanceof StringValue) {
2960        QuercusClass cl = findClass(obj.toString());
2961
2962        if (cl == null)
2963          throw new IllegalStateException JavaDoc(L.l("can't find class {0}",
2964                                              obj.toString()));
2965
2966        return new CallbackFunction(cl.getFunction(name.toString()));
2967      }
2968      else {
2969        return new CallbackObjectMethod(this, obj, name.toString());
2970      }
2971    }
2972    else
2973      return null;
2974  }
2975
2976  /**
2977   * Evaluates an included file.
2978   */

2979  public Value require_once(String JavaDoc include)
2980  {
2981    return include(getSelfDirectory(), include, true, true);
2982  }
2983
2984  /**
2985   * Evaluates an included file.
2986   */

2987  public Value require(String JavaDoc include)
2988  {
2989    return include(getSelfDirectory(), include, true, false);
2990  }
2991
2992  /**
2993   * Evaluates an included file.
2994   */

2995  public Value include(String JavaDoc include)
2996  {
2997    return include(getSelfDirectory(), include, false, false);
2998  }
2999
3000  /**
3001   * Evaluates an included file.
3002   */

3003  public Value include_once(String JavaDoc include)
3004  {
3005    return include(getSelfDirectory(), include, false, true);
3006  }
3007
3008  /**
3009   * Evaluates an included file.
3010   */

3011  public Value include(Path scriptPwd, String JavaDoc include,
3012               boolean isRequire, boolean isOnce)
3013  {
3014    try {
3015      Path pwd = getPwd();
3016
3017      Path path = lookupInclude(include, pwd, scriptPwd);
3018
3019      if (path != null) {
3020      }
3021      else if (isRequire) {
3022    error(L.l("'{0}' is not a valid path", include));
3023    return NullValue.NULL;
3024      }
3025      else {
3026    warning(L.l("'{0}' is not a valid path", include));
3027    return NullValue.NULL;
3028      }
3029
3030      if (isOnce && _includeSet.contains(path))
3031    return NullValue.NULL;
3032
3033      _includeSet.add(path);
3034
3035      QuercusPage page;
3036
3037      page = _quercus.parse(path);
3038
3039      importPage(page);
3040
3041      return page.execute(this);
3042    } catch (IOException JavaDoc e) {
3043      throw new QuercusModuleException(e);
3044    }
3045  }
3046
3047  private void importPage(QuercusPage page)
3048  {
3049    long crc = _defState.getCrc();
3050
3051    DefinitionKey key = new DefinitionKey(crc, page);
3052      
3053    DefinitionState defState = _quercus.getDefinitionCache(key);
3054
3055    if (defState != null) {
3056      _defState = defState;
3057    }
3058    else {
3059      page.importDefinitions(this);
3060
3061      _quercus.putDefinitionCache(key, _defState);
3062    }
3063  }
3064
3065  /**
3066   * Looks up based on the pwd.
3067   */

3068  public Path lookupPwd(Value relPathV)
3069  {
3070    if (! relPathV.isset())
3071      return null;
3072
3073    StringValue relPath = relPathV.toStringValue();
3074
3075    if (relPath.length() == 0)
3076      return null;
3077    
3078    Path path = _lookupCache.get(relPath);
3079
3080    if (path == null) {
3081      path = getPwd().lookup(relPath.toString());
3082      _lookupCache.put(relPath, path);
3083    }
3084
3085    return path;
3086  }
3087
3088  /**
3089   * Looks up the path.
3090   */

3091  public Path lookup(String JavaDoc relPath)
3092  {
3093    return lookupInclude(getSelfDirectory(), relPath);
3094  }
3095
3096  /**
3097   * Looks up the path.
3098   */

3099  public Path lookupInclude(String JavaDoc relPath)
3100  {
3101    return lookupInclude(relPath, getPwd(), getSelfDirectory());
3102  }
3103
3104  private Path lookupInclude(String JavaDoc include, Path pwd, Path scriptPwd)
3105  {
3106    String JavaDoc includePath = getIniString("include_path");
3107
3108    if (includePath == null)
3109      includePath = ".";
3110    
3111    Path path = _quercus.getIncludeCache(include, includePath, pwd, scriptPwd);
3112
3113    if (path == null) {
3114      path = lookupIncludeImpl(include, pwd, scriptPwd);
3115
3116      if (path != null)
3117    _quercus.putIncludeCache(include, includePath, pwd, scriptPwd, path);
3118    }
3119    
3120    return path;
3121  }
3122    
3123  private Path lookupIncludeImpl(String JavaDoc include, Path pwd, Path scriptPwd)
3124  {
3125    // php/0b0g
3126

3127    Path path = lookupInclude(pwd, include);
3128
3129    if (path == null) {
3130      // php/0b0l
3131
path = lookupInclude(scriptPwd, include);
3132    }
3133
3134    if (path == null) {
3135      // php/0b21
3136
path = scriptPwd.lookup(include);
3137
3138      if (! path.canRead() || path.isDirectory())
3139    path = null;
3140    }
3141
3142    return path;
3143  }
3144
3145  /**
3146   * Looks up the path.
3147   */

3148  private Path lookupInclude(Path pwd, String JavaDoc relPath)
3149  {
3150    ArrayList JavaDoc<Path> pathList = getIncludePath(pwd);
3151
3152    for (int i = 0; i < pathList.size(); i++) {
3153      Path path = pathList.get(i).lookup(relPath);
3154
3155      if (path.canRead() && ! path.isDirectory()) {
3156        return path;
3157      }
3158    }
3159
3160    return null;
3161  }
3162
3163  /**
3164   * Returns the include path.
3165   */

3166  private ArrayList JavaDoc<Path> getIncludePath(Path pwd)
3167  {
3168    String JavaDoc includePath = getIniString("include_path");
3169
3170    if (includePath == null)
3171      includePath = ".";
3172
3173    if (! includePath.equals(_includePath)) {
3174      _includePathList = new ArrayList JavaDoc<String JavaDoc>();
3175      _includePathMap = new HashMap JavaDoc<Path,ArrayList JavaDoc<Path>>();
3176
3177      int head = 0;
3178      int tail;
3179      while ((tail = includePath.indexOf(':', head)) >= 0) {
3180        String JavaDoc subpath = includePath.substring(head, tail);
3181
3182        _includePathList.add(subpath);
3183
3184        head = tail + 1;
3185      }
3186
3187      String JavaDoc subpath = includePath.substring(head);
3188
3189      _includePathList.add(subpath);
3190
3191      _includePath = includePath;
3192    }
3193
3194    ArrayList JavaDoc<Path> pathList = _includePathMap.get(pwd);
3195
3196    if (pathList == null) {
3197      pathList = new ArrayList JavaDoc<Path>();
3198
3199      for (int i = 0; i < _includePathList.size(); i++) {
3200    pathList.add(pwd.lookup(_includePathList.get(i)));
3201      }
3202
3203      _includePathMap.put(pwd, pathList);
3204    }
3205
3206    return pathList;
3207  }
3208
3209  /**
3210   * Sets the include path.
3211   */

3212  public String JavaDoc setIncludePath(String JavaDoc path)
3213  {
3214    _prevIncludePath = getIniString("include_path");
3215
3216    if (_prevIncludePath == null)
3217      _prevIncludePath = "";
3218
3219    setIni("include_path", path);
3220
3221    return _prevIncludePath;
3222  }
3223
3224  /**
3225   * Restores the previous include path.
3226   */

3227  public void restoreIncludePath()
3228  {
3229    String JavaDoc path = getIniString("include_path");
3230
3231    setIni("include_path", _prevIncludePath);
3232
3233    _prevIncludePath = path;
3234  }
3235
3236  /**
3237   * Handles error suppression.
3238   */

3239  public Value suppress(int errorMask, Value value)
3240  {
3241    setErrorMask(errorMask);
3242
3243    return value;
3244  }
3245
3246  /**
3247   * Handles exit/die
3248   */

3249  public Value exit(String JavaDoc msg)
3250  {
3251    try {
3252      getOut().print(msg);
3253    } catch (IOException JavaDoc e) {
3254      log.log(Level.WARNING, e.toString(), e);
3255    }
3256
3257    throw new QuercusExitException(msg);
3258  }
3259
3260  /**
3261   * Handles exit/die
3262   */

3263  public Value exit()
3264  {
3265    throw new QuercusExitException();
3266  }
3267
3268  /**
3269   * Handles exit/die
3270   */

3271  public Value die(String JavaDoc msg)
3272  {
3273    try {
3274      getOut().print(msg);
3275    } catch (IOException JavaDoc e) {
3276      log.log(Level.WARNING, e.toString(), e);
3277    }
3278
3279    throw new QuercusDieException(msg);
3280  }
3281
3282  /**
3283   * Handles exit/die
3284   */

3285  public Value die()
3286  {
3287    throw new QuercusDieException();
3288  }
3289
3290  /**
3291   * Handles exit/die
3292   */

3293  public Value cast(Class JavaDoc cl, Value value)
3294  {
3295    value = value.toValue();
3296
3297    if (value.isNull())
3298      return null;
3299    else if (cl.isAssignableFrom(value.getClass()))
3300      return value;
3301    else {
3302      error(L.l("{0} ({1}) is not assignable to {2}",
3303                value, value.getClass().getName(), cl.getName()));
3304
3305      return value;
3306    }
3307  }
3308
3309  /**
3310   * Returns the first value
3311   */

3312  public static Value first(Value value)
3313  {
3314    return value;
3315  }
3316
3317  /**
3318   * Returns the first value
3319   */

3320  public static Value first(Value value, Value a1)
3321  {
3322    return value;
3323  }
3324
3325  /**
3326   * Returns the first value
3327   */

3328  public static Value first(Value value, Value a1, Value a2)
3329  {
3330    return value;
3331  }
3332
3333  /**
3334   * Returns the first value
3335   */

3336  public static Value first(Value value, Value a1, Value a2, Value a3)
3337  {
3338    return value;
3339  }
3340
3341  /**
3342   * Returns the first value
3343   */

3344  public static Value first(Value value, Value a1, Value a2, Value a3,
3345                            Value a4)
3346  {
3347    return value;
3348  }
3349
3350  /**
3351   * Returns the first value
3352   */

3353  public static Value first(Value value, Value a1, Value a2, Value a3,
3354                            Value a4, Value a5)
3355  {
3356    return value;
3357  }
3358
3359  /**
3360   * A fatal runtime error.
3361   */

3362  public Value error(String JavaDoc msg)
3363  {
3364    return error(B_ERROR, "", msg + getFunctionLocation());
3365  }
3366
3367  /**
3368   * A fatal runtime error.
3369   */

3370  public Value error(String JavaDoc loc, String JavaDoc msg)
3371  {
3372    return error(B_ERROR, loc, msg + getFunctionLocation());
3373  }
3374
3375  /**
3376   * A warning with an exception.
3377   */

3378  public Value error(String JavaDoc msg, Throwable JavaDoc e)
3379  {
3380    log.log(Level.WARNING, e.toString(), e);
3381
3382    return error(msg);
3383  }
3384
3385  /**
3386   * A warning with an exception.
3387   */

3388  public Value error(Throwable JavaDoc e)
3389  {
3390    log.log(Level.WARNING, e.toString(), e);
3391
3392    return error(e.toString());
3393  }
3394
3395  /**
3396   * A fatal runtime error.
3397   */

3398  public RuntimeException JavaDoc errorException(String JavaDoc msg)
3399  {
3400    Location location = getLocation();
3401    String JavaDoc prefix = location.getMessagePrefix();
3402    
3403    String JavaDoc fullMsg = prefix + msg + getFunctionLocation();
3404
3405    error(B_ERROR, "", fullMsg);
3406
3407    throw new QuercusRuntimeException(fullMsg);
3408  }
3409
3410  /**
3411   * A runtime warning.
3412   */

3413  public Value warning(String JavaDoc msg)
3414  {
3415    if (log.isLoggable(Level.FINER)) {
3416      QuercusException e = new QuercusException(msg);
3417
3418      log.log(Level.FINER, e.toString(), e);
3419    }
3420
3421    return error(B_WARNING, "", msg + getFunctionLocation());
3422  }
3423
3424  /**
3425   * A warning with an exception.
3426   */

3427  public Value warning(String JavaDoc msg, Throwable JavaDoc e)
3428  {
3429    log.log(Level.FINE, e.toString(), e);
3430
3431    return warning(msg);
3432  }
3433
3434  /**
3435   * A warning with an exception.
3436   */

3437  public Value warning(Throwable JavaDoc e)
3438  {
3439    return warning(e.toString(), e);
3440  }
3441
3442  /**
3443   * A runtime strict warning.
3444   */

3445  public Value strict(String JavaDoc msg)
3446  {
3447    if (log.isLoggable(Level.FINER)) {
3448      QuercusException e = new QuercusException(msg);
3449
3450      log.log(Level.FINER, e.toString(), e);
3451    }
3452
3453    return error(B_STRICT, "", msg + getFunctionLocation());
3454  }
3455
3456  /**
3457   * A warning about an invalid argument passed to a function.
3458   */

3459  public Value invalidArgument(String JavaDoc name, Object JavaDoc value)
3460  {
3461    return warning(L.l("invalid value `{0}' for `{1}'", value, name));
3462  }
3463
3464  /**
3465   * A warning about an deprecated argument passed to a function.
3466   */

3467  public Value deprecatedArgument(String JavaDoc name)
3468  {
3469    return strict(L.l("argument `{1}' is deprecated", name));
3470  }
3471
3472  /**
3473   * A notice.
3474   */

3475  public Value notice(String JavaDoc msg)
3476  {
3477    return error(B_NOTICE, "", msg + getFunctionLocation());
3478  }
3479
3480  /**
3481   * A notice with an exception.
3482   */

3483  public Value notice(String JavaDoc msg, Throwable JavaDoc e)
3484  {
3485    log.log(Level.FINE, e.toString(), e);
3486
3487    return notice(msg);
3488  }
3489
3490  /**
3491   * A stub notice.
3492   */

3493  public Value stub(String JavaDoc msg)
3494  {
3495    if (log.isLoggable(Level.FINE))
3496      log.fine(getLocation().getMessagePrefix() + msg);
3497
3498    return NullValue.NULL;
3499  }
3500
3501  public static Value nullAsFalse(Value value)
3502  {
3503    return value == null || value.isNull() ? BooleanValue.FALSE : value;
3504  }
3505
3506  /**
3507   * A parse error
3508   */

3509  public Value parse(String JavaDoc msg)
3510    throws Exception JavaDoc
3511  {
3512    return error(B_PARSE, "", msg);
3513  }
3514
3515  /**
3516   * A parse error
3517   */

3518  public Value compileError(String JavaDoc msg)
3519  {
3520    return error(B_COMPILE_ERROR, "", msg);
3521  }
3522
3523  /**
3524   * A parse warning
3525   */

3526  public Value compileWarning(String JavaDoc msg)
3527  {
3528    return error(B_COMPILE_WARNING, "", msg);
3529  }
3530
3531  /**
3532   * Returns the error mask.
3533   */

3534  public int getErrorMask()
3535  {
3536    return _errorMask;
3537  }
3538
3539  /**
3540   * Sets the error mask.
3541   */

3542  public int setErrorMask(int mask)
3543  {
3544    int oldMask = _errorMask;
3545
3546    _errorMask = mask;
3547
3548    return oldMask;
3549  }
3550
3551  /**
3552   * Sets an error handler
3553   */

3554  public void setErrorHandler(int mask, Callback fun)
3555  {
3556    for (int i = 0; i < _errorHandlers.length; i++)
3557      _prevErrorHandlers[i] = _errorHandlers[i];
3558
3559    if ((mask & E_ERROR) != 0)
3560      _errorHandlers[B_ERROR] = fun;
3561
3562    if ((mask & E_WARNING) != 0)
3563      _errorHandlers[B_WARNING] = fun;
3564
3565    if ((mask & E_PARSE) != 0)
3566      _errorHandlers[B_PARSE] = fun;
3567
3568    if ((mask & E_NOTICE) != 0)
3569      _errorHandlers[B_NOTICE] = fun;
3570
3571    if ((mask & E_USER_ERROR) != 0)
3572      _errorHandlers[B_USER_ERROR] = fun;
3573
3574    if ((mask & E_USER_WARNING) != 0)
3575      _errorHandlers[B_USER_WARNING] = fun;
3576
3577    if ((mask & E_USER_NOTICE) != 0)
3578      _errorHandlers[B_USER_NOTICE] = fun;
3579
3580    if ((mask & E_STRICT) != 0)
3581      _errorHandlers[B_STRICT] = fun;
3582  }
3583
3584  /**
3585   * Sets an error handler
3586   */

3587  public void restoreErrorHandler()
3588  {
3589    for (int i = 0; i < _errorHandlers.length; i++)
3590      _errorHandlers[i] = _prevErrorHandlers[i];
3591  }
3592  
3593  /**
3594   * Gets the exception handler
3595   */

3596  public Callback getExceptionHandler()
3597  {
3598    return _exceptionHandler;
3599  }
3600  
3601  /**
3602   * Sets an exception handler
3603   */

3604  public Value setExceptionHandler(Callback fun)
3605  {
3606    _prevExceptionHandler = _exceptionHandler;
3607    
3608    _exceptionHandler = fun;
3609
3610    if (_prevExceptionHandler != null)
3611      return _prevExceptionHandler.toStringValue();
3612    else
3613      return NullValue.NULL;
3614  }
3615  
3616  /**
3617   * Restore an exception handler
3618   */

3619  public void restoreExceptionHandler()
3620  {
3621    _exceptionHandler = _prevExceptionHandler;
3622  }
3623
3624  /**
3625   * Writes an error.
3626   */

3627  public Value error(int code, String JavaDoc loc, String JavaDoc msg)
3628  {
3629    int mask = 1 << code;
3630
3631    Location location = getLocation();
3632
3633    String JavaDoc locationMessagePrefix = loc;
3634
3635    if (loc.equals(""))
3636      locationMessagePrefix = location.getMessagePrefix();
3637
3638    if (code >= 0 && code < _errorHandlers.length &&
3639        _errorHandlers[code] != null) {
3640      Callback handler = _errorHandlers[code];
3641
3642      try {
3643        _errorHandlers[code] = null;
3644
3645        Value fileNameV = NullValue.NULL;
3646
3647        String JavaDoc fileName = location.getFileName();
3648
3649        if (fileName != null)
3650          fileNameV = new StringValueImpl(fileName);
3651
3652        Value lineV = NullValue.NULL;
3653        int line = location.getLineNumber();
3654        if (line > 0)
3655          lineV = new LongValue(line);
3656
3657        Value context = NullValue.NULL;
3658
3659        handler.call(this, new LongValue(mask), new StringValueImpl(msg),
3660                     fileNameV, lineV, context);
3661
3662        return NullValue.NULL;
3663      }
3664      catch (RuntimeException JavaDoc e) {
3665        throw e;
3666      }
3667      catch (Throwable JavaDoc e) {
3668        throw new RuntimeException JavaDoc(e);
3669      }
3670      finally {
3671        _errorHandlers[code] = handler;
3672      }
3673    }
3674
3675    if ((_errorMask & mask) != 0) {
3676      try {
3677    String JavaDoc fullMsg = locationMessagePrefix + getCodeName(mask) + msg;
3678
3679    if (getIniBoolean("track_errors"))
3680      setGlobalValue("php_errormsg", new StringValueImpl(fullMsg));
3681
3682    if (getIniBoolean("display_errors"))
3683      getOut().println(fullMsg);
3684
3685    if (getIniBoolean("log_errors"))
3686      log.info(fullMsg);
3687      }
3688      catch (IOException JavaDoc e) {
3689        log.log(Level.FINE, e.toString(), e);
3690      }
3691    }
3692
3693    if ((mask & (E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR)) != 0)
3694    {
3695      if (! "".equals(locationMessagePrefix)) {
3696    /*
3697        throw new QuercusLineExitException(getLocation() +
3698                                              getCodeName(mask) +
3699                                              msg);
3700    */

3701        throw new QuercusExitException(locationMessagePrefix +
3702                                       getCodeName(mask) +
3703                                       msg);
3704      }
3705      else
3706        throw new QuercusExitException(msg);
3707    }
3708
3709    return NullValue.NULL;
3710  }
3711
3712  /**
3713   * Returns the error code name.
3714   */

3715  private String JavaDoc getCodeName(int code)
3716  {
3717    switch (code) {
3718    case E_ERROR:
3719      return "Fatal Error: ";
3720    case E_WARNING:
3721      return "Warning: ";
3722    case E_PARSE:
3723      return "Parse Error: ";
3724    case E_NOTICE:
3725      return "Notice: ";
3726    case E_CORE_ERROR:
3727      return "Fatal Error: ";
3728    case E_CORE_WARNING:
3729      return "Warning: ";
3730    case E_COMPILE_ERROR:
3731      return "Fatal Error: ";
3732    case E_COMPILE_WARNING:
3733      return "Warning : ";
3734    case E_USER_ERROR:
3735      return "Fatal Error: ";
3736    case E_USER_WARNING:
3737      return "Warning: ";
3738    case E_USER_NOTICE:
3739      return "Notice: ";
3740    case E_STRICT:
3741      return "Notice: ";
3742
3743    default:
3744      return String.valueOf("ErrorCode(" + code + ")");
3745    }
3746  }
3747
3748  /**
3749   * Returns the source of an error line.
3750   */

3751  public static String JavaDoc []getSourceLine(Path path, int sourceLine, int length)
3752  {
3753    if (path == null)
3754      return null;
3755
3756    ReadStream is = null;
3757
3758    try {
3759      is = path.openRead();
3760      int ch;
3761      boolean hasCr = false;
3762      int line = 1;
3763
3764      while (line < sourceLine) {
3765        ch = is.read();
3766
3767        if (ch < 0)
3768          return null;
3769        else if (ch == '\r') {
3770          hasCr = true;
3771          line++;
3772        }
3773        else if (ch == '\n') {
3774          if (! hasCr)
3775            line++;
3776          hasCr = false;
3777        }
3778        else
3779          hasCr = false;
3780      }
3781
3782      String JavaDoc []result = new String JavaDoc[length];
3783
3784      int i = 0;
3785      StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
3786      while (i < length && (ch = is.read()) > 0) {
3787        if (ch == '\n' && hasCr) {
3788          hasCr = false;
3789          continue;
3790        }
3791        else if (ch == '\r') {
3792          hasCr = true;
3793          result[i++] = sb.toString();
3794          sb.setLength(0);
3795        }
3796        else if (ch == '\n') {
3797          hasCr = false;
3798          result[i++] = sb.toString();
3799          sb.setLength(0);
3800        }
3801        else {
3802          hasCr = false;
3803          sb.append((char) ch);
3804        }
3805      }
3806
3807      if (i < length)
3808        result[i] = sb.toString();
3809
3810      return result;
3811    }
3812    catch (IOException JavaDoc e) {
3813      log.log(Level.FINE, e.toString(), e);
3814    }
3815    finally {
3816      if (is != null)
3817    is.close();
3818    }
3819
3820    return null;
3821  }
3822
3823  /**
3824   * Returns the current execution location.
3825   *
3826   * Use with care, for compiled code this can be a relatively expensive
3827   * operation.
3828   */

3829  public Location getLocation()
3830  {
3831    Expr call = peekCall(0);
3832
3833    if (call != null)
3834      return call.getLocation();
3835
3836    return Location.UNKNOWN;
3837  }
3838
3839  public int getSourceLine(String JavaDoc className, int javaLine)
3840  {
3841    return javaLine;
3842  }
3843
3844  /**
3845   * Returns the current function.
3846   */

3847  public String JavaDoc getFunctionLocation()
3848  {
3849    // XXX: need to work with compiled code, too
3850
Expr call = peekCall(0);
3851
3852    if (call != null)
3853      return call.getFunctionLocation();
3854    else
3855      return "";
3856  }
3857
3858  /**
3859   * Converts a boolean to the boolean value
3860   */

3861  public static Value toValue(boolean value)
3862  {
3863    return value ? BooleanValue.TRUE : BooleanValue.FALSE;
3864  }
3865
3866  /**
3867   * Converts a boolean to the boolean value
3868   */

3869  public static Value toValue(long value)
3870  {
3871    return new LongValue(value);
3872  }
3873
3874  /**
3875   * Converts to a variable
3876   */

3877  public static Var toVar(Value value)
3878  {
3879    if (value instanceof Var)
3880      return (Var) value;
3881    else if (value == null)
3882      return new Var();
3883    else
3884      return new Var(value);
3885  }
3886
3887  /**
3888   * Sets a vield variable
3889   */

3890  public static Value setFieldVar(Value oldValue, Value value)
3891  {
3892    if (value instanceof Var)
3893      return value;
3894    else if (oldValue instanceof Var)
3895      return new Var(value);
3896    else
3897      return value;
3898  }
3899
3900  /**
3901   * Sets a reference
3902   */

3903  public static Value setRef(Value oldValue, Value value)
3904  {
3905    // php/3243
3906
if (value instanceof Var)
3907      return value;
3908    /*
3909    else if (oldValue instanceof Var) {
3910      oldValue.set(value);
3911
3912      return oldValue;
3913    }
3914    */

3915    else
3916      return new Var(value);
3917  }
3918
3919  /**
3920   * Returns the last value.
3921   */

3922  public static Value comma(Value a0, Value a1)
3923  {
3924    return a1;
3925  }
3926
3927  /**
3928   * Returns the last value.
3929   */

3930  public static Value comma(Value a0, Value a1, Value a2)
3931  {
3932    return a2;
3933  }
3934
3935  /**
3936   * Returns the last value.
3937   */

3938  public static Value comma(Value a0, Value a1, Value a2, Value a3)
3939  {
3940    return a3;
3941  }
3942
3943  /**
3944   * Returns the last value.
3945   */

3946  public static Value comma(Value a0, Value a1, Value a2, Value a3, Value a4)
3947  {
3948    return a4;
3949  }
3950
3951  public String JavaDoc toString()
3952  {
3953    return "Env[]";
3954  }
3955
3956  /**
3957   * Returns ifNull if condition.isNull(), otherwise returns ifNotNull.
3958   */

3959  public Value ifNull(Value condition, Value ifNull, Value ifNotNull)
3960  {
3961    return condition.isNull() ? ifNull : ifNotNull;
3962  }
3963
3964  /**
3965   * Returns the locale info.
3966   */

3967  public LocaleInfo getLocaleInfo()
3968  {
3969    if (_locale == null)
3970      _locale = new LocaleInfo();
3971
3972    return _locale;
3973  }
3974
3975  /**
3976   * Registers a shutdown function.
3977   */

3978  public void addShutdown(Callback callback, Value []args)
3979  {
3980    _shutdownList.add(new Shutdown JavaDoc(callback, args));
3981  }
3982
3983  /**
3984   * Called when the Env is no longer needed.
3985   */

3986  public void close()
3987  {
3988    while (_outputBuffer != null)
3989      popOutputBuffer();
3990
3991    try {
3992      for (int i = 0; i < _shutdownList.size(); i++)
3993        _shutdownList.get(i).call(this);
3994    }
3995    catch (Throwable JavaDoc e) {
3996      log.log(Level.FINE, e.toString(), e);
3997    }
3998
3999    sessionWriteClose();
4000
4001    ArrayList JavaDoc<SoftReference JavaDoc<Closeable JavaDoc>> closeList;
4002    closeList = new ArrayList JavaDoc<SoftReference JavaDoc<Closeable JavaDoc>>(_closeList);
4003    
4004    for (SoftReference JavaDoc<Closeable JavaDoc> ref : closeList) {
4005      try {
4006        Closeable JavaDoc close = ref.get();
4007
4008        if (close != null)
4009          close.close();
4010      }
4011      catch (Throwable JavaDoc e) {
4012        log.log(Level.FINER, e.toString(), e);
4013      }
4014    }
4015
4016    for (int i = 0; _removePaths != null && i < _removePaths.size(); i++) {
4017      Path path = _removePaths.get(i);
4018
4019      try {
4020        path.remove();
4021      }
4022      catch (IOException JavaDoc e) {
4023        log.log(Level.FINER, e.toString(), e);
4024      }
4025    }
4026  }
4027
4028  public void sessionWriteClose()
4029  {
4030    SessionArrayValue session = _session;
4031
4032    _session = null;
4033
4034    if (session != null && session.getSize() > 0) {
4035      SessionCallback callback = getSessionCallback();
4036
4037      if (callback != null) {
4038        String JavaDoc value = VariableModule.serialize(session.getArray());
4039
4040        callback.write(this, session.getId(), value);
4041
4042        callback.close(this);
4043      }
4044      else {
4045        _quercus.saveSession(this, session);
4046
4047        setGlobalValue("_SESSION", session.copy(this));
4048        setGlobalValue("HTTP_SESSION_VARS", session.copy(this));
4049      }
4050    }
4051  }
4052
4053  static class ClassKey {
4054    private final WeakReference JavaDoc<ClassDef> _defRef;
4055    private final WeakReference JavaDoc<QuercusClass> _parentRef;
4056
4057    ClassKey(ClassDef def, QuercusClass parent)
4058    {
4059      _defRef = new WeakReference JavaDoc<ClassDef>(def);
4060
4061      if (parent != null)
4062    _parentRef = new WeakReference JavaDoc<QuercusClass>(parent);
4063      else
4064    _parentRef = null;
4065    }
4066
4067    public int hashCode()
4068    {
4069      int hash = 37;
4070
4071      ClassDef def = _defRef.get();
4072      
4073      QuercusClass parent = null;
4074      if (_parentRef != null)
4075    parent = _parentRef.get();
4076
4077      if (def != null)
4078    hash = 65521 * hash + def.hashCode();
4079
4080      if (parent != null)
4081    hash = 65521 * hash + parent.hashCode();
4082
4083      return hash;
4084    }
4085
4086    public boolean equals(Object JavaDoc o)
4087    {
4088      ClassKey key = (ClassKey) o;
4089
4090      ClassDef aDef = _defRef.get();
4091      ClassDef bDef = key._defRef.get();
4092
4093      if (aDef != bDef)
4094    return false;
4095
4096      if (_parentRef == key._parentRef)
4097    return true;
4098      
4099      else if (_parentRef != null && key._parentRef != null)
4100    return _parentRef.get() == key._parentRef.get();
4101
4102      else
4103    return false;
4104    }
4105  }
4106
4107  static class ConnectionEntry {
4108    private DataSource JavaDoc _ds;
4109    private String JavaDoc _user;
4110    private String JavaDoc _password;
4111    private Connection JavaDoc _conn;
4112
4113    public void init(DataSource JavaDoc ds, String JavaDoc user, String JavaDoc password)
4114    {
4115      _ds = ds;
4116      _user = user;
4117      _password = password;
4118    }
4119
4120    public void setConnection(Connection JavaDoc conn)
4121    {
4122      _conn = conn;
4123    }
4124
4125    public Connection JavaDoc getConnection()
4126    {
4127      return _conn;
4128    }
4129
4130    public int hashCode()
4131    {
4132      int hash = _ds.hashCode();
4133      
4134      if (_user == null)
4135    return hash;
4136      else
4137    return 65521 * hash + _user.hashCode();
4138    }
4139
4140    public boolean equals(Object JavaDoc o)
4141    {
4142      if (! (o instanceof ConnectionEntry))
4143    return false;
4144
4145      ConnectionEntry entry = (ConnectionEntry) o;
4146
4147      if (_ds != entry._ds)
4148    return false;
4149      else if (_user == null)
4150    return entry._user == null;
4151      else
4152    return _user.equals(entry._user);
4153    }
4154  }
4155
4156  static {
4157    SPECIAL_VARS.put("GLOBALS", _GLOBAL);
4158    SPECIAL_VARS.put("_SERVER", _SERVER);
4159    SPECIAL_VARS.put("_GET", _GET);
4160    SPECIAL_VARS.put("_POST", _POST);
4161    SPECIAL_VARS.put("_FILES", _FILES);
4162    SPECIAL_VARS.put("_REQUEST", _REQUEST);
4163    SPECIAL_VARS.put("_COOKIE", _COOKIE);
4164    SPECIAL_VARS.put("_SESSION", _SESSION);
4165    SPECIAL_VARS.put("_ENV", _ENV);
4166    SPECIAL_VARS.put("HTTP_GET_VARS", HTTP_GET_VARS);
4167    SPECIAL_VARS.put("HTTP_POST_VARS", HTTP_POST_VARS);
4168    SPECIAL_VARS.put("HTTP_POST_FILES", HTTP_POST_FILES);
4169    SPECIAL_VARS.put("HTTP_COOKIE_VARS", HTTP_COOKIE_VARS);
4170    SPECIAL_VARS.put("HTTP_SERVER_VARS", HTTP_SERVER_VARS);
4171    SPECIAL_VARS.put("PHP_SELF", PHP_SELF);
4172  }
4173}
4174
4175
Popular Tags