KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > quercus > lib > ErrorModule


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.lib;
31
32 import com.caucho.quercus.QuercusDieException;
33 import com.caucho.quercus.QuercusModuleException;
34 import com.caucho.quercus.annotation.Optional;
35 import com.caucho.quercus.env.*;
36 import com.caucho.quercus.expr.Expr;
37 import com.caucho.quercus.expr.FunctionExpr;
38 import com.caucho.quercus.expr.IncludeExpr;
39 import com.caucho.quercus.expr.MethodCallExpr;
40 import com.caucho.quercus.module.AbstractQuercusModule;
41 import com.caucho.util.L10N;
42
43 import java.io.IOException JavaDoc;
44 import java.util.HashMap JavaDoc;
45 import java.util.Map JavaDoc;
46 import java.util.logging.Logger JavaDoc;
47
48 /**
49  * PHP error handling.
50  */

51 public class ErrorModule extends AbstractQuercusModule {
52   private static final L10N L = new L10N(ErrorModule.class);
53   private static final Logger JavaDoc log
54     = Logger.getLogger(ErrorModule.class.getName());
55
56   private static final HashMap JavaDoc<String JavaDoc,StringValue> _iniMap
57     = new HashMap JavaDoc<String JavaDoc,StringValue>();
58
59   public static final int E_ERROR = Env.E_ERROR;
60   public static final int E_WARNING = Env.E_WARNING;
61   public static final int E_PARSE = Env.E_PARSE;
62   public static final int E_NOTICE = Env.E_NOTICE;
63   public static final int E_CORE_ERROR = Env.E_CORE_ERROR;
64   public static final int E_CORE_WARNING = Env.E_CORE_WARNING;
65   public static final int E_COMPILE_ERROR = Env.E_COMPILE_ERROR;
66   public static final int E_COMPILE_WARNING = Env.E_COMPILE_WARNING;
67   public static final int E_USER_ERROR = Env.E_USER_ERROR;
68   public static final int E_USER_WARNING = Env.E_USER_WARNING;
69   public static final int E_USER_NOTICE = Env.E_USER_NOTICE;
70   public static final int E_ALL = Env.E_ALL;
71   public static final int E_STRICT = Env.E_STRICT;
72
73   private long _errorReporting = Env.E_DEFAULT;
74
75   /**
76    * Returns the default quercus.ini values.
77    */

78   public Map JavaDoc<String JavaDoc,StringValue> getDefaultIni()
79   {
80     return _iniMap;
81   }
82
83   /**
84    * Exits
85    */

86   public Value die(Env env, @Optional String JavaDoc msg)
87   {
88     try {
89       if (msg != null) {
90     env.getOut().print(msg);
91
92     throw new QuercusDieException(msg);
93       }
94       else
95     throw new QuercusDieException(msg);
96     } catch (IOException JavaDoc e) {
97       throw new QuercusModuleException(e);
98     }
99   }
100   
101   /**
102    * Produces a backtrace
103    */

104   public static Value debug_backtrace(Env env)
105   {
106     ArrayValue result = new ArrayValueImpl();
107
108     Exception JavaDoc e = new Exception JavaDoc();
109     e.fillInStackTrace();
110
111     StackTraceElement JavaDoc []stack = e.getStackTrace();
112     int depth = 0;
113
114     for (int i = 1; i < stack.length; i++) {
115       StackTraceElement JavaDoc elt = stack[i];
116
117       String JavaDoc name = elt.getMethodName();
118       String JavaDoc className = elt.getClassName();
119
120       // System.out.println("NAME: " + name + " " + elt.getClassName());
121

122       if (name.equals("executeTop")) {
123     return result;
124       }
125       else if (className.startsWith("_quercus._")
126       && name.equals("call")) {
127     String JavaDoc path = unmangleFile(className);
128     String JavaDoc fileName = env.getPwd().lookup("./" + path).getNativePath();
129     
130     ArrayValue call = new ArrayValueImpl();
131     result.put(call);
132
133     call.put("file", fileName);
134     call.put("line", env.getSourceLine(className, elt.getLineNumber()));
135     
136     call.put("function", unmangleFunction(className));
137
138     call.put(new StringValueImpl("args"), new ArrayValueImpl());
139       }
140       else if (className.startsWith("_quercus._")
141            && name.equals("callMethod")) {
142     String JavaDoc path = unmangleFile(className);
143     String JavaDoc fileName = env.getPwd().lookup("./" + path).getNativePath();
144     
145     ArrayValue call = new ArrayValueImpl();
146     result.put(call);
147
148     call.put("file", fileName);
149     call.put("line", env.getSourceLine(className, elt.getLineNumber()));
150     
151     call.put("function", unmangleFunction(className));
152     call.put("class", unmangleClass(className));
153     call.put("type", "->");
154
155     call.put(new StringValueImpl("args"), new ArrayValueImpl());
156       }
157       else if (className.startsWith("_quercus._")
158            && name.equals("execute")) {
159     if (stack[i - 1].getMethodName().equals("include") &&
160         stack[i - 1].getClassName().equals("com.caucho.quercus.env.Env")) {
161       String JavaDoc path = unmangleFile(className);
162       String JavaDoc fileName = env.getPwd().lookup("./" + path).getNativePath();
163     
164       ArrayValue call = new ArrayValueImpl();
165       result.put(call);
166
167       call.put("file", fileName);
168       call.put("line", env.getSourceLine(className, elt.getLineNumber()));
169
170       call.put(new StringValueImpl("args"), new ArrayValueImpl());
171     }
172       }
173       else if (className.equals("com.caucho.quercus.expr.FunctionExpr")
174            && name.equals("evalImpl")) {
175     if (stack[i - 1].getMethodName().equals("evalArguments")) {
176     }
177     else if (result.getSize() == 0 && depth == 0)
178       depth++;
179     else
180       addInterpreted(env, result, depth++);
181       }
182       else if (className.equals("com.caucho.quercus.expr.MethodCallExpr")
183            && name.equals("eval")) {
184     if (stack[i - 1].getMethodName().equals("evalArguments")) {
185     }
186     else if (result.getSize() == 0 && depth == 0)
187       depth++;
188     else
189       addInterpreted(env, result, depth++);
190       }
191       else if (className.equals("com.caucho.quercus.expr.IncludeExpr")
192            && name.equals("eval")) {
193     addInterpreted(env, result, depth++);
194       }
195       else if (className.startsWith("com.caucho.quercus")) {
196       }
197       else if (name.equals("invoke") || name.equals("invoke0")) {
198       }
199       else {
200     ArrayValue call = new ArrayValueImpl();
201     result.put(call);
202
203     call.put("file", elt.getFileName());
204     call.put("line", elt.getLineNumber());
205     
206     call.put("function", elt.getMethodName());
207     call.put("class", elt.getClassName());
208
209     call.put(new StringValueImpl("args"), new ArrayValueImpl());
210       }
211     }
212
213     return result;
214   }
215
216   private static void addInterpreted(Env env, ArrayValue result, int i)
217   {
218     Expr expr = env.peekCall(i);
219     if (expr instanceof FunctionExpr) {
220       FunctionExpr callExpr = (FunctionExpr) expr;
221
222       ArrayValue call = new ArrayValueImpl();
223       result.put(call);
224       
225       if (callExpr.getFileName() != null) {
226     call.put("file", callExpr.getFileName());
227     call.put("line", callExpr.getLine());
228       }
229     
230       call.put("function", callExpr.getName());
231
232       call.put(new StringValueImpl("args"), new ArrayValueImpl());
233     }
234     else if (expr instanceof MethodCallExpr) {
235       MethodCallExpr callExpr = (MethodCallExpr) expr;
236
237       ArrayValue call = new ArrayValueImpl();
238       result.put(call);
239       
240       if (callExpr.getFileName() != null) {
241     call.put("file", callExpr.getFileName());
242     call.put("line", callExpr.getLine());
243       }
244     
245       call.put("function", callExpr.getName());
246
247       call.put("class",
248            env.peekCallThis(i).getQuercusClass().getName());
249
250       call.put("type", "->");
251
252       call.put(new StringValueImpl("args"), new ArrayValueImpl());
253     }
254     else if (expr instanceof IncludeExpr) {
255       ArrayValue call = new ArrayValueImpl();
256       result.put(call);
257       
258       if (expr.getFileName() != null) {
259     call.put("file", expr.getFileName());
260     call.put("line", expr.getLine());
261       }
262     
263       call.put("function", "include");
264
265       call.put(new StringValueImpl("args"), new ArrayValueImpl());
266     }
267   }
268
269   private static String JavaDoc unmangleFile(String JavaDoc className)
270   {
271     int i = "_quercus".length();
272     int end = className.indexOf('$');
273
274     if (end < 0)
275       end = className.length();
276     
277     StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
278
279     for (; i < end; i++) {
280       char ch = className.charAt(i);
281
282       if (ch == '.' && className.charAt(i + 1) == '_') {
283     sb.append('/');
284     i++;
285       }
286       else if (ch != '_') {
287     sb.append(ch);
288       }
289       else if (className.charAt(i + 1) == '_') {
290     sb.append('.');
291     i++;
292       }
293       else {
294     System.out.println("UNKNOWN:" + className.charAt(i + 1) + " " + className);
295       }
296     }
297
298     return sb.toString();
299   }
300
301   private static String JavaDoc unmangleFunction(String JavaDoc className)
302   {
303     int p = className.lastIndexOf("$fun_");
304
305     if (p > 0)
306       return className.substring(p + "$fun_".length());
307     else
308       return className;
309   }
310
311   private static String JavaDoc unmangleClass(String JavaDoc className)
312   {
313     int p = className.lastIndexOf("$quercus_");
314     int q = className.lastIndexOf("$");
315
316     if (p > 0 && p < q)
317       return className.substring(p + "$quercus_".length(), q);
318     else
319       return className;
320   }
321
322   /**
323    * Write an error
324    */

325   /*
326   public Value error(Env env, String msg)
327     throws Exception
328   {
329     // XXX: valiate
330     env.error(msg);
331
332     return NullValue.NULL;
333   }
334   */

335
336   /**
337    * Exits
338    */

339   public Value exit(Env env, @Optional String JavaDoc msg)
340   {
341     try {
342       if (msg != null) {
343     env.getOut().print(msg);
344
345     env.exit(msg);
346       }
347       else
348     env.exit();
349
350       throw new IllegalStateException JavaDoc();
351     } catch (IOException JavaDoc e) {
352       throw new QuercusModuleException(e);
353     }
354   }
355
356   /**
357    * Send a message to the log.
358    */

359   public static boolean error_log(String JavaDoc message,
360                                   @Optional int type,
361                                   @Optional String JavaDoc destination,
362                                   @Optional String JavaDoc extraHeaders)
363   {
364     log.warning(message);
365
366     // XXX: optional parameters not implemented since they seem to
367
// conflict with the java.util.logging methodology
368

369     return true;
370   }
371
372   /**
373    * Changes the error reporting value.
374    */

375   public static long error_reporting(Env env,
376                                      @Optional Value levelV)
377   {
378     if (levelV instanceof DefaultValue)
379       return env.getErrorMask();
380     else
381       return env.setErrorMask(levelV.toInt());
382   }
383
384   /**
385    * Restores the error handler
386    *
387    * @param env the quercus environment
388    */

389   public static boolean restore_error_handler(Env env)
390   {
391     env.restoreErrorHandler();
392
393     return true;
394   }
395
396   /**
397    * Sets an error handler
398    *
399    * @param env the quercus environment
400    * @param fun the error handler
401    * @param code errorMask error level
402    */

403   public static boolean set_error_handler(Env env,
404                       Callback fun,
405                       @Optional("E_ALL") int errorMask)
406   {
407     env.setErrorHandler(errorMask, fun);
408
409     return true;
410   }
411
412   /**
413    * Sets an exception handler
414    *
415    * @param env the quercus environment
416    * @param fun the exception handler
417    */

418   public static Value set_exception_handler(Env env,
419                         Callback fun)
420   {
421     return env.setExceptionHandler(fun);
422   }
423
424   /**
425    * Restore an exception handler
426    *
427    * @param env the quercus environment
428    */

429   public static Value restore_exception_handler(Env env)
430   {
431     env.restoreExceptionHandler();
432
433     return BooleanValue.TRUE;
434   }
435
436   /**
437    * Triggers an error.
438    *
439    * @param env the quercus environment
440    * @param msg the error message
441    * @param code the error level
442    */

443   public static Value trigger_error(Env env,
444                                     String JavaDoc msg,
445                                     @Optional("E_USER_NOTICE") int code)
446   {
447     switch (code) {
448     case Env.E_USER_NOTICE:
449       env.error(Env.B_USER_NOTICE, "", msg);
450       return BooleanValue.TRUE;
451
452     case Env.E_USER_WARNING:
453       env.error(Env.B_USER_WARNING, "", msg);
454       return BooleanValue.TRUE;
455
456     case Env.E_USER_ERROR:
457       env.error(Env.B_USER_ERROR, "", msg);
458       return BooleanValue.TRUE;
459
460     default:
461       env.warning(L.l("'0x{0}' is an invalid error type",
462                       Integer.toHexString(code)));
463
464       return BooleanValue.FALSE;
465     }
466   }
467
468   /**
469    * Triggers an error.
470    *
471    * @param env the quercus environment
472    * @param msg the error message
473    * @param code the error level
474    */

475   public Value user_error(Env env,
476                           String JavaDoc msg,
477                           @Optional("E_USER_NOTICE") int code)
478   {
479     return trigger_error(env, msg, code);
480   }
481
482   static {
483     addIni(_iniMap, "error_reporing", null, PHP_INI_ALL);
484     addIni(_iniMap, "display_errors", "1", PHP_INI_ALL);
485     addIni(_iniMap, "display_startup_errors", "0", PHP_INI_ALL);
486     addIni(_iniMap, "log_errors", "0", PHP_INI_ALL);
487     addIni(_iniMap, "log_errors_max_len", "1024", PHP_INI_ALL);
488     addIni(_iniMap, "ignore_repeated_errors", "0", PHP_INI_ALL);
489     addIni(_iniMap, "ignore_repeated_source", "0", PHP_INI_ALL);
490     addIni(_iniMap, "report_memleaks", "1", PHP_INI_ALL);
491     addIni(_iniMap, "track_errors", "0", PHP_INI_ALL);
492     addIni(_iniMap, "html_errors", "1", PHP_INI_ALL);
493     addIni(_iniMap, "docref_root", "", PHP_INI_ALL);
494     addIni(_iniMap, "docref_ext", "", PHP_INI_ALL);
495     addIni(_iniMap, "error_prepend_string", null, PHP_INI_ALL);
496     addIni(_iniMap, "error_append_string", null, PHP_INI_ALL);
497     addIni(_iniMap, "error_log", null, PHP_INI_ALL);
498     addIni(_iniMap, "warn_plus_overloading", null, PHP_INI_ALL);
499   }
500 }
501
502
Popular Tags