KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > quercus > program > Statement


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.program;
31
32 import com.caucho.quercus.Location;
33 import com.caucho.quercus.QuercusExecutionException;
34 import com.caucho.quercus.env.Env;
35 import com.caucho.quercus.env.Value;
36
37 import java.util.IdentityHashMap JavaDoc;
38 import java.util.logging.Level JavaDoc;
39 import java.util.logging.Logger JavaDoc;
40
41 /**
42  * Represents a PHP statement
43  */

44 abstract public class Statement {
45   private static final Logger JavaDoc log = Logger.getLogger(Statement.class.getName());
46
47   public static final int FALL_THROUGH = 0;
48   public static final int BREAK_FALL_THROUGH = 0x1;
49   public static final int RETURN = 0x2;
50
51   private final Location _location;
52
53   protected Statement()
54   {
55     _location = Location.UNKNOWN;
56   }
57
58   protected Statement(Location location)
59   {
60     _location = location;
61   }
62
63   public Location getLocation()
64   {
65     return _location;
66   }
67
68   abstract public Value execute(Env env);
69
70   /**
71    * Returns true if the statement can fallthrough.
72    */

73   public int fallThrough()
74   {
75     return FALL_THROUGH;
76   }
77
78   final protected void rethrow(Throwable JavaDoc t)
79     throws Throwable JavaDoc
80   {
81     rethrow(t, Throwable JavaDoc.class);
82   }
83
84   final protected <E extends Throwable JavaDoc> void rethrow(Throwable JavaDoc t, Class JavaDoc<E> cl)
85     throws E
86   {
87     E typedT;
88
89     if (!cl.isAssignableFrom(t.getClass())) {
90       try {
91         typedT = cl.newInstance();
92         typedT.initCause(t);
93       }
94       catch (InstantiationException JavaDoc e) {
95         log.log(Level.WARNING, t.toString(), t);
96         throw new RuntimeException JavaDoc(e);
97       }
98       catch (IllegalAccessException JavaDoc e) {
99         log.log(Level.WARNING, t.toString(), t);
100         throw new RuntimeException JavaDoc(e);
101       }
102     }
103     else
104       typedT = (E) t;
105
106     Throwable JavaDoc rootCause = t;
107
108     // guard against circular cause
109
IdentityHashMap JavaDoc<Throwable JavaDoc, Boolean JavaDoc> causes = new IdentityHashMap JavaDoc<Throwable JavaDoc, Boolean JavaDoc>();
110
111     causes.put(rootCause, Boolean.TRUE);
112
113     while (rootCause.getCause() != null) {
114       Throwable JavaDoc cause = rootCause.getCause();
115
116       if (causes.containsKey(cause))
117         break;
118
119       causes.put(cause, Boolean.TRUE);
120
121       rootCause = cause;
122     }
123
124     if (!(rootCause instanceof QuercusExecutionException)) {
125       String JavaDoc rootCauseName = rootCause.getClass().getName();
126       String JavaDoc rootCauseMessage = rootCause.getMessage();
127
128       StringBuilder JavaDoc quercusExMessage = new StringBuilder JavaDoc();
129
130       quercusExMessage.append(rootCauseName);
131
132       if (rootCauseMessage != null && rootCauseMessage.length() > 0) {
133         quercusExMessage.append(" ");
134         quercusExMessage.append(rootCauseMessage);
135       }
136
137       QuercusExecutionException quercusEx
138         = new QuercusExecutionException(quercusExMessage.toString());
139
140       StackTraceElement JavaDoc[] quercusExStackTrace = quercusEx.getStackTrace();
141       StackTraceElement JavaDoc[] rootCauseStackTrace = rootCause.getStackTrace();
142
143       int quercusExIndex = quercusExStackTrace.length - 1;
144       int rootCauseIndex = rootCauseStackTrace.length - 1;
145
146       while (rootCauseIndex >= 0 && quercusExIndex >= 0) {
147         StackTraceElement JavaDoc rootCauseElement = rootCauseStackTrace[rootCauseIndex];
148         StackTraceElement JavaDoc quercusExElement = quercusExStackTrace[quercusExIndex];
149
150         if (! quercusExElement.equals(rootCauseElement))
151           break;
152
153         rootCauseIndex--;
154         quercusExIndex--;
155       }
156
157       int len = rootCauseIndex + 1;
158
159       StackTraceElement JavaDoc[] trimmedElements = new StackTraceElement JavaDoc[len];
160       System.arraycopy(rootCauseStackTrace, 0, trimmedElements, 0, len);
161
162       quercusEx.setStackTrace(trimmedElements);
163       rootCause.initCause(quercusEx);
164       rootCause = quercusEx;
165     }
166
167     String JavaDoc className = _location.getClassName();
168     String JavaDoc functionName = _location.getFunctionName();
169     String JavaDoc fileName = _location.getFileName();
170     int lineNumber = _location.getLineNumber();
171
172     if (className == null)
173       className = "";
174
175     if (functionName == null)
176       functionName = "";
177
178     StackTraceElement JavaDoc[] existingElements = rootCause.getStackTrace();
179     int len = existingElements.length;
180     StackTraceElement JavaDoc lastElement;
181
182     if (len > 1)
183       lastElement = existingElements[len - 1];
184     else
185       lastElement = null;
186
187     // early return if function and class are same as last one
188
if (lastElement != null
189         && (functionName.equals(lastElement.getMethodName()))
190         && (className.equals(lastElement.getClassName())))
191     {
192       throw typedT;
193     }
194
195     StackTraceElement JavaDoc[] elements = new StackTraceElement JavaDoc[len + 1];
196
197     System.arraycopy(existingElements, 0, elements, 0, len);
198
199     elements[len] = new StackTraceElement JavaDoc(className,
200                                           functionName,
201                                           fileName,
202                                           lineNumber);
203
204     rootCause.setStackTrace(elements);
205
206     throw typedT;
207   }
208
209   public String JavaDoc toString()
210   {
211     return getClass().getSimpleName() + "[]";
212   }
213 }
214
215
Popular Tags