Source Code Cross Referenced for SignatureParser.java in  » Ajax » dwr » org » directwebremoting » impl » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Ajax » dwr » org.directwebremoting.impl 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2005 Joe Walker
003:         *
004:         * Licensed under the Apache License, Version 2.0 (the "License");
005:         * you may not use this file except in compliance with the License.
006:         * You may obtain a copy of the License at
007:         *
008:         *     http://www.apache.org/licenses/LICENSE-2.0
009:         *
010:         * Unless required by applicable law or agreed to in writing, software
011:         * distributed under the License is distributed on an "AS IS" BASIS,
012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013:         * See the License for the specific language governing permissions and
014:         * limitations under the License.
015:         */
016:        package org.directwebremoting.impl;
017:
018:        import java.lang.reflect.Method;
019:        import java.util.ArrayList;
020:        import java.util.HashMap;
021:        import java.util.List;
022:        import java.util.Map;
023:        import java.util.StringTokenizer;
024:        import java.util.Map.Entry;
025:
026:        import org.apache.commons.logging.Log;
027:        import org.apache.commons.logging.LogFactory;
028:        import org.directwebremoting.extend.ConverterManager;
029:        import org.directwebremoting.extend.Creator;
030:        import org.directwebremoting.extend.CreatorManager;
031:        import org.directwebremoting.extend.TypeHintContext;
032:        import org.directwebremoting.util.LocalUtil;
033:
034:        /**
035:         * A parser for type info in a dwr.xml signature.
036:         * @author Joe Walker [joe at getahead dot ltd dot uk]
037:         */
038:        public class SignatureParser {
039:            /**
040:             * Simple ctor
041:             * @param converterManager Having understood the extra type info we add it in here.
042:             * @param creatorManager If we can't find a class by Java name we can lookup by Javascript name
043:             */
044:            public SignatureParser(ConverterManager converterManager,
045:                    CreatorManager creatorManager) {
046:                this .converterManager = converterManager;
047:                this .creatorManager = creatorManager;
048:
049:                packageImports.add("java.lang");
050:            }
051:
052:            /**
053:             * Parse some text and add it into the converter manager.
054:             * @param sigtext The text to parse
055:             */
056:            public void parse(String sigtext) {
057:                try {
058:                    log.debug("Parsing extra type info: ");
059:
060:                    String reply = LegacyCompressor
061:                            .stripMultiLineComments(sigtext);
062:                    reply = LegacyCompressor.stripSingleLineComments(reply);
063:                    String process = reply;
064:
065:                    process = process.replace('\n', ' ');
066:                    process = process.replace('\r', ' ');
067:                    process = process.replace('\t', ' ');
068:
069:                    StringTokenizer st = new StringTokenizer(process, ";");
070:                    while (st.hasMoreTokens()) {
071:                        String line = st.nextToken();
072:                        line = line.trim();
073:                        if (line.length() == 0) {
074:                            continue;
075:                        }
076:
077:                        if (line.startsWith("import ")) {
078:                            parseImportLine(line);
079:                        } else {
080:                            parseDeclarationLine(line);
081:                        }
082:                    }
083:                } catch (Exception ex) {
084:                    log.error("Unexpected Error", ex);
085:                }
086:            }
087:
088:            /**
089:             * Parse a single import line
090:             * @param line The import statement
091:             */
092:            private void parseImportLine(String line) {
093:                String shortcut = line.substring(7, line.length());
094:                shortcut = shortcut.trim();
095:
096:                if (line.endsWith(".*")) {
097:                    shortcut = shortcut.substring(0, shortcut.length() - 2);
098:                    packageImports.add(shortcut);
099:                } else {
100:                    int lastDot = line.lastIndexOf('.');
101:                    if (lastDot == -1) {
102:                        log.error("Missing . from import statement: " + line);
103:                        return;
104:                    }
105:
106:                    String leaf = line.substring(lastDot + 1);
107:                    classImports.put(leaf, shortcut);
108:                }
109:            }
110:
111:            /**
112:             * Parse a single declaration line.
113:             * Where line is defined as being everything in between 2 ; chars.
114:             * @param line The line to parse
115:             */
116:            private void parseDeclarationLine(String line) {
117:                int openBrace = line.indexOf('(');
118:                int closeBrace = line.indexOf(')');
119:
120:                if (openBrace == -1) {
121:                    log.error("Missing ( in declaration: " + line);
122:                    return;
123:                }
124:
125:                if (closeBrace == -1) {
126:                    log.error("Missing ) in declaration: " + line);
127:                    return;
128:                }
129:
130:                if (openBrace > closeBrace) {
131:                    log.error("( Must come before ) in declaration: " + line);
132:                    return;
133:                }
134:
135:                // Class name and method name come before the opening (
136:                String classMethod = line.substring(0, openBrace).trim();
137:
138:                Method method = findMethod(classMethod);
139:                if (method == null) {
140:                    // Debug is done by findMethod()
141:                    return;
142:                }
143:
144:                // Now we need to get a list of all the parameters
145:                String paramDecl = line.substring(openBrace + 1, closeBrace);
146:                String[] paramNames = split(paramDecl);
147:
148:                // Check that we have the right number
149:                if (method.getParameterTypes().length != paramNames.length) {
150:                    log
151:                            .error("Parameter mismatch parsing signatures section in dwr.xml on line: "
152:                                    + line);
153:                    log.info("- Reflected method had: "
154:                            + method.getParameterTypes().length
155:                            + " parameters: " + method.toString());
156:                    log.info("- Signatures section had: " + paramNames.length
157:                            + " parameters");
158:                    log
159:                            .info("- This can be caused by method overloading which is not supported by Javascript or DWR");
160:                    return;
161:                }
162:
163:                for (int i = 0; i < paramNames.length; i++) {
164:                    String[] genericList = getGenericParameterTypeList(paramNames[i]);
165:                    for (int j = 0; j < genericList.length; j++) {
166:                        String type = genericList[j].trim();
167:                        Class<?> clazz = findClass(type);
168:
169:                        if (clazz != null) {
170:                            TypeHintContext thc = new TypeHintContext(
171:                                    converterManager, method, i)
172:                                    .createChildContext(j);
173:                            converterManager.setExtraTypeInfo(thc, clazz);
174:
175:                            if (log.isDebugEnabled()) {
176:                                log.debug("- " + thc + " = " + clazz.getName());
177:                            }
178:                        } else {
179:                            log
180:                                    .warn("Missing class ("
181:                                            + type
182:                                            + ") while parsing signature section on line: "
183:                                            + line);
184:                        }
185:                    }
186:                }
187:            }
188:
189:            /**
190:             * Lookup a class acording to the import rules
191:             * @param type The name of the class to find
192:             * @return The found class, or null if it does not exist
193:             */
194:            private Class<?> findClass(String type) {
195:                String itype = type;
196:
197:                // Handle inner classes
198:                if (itype.indexOf('.') != -1) {
199:                    log.debug("Inner class detected: " + itype);
200:                    itype = itype.replace('.', '$');
201:                }
202:
203:                try {
204:                    String full = classImports.get(itype);
205:                    if (full == null) {
206:                        full = itype;
207:                    }
208:
209:                    return LocalUtil.classForName(full);
210:                } catch (Exception ex) {
211:                    // log.debug("Trying to find class in package imports");
212:                }
213:
214:                for (String pkg : packageImports) {
215:                    String lookup = pkg + '.' + itype;
216:
217:                    try {
218:                        return LocalUtil.classForName(lookup);
219:                    } catch (Exception ex) {
220:                        // log.debug("Not found: " + lookup);
221:                    }
222:                }
223:
224:                // So we've failed to find a Java class name. We can also lookup by
225:                // Javascript name to help the situation where there is a dynamic proxy
226:                // in the way.
227:                Creator creator = creatorManager.getCreator(type);
228:                if (creator != null) {
229:                    return creator.getType();
230:                }
231:
232:                log.error("Failed to find class: '" + itype
233:                        + "' from <signature> block.");
234:                log.info("- Looked in the following class imports:");
235:                for (Entry<String, String> entry : classImports.entrySet()) {
236:                    log.info("  - " + entry.getKey() + " -> "
237:                            + entry.getValue());
238:                }
239:                log.info("- Looked in the following package imports:");
240:                for (String pkg : packageImports) {
241:                    log.info("  - " + pkg);
242:                }
243:
244:                return null;
245:            }
246:
247:            /**
248:             * Convert a parameter like "Map&lt;Integer, URL&gt;" into an array,
249:             * something like [Integer, URL].
250:             * @param paramName The parameter declaration string
251:             * @return The array of generic types as strings
252:             */
253:            private static String[] getGenericParameterTypeList(String paramName) {
254:                int openGeneric = paramName.indexOf('<');
255:                if (openGeneric == -1) {
256:                    log.debug("No < in paramter declaration: " + paramName);
257:                    return new String[0];
258:                }
259:
260:                int closeGeneric = paramName.lastIndexOf('>');
261:                if (closeGeneric == -1) {
262:                    log.error("Missing > in generic declaration: " + paramName);
263:                    return new String[0];
264:                }
265:
266:                String generics = paramName.substring(openGeneric + 1,
267:                        closeGeneric);
268:                StringTokenizer st = new StringTokenizer(generics, ",");
269:                String[] types = new String[st.countTokens()];
270:                int i = 0;
271:                while (st.hasMoreTokens()) {
272:                    types[i] = st.nextToken();
273:                    i++;
274:                }
275:
276:                return types;
277:            }
278:
279:            /**
280:             * Find a method from the declaration string
281:             * @param classMethod The declaration that comes before the (
282:             * @return The found method, or null if one was not found.
283:             */
284:            private Method findMethod(String classMethod) {
285:                String classMethodChop = classMethod;
286:
287:                // If there is a return type then it must be before the last space.
288:                int lastSpace = classMethodChop.lastIndexOf(' ');
289:                if (lastSpace >= 0) {
290:                    classMethodChop = classMethodChop.substring(lastSpace);
291:                }
292:
293:                // The method name comes after the last .
294:                int lastDot = classMethodChop.lastIndexOf('.');
295:                if (lastDot == -1) {
296:                    log.error("Missing . to separate class name and method: "
297:                            + classMethodChop);
298:                    return null;
299:                }
300:
301:                String className = classMethodChop.substring(0, lastDot).trim();
302:                String methodName = classMethodChop.substring(lastDot + 1)
303:                        .trim();
304:
305:                Class<?> clazz = findClass(className);
306:                if (clazz == null) {
307:                    // Debug is done by findClass()
308:                    return null;
309:                }
310:
311:                Method method = null;
312:                Method[] methods = clazz.getMethods();
313:                for (Method test : methods) {
314:                    if (test.getName().equals(methodName)) {
315:                        if (method == null) {
316:                            method = test;
317:                        } else {
318:                            log
319:                                    .warn("Setting extra type info to overloaded methods may fail with <parameter .../>");
320:                        }
321:                    }
322:                }
323:
324:                if (method == null) {
325:                    log.error("Unable to find method called: " + methodName
326:                            + " on type: " + clazz.getName());
327:                }
328:
329:                return method;
330:            }
331:
332:            /**
333:             * Chop a parameter declaration string into separate parameters
334:             * @param paramDecl The full set of parameter declarations
335:             * @return An array of found parameters
336:             */
337:            private static String[] split(String paramDecl) {
338:                List<String> params = new ArrayList<String>();
339:
340:                boolean inGeneric = false;
341:                int start = 0;
342:                for (int i = 0; i < paramDecl.length(); i++) {
343:                    char c = paramDecl.charAt(i);
344:                    if (c == '<') {
345:                        if (inGeneric) {
346:                            log.error("Found < while parsing generic section: "
347:                                    + paramDecl);
348:                            break;
349:                        }
350:
351:                        inGeneric = true;
352:                    }
353:
354:                    if (c == '>') {
355:                        if (!inGeneric) {
356:                            log
357:                                    .error("Found > while not parsing generic section: "
358:                                            + paramDecl);
359:                            break;
360:                        }
361:
362:                        inGeneric = false;
363:                    }
364:
365:                    if (!inGeneric && c == ',') {
366:                        // This is the start of a new parameter
367:                        String param = paramDecl.substring(start, i);
368:                        params.add(param);
369:                        start = i + 1;
370:                    }
371:                }
372:
373:                // Add in the bit at the end:
374:                String param = paramDecl.substring(start, paramDecl.length());
375:                params.add(param);
376:
377:                return params.toArray(new String[params.size()]);
378:            }
379:
380:            /**
381:             * The map of specific class imports that we have parsed.
382:             */
383:            private Map<String, String> classImports = new HashMap<String, String>();
384:
385:            /**
386:             * The map of package imports that we have parsed.
387:             */
388:            private List<String> packageImports = new ArrayList<String>();
389:
390:            /**
391:             * Having understood the extra type info we add it in here.
392:             */
393:            private ConverterManager converterManager;
394:
395:            /**
396:             * If we can't find a class by Java name we can lookup by Javascript name
397:             */
398:            private CreatorManager creatorManager;
399:
400:            /**
401:             * The log stream
402:             */
403:            public static final Log log = LogFactory
404:                    .getLog(SignatureParser.class);
405:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.