KickJava   Java API By Example, From Geeks To Geeks.

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


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

29
30 package com.caucho.quercus.env;
31
32 import com.caucho.quercus.Quercus;
33 import com.caucho.quercus.QuercusException;
34 import com.caucho.quercus.program.AbstractFunction;
35 import com.caucho.quercus.program.ClassDef;
36 import com.caucho.quercus.program.UnsetFunction;
37 import com.caucho.util.Crc64;
38 import com.caucho.util.L10N;
39 import com.caucho.util.LruCache;
40
41 import java.lang.ref.SoftReference JavaDoc;
42 import java.lang.ref.WeakReference JavaDoc;
43 import java.util.ArrayList JavaDoc;
44 import java.util.Collections JavaDoc;
45 import java.util.HashMap JavaDoc;
46 import java.util.logging.Logger JavaDoc;
47
48 /**
49  * Represents the state of the definitions: functions, classes and
50  * constants.
51  */

52 public final class DefinitionState {
53   private static final L10N L = new L10N(DefinitionState.class);
54   private static final Logger JavaDoc log
55     = Logger.getLogger(DefinitionState.class.getName());
56   
57   private static final
58     LruCache<ClassKey,SoftReference JavaDoc<QuercusClass>> _classCache
59     = new LruCache<ClassKey,SoftReference JavaDoc<QuercusClass>>(4096);
60
61   private final Quercus _quercus;
62
63   private boolean _isStrict;
64
65   private HashMap JavaDoc<String JavaDoc, AbstractFunction> _funMap;
66
67   private HashMap JavaDoc<String JavaDoc, AbstractFunction> _lowerFunMap;
68
69   private HashMap JavaDoc<String JavaDoc, ClassDef> _classDefMap;
70
71   private HashMap JavaDoc<String JavaDoc, ClassDef> _lowerClassDefMap;
72
73   private boolean _isLazy;
74
75   // crc of the entries
76
private long _crc;
77
78   public DefinitionState(Quercus quercus)
79   {
80     _quercus = quercus;
81
82     _isStrict = quercus.isStrict();
83
84     _funMap = new HashMap JavaDoc<String JavaDoc, AbstractFunction>(8192, 0.5F);
85     _classDefMap = new HashMap JavaDoc<String JavaDoc, ClassDef>();
86
87     if (! _isStrict) {
88       _lowerFunMap = new HashMap JavaDoc<String JavaDoc, AbstractFunction>(8192, 0.5F);
89
90       _lowerClassDefMap = new HashMap JavaDoc<String JavaDoc, ClassDef>();
91     }
92   }
93
94   private DefinitionState(DefinitionState oldState)
95   {
96     this(oldState._quercus);
97
98     _funMap.putAll(oldState._funMap);
99
100     if (_lowerFunMap != null)
101       _lowerFunMap.putAll(oldState._lowerFunMap);
102
103     _classDefMap.putAll(oldState._classDefMap);
104
105     if (_lowerClassDefMap != null)
106       _lowerClassDefMap.putAll(oldState._lowerClassDefMap);
107
108     _crc = oldState._crc;
109   }
110
111   private DefinitionState(DefinitionState oldState, boolean isLazy)
112   {
113     _isLazy = true;
114     
115     _quercus = oldState._quercus;
116     _isStrict = oldState._isStrict;
117
118     _funMap = oldState._funMap;
119     _lowerFunMap = oldState._lowerFunMap;
120
121     _classDefMap = oldState._classDefMap;
122     _lowerClassDefMap = oldState._lowerClassDefMap;
123     
124     _crc = oldState._crc;
125   }
126
127   /**
128    * Returns true for strict mode.
129    */

130   public final boolean isStrict()
131   {
132     return _isStrict;
133   }
134
135   /**
136    * Returns the owning PHP engine.
137    */

138   public Quercus getQuercus()
139   {
140     return _quercus;
141   }
142
143   /**
144    * returns the crc.
145    */

146   public long getCrc()
147   {
148     return _crc;
149   }
150
151   /**
152    * Returns an array of the defined functions.
153    */

154   public ArrayValue getDefinedFunctions()
155   {
156     ArrayValue result = new ArrayValueImpl();
157
158     ArrayValue internal = _quercus.getDefinedFunctions();
159     ArrayValue user = new ArrayValueImpl();
160
161     result.put(new StringValueImpl("internal"), internal);
162     result.put(new StringValueImpl("user"), user);
163
164     for (String JavaDoc name : _funMap.keySet()) {
165       StringValue key = new StringValueImpl(name);
166
167       if (! internal.contains(key).isset())
168         user.put(name);
169     }
170
171     return result;
172   }
173
174   /**
175    * Finds the java reflection method for the function with the given name.
176    *
177    * @param name the method name
178    * @return the found method or null if no method found.
179    */

180   public AbstractFunction findFunction(String JavaDoc name)
181   {
182     AbstractFunction fun = _funMap.get(name);
183
184     if (fun == null) {
185     }
186     else if (fun instanceof UnsetFunction) {
187       UnsetFunction unsetFun = (UnsetFunction) fun;
188
189       if (_crc == unsetFun.getCrc())
190     return null;
191     }
192     else {
193       return fun;
194     }
195     
196     if (_lowerFunMap != null) {
197       fun = _lowerFunMap.get(name.toLowerCase());
198
199       if (fun != null) {
200     _funMap.put(name, fun);
201
202     return fun;
203       }
204     }
205
206     fun = findModuleFunction(name);
207
208     if (fun != null) {
209       _funMap.put(name, fun);
210
211       return fun;
212     }
213     else {
214       _funMap.put(name, new UnsetFunction(_crc));
215       
216       return null;
217     }
218   }
219
220   /**
221    * Finds the java reflection method for the function with the given name.
222    *
223    * @param name the method name
224    * @return the found method or null if no method found.
225    */

226   private AbstractFunction findModuleFunction(String JavaDoc name)
227   {
228     AbstractFunction fun = null;
229
230     fun = _quercus.findFunction(name);
231     if (fun != null)
232       return fun;
233
234     return fun;
235   }
236
237   /**
238    * Adds a function, e.g. from an include.
239    */

240   public Value addFunction(String JavaDoc name, AbstractFunction fun)
241   {
242     AbstractFunction oldFun = findFunction(name);
243
244     if (oldFun != null) {
245       throw new QuercusException(L.l("can't redefine function {0}", name));
246     }
247
248     copyOnWrite();
249     _funMap.put(name, fun);
250     _crc = Crc64.generate(_crc, name);
251
252     if (_lowerFunMap != null)
253       _lowerFunMap.put(name.toLowerCase(), fun);
254
255     return BooleanValue.TRUE;
256   }
257
258   /**
259    * Adds a function from a compiled include
260    *
261    * @param name the function name, must be an intern() string
262    * @param lowerName the function name, must be an intern() string
263    */

264   public Value addFunction(String JavaDoc name, String JavaDoc lowerName, AbstractFunction fun)
265   {
266     // XXX: skip the old function check since the include for compiled
267
// pages is already verified. Might have a switch here?
268
/*
269     AbstractFunction oldFun = _lowerFunMap.get(lowerName);
270
271     if (oldFun == null)
272       oldFun = _quercus.findLowerFunctionImpl(lowerName);
273
274     if (oldFun != null) {
275       throw new QuercusException(L.l("can't redefine function {0}", name));
276     }
277     */

278
279     copyOnWrite();
280     _funMap.put(name, fun);
281     _crc = Crc64.generate(_crc, name);
282
283     if (_lowerFunMap != null)
284       _lowerFunMap.put(lowerName, fun);
285
286     return BooleanValue.TRUE;
287   }
288
289   /**
290    * Adds a class, e.g. from an include.
291    */

292   public void addClassDef(String JavaDoc name, ClassDef cl)
293   {
294     copyOnWrite();
295     _classDefMap.put(name, cl);
296     _crc = Crc64.generate(_crc, name);
297
298     if (_lowerClassDefMap != null)
299       _lowerClassDefMap.put(name.toLowerCase(), cl);
300   }
301
302   /**
303    * Adds a class, e.g. from an include.
304    */

305   public ClassDef findClassDef(String JavaDoc name)
306   {
307     ClassDef def = _classDefMap.get(name);
308
309     if (def != null)
310       return def;
311
312     if (_lowerClassDefMap != null)
313       def = _lowerClassDefMap.get(name.toLowerCase());
314
315     return def;
316   }
317
318   /**
319    * Returns the declared classes.
320    *
321    * @return an array of the declared classes()
322    */

323   public Value getDeclaredClasses()
324   {
325     ArrayList JavaDoc<String JavaDoc> names = new ArrayList JavaDoc<String JavaDoc>();
326
327     /*
328     for (String name : _classMap.keySet()) {
329       if (! names.contains(name))
330         names.add(name);
331     }
332     */

333
334     for (String JavaDoc name : _classDefMap.keySet()) {
335       if (! names.contains(name))
336         names.add(name);
337     }
338
339     for (String JavaDoc name : _quercus.getClassMap().keySet()) {
340       if (! names.contains(name))
341         names.add(name);
342     }
343
344     Collections.sort(names);
345
346     ArrayValue array = new ArrayValueImpl();
347
348     for (String JavaDoc name : names) {
349       array.put(new StringValueImpl(name));
350     }
351
352     return array;
353   }
354
355   public DefinitionState copy()
356   {
357     return new DefinitionState(this);
358   }
359
360   public DefinitionState copyLazy()
361   {
362     return new DefinitionState(this, true);
363   }
364
365   private void copyOnWrite()
366   {
367     if (! _isLazy)
368       return;
369     
370     _isLazy = false;
371
372     _funMap = new HashMap JavaDoc<String JavaDoc, AbstractFunction>(_funMap);
373
374     if (_lowerFunMap != null) {
375       _lowerFunMap = new HashMap JavaDoc<String JavaDoc, AbstractFunction>(_lowerFunMap);
376     }
377
378     _classDefMap = new HashMap JavaDoc<String JavaDoc, ClassDef>(_classDefMap);
379
380     if (_lowerClassDefMap != null) {
381       _lowerClassDefMap = new HashMap JavaDoc<String JavaDoc, ClassDef>(_lowerClassDefMap);
382     }
383   }
384
385   static class ClassKey {
386     private final WeakReference JavaDoc<ClassDef> _defRef;
387     private final WeakReference JavaDoc<QuercusClass> _parentRef;
388
389     ClassKey(ClassDef def, QuercusClass parent)
390     {
391       _defRef = new WeakReference JavaDoc<ClassDef>(def);
392
393       if (parent != null)
394     _parentRef = new WeakReference JavaDoc<QuercusClass>(parent);
395       else
396     _parentRef = null;
397     }
398
399     public int hashCode()
400     {
401       int hash = 37;
402
403       ClassDef def = _defRef.get();
404       
405       QuercusClass parent = null;
406       if (_parentRef != null)
407     parent = _parentRef.get();
408
409       if (def != null)
410     hash = 65521 * hash + def.hashCode();
411
412       if (parent != null)
413     hash = 65521 * hash + parent.hashCode();
414
415       return hash;
416     }
417
418     public boolean equals(Object JavaDoc o)
419     {
420       ClassKey key = (ClassKey) o;
421
422       ClassDef aDef = _defRef.get();
423       ClassDef bDef = key._defRef.get();
424
425       if (aDef != bDef)
426     return false;
427
428       if (_parentRef == key._parentRef)
429     return true;
430       
431       else if (_parentRef != null && key._parentRef != null)
432     return _parentRef.get() == key._parentRef.get();
433
434       else
435     return false;
436     }
437   }
438 }
439
440
Popular Tags