KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > directwebremoting > impl > DefaultDebugPageGenerator


1 /*
2  * Copyright 2005 Joe Walker
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.directwebremoting.impl;
17
18 import java.io.BufferedReader JavaDoc;
19 import java.io.IOException JavaDoc;
20 import java.io.InputStream JavaDoc;
21 import java.io.InputStreamReader JavaDoc;
22 import java.lang.reflect.Method JavaDoc;
23 import java.util.Arrays JavaDoc;
24 import java.util.Collection JavaDoc;
25 import java.util.Collections JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.Map JavaDoc;
29
30 import org.directwebremoting.extend.AccessControl;
31 import org.directwebremoting.extend.ConverterManager;
32 import org.directwebremoting.extend.Creator;
33 import org.directwebremoting.extend.CreatorManager;
34 import org.directwebremoting.extend.DebugPageGenerator;
35 import org.directwebremoting.extend.DwrConstants;
36 import org.directwebremoting.servlet.EngineHandler;
37 import org.directwebremoting.servlet.PathConstants;
38 import org.directwebremoting.servlet.UtilHandler;
39 import org.directwebremoting.util.JavascriptUtil;
40 import org.directwebremoting.util.LocalUtil;
41 import org.directwebremoting.util.Logger;
42 import org.directwebremoting.util.Messages;
43
44 /**
45  * A default implementation of TestPageGenerator
46  * @author Joe Walker [joe at getahead dot ltd dot uk]
47  */

48 public class DefaultDebugPageGenerator implements DebugPageGenerator
49 {
50     /* (non-Javadoc)
51      * @see org.directwebremoting.DebugPageGenerator#generateIndexPage(java.lang.String)
52      */

53     public String JavaDoc generateIndexPage(final String JavaDoc root) throws SecurityException JavaDoc
54     {
55         if (!creatorManager.isDebug())
56         {
57             log.warn("Failed attempt to access test pages outside of debug mode. Set the debug init-parameter to true to enable.");
58             throw new SecurityException JavaDoc(Messages.getString("DefaultDebugPageGenerator.AccessDenied"));
59         }
60
61         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
62
63         buffer.append("<html>\n");
64         buffer.append("<head><title>DWR Test Index</title></head>\n");
65         buffer.append("<body>\n");
66
67         buffer.append("<h2>Classes known to DWR:</h2>\n");
68         buffer.append("<ul>\n");
69         for (Iterator JavaDoc it = creatorManager.getCreatorNames().iterator(); it.hasNext();)
70         {
71             String JavaDoc name = (String JavaDoc) it.next();
72             Creator creator = creatorManager.getCreator(name);
73
74             buffer.append("<li><a HREF='");
75             buffer.append(root);
76             buffer.append(testHandlerUrl);
77             buffer.append(name);
78             buffer.append("'>");
79             buffer.append(name);
80             buffer.append("</a> (");
81             buffer.append(creator.getType().getName());
82             buffer.append(")</li>\n");
83         }
84         buffer.append("</ul>\n");
85
86         buffer.append("</body></html>\n");
87
88         return buffer.toString();
89     }
90
91     /* (non-Javadoc)
92      * @see org.directwebremoting.DebugPageGenerator#generateTestPage(java.lang.String, java.lang.String)
93      */

94     public String JavaDoc generateTestPage(final String JavaDoc root, final String JavaDoc scriptName) throws SecurityException JavaDoc
95     {
96         if (!creatorManager.isDebug())
97         {
98             log.warn("Failed attempt to access test pages outside of debug mode. Set the debug init-parameter to true to enable.");
99             throw new SecurityException JavaDoc(Messages.getString("DefaultAccessControl.AccessDenied"));
100         }
101
102         String JavaDoc interfaceURL = root + interfaceHandlerUrl + scriptName + PathConstants.EXTENSION_JS;
103         String JavaDoc engineURL = root + engineHandlerUrl;
104         String JavaDoc utilURL = root + utilHandlerUrl;
105
106         String JavaDoc proxyInterfaceURL = PATH_UP + interfaceHandlerUrl + scriptName + PathConstants.EXTENSION_JS;
107         String JavaDoc proxyEngineURL = PATH_UP + engineHandlerUrl;
108         String JavaDoc proxyUtilURL = PATH_UP + utilHandlerUrl;
109
110         Creator creator = creatorManager.getCreator(scriptName);
111         Method JavaDoc[] methods = creator.getType().getMethods();
112         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
113
114         buffer.append("<html>\n");
115         buffer.append("<head>\n");
116         buffer.append(" <title>DWR Test</title>\n");
117         buffer.append(" <!-- These paths use .. so that they still work behind a path mapping proxy. The fully qualified version is more cut and paste friendly. -->\n");
118         buffer.append(" <script type='text/javascript' SRC='" + proxyInterfaceURL + "'></script>\n");
119         buffer.append(" <script type='text/javascript' SRC='" + proxyEngineURL + "'></script>\n");
120         buffer.append(" <script type='text/javascript' SRC='" + proxyUtilURL + "'></script>\n");
121         buffer.append(" <script type='text/javascript'>\n");
122         buffer.append(" function objectEval(text)\n");
123         buffer.append(" {\n");
124         buffer.append(" // eval() breaks when we use it to get an object using the { a:42, b:'x' }\n");
125         buffer.append(" // syntax because it thinks that { and } surround a block and not an object\n");
126         buffer.append(" // So we wrap it in an array and extract the first element to get around\n");
127         buffer.append(" // this.\n");
128         buffer.append(" // This code is only needed for interpreting the parameter input fields,\n");
129         buffer.append(" // so you can ignore this for normal use.\n");
130         buffer.append(" // The regex = [start of line][whitespace]{[stuff]}[whitespace][end of line]\n");
131         buffer.append(" text = text.replace(/\\n/g, ' ');\n");
132         buffer.append(" text = text.replace(/\\r/g, ' ');\n");
133         buffer.append(" if (text.match(/^\\s*\\{.*\\}\\s*$/))\n");
134         buffer.append(" {\n");
135         buffer.append(" text = '[' + text + '][0]';\n");
136         buffer.append(" }\n");
137         buffer.append(" return eval(text);\n");
138         buffer.append(" }\n");
139         buffer.append(" </script>\n");
140         buffer.append(" <style>\n");
141         buffer.append(" input.itext { font-size: smaller; background: #E4E4E4; border: 0; }\n");
142         buffer.append(" input.ibutton { font-size: xx-small; border: 1px outset; margin: 0px; padding: 0px; }\n");
143         buffer.append(" span.reply { background: #ffffdd; white-space: pre; }\n");
144         buffer.append(" span.warning { font-size: smaller; color: red; }\n");
145         buffer.append(" </style>\n");
146         buffer.append("</head>\n");
147         buffer.append("<body onload='dwr.util.useLoadingMessage()'>\n");
148         buffer.append(BLANK);
149
150         buffer.append("<h2>Methods For: " + scriptName + " (" + creator.getType().getName() + ")</h2>\n");
151         buffer.append("<p>To use this class in your javascript you will need the following script includes:</p>\n");
152         buffer.append("<pre>\n");
153         buffer.append(" &lt;script type='text/javascript' SRC='<a HREF='" + interfaceURL + "'>" + interfaceURL + "</a>'&gt;&lt;/script&gt;\n");
154         buffer.append(" &lt;script type='text/javascript' SRC='<a HREF='" + engineURL + "'>" + engineURL + "</a>'&gt;&lt;/script&gt;\n");
155         buffer.append("</pre>\n");
156
157         buffer.append("<p>In addition there is an optional utility script:</p>\n");
158         buffer.append("<pre>\n");
159         buffer.append(" &lt;script type='text/javascript' SRC='<a HREF='" + utilURL + "'>" + utilURL + "</a>'&gt;&lt;/script&gt;\n");
160         buffer.append("</pre>\n");
161
162         buffer.append("<p>Replies from DWR are shown with a yellow background if they are simple or in an alert box otherwise.<br/>\n");
163         buffer.append("The inputs are evaluated as Javascript so strings must be quoted before execution.</p>\n");
164
165         buffer.append("<p>There are " + methods.length + " declared methods:</p><ul>\n");
166
167         for (int i = 0; i < methods.length; i++)
168         {
169             Method JavaDoc method = methods[i];
170             String JavaDoc methodName = method.getName();
171
172             // Is it on the list of banned names
173
if (JavascriptUtil.isReservedWord(methodName))
174             {
175                 buffer.append(BLANK);
176                 buffer.append("<li style='color: #88A;'>" + methodName + "() is not available because it is a reserved word.</li>\n");
177                 continue;
178             }
179
180             buffer.append(BLANK);
181             buffer.append("<li>\n");
182             buffer.append(" " + methodName + '(');
183
184             Class JavaDoc[] paramTypes = method.getParameterTypes();
185             for (int j = 0; j < paramTypes.length; j++)
186             {
187                 Class JavaDoc paramType = paramTypes[j];
188
189                 // The special type that we handle transparently
190
if (LocalUtil.isServletClass(paramType))
191                 {
192                     buffer.append("AUTO");
193                 }
194                 else
195                 {
196                     String JavaDoc value = BLANK;
197                     if (paramType == String JavaDoc.class)
198                     {
199                         value = "\"\"";
200                     }
201                     else if (paramType == Boolean JavaDoc.class || paramType == Boolean.TYPE)
202                     {
203                         value = "true";
204                     }
205                     else if (paramType == Integer JavaDoc.class || paramType == Integer.TYPE || paramType == Short JavaDoc.class || paramType == Short.TYPE
206                         || paramType == Long JavaDoc.class || paramType == Long.TYPE || paramType == Byte JavaDoc.class || paramType == Byte.TYPE)
207                     {
208                         value = "0";
209                     }
210                     else if (paramType == Float JavaDoc.class || paramType == Float.TYPE || paramType == Double JavaDoc.class || paramType == Double.TYPE)
211                     {
212                         value = "0.0";
213                     }
214                     else if (paramType.isArray() || Collection JavaDoc.class.isAssignableFrom(paramType))
215                     {
216                         value = "[]";
217                     }
218                     else if (Map JavaDoc.class.isAssignableFrom(paramType))
219                     {
220                         value = "{}";
221                     }
222
223                     buffer.append(" <input class='itext' type='text' size='10' value='" + value + "' id='p" + i + j + "' title='Will be converted to: " + paramType.getName() + "'/>");
224                 }
225
226                 buffer.append(j == paramTypes.length - 1 ? BLANK : ", \n");
227             }
228             buffer.append(" );\n");
229
230             String JavaDoc onclick = scriptName + '.' + methodName + "(";
231             for (int j = 0; j < paramTypes.length; j++)
232             {
233                 if (!LocalUtil.isServletClass(paramTypes[j]))
234                 {
235                     onclick += "objectEval($(\"p" + i + j + "\").value), ";
236                 }
237             }
238             onclick += "reply" + i + ");";
239
240             buffer.append(" <input class='ibutton' type='button' onclick='" + onclick + "' value='Execute' title='Calls " + scriptName + '.' + methodName + "(). View source for details.'/>\n");
241
242             buffer.append(" <script type='text/javascript'>\n");
243             buffer.append(" var reply" + i + " = function(data)\n");
244             buffer.append(" {\n");
245             buffer.append(" if (data != null && typeof data == 'object') alert(dwr.util.toDescriptiveString(data, 2));\n");
246             buffer.append(" else dwr.util.setValue('d" + i + "', dwr.util.toDescriptiveString(data, 1));\n");
247             buffer.append(" }\n");
248             buffer.append(" </script>\n");
249             buffer.append(" <span id='d" + i + "' class='reply'></span>\n");
250
251             // Print a warning if this method is overloaded
252
boolean overloaded = false;
253             for (int j = 0; j < methods.length; j++)
254             {
255                 if (j != i && methods[j].getName().equals(methodName))
256                 {
257                     overloaded = true;
258                 }
259             }
260             if (overloaded)
261             {
262                 buffer.append("<br/><span class='warning'>(Warning: overloaded methods are not recommended. See <a HREF='#overloadedMethod'>below</a>)</span>\n");
263             }
264
265             // Print a warning if the method uses un-marshallable types
266
for (int j = 0; j < paramTypes.length; j++)
267             {
268                 if (!converterManager.isConvertable(paramTypes[j]))
269                 {
270                     buffer.append("<br/><span class='warning'>(Warning: No Converter for " + paramTypes[j].getName() + ". See <a HREF='#missingConverter'>below</a>)</span>\n");
271                 }
272             }
273
274             if (!converterManager.isConvertable(method.getReturnType()))
275             {
276                 buffer.append("<br/><span class='warning'>(Warning: No Converter for " + method.getReturnType().getName() + ". See <a HREF='#missingConverter'>below</a>)</span>\n");
277             }
278
279             // See also the call to getReasonToNotExecute() above
280
try
281             {
282                 accessControl.assertIsDisplayable(creator, scriptName, method);
283             }
284             catch (SecurityException JavaDoc ex)
285             {
286                 buffer.append("<br/><span class='warning'>(Warning: " + methodName + "() is excluded: " + ex.getMessage() + ". See <a HREF='#excludedMethod'>below</a>)</span>\n");
287             }
288
289             // We don't need to call assertExecutionIsPossible() because those
290
// checks should be done by assertIsDisplayable() above
291
// accessControl.assertExecutionIsPossible(creator, scriptName, method);
292

293             buffer.append("</li>\n");
294         }
295
296         buffer.append(BLANK);
297         buffer.append("</ul>\n");
298
299         buffer.append("<h2>Other Links</h2>\n");
300         buffer.append("<ul>\n");
301         buffer.append("<li>Back to <a HREF='" + root + "/'>class index</a>.</li>\n");
302         buffer.append("</ul>\n");
303
304         synchronized (scriptCache)
305         {
306             String JavaDoc output = (String JavaDoc) scriptCache.get(PathConstants.FILE_HELP);
307             if (output == null)
308             {
309                 InputStream JavaDoc raw = getClass().getResourceAsStream(DwrConstants.PACKAGE + PathConstants.FILE_HELP);
310                 if (raw == null)
311                 {
312                     log.error(Messages.getString("DefaultProcessor.MissingHelp", PathConstants.FILE_HELP));
313                     output = "<p>Failed to read help text from resource file. Check dwr.jar is built to include html files.</p>";
314                 }
315                 else
316                 {
317                     StringBuffer JavaDoc fileBuffer = new StringBuffer JavaDoc();
318
319                     BufferedReader JavaDoc in = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(raw));
320                     while (true)
321                     {
322                         try
323                         {
324                             String JavaDoc line = in.readLine();
325                             if (line == null)
326                             {
327                                 break;
328                             }
329
330                             fileBuffer.append(line);
331                             fileBuffer.append('\n');
332                         }
333                         catch (IOException JavaDoc ex)
334                         {
335                             fileBuffer.append(ex.toString());
336                             fileBuffer.append('\n');
337                             break;
338                         }
339                     }
340
341                     output = fileBuffer.toString();
342                 }
343
344                 scriptCache.put(PathConstants.FILE_HELP, output);
345             }
346
347             buffer.append(output);
348         }
349
350         buffer.append("</body></html>\n");
351
352         return buffer.toString();
353     }
354
355     /* (non-Javadoc)
356      * @see org.directwebremoting.DebugPageGenerator#generateInterfaceUrl(java.lang.String, java.lang.String)
357      */

358     public String JavaDoc generateInterfaceUrl(String JavaDoc root, String JavaDoc scriptName)
359     {
360         return root + interfaceHandlerUrl + scriptName + PathConstants.EXTENSION_JS;
361     }
362
363     /* (non-Javadoc)
364      * @see org.directwebremoting.DebugPageGenerator#generateEngineUrl(java.lang.String)
365      */

366     public String JavaDoc generateEngineUrl(String JavaDoc root)
367     {
368         return root + engineHandlerUrl;
369     }
370
371     /* (non-Javadoc)
372      * @see org.directwebremoting.DebugPageGenerator#generateLibraryUrl(java.lang.String, java.lang.String)
373      */

374     public String JavaDoc generateLibraryUrl(String JavaDoc root, String JavaDoc library)
375     {
376         return root + library;
377     }
378
379     /* (non-Javadoc)
380      * @see org.directwebremoting.DebugPageGenerator#getAvailableLibraries()
381      */

382     public Collection JavaDoc getAvailableLibraries()
383     {
384         if (availableLibraries == null)
385         {
386             availableLibraries = Collections.unmodifiableCollection(Arrays.asList(new String JavaDoc[] { utilHandlerUrl }));
387         }
388
389         return availableLibraries;
390     }
391
392     /**
393      * Accessor for the DefaultCreatorManager that we configure
394      * @param converterManager The new DefaultConverterManager
395      */

396     public void setConverterManager(ConverterManager converterManager)
397     {
398         this.converterManager = converterManager;
399     }
400
401     /**
402      * Accessor for the DefaultCreatorManager that we configure
403      * @param creatorManager The new DefaultConverterManager
404      */

405     public void setCreatorManager(CreatorManager creatorManager)
406     {
407         this.creatorManager = creatorManager;
408     }
409
410     /**
411      * Accessor for the security manager
412      * @param accessControl The accessControl to set.
413      */

414     public void setAccessControl(AccessControl accessControl)
415     {
416         this.accessControl = accessControl;
417     }
418
419     /**
420      * @param engineHandlerUrl the engineHandlerUrl to set
421      */

422     public void setEngineHandlerUrl(String JavaDoc engineHandlerUrl)
423     {
424         this.engineHandlerUrl = engineHandlerUrl;
425     }
426
427     /**
428      * @param utilHandlerUrl the utilHandlerUrl to set
429      */

430     public void setUtilHandlerUrl(String JavaDoc utilHandlerUrl)
431     {
432         this.utilHandlerUrl = utilHandlerUrl;
433     }
434
435     /**
436      * @param testHandlerUrl the testHandlerUrl to set
437      */

438     public void setTestHandlerUrl(String JavaDoc testHandlerUrl)
439     {
440         this.testHandlerUrl = testHandlerUrl;
441     }
442
443     /**
444      * Setter for the URL that this handler available on
445      * @param interfaceHandlerUrl the interfaceHandlerUrl to set
446      */

447     public void setInterfaceHandlerUrl(String JavaDoc interfaceHandlerUrl)
448     {
449         this.interfaceHandlerUrl = interfaceHandlerUrl;
450     }
451
452     /**
453      * The URL for the {@link EngineHandler}
454      */

455     protected String JavaDoc engineHandlerUrl;
456
457     /**
458      * The URL for the {@link UtilHandler}
459      */

460     protected String JavaDoc utilHandlerUrl;
461
462     /**
463      * The URL for the {@link UtilHandler}
464      */

465     protected String JavaDoc testHandlerUrl;
466
467     /**
468      * What URL is this handler available on?
469      */

470     protected String JavaDoc interfaceHandlerUrl;
471
472     /**
473      * How we convert parameters
474      */

475     protected ConverterManager converterManager = null;
476
477     /**
478      * How we create new beans
479      */

480     protected CreatorManager creatorManager = null;
481
482     /**
483      * The security manager
484      */

485     protected AccessControl accessControl = null;
486
487     /**
488      * We cache the script output for speed
489      */

490     protected final Map JavaDoc scriptCache = new HashMap JavaDoc();
491
492     /**
493      * For getAvailableLibraries() - just a RO Collection that currently returns
494      * only util.js, but may be expanded in the future.
495      */

496     private Collection JavaDoc availableLibraries = null;
497
498     /**
499      * 2 dots
500      */

501     private static final String JavaDoc PATH_UP = "..";
502
503     /**
504      * Empty string
505      */

506     public static final String JavaDoc BLANK = "";
507
508     /**
509      * The log stream
510      */

511     private static final Logger log = Logger.getLogger(DefaultDebugPageGenerator.class);
512 }
513
Popular Tags