KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > quercus > Quercus


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

29
30 package com.caucho.quercus;
31
32 import com.caucho.config.ConfigException;
33 import com.caucho.quercus.annotation.ClassImplementation;
34 import com.caucho.quercus.env.*;
35 import com.caucho.quercus.lib.file.FileModule;
36 import com.caucho.quercus.lib.session.QuercusSessionManager;
37 import com.caucho.quercus.module.ModuleContext;
38 import com.caucho.quercus.module.ModuleInfo;
39 import com.caucho.quercus.module.ModuleStartupListener;
40 import com.caucho.quercus.module.QuercusModule;
41 import com.caucho.quercus.module.StaticFunction;
42 import com.caucho.quercus.page.InterpretedPage;
43 import com.caucho.quercus.page.PageManager;
44 import com.caucho.quercus.page.QuercusPage;
45 import com.caucho.quercus.parser.QuercusParser;
46 import com.caucho.quercus.program.ClassDef;
47 import com.caucho.quercus.program.InterpretedClassDef;
48 import com.caucho.quercus.program.JavaClassDef;
49 import com.caucho.quercus.program.JavaImplClassDef;
50 import com.caucho.quercus.program.QuercusProgram;
51 import com.caucho.util.Alarm;
52 import com.caucho.util.L10N;
53 import com.caucho.util.Log;
54 import com.caucho.util.LruCache;
55 import com.caucho.util.TimedCache;
56 import com.caucho.vfs.*;
57
58 import javax.sql.DataSource JavaDoc;
59 import java.io.IOException JavaDoc;
60 import java.io.InputStream JavaDoc;
61 import java.lang.ref.SoftReference JavaDoc;
62 import java.lang.reflect.Constructor JavaDoc;
63 import java.lang.reflect.InvocationTargetException JavaDoc;
64 import java.sql.*;
65 import java.net.URL JavaDoc;
66 import java.util.Enumeration JavaDoc;
67 import java.util.HashMap JavaDoc;
68 import java.util.HashSet JavaDoc;
69 import java.util.Map JavaDoc;
70 import java.util.logging.Level JavaDoc;
71 import java.util.logging.Logger JavaDoc;
72
73 /**
74  * Facade for the PHP language.
75  */

76 public class Quercus
77 {
78   private static L10N L = new L10N(Quercus.class);
79   private static final Logger JavaDoc log = Log.open(Quercus.class);
80
81   private static HashSet JavaDoc<String JavaDoc> _superGlobals
82     = new HashSet JavaDoc<String JavaDoc>();
83
84   private final PageManager _pageManager;
85   private final QuercusSessionManager _sessionManager;
86
87   private final ClassLoader JavaDoc _loader;
88   
89   private ModuleContext _moduleContext;
90
91   private HashMap JavaDoc<String JavaDoc, InternStringValue> _internMap
92     = new HashMap JavaDoc<String JavaDoc, InternStringValue>();
93
94   private HashMap JavaDoc<String JavaDoc, QuercusModule> _modules
95     = new HashMap JavaDoc<String JavaDoc, QuercusModule>();
96
97   private HashSet JavaDoc<ModuleStartupListener> _moduleStartupListeners
98     = new HashSet JavaDoc<ModuleStartupListener>();
99
100   private HashSet JavaDoc<String JavaDoc> _extensionSet
101     = new HashSet JavaDoc<String JavaDoc>();
102
103   private HashMap JavaDoc<String JavaDoc, Value> _constMap
104     = new HashMap JavaDoc<String JavaDoc, Value>();
105
106   private HashMap JavaDoc<String JavaDoc, StaticFunction> _funMap
107     = new HashMap JavaDoc<String JavaDoc, StaticFunction>();
108
109   private HashMap JavaDoc<String JavaDoc, StaticFunction> _lowerFunMap
110     = new HashMap JavaDoc<String JavaDoc, StaticFunction>();
111
112   private ClassDef _stdClassDef;
113   private QuercusClass _stdClass;
114
115   private HashMap JavaDoc<String JavaDoc, ClassDef> _staticClasses
116     = new HashMap JavaDoc<String JavaDoc, ClassDef>();
117
118   private HashMap JavaDoc<String JavaDoc, ClassDef> _lowerStaticClasses
119     = new HashMap JavaDoc<String JavaDoc, ClassDef>();
120
121   private HashMap JavaDoc<String JavaDoc, JavaClassDef> _javaClassWrappers
122     = new HashMap JavaDoc<String JavaDoc, JavaClassDef>();
123
124   private HashMap JavaDoc<String JavaDoc, JavaClassDef> _lowerJavaClassWrappers
125     = new HashMap JavaDoc<String JavaDoc, JavaClassDef>();
126
127   private HashMap JavaDoc<String JavaDoc, StringValue> _iniMap
128     = new HashMap JavaDoc<String JavaDoc, StringValue>();
129
130   private HashMap JavaDoc<Value, Value> _serverEnvMap
131     = new HashMap JavaDoc<Value, Value>();
132
133   private LruCache<String JavaDoc, QuercusProgram> _evalCache
134     = new LruCache<String JavaDoc, QuercusProgram>(256);
135
136   private TimedCache<IncludeKey, Path> _includeCache
137     = new TimedCache<IncludeKey, Path>(4096, 10000);
138
139   private LruCache<DefinitionKey,SoftReference JavaDoc<DefinitionState>> _defCache
140     = new LruCache<DefinitionKey,SoftReference JavaDoc<DefinitionState>>(4096);
141
142   private long _defCacheHitCount;
143   private long _defCacheMissCount;
144
145   // XXX: needs to be a timed LRU
146
private LruCache<String JavaDoc, SessionArrayValue> _sessionMap
147     = new LruCache<String JavaDoc, SessionArrayValue>(4096);
148
149   private HashMap JavaDoc<String JavaDoc, Object JavaDoc> _specialMap
150     = new HashMap JavaDoc<String JavaDoc, Object JavaDoc>();
151
152   private String JavaDoc _scriptEncoding = "utf-8";
153
154   private boolean _isStrict;
155
156   private DataSource JavaDoc _database;
157
158   private long _staticId;
159
160   private Path _pwd;
161   private Path _workDir;
162
163   /**
164    * Constructor.
165    */

166   public Quercus()
167   {
168     _loader = Thread.currentThread().getContextClassLoader();
169     
170     _moduleContext = getLocalContext();
171     
172     initStaticFunctions();
173     initStaticClasses();
174     initStaticClassServices();
175
176     _pageManager = createPageManager();
177     
178     _sessionManager = createSessionManager();
179
180     _workDir = getWorkDir();
181   }
182   
183   /**
184    * Returns the working directory.
185    */

186   public Path getPwd()
187   {
188     if (_pwd == null)
189       _pwd = new FilePath(System.getProperty("user.dir"));
190     
191     return _pwd;
192   }
193
194   /**
195    * Sets the working directory.
196    */

197   public void setPwd(Path path)
198   {
199     _pwd = path;
200   }
201
202   public Path getWorkDir()
203   {
204     if (_workDir == null)
205       _workDir = getPwd().lookup("WEB-INF/work");
206
207     return _workDir;
208   }
209
210   public void setWorkDir(Path workDir)
211   {
212     _workDir = workDir;
213   }
214
215   public String JavaDoc getCookieName()
216   {
217     return "JSESSIONID";
218   }
219
220   public String JavaDoc getVersion()
221   {
222     return "Resin/3.1.0";
223   }
224
225   public String JavaDoc getVersionDate()
226   {
227     return "20061220T1222";
228   }
229
230   protected PageManager createPageManager()
231   {
232     return new PageManager(this);
233   }
234
235   protected QuercusSessionManager createSessionManager()
236   {
237     return new QuercusSessionManager();
238   }
239   
240   /**
241    * Returns the context for this class loader.
242    */

243   public final ModuleContext getLocalContext()
244   {
245     return getLocalContext(_loader);
246   }
247
248   public ModuleContext getLocalContext(ClassLoader JavaDoc loader)
249   {
250     synchronized (this) {
251       if (_moduleContext == null)
252     _moduleContext = createModuleContext(loader);
253     }
254
255     return _moduleContext;
256   }
257
258   protected ModuleContext createModuleContext(ClassLoader JavaDoc loader)
259   {
260     return new ModuleContext(loader);
261   }
262
263   /**
264    * Returns the module context.
265    */

266   public ModuleContext getModuleContext()
267   {
268     return _moduleContext;
269   }
270
271   public QuercusSessionManager getQuercusSessionManager()
272   {
273     return _sessionManager;
274   }
275
276   /**
277    * Set true if pages should be compiled.
278    */

279   public void setCompile(boolean isCompile)
280   {
281     _pageManager.setCompile(isCompile);
282   }
283
284   /**
285    * Set true if pages should be compiled.
286    */

287   public void setLazyCompile(boolean isCompile)
288   {
289     _pageManager.setLazyCompile(isCompile);
290   }
291
292   public String JavaDoc getScriptEncoding()
293   {
294     return _scriptEncoding;
295   }
296
297   public void setScriptEncoding(String JavaDoc encoding)
298   {
299     _scriptEncoding = encoding;
300   }
301
302   /**
303    * Sets the default data source.
304    */

305   public void setDatabase(DataSource JavaDoc database)
306   {
307     _database = database;
308   }
309
310   /**
311    * Gets the default data source.
312    */

313   public DataSource JavaDoc getDatabase()
314   {
315     return _database;
316   }
317
318   /**
319    * Gets the default data source.
320    */

321   public DataSource JavaDoc findDatabase(String JavaDoc driver, String JavaDoc url)
322   {
323     if (_database != null)
324       return _database;
325     else {
326       throw new QuercusModuleException(L.l("Can't find database for driver '{0}' and url '{1}'",
327                        driver, url));
328     }
329   }
330
331   /**
332    * Unwrap connection if necessary.
333    */

334   public Connection getConnection(Connection conn)
335   {
336     return conn;
337   }
338
339   /**
340    * Unwrap statement if necessary.
341    */

342   public Statement getStatement(Statement stmt)
343   {
344     return stmt;
345   }
346
347   /**
348    * Sets the strict mode.
349    */

350   public void setStrict(boolean isStrict)
351   {
352     _isStrict = isStrict;
353   }
354
355   /**
356    * Gets the strict mode.
357    */

358   public boolean isStrict()
359   {
360     return _isStrict;
361   }
362
363   /**
364    * Adds a module
365    */

366   public void addModule(QuercusModule module)
367     throws ConfigException
368   {
369     try {
370       introspectPhpModuleClass(module.getClass());
371     } catch (Exception JavaDoc e) {
372       throw new ConfigException(e);
373     }
374   }
375
376   /**
377    * Adds a java class
378    */

379   public void addJavaClass(String JavaDoc name, Class JavaDoc type)
380     throws ConfigException
381   {
382     try {
383       if (type.isAnnotationPresent(ClassImplementation.class))
384         introspectJavaImplClass(name, type, null);
385       else
386         introspectJavaClass(name, type, null, null);
387     } catch (Exception JavaDoc e) {
388       throw new ConfigException(e);
389     }
390   }
391
392   /**
393    * Adds a impl class
394    */

395   public void addImplClass(String JavaDoc name, Class JavaDoc type)
396     throws ConfigException
397   {
398     try {
399       introspectJavaImplClass(name, type, null);
400     } catch (Exception JavaDoc e) {
401       throw new ConfigException(e);
402     }
403   }
404
405   /**
406    * Adds a java class
407    */

408   public JavaClassDef getJavaClassDefinition(String JavaDoc className)
409   {
410     JavaClassDef def = _javaClassWrappers.get(className);
411
412     if (def != null)
413       return def;
414
415     try {
416       ClassLoader JavaDoc loader = Thread.currentThread().getContextClassLoader();
417
418       Class JavaDoc type;
419
420       try {
421         type = Class.forName(className, false, loader);
422       }
423       catch (ClassNotFoundException JavaDoc e) {
424         throw new ClassNotFoundException JavaDoc(L.l("'{0}' not valid {1}", className, e.toString()));
425
426       }
427
428       def = JavaClassDef.create(getModuleContext(), className, type);
429
430       _javaClassWrappers.put(className, def);
431
432       // def.introspect(getModuleContext());
433

434       return def;
435     } catch (RuntimeException JavaDoc e) {
436       throw e;
437     } catch (Exception JavaDoc e) {
438       throw new QuercusRuntimeException(e);
439     }
440   }
441
442   /**
443    * Finds the java class wrapper.
444    */

445   public ClassDef findJavaClassWrapper(String JavaDoc name)
446   {
447     ClassDef def = _javaClassWrappers.get(name);
448
449     if (def != null)
450       return def;
451
452     return _lowerJavaClassWrappers.get(name.toLowerCase());
453   }
454
455   /**
456    * Sets an ini file.
457    */

458   public void setIniFile(Path path)
459   {
460     // XXX: Not sure why this dependency would be useful
461
// Environment.addDependency(new Depend(path));
462

463     if (path.canRead()) {
464       Env env = new Env(this);
465
466       Value result = FileModule.parse_ini_file(env, path, false);
467
468       if (result instanceof ArrayValue) {
469         ArrayValue array = (ArrayValue) result;
470
471         for (Map.Entry JavaDoc<Value,Value> entry : array.entrySet()) {
472           setIni(entry.getKey().toString(), entry.getValue().toString());
473         }
474       }
475     }
476   }
477
478   /**
479    * Sets an ini value.
480    */

481   public void setIni(String JavaDoc name, StringValue value)
482   {
483     // XXX: s/b specified some other way
484
if ("magic_quotes_sybase".equals(value.toString())
485         || "magic_quotes_runtime".equals(value.toString())) {
486       if (value.toBoolean())
487         throw new UnsupportedOperationException JavaDoc(name);
488     }
489
490     _iniMap.put(name, value);
491   }
492
493   /**
494    * Sets a server env value.
495    */

496   public void setServerEnv(String JavaDoc name, String JavaDoc value)
497   {
498     setServerEnv(new StringValueImpl(name), new StringValueImpl(value));
499   }
500
501   /**
502    * Sets a server env value.
503    */

504   public void setServerEnv(StringValue name, StringValue value)
505   {
506     _serverEnvMap.put(name, value);
507   }
508
509   /**
510    * Gets a server env value.
511    */

512   public Value getServerEnv(StringValue name)
513   {
514     return _serverEnvMap.get(name);
515   }
516
517   /**
518    * Returns the server env map.
519    */

520   public HashMap JavaDoc<Value,Value> getServerEnvMap()
521   {
522     return _serverEnvMap;
523   }
524
525   /**
526    * Sets an ini value.
527    */

528   public void setIni(String JavaDoc name, String JavaDoc value)
529   {
530     if ("off".equalsIgnoreCase(value))
531       value = "";
532
533     setIni(name, new StringValueImpl(value));
534   }
535
536   /**
537    * Gets an ini value.
538    */

539   public StringValue getIni(String JavaDoc name)
540   {
541     return _iniMap.get(name);
542   }
543
544   /**
545    * Gets all ini values having this prefix.
546    */

547   public HashMap JavaDoc<String JavaDoc,StringValue> getIniAll(String JavaDoc prefix)
548   {
549     if (_iniMap == null)
550       return null;
551
552     HashMap JavaDoc<String JavaDoc, StringValue> iniCopy = new HashMap JavaDoc<String JavaDoc, StringValue>();
553
554     for (Map.Entry JavaDoc<String JavaDoc, StringValue> entry : _iniMap.entrySet()) {
555       String JavaDoc key = entry.getKey();
556       StringValue value = entry.getValue();
557       if (key.startsWith(prefix))
558         iniCopy.put(key, entry.getValue());
559     }
560
561     return iniCopy;
562   }
563
564   /**
565    * Returns the relative path.
566    */

567   /*
568   public String getClassName(Path path)
569   {
570     return _pageManager.getClassName(path);
571   }
572   */

573
574   /**
575    * Returns an include path.
576    */

577   public Path getIncludeCache(String JavaDoc include,
578                               String JavaDoc includePath,
579                               Path pwd,
580                               Path scriptPwd)
581   {
582     IncludeKey key = new IncludeKey(include, includePath, pwd, scriptPwd);
583
584     Path path = _includeCache.get(key);
585
586     return path;
587   }
588
589   /**
590    * Adds an include path.
591    */

592   public void putIncludeCache(String JavaDoc include,
593                               String JavaDoc includePath,
594                               Path pwd,
595                               Path scriptPwd,
596                               Path path)
597   {
598     IncludeKey key = new IncludeKey(include, includePath, pwd, scriptPwd);
599
600     _includeCache.put(key, path);
601   }
602
603   /**
604    * Returns the definition cache hit count.
605    */

606   public long getDefCacheHitCount()
607   {
608     return _defCacheHitCount;
609   }
610
611   /**
612    * Returns the definition cache miss count.
613    */

614   public long getDefCacheMisstCount()
615   {
616     return _defCacheMissCount;
617   }
618
619   /**
620    * Returns the definition state for an include.
621    */

622   public DefinitionState getDefinitionCache(DefinitionKey key)
623   {
624     SoftReference JavaDoc<DefinitionState> defStateRef = _defCache.get(key);
625
626     if (defStateRef != null) {
627       DefinitionState defState = defStateRef.get();
628
629       if (defState != null) {
630         _defCacheHitCount++;
631
632         return defState.copyLazy();
633       }
634     }
635
636     _defCacheMissCount++;
637
638     return null;
639   }
640
641   /**
642    * Returns the definition state for an include.
643    */

644   public void putDefinitionCache(DefinitionKey key,
645                                  DefinitionState defState)
646   {
647     _defCache.put(key, new SoftReference JavaDoc<DefinitionState>(defState.copy()));
648   }
649
650   /**
651    * Parses a quercus program.
652    *
653    * @param path the source file path
654    * @return the parsed program
655    * @throws IOException
656    */

657   public QuercusPage parse(Path path)
658     throws IOException JavaDoc
659   {
660     return _pageManager.parse(path);
661   }
662
663   /**
664    * Parses a quercus program.
665    *
666    * @param path the source file path
667    * @return the parsed program
668    * @throws IOException
669    */

670   public QuercusPage parse(Path path, String JavaDoc fileName, int line)
671     throws IOException JavaDoc
672   {
673     return _pageManager.parse(path, fileName, line);
674   }
675
676   /**
677    * Parses a quercus program.
678    *
679    * @param path the source file path
680    * @return the parsed program
681    * @throws IOException
682    */

683   public QuercusPage parse(ReadStream is)
684     throws IOException JavaDoc
685   {
686     return new InterpretedPage(QuercusParser.parse(this, is));
687   }
688
689   /**
690    * Parses a quercus string.
691    *
692    * @param code the source code
693    * @return the parsed program
694    * @throws IOException
695    */

696   public QuercusProgram parseCode(String JavaDoc code)
697     throws IOException JavaDoc
698   {
699     QuercusProgram program = _evalCache.get(code);
700
701     if (program == null) {
702       program = QuercusParser.parseEval(this, code);
703       _evalCache.put(code, program);
704     }
705
706     return program;
707   }
708
709   /**
710    * Parses a quercus string.
711    *
712    * @param code the source code
713    * @return the parsed program
714    * @throws IOException
715    */

716   public QuercusProgram parseEvalExpr(String JavaDoc code)
717     throws IOException JavaDoc
718   {
719     // XXX: possible conflict with parse eval because of the
720
// return value changes
721
QuercusProgram program = _evalCache.get(code);
722
723     if (program == null) {
724       program = QuercusParser.parseEvalExpr(this, code);
725       _evalCache.put(code, program);
726     }
727
728     return program;
729   }
730
731   /**
732    * Parses a function.
733    *
734    * @param args the arguments
735    * @param code the source code
736    * @return the parsed program
737    * @throws IOException
738    */

739   public Value parseFunction(String JavaDoc args, String JavaDoc code)
740     throws IOException JavaDoc
741   {
742     return QuercusParser.parseFunction(this, args, code);
743   }
744
745   /**
746    * Returns the function with the given name.
747    */

748   public StaticFunction findFunction(String JavaDoc name)
749   {
750     StaticFunction fun = _funMap.get(name);
751
752     if (fun == null)
753       fun = _lowerFunMap.get(name.toLowerCase());
754
755     return fun;
756   }
757
758   /**
759    * Returns the function with the given name.
760    */

761   public StaticFunction findFunctionImpl(String JavaDoc name)
762   {
763     StaticFunction fun = _funMap.get(name);
764
765     return fun;
766   }
767
768   /**
769    * Returns the function with the given name.
770    */

771   public StaticFunction findLowerFunctionImpl(String JavaDoc lowerName)
772   {
773     StaticFunction fun = _lowerFunMap.get(lowerName);
774
775     return fun;
776   }
777
778   /**
779    * Returns an array of the defined functions.
780    */

781   public ArrayValue getDefinedFunctions()
782   {
783     ArrayValue internal = new ArrayValueImpl();
784
785     for (String JavaDoc name : _funMap.keySet()) {
786       internal.put(name);
787     }
788
789     return internal;
790   }
791
792   /**
793    * Returns true if the variable is a superglobal.
794    */

795   public static boolean isSuperGlobal(String JavaDoc name)
796   {
797     return _superGlobals.contains(name);
798   }
799
800   /**
801    * Returns the stdClass definition.
802    */

803   public QuercusClass getStdClass()
804   {
805     return _stdClass;
806   }
807
808   /**
809    * Returns the class with the given name.
810    */

811   public ClassDef findClass(String JavaDoc name)
812   {
813     ClassDef def = _staticClasses.get(name);
814
815     if (def == null)
816       def = _lowerStaticClasses.get(name.toLowerCase());
817
818     return def;
819   }
820
821   /**
822    * Returns the class maps.
823    */

824   public HashMap JavaDoc<String JavaDoc, ClassDef> getClassMap()
825   {
826     return _staticClasses;
827   }
828
829   /**
830    * Returns the module with the given name.
831    */

832   public QuercusModule findModule(String JavaDoc name)
833   {
834     return _modules.get(name);
835   }
836
837   /**
838    * Returns a list of the modules that have some startup code to run.
839    */

840   public HashSet JavaDoc<ModuleStartupListener> getModuleStartupListeners()
841   {
842     return _moduleStartupListeners;
843   }
844
845   /**
846    * Returns true if an extension is loaded.
847    */

848   public boolean isExtensionLoaded(String JavaDoc name)
849   {
850     return _extensionSet.contains(name);
851   }
852
853   /**
854    * Returns true if an extension is loaded.
855    */

856   public HashSet JavaDoc<String JavaDoc> getLoadedExtensions()
857   {
858     return _extensionSet;
859   }
860
861   /**
862    * Returns true if an extension is loaded.
863    */

864   public Value getExtensionFuncs(String JavaDoc name)
865   {
866     ArrayValue value = null;
867
868     for (QuercusModule module : _modules.values()) {
869       String JavaDoc []ext = module.getLoadedExtensions();
870       boolean hasExt = false;
871
872       for (int i = 0; i < ext.length; i++) {
873         if (name.equals(ext[i]))
874           hasExt = true;
875       }
876
877       if (hasExt) {
878         value = new ArrayValueImpl();
879       }
880     }
881
882     if (value != null)
883       return value;
884     else
885       return BooleanValue.FALSE;
886   }
887
888   public HashMap JavaDoc<String JavaDoc, Value> getConstMap()
889   {
890     return _constMap;
891   }
892
893   /**
894    * Interns a string.
895    */

896   public InternStringValue intern(String JavaDoc name)
897   {
898     synchronized (_internMap) {
899       InternStringValue value = _internMap.get(name);
900
901       if (value == null) {
902         name = name.intern();
903
904         value = new InternStringValue(name);
905         _internMap.put(name, value);
906       }
907
908       return value;
909     }
910   }
911
912   /**
913    * Returns a named constant.
914    */

915   public Value getConstant(String JavaDoc name)
916   {
917     return _constMap.get(name);
918   }
919
920   public String JavaDoc createStaticName()
921   {
922     return ("s" + _staticId++).intern();
923   }
924
925   /**
926    * Loads the session from the backing.
927    */

928   public SessionArrayValue loadSession(Env env, String JavaDoc sessionId)
929   {
930     long now = Alarm.getCurrentTime();
931
932     SessionArrayValue session =
933       _sessionManager.getSession(env, sessionId, now);
934
935     if (session == null)
936       session = _sessionManager.createSession(env, sessionId, now);
937
938     return session;
939   }
940
941   /**
942    * Saves the session to the backing.
943    */

944   public void saveSession(Env env, SessionArrayValue session)
945   {
946     _sessionManager.saveSession(env, session);
947   }
948
949   /**
950    * Removes the session from the backing.
951    */

952   public void destroySession(String JavaDoc sessionId)
953   {
954     _sessionManager.removeSession(sessionId);
955   }
956
957   /**
958    * Loads a special value
959    */

960   public Object JavaDoc getSpecial(String JavaDoc key)
961   {
962     return _specialMap.get(key);
963   }
964
965   /**
966    * Saves a special value
967    */

968   public void setSpecial(String JavaDoc key, Object JavaDoc value)
969   {
970     _specialMap.put(key, value);
971   }
972
973   /**
974    * Scans the classpath for META-INF/services/com.caucho.quercus.QuercusModule
975    */

976   private void initStaticFunctions()
977   {
978     Thread JavaDoc thread = Thread.currentThread();
979     ClassLoader JavaDoc loader = thread.getContextClassLoader();
980
981     try {
982       String JavaDoc quercusModule
983         = "META-INF/services/com.caucho.quercus.QuercusModule";
984       Enumeration JavaDoc<URL JavaDoc> urls = loader.getResources(quercusModule);
985
986       while (urls.hasMoreElements()) {
987         URL JavaDoc url = urls.nextElement();
988
989         InputStream JavaDoc is = null;
990         ReadStream rs = null;
991         try {
992           is = url.openStream();
993       
994       rs = new ReadStream(new VfsStream(is, null));
995
996           parseServicesModule(rs);
997         } catch (Throwable JavaDoc e) {
998           log.log(Level.WARNING, e.toString(), e);
999         } finally {
1000          if (rs != null)
1001            rs.close();
1002          if (is != null)
1003            is.close();
1004        }
1005      }
1006
1007    } catch (Exception JavaDoc e) {
1008      log.log(Level.WARNING, e.toString(), e);
1009    }
1010  }
1011
1012  /**
1013   * Parses the services file, looking for PHP services.
1014   */

1015  private void parseServicesModule(ReadStream in)
1016    throws IOException JavaDoc, ClassNotFoundException JavaDoc,
1017           IllegalAccessException JavaDoc, InstantiationException JavaDoc
1018  {
1019    ClassLoader JavaDoc loader = Thread.currentThread().getContextClassLoader();
1020    String JavaDoc line;
1021
1022    while ((line = in.readLine()) != null) {
1023      int p = line.indexOf('#');
1024
1025      if (p >= 0)
1026        line = line.substring(0, p);
1027
1028      line = line.trim();
1029
1030      if (line.length() > 0) {
1031        String JavaDoc className = line;
1032
1033        try {
1034          Class JavaDoc cl;
1035          try {
1036            cl = Class.forName(className, false, loader);
1037          }
1038          catch (ClassNotFoundException JavaDoc e) {
1039            throw new ClassNotFoundException JavaDoc(L.l("`{0}' not valid {1}", className, e.toString()));
1040          }
1041
1042          introspectPhpModuleClass(cl);
1043        } catch (Throwable JavaDoc e) {
1044          log.info("Failed loading " + className + "\n" + e.toString());
1045          log.log(Level.FINE, e.toString(), e);
1046        }
1047      }
1048    }
1049  }
1050
1051  /**
1052   * Introspects the module class for functions.
1053   *
1054   * @param cl the class to introspect.
1055   */

1056  private void introspectPhpModuleClass(Class JavaDoc cl)
1057    throws IllegalAccessException JavaDoc, InstantiationException JavaDoc, ConfigException
1058  {
1059    log.fine("Quercus loading module " + cl.getName());
1060
1061    QuercusModule module = (QuercusModule) cl.newInstance();
1062
1063    ModuleContext context = getLocalContext();
1064
1065    ModuleInfo info = context.addModule(module.getClass().getName(),
1066                    module);
1067
1068    _modules.put(info.getName(), info.getModule());
1069
1070    if (info.getModule() instanceof ModuleStartupListener)
1071      _moduleStartupListeners.add((ModuleStartupListener)info.getModule());
1072
1073    for (String JavaDoc ext : info.getLoadedExtensions())
1074      _extensionSet.add(ext);
1075
1076    Map JavaDoc<String JavaDoc, Value> map = info.getConstMap();
1077
1078    if (map != null)
1079      _constMap.putAll(map);
1080
1081    Map JavaDoc<String JavaDoc, StringValue> iniMap = info.getDefaultIni();
1082    _iniMap.putAll(iniMap);
1083
1084    for (Map.Entry JavaDoc<String JavaDoc, StaticFunction> entry : info.getFunctions().entrySet()) {
1085      _funMap.put(entry.getKey(), entry.getValue());
1086      _lowerFunMap.put(entry.getKey().toLowerCase(), entry.getValue());
1087    }
1088  }
1089
1090  public static Value objectToValue(Object JavaDoc obj)
1091  {
1092    if (obj == null)
1093      return NullValue.NULL;
1094    else if (Byte JavaDoc.class.equals(obj.getClass()) ||
1095             Short JavaDoc.class.equals(obj.getClass()) ||
1096             Integer JavaDoc.class.equals(obj.getClass()) ||
1097             Long JavaDoc.class.equals(obj.getClass())) {
1098      return LongValue.create(((Number JavaDoc) obj).longValue());
1099    } else if (Float JavaDoc.class.equals(obj.getClass()) ||
1100               Double JavaDoc.class.equals(obj.getClass())) {
1101      return DoubleValue.create(((Number JavaDoc) obj).doubleValue());
1102    } else if (String JavaDoc.class.equals(obj.getClass())) {
1103      return new StringValueImpl((String JavaDoc) obj);
1104    } else {
1105      // XXX: unknown types, e.g. Character?
1106

1107      return null;
1108    }
1109  }
1110
1111  /**
1112   * Scans the classpath for META-INF/services/com.caucho.quercus.QuercusClass
1113   */

1114  private void initStaticClassServices()
1115  {
1116    Thread JavaDoc thread = Thread.currentThread();
1117    ClassLoader JavaDoc loader = thread.getContextClassLoader();
1118
1119    try {
1120      String JavaDoc quercusModule
1121        = "META-INF/services/com.caucho.quercus.QuercusClass";
1122      Enumeration JavaDoc<URL JavaDoc> urls = loader.getResources(quercusModule);
1123
1124      while (urls.hasMoreElements()) {
1125        URL JavaDoc url = urls.nextElement();
1126
1127        InputStream JavaDoc is = null;
1128        ReadStream rs = null;
1129        try {
1130          is = url.openStream();
1131      
1132      rs = new ReadStream(new VfsStream(is, null));
1133      
1134          parseClassServicesModule(rs);
1135        } catch (Throwable JavaDoc e) {
1136          log.log(Level.WARNING, e.toString(), e);
1137        } finally {
1138          if (rs != null)
1139            rs.close();
1140          if (is != null)
1141            is.close();
1142        }
1143      }
1144
1145    } catch (Exception JavaDoc e) {
1146      log.log(Level.WARNING, e.toString(), e);
1147    }
1148  }
1149
1150  /**
1151   * Parses the services file, looking for PHP services.
1152   */

1153  private void parseClassServicesModule(ReadStream in)
1154    throws IOException JavaDoc, ClassNotFoundException JavaDoc,
1155           IllegalAccessException JavaDoc, InstantiationException JavaDoc,
1156           ConfigException, NoSuchMethodException JavaDoc, InvocationTargetException JavaDoc
1157  {
1158    ClassLoader JavaDoc loader = Thread.currentThread().getContextClassLoader();
1159    String JavaDoc line;
1160
1161    while ((line = in.readLine()) != null) {
1162      int p = line.indexOf('#');
1163
1164      if (p >= 0)
1165        line = line.substring(0, p);
1166
1167      line = line.trim();
1168
1169      if (line.length() == 0)
1170        continue;
1171
1172      String JavaDoc[] args = line.split(" ");
1173
1174      String JavaDoc className = args[0];
1175
1176      Class JavaDoc cl;
1177
1178      try {
1179        cl = Class.forName(className, false, loader);
1180
1181        String JavaDoc phpClassName = null;
1182        String JavaDoc extension = null;
1183        String JavaDoc definedBy = null;
1184
1185        for (int i = 1; i < args.length; i++) {
1186          if ("as".equals(args[i])) {
1187            i++;
1188            if (i >= args.length)
1189              throw new IOException JavaDoc(L.l("expecting Quercus class name after `{0}' in definition for class {1}", "as", className));
1190
1191            phpClassName = args[i];
1192          }
1193          else if ("provides".equals(args[i])) {
1194            i++;
1195            if (i >= args.length)
1196              throw new IOException JavaDoc(L.l("expecting name of extension after `{0}' in definition for class {1}", "extension", className));
1197
1198            extension = args[i];
1199          }
1200          else if ("definedBy".equals(args[i])) {
1201            i++;
1202            if (i >= args.length)
1203              throw new IOException JavaDoc(L.l("expecting name of class implementing JavaClassDef after `{0}' in definition for class {1}", "definedBy", className));
1204
1205            definedBy = args[i];
1206          }
1207          else {
1208            throw new IOException JavaDoc(L.l("unknown token `{0}' in definition for class {1} ", args[i], className));
1209          }
1210        }
1211
1212        if (phpClassName == null)
1213          phpClassName = className.substring(className.lastIndexOf('.') + 1);
1214
1215
1216        Class JavaDoc javaClassDefClass;
1217
1218        if (definedBy != null) {
1219          javaClassDefClass = Class.forName(definedBy, false, loader);
1220        }
1221        else
1222          javaClassDefClass = null;
1223
1224        introspectJavaClass(phpClassName, cl, extension, javaClassDefClass);
1225      } catch (Throwable JavaDoc e) {
1226        log.info("Failed loading " + className + "\n" + e.toString());
1227        log.log(Level.FINE, e.toString(), e);
1228      }
1229    }
1230  }
1231
1232  /**
1233   * Introspects the module class for functions.
1234   *
1235   * @param name the php class name
1236   * @param type the class to introspect.
1237   * @param extension the extension provided by the class, or null
1238   * @param javaClassDefClass
1239   */

1240  private void introspectJavaClass(String JavaDoc name, Class JavaDoc type, String JavaDoc extension,
1241                                   Class JavaDoc javaClassDefClass)
1242    throws IllegalAccessException JavaDoc, InstantiationException JavaDoc, ConfigException,
1243           NoSuchMethodException JavaDoc, InvocationTargetException JavaDoc
1244  {
1245    if (log.isLoggable(Level.FINE))
1246      log.fine(L.l("Quercus loading class {0}", name));
1247
1248    ModuleContext context = getLocalContext();
1249
1250    if (type.isAnnotationPresent(ClassImplementation.class)) {
1251      if (javaClassDefClass != null)
1252        throw new UnimplementedException();
1253
1254      ClassDef def = context.addClassImpl(name, type, extension);
1255
1256      _staticClasses.put(name, def);
1257      _lowerStaticClasses.put(name.toLowerCase(), def);
1258    }
1259    else {
1260      JavaClassDef def = context.addClass(name, type,
1261                      extension, javaClassDefClass);
1262
1263      _javaClassWrappers.put(name, def);
1264      _lowerJavaClassWrappers.put(name.toLowerCase(), def);
1265
1266      _staticClasses.put(name, def);
1267      _lowerStaticClasses.put(name.toLowerCase(), def);
1268    }
1269
1270    if (extension != null)
1271      _extensionSet.add(extension);
1272  }
1273
1274  /**
1275   * Introspects the module class for functions.
1276   *
1277   * @param name the php class name
1278   * @param type the class to introspect.
1279   * @param extension the extension provided by the class, or null
1280   */

1281  private void introspectJavaImplClass(String JavaDoc name,
1282                                       Class JavaDoc type,
1283                                       String JavaDoc extension)
1284    throws IllegalAccessException JavaDoc, InstantiationException JavaDoc, ConfigException
1285  {
1286    if (log.isLoggable(Level.FINEST)) {
1287      if (extension == null)
1288        log.finest(L.l("Quercus loading class {0} with type {1}", name, type.getName()));
1289      else
1290        log.finest(L.l("Quercus loading class {0} with type {1} providing extension {2}", name, type.getName(), extension));
1291    }
1292
1293    ModuleContext context = getLocalContext();
1294
1295    JavaImplClassDef def = context.addClassImpl(name, type, extension);
1296
1297    _staticClasses.put(name, def);
1298    _lowerStaticClasses.put(name.toLowerCase(), def);
1299  }
1300
1301  /**
1302   * Scans the classpath for META-INF/services/com.caucho.quercus.QuercusClass
1303   */

1304  private void initStaticClasses()
1305  {
1306    _stdClassDef = new InterpretedClassDef("stdClass", null, new String JavaDoc[0]);
1307    _stdClass = new QuercusClass(_stdClassDef, null);
1308
1309    _staticClasses.put(_stdClass.getName(), _stdClassDef);
1310    _lowerStaticClasses.put(_stdClass.getName().toLowerCase(), _stdClassDef);
1311
1312    /*
1313    InterpretedClassDef exn = new InterpretedClassDef("Exception",
1314                              null,
1315                              new String[0]);
1316
1317    try {
1318      exn.setConstructor(new StaticFunction(_moduleContext,
1319                        null,
1320                        Quercus.class.getMethod("exnConstructor", new Class[] { Env.class, Value.class, String.class })));
1321    } catch (Exception e) {
1322      throw new QuercusException(e);
1323    }
1324    
1325    // QuercusClass exnCl = new QuercusClass(exn, null);
1326
1327    _staticClasses.put(exn.getName(), exn);
1328    _lowerStaticClasses.put(exn.getName().toLowerCase(), exn);
1329    */

1330  }
1331
1332  public void close()
1333  {
1334    _pageManager.close();
1335  }
1336
1337  public static Value exnConstructor(Env env, Value obj, String JavaDoc msg)
1338  {
1339    if (obj != null) {
1340      obj.putField(env, "message", new StringValueImpl(msg));
1341    }
1342
1343    return NullValue.NULL;
1344
1345  }
1346
1347  static class IncludeKey {
1348    private final String JavaDoc _include;
1349    private final String JavaDoc _includePath;
1350    private final Path _pwd;
1351    private final Path _scriptPwd;
1352
1353    IncludeKey(String JavaDoc include, String JavaDoc includePath, Path pwd, Path scriptPwd)
1354    {
1355      _include = include;
1356      _includePath = includePath;
1357      _pwd = pwd;
1358      _scriptPwd = scriptPwd;
1359    }
1360
1361    public int hashCode()
1362    {
1363      int hash = 37;
1364
1365      hash = 65537 * hash + _include.hashCode();
1366      hash = 65537 * hash + _includePath.hashCode();
1367      hash = 65537 * hash + _pwd.hashCode();
1368      hash = 65537 * hash + _scriptPwd.hashCode();
1369
1370      return hash;
1371    }
1372
1373    public boolean equals(Object JavaDoc o)
1374    {
1375      if (! (o instanceof IncludeKey))
1376        return false;
1377
1378      IncludeKey key = (IncludeKey) o;
1379
1380      return (_include.equals(key._include) &&
1381              _includePath.equals(key._includePath) &&
1382              _pwd.equals(key._pwd) &&
1383              _scriptPwd.equals(key._scriptPwd));
1384    }
1385  }
1386
1387  static {
1388    _superGlobals.add("GLOBALS");
1389    _superGlobals.add("_COOKIE");
1390    _superGlobals.add("_ENV");
1391    _superGlobals.add("_FILES");
1392    _superGlobals.add("_GET");
1393    _superGlobals.add("_POST");
1394    _superGlobals.add("_SERVER");
1395    _superGlobals.add("_SESSION");
1396    _superGlobals.add("_REQUEST");
1397  }
1398}
1399
1400
Popular Tags