Source Code Cross Referenced for Env.java in  » EJB-Server-resin-3.1.5 » quercus » com » caucho » quercus » env » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » EJB Server resin 3.1.5 » quercus » com.caucho.quercus.env 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
0003:         *
0004:         * This file is part of Resin(R) Open Source
0005:         *
0006:         * Each copy or derived work must preserve the copyright notice and this
0007:         * notice unmodified.
0008:         *
0009:         * Resin Open Source is free software; you can redistribute it and/or modify
0010:         * it under the terms of the GNU General Public License as published by
0011:         * the Free Software Foundation; either version 2 of the License, or
0012:         * (at your option) any later version.
0013:         *
0014:         * Resin Open Source is distributed in the hope that it will be useful,
0015:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
0017:         * of NON-INFRINGEMENT.  See the GNU General Public License for more
0018:         * details.
0019:         *
0020:         * You should have received a copy of the GNU General Public License
0021:         * along with Resin Open Source; if not, write to the
0022:         *
0023:         *   Free Software Foundation, Inc.
0024:         *   59 Temple Place, Suite 330
0025:         *   Boston, MA 02111-1307  USA
0026:         *
0027:         * @author Scott Ferguson
0028:         */
0029:
0030:        package com.caucho.quercus.env;
0031:
0032:        import com.caucho.quercus.*;
0033:        import com.caucho.quercus.expr.Expr;
0034:        import com.caucho.quercus.function.Marshal;
0035:        import com.caucho.quercus.function.MarshalFactory;
0036:        import com.caucho.quercus.lib.ErrorModule;
0037:        import com.caucho.quercus.lib.VariableModule;
0038:        import com.caucho.quercus.lib.file.FileModule;
0039:        import com.caucho.quercus.lib.string.StringModule;
0040:        import com.caucho.quercus.lib.string.StringUtility;
0041:        import com.caucho.quercus.module.ModuleContext;
0042:        import com.caucho.quercus.module.ModuleStartupListener;
0043:        import com.caucho.quercus.module.IniDefinition;
0044:        import com.caucho.quercus.page.QuercusPage;
0045:        import com.caucho.quercus.program.*;
0046:        import com.caucho.quercus.resources.StreamContextResource;
0047:        import com.caucho.util.*;
0048:        import com.caucho.vfs.ByteToChar;
0049:        import com.caucho.vfs.Encoding;
0050:        import com.caucho.vfs.NullPath;
0051:        import com.caucho.vfs.Path;
0052:        import com.caucho.vfs.ReadStream;
0053:        import com.caucho.vfs.WriteStream;
0054:        import com.caucho.vfs.TempBuffer;
0055:        import com.caucho.vfs.i18n.EncodingReader;
0056:
0057:        import javax.script.Bindings;
0058:        import javax.script.ScriptContext;
0059:        import javax.servlet.ServletContext;
0060:        import javax.servlet.http.Cookie;
0061:        import javax.servlet.http.HttpServletRequest;
0062:        import javax.servlet.http.HttpServletResponse;
0063:        import javax.servlet.http.HttpSession;
0064:        import javax.sql.DataSource;
0065:        import java.io.IOException;
0066:        import java.lang.ref.SoftReference;
0067:        import java.lang.ref.WeakReference;
0068:        import java.lang.reflect.Array;
0069:        import java.net.URL;
0070:        import java.sql.Connection;
0071:        import java.util.ArrayList;
0072:        import java.util.Collections;
0073:        import java.util.HashMap;
0074:        import java.util.HashSet;
0075:        import java.util.LinkedHashMap;
0076:        import java.util.Map;
0077:        import java.util.IdentityHashMap;
0078:        import java.util.TimeZone;
0079:        import java.util.logging.Level;
0080:        import java.util.logging.Logger;
0081:
0082:        /**
0083:         * Represents the Quercus environment.
0084:         */
0085:        public class Env {
0086:            private static final L10N L = new L10N(Env.class);
0087:            private static final Logger log = Logger.getLogger(Env.class
0088:                    .getName());
0089:
0090:            public static final int B_ERROR = 0;
0091:            public static final int B_WARNING = 1;
0092:            public static final int B_PARSE = 2;
0093:            public static final int B_NOTICE = 3;
0094:            public static final int B_CORE_ERROR = 4;
0095:            public static final int B_CORE_WARNING = 5;
0096:            public static final int B_COMPILE_ERROR = 6;
0097:            public static final int B_COMPILE_WARNING = 7;
0098:            public static final int B_USER_ERROR = 8;
0099:            public static final int B_USER_WARNING = 9;
0100:            public static final int B_USER_NOTICE = 10;
0101:            public static final int B_STRICT = 11;
0102:
0103:            public static final int E_ERROR = 1 << B_ERROR;
0104:            public static final int E_WARNING = 1 << B_WARNING;
0105:            public static final int E_PARSE = 1 << B_PARSE;
0106:            public static final int E_NOTICE = 1 << B_NOTICE;
0107:            public static final int E_CORE_ERROR = 1 << B_CORE_ERROR;
0108:            public static final int E_CORE_WARNING = 1 << B_CORE_WARNING;
0109:            public static final int E_COMPILE_ERROR = 1 << B_COMPILE_ERROR;
0110:            public static final int E_COMPILE_WARNING = 1 << B_COMPILE_WARNING;
0111:            public static final int E_USER_ERROR = 1 << B_USER_ERROR;
0112:            public static final int E_USER_WARNING = 1 << B_USER_WARNING;
0113:            public static final int E_USER_NOTICE = 1 << B_USER_NOTICE;
0114:            public static final int E_ALL = 2048 - 1;
0115:            public static final int E_STRICT = 1 << B_STRICT;
0116:
0117:            public static final int E_DEFAULT = E_ALL & ~E_NOTICE;
0118:
0119:            private static final int _SERVER = 1;
0120:            private static final int _GET = 2;
0121:            private static final int _POST = 3;
0122:            private static final int _COOKIE = 4;
0123:            private static final int _GLOBAL = 5;
0124:            private static final int _REQUEST = 6;
0125:            private static final int _SESSION = 7;
0126:            private static final int HTTP_GET_VARS = 8;
0127:            private static final int HTTP_POST_VARS = 9;
0128:            private static final int HTTP_COOKIE_VARS = 10;
0129:            private static final int PHP_SELF = 11;
0130:            private static final int _FILES = 12;
0131:            private static final int HTTP_POST_FILES = 13;
0132:            private static final int _ENV = 14;
0133:            private static final int HTTP_SERVER_VARS = 15;
0134:
0135:            private static final IntMap SPECIAL_VARS = new IntMap();
0136:
0137:            private static final StringValue PHP_SELF_STRING = new StringBuilderValue(
0138:                    "PHP_SELF");
0139:
0140:            private static final StringValue UTF8_STRING = new StringBuilderValue(
0141:                    "utf-8");
0142:
0143:            public static final Value[] EMPTY_VALUE = new Value[0];
0144:
0145:            private static final LruCache<ClassKey, SoftReference<QuercusClass>> _classCache = new LruCache<ClassKey, SoftReference<QuercusClass>>(
0146:                    4096);
0147:
0148:            private static final LruCache<IncludeKey, SoftReference<IncludeCache>> _includeCache = new LruCache<IncludeKey, SoftReference<IncludeCache>>(
0149:                    4096);
0150:
0151:            private static ThreadLocal<Env> _threadEnv = new ThreadLocal<Env>();
0152:
0153:            private static final FreeList<AbstractFunction[]> _freeFunList = new FreeList<AbstractFunction[]>(
0154:                    256);
0155:
0156:            protected final Quercus _quercus;
0157:            private final boolean _isUnicodeSemantics;
0158:            private QuercusPage _page;
0159:
0160:            private Value _this  = NullThisValue.NULL;
0161:
0162:            private ArrayList<SoftReference<EnvCleanup>> _cleanupList = new ArrayList<SoftReference<EnvCleanup>>();
0163:
0164:            private ArrayList<Shutdown> _shutdownList = new ArrayList<Shutdown>();
0165:
0166:            private final HashMap<String, Var> _globalMap = new HashMap<String, Var>(
0167:                    1024);
0168:
0169:            private HashMap<String, Var> _staticMap = new HashMap<String, Var>();
0170:
0171:            private HashMap<String, Var> _map = _globalMap;
0172:
0173:            private HashMap<String, Value> _constMap = new HashMap<String, Value>(
0174:                    1024);
0175:
0176:            private HashMap<String, Value> _lowerConstMap = new HashMap<String, Value>(
0177:                    1024);
0178:
0179:            private HashMap<String, QuercusClass> _classMap = new HashMap<String, QuercusClass>();
0180:
0181:            private HashMap<String, QuercusClass> _lowerClassMap = new HashMap<String, QuercusClass>();
0182:
0183:            private HashSet<String> _initializedClassSet = new HashSet<String>();
0184:
0185:            // Function map
0186:            public AbstractFunction[] _fun;
0187:            // Class map
0188:            public ClassDef[] _classDef;
0189:            public QuercusClass[] _qClass;
0190:
0191:            private IdentityHashMap<String, Value> _iniMap;
0192:
0193:            // specialMap is used for implicit resources like the mysql link
0194:            private HashMap<String, Object> _specialMap = new HashMap<String, Object>();
0195:
0196:            // include_path ini
0197:            private int _iniCount = 1;
0198:
0199:            private String _defaultIncludePath;
0200:            private String _includePath;
0201:            private int _includePathIniCount;
0202:            private ArrayList<String> _includePathList;
0203:            private HashMap<Path, ArrayList<Path>> _includePathMap;
0204:
0205:            private LinkedHashMap<Path, QuercusPage> _includeMap = new LinkedHashMap<Path, QuercusPage>();
0206:
0207:            private HashMap<StringValue, Path> _lookupCache = new HashMap<StringValue, Path>();
0208:
0209:            private HashMap<ConnectionEntry, ConnectionEntry> _connMap = new HashMap<ConnectionEntry, ConnectionEntry>();
0210:
0211:            private AbstractFunction _autoload;
0212:            private HashSet<String> _autoloadClasses = new HashSet<String>();
0213:
0214:            private LinkedHashMap<String, AbstractFunction> _autoloadFunctionMap;
0215:
0216:            private long _startTime;
0217:            private long _timeLimit = 600000L;
0218:
0219:            private Expr[] _callStack = new Expr[256];
0220:            private Value[] _callThisStack = new Value[256];
0221:            private int _callStackTop;
0222:
0223:            private Value[] _functionArgs;
0224:
0225:            private Path _selfPath;
0226:            private Path _selfDirectory;
0227:            private Path _pwd;
0228:            private Path _uploadPath;
0229:            private Path _tmpPath;
0230:            private ArrayList<Path> _removePaths;
0231:
0232:            private final boolean _isStrict;
0233:
0234:            private HttpServletRequest _request;
0235:            private HttpServletResponse _response;
0236:
0237:            private ArrayValue _post;
0238:            private ArrayValue _files;
0239:            private SessionArrayValue _session;
0240:            private HttpSession _javaSession;
0241:
0242:            private ScriptContext _scriptContext;
0243:
0244:            private WriteStream _originalOut;
0245:            private OutputBuffer _outputBuffer;
0246:
0247:            private WriteStream _out;
0248:
0249:            private LocaleInfo _locale;
0250:
0251:            private Callback[] _prevErrorHandlers = new Callback[B_STRICT + 1];
0252:            private Callback[] _errorHandlers = new Callback[B_STRICT + 1];
0253:
0254:            private Callback _prevExceptionHandler;
0255:            private Callback _exceptionHandler;
0256:
0257:            private SessionCallback _sessionCallback;
0258:
0259:            private StreamContextResource _defaultStreamContext;
0260:
0261:            // XXX: need to look this up from the module itself
0262:            private int _errorMask = E_DEFAULT;
0263:
0264:            private int _objectId = 0;
0265:
0266:            private Logger _logger;
0267:
0268:            // hold special Quercus php import statements
0269:            private ImportMap _importMap;
0270:
0271:            private TimeZone _defaultTimeZone;
0272:
0273:            private Object _gzStream;
0274:
0275:            private Env _oldThreadEnv;
0276:
0277:            public Env(Quercus quercus, QuercusPage page, WriteStream out,
0278:                    HttpServletRequest request, HttpServletResponse response) {
0279:                _quercus = quercus;
0280:
0281:                _isStrict = quercus.isStrict();
0282:                _isUnicodeSemantics = quercus.isUnicodeSemantics();
0283:
0284:                _page = page;
0285:
0286:                // XXX: grab initial from page
0287:                // _defState = new DefinitionState(quercus);
0288:
0289:                AbstractFunction[] defFuns = quercus.getFunctionMap();
0290:                _fun = _freeFunList.allocate();
0291:                if (_fun == null || _fun.length != defFuns.length)
0292:                    _fun = new AbstractFunction[defFuns.length];
0293:                System.arraycopy(defFuns, 0, _fun, 0, defFuns.length);
0294:
0295:                ClassDef[] defClasses = quercus.getClassDefMap();
0296:
0297:                _classDef = new ClassDef[defClasses.length];
0298:                _qClass = new QuercusClass[_classDef.length];
0299:
0300:                _originalOut = out;
0301:                _out = out;
0302:
0303:                _request = request;
0304:                _response = response;
0305:
0306:                if (page != null) {
0307:                    _page.init(this );
0308:
0309:                    _page.importDefinitions(this );
0310:                }
0311:
0312:                setPwd(_quercus.getPwd());
0313:
0314:                if (_page != null) {
0315:                    setSelfPath(_page.getSelfPath(null));
0316:
0317:                    // php/0b32
0318:                    _includeMap.put(_selfPath, _page);
0319:                }
0320:
0321:                if (_request != null && _request.getMethod().equals("POST")) {
0322:                    _post = new ArrayValueImpl();
0323:                    _files = new ArrayValueImpl();
0324:                    Post.fillPost(this , _post, _files, _request,
0325:                            getIniBoolean("magic_quotes_gpc"));
0326:                }
0327:
0328:                /*
0329:                Cluster cluster = Cluster.getLocal();
0330:
0331:                if (cluster != null) {
0332:                  ClusterServer selfServer = cluster.getSelfServer();
0333:
0334:                  if (selfServer != null)
0335:                    setIni("caucho.server_id", selfServer.getId());
0336:                }
0337:                 */
0338:            }
0339:
0340:            public Env(Quercus quercus) {
0341:                this (quercus, null, null, null, null);
0342:            }
0343:
0344:            public static Env getInstance() {
0345:                return _threadEnv.get();
0346:            }
0347:
0348:            //
0349:            // i18n
0350:            //
0351:
0352:            /**
0353:             * Returns true if unicode.semantics is on.
0354:             */
0355:            public boolean isUnicodeSemantics() {
0356:                return _isUnicodeSemantics;
0357:            }
0358:
0359:            /**
0360:             * Returns the encoding used for scripts.
0361:             */
0362:            public String getScriptEncoding() {
0363:                StringValue encoding = getIni("unicode.script_encoding");
0364:
0365:                if (encoding.length() == 0) {
0366:                    encoding = getIni("unicode.fallback_encoding");
0367:
0368:                    if (encoding.length() == 0)
0369:                        return getQuercus().getScriptEncoding();
0370:                }
0371:
0372:                return encoding.toString();
0373:            }
0374:
0375:            /**
0376:             * Returns the encoding used for runtime conversions, e.g. files
0377:             * XXX: ISO-8859-1 when unicode.semantics is OFF
0378:             */
0379:            public String getRuntimeEncoding() {
0380:                if (!_isUnicodeSemantics)
0381:                    return "iso-8859-1";
0382:
0383:                StringValue encoding = getIni("unicode.runtime_encoding");
0384:
0385:                if (encoding.length() == 0) {
0386:                    encoding = getIni("unicode.fallback_encoding");
0387:
0388:                    if (encoding.length() == 0)
0389:                        encoding = UTF8_STRING;
0390:                }
0391:
0392:                return encoding.toString();
0393:            }
0394:
0395:            /**
0396:             * Sets the encoding used for runtime conversions.
0397:             */
0398:            public Value setRuntimeEncoding(String encoding) {
0399:                return setIni("unicode.runtime_encoding", encoding);
0400:            }
0401:
0402:            /**
0403:             * Returns the encoding used for runtime conversions, e.g. files
0404:             */
0405:            public EncodingReader getRuntimeEncodingFactory()
0406:                    throws IOException {
0407:                return Encoding.getReadFactory(getRuntimeEncoding());
0408:            }
0409:
0410:            /**
0411:             * Returns the encoding used for input, i.e. post,
0412:             * null if unicode.semantics is off.
0413:             */
0414:            public String getHttpInputEncoding() {
0415:                if (!_isUnicodeSemantics)
0416:                    return null;
0417:
0418:                StringValue encoding = getIni("unicode.http_input_encoding");
0419:
0420:                if (encoding.length() == 0) {
0421:                    encoding = getIni("unicode.fallback_encoding");
0422:
0423:                    if (encoding.length() == 0)
0424:                        encoding = UTF8_STRING;
0425:                }
0426:
0427:                return encoding.toString();
0428:            }
0429:
0430:            /**
0431:             * Returns the encoding used for output, null if unicode.semantics is off.
0432:             */
0433:            public String getOutputEncoding() {
0434:                if (!_isUnicodeSemantics)
0435:                    return null;
0436:
0437:                String encoding = Quercus.INI_UNICODE_OUTPUT_ENCODING
0438:                        .getAsString(this );
0439:
0440:                if (encoding == null)
0441:                    encoding = Quercus.INI_UNICODE_FALLBACK_ENCODING
0442:                            .getAsString(this );
0443:
0444:                if (encoding == null)
0445:                    encoding = "utf-8";
0446:
0447:                return encoding;
0448:            }
0449:
0450:            /**
0451:             * Creates a binary builder.
0452:             */
0453:            public StringValue createBinaryBuilder() {
0454:                if (_isUnicodeSemantics)
0455:                    return new BinaryBuilderValue();
0456:                else
0457:                    return new StringBuilderValue();
0458:            }
0459:
0460:            /**
0461:             * Creates a binary builder for large things like files.
0462:             */
0463:            public StringValue createLargeBinaryBuilder() {
0464:                if (_isUnicodeSemantics)
0465:                    return new BinaryBuilderValue();
0466:                else
0467:                    return new LargeStringBuilderValue();
0468:            }
0469:
0470:            /**
0471:             * Creates a binary builder.
0472:             */
0473:            public StringValue createBinaryBuilder(int length) {
0474:                if (_isUnicodeSemantics)
0475:                    return new BinaryBuilderValue(length);
0476:                else
0477:                    return new StringBuilderValue(length);
0478:            }
0479:
0480:            /**
0481:             * Creates a binary builder.
0482:             */
0483:            public StringValue createBinaryBuilder(byte[] buffer, int offset,
0484:                    int length) {
0485:                if (_isUnicodeSemantics)
0486:                    return new BinaryBuilderValue(buffer, offset, length);
0487:                else
0488:                    return new StringBuilderValue(buffer, offset, length);
0489:            }
0490:
0491:            /**
0492:             * Creates a binary builder.
0493:             */
0494:            public StringValue createBinaryBuilder(byte[] buffer) {
0495:                if (_isUnicodeSemantics)
0496:                    return new BinaryBuilderValue(buffer, 0, buffer.length);
0497:                else
0498:                    return new StringBuilderValue(buffer, 0, buffer.length);
0499:            }
0500:
0501:            /**
0502:             * Creates a unicode builder.
0503:             */
0504:            public StringValue createUnicodeBuilder() {
0505:                if (_isUnicodeSemantics)
0506:                    return new UnicodeBuilderValue();
0507:                else
0508:                    return new StringBuilderValue();
0509:            }
0510:
0511:            public TimeZone getDefaultTimeZone() {
0512:                return _defaultTimeZone;
0513:            }
0514:
0515:            public void setDefaultTimeZone(String id) {
0516:                _defaultTimeZone = TimeZone.getTimeZone(id);
0517:            }
0518:
0519:            public void setDefaultTimeZone(TimeZone zone) {
0520:                _defaultTimeZone = zone;
0521:            }
0522:
0523:            /*
0524:             * Returns the ServletContext.
0525:             */
0526:            public ServletContext getServletContext() {
0527:                return _quercus.getServletContext();
0528:            }
0529:
0530:            /*
0531:             * Sets the ScriptContext.
0532:             */
0533:            public void setScriptContext(ScriptContext context) {
0534:                _scriptContext = context;
0535:            }
0536:
0537:            /**
0538:             * Returns true for strict mode.
0539:             */
0540:            public final boolean isStrict() {
0541:                return _isStrict;
0542:            }
0543:
0544:            public void start() {
0545:                _oldThreadEnv = _threadEnv.get();
0546:
0547:                _startTime = Alarm.getCurrentTime();
0548:                _timeLimit = getIniLong("max_execution_time") * 1000;
0549:
0550:                _threadEnv.set(this );
0551:
0552:                // quercus/1b06
0553:                String encoding = getOutputEncoding();
0554:
0555:                String type = getIniString("default_mimetype");
0556:
0557:                if ("".equals(type) || _response == null) {
0558:                } else if (encoding != null)
0559:                    _response.setContentType(type + "; charset=" + encoding);
0560:                else
0561:                    _response.setContentType(type);
0562:
0563:                if (_out != null && encoding != null) {
0564:                    try {
0565:                        _out.setEncoding(encoding);
0566:                    } catch (Exception e) {
0567:                        log.log(Level.WARNING, e.toString(), e);
0568:                    }
0569:                }
0570:
0571:                HashSet<ModuleStartupListener> listeners = _quercus
0572:                        .getModuleStartupListeners();
0573:
0574:                for (ModuleStartupListener listener : listeners)
0575:                    listener.startup(this );
0576:            }
0577:
0578:            /**
0579:             * add resource to the list of refrences that are
0580:             * cleaned up when finished with this environment.
0581:             */
0582:            public void addCleanup(EnvCleanup envCleanup) {
0583:                _cleanupList.add(new SoftReference<EnvCleanup>(envCleanup));
0584:            }
0585:
0586:            /**
0587:             * remove resource from the list of refrences that are
0588:             * cleaned up when finished with this environment.
0589:             *
0590:             * @param resource
0591:             */
0592:            public void removeCleanup(EnvCleanup envCleanup) {
0593:                for (int i = _cleanupList.size() - 1; i >= 0; i--) {
0594:                    SoftReference<EnvCleanup> ref = _cleanupList.get(i);
0595:
0596:                    EnvCleanup res = ref.get();
0597:
0598:                    if (envCleanup.equals(res)) {
0599:                        _cleanupList.remove(i);
0600:                        break;
0601:                    }
0602:                }
0603:            }
0604:
0605:            /**
0606:             * Returns the owning PHP engine.
0607:             */
0608:            public Quercus getQuercus() {
0609:                return _quercus;
0610:            }
0611:
0612:            /**
0613:             * Returns the owning PHP engine.
0614:             */
0615:            public ModuleContext getModuleContext() {
0616:                return _quercus.getModuleContext();
0617:            }
0618:
0619:            /**
0620:             * Returns the configured database.
0621:             */
0622:            public DataSource getDatabase() {
0623:                return _quercus.getDatabase();
0624:            }
0625:
0626:            protected final DataSource findDatabase(String driver, String url)
0627:                    throws Exception {
0628:                return _quercus.findDatabase(driver, url);
0629:            }
0630:
0631:            /**
0632:             * Returns the configured database.
0633:             */
0634:            public Connection getConnection(String driver, String url,
0635:                    String userName, String password) throws Exception {
0636:                DataSource database = _quercus.getDatabase();
0637:
0638:                if (database != null) {
0639:                    ConnectionEntry entry = new ConnectionEntry();
0640:                    entry.init(database, null, null);
0641:
0642:                    ConnectionEntry oldEntry = _connMap.get(entry);
0643:
0644:                    Connection conn;
0645:                    if (oldEntry != null
0646:                            && (conn = oldEntry.getConnection()) != null
0647:                            && !conn.isClosed())
0648:                        return conn;
0649:
0650:                    entry.setConnection(database.getConnection());
0651:                    _connMap.put(entry, entry);
0652:
0653:                    conn = entry.getConnection();
0654:
0655:                    return conn;
0656:                }
0657:
0658:                database = findDatabase(driver, url);
0659:
0660:                ConnectionEntry entry = new ConnectionEntry();
0661:                entry.init(database, userName, password);
0662:
0663:                ConnectionEntry oldEntry = _connMap.get(entry);
0664:
0665:                Connection conn;
0666:
0667:                if (oldEntry == null
0668:                        || (conn = oldEntry.getConnection()) == null
0669:                        || conn.isClosed()) {
0670:                    if (userName == null || userName.equals(""))
0671:                        conn = database.getConnection();
0672:                    else
0673:                        conn = database.getConnection(userName, password);
0674:
0675:                    entry.setConnection(conn);
0676:
0677:                    _connMap.put(entry, entry);
0678:                }
0679:
0680:                return conn;
0681:            }
0682:
0683:            /**
0684:             * Returns the configured database.
0685:             */
0686:            public DataSource getDataSource(String driver, String url)
0687:                    throws Exception {
0688:                DataSource database = _quercus.getDatabase();
0689:
0690:                if (database != null)
0691:                    return database;
0692:                else
0693:                    return findDatabase(driver, url);
0694:            }
0695:
0696:            /**
0697:             * Sets the time limit.
0698:             */
0699:            public void setTimeLimit(long ms) {
0700:                if (ms <= 0)
0701:                    ms = Long.MAX_VALUE / 2;
0702:
0703:                _timeLimit = ms;
0704:            }
0705:
0706:            /**
0707:             * Checks for the program timeout.
0708:             */
0709:            public final void checkTimeout() {
0710:                long now = Alarm.getCurrentTime();
0711:
0712:                if (_timeLimit > 0 && _startTime + _timeLimit < now)
0713:                    throw new QuercusRuntimeException(L.l("script timed out"));
0714:            }
0715:
0716:            public void resetTimeout() {
0717:                _startTime = Alarm.getCurrentTime();
0718:            }
0719:
0720:            /**
0721:             * Returns the writer.
0722:             */
0723:            public WriteStream getOut() {
0724:                return _out;
0725:            }
0726:
0727:            /**
0728:             * Returns the writer.
0729:             */
0730:            public WriteStream getOriginalOut() {
0731:                return _originalOut;
0732:            }
0733:
0734:            /**
0735:             * Flushes the output buffer.
0736:             */
0737:            public final void flush() {
0738:                try {
0739:                    getOut().flush();
0740:                } catch (IOException e) {
0741:                    throw new QuercusModuleException(e);
0742:                }
0743:            }
0744:
0745:            /**
0746:             * Prints a string
0747:             */
0748:            public final void print(String v) {
0749:                try {
0750:                    getOut().print(v);
0751:                } catch (IOException e) {
0752:                    throw new QuercusModuleException(e);
0753:                }
0754:            }
0755:
0756:            /**
0757:             * Prints a character buffer.
0758:             */
0759:            public final void print(char[] buffer, int offset, int length) {
0760:                try {
0761:                    getOut().print(buffer, offset, length);
0762:                } catch (IOException e) {
0763:                    throw new QuercusModuleException(e);
0764:                }
0765:            }
0766:
0767:            /**
0768:             * Prints a char
0769:             */
0770:            public final void print(char v) {
0771:                try {
0772:                    getOut().print(v);
0773:                } catch (IOException e) {
0774:                    throw new QuercusModuleException(e);
0775:                }
0776:            }
0777:
0778:            /**
0779:             * Prints a long
0780:             */
0781:            public final void print(long v) {
0782:                try {
0783:                    getOut().print(v);
0784:                } catch (IOException e) {
0785:                    throw new QuercusModuleException(e);
0786:                }
0787:            }
0788:
0789:            /**
0790:             * Prints a double
0791:             */
0792:            public final void print(double v) {
0793:                try {
0794:                    long longV = (long) v;
0795:
0796:                    if (v == longV)
0797:                        getOut().print(longV);
0798:                    else
0799:                        getOut().print(v);
0800:                } catch (IOException e) {
0801:                    throw new QuercusModuleException(e);
0802:                }
0803:            }
0804:
0805:            /**
0806:             * Prints an object
0807:             */
0808:            public final void print(Object v) {
0809:                try {
0810:                    getOut().print(v);
0811:                } catch (IOException e) {
0812:                    throw new QuercusModuleException(e);
0813:                }
0814:            }
0815:
0816:            /**
0817:             * Prints a value
0818:             */
0819:            public final void print(Value v) {
0820:                v.print(this );
0821:            }
0822:
0823:            /**
0824:             * Prints a string
0825:             */
0826:            public final void println() {
0827:                try {
0828:                    getOut().println();
0829:                } catch (IOException e) {
0830:                    throw new QuercusModuleException(e);
0831:                }
0832:            }
0833:
0834:            /**
0835:             * Prints a string
0836:             */
0837:            public final void println(String v) {
0838:                try {
0839:                    getOut().println(v);
0840:                } catch (IOException e) {
0841:                    throw new QuercusModuleException(e);
0842:                }
0843:            }
0844:
0845:            /**
0846:             * Prints a string
0847:             */
0848:            public final void println(Value v) {
0849:                try {
0850:                    v.print(this );
0851:                    getOut().println();
0852:                } catch (IOException e) {
0853:                    throw new QuercusModuleException(e);
0854:                }
0855:            }
0856:
0857:            /**
0858:             * Prints and object.
0859:             */
0860:            public final void println(Object v) {
0861:                try {
0862:                    getOut().println(v);
0863:                } catch (IOException e) {
0864:                    throw new QuercusModuleException(e);
0865:                }
0866:            }
0867:
0868:            /**
0869:             * Prints a byte buffer.
0870:             */
0871:            public final void write(byte[] buffer, int offset, int length) {
0872:                try {
0873:                    getOut().write(buffer, offset, length);
0874:                } catch (IOException e) {
0875:                    throw new QuercusModuleException(e);
0876:                }
0877:            }
0878:
0879:            /**
0880:             * Returns the current output buffer.
0881:             */
0882:            public OutputBuffer getOutputBuffer() {
0883:                return _outputBuffer;
0884:            }
0885:
0886:            /**
0887:             * Returns the writer.
0888:             */
0889:            public void pushOutputBuffer(Callback callback, int chunkSize,
0890:                    boolean erase) {
0891:                if (_outputBuffer == null) {
0892:                    _outputBuffer = new OutputBuffer(_outputBuffer, this ,
0893:                            callback, chunkSize, erase);
0894:                } else
0895:                    _outputBuffer = new OutputBuffer(_outputBuffer, this ,
0896:                            callback, chunkSize, erase);
0897:
0898:                _out = _outputBuffer.getOut();
0899:            }
0900:
0901:            /**
0902:             * Pops the output buffer
0903:             */
0904:            public boolean popOutputBuffer() {
0905:                OutputBuffer outputBuffer = _outputBuffer;
0906:
0907:                if (outputBuffer == null)
0908:                    return false;
0909:
0910:                outputBuffer.close();
0911:
0912:                _outputBuffer = outputBuffer.getNext();
0913:
0914:                if (_outputBuffer != null)
0915:                    _out = _outputBuffer.getOut();
0916:                else {
0917:                    _out = _originalOut;
0918:                }
0919:
0920:                return true;
0921:            }
0922:
0923:            /**
0924:             * Returns the current directory.
0925:             */
0926:            public Path getPwd() {
0927:                return _pwd;
0928:            }
0929:
0930:            /**
0931:             * Returns the current directory.
0932:             */
0933:            public Path getWorkDir() {
0934:                return _quercus.getWorkDir();
0935:            }
0936:
0937:            /**
0938:             * Sets the current directory.
0939:             */
0940:            public void setPwd(Path path) {
0941:                _pwd = path;
0942:                _lookupCache.clear();
0943:            }
0944:
0945:            /**
0946:             * Returns the initial directory.
0947:             */
0948:            public Path getSelfPath() {
0949:                return _selfPath;
0950:            }
0951:
0952:            /**
0953:             * Returns the initial directory.
0954:             */
0955:            public Path getSelfDirectory() {
0956:                return _selfDirectory;
0957:            }
0958:
0959:            /**
0960:             * Sets the initial directory.
0961:             */
0962:            public void setSelfPath(Path path) {
0963:                _selfPath = path;
0964:                _selfDirectory = _selfPath.getParent();
0965:            }
0966:
0967:            /**
0968:             * Returns the upload directory.
0969:             */
0970:            public Path getUploadDirectory() {
0971:                if (_uploadPath == null) {
0972:                    String realPath = getIniString("upload_tmp_dir");
0973:
0974:                    if (realPath == null)
0975:                        realPath = getRequest().getRealPath("/WEB-INF/upload");
0976:
0977:                    _uploadPath = _quercus.getPwd().lookup(realPath);
0978:
0979:                    try {
0980:                        if (!_uploadPath.isDirectory())
0981:                            _uploadPath.mkdirs();
0982:                    } catch (IOException e) {
0983:                        log.log(Level.FINE, e.toString(), e);
0984:                    }
0985:
0986:                    _uploadPath = _uploadPath.createRoot();
0987:                }
0988:
0989:                return _uploadPath;
0990:            }
0991:
0992:            /*
0993:             * Returns the temp directory (used by tmpfile()).
0994:             */
0995:            public Path getTempDirectory() {
0996:                String realPath;
0997:
0998:                if (_tmpPath == null) {
0999:                    if (getRequest() != null)
1000:                        realPath = getRequest().getRealPath("/WEB-INF/tmp");
1001:                    else
1002:                        realPath = "file:/tmp";
1003:
1004:                    _tmpPath = getPwd().lookup(realPath);
1005:
1006:                    try {
1007:                        if (!_tmpPath.isDirectory())
1008:                            _tmpPath.mkdirs();
1009:                    } catch (IOException e) {
1010:                        log.log(Level.FINE, e.toString(), e);
1011:                    }
1012:                }
1013:
1014:                return _tmpPath;
1015:            }
1016:
1017:            /**
1018:             * Adds an auto-remove path.
1019:             */
1020:            public void addRemovePath(Path path) {
1021:                if (_removePaths == null)
1022:                    _removePaths = new ArrayList<Path>();
1023:
1024:                _removePaths.add(path);
1025:            }
1026:
1027:            /**
1028:             * Returns the request.
1029:             */
1030:            public HttpServletRequest getRequest() {
1031:                return _request;
1032:            }
1033:
1034:            /**
1035:             * Returns the most recently modified time of all of the {@link Path}'s that
1036:             * have been used for this Env, or 0 if that cannot be determined.
1037:             */
1038:            /*
1039:            public long getLastModified()
1040:            {
1041:              long lastModified = 0;
1042:
1043:              if (_page != null) {
1044:                Path pagePath = _page.getSelfPath(this);
1045:
1046:                if (pagePath != null)
1047:                  lastModified = pagePath.getLastModified();
1048:              }
1049:
1050:              for (Path includePath : _includeSet) {
1051:                long includeLastModified = includePath.getLastModified();
1052:
1053:                if (lastModified < includeLastModified)
1054:                  lastModified = includeLastModified;
1055:              }
1056:
1057:              return lastModified;
1058:            }
1059:             */
1060:
1061:            /**
1062:             * Returns the response.
1063:             */
1064:            public HttpServletResponse getResponse() {
1065:                return _response;
1066:            }
1067:
1068:            /**
1069:             * Sets the session callback.
1070:             */
1071:            public void setSessionCallback(SessionCallback callback) {
1072:                _sessionCallback = callback;
1073:            }
1074:
1075:            /**
1076:             * Gets the session callback.
1077:             */
1078:            public SessionCallback getSessionCallback() {
1079:                return _sessionCallback;
1080:            }
1081:
1082:            /**
1083:             * Returns the session.
1084:             */
1085:            public SessionArrayValue getSession() {
1086:                return _session;
1087:            }
1088:
1089:            /**
1090:             * Returns the Java Http session.
1091:             */
1092:            public HttpSession getJavaSession() {
1093:                return _javaSession;
1094:            }
1095:
1096:            /**
1097:             * Sets the session.
1098:             */
1099:            public void setSession(SessionArrayValue session) {
1100:                _session = session;
1101:
1102:                if (session != null) {
1103:                    Value var = getGlobalVar("_SESSION");
1104:
1105:                    if (!(var instanceof  SessionVar)) {
1106:                        var = new SessionVar();
1107:                        setGlobalValue("_SESSION", var);
1108:                    }
1109:
1110:                    var.set(session);
1111:
1112:                    setGlobalValue("HTTP_SESSION_VARS", session);
1113:
1114:                    session.addUse();
1115:                } else {
1116:                    // php/1k0v
1117:                    Value v = getGlobalVar("_SESSION");
1118:
1119:                    if (v != null)
1120:                        v.set(UnsetValue.UNSET);
1121:
1122:                    v = getGlobalVar("HTTP_SESSION_VARS");
1123:
1124:                    if (v != null)
1125:                        v.set(UnsetValue.UNSET);
1126:                }
1127:            }
1128:
1129:            /**
1130:             * Returns a new session id.
1131:             */
1132:            public String generateSessionId() {
1133:                String sessionId = _quercus.getQuercusSessionManager()
1134:                        .createSessionId(this );
1135:
1136:                if (_javaSession != null)
1137:                    sessionId = _javaSession.getId().substring(0, 3)
1138:                            + sessionId.substring(3);
1139:
1140:                return sessionId;
1141:            }
1142:
1143:            /**
1144:             * Create the session.
1145:             */
1146:            public SessionArrayValue createSession(String sessionId,
1147:                    boolean create) {
1148:                long now = Alarm.getCurrentTime();
1149:
1150:                SessionCallback callback = getSessionCallback();
1151:
1152:                _javaSession = _request.getSession(true);
1153:
1154:                if (create && _javaSession.getId().length() >= 3
1155:                        && sessionId.length() >= 3)
1156:                    sessionId = _javaSession.getId().substring(0, 3)
1157:                            + sessionId.substring(3);
1158:
1159:                SessionArrayValue session = _quercus.loadSession(this ,
1160:                        sessionId);
1161:
1162:                if (callback != null) {
1163:                    StringValue value = callback.read(this , sessionId);
1164:
1165:                    if (value != null && value.length() != 0) {
1166:                        Value unserialize = VariableModule.unserialize(this ,
1167:                                value);
1168:
1169:                        if (unserialize instanceof  ArrayValue) {
1170:                            ArrayValue arrayValue = (ArrayValue) unserialize;
1171:
1172:                            session.reset(now);
1173:                            session.putAll(arrayValue);
1174:                        }
1175:                    }
1176:                }
1177:
1178:                setSession(session);
1179:
1180:                return session;
1181:            }
1182:
1183:            /**
1184:             * Destroy the session.
1185:             */
1186:            public void destroySession(String sessionId) {
1187:                SessionCallback callback = getSessionCallback();
1188:
1189:                if (callback != null) {
1190:                    callback.destroy(this , sessionId);
1191:                } else {
1192:                    _quercus.destroySession(sessionId);
1193:                }
1194:
1195:                setSession(null);
1196:            }
1197:
1198:            /**
1199:             * Returns the logger used for syslog.
1200:             */
1201:            public Logger getLogger() {
1202:                if (_logger == null)
1203:                    _logger = Logger.getLogger("quercus.quercus");
1204:
1205:                return _logger;
1206:            }
1207:
1208:            /**
1209:             * Returns the configuration value of an init var.
1210:             */
1211:            public Value getConfigVar(String name) {
1212:                return getIniDefinition(name).getValue(_quercus);
1213:            }
1214:
1215:            /**
1216:             * Returns a map of the ini values that have been explicitly set.
1217:             */
1218:            public IdentityHashMap<String, Value> getIniMap(boolean create) {
1219:                if (_iniMap == null && create)
1220:                    _iniMap = new IdentityHashMap<String, Value>();
1221:
1222:                return _iniMap;
1223:            }
1224:
1225:            /**
1226:             * Sets an ini value.
1227:             */
1228:            public StringValue setIni(String name, Value value) {
1229:                _iniCount++;
1230:
1231:                StringValue oldValue = getIni(name);
1232:
1233:                getIniDefinition(name).set(this , value);
1234:
1235:                return oldValue;
1236:            }
1237:
1238:            /**
1239:             * Sets an ini value.
1240:             */
1241:            public StringValue setIni(String name, String value) {
1242:                _iniCount++;
1243:
1244:                StringValue oldValue = getIni(name);
1245:
1246:                getIniDefinition(name).set(this , value);
1247:
1248:                return oldValue;
1249:            }
1250:
1251:            /**
1252:             * Returns an ini value.
1253:             */
1254:            public StringValue getIni(String name) {
1255:                return getIniDefinition(name).getAsStringValue(this );
1256:            }
1257:
1258:            private IniDefinition getIniDefinition(String name) {
1259:                return _quercus.getIniDefinitions().get(name);
1260:            }
1261:
1262:            /**
1263:             * Returns an ini value.
1264:             */
1265:            public boolean getIniBoolean(String name) {
1266:                return getIniDefinition(name).getAsBoolean(this );
1267:            }
1268:
1269:            /**
1270:             * Returns an ini value as a long.
1271:             */
1272:            public long getIniLong(String name) {
1273:                return getIniDefinition(name).getAsLong(this );
1274:            }
1275:
1276:            /**
1277:             * Returns an ini value as a string, null for missing or empty string
1278:             */
1279:            public String getIniString(String name) {
1280:                return getIniDefinition(name).getAsString(this );
1281:            }
1282:
1283:            /**
1284:             * Returns an ini value.
1285:             */
1286:            public long getIniBytes(String name, long deflt) {
1287:                return getIniDefinition(name).getAsLongBytes(this , deflt);
1288:            }
1289:
1290:            /**
1291:             * Returns the ByteToChar converter.
1292:             */
1293:            public ByteToChar getByteToChar() {
1294:                return ByteToChar.create();
1295:            }
1296:
1297:            /**
1298:             * Returns the 'this' value.
1299:             */
1300:            public Value getThis() {
1301:                return _this ;
1302:            }
1303:
1304:            /**
1305:             * Sets the 'this' value, returning the old value.
1306:             */
1307:            public Value setThis(Value value) {
1308:                Value oldThis = _this ;
1309:
1310:                _this  = value.toValue();
1311:
1312:                return oldThis;
1313:            }
1314:
1315:            /**
1316:             * Gets a value.
1317:             */
1318:            public Value getValue(String name) {
1319:                Var var = getRef(name);
1320:
1321:                if (var != null)
1322:                    return var.toValue();
1323:                else
1324:                    return NullValue.NULL;
1325:            }
1326:
1327:            /**
1328:             * Gets a special value, a special value is used to store and retrieve module
1329:             * specific values in the env using a unique name.
1330:             */
1331:            public <T> T getSpecialValue(String name) {
1332:                return (T) _specialMap.get(name);
1333:            }
1334:
1335:            /**
1336:             * Gets a global
1337:             */
1338:            public Value getGlobalValue(String name) {
1339:                Var var = getGlobalRef(name);
1340:
1341:                if (var != null)
1342:                    return var.toValue();
1343:                else
1344:                    return NullValue.NULL;
1345:            }
1346:
1347:            /**
1348:             * Gets a variable
1349:             *
1350:             * @param name the variable name
1351:             * @param var the current value of the variable
1352:             */
1353:            public final Var getVar(String name, Value value) {
1354:                if (value != null)
1355:                    return (Var) value;
1356:
1357:                Var var = _map.get(name);
1358:
1359:                if (var != null)
1360:                    return var;
1361:
1362:                var = getRef(name);
1363:
1364:                if (var == null) {
1365:                    var = new Var();
1366:
1367:                    if (_map == _globalMap)
1368:                        var.setGlobal();
1369:
1370:                    _map.put(name, var);
1371:                }
1372:
1373:                return var;
1374:            }
1375:
1376:            /**
1377:             * Gets a variable
1378:             *
1379:             * @param name the variable name
1380:             * @param value the current value of the variable
1381:             */
1382:            public final Var getGlobalVar(String name, Value value) {
1383:                if (value != null)
1384:                    return (Var) value;
1385:
1386:                Var var = _globalMap.get(name);
1387:
1388:                if (var != null)
1389:                    return var;
1390:
1391:                var = getSpecialRef(name);
1392:
1393:                if (var == null) {
1394:                    var = new Var();
1395:                    var.setGlobal();
1396:                }
1397:
1398:                _globalMap.put(name, var);
1399:
1400:                return var;
1401:            }
1402:
1403:            /**
1404:             * Gets a static variable name.
1405:             */
1406:            public final String createStaticName() {
1407:                return _quercus.createStaticName();
1408:            }
1409:
1410:            /**
1411:             * Gets a static variable
1412:             *
1413:             * @param name the variable name
1414:             */
1415:            public final Var getStaticVar(String name) {
1416:                Var var = _staticMap.get(name);
1417:
1418:                if (var == null) {
1419:                    var = new Var();
1420:                    var.setGlobal();
1421:                    _staticMap.put(name, var);
1422:                }
1423:
1424:                return var;
1425:            }
1426:
1427:            /**
1428:             * Unsets variable
1429:             *
1430:             * @param name the variable name
1431:             */
1432:            public final Var unsetVar(String name) {
1433:                _map.remove(name);
1434:
1435:                return null;
1436:            }
1437:
1438:            /**
1439:             * Gets a variable
1440:             *
1441:             * @param name the variable name
1442:             * @param value the current value of the variable
1443:             */
1444:            public final Var setVar(String name, Value value) {
1445:                Var var;
1446:
1447:                if (value instanceof  Var) {
1448:                    var = (Var) value;
1449:
1450:                    if (_map == _globalMap)
1451:                        var.setGlobal();
1452:                } else
1453:                    var = new Var(value.toValue());
1454:
1455:                _map.put(name, var);
1456:
1457:                return var;
1458:            }
1459:
1460:            /**
1461:             * Unsets variable
1462:             *
1463:             * @param name the variable name
1464:             */
1465:            public final Var unsetLocalVar(String name) {
1466:                _map.remove(name);
1467:
1468:                return null;
1469:            }
1470:
1471:            /**
1472:             * Unsets variable
1473:             *
1474:             * @param name the variable name
1475:             */
1476:            public final Var unsetGlobalVar(String name) {
1477:                _globalMap.remove(name);
1478:
1479:                return null;
1480:            }
1481:
1482:            /**
1483:             * Gets a local
1484:             *
1485:             * @param var the current value of the variable
1486:             */
1487:            public static final Value getLocalVar(Value var) {
1488:                if (var == null)
1489:                    var = new Var();
1490:
1491:                return var;
1492:            }
1493:
1494:            /**
1495:             * Gets a local value
1496:             *
1497:             * @param var the current value of the variable
1498:             */
1499:            public static final Value getLocalValue(Value var) {
1500:                if (var != null)
1501:                    return var;
1502:                else
1503:                    return NullValue.NULL;
1504:            }
1505:
1506:            /**
1507:             * Gets a local
1508:             *
1509:             * @param var the current value of the variable
1510:             */
1511:            public static final Value setLocalVar(Value var, Value value) {
1512:                value = value.toValue();
1513:
1514:                if (var instanceof  Var)
1515:                    var.set(value);
1516:
1517:                return value;
1518:            }
1519:
1520:            /**
1521:             * Gets a value.
1522:             */
1523:            public Var getRef(String name) {
1524:                Var var = _map.get(name);
1525:
1526:                if (var == null) {
1527:                    var = getSpecialRef(name);
1528:
1529:                    if (var != null) {
1530:                        var.setGlobal();
1531:                        _globalMap.put(name, var);
1532:
1533:                        var = _map.get(name);
1534:                    }
1535:                }
1536:
1537:                return var;
1538:            }
1539:
1540:            /**
1541:             * Returns the raw global lookup.
1542:             */
1543:            public Var getGlobalRaw(String name) {
1544:                return _globalMap.get(name);
1545:            }
1546:
1547:            /**
1548:             * Gets a global value.
1549:             */
1550:            public Var getGlobalRef(String name) {
1551:                Var var = _globalMap.get(name);
1552:
1553:                if (var == null) {
1554:                    var = getSpecialRef(name);
1555:                    if (var == null)
1556:                        var = new Var();
1557:
1558:                    _globalMap.put(name, var);
1559:                }
1560:
1561:                return var;
1562:            }
1563:
1564:            /**
1565:             * Gets a value.
1566:             */
1567:            public Var getSpecialRef(String name) {
1568:                Var var = null;
1569:
1570:                switch (SPECIAL_VARS.get(name)) {
1571:                case _ENV: {
1572:                    var = new Var();
1573:
1574:                    _globalMap.put(name, var);
1575:
1576:                    var.set(new ArrayValueImpl());
1577:
1578:                    return var;
1579:                }
1580:
1581:                case HTTP_POST_VARS:
1582:                    if (!Quercus.INI_REGISTER_LONG_ARRAYS.getAsBoolean(this ))
1583:                        return null;
1584:                case _POST: {
1585:                    var = new Var();
1586:
1587:                    _globalMap.put(name, var);
1588:
1589:                    ArrayValue post = new ArrayValueImpl();
1590:
1591:                    var.set(post);
1592:
1593:                    if (_request == null)
1594:                        return null;
1595:
1596:                    if (!"POST".equals(_request.getMethod()))
1597:                        return var;
1598:
1599:                    if (_post != null) {
1600:                        for (Map.Entry<Value, Value> entry : _post.entrySet()) {
1601:                            post.put(entry.getKey(), entry.getValue());
1602:                        }
1603:                    }
1604:                }
1605:                    break;
1606:
1607:                case HTTP_POST_FILES:
1608:                    if (!Quercus.INI_REGISTER_LONG_ARRAYS.getAsBoolean(this ))
1609:                        return null;
1610:                case _FILES: {
1611:                    var = new Var();
1612:
1613:                    _globalMap.put(name, var);
1614:
1615:                    ArrayValue files = new ArrayValueImpl();
1616:
1617:                    if (_files != null) {
1618:                        for (Map.Entry<Value, Value> entry : _files.entrySet()) {
1619:                            files.put(entry.getKey(), entry.getValue());
1620:                        }
1621:                    }
1622:
1623:                    var.set(files);
1624:                }
1625:                    break;
1626:
1627:                case HTTP_GET_VARS:
1628:                    if (!Quercus.INI_REGISTER_LONG_ARRAYS.getAsBoolean(this ))
1629:                        return null;
1630:
1631:                case _GET: {
1632:                    var = new Var();
1633:
1634:                    ArrayValue array = new ArrayValueImpl();
1635:
1636:                    var.set(array);
1637:                    _globalMap.put(name, var);
1638:
1639:                    String queryString = _request.getQueryString();
1640:                    if (queryString == null)
1641:                        return var;
1642:
1643:                    StringUtility.parseStr(this , queryString, array, true,
1644:                            getHttpInputEncoding());
1645:
1646:                    return var;
1647:                }
1648:
1649:                case _REQUEST: {
1650:                    var = new Var();
1651:
1652:                    ArrayValue array = new ArrayValueImpl();
1653:
1654:                    var.set(array);
1655:
1656:                    _globalMap.put(name, var);
1657:
1658:                    if (_request == null)
1659:                        return var;
1660:
1661:                    try {
1662:                        String encoding = getHttpInputEncoding();
1663:
1664:                        if (encoding == null)
1665:                            encoding = "iso-8859-1";
1666:
1667:                        _request.setCharacterEncoding(encoding);
1668:                    } catch (Exception e) {
1669:                        log.log(Level.FINE, e.toString(), e);
1670:                    }
1671:
1672:                    ArrayList<String> keys = new ArrayList<String>();
1673:                    keys.addAll(_request.getParameterMap().keySet());
1674:
1675:                    Collections.sort(keys);
1676:
1677:                    boolean isMagicQuotes = getIniBoolean("magic_quotes_gpc");
1678:
1679:                    for (String key : keys) {
1680:                        String[] value = _request.getParameterValues(key);
1681:
1682:                        Post.addFormValue(this , array, key, value,
1683:                                isMagicQuotes);
1684:                    }
1685:
1686:                    if (name.equals("_REQUEST") && _post != null) {
1687:                        for (Map.Entry<Value, Value> entry : _post.entrySet()) {
1688:                            array.put(entry.getKey(), entry.getValue().copy());
1689:                        }
1690:                    }
1691:
1692:                    Cookie[] cookies = _request.getCookies();
1693:                    for (int i = 0; cookies != null && i < cookies.length; i++) {
1694:                        Post.addFormValue(this , array, cookies[i].getName(),
1695:                                new String[] { cookies[i].getValue() },
1696:                                isMagicQuotes);
1697:                    }
1698:
1699:                    return var;
1700:                }
1701:
1702:                case HTTP_SERVER_VARS:
1703:                    if (!Quercus.INI_REGISTER_LONG_ARRAYS.getAsBoolean(this ))
1704:                        return null;
1705:                case _SERVER: {
1706:                    var = new Var();
1707:
1708:                    _globalMap.put(name, var);
1709:
1710:                    var.set(new ServerArrayValue(this ));
1711:
1712:                    return var;
1713:                }
1714:
1715:                case _GLOBAL: {
1716:                    var = new Var();
1717:
1718:                    _globalMap.put(name, var);
1719:
1720:                    var.set(new GlobalArrayValue(this ));
1721:
1722:                    return var;
1723:                }
1724:
1725:                case HTTP_COOKIE_VARS:
1726:                    if (!Quercus.INI_REGISTER_LONG_ARRAYS.getAsBoolean(this ))
1727:                        return null;
1728:                case _COOKIE: {
1729:                    var = new Var();
1730:                    _globalMap.put(name, var);
1731:
1732:                    if (_request == null)
1733:                        return var;
1734:
1735:                    ArrayValue array = new ArrayValueImpl();
1736:
1737:                    Cookie[] cookies = _request.getCookies();
1738:                    if (cookies != null) {
1739:                        for (int i = 0; i < cookies.length; i++) {
1740:                            Cookie cookie = cookies[i];
1741:
1742:                            String value = decodeValue(cookie.getValue());
1743:
1744:                            StringValue valueAsValue = createString(value);
1745:
1746:                            if (getIniBoolean("magic_quotes_gpc")) // php/0876
1747:                                valueAsValue = StringModule
1748:                                        .addslashes(valueAsValue);
1749:
1750:                            array.append(createString(cookie.getName()),
1751:                                    valueAsValue);
1752:                        }
1753:                    }
1754:
1755:                    var.set(array);
1756:
1757:                    return var;
1758:                }
1759:
1760:                case PHP_SELF: {
1761:                    var = new Var();
1762:                    _globalMap.put(name, var);
1763:
1764:                    var.set(getGlobalVar("_SERVER").get(PHP_SELF_STRING));
1765:
1766:                    return var;
1767:                }
1768:
1769:                default: {
1770:                    if (_scriptContext != null) {
1771:                        Object value = _scriptContext.getAttribute(name);
1772:
1773:                        if (value == null) {
1774:                            Bindings bindings = _scriptContext
1775:                                    .getBindings(ScriptContext.ENGINE_SCOPE);
1776:
1777:                            if (bindings != null)
1778:                                value = bindings.get(name);
1779:                        }
1780:
1781:                        if (value == null) {
1782:                            Bindings bindings = _scriptContext
1783:                                    .getBindings(ScriptContext.GLOBAL_SCOPE);
1784:
1785:                            if (bindings != null)
1786:                                value = bindings.get(name);
1787:                        }
1788:
1789:                        if (value != null) {
1790:                            var = new Var();
1791:                            _globalMap.put(name, var);
1792:
1793:                            var.set(wrapJava(value));
1794:
1795:                            return var;
1796:                        }
1797:                    }
1798:                }
1799:                } // end switch
1800:
1801:                return var;
1802:            }
1803:
1804:            private static String decodeValue(String s) {
1805:                int len = s.length();
1806:                StringBuilder sb = new StringBuilder();
1807:
1808:                for (int i = 0; i < len; i++) {
1809:                    char ch = s.charAt(i);
1810:
1811:                    if (ch == '%' && i + 2 < len) {
1812:                        int d1 = s.charAt(i + 1);
1813:                        int d2 = s.charAt(i + 2);
1814:
1815:                        int v = 0;
1816:
1817:                        if ('0' <= d1 && d1 <= '9')
1818:                            v = 16 * (d1 - '0');
1819:                        else if ('a' <= d1 && d1 <= 'f')
1820:                            v = 16 * (d1 - 'a' + 10);
1821:                        else if ('A' <= d1 && d1 <= 'F')
1822:                            v = 16 * (d1 - 'A' + 10);
1823:                        else {
1824:                            sb.append('%');
1825:                            continue;
1826:                        }
1827:
1828:                        if ('0' <= d2 && d2 <= '9')
1829:                            v += (d2 - '0');
1830:                        else if ('a' <= d2 && d2 <= 'f')
1831:                            v += (d2 - 'a' + 10);
1832:                        else if ('A' <= d2 && d2 <= 'F')
1833:                            v += (d2 - 'A' + 10);
1834:                        else {
1835:                            sb.append('%');
1836:                            continue;
1837:                        }
1838:
1839:                        i += 2;
1840:                        sb.append((char) v);
1841:                    } else if (ch == '+')
1842:                        sb.append(' ');
1843:                    else
1844:                        sb.append(ch);
1845:                }
1846:
1847:                return sb.toString();
1848:            }
1849:
1850:            /**
1851:             * Gets a value.
1852:             */
1853:            public Var getVar(String name) {
1854:                Var var = _map.get(name);
1855:
1856:                if (var != null)
1857:                    return var;
1858:
1859:                var = getRef(name);
1860:
1861:                if (var == null) {
1862:                    var = new Var();
1863:
1864:                    if (_map == _globalMap) {
1865:                        // php/379c
1866:                        var.setGlobal();
1867:                    }
1868:
1869:                    _map.put(name, var);
1870:                }
1871:
1872:                return var;
1873:            }
1874:
1875:            /**
1876:             * Gets a value.
1877:             */
1878:            public Var getGlobalVar(String name) {
1879:                Var var = getGlobalRef(name);
1880:
1881:                if (var == null) {
1882:                    var = new Var();
1883:                    var.setGlobal();
1884:                    _globalMap.put(name, var);
1885:                }
1886:
1887:                return var;
1888:            }
1889:
1890:            public boolean isGlobalEnv() {
1891:                return _map == _globalMap;
1892:            }
1893:
1894:            /**
1895:             * Sets a value.
1896:             */
1897:            public Value setValue(String name, Value value) {
1898:                if (value instanceof  Var)
1899:                    _map.put(name, (Var) value);
1900:                else {
1901:                    Var var = getVar(name);
1902:                    var.set(value);
1903:                }
1904:
1905:                return value;
1906:            }
1907:
1908:            /**
1909:             * Sets a special value, a special value is used to store and retrieve module
1910:             * specific values in the env using a unique name.
1911:             */
1912:            public Object setSpecialValue(String name, Object value) {
1913:                _specialMap.put(name, value);
1914:
1915:                return value;
1916:            }
1917:
1918:            /**
1919:             * Sets a value.
1920:             */
1921:            public Value setGlobalValue(String name, Value value) {
1922:                if (value instanceof  Var)
1923:                    _globalMap.put(name, (Var) value);
1924:                else {
1925:                    Var var = getGlobalVar(name);
1926:                    var.set(value);
1927:                }
1928:
1929:                return value;
1930:            }
1931:
1932:            /**
1933:             * Gets a static class field.
1934:             *
1935:             * @param className of the owning class 
1936:             * @param name of the variable
1937:             */
1938:            public Value getStaticClassFieldValue(String className, String name) {
1939:                Var var = getStaticClassFieldVar(className, name);
1940:
1941:                if (var != null) {
1942:                    Value val = var.toValue();
1943:
1944:                    return val;
1945:                } else
1946:                    return NullValue.NULL;
1947:            }
1948:
1949:            /**
1950:             * Gets a static field from a class.
1951:             *
1952:             * @param className of the owning class 
1953:             * @param name of the variable
1954:             */
1955:            public final Var getStaticClassFieldVar(String className,
1956:                    String name) {
1957:                QuercusClass cl = findAbstractClass(className);
1958:
1959:                Var var = cl.getStaticField(this , name);
1960:
1961:                if (var == null) {
1962:                    error(L.l("{0}::${1} is an undeclared static property",
1963:                            className, name));
1964:                }
1965:
1966:                return var;
1967:            }
1968:
1969:            /**
1970:             * Sets the calling function expression.
1971:             */
1972:            public void pushCall(Expr call, Value obj) {
1973:                if (_callStack.length <= _callStackTop) {
1974:                    Expr[] newStack = new Expr[2 * _callStack.length];
1975:                    System.arraycopy(_callStack, 0, newStack, 0,
1976:                            _callStack.length);
1977:                    _callStack = newStack;
1978:
1979:                    Value[] newThisStack = new Value[2 * _callThisStack.length];
1980:                    System.arraycopy(_callThisStack, 0, newThisStack, 0,
1981:                            _callThisStack.length);
1982:                    _callThisStack = newThisStack;
1983:                }
1984:
1985:                _callStack[_callStackTop] = call;
1986:                _callThisStack[_callStackTop] = obj;
1987:
1988:                _callStackTop++;
1989:            }
1990:
1991:            /**
1992:             * Pops the top call.
1993:             */
1994:            public Expr popCall() {
1995:                return _callStack[--_callStackTop];
1996:            }
1997:
1998:            /**
1999:             * Returns the stack depth.
2000:             */
2001:            public int getCallDepth() {
2002:                return _callStackTop;
2003:            }
2004:
2005:            /**
2006:             * Peeks at the the top call.
2007:             */
2008:            public Expr peekCall(int depth) {
2009:                if (_callStackTop - depth > 0)
2010:                    return _callStack[_callStackTop - depth - 1];
2011:                else
2012:                    return null;
2013:            }
2014:
2015:            /**
2016:             * Peeks at the the "this" top call.
2017:             */
2018:            public Value peekCallThis(int depth) {
2019:                if (_callStackTop - depth > 0)
2020:                    return _callThisStack[_callStackTop - depth - 1];
2021:                else
2022:                    return null;
2023:            }
2024:
2025:            public ArrayList<String> getStackTrace() {
2026:                ArrayList<String> trace = new ArrayList<String>();
2027:
2028:                for (int i = _callStackTop - 1; i >= 0; i--) {
2029:                    String entry;
2030:                    Location location = _callStack[i].getLocation();
2031:                    String loc;
2032:
2033:                    if (location != null && location.getFileName() != null) {
2034:                        loc = (" (at " + location.getFileName() + ":"
2035:                                + location.getLineNumber() + ")");
2036:                    } else
2037:                        loc = "";
2038:
2039:                    if (_callThisStack[i] != null
2040:                            && !"".equals(_callThisStack[i].toString())) {
2041:                        entry = _callThisStack[i] + "."
2042:                                + _callStack[i].toString() + loc;
2043:                    } else
2044:                        entry = _callStack[i].toString() + loc;
2045:
2046:                    trace.add(entry);
2047:                }
2048:
2049:                return trace;
2050:            }
2051:
2052:            /**
2053:             * Pushes a new environment.
2054:             */
2055:            public HashMap<String, Var> pushEnv(HashMap<String, Var> map) {
2056:                HashMap<String, Var> oldEnv = _map;
2057:
2058:                _map = map;
2059:
2060:                return oldEnv;
2061:            }
2062:
2063:            /**
2064:             * Restores the old environment.
2065:             */
2066:            public void popEnv(HashMap<String, Var> oldEnv) {
2067:                _map = oldEnv;
2068:            }
2069:
2070:            /**
2071:             * Returns the current environment.
2072:             */
2073:            public HashMap<String, Var> getEnv() {
2074:                return _map;
2075:            }
2076:
2077:            /**
2078:             * Returns the current environment.
2079:             */
2080:            public HashMap<String, Var> getGlobalEnv() {
2081:                return _globalMap;
2082:            }
2083:
2084:            /**
2085:             * Pushes a new environment.
2086:             */
2087:            public final Value[] setFunctionArgs(Value[] args) {
2088:                Value[] oldArgs = _functionArgs;
2089:
2090:                Value[] newArgs = new Value[args.length];
2091:
2092:                for (int i = 0; args != null && i < args.length; i++) {
2093:                    // php/3715, 3768
2094:                    newArgs[i] = args[i].toValue().toArgValue();
2095:                }
2096:
2097:                _functionArgs = newArgs;
2098:
2099:                return oldArgs;
2100:            }
2101:
2102:            /**
2103:             * Pushes a new environment.
2104:             */
2105:            public final Value[] setFunctionArgsNoCopy(Value[] args) {
2106:                Value[] oldArgs = _functionArgs;
2107:
2108:                for (int i = 0; args != null && i < args.length; i++)
2109:                    args[i] = args[i].toValue();
2110:
2111:                _functionArgs = args;
2112:
2113:                return oldArgs;
2114:            }
2115:
2116:            /**
2117:             * Pushes a new environment.
2118:             */
2119:            public final void restoreFunctionArgs(Value[] args) {
2120:                _functionArgs = args;
2121:            }
2122:
2123:            /**
2124:             * Returns the function args.
2125:             */
2126:            public final Value[] getFunctionArgs() {
2127:                return _functionArgs;
2128:            }
2129:
2130:            /**
2131:             * Removes a specialValue
2132:             */
2133:            public Object removeSpecialValue(String name) {
2134:                return _specialMap.remove(name);
2135:            }
2136:
2137:            /**
2138:             * Returns a constant.
2139:             */
2140:            public Value getConstant(String name) {
2141:                Value value = getConstantImpl(name);
2142:
2143:                if (value != null)
2144:                    return value;
2145:
2146:                /* XXX:
2147:                   notice(L.l("Converting undefined constant '{0}' to string.",
2148:                   name));
2149:                 */
2150:
2151:                value = createString(name);
2152:
2153:                return value;
2154:            }
2155:
2156:            /**
2157:             * Returns true if the constant is defined.
2158:             */
2159:            public boolean isDefined(String name) {
2160:                return getConstantImpl(name) != null;
2161:            }
2162:
2163:            /**
2164:             * Returns a constant.
2165:             */
2166:            private Value getConstantImpl(String name) {
2167:                Value value = _constMap.get(name);
2168:
2169:                if (value != null)
2170:                    return value;
2171:
2172:                value = _quercus.getConstant(name);
2173:                if (value != null)
2174:                    return value;
2175:
2176:                if (_lowerConstMap != null) {
2177:                    value = _lowerConstMap.get(name.toLowerCase());
2178:
2179:                    if (value != null)
2180:                        return value;
2181:                }
2182:
2183:                return null;
2184:            }
2185:
2186:            /**
2187:             * Removes a constant.
2188:             */
2189:            public Value removeConstant(String name) {
2190:                return _constMap.remove(name);
2191:            }
2192:
2193:            /**
2194:             * Sets a constant.
2195:             */
2196:            public Value addConstant(String name, Value value,
2197:                    boolean isCaseInsensitive) {
2198:                Value oldValue = _constMap.get(name);
2199:
2200:                if (oldValue != null)
2201:                    return oldValue;
2202:
2203:                _constMap.put(name, value);
2204:
2205:                if (_lowerConstMap != null && isCaseInsensitive)
2206:                    _lowerConstMap.put(name.toLowerCase(), value);
2207:
2208:                return value;
2209:            }
2210:
2211:            /**
2212:             * Returns an array of the defined functions.
2213:             */
2214:            public ArrayValue getDefinedConstants() {
2215:                ArrayValue result = new ArrayValueImpl();
2216:
2217:                for (Map.Entry<String, Value> entry : _quercus.getConstMap()
2218:                        .entrySet()) {
2219:                    result.put(createString(entry.getKey()), entry.getValue());
2220:                }
2221:
2222:                for (Map.Entry<String, Value> entry : _constMap.entrySet()) {
2223:                    result.put(createString(entry.getKey()), entry.getValue());
2224:                }
2225:
2226:                return result;
2227:            }
2228:
2229:            /**
2230:             * Returns true if an extension is loaded.
2231:             */
2232:            public boolean isExtensionLoaded(String name) {
2233:                return getQuercus().isExtensionLoaded(name);
2234:            }
2235:
2236:            /**
2237:             * Returns true if an extension is loaded.
2238:             */
2239:            public HashSet<String> getLoadedExtensions() {
2240:                return getQuercus().getLoadedExtensions();
2241:            }
2242:
2243:            /**
2244:             * Returns true if an extension is loaded.
2245:             */
2246:            public Value getExtensionFuncs(String name) {
2247:                return getQuercus().getExtensionFuncs(name);
2248:            }
2249:
2250:            /**
2251:             * Returns the default stream resource.
2252:             */
2253:            public StreamContextResource getDefaultStreamContext() {
2254:                if (_defaultStreamContext == null)
2255:                    _defaultStreamContext = new StreamContextResource();
2256:
2257:                return _defaultStreamContext;
2258:            }
2259:
2260:            public ArrayValue getDefinedFunctions() {
2261:                // return _defState.getDefinedFunctions();
2262:                return new ArrayValueImpl();
2263:            }
2264:
2265:            /**
2266:             * Returns the function with a given name.
2267:             *
2268:             * Compiled mode normally uses the _fun array directly, so this call
2269:             * is rare.
2270:             */
2271:            public AbstractFunction findFunction(String name) {
2272:                int id = _quercus.findFunctionId(name);
2273:
2274:                if (id >= 0) {
2275:                    if (id < _fun.length
2276:                            && !(_fun[id] instanceof  UndefinedFunction))
2277:                        return _fun[id];
2278:                    else
2279:                        return null;
2280:                }
2281:
2282:                AbstractFunction fun = _quercus.findFunctionImpl(name);
2283:
2284:                if (fun != null)
2285:                    return fun;
2286:
2287:                if (isStrict())
2288:                    return null;
2289:
2290:                name = name.toLowerCase();
2291:
2292:                id = _quercus.findFunctionId(name);
2293:
2294:                if (id >= 0) {
2295:                    if (id < _fun.length
2296:                            && !(_fun[id] instanceof  UndefinedFunction))
2297:                        return _fun[id];
2298:                    else
2299:                        return null;
2300:                }
2301:
2302:                return _quercus.findLowerFunctionImpl(name);
2303:            }
2304:
2305:            public AbstractFunction getFunction(String name) {
2306:                AbstractFunction fun = findFunction(name);
2307:
2308:                if (fun != null)
2309:                    return fun;
2310:                else
2311:                    throw createErrorException(L.l(
2312:                            "'{0}' is an unknown function.", name));
2313:            }
2314:
2315:            /**
2316:             * Finds the java reflection method for the function with the given name.
2317:             *
2318:             * @param name the method name
2319:             * @return the found method or null if no method found.
2320:             */
2321:            public AbstractFunction getFunction(Value name) {
2322:                name = name.toValue();
2323:
2324:                if (name instanceof  CallbackFunction)
2325:                    return ((CallbackFunction) name).getFunction();
2326:
2327:                return getFunction(name.toString());
2328:            }
2329:
2330:            /*
2331:            public DefinitionState getDefinitionState()
2332:            {
2333:              return _defState;
2334:            }
2335:             */
2336:
2337:            public Value addFunction(String name, AbstractFunction fun) {
2338:                AbstractFunction staticFun = _quercus
2339:                        .findLowerFunctionImpl(name.toLowerCase());
2340:
2341:                if (staticFun != null)
2342:                    throw new QuercusException(L.l(
2343:                            "can't redefine function {0}", name));
2344:
2345:                int id = _quercus.getFunctionId(name);
2346:
2347:                // XXX: anonymous/generated functions(?), e.g. like foo2431
2348:
2349:                if (_fun.length <= id) {
2350:                    AbstractFunction[] funMap = new AbstractFunction[id + 256];
2351:                    System.arraycopy(_fun, 0, funMap, 0, _fun.length);
2352:                    _fun = funMap;
2353:                }
2354:
2355:                if (_fun[id] != null
2356:                        && !(_fun[id] instanceof  UndefinedFunction))
2357:                    throw new QuercusException(L.l(
2358:                            "can't redefine function {0}", name));
2359:
2360:                _fun[id] = fun;
2361:
2362:                return BooleanValue.TRUE;
2363:            }
2364:
2365:            /**
2366:             * Adds a function from a compiled include
2367:             *
2368:             * @param name the function name, must be an intern() string
2369:             * @param lowerName the function name, must be an intern() string
2370:             */
2371:            public Value addFunctionFromPage(String name, String lowerName,
2372:                    AbstractFunction fun) {
2373:                // XXX: skip the old function check since the include for compiled
2374:                // pages is already verified.  Might have a switch here?
2375:                /*
2376:                AbstractFunction oldFun = _lowerFunMap.get(lowerName);
2377:
2378:                if (oldFun == null)
2379:                  oldFun = _quercus.findLowerFunctionImpl(lowerName);
2380:
2381:                if (oldFun != null) {
2382:                  throw new QuercusException(L.l("can't redefine function {0}", name));
2383:                }
2384:
2385:                _funMap.put(name, fun);
2386:
2387:                if (! isStrict())
2388:                  _lowerFunMap.put(lowerName, fun);
2389:                 */
2390:
2391:                return BooleanValue.TRUE;
2392:            }
2393:
2394:            /**
2395:             * Finds the java reflection method for the function with the given name.
2396:             *
2397:             * @param className the class name
2398:             * @param methodName the method name
2399:             * @return the found method or null if no method found.
2400:             */
2401:            public AbstractFunction findMethod(String className,
2402:                    String methodName) {
2403:                QuercusClass cl = findClass(className);
2404:
2405:                if (cl == null) {
2406:                    error(L.l("'{0}' is an unknown class.", className));
2407:                    return null;
2408:                }
2409:
2410:                AbstractFunction fun = cl.findFunction(methodName);
2411:
2412:                if (fun == null && !isStrict())
2413:                    fun = cl.findFunctionLowerCase(methodName.toLowerCase());
2414:
2415:                if (fun == null) {
2416:                    error(L.l("'{0}::{1}' is an unknown method.", className,
2417:                            methodName));
2418:                    return null;
2419:                }
2420:
2421:                return fun;
2422:            }
2423:
2424:            /**
2425:             * Compiles and calluates the given code
2426:             *
2427:             * @param code the code to calluate
2428:             * @return the result
2429:             */
2430:            public Value evalCode(String code) throws IOException {
2431:                if (log.isLoggable(Level.FINER))
2432:                    log.finer(code);
2433:
2434:                Quercus quercus = getQuercus();
2435:
2436:                QuercusProgram program = quercus.parseEvalExpr(code);
2437:
2438:                Value value = program.execute(this );
2439:
2440:                return value;
2441:            }
2442:
2443:            /**
2444:             * Evaluates the named function.
2445:             *
2446:             * @param name the function name
2447:             * @return the function value
2448:             */
2449:            public Value call(String name) {
2450:                AbstractFunction fun = findFunction(name);
2451:
2452:                if (fun == null)
2453:                    return error(L.l("'{0}' is an unknown function.", name));
2454:
2455:                return fun.call(this );
2456:            }
2457:
2458:            /**
2459:             * Evaluates the named function.
2460:             *
2461:             * @param name the function name
2462:             * @param a0 the first argument
2463:             * @return the function value
2464:             */
2465:            public Value call(String name, Value a0) {
2466:                AbstractFunction fun = findFunction(name);
2467:
2468:                if (fun == null)
2469:                    return error(L.l("'{0}' is an unknown function.", name));
2470:
2471:                return fun.call(this , a0);
2472:            }
2473:
2474:            /**
2475:             * Evaluates the named function.
2476:             *
2477:             * @param name the function name
2478:             * @param a0 the first argument
2479:             * @param a1 the second argument
2480:             * @return the function value
2481:             */
2482:            public Value call(String name, Value a0, Value a1) {
2483:                return getFunction(name).call(this , a0, a1);
2484:            }
2485:
2486:            /**
2487:             * Evaluates the named function.
2488:             *
2489:             * @param name the function name
2490:             * @param a0 the first argument
2491:             * @param a1 the second argument
2492:             * @param a2 the third argument
2493:             * @return the function value
2494:             */
2495:            public Value call(String name, Value a0, Value a1, Value a2) {
2496:                return getFunction(name).call(this , a0, a1, a2);
2497:            }
2498:
2499:            /**
2500:             * Evaluates the named function.
2501:             *
2502:             * @param name the function name
2503:             * @param a0 the first argument
2504:             * @param a1 the second argument
2505:             * @param a2 the third argument
2506:             * @param a3 the fourth argument
2507:             * @return the function value
2508:             */
2509:            public Value call(String name, Value a0, Value a1, Value a2,
2510:                    Value a3) {
2511:                return getFunction(name).call(this , a0, a1, a2, a3);
2512:            }
2513:
2514:            /**
2515:             * Evaluates the named function.
2516:             *
2517:             * @param name the function name
2518:             * @param a0 the first argument
2519:             * @param a1 the second argument
2520:             * @param a2 the third argument
2521:             * @param a3 the fourth argument
2522:             * @param a4 the fifth argument
2523:             * @return the function value
2524:             */
2525:            public Value call(String name, Value a0, Value a1, Value a2,
2526:                    Value a3, Value a4) {
2527:                return getFunction(name).call(this , a0, a1, a2, a3, a4);
2528:            }
2529:
2530:            /**
2531:             * Evaluates the named function.
2532:             *
2533:             * @param name the function name
2534:             * @param args the arguments
2535:             * @return the function value
2536:             */
2537:            public Value call(String name, Value[] args) {
2538:                return getFunction(name).call(this , args);
2539:            }
2540:
2541:            /**
2542:             * Evaluates the named function.
2543:             *
2544:             * @param name the function name
2545:             * @return the function value
2546:             */
2547:            public Value callRef(String name) {
2548:                AbstractFunction fun = findFunction(name);
2549:
2550:                if (fun == null)
2551:                    return error(L.l("'{0}' is an unknown function.", name));
2552:
2553:                return fun.callRef(this );
2554:            }
2555:
2556:            /**
2557:             * EvalRefuates the named function.
2558:             *
2559:             * @param name the function name
2560:             * @param a0 the first argument
2561:             * @return the function value
2562:             */
2563:            public Value callRef(String name, Value a0) {
2564:                AbstractFunction fun = findFunction(name);
2565:
2566:                if (fun == null)
2567:                    return error(L.l("'{0}' is an unknown function.", name));
2568:
2569:                return fun.callRef(this , a0);
2570:            }
2571:
2572:            /**
2573:             * EvalRefuates the named function.
2574:             *
2575:             * @param name the function name
2576:             * @param a0 the first argument
2577:             * @param a1 the second argument
2578:             * @return the function value
2579:             */
2580:            public Value callRef(String name, Value a0, Value a1) {
2581:                AbstractFunction fun = findFunction(name);
2582:
2583:                if (fun == null)
2584:                    return error(L.l("'{0}' is an unknown function.", name));
2585:
2586:                return fun.callRef(this , a0, a1);
2587:            }
2588:
2589:            /**
2590:             * EvalRefuates the named function.
2591:             *
2592:             * @param name the function name
2593:             * @param a0 the first argument
2594:             * @param a1 the second argument
2595:             * @param a2 the third argument
2596:             * @return the function value
2597:             */
2598:            public Value callRef(String name, Value a0, Value a1, Value a2) {
2599:                AbstractFunction fun = findFunction(name);
2600:
2601:                if (fun == null)
2602:                    return error(L.l("'{0}' is an unknown function.", name));
2603:
2604:                return fun.callRef(this , a0, a1, a2);
2605:            }
2606:
2607:            /**
2608:             * Evaluates the named function.
2609:             *
2610:             * @param name the function name
2611:             * @param a0 the first argument
2612:             * @param a1 the second argument
2613:             * @param a2 the third argument
2614:             * @param a3 the fourth argument
2615:             * @return the function value
2616:             */
2617:            public Value callRef(String name, Value a0, Value a1, Value a2,
2618:                    Value a3) {
2619:                AbstractFunction fun = findFunction(name);
2620:
2621:                if (fun == null)
2622:                    return error(L.l("'{0}' is an unknown function.", name));
2623:
2624:                return fun.callRef(this , a0, a1, a2, a3);
2625:            }
2626:
2627:            /**
2628:             * Evaluates the named function.
2629:             *
2630:             * @param name the function name
2631:             * @param a0 the first argument
2632:             * @param a1 the second argument
2633:             * @param a2 the third argument
2634:             * @param a3 the fourth argument
2635:             * @param a4 the fifth argument
2636:             * @return the function value
2637:             */
2638:            public Value callRef(String name, Value a0, Value a1, Value a2,
2639:                    Value a3, Value a4) {
2640:                AbstractFunction fun = findFunction(name);
2641:
2642:                if (fun == null)
2643:                    return error(L.l("'{0}' is an unknown function.", name));
2644:
2645:                return fun.callRef(this , a0, a1, a2, a3, a4);
2646:            }
2647:
2648:            /**
2649:             * Evaluates the named function.
2650:             *
2651:             * @param name the function name
2652:             * @param args the arguments
2653:             * @return the function value
2654:             */
2655:            public Value callRef(String name, Value[] args) {
2656:                AbstractFunction fun = findFunction(name);
2657:
2658:                if (fun == null)
2659:                    return error(L.l("'{0}' is an unknown function.", name));
2660:
2661:                return fun.callRef(this , args);
2662:            }
2663:
2664:            /**
2665:             * Adds a class, e.g. from an include.
2666:             */
2667:            public void addClassDef(String name, ClassDef cl) {
2668:                int id = _quercus.getClassId(name);
2669:
2670:                if (_classDef.length <= id) {
2671:                    ClassDef[] def = new ClassDef[id + 256];
2672:                    System.arraycopy(_classDef, 0, def, 0, _classDef.length);
2673:                    _classDef = def;
2674:                }
2675:
2676:                _classDef[id] = cl;
2677:            }
2678:
2679:            public ClassDef findClassDef(String name) {
2680:                int id = _quercus.getClassId(name);
2681:
2682:                if (id < _classDef.length)
2683:                    return _classDef[id];
2684:                else
2685:                    return null;
2686:            }
2687:
2688:            /**
2689:             * Creates a stdClass object.
2690:             */
2691:            public ObjectValue createObject() {
2692:                try {
2693:                    return (ObjectValue) _quercus.getStdClass().callNew(this ,
2694:                            EMPTY_VALUE);
2695:                } catch (Exception e) {
2696:                    throw new QuercusModuleException(e);
2697:                }
2698:            }
2699:
2700:            /*
2701:             * Creates an empty string.
2702:             */
2703:            public StringValue createEmptyString() {
2704:                if (_isUnicodeSemantics)
2705:                    return UnicodeBuilderValue.EMPTY;
2706:                else
2707:                    return StringBuilderValue.EMPTY;
2708:            }
2709:
2710:            /**
2711:             * Creates a PHP string from a byte buffer.
2712:             */
2713:            public StringValue createString(byte[] buffer, int offset,
2714:                    int length) {
2715:                if (_isUnicodeSemantics)
2716:                    return new UnicodeValueImpl(new String(buffer, offset,
2717:                            length));
2718:                else
2719:                    return new StringBuilderValue(buffer, offset, length);
2720:            }
2721:
2722:            /**
2723:             * Creates a PHP string from a byte buffer.
2724:             */
2725:            public StringValue createString(char[] buffer, int length) {
2726:                if (_isUnicodeSemantics)
2727:                    return new UnicodeBuilderValue(buffer, length);
2728:                else
2729:                    return new StringBuilderValue(buffer, 0, length);
2730:            }
2731:
2732:            /**
2733:             * Creates a PHP string from a char buffer.
2734:             */
2735:            public StringValue createString(char[] buffer, int offset,
2736:                    int length) {
2737:                if (_isUnicodeSemantics)
2738:                    return new UnicodeBuilderValue(buffer, offset, length);
2739:                else
2740:                    return new StringBuilderValue(buffer, offset, length);
2741:            }
2742:
2743:            /**
2744:             * Creates a PHP string from a java String.
2745:             */
2746:            public StringValue createString(String s) {
2747:                if (s == null) {
2748:                    return (_isUnicodeSemantics ? UnicodeBuilderValue.EMPTY
2749:                            : StringBuilderValue.EMPTY);
2750:                } else if (_isUnicodeSemantics)
2751:                    return new UnicodeBuilderValue(s);
2752:                else
2753:                    return new StringBuilderValue(s);
2754:            }
2755:
2756:            /**
2757:             * Creates a string from a byte.
2758:             */
2759:            public StringValue createString(char ch) {
2760:                // XXX: create static cache for this
2761:
2762:                if (_isUnicodeSemantics)
2763:                    return new UnicodeValueImpl(String.valueOf(ch));
2764:                else
2765:                    return new StringBuilderValue(String.valueOf(ch));
2766:            }
2767:
2768:            /**
2769:             * Creates a PHP string from a buffer.
2770:             */
2771:            public StringValue createBinaryString(TempBuffer head) {
2772:                StringValue string;
2773:
2774:                if (_isUnicodeSemantics)
2775:                    string = new BinaryBuilderValue();
2776:                else
2777:                    string = new StringBuilderValue();
2778:
2779:                for (; head != null; head = head.getNext()) {
2780:                    string.append(head.getBuffer(), 0, head.getLength());
2781:                }
2782:
2783:                return string;
2784:            }
2785:
2786:            /**
2787:             * Creates a PHP Exception.
2788:             */
2789:            public Value createException(Exception e) {
2790:                QuercusClass cls = findClass("Exception");
2791:
2792:                StringValue message = createString(e.getMessage());
2793:                Value[] args = { message };
2794:
2795:                Value value = cls.callNew(this , args);
2796:
2797:                StackTraceElement elt = e.getStackTrace()[0];
2798:
2799:                value.putField(this , "file", createString(elt.getFileName()));
2800:                value.putField(this , "line", LongValue.create(elt
2801:                        .getLineNumber()));
2802:                value
2803:                        .putField(this , "trace", ErrorModule
2804:                                .debug_backtrace(this ));
2805:
2806:                return value;
2807:            }
2808:
2809:            /**
2810:             * Generate an object id.
2811:             */
2812:            public int generateId() {
2813:                return ++_objectId;
2814:            }
2815:
2816:            /**
2817:             * Returns an introspected Java class defintion.
2818:             */
2819:            public JavaClassDef getJavaClassDefinition(String className) {
2820:                JavaClassDef def = getJavaClassDefinition(className, true);
2821:
2822:                if (def != null)
2823:                    return def;
2824:                else
2825:                    throw createErrorException(L.l(
2826:                            "'{0}' class definition not found", className));
2827:            }
2828:
2829:            /*
2830:             * Returns an introspected Java class definition.
2831:             */
2832:            public JavaClassDef getJavaClassDefinition(Class type) {
2833:                JavaClassDef def = _quercus.getJavaClassDefinition(type, type
2834:                        .getName());
2835:
2836:                def.init();
2837:
2838:                return def;
2839:            }
2840:
2841:            private JavaClassDef getJavaClassDefinition(String className,
2842:                    boolean useImport) {
2843:                JavaClassDef def = null;
2844:
2845:                try {
2846:                    def = _quercus.getJavaClassDefinition(className);
2847:                } catch (Throwable e) {
2848:                    if (useImport) {
2849:                        def = importJavaClass(className);
2850:                    } else
2851:                        log.log(Level.FINER, e.toString(), e);
2852:
2853:                }
2854:
2855:                if (def != null)
2856:                    def.init();
2857:
2858:                return def;
2859:            }
2860:
2861:            /**
2862:             * Imports a Java class.
2863:             * 
2864:             * @param className name of class to import
2865:             * @return class definition of imported class, null if class not found
2866:             */
2867:            public JavaClassDef importJavaClass(String className) {
2868:                if (_importMap == null)
2869:                    return null;
2870:
2871:                String fullName = _importMap.getQualified(className);
2872:
2873:                if (fullName != null) {
2874:                    return getJavaClassDefinition(fullName, false);
2875:                } else {
2876:                    ArrayList<String> wildcardList = _importMap
2877:                            .getWildcardList();
2878:
2879:                    for (String entry : wildcardList) {
2880:                        fullName = entry + '.' + className;
2881:
2882:                        JavaClassDef def = getJavaClassDefinition(fullName,
2883:                                false);
2884:
2885:                        if (def != null) {
2886:                            _importMap.putQualified(className, fullName);
2887:                            return def;
2888:                        }
2889:                    }
2890:                }
2891:
2892:                return null;
2893:            }
2894:
2895:            /**
2896:             * Adds a Quercus class import.
2897:             * 
2898:             * @param javaName fully qualified class import string
2899:             */
2900:            public void putQualifiedImport(String javaName) {
2901:                if (_importMap == null)
2902:                    _importMap = new ImportMap();
2903:
2904:                String phpName = _importMap.putQualified(javaName);
2905:            }
2906:
2907:            /**
2908:             * Adds a Quercus class import.
2909:             * 
2910:             * @param name wildcard class import string minus '*' at the end (i.e. java.util.)
2911:             */
2912:            public void addWildcardImport(String name) {
2913:                if (_importMap == null)
2914:                    _importMap = new ImportMap();
2915:
2916:                _importMap.addWildcardImport(name);
2917:            }
2918:
2919:            /**
2920:             * Returns a PHP value for a Java object
2921:             */
2922:            public Value wrapJava(Object obj) {
2923:                return wrapJava(obj, null, false);
2924:            }
2925:
2926:            /**
2927:             * Returns a PHP value for a Java object
2928:             *
2929:             * @param isNullAsFalse what to return if <i>obj</i> is null, if true return
2930:             * {@link BooleanValue.FALSE} otherwise return {@link NullValue.NULL)
2931:             */
2932:            public Value wrapJava(Object obj, boolean isNullAsFalse) {
2933:                return wrapJava(obj, null, isNullAsFalse);
2934:            }
2935:
2936:            /**
2937:             * Returns a PHP value for a Java object
2938:             *
2939:             * @param isNullAsFalse what to return if <i>obj</i> is null, if true return
2940:             * {@link BooleanValue.FALSE} otherwise return {@link NullValue.NULL)
2941:             */
2942:            public Value wrapJava(Object obj, JavaClassDef def,
2943:                    boolean isNullAsFalse) {
2944:                if (obj == null) {
2945:                    if (isNullAsFalse)
2946:                        return BooleanValue.FALSE;
2947:                    else
2948:                        return NullValue.NULL;
2949:                }
2950:
2951:                if (obj instanceof  Value)
2952:                    return (Value) obj;
2953:
2954:                if (def == null)
2955:                    def = getJavaClassDefinition(obj.getClass());
2956:                else if (def.getType() != obj.getClass()) {
2957:                    // XXX: what if types are incompatible, does it matter?
2958:                    // if it doesn't matter, simplify this to one if with no else
2959:                    def = getJavaClassDefinition(obj.getClass());
2960:                }
2961:
2962:                if (def.isArray()) {
2963:                    ArrayValueImpl arrayValueImpl = new ArrayValueImpl();
2964:
2965:                    Class componentClass = def.getType().getComponentType();
2966:
2967:                    MarshalFactory factory = _quercus.getModuleContext()
2968:                            .getMarshalFactory();
2969:                    Marshal componentClassMarshal = factory
2970:                            .create(componentClass);
2971:
2972:                    int length = Array.getLength(obj);
2973:
2974:                    for (int i = 0; i < length; i++) {
2975:                        arrayValueImpl.put(componentClassMarshal.unmarshal(
2976:                                this , Array.get(obj, i)));
2977:                    }
2978:
2979:                    return arrayValueImpl;
2980:                } else {
2981:                    return def.wrap(this , obj);
2982:                }
2983:            }
2984:
2985:            /**
2986:             * Finds the class with the given name.
2987:             *
2988:             * @param name the class name
2989:             * @return the found class or null if no class found.
2990:             */
2991:            public QuercusClass findClass(String name) {
2992:                return findClass(name, true);
2993:            }
2994:
2995:            /**
2996:             * Finds the class with the given name.
2997:             *
2998:             * @param name the class name
2999:             * @param useAutoload use autoload to locate the class if necessary
3000:             * @return the found class or null if no class found.
3001:             */
3002:            public QuercusClass findClass(String name, boolean useAutoload) {
3003:                QuercusClass cl = _classMap.get(name);
3004:
3005:                if (cl != null)
3006:                    return cl;
3007:
3008:                cl = _lowerClassMap.get(name.toLowerCase());
3009:
3010:                if (cl != null)
3011:                    return cl;
3012:
3013:                cl = createClassImpl(name, useAutoload, true);
3014:
3015:                if (cl != null) {
3016:                    _classMap.put(cl.getName(), cl);
3017:                    _lowerClassMap.put(cl.getName().toLowerCase(), cl);
3018:
3019:                    // php/09b7
3020:                    cl.init(this );
3021:
3022:                    return cl;
3023:                } else
3024:                    return null;
3025:            }
3026:
3027:            /**
3028:             * Finds the class with the given name.
3029:             *
3030:             * @param name the class name
3031:             * @param useAutoload use autoload to locate the class if necessary
3032:             * @param useImport import the class if necessary
3033:             * 
3034:             * @return the found class or null if no class found.
3035:             */
3036:            private QuercusClass createClassImpl(String name,
3037:                    boolean useAutoload, boolean useImport) {
3038:                int id = _quercus.getClassId(name);
3039:
3040:                ClassDef classDef = _classDef[id];
3041:
3042:                if (classDef != null) {
3043:                    String parentName = classDef.getParentName();
3044:
3045:                    QuercusClass parent = null;
3046:
3047:                    if (parentName != null)
3048:                        parent = findClass(parentName);
3049:
3050:                    if (parentName == null || parent instanceof  QuercusClass)
3051:                        return createQuercusClass(classDef,
3052:                                (QuercusClass) parent);
3053:                    else
3054:                        return null; // php/
3055:                }
3056:
3057:                ClassDef staticClass = _quercus.findClass(name);
3058:
3059:                if (staticClass != null)
3060:                    return createQuercusClass(staticClass, null); // XXX: cache
3061:
3062:                if (useAutoload) {
3063:                    if (!_autoloadClasses.contains(name)) {
3064:                        try {
3065:                            _autoloadClasses.add(name);
3066:
3067:                            if (_autoloadFunctionMap != null) {
3068:                                for (Map.Entry<String, AbstractFunction> entry : _autoloadFunctionMap
3069:                                        .entrySet()) {
3070:                                    entry.getValue().call(this ,
3071:                                            new StringBuilderValue(name));
3072:
3073:                                    QuercusClass cls = createClassImpl(name,
3074:                                            false, useImport);
3075:
3076:                                    if (cls != null)
3077:                                        break;
3078:                                }
3079:                            } else {
3080:                                if (_autoload == null)
3081:                                    _autoload = findFunction("__autoload");
3082:
3083:                                if (_autoload != null) {
3084:                                    _autoload.call(this ,
3085:                                            new StringBuilderValue(name));
3086:
3087:                                    return createClassImpl(name, false,
3088:                                            useImport);
3089:                                }
3090:                            }
3091:                        } finally {
3092:                            _autoloadClasses.remove(name);
3093:                        }
3094:                    }
3095:                }
3096:
3097:                if (useImport) {
3098:                    if (importPhpClass(name)) {
3099:                        return createClassImpl(name, false, false);
3100:                    } else {
3101:                        try {
3102:                            JavaClassDef javaClassDef = getJavaClassDefinition(
3103:                                    name, true);
3104:
3105:                            if (javaClassDef != null)
3106:                                return createQuercusClass(javaClassDef, null);
3107:                        } catch (Exception e) {
3108:                            log.log(Level.FINER, e.toString(), e);
3109:                        }
3110:                    }
3111:                }
3112:
3113:                return null;
3114:            }
3115:
3116:            /*
3117:             * Registers an SPL autoload function.
3118:             */
3119:            public void addAutoloadFunction(String name) {
3120:                if (_autoloadFunctionMap == null)
3121:                    _autoloadFunctionMap = new LinkedHashMap<String, AbstractFunction>();
3122:
3123:                _autoloadFunctionMap.put(name, getFunction(name));
3124:            }
3125:
3126:            /*
3127:             * Unregisters an SPL autoload function.
3128:             */
3129:            public void removeAutoloadFunction(String fun) {
3130:                if (_autoloadFunctionMap != null) {
3131:                    _autoloadFunctionMap.remove(fun);
3132:
3133:                    //restore original __autoload functionality
3134:                    if (_autoloadFunctionMap.size() == 0)
3135:                        _autoloadFunctionMap = null;
3136:                }
3137:            }
3138:
3139:            /*
3140:             * Returns the registered SPL autoload functions.
3141:             */
3142:            public LinkedHashMap<String, AbstractFunction> getAutoloadFunctions() {
3143:                return _autoloadFunctionMap;
3144:            }
3145:
3146:            /**
3147:             * Imports a PHP class.
3148:             *
3149:             * @param name of the PHP class
3150:             * 
3151:             * @return true if matching php file was found and included.
3152:             */
3153:            public boolean importPhpClass(String name) {
3154:                if (_importMap == null)
3155:                    return false;
3156:
3157:                String fullName = _importMap.getQualifiedPhp(name);
3158:
3159:                URL url = null;
3160:                ClassLoader loader = Thread.currentThread()
3161:                        .getContextClassLoader();
3162:
3163:                if (fullName != null) {
3164:                    url = loader.getResource(fullName);
3165:                } else {
3166:                    for (String entry : _importMap.getWildcardPhpList()) {
3167:
3168:                        url = loader.getResource(entry + '/' + name + ".php");
3169:
3170:                        if (url != null)
3171:                            break;
3172:                    }
3173:                }
3174:
3175:                if (url != null) {
3176:                    includeOnce(url.toString());
3177:                    return true;
3178:                } else {
3179:                    return false;
3180:                }
3181:            }
3182:
3183:            /**
3184:             * Returns the declared classes.
3185:             *
3186:             * @return an array of the declared classes()
3187:             */
3188:            public Value getDeclaredClasses() {
3189:                // return _defState.getDeclaredClasses(this);
3190:                return NullValue.NULL;
3191:            }
3192:
3193:            /**
3194:             * Finds the class with the given name.
3195:             *
3196:             * @param name the class name
3197:             * @return the found class or null if no class found.
3198:             */
3199:            public QuercusClass findAbstractClass(String name) {
3200:                QuercusClass cl = findClass(name, true);
3201:
3202:                if (cl != null)
3203:                    return cl;
3204:
3205:                throw createErrorException(L.l(
3206:                        "'{0}' is an unknown class name.", name));
3207:                /*
3208:                // return _quercus.findJavaClassWrapper(name);
3209:
3210:                return null;
3211:                 */
3212:            }
3213:
3214:            /**
3215:             * Finds the class with the given name.
3216:             *
3217:             * @param name the class name
3218:             * @return the found class
3219:             * @throws QuercusRuntimeException if the class is not found
3220:             */
3221:            public QuercusClass getClass(String name) {
3222:                QuercusClass cl = findClass(name);
3223:
3224:                if (cl != null)
3225:                    return cl;
3226:                else
3227:                    throw createErrorException(L.l(
3228:                            "'{0}' is an unknown class.", name));
3229:            }
3230:
3231:            QuercusClass createQuercusClass(ClassDef def, QuercusClass parent) {
3232:                ClassKey key = new ClassKey(def, parent);
3233:
3234:                SoftReference<QuercusClass> qClassRef = _classCache.get(key);
3235:                QuercusClass qClass;
3236:
3237:                if (qClassRef != null) {
3238:                    qClass = qClassRef.get();
3239:
3240:                    if (qClass != null) {
3241:                        return qClass;
3242:                    }
3243:                }
3244:
3245:                qClass = new QuercusClass(getModuleContext(), def, parent);
3246:                qClass.validate(this );
3247:
3248:                _classCache.put(key, new SoftReference<QuercusClass>(qClass));
3249:
3250:                return qClass;
3251:            }
3252:
3253:            /**
3254:             * Returns true if class has already been initialized.
3255:             */
3256:            public boolean isInitializedClass(String name) {
3257:                return _initializedClassSet.contains(name);
3258:            }
3259:
3260:            /**
3261:             * Mark this class as being initialized.
3262:             */
3263:            public void addInitializedClass(String name) {
3264:                _initializedClassSet.add(name);
3265:            }
3266:
3267:            /**
3268:             * Finds the class and method.
3269:             *
3270:             * @param className the class name
3271:             * @param methodName the method name
3272:             * @return the found method or null if no method found.
3273:             */
3274:            public AbstractFunction findFunction(String className,
3275:                    String methodName) {
3276:                QuercusClass cl = findClass(className);
3277:
3278:                if (cl == null)
3279:                    throw new QuercusRuntimeException(L.l(
3280:                            "'{0}' is an unknown class", className));
3281:
3282:                return cl.findFunction(methodName);
3283:            }
3284:
3285:            /**
3286:             * Returns the appropriate callback.
3287:             */
3288:            public Callback createCallback(Value value) {
3289:                if (value == null || value.isNull())
3290:                    return null;
3291:
3292:                value = value.toValue();
3293:
3294:                if (value instanceof  Callback)
3295:                    return (Callback) value;
3296:
3297:                else if (value instanceof  StringValue)
3298:                    return new CallbackFunction(this , value.toString());
3299:
3300:                else if (value instanceof  ArrayValue) {
3301:                    Value obj = value.get(LongValue.ZERO);
3302:                    Value name = value.get(LongValue.ONE);
3303:
3304:                    if (!(name instanceof  StringValue))
3305:                        throw new IllegalStateException(L.l(
3306:                                "unknown callback name {0}", name));
3307:
3308:                    if (obj instanceof  StringValue) {
3309:                        QuercusClass cl = findClass(obj.toString());
3310:
3311:                        if (cl == null)
3312:                            throw new IllegalStateException(L.l(
3313:                                    "can't find class {0}", obj.toString()));
3314:
3315:                        return new CallbackFunction(cl.getFunction(name
3316:                                .toString()));
3317:                    } else {
3318:                        return new CallbackObjectMethod(this , obj, name
3319:                                .toString());
3320:                    }
3321:                } else
3322:                    return null;
3323:            }
3324:
3325:            /**
3326:             * Evaluates an included file.
3327:             */
3328:            public Value requireOnce(String include) {
3329:                return include(getSelfDirectory(), include, true, true);
3330:            }
3331:
3332:            /**
3333:             * Evaluates an included file.
3334:             */
3335:            public Value require(String include) {
3336:                return include(getSelfDirectory(), include, true, false);
3337:            }
3338:
3339:            /**
3340:             * Evaluates an included file.
3341:             */
3342:            public Value include(String include) {
3343:                return include(getSelfDirectory(), include, false, false);
3344:            }
3345:
3346:            /**
3347:             * Evaluates an included file.
3348:             */
3349:            public Value includeOnce(String include) {
3350:                return include(getSelfDirectory(), include, false, true);
3351:            }
3352:
3353:            /**
3354:             * Evaluates an included file.
3355:             */
3356:            public Value includeOnce(Path scriptPwd, String include,
3357:                    boolean isRequire) {
3358:                return include(scriptPwd, include, isRequire, true);
3359:            }
3360:
3361:            /**
3362:             * Evaluates an included file.
3363:             */
3364:            public Value include(Path scriptPwd, String include,
3365:                    boolean isRequire, boolean isOnce) {
3366:                try {
3367:                    Path pwd = getPwd();
3368:
3369:                    Path path = lookupInclude(include, pwd, scriptPwd);
3370:
3371:                    if (path != null) {
3372:                    } else if (isRequire) {
3373:                        error(L.l("'{0}' is not a valid path", include));
3374:                        return NullValue.NULL;
3375:                    } else {
3376:                        warning(L.l("'{0}' is not a valid path", include));
3377:                        return NullValue.NULL;
3378:                    }
3379:
3380:                    // php/0b2d
3381:                    if (!"".equals(path.getScheme())
3382:                            && !"file".equals(path.getScheme())
3383:                            && !"memory".equals(path.getScheme())) {
3384:                        String msg = (L.l("attempt to include {0}", path
3385:                                .getURL()));
3386:
3387:                        log.warning(dbgId() + msg);
3388:                        error(msg);
3389:
3390:                        return NullValue.NULL;
3391:                    }
3392:
3393:                    QuercusPage page = _includeMap.get(path);
3394:
3395:                    if (page == null || page.isModified(this )) {
3396:                        page = _quercus.parse(path);
3397:
3398:                        page.importDefinitions(this );
3399:
3400:                        _includeMap.put(path, page);
3401:                    } else if (isOnce)
3402:                        return NullValue.NULL;
3403:
3404:                    return page.execute(this );
3405:                } catch (IOException e) {
3406:                    throw new QuercusModuleException(e);
3407:                }
3408:            }
3409:
3410:            /**
3411:             * Looks up based on the pwd.
3412:             */
3413:            public Path lookupPwd(Value relPathV) {
3414:                if (!relPathV.isset())
3415:                    return null;
3416:
3417:                StringValue relPath = relPathV.toStringValue();
3418:
3419:                if (relPath.length() == 0)
3420:                    return null;
3421:
3422:                Path path = _lookupCache.get(relPath);
3423:
3424:                if (path == null) {
3425:                    path = getPwd().lookup(relPath.toString());
3426:                    _lookupCache.put(relPath, path);
3427:                }
3428:
3429:                return path;
3430:            }
3431:
3432:            /**
3433:             * Looks up the path.
3434:             */
3435:            public Path lookup(String relPath) {
3436:                return lookupInclude(getSelfDirectory(), relPath);
3437:            }
3438:
3439:            /**
3440:             * Looks up the path.
3441:             */
3442:            public Path lookupInclude(String relPath) {
3443:                return lookupInclude(relPath, getPwd(), getSelfDirectory());
3444:            }
3445:
3446:            private Path lookupInclude(String include, Path pwd, Path scriptPwd) {
3447:                String includePath = getDefaultIncludePath();
3448:
3449:                Path path = _quercus.getIncludeCache(include, includePath, pwd,
3450:                        scriptPwd);
3451:
3452:                if (path == null) {
3453:                    path = lookupIncludeImpl(include, pwd, scriptPwd);
3454:
3455:                    if (path != null)
3456:                        _quercus.putIncludeCache(include, includePath, pwd,
3457:                                scriptPwd, path);
3458:                }
3459:
3460:                _includePath = includePath;
3461:                _includePathIniCount = _iniCount;
3462:
3463:                return path;
3464:            }
3465:
3466:            private String getDefaultIncludePath() {
3467:                String includePath = _includePath;
3468:
3469:                if (_includePathIniCount != _iniCount) {
3470:                    includePath = Quercus.INI_INCLUDE_PATH.getAsString(this );
3471:                    _includePath = null;
3472:                    _includePathList = null;
3473:                }
3474:
3475:                if (includePath == null)
3476:                    includePath = ".";
3477:
3478:                return includePath;
3479:            }
3480:
3481:            private Path lookupIncludeImpl(String include, Path pwd,
3482:                    Path scriptPwd) {
3483:                // php/0b0g
3484:
3485:                Path path = lookupInclude(pwd, include);
3486:
3487:                if (path == null) {
3488:                    // php/0b0l
3489:                    path = lookupInclude(scriptPwd, include);
3490:                }
3491:
3492:                if (path == null) {
3493:                    // php/0b21
3494:                    path = scriptPwd.lookup(include);
3495:
3496:                    if (!path.canRead() || path.isDirectory())
3497:                        path = null;
3498:                }
3499:
3500:                return path;
3501:            }
3502:
3503:            /**
3504:             * Looks up the path.
3505:             */
3506:            private Path lookupInclude(Path pwd, String relPath) {
3507:                ArrayList<Path> pathList = getIncludePath(pwd);
3508:
3509:                for (int i = 0; i < pathList.size(); i++) {
3510:                    Path path = pathList.get(i).lookup(relPath);
3511:
3512:                    if (path.canRead() && !path.isDirectory()) {
3513:                        return path;
3514:                    }
3515:                }
3516:
3517:                return null;
3518:            }
3519:
3520:            /**
3521:             * Returns the include path.
3522:             */
3523:            private ArrayList<Path> getIncludePath(Path pwd) {
3524:                String includePath = getDefaultIncludePath();
3525:
3526:                if (_includePathList == null) {
3527:                    _includePathList = new ArrayList<String>();
3528:                    _includePathMap = new HashMap<Path, ArrayList<Path>>();
3529:
3530:                    int head = 0;
3531:                    int tail;
3532:
3533:                    String pathSeparator = FileModule.PATH_SEPARATOR;
3534:                    int length = pathSeparator.length();
3535:
3536:                    while ((tail = includePath.indexOf(pathSeparator, head)) >= 0) {
3537:                        String subpath = includePath.substring(head, tail);
3538:
3539:                        _includePathList.add(subpath);
3540:
3541:                        head = tail + length;
3542:                    }
3543:
3544:                    String subpath = includePath.substring(head);
3545:
3546:                    _includePathList.add(subpath);
3547:
3548:                    _includePath = includePath;
3549:                    _includePathIniCount = _iniCount;
3550:                }
3551:
3552:                ArrayList<Path> pathList = _includePathMap.get(pwd);
3553:
3554:                if (pathList == null) {
3555:                    pathList = new ArrayList<Path>();
3556:
3557:                    for (int i = 0; i < _includePathList.size(); i++) {
3558:                        pathList.add(pwd.lookup(_includePathList.get(i)));
3559:                    }
3560:
3561:                    _includePathMap.put(pwd, pathList);
3562:                }
3563:
3564:                return pathList;
3565:            }
3566:
3567:            /**
3568:             * Sets the include path.
3569:             */
3570:            public String setIncludePath(String path) {
3571:                String prevIncludePath = Quercus.INI_INCLUDE_PATH
3572:                        .getAsString(this );
3573:
3574:                if (_defaultIncludePath == null)
3575:                    _defaultIncludePath = prevIncludePath;
3576:
3577:                Quercus.INI_INCLUDE_PATH.set(this , path);
3578:
3579:                // reset include path cache count
3580:                _includePathIniCount = -1;
3581:
3582:                return prevIncludePath;
3583:            }
3584:
3585:            /**
3586:             * Restores the default include path.
3587:             */
3588:            public void restoreIncludePath() {
3589:                Quercus.INI_INCLUDE_PATH.set(this , _defaultIncludePath);
3590:            }
3591:
3592:            /**
3593:             * Returns all the included files.
3594:             */
3595:            public ArrayValue getIncludedFiles() {
3596:                ArrayValue array = new ArrayValueImpl();
3597:
3598:                for (Path path : _includeMap.keySet()) {
3599:                    array.put(createString(path.toString()));
3600:                }
3601:
3602:                return array;
3603:            }
3604:
3605:            /**
3606:             * Handles error suppression.
3607:             */
3608:            public Value suppress(int errorMask, Value value) {
3609:                setErrorMask(errorMask);
3610:
3611:                return value;
3612:            }
3613:
3614:            /**
3615:             * Handles exit/die
3616:             */
3617:            public Value exit(Value msg) {
3618:                if (msg.isNull() || msg instanceof  LongValue)
3619:                    return exit();
3620:
3621:                try {
3622:                    getOut().print(msg.toString());
3623:                } catch (IOException e) {
3624:                    log.log(Level.WARNING, e.toString(), e);
3625:                }
3626:
3627:                throw new QuercusExitException(msg.toString());
3628:            }
3629:
3630:            /**
3631:             * Handles exit/die
3632:             */
3633:            public Value exit() {
3634:                throw new QuercusExitException();
3635:            }
3636:
3637:            /**
3638:             * Handles exit/die
3639:             */
3640:            public Value die(String msg) {
3641:                try {
3642:                    getOut().print(msg);
3643:                } catch (IOException e) {
3644:                    log.log(Level.WARNING, e.toString(), e);
3645:                }
3646:
3647:                throw new QuercusDieException(msg);
3648:            }
3649:
3650:            /**
3651:             * Handles exit/die
3652:             */
3653:            public Value die() {
3654:                throw new QuercusDieException();
3655:            }
3656:
3657:            /**
3658:             * Handles exit/die
3659:             */
3660:            public Value cast(Class cl, Value value) {
3661:                value = value.toValue();
3662:
3663:                if (value.isNull())
3664:                    return null;
3665:                else if (cl.isAssignableFrom(value.getClass()))
3666:                    return value;
3667:                else {
3668:                    error(L.l("{0} ({1}) is not assignable to {2}", value,
3669:                            value.getClass().getName(), cl.getName()));
3670:
3671:                    return value;
3672:                }
3673:            }
3674:
3675:            /**
3676:             * Returns the first value
3677:             */
3678:            public static Value first(Value value) {
3679:                return value;
3680:            }
3681:
3682:            /**
3683:             * Returns the first value
3684:             */
3685:            public static Value first(Value value, Value a1) {
3686:                return value;
3687:            }
3688:
3689:            /**
3690:             * Returns the first value
3691:             */
3692:            public static Value first(Value value, Value a1, Value a2) {
3693:                return value;
3694:            }
3695:
3696:            /**
3697:             * Returns the first value
3698:             */
3699:            public static Value first(Value value, Value a1, Value a2, Value a3) {
3700:                return value;
3701:            }
3702:
3703:            /**
3704:             * Returns the first value
3705:             */
3706:            public static Value first(Value value, Value a1, Value a2,
3707:                    Value a3, Value a4) {
3708:                return value;
3709:            }
3710:
3711:            /**
3712:             * Returns the first value
3713:             */
3714:            public static Value first(Value value, Value a1, Value a2,
3715:                    Value a3, Value a4, Value a5) {
3716:                return value;
3717:            }
3718:
3719:            /**
3720:             * A fatal runtime error.
3721:             */
3722:            public Value error(String msg) {
3723:                return error(B_ERROR, "", msg + getFunctionLocation());
3724:            }
3725:
3726:            /**
3727:             * A fatal runtime error.
3728:             */
3729:            public Value error(Location location, String msg) {
3730:                return error(B_ERROR, location, msg + getFunctionLocation());
3731:            }
3732:
3733:            /**
3734:             * A fatal runtime error.
3735:             */
3736:            public Value error(String loc, String msg) {
3737:                return error(B_ERROR, loc, msg + getFunctionLocation());
3738:            }
3739:
3740:            /**
3741:             * A warning with an exception.
3742:             */
3743:            public Value error(String msg, Throwable e) {
3744:                log.log(Level.WARNING, e.toString(), e);
3745:
3746:                return error(msg);
3747:            }
3748:
3749:            /**
3750:             * A warning with an exception.
3751:             */
3752:            public Value error(Throwable e) {
3753:                log.log(Level.WARNING, e.toString(), e);
3754:
3755:                return error(e.toString());
3756:            }
3757:
3758:            /**
3759:             * A fatal runtime error.
3760:             */
3761:            public QuercusRuntimeException createErrorException(String msg)
3762:                    throws QuercusRuntimeException {
3763:                return createErrorException(null, msg);
3764:            }
3765:
3766:            /**
3767:             * A fatal runtime error.
3768:             */
3769:            public QuercusRuntimeException createErrorException(
3770:                    Location location, String msg)
3771:                    throws QuercusRuntimeException {
3772:                if (location == null)
3773:                    location = getLocation();
3774:
3775:                String prefix = location.getMessagePrefix();
3776:
3777:                String fullMsg = msg + getFunctionLocation();
3778:
3779:                error(B_ERROR, location, fullMsg);
3780:
3781:                String exMsg = prefix + fullMsg;
3782:
3783:                return new QuercusRuntimeException(fullMsg);
3784:            }
3785:
3786:            /**
3787:             * A runtime warning.
3788:             */
3789:            public Value warning(String msg) {
3790:                if (log.isLoggable(Level.FINER)) {
3791:                    QuercusException e = new QuercusException(msg);
3792:
3793:                    log.log(Level.FINER, e.toString(), e);
3794:                }
3795:
3796:                return error(B_WARNING, "", msg + getFunctionLocation());
3797:            }
3798:
3799:            /**
3800:             * A runtime warning.
3801:             */
3802:            public Value warning(Location location, String msg) {
3803:                if (log.isLoggable(Level.FINER)) {
3804:                    QuercusException e = new QuercusException(msg);
3805:
3806:                    log.log(Level.FINER, e.toString(), e);
3807:                }
3808:
3809:                return error(B_WARNING, location, "", msg
3810:                        + getFunctionLocation());
3811:            }
3812:
3813:            /**
3814:             * A warning with an exception.
3815:             */
3816:            public Value warning(String msg, Throwable e) {
3817:                log.log(Level.FINE, e.toString(), e);
3818:
3819:                return warning(msg);
3820:            }
3821:
3822:            /**
3823:             * A warning with an exception.
3824:             */
3825:            public Value warning(Location location, String msg, Throwable e) {
3826:                log.log(Level.FINE, e.toString(), e);
3827:
3828:                return warning(location, msg);
3829:            }
3830:
3831:            /**
3832:             * A warning with an exception.
3833:             */
3834:            public Value warning(Throwable e) {
3835:                return warning(e.toString(), e);
3836:            }
3837:
3838:            /**
3839:             * A warning with an exception.
3840:             */
3841:            public Value warning(Location location, Throwable e) {
3842:                return warning(location, e.toString(), e);
3843:            }
3844:
3845:            /**
3846:             * A runtime strict warning.
3847:             */
3848:            public Value strict(String msg) {
3849:                if (log.isLoggable(Level.FINER)) {
3850:                    QuercusException e = new QuercusException(msg);
3851:
3852:                    log.log(Level.FINER, e.toString(), e);
3853:                }
3854:
3855:                return error(B_STRICT, "", msg + getFunctionLocation());
3856:            }
3857:
3858:            /**
3859:             * A warning about an invalid argument passed to a function.
3860:             */
3861:            public Value invalidArgument(String name, Object value) {
3862:                return warning(L
3863:                        .l("invalid value `{0}' for `{1}'", value, name));
3864:            }
3865:
3866:            /**
3867:             * A warning about an deprecated argument passed to a function.
3868:             */
3869:            public Value deprecatedArgument(String name) {
3870:                return strict(L.l("argument `{1}' is deprecated", name));
3871:            }
3872:
3873:            /**
3874:             * A notice.
3875:             */
3876:            public Value notice(String msg) {
3877:                return error(B_NOTICE, "", msg + getFunctionLocation());
3878:            }
3879:
3880:            /**
3881:             * A notice with an exception.
3882:             */
3883:            public Value notice(String msg, Throwable e) {
3884:                log.log(Level.FINE, e.toString(), e);
3885:
3886:                return notice(msg);
3887:            }
3888:
3889:            /**
3890:             * A stub notice.
3891:             */
3892:            public Value stub(String msg) {
3893:                if (log.isLoggable(Level.FINE))
3894:                    log.fine(getLocation().getMessagePrefix() + msg);
3895:
3896:                return NullValue.NULL;
3897:            }
3898:
3899:            public static Value nullAsFalse(Value value) {
3900:                return value == null || value.isNull() ? BooleanValue.FALSE
3901:                        : value;
3902:            }
3903:
3904:            /**
3905:             * A parse error
3906:             */
3907:            public Value parse(String msg) throws Exception {
3908:                return error(B_PARSE, "", msg);
3909:            }
3910:
3911:            /**
3912:             * A parse error
3913:             */
3914:            public Value compileError(String msg) {
3915:                return error(B_COMPILE_ERROR, "", msg);
3916:            }
3917:
3918:            /**
3919:             * A parse warning
3920:             */
3921:            public Value compileWarning(String msg) {
3922:                return error(B_COMPILE_WARNING, "", msg);
3923:            }
3924:
3925:            /**
3926:             * Returns the error mask.
3927:             */
3928:            public int getErrorMask() {
3929:                return _errorMask;
3930:            }
3931:
3932:            /**
3933:             * Sets the error mask.
3934:             */
3935:            public int setErrorMask(int mask) {
3936:                int oldMask = _errorMask;
3937:
3938:                _errorMask = mask;
3939:
3940:                return oldMask;
3941:            }
3942:
3943:            /**
3944:             * Sets an error handler
3945:             */
3946:            public void setErrorHandler(int mask, Callback fun) {
3947:                for (int i = 0; i < _errorHandlers.length; i++)
3948:                    _prevErrorHandlers[i] = _errorHandlers[i];
3949:
3950:                if ((mask & E_ERROR) != 0)
3951:                    _errorHandlers[B_ERROR] = fun;
3952:
3953:                if ((mask & E_WARNING) != 0)
3954:                    _errorHandlers[B_WARNING] = fun;
3955:
3956:                if ((mask & E_PARSE) != 0)
3957:                    _errorHandlers[B_PARSE] = fun;
3958:
3959:                if ((mask & E_NOTICE) != 0)
3960:                    _errorHandlers[B_NOTICE] = fun;
3961:
3962:                if ((mask & E_USER_ERROR) != 0)
3963:                    _errorHandlers[B_USER_ERROR] = fun;
3964:
3965:                if ((mask & E_USER_WARNING) != 0)
3966:                    _errorHandlers[B_USER_WARNING] = fun;
3967:
3968:                if ((mask & E_USER_NOTICE) != 0)
3969:                    _errorHandlers[B_USER_NOTICE] = fun;
3970:
3971:                if ((mask & E_STRICT) != 0)
3972:                    _errorHandlers[B_STRICT] = fun;
3973:            }
3974:
3975:            /**
3976:             * Sets an error handler
3977:             */
3978:            public void restoreErrorHandler() {
3979:                for (int i = 0; i < _errorHandlers.length; i++)
3980:                    _errorHandlers[i] = _prevErrorHandlers[i];
3981:            }
3982:
3983:            /**
3984:             * Gets the exception handler
3985:             */
3986:            public Callback getExceptionHandler() {
3987:                return _exceptionHandler;
3988:            }
3989:
3990:            /**
3991:             * Sets an exception handler
3992:             */
3993:            public Value setExceptionHandler(Callback fun) {
3994:                _prevExceptionHandler = _exceptionHandler;
3995:
3996:                _exceptionHandler = fun;
3997:
3998:                if (_prevExceptionHandler != null)
3999:                    return _prevExceptionHandler.toStringValue();
4000:                else
4001:                    return NullValue.NULL;
4002:            }
4003:
4004:            /**
4005:             * Restore an exception handler
4006:             */
4007:            public void restoreExceptionHandler() {
4008:                _exceptionHandler = _prevExceptionHandler;
4009:            }
4010:
4011:            /*
4012:             * Writes an error.
4013:             */
4014:            public Value error(int code, String locString, String msg) {
4015:                return error(code, null, locString, msg);
4016:            }
4017:
4018:            /*
4019:             * Writes an error.
4020:             */
4021:            public Value error(int code, Location location, String msg) {
4022:                return error(code, location, "", msg);
4023:            }
4024:
4025:            /**
4026:             * Writes an error.
4027:             */
4028:            public Value error(int code, Location location, String loc,
4029:                    String msg) {
4030:                int mask = 1 << code;
4031:
4032:                if (location == null)
4033:                    location = getLocation();
4034:
4035:                String locationMessagePrefix = loc;
4036:
4037:                if (loc.equals(""))
4038:                    locationMessagePrefix = location.getMessagePrefix();
4039:
4040:                if (code >= 0 && code < _errorHandlers.length
4041:                        && _errorHandlers[code] != null) {
4042:                    Callback handler = _errorHandlers[code];
4043:
4044:                    try {
4045:                        _errorHandlers[code] = null;
4046:
4047:                        Value fileNameV = NullValue.NULL;
4048:
4049:                        String fileName = location.getFileName();
4050:
4051:                        if (fileName != null)
4052:                            fileNameV = createString(fileName);
4053:
4054:                        Value lineV = NullValue.NULL;
4055:                        int line = location.getLineNumber();
4056:                        if (line > 0)
4057:                            lineV = new LongValue(line);
4058:
4059:                        Value context = NullValue.NULL;
4060:
4061:                        handler.call(this , new LongValue(mask),
4062:                                createString(msg), fileNameV, lineV, context);
4063:
4064:                        return NullValue.NULL;
4065:                    } catch (RuntimeException e) {
4066:                        throw e;
4067:                    } catch (Throwable e) {
4068:                        throw new RuntimeException(e);
4069:                    } finally {
4070:                        _errorHandlers[code] = handler;
4071:                    }
4072:                }
4073:
4074:                if ((_errorMask & mask) != 0) {
4075:                    try {
4076:                        String fullMsg = locationMessagePrefix
4077:                                + getCodeName(mask) + msg;
4078:
4079:                        if (getIniBoolean("track_errors"))
4080:                            setGlobalValue("php_errormsg",
4081:                                    createString(fullMsg));
4082:
4083:                        if (getIniBoolean("display_errors"))
4084:                            getOut().println(fullMsg);
4085:
4086:                        if (getIniBoolean("log_errors"))
4087:                            log.info(fullMsg);
4088:                    } catch (IOException e) {
4089:                        log.log(Level.FINE, e.toString(), e);
4090:                    }
4091:                }
4092:
4093:                if ((mask & (E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR)) != 0) {
4094:                    if (!"".equals(locationMessagePrefix)) {
4095:                        /*
4096:                            throw new QuercusLineExitException(getLocation() +
4097:                                                                  getCodeName(mask) +
4098:                                                                  msg);
4099:                         */
4100:                        throw new QuercusErrorException(locationMessagePrefix
4101:                                + getCodeName(mask) + msg);
4102:                    } else
4103:                        throw new QuercusErrorException(msg);
4104:                }
4105:
4106:                return NullValue.NULL;
4107:            }
4108:
4109:            /**
4110:             * Returns the error code name.
4111:             */
4112:            private String getCodeName(int code) {
4113:                switch (code) {
4114:                case E_ERROR:
4115:                    return "Fatal Error: ";
4116:                case E_WARNING:
4117:                    return "Warning: ";
4118:                case E_PARSE:
4119:                    return "Parse Error: ";
4120:                case E_NOTICE:
4121:                    return "Notice: ";
4122:                case E_CORE_ERROR:
4123:                    return "Fatal Error: ";
4124:                case E_CORE_WARNING:
4125:                    return "Warning: ";
4126:                case E_COMPILE_ERROR:
4127:                    return "Fatal Error: ";
4128:                case E_COMPILE_WARNING:
4129:                    return "Warning : ";
4130:                case E_USER_ERROR:
4131:                    return "Fatal Error: ";
4132:                case E_USER_WARNING:
4133:                    return "Warning: ";
4134:                case E_USER_NOTICE:
4135:                    return "Notice: ";
4136:                case E_STRICT:
4137:                    return "Notice: ";
4138:
4139:                default:
4140:                    return String.valueOf("ErrorCode(" + code + ")");
4141:                }
4142:            }
4143:
4144:            /**
4145:             * Returns the source of an error line.
4146:             */
4147:            public static String[] getSourceLine(Path path, int sourceLine,
4148:                    int length) {
4149:                if (path == null)
4150:                    return null;
4151:                else if (path instanceof  NullPath) {
4152:                    // for QuercusScriptEngine.eval() where only a Reader is passed in
4153:                    // XXX: not too pretty
4154:                    return null;
4155:                }
4156:
4157:                ReadStream is = null;
4158:
4159:                try {
4160:                    is = path.openRead();
4161:                    int ch;
4162:                    boolean hasCr = false;
4163:                    int line = 1;
4164:
4165:                    while (line < sourceLine) {
4166:                        ch = is.read();
4167:
4168:                        if (ch < 0)
4169:                            return null;
4170:                        else if (ch == '\r') {
4171:                            hasCr = true;
4172:                            line++;
4173:                        } else if (ch == '\n') {
4174:                            if (!hasCr)
4175:                                line++;
4176:                            hasCr = false;
4177:                        } else
4178:                            hasCr = false;
4179:                    }
4180:
4181:                    String[] result = new String[length];
4182:
4183:                    int i = 0;
4184:                    StringBuilder sb = new StringBuilder();
4185:                    while (i < length && (ch = is.read()) > 0) {
4186:                        if (ch == '\n' && hasCr) {
4187:                            hasCr = false;
4188:                            continue;
4189:                        } else if (ch == '\r') {
4190:                            hasCr = true;
4191:                            result[i++] = sb.toString();
4192:                            sb.setLength(0);
4193:                        } else if (ch == '\n') {
4194:                            hasCr = false;
4195:                            result[i++] = sb.toString();
4196:                            sb.setLength(0);
4197:                        } else {
4198:                            hasCr = false;
4199:                            sb.append((char) ch);
4200:                        }
4201:                    }
4202:
4203:                    if (i < length)
4204:                        result[i] = sb.toString();
4205:
4206:                    return result;
4207:                } catch (IOException e) {
4208:                    log.log(Level.FINE, e.toString(), e);
4209:                } finally {
4210:                    if (is != null)
4211:                        is.close();
4212:                }
4213:
4214:                return null;
4215:            }
4216:
4217:            /**
4218:             * Returns the current execution location.
4219:             *
4220:             * Use with care, for compiled code this can be a relatively expensive
4221:             * operation.
4222:             */
4223:            public Location getLocation() {
4224:                Expr call = peekCall(0);
4225:
4226:                if (call != null)
4227:                    return call.getLocation();
4228:
4229:                return Location.UNKNOWN;
4230:            }
4231:
4232:            public int getSourceLine(String className, int javaLine) {
4233:                return javaLine;
4234:            }
4235:
4236:            /**
4237:             * Returns the current function.
4238:             */
4239:            public String getFunctionLocation() {
4240:                // XXX: need to work with compiled code, too
4241:                Expr call = peekCall(0);
4242:
4243:                if (call != null)
4244:                    return call.getFunctionLocation();
4245:                else
4246:                    return "";
4247:            }
4248:
4249:            /**
4250:             * Converts a boolean to the boolean value
4251:             */
4252:            public static Value toValue(boolean value) {
4253:                return value ? BooleanValue.TRUE : BooleanValue.FALSE;
4254:            }
4255:
4256:            /**
4257:             * Converts a boolean to the boolean value
4258:             */
4259:            public static Value toValue(long value) {
4260:                return new LongValue(value);
4261:            }
4262:
4263:            /**
4264:             * Converts to a variable
4265:             */
4266:            public static Var toVar(Value value) {
4267:                if (value instanceof  Var)
4268:                    return (Var) value;
4269:                else if (value == null)
4270:                    return new Var();
4271:                else
4272:                    return new Var(value);
4273:            }
4274:
4275:            /**
4276:             * Sets a vield variable
4277:             */
4278:            public static Value setFieldVar(Value oldValue, Value value) {
4279:                if (value instanceof  Var)
4280:                    return value;
4281:                else if (oldValue instanceof  Var)
4282:                    return new Var(value);
4283:                else
4284:                    return value;
4285:            }
4286:
4287:            /**
4288:             * Sets a reference
4289:             */
4290:            public static Value setRef(Value oldValue, Value value) {
4291:                // php/3243
4292:                if (value instanceof  Var)
4293:                    return value;
4294:                /*
4295:                else if (oldValue instanceof Var) {
4296:                  oldValue.set(value);
4297:
4298:                  return oldValue;
4299:                }
4300:                 */
4301:                else
4302:                    return new Var(value);
4303:            }
4304:
4305:            /**
4306:             * Returns the last value.
4307:             */
4308:            public static Value comma(Value a0, Value a1) {
4309:                return a1;
4310:            }
4311:
4312:            /**
4313:             * Returns the last value.
4314:             */
4315:            public static Value comma(Value a0, Value a1, Value a2) {
4316:                return a2;
4317:            }
4318:
4319:            /**
4320:             * Returns the last value.
4321:             */
4322:            public static Value comma(Value a0, Value a1, Value a2, Value a3) {
4323:                return a3;
4324:            }
4325:
4326:            /**
4327:             * Returns the last value.
4328:             */
4329:            public static Value comma(Value a0, Value a1, Value a2, Value a3,
4330:                    Value a4) {
4331:                return a4;
4332:            }
4333:
4334:            public String toString() {
4335:                return "Env[]";
4336:            }
4337:
4338:            /**
4339:             * Returns ifNull if condition.isNull(), otherwise returns ifNotNull.
4340:             */
4341:            public Value ifNull(Value condition, Value ifNull, Value ifNotNull) {
4342:                return condition.isNull() ? ifNull : ifNotNull;
4343:            }
4344:
4345:            /**
4346:             * Returns the locale info.
4347:             */
4348:            public LocaleInfo getLocaleInfo() {
4349:                if (_locale == null)
4350:                    _locale = new LocaleInfo();
4351:
4352:                return _locale;
4353:            }
4354:
4355:            /**
4356:             * Registers a shutdown function.
4357:             */
4358:            public void addShutdown(Callback callback, Value[] args) {
4359:                _shutdownList.add(new Shutdown(callback, args));
4360:            }
4361:
4362:            // XXX: hack until can clean up
4363:            public void setGzStream(Object obj) {
4364:                _gzStream = obj;
4365:            }
4366:
4367:            // XXX: hack until can clean up
4368:            public Object getGzStream() {
4369:                return _gzStream;
4370:            }
4371:
4372:            /**
4373:             * Called when the Env is no longer needed.
4374:             */
4375:            public void close() {
4376:                try {
4377:                    // php/1l0t
4378:                    // output buffers callbacks may throw an exception
4379:                    while (_outputBuffer != null) {
4380:                        popOutputBuffer();
4381:                    }
4382:
4383:                    _freeFunList.free(_fun);
4384:                }
4385:                //catch (Exception e) {
4386:                //throw new RuntimeException(e);
4387:                //}
4388:                finally {
4389:                    try {
4390:                        for (int i = 0; i < _shutdownList.size(); i++)
4391:                            _shutdownList.get(i).call(this );
4392:                    } catch (Throwable e) {
4393:                        log.log(Level.FINE, e.toString(), e);
4394:                    }
4395:
4396:                    try {
4397:                        sessionWriteClose();
4398:                    } catch (Throwable e) {
4399:                        log.log(Level.FINE, e.toString(), e);
4400:                    }
4401:
4402:                    ArrayList<SoftReference<EnvCleanup>> cleanupList = _cleanupList;
4403:                    _cleanupList = new ArrayList<SoftReference<EnvCleanup>>(
4404:                            _cleanupList);
4405:
4406:                    for (SoftReference<EnvCleanup> ref : cleanupList) {
4407:                        try {
4408:                            EnvCleanup envCleanup = ref.get();
4409:
4410:                            if (envCleanup != null)
4411:                                envCleanup.cleanup();
4412:                        } catch (Throwable e) {
4413:                            log.log(Level.FINER, e.toString(), e);
4414:                        }
4415:                    }
4416:
4417:                    _threadEnv.set(_oldThreadEnv);
4418:
4419:                    for (int i = 0; _removePaths != null
4420:                            && i < _removePaths.size(); i++) {
4421:                        Path path = _removePaths.get(i);
4422:
4423:                        try {
4424:                            path.remove();
4425:                        } catch (IOException e) {
4426:                            log.log(Level.FINER, e.toString(), e);
4427:                        }
4428:                    }
4429:                }
4430:            }
4431:
4432:            public void sessionWriteClose() {
4433:                SessionArrayValue session = _session;
4434:
4435:                _session = null;
4436:
4437:                if (session != null) {
4438:                    SessionCallback callback = getSessionCallback();
4439:
4440:                    if (callback != null) {
4441:                        String value;
4442:
4443:                        // php/1k6e
4444:                        if (session.getSize() > 0)
4445:                            value = VariableModule
4446:                                    .serialize(session.getArray());
4447:                        else
4448:                            value = "";
4449:
4450:                        callback.write(this , session.getId(), value);
4451:
4452:                        callback.close(this );
4453:                    } else {
4454:                        _quercus.saveSession(this , session);
4455:
4456:                        setGlobalValue("_SESSION", session.copy(this ));
4457:                        setGlobalValue("HTTP_SESSION_VARS", session.copy(this ));
4458:                    }
4459:                }
4460:            }
4461:
4462:            public String dbgId() {
4463:                return "Quercus[" + _selfPath + "] ";
4464:            }
4465:
4466:            static class ClassKey {
4467:                private final WeakReference<ClassDef> _defRef;
4468:                private final WeakReference<QuercusClass> _parentRef;
4469:
4470:                private final int _hash;
4471:
4472:                ClassKey(ClassDef def, QuercusClass parent) {
4473:                    _defRef = new WeakReference<ClassDef>(def);
4474:
4475:                    if (parent != null)
4476:                        _parentRef = new WeakReference<QuercusClass>(parent);
4477:                    else
4478:                        _parentRef = null;
4479:
4480:                    // hash needs to be precalculated so losing a weak references won't
4481:                    // change the result
4482:
4483:                    int hash = 37;
4484:
4485:                    if (def != null)
4486:                        hash = 65521 * hash + def.hashCode();
4487:
4488:                    if (parent != null)
4489:                        hash = 65521 * hash + parent.hashCode();
4490:
4491:                    _hash = hash;
4492:                }
4493:
4494:                public int hashCode() {
4495:                    return _hash;
4496:                }
4497:
4498:                public boolean equals(Object o) {
4499:                    ClassKey key = (ClassKey) o;
4500:
4501:                    ClassDef aDef = _defRef.get();
4502:                    ClassDef bDef = key._defRef.get();
4503:
4504:                    if (aDef != bDef)
4505:                        return false;
4506:
4507:                    if (_parentRef == key._parentRef)
4508:                        return true;
4509:
4510:                    else if (_parentRef != null && key._parentRef != null)
4511:                        return _parentRef.get() == key._parentRef.get();
4512:
4513:                    else
4514:                        return false;
4515:                }
4516:            }
4517:
4518:            static class ConnectionEntry {
4519:                private DataSource _ds;
4520:                private String _user;
4521:                private String _password;
4522:                private Connection _conn;
4523:
4524:                public void init(DataSource ds, String user, String password) {
4525:                    _ds = ds;
4526:                    _user = user;
4527:                    _password = password;
4528:                }
4529:
4530:                public void setConnection(Connection conn) {
4531:                    _conn = conn;
4532:                }
4533:
4534:                public Connection getConnection() {
4535:                    return _conn;
4536:                }
4537:
4538:                public int hashCode() {
4539:                    int hash = _ds.hashCode();
4540:
4541:                    if (_user == null)
4542:                        return hash;
4543:                    else
4544:                        return 65521 * hash + _user.hashCode();
4545:                }
4546:
4547:                public boolean equals(Object o) {
4548:                    if (!(o instanceof  ConnectionEntry))
4549:                        return false;
4550:
4551:                    ConnectionEntry entry = (ConnectionEntry) o;
4552:
4553:                    if (_ds != entry._ds)
4554:                        return false;
4555:                    else if (_user == null)
4556:                        return entry._user == null;
4557:                    else
4558:                        return _user.equals(entry._user);
4559:                }
4560:
4561:                public String toString() {
4562:                    return getClass().getSimpleName() + "[ds=" + _ds
4563:                            + ", user=" + _user + "]";
4564:                }
4565:            }
4566:
4567:            static {
4568:                SPECIAL_VARS.put("GLOBALS", _GLOBAL);
4569:                SPECIAL_VARS.put("_SERVER", _SERVER);
4570:                SPECIAL_VARS.put("_GET", _GET);
4571:                SPECIAL_VARS.put("_POST", _POST);
4572:                SPECIAL_VARS.put("_FILES", _FILES);
4573:                SPECIAL_VARS.put("_REQUEST", _REQUEST);
4574:                SPECIAL_VARS.put("_COOKIE", _COOKIE);
4575:                SPECIAL_VARS.put("_SESSION", _SESSION);
4576:                SPECIAL_VARS.put("_ENV", _ENV);
4577:                SPECIAL_VARS.put("HTTP_GET_VARS", HTTP_GET_VARS);
4578:                SPECIAL_VARS.put("HTTP_POST_VARS", HTTP_POST_VARS);
4579:                SPECIAL_VARS.put("HTTP_POST_FILES", HTTP_POST_FILES);
4580:                SPECIAL_VARS.put("HTTP_COOKIE_VARS", HTTP_COOKIE_VARS);
4581:                SPECIAL_VARS.put("HTTP_SERVER_VARS", HTTP_SERVER_VARS);
4582:                SPECIAL_VARS.put("PHP_SELF", PHP_SELF);
4583:            }
4584:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.