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.BufferedReader;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.Reader;
25 import java.io.Writer;
26 import java.util.HashMap;
27 import java.util.Map;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.springframework.extensions.surf.core.processor.ProcessorExtension;
32 import org.springframework.extensions.surf.core.scripts.ScriptException;
33 import org.springframework.extensions.webscripts.processor.AbstractTemplateProcessor;
34
35 import com.caucho.quercus.Quercus;
36 import com.caucho.quercus.env.Env;
37 import com.caucho.quercus.env.StringInputStream;
38 import com.caucho.quercus.env.Value;
39 import com.caucho.quercus.module.QuercusModule;
40 import com.caucho.quercus.page.QuercusPage;
41 import com.caucho.util.CharBuffer;
42 import com.caucho.vfs.ReadStream;
43 import com.caucho.vfs.StringWriter;
44 import com.caucho.vfs.VfsStream;
45 import com.caucho.vfs.WriteStream;
46
47
48
49
50
51
52
53 public class PHPTemplateProcessor extends AbstractTemplateProcessor
54 {
55 private static Log logger = LogFactory.getLog(PHPTemplateProcessor.class);
56
57
58 public static final String ALF_AVAILABLE = "ALF_AVAILABLE";
59
60
61 private String defaultEncoding;
62
63
64 private Quercus quercus;
65
66
67
68
69 public PHPTemplateProcessor()
70 {
71
72 this.quercus = new Quercus();
73
74
75 this.quercus.setServerEnv(PHPTemplateProcessor.ALF_AVAILABLE, "true");
76 }
77
78
79
80
81 public void setDefaultEncoding(String defaultEncoding)
82 {
83 this.defaultEncoding = defaultEncoding;
84 }
85
86
87
88
89 public String getDefaultEncoding()
90 {
91 return this.defaultEncoding;
92 }
93
94
95
96
97 public String getExtension()
98 {
99 return "php";
100 }
101
102
103
104
105 public String getName()
106 {
107 return "php";
108 }
109
110
111
112
113 public void init()
114 {
115 super.init();
116
117
118 }
119
120
121
122
123 public void registerProcessorExtension(ProcessorExtension processorExtension)
124 {
125
126 super.registerProcessorExtension(processorExtension);
127
128
129 if (processorExtension instanceof PHPMethodExtension)
130 {
131 this.quercus.addModule((QuercusModule)processorExtension);
132 ((PHPMethodExtension)processorExtension).initialiseModule(this.quercus.findModule(processorExtension.getClass().getName()));
133 }
134 else if (processorExtension instanceof PHPObjectExtension)
135 {
136 try
137 {
138 Class clazz = Class.forName(((PHPObjectExtension)processorExtension).getExtensionClass());
139 this.quercus.addJavaClass(processorExtension.getExtensionName(), clazz);
140 }
141 catch (ClassNotFoundException exception)
142 {
143 throw new PHPProcessorException("PHP Object Extension class '" + ((PHPObjectExtension)processorExtension).getExtensionClass() + "' could not be found.", exception);
144 }
145 }
146 }
147
148
149
150
151
152
153
154
155
156 private Object executePHPScript(String script, Writer out, Map<String, Object> model)
157 {
158 return executePHPScript(new StringInputStream(script), out, model);
159 }
160
161
162
163
164
165
166
167
168
169 private Object executePHPScript(InputStream is, Writer out, Map<String, Object> model)
170 {
171 try
172 {
173
174 StringWriter writer = new StringWriter(new CharBuffer(1024));
175 writer.openWrite();
176
177
178 VfsStream stream = new VfsStream(is, null);
179 QuercusPage page = this.quercus.parse(new ReadStream(stream));
180
181
182 WriteStream ws = new WriteStream(writer);
183 Env env = new Env(this.quercus, page, ws, null, null);
184 env.start();
185
186
187 Value value = page.executeTop(env);
188
189
190 ws.flush();
191
192
193 String result = ((StringWriter)ws.getSource()).getString();
194 if (out != null)
195 {
196 out.write(result);
197 out.flush();
198 }
199
200
201 return value.toJavaObject();
202 }
203 catch (Exception exception)
204 {
205 throw new ScriptException("Error executing script.", exception);
206 }
207 }
208
209
210
211
212
213
214 @SuppressWarnings("unchecked")
215 private Map<String, Object> getModel(Object model)
216 {
217 Map<String, Object> result = null;
218 if (model != null && model instanceof Map)
219 {
220 result = (Map<String, Object>)model;
221 }
222 else
223 {
224 result = new HashMap<String, Object>(2);
225 }
226 return result;
227 }
228
229
230
231
232 public boolean hasTemplate(String template)
233 {
234 boolean has = false;
235
236 try
237 {
238 Object templateSource = getTemplateLoader().findTemplateSource(template);
239 has = (templateSource != null);
240 }
241 catch (IOException ioe) { }
242
243 return has;
244 }
245
246
247
248
249 public void process(String templatePath, Object model, Writer out)
250 {
251
252 try
253 {
254 StringBuilder sb = new StringBuilder();
255
256 Object templateSource = getTemplateLoader().findTemplateSource(templatePath);
257 Reader reader = getTemplateLoader().getReader(templateSource, this.defaultEncoding);
258 BufferedReader br = new BufferedReader(reader);
259
260 String eachLine = br.readLine();
261 while (eachLine != null)
262 {
263 sb.append(eachLine);
264 sb.append("\n");
265 eachLine = br.readLine();
266 }
267
268 String template = sb.toString();
269
270 processString(template, model, out);
271 }
272 catch (IOException ioe)
273 {
274 logger.error(ioe);
275 }
276 }
277
278
279
280
281 public void processString(String template, Object model, Writer out)
282 {
283 executePHPScript(template, out, getModel(model));
284 }
285
286
287
288
289 public void reset()
290 {
291 init();
292 }
293
294 }