1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.springframework.extensions.webscripts.processor;
20
21 import java.io.InputStream;
22 import java.io.Writer;
23 import java.util.HashMap;
24 import java.util.Map;
25
26 import org.springframework.extensions.surf.core.processor.ProcessorExtension;
27 import org.springframework.extensions.surf.core.scripts.ScriptException;
28 import org.springframework.extensions.webscripts.ScriptContent;
29 import org.springframework.extensions.webscripts.processor.AbstractScriptProcessor;
30
31 import com.caucho.quercus.Quercus;
32 import com.caucho.quercus.env.ArrayValue;
33 import com.caucho.quercus.env.ArrayValueImpl;
34 import com.caucho.quercus.env.BooleanValue;
35 import com.caucho.quercus.env.DoubleValue;
36 import com.caucho.quercus.env.Env;
37 import com.caucho.quercus.env.StringInputStream;
38 import com.caucho.quercus.env.StringValue;
39 import com.caucho.quercus.env.Value;
40 import com.caucho.quercus.module.QuercusModule;
41 import com.caucho.quercus.page.QuercusPage;
42 import com.caucho.util.CharBuffer;
43 import com.caucho.vfs.ReadStream;
44 import com.caucho.vfs.StringWriter;
45 import com.caucho.vfs.VfsStream;
46 import com.caucho.vfs.WriteStream;
47
48
49
50
51
52
53
54 public class PHPScriptProcessor extends AbstractScriptProcessor
55 {
56
57 public static final String ALF_AVAILABLE = "ALF_AVAILABLE";
58
59
60 private Quercus quercus;
61
62
63
64
65 public PHPScriptProcessor()
66 {
67
68 this.quercus = new Quercus();
69
70
71 this.quercus.setServerEnv(PHPScriptProcessor.ALF_AVAILABLE, "true");
72 }
73
74
75
76
77 public String getExtension()
78 {
79 return "php";
80 }
81
82
83
84
85 public String getName()
86 {
87 return "php";
88 }
89
90
91
92
93 public void init()
94 {
95 super.init();
96
97
98 }
99
100
101
102
103
104 public void registerProcessorExtension(ProcessorExtension processorExtension)
105 {
106
107 super.registerProcessorExtension(processorExtension);
108
109
110 if (processorExtension instanceof PHPMethodExtension)
111 {
112 this.quercus.addModule((QuercusModule)processorExtension);
113 ((PHPMethodExtension)processorExtension).initialiseModule(this.quercus.findModule(processorExtension.getClass().getName()));
114 }
115 else if (processorExtension instanceof PHPObjectExtension)
116 {
117 try
118 {
119 Class clazz = Class.forName(((PHPObjectExtension)processorExtension).getExtensionClass());
120 this.quercus.addJavaClass(processorExtension.getExtensionName(), clazz);
121 }
122 catch (ClassNotFoundException exception)
123 {
124 throw new PHPProcessorException("PHP Object Extension class '" + ((PHPObjectExtension)processorExtension).getExtensionClass() + "' could not be found.", exception);
125 }
126 }
127 }
128
129
130
131
132
133
134
135
136
137 private Object executePHPScript(String script, Writer out, Map<String, Object> model)
138 {
139 return executePHPScript(new StringInputStream(script), out, model);
140 }
141
142
143
144
145
146
147
148
149
150 private Object executePHPScript(InputStream is, Writer out, Map<String, Object> model)
151 {
152 try
153 {
154
155 StringWriter writer = new StringWriter(new CharBuffer(1024));
156 writer.openWrite();
157
158
159 VfsStream stream = new VfsStream(is, null);
160 QuercusPage page = this.quercus.parse(new ReadStream(stream));
161
162
163 WriteStream ws = new WriteStream(writer);
164 Env env = new Env(this.quercus, page, ws, null, null);
165 env.start();
166
167
168 Value value = page.executeTop(env);
169
170
171 ws.flush();
172
173
174 String result = ((StringWriter)ws.getSource()).getString();
175 if (out != null)
176 {
177 out.write(result);
178 }
179
180
181 return value.toJavaObject();
182 }
183 catch (Exception exception)
184 {
185 throw new ScriptException("Error executing script.", exception);
186 }
187 }
188
189
190
191
192
193
194 @SuppressWarnings("unchecked")
195 private Map<String, Object> getModel(Object model)
196 {
197 Map<String, Object> result = null;
198 if (model != null && model instanceof Map)
199 {
200 result = (Map<String, Object>)model;
201 }
202 else
203 {
204 result = new HashMap<String, Object>(2);
205 }
206 return result;
207 }
208
209
210
211
212 public ScriptContent findScript(String path)
213 {
214 return getScriptLoader().getScript(path);
215 }
216
217
218
219
220 public Object executeScript(String path, Map<String, Object> model)
221 {
222 ScriptContent scriptContent = getScriptLoader().getScript(path);
223 return executeScript(scriptContent, model);
224 }
225
226
227
228
229 public Object executeScript(ScriptContent location, Map<String, Object> model)
230 {
231 return executePHPScript(location.getInputStream(), null, model);
232 }
233
234
235
236
237 public Object unwrapValue(Object value)
238 {
239 Value result = null;
240
241 if (value instanceof String)
242 {
243 result = StringValue.create(value);
244 }
245 else if (value instanceof Integer)
246 {
247
248 result = DoubleValue.create(((Integer)value).doubleValue());
249 }
250 else if (value instanceof Boolean)
251 {
252 result = BooleanValue.create((Boolean)value);
253 }
254 else if (value instanceof Map)
255 {
256 Map map = (Map)value;
257 ArrayValue arrayValue = new ArrayValueImpl(map.size());
258 for (Object objKey : map.keySet())
259 {
260 if (objKey instanceof String)
261 {
262 String key = (String)objKey;
263 Object objValue = map.get(key);
264 arrayValue.put(StringValue.create(key), (Value) unwrapValue(objValue));
265 }
266 }
267 result = arrayValue;
268 }
269
270 return result;
271 }
272
273
274
275
276 public void reset()
277 {
278 init();
279 }
280 }