Source Code Cross Referenced for JxpProcessor.java in  » Template-Engine » jxp » org » onemind » jxp » 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 » Template Engine » jxp » org.onemind.jxp 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright (C) 2004 TiongHiang Lee
0003:         *
0004:         * This library is free software; you can redistribute it and/or
0005:         * modify it under the terms of the GNU Lesser General Public
0006:         * License as published by the Free Software Foundation; either
0007:         * version 2.1 of the License, or (at your option) any later version.
0008:         *
0009:         * This library is distributed in the hope that it will be useful,
0010:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0012:         * Lesser General Public License for more details.
0013:         *
0014:         * You should have received a copy of the GNU Lesser General Public
0015:         * License along with this library; if not,  write to the Free Software
0016:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
0017:         *
0018:         * Email: thlee@onemindsoft.org
0019:         */
0020:
0021:        package org.onemind.jxp;
0022:
0023:        import java.io.*;
0024:        import java.lang.reflect.*;
0025:        import java.util.*;
0026:        import java.util.logging.Level;
0027:        import java.util.logging.Logger;
0028:        import org.onemind.commons.invoke.InvocableFunction;
0029:        import org.onemind.commons.java.datastructure.NametableStack;
0030:        import org.onemind.commons.java.datastructure.ThreadLocalStack;
0031:        import org.onemind.commons.java.lang.reflect.ReflectUtils;
0032:        import org.onemind.commons.java.util.*;
0033:        import org.onemind.jxp.parser.*;
0034:        import org.onemind.jxp.util.StaticImport;
0035:        import org.onemind.jxp.util.StaticImportUtils;
0036:
0037:        /**
0038:         * The jxp processor
0039:         * @author TiongHiang Lee (thlee@onemindsoft.org)
0040:         * 
0041:         */
0042:        public class JxpProcessor implements  JxpParserVisitor {
0043:
0044:            /** the logger * */
0045:            private static final Logger _logger = Logger
0046:                    .getLogger(JxpProcessor.class.getName());
0047:
0048:            /** represent ONE * */
0049:            private static final Integer ONE = new Integer(1);
0050:
0051:            /** contains zero values for primitive **/
0052:            private static final Map PRIMITIVE_DEFAULTS = new HashMap();
0053:            static {
0054:                PRIMITIVE_DEFAULTS.put(Integer.TYPE, new Integer(0));
0055:                PRIMITIVE_DEFAULTS.put(Long.TYPE, new Long(0));
0056:                PRIMITIVE_DEFAULTS.put(Float.TYPE, new Float(0));
0057:                PRIMITIVE_DEFAULTS.put(Double.TYPE, new Double(0));
0058:                PRIMITIVE_DEFAULTS.put(Character.TYPE, new Character((char) 0));
0059:                PRIMITIVE_DEFAULTS.put(Byte.TYPE, new Byte((byte) 0));
0060:                PRIMITIVE_DEFAULTS.put(Boolean.TYPE, Boolean.FALSE);
0061:            }
0062:
0063:            /**
0064:             * process a file
0065:             * @param args the arguments
0066:             * @throws Exception if exception
0067:             */
0068:            public static void main(String[] args) throws Exception {
0069:                if (args.length != 2) {
0070:                    System.out
0071:                            .println("Usage: java org.onemind.jxp.JxpProcessor <source dir> <page>");
0072:                } else {
0073:                    FilePageSource source = new FilePageSource(args[0]);
0074:                    JxpContext context = new JxpContext(source);
0075:                    JxpProcessor processor = new JxpProcessor(context);
0076:                    Writer writer = new OutputStreamWriter(System.out);
0077:                    try {
0078:                        processor.process(args[1], writer,
0079:                                Collections.EMPTY_MAP);
0080:                    } catch (Exception e) {
0081:                        e.printStackTrace();
0082:                    }
0083:                    writer.flush();
0084:                }
0085:            }
0086:
0087:            /**
0088:             * Represents a user defined function
0089:             * @author TiongHiang Lee (thlee@onemindsoft.org)
0090:             * 
0091:             */
0092:            private class JxpUserDefinedFunction {
0093:
0094:                /** the declarator **/
0095:                private SimpleNode _paramSpec;
0096:
0097:                /** the block **/
0098:                private AstBlock _block;
0099:
0100:                /**
0101:                 * Constructor
0102:                 * @param dec the declarator
0103:                 * @param block the function block
0104:                 */
0105:                public JxpUserDefinedFunction(SimpleNode paramSpec,
0106:                        AstBlock block) {
0107:                    _paramSpec = paramSpec;
0108:                    _block = block;
0109:                }
0110:
0111:                /**
0112:                 * Get the declarator
0113:                 * @return the declarator
0114:                 */
0115:                public SimpleNode getParameterSpec() {
0116:                    return _paramSpec;
0117:                }
0118:
0119:                /**
0120:                 * Get the block
0121:                 * @return the block
0122:                 */
0123:                public AstBlock getBlock() {
0124:                    return _block;
0125:                }
0126:            }
0127:
0128:            /** a context local keep tracks of current processing context * */
0129:            private ThreadLocalStack _contextLocal = new ThreadLocalStack();
0130:
0131:            /** the jxp page source * */
0132:            private JxpContext _context;
0133:
0134:            /** whether do method status **/
0135:            //TODO: add as config options
0136:            private boolean doMethodStats;
0137:
0138:            /** whether to check function argument type **/
0139:            private boolean _checkFunctionArgumentType = false;
0140:
0141:            /** the method statistic counter **/
0142:            private final Counter _methodStats = new Counter();
0143:
0144:            /**
0145:             * Constructor
0146:             * @param source the page source
0147:             */
0148:            public JxpProcessor(JxpContext context) {
0149:                _context = context;
0150:            }
0151:
0152:            /**
0153:             * Get the source
0154:             * @return the source
0155:             */
0156:            public final JxpContext getContext() {
0157:                return _context;
0158:            }
0159:
0160:            /**
0161:             * Assign the value assignable target node to the value
0162:             * @param node the assignable target
0163:             * @param value the value to assign
0164:             * @return the value assinged
0165:             * @throws ProcessingException if the node is not an assignable
0166:             */
0167:            protected Object assign(SimpleNode node, Object value)
0168:                    throws ProcessingException {
0169:                Object target = resolveAssignmentTarget(node, true);
0170:                if (target instanceof  Assignable) {
0171:                    return ((Assignable) target).assign(value);
0172:                } else {
0173:                    return generateProcessingException(
0174:                            new IllegalArgumentException(node
0175:                                    + " is not assignable"), node);
0176:                }
0177:            }
0178:
0179:            /**
0180:             * Assign a variable in a current nametable stack to the value
0181:             * @param name the variable name
0182:             * @param value the value
0183:             * @return the value assigned
0184:             */
0185:            protected Object assignVariable(String name, Object value) {
0186:                NametableStack ntStack = getCurrentContext()
0187:                        .getNametableStack();
0188:                ntStack.assign(name, value);
0189:                return value;
0190:            }
0191:
0192:            /**
0193:             * Call the function of the processor. Call predefined print or println if the method name matched. Otherwise, reflection will
0194:             * be used on the processor to invoke method
0195:             * @param methodName the method name
0196:             * @param args the arguments
0197:             * @return the value returned by the method call
0198:             * @throws Exception if there's problem calling method
0199:             */
0200:            protected Object callFunction(String methodName, Object[] args)
0201:                    throws Exception {
0202:                //built-in functions
0203:                if (methodName.equals("print")) {
0204:                    print(args[0]);
0205:                    return null;
0206:                } else if (methodName.equals("println")) {
0207:                    println(args[0]);
0208:                    return null;
0209:                } else if (methodName.equals("getJxpEnvironment")) {
0210:                    return getEnvironment();
0211:                } else {
0212:                    JxpProcessingContext context = getCurrentContext();
0213:                    String functionName = methodName;
0214:                    if (context.getUserDefinedFunctions().containsKey(
0215:                            functionName)) {
0216:                        JxpUserDefinedFunction function = (JxpUserDefinedFunction) context
0217:                                .getUserDefinedFunctions().get(functionName);
0218:                        NametableStack nt = context.getNametableStack();
0219:                        int scope = nt.newLocalScope();
0220:                        declareFunctionLocals(functionName, function
0221:                                .getParameterSpec(), args);
0222:                        try {
0223:                            Object obj = function.getBlock().jjtAccept(this ,
0224:                                    null);
0225:                            if (obj == Control.EXIT) {
0226:                                return obj;
0227:                            } else if (obj instanceof  Control) //return value
0228:                            {
0229:                                return ((Control) obj).getObject();
0230:                            } else {
0231:                                return obj;
0232:                            }
0233:                        } finally {
0234:                            nt.closeLocalScope(scope);
0235:                        }
0236:                    } else {
0237:                        //try static import
0238:                        List staticImports = context.getStaticImports();
0239:                        Iterator it = staticImports.iterator();
0240:                        while (it.hasNext()) {
0241:                            StaticImport sImport = (StaticImport) it.next();
0242:                            InvocableFunction func = sImport.getFunction(
0243:                                    functionName, args);
0244:                            if (func != null) {
0245:                                return func.invoke(null, args);
0246:                            }
0247:                        }
0248:                        //lastly, throw exception
0249:                        throw new NoSuchMethodException("Method " + methodName
0250:                                + " not found for the Processor");
0251:                    }
0252:                }
0253:            }
0254:
0255:            /**
0256:             * Create the function environment
0257:             * @param params the parameters
0258:             * @param args the arguments
0259:             */
0260:            public void declareFunctionLocals(String functionName,
0261:                    SimpleNode params, Object[] args) throws Exception {
0262:                NametableStack ntStack = getCurrentContext()
0263:                        .getNametableStack();
0264:                int n = params.jjtGetNumChildren();
0265:                Map defaults = new HashMap();
0266:                for (int i = 0; i < args.length; i++) {
0267:                    if (args[i] instanceof  AstNamedArgument) {
0268:                        SimpleNode arg = (SimpleNode) args[i];
0269:                        Object value = arg.jjtGetChild(0).jjtAccept(this , null);
0270:                        defaults.put(arg.getData(), value);
0271:                    }
0272:                }
0273:                if (params instanceof  AstFormalParameters) {
0274:                    for (int i = 0; i < n; i++) {
0275:                        AstFormalParameter param = (AstFormalParameter) params
0276:                                .jjtGetChild(i);
0277:                        AstVariableDeclaratorId id = (AstVariableDeclaratorId) param
0278:                                .jjtGetChild(1);
0279:                        AstType type = (AstType) param.jjtGetChild(0);
0280:                        Class paramType = (Class) type.jjtAccept(this , null);
0281:
0282:                        if (param.jjtGetNumChildren() == 2) {//no defaults
0283:                            if (args.length <= i) {
0284:                                throw new IllegalArgumentException(
0285:                                        "Mismatch number of arguments");
0286:                            } else if (args[i] instanceof  AstNamedArgument) {
0287:                                throw new IllegalArgumentException(
0288:                                        "Expecting required paramater "
0289:                                                + id.getData()
0290:                                                + " for function "
0291:                                                + functionName);
0292:                            } else {
0293:                                if (_checkFunctionArgumentType) {//do type checking                   
0294:                                    if (paramType.isPrimitive()) {
0295:                                        if (args[i] == null) {
0296:                                            throw new IllegalArgumentException(
0297:                                                    "Primitive argument "
0298:                                                            + id.getData()
0299:                                                            + " cannot be null");
0300:                                        } else if (!ReflectUtils
0301:                                                .isPrimitiveInstance(paramType,
0302:                                                        args[i])) {
0303:                                            throw new IllegalArgumentException(
0304:                                                    "Mismatch argument type for "
0305:                                                            + id.getData()
0306:                                                            + ". Expecting "
0307:                                                            + paramType
0308:                                                                    .getName());
0309:                                        }
0310:                                    } else if (args[i] != null) {
0311:                                        if (!paramType.isInstance(args[i])) {
0312:                                            throw new IllegalArgumentException(
0313:                                                    "Mismatch argument type for "
0314:                                                            + id.getData()
0315:                                                            + ". Expecting "
0316:                                                            + paramType
0317:                                                                    .getName());
0318:                                        }
0319:                                    }
0320:
0321:                                }
0322:                                ntStack.declare((String) id.getData(), args[i]);
0323:                            }
0324:                        } else {//has default                    
0325:                            if (defaults.containsKey(id.getData())) {
0326:                                Object value = defaults.remove(id.getData());
0327:                                ntStack.declare((String) id.getData(), value);
0328:                            } else {
0329:                                if (i >= args.length
0330:                                        || args[i] instanceof  AstNamedArgument) {
0331:                                    Object value = param.jjtGetChild(2)
0332:                                            .jjtAccept(this , null);
0333:                                    ntStack.declare((String) id.getData(),
0334:                                            value);
0335:                                } else {
0336:                                    ntStack.declare((String) id.getData(),
0337:                                            args[i]);
0338:                                }
0339:                            }
0340:                        }
0341:                    }
0342:                    if (defaults.size() > 0) {
0343:                        throw new IllegalArgumentException("Unknown default "
0344:                                + defaults + " for function " + functionName);
0345:                    }
0346:                } else {//assume variable parameters (varargs)
0347:                    ntStack.declare((String) params.getData(), args);
0348:                }
0349:            }
0350:
0351:            /**
0352:             * Throws the exception
0353:             * @param e the throwable
0354:             * @param node the node that the exception current
0355:             * @return will not return since exception will always be thrown
0356:             */
0357:            private ProcessingException generateProcessingException(
0358:                    Throwable e, SimpleNode node) {
0359:                ProcessingException ex = new ProcessingException(
0360:                        getCurrentContext().getCurrentPage(), e, node);
0361:                return ex;
0362:            }
0363:
0364:            /**
0365:             * Include another page as a part of current page and process it
0366:             * @param id the id
0367:             * @return the object
0368:             * @throws Exception if there's exception
0369:             */
0370:            protected Object includeCall(String id) throws Exception {
0371:                return process(id, getCurrentContext());
0372:            }
0373:
0374:            /**
0375:             * Instantiate an instance of class type using the arguments
0376:             * @param type the type to instantiate
0377:             * @param args the arguments
0378:             * @return the object instantiated
0379:             * @throws Exception if there's problem in the instantiation
0380:             */
0381:            protected Object instantiate(Class type, Object[] args)
0382:                    throws Exception {
0383:                if (_logger.isLoggable(Level.FINEST)) {
0384:                    _logger.finest("Instantiaing " + type + " with "
0385:                            + StringUtils.concat(args, ","));
0386:                }
0387:                return ReflectUtils.newInstance(type, args);
0388:            }
0389:
0390:            /**
0391:             * Invoke the method of object obj with given argument
0392:             * @param obj the object
0393:             * @param methodName the method name
0394:             * @param args the arguments
0395:             * @return the value return by the method invoked
0396:             * @throws Exception if there's problem invoking the method
0397:             */
0398:            protected Object invokeMethod(Object obj, String methodName,
0399:                    Object[] args) throws Exception {
0400:                if (_logger.isLoggable(Level.FINEST)) {
0401:                    _logger.finest("Invoking " + obj.getClass() + "."
0402:                            + methodName + "(" + StringUtils.concat(args, ",")
0403:                            + ")");
0404:                }
0405:                if (obj == this ) {
0406:                    return callFunction(methodName, args);
0407:                } else {
0408:                    if (doMethodStats) {
0409:                        _methodStats.count(methodName);
0410:                    }
0411:                    if (obj instanceof  JxpInvocable) {
0412:                        JxpInvocable invocable = (JxpInvocable) obj;
0413:                        if (invocable.canInvoke(methodName, args)) {
0414:                            return invocable.invoke(methodName, args);
0415:                        }
0416:                    } //else fall through
0417:                    return ReflectUtils.invoke(obj, methodName, args);
0418:                }
0419:            }
0420:
0421:            /**
0422:             * Look up a variable in current nametable stack
0423:             * @param variableName the variable name
0424:             * @return the value of the variable
0425:             * @throws NoSuchFieldException the the variable cannot be found
0426:             */
0427:            protected Object lookupVariable(String variableName)
0428:                    throws NoSuchFieldException {
0429:                NametableStack ntStack = getCurrentContext()
0430:                        .getNametableStack();
0431:                if (!ntStack.containsName(variableName)) {
0432:                    throw new NoSuchFieldException("Variable/Function "
0433:                            + variableName + " is not declared before");
0434:                }
0435:                Object v = ntStack.access(variableName);
0436:                if (_logger.isLoggable(Level.FINEST)) {
0437:                    _logger.finest("Looking up variable " + variableName
0438:                            + " found " + v);
0439:                }
0440:                return v;
0441:            }
0442:
0443:            /**
0444:             * print the object by printing o.toString() using writer of current context. If the object is null, "null" will be printed.
0445:             * @param o the object
0446:             * @throws IOException if there's problem doing the printing
0447:             */
0448:            protected void print(Object o) throws IOException {
0449:                if (o == null) {
0450:                    print("null");
0451:                } else {
0452:                    print(o.toString());
0453:                }
0454:            }
0455:
0456:            /**
0457:             * Print the string using writer of current context
0458:             * @param s the string
0459:             * @throws IOException if there's io problem TODO: make to flag IOException to avoid call writes again
0460:             */
0461:            protected void print(String s) throws IOException {
0462:                Writer writer = getCurrentContext().getWriter();
0463:                try {
0464:                    writer.write(s);
0465:                } catch (Exception e) {
0466:                    _logger.throwing(getClass().getName(), "print", e);
0467:                }
0468:            }
0469:
0470:            /**
0471:             * print the object with the line delimiter "\n"
0472:             * @param o the object
0473:             * @throws IOException if there's problem doing the printing
0474:             */
0475:            protected void println(Object o) throws IOException {
0476:                print(o + "\n");
0477:            }
0478:
0479:            /**
0480:             * print the object with the line delimiter "\n"
0481:             * @param s the string
0482:             * @throws IOException if there's problem doing the printing
0483:             */
0484:            protected void println(String s) throws IOException {
0485:                print(s + "\n");
0486:            }
0487:
0488:            /**
0489:             * Process a page with empty environment
0490:             */
0491:            public Object process(String id, Writer writer) throws Exception {
0492:                return process(id, writer, Collections.EMPTY_MAP);
0493:            }
0494:
0495:            /**
0496:             * process the page identified by id with the context given
0497:             * @param id the id
0498:             * @param env the environment
0499:             * @return value return by this page
0500:             * @throws Exception if there's problem doing the printing
0501:             */
0502:            public Object process(String id, Writer writer, Map env)
0503:                    throws Exception {
0504:                JxpProcessingContext procContext = _context
0505:                        .createProcessingContext(env, writer);
0506:                int scope = _contextLocal.pushLocal(procContext);
0507:                try {
0508:                    return process(id, procContext);
0509:                } finally {
0510:                    _contextLocal.popLocalUtil(scope);
0511:                }
0512:            }
0513:
0514:            /**
0515:             * Processing a page identified by id in current context
0516:             * @param id the id
0517:             * @return the value return by the processing
0518:             * @throws Exception if there's problem doing the printing
0519:             */
0520:            protected Object process(String id, JxpProcessingContext context)
0521:                    throws Exception {
0522:                //resolve the actual id
0523:                String scriptId = id;
0524:                JxpPage currentPage = context.getCurrentPage();
0525:                if (currentPage != null && !id.startsWith("/")) //relative path
0526:                {
0527:                    String prefix = StringUtils.substringBeforeLast(currentPage
0528:                            .getName(), "/");
0529:                    if (prefix != null) {
0530:                        scriptId = FileUtils.concatFilePath(prefix, id);
0531:                    }
0532:                }
0533:                JxpPage page = _context.getPageSource().getJxpPage(scriptId);
0534:                try {
0535:                    context.pushPage(page);
0536:                    return visit(page.getJxpDocument(), null);
0537:                } finally {
0538:                    context.popPage(page);
0539:                }
0540:            }
0541:
0542:            /**
0543:             * Get the current processing context
0544:             * @return the current processing context
0545:             */
0546:            public JxpProcessingContext getCurrentContext() {
0547:                return (JxpProcessingContext) _contextLocal.getLocal();
0548:            }
0549:
0550:            /**
0551:             * Process a page identified by id in current context
0552:             * @param id the id
0553:             * @return the value return by the page
0554:             * @throws Exception if there's problem doing the printing
0555:             */
0556:            protected Object processCall(String id) throws Exception {
0557:                JxpProcessingContext context = getCurrentContext();
0558:                int scope = context.getNametableStack().newScope();
0559:                try {
0560:                    return process(id, context);
0561:                } finally {
0562:                    context.getNametableStack().closeScope(scope);
0563:                }
0564:            }
0565:
0566:            /**
0567:             * Resolve the arguments for function or method call
0568:             * @param node the node
0569:             * @param context the context
0570:             * @return object array containing the resolved argument values
0571:             * @throws Exception if there's problem
0572:             */
0573:            protected Object[] resolveArguments(AstArguments node,
0574:                    JxpProcessingContext context) throws Exception {
0575:                int n = node.jjtGetNumChildren();
0576:                Object[] args = new Object[n];
0577:                for (int i = 0; i < n; i++) {
0578:                    args[i] = node.jjtGetChild(i).jjtAccept(this , context);
0579:                }
0580:                return args;
0581:            }
0582:
0583:            /**
0584:             * Resolve the array dimensions needed
0585:             * @param node the ArrayDims node
0586:             * @param context the processing context
0587:             * @return the int array containing the dimensions info
0588:             * @throws Exception if there's problem resolving the dimension
0589:             */
0590:            protected int[] resolveArrayDims(AstArrayDims node,
0591:                    JxpProcessingContext context) throws Exception {
0592:                int[] dims = new int[node.jjtGetNumChildren()];
0593:                for (int i = 0; i < node.jjtGetNumChildren(); i++) {
0594:                    Object o = node.jjtGetChild(i).jjtAccept(this , context);
0595:                    if (o instanceof  Number) {
0596:                        dims[i] = ((Number) o).intValue();
0597:                    } else {
0598:                        throw generateProcessingException(
0599:                                new IllegalArgumentException("Array dimension "
0600:                                        + o + " is not a number"), node);
0601:                    }
0602:                }
0603:                return dims;
0604:            }
0605:
0606:            /**
0607:             * Resolve the assignment target. Exception will be thrown if the node is not assignable and throwExcpetion is true. Otherwise
0608:             * null will be return if the node cannot be resolved to assignment target.
0609:             * @param node the simple node or the target
0610:             * @param throwException whether to throw exception
0611:             * @return the target
0612:             * @throws ProcessingException if the target cannot be resolved
0613:             */
0614:            protected Assignable resolveAssignmentTarget(SimpleNode node,
0615:                    boolean throwException) throws ProcessingException {
0616:                if (node instanceof  AstName) {
0617:                    AstName name = (AstName) node;
0618:                    List l = (List) name.getData();
0619:                    JxpProcessingContext context = getCurrentContext();
0620:                    if (l.size() == 1) {
0621:                        String variableName = (String) l.get(0);
0622:                        // first case
0623:                        if (context.getNametableStack().containsName(
0624:                                variableName)) {
0625:                            return new VariableAssignable((String) l.get(0),
0626:                                    context);
0627:                        } else {
0628:                            //second case
0629:                            JxpPage page = context.getCurrentPage();
0630:                            if (page.hasStaticVariable(variableName)) {
0631:                                return new StaticVariableAssignable((String) l
0632:                                        .get(0), page);
0633:                            }
0634:                            throw generateProcessingException(
0635:                                    new IllegalArgumentException("Variable "
0636:                                            + variableName
0637:                                            + " has not been declared."), node);
0638:                        }
0639:                    } else {
0640:                        //TODO: how about assigning to a field? arr
0641:                        if (throwException) {
0642:                            throw generateProcessingException(
0643:                                    new IllegalArgumentException(node
0644:                                            + " is not assignable"), node);
0645:                        } else {
0646:                            return null;
0647:                        }
0648:                    }
0649:                } else if (node instanceof  AstArrayReference) {
0650:                    try {
0651:                        Object obj = node.jjtGetChild(0).jjtAccept(this , null);
0652:                        if (obj == null) {
0653:                            throw generateProcessingException(
0654:                                    new NullPointerException(),
0655:                                    (SimpleNode) node.jjtGetChild(0));
0656:                        }
0657:                        if (!obj.getClass().isArray()) {
0658:                            throw generateProcessingException(
0659:                                    new IllegalArgumentException(
0660:                                            "Argument is not an array"),
0661:                                    (SimpleNode) node.jjtGetChild(0));
0662:                        }
0663:                        Object dimObj = node.jjtGetChild(1).jjtAccept(this ,
0664:                                null);
0665:                        int dim = 0;
0666:                        if (dimObj instanceof  Number) {
0667:                            dim = ((Number) dimObj).intValue();
0668:                        } else {
0669:                            throw generateProcessingException(
0670:                                    new IllegalArgumentException(
0671:                                            "Invalid index type "
0672:                                                    + dimObj.getClass()
0673:                                                    + " for array"), node);
0674:                        }
0675:                        return new ArrayAssignable(obj, dim);
0676:                    } catch (ProcessingException e) {
0677:                        throw (ProcessingException) e;
0678:                    } catch (Exception e) {
0679:                        throw generateProcessingException(e, node);
0680:                    }
0681:                } else { //TODO: other kind of assignable such as array etc
0682:                    if (throwException) {
0683:                        throw generateProcessingException(
0684:                                new IllegalArgumentException(node
0685:                                        + " is not assignable"), node);
0686:                    } else {
0687:                        return null;
0688:                    }
0689:                }
0690:            }
0691:
0692:            /**
0693:             * Resolve the class. Call the current context for resolving since the imports in context specific
0694:             * @param className the class name
0695:             * @return the class
0696:             */
0697:            protected final Class resolveClass(String className) {
0698:                return getCurrentContext().resolveClass(className);
0699:            }
0700:
0701:            /**
0702:             * Resolve the field on and object. Also resolve the array length field
0703:             * @param obj the object
0704:             * @param fieldName the field name
0705:             * @return the field value
0706:             * @throws Exception if the field cannot be resolved
0707:             */
0708:            protected Object resolveField(Object obj, String fieldName)
0709:                    throws Exception {
0710:                if (_logger.isLoggable(Level.FINEST)) {
0711:                    _logger.finest("Resolving field " + fieldName + " of "
0712:                            + obj);
0713:                }
0714:                if (obj == null) {
0715:                    throw new NoSuchFieldException("Cannot find field "
0716:                            + fieldName + " for null");
0717:                }
0718:                if (fieldName.equals("class")) {
0719:                    if (obj instanceof  Class) {
0720:                        return (Class) obj;
0721:                    } else {
0722:                        throw new IllegalStateException(
0723:                                ".class cannot be apply to " + obj);
0724:                    }
0725:                }
0726:                if (fieldName.equals("length")) { //check if is array
0727:                    if (obj.getClass().isArray()) {
0728:                        return new Integer(Array.getLength(obj));
0729:                    } //otherwise just pass through
0730:                }
0731:                if (obj instanceof  JxpInvocable) {
0732:                    JxpInvocable invocable = (JxpInvocable) obj;
0733:                    if (invocable.canInvoke(fieldName, null)) {
0734:                        return invocable.invoke(fieldName, null);
0735:                    }
0736:                }
0737:                if (obj instanceof  Map) {
0738:                    return ((Map) obj).get(fieldName);
0739:                } //otherwise just pass through to use reflection
0740:                Field f = null;
0741:                if (obj instanceof  Class) {
0742:                    f = ((Class) obj).getField(fieldName);
0743:                } else {
0744:                    f = obj.getClass().getField(fieldName);
0745:                }
0746:                return f.get(obj);
0747:            }
0748:
0749:            /**
0750:             * Resolve a object given the name in current processing context. It cound be variable, or class
0751:             * @param l containing series of identifier
0752:             * @return the object associated with the name
0753:             * @throws Exception if there's problem resolving the name
0754:             */
0755:            protected Object resolveName(List l) throws Exception {
0756:                Object current = null;
0757:                JxpProcessingContext context = getCurrentContext();
0758:                NametableStack ntStack = context.getNametableStack();
0759:                for (int i = 0; i < l.size(); i++) {
0760:                    String s = (String) l.get(i);
0761:                    if (i == 0) {
0762:                        //first case, variable
0763:                        if (ntStack.containsName(s)) {
0764:                            current = ntStack.access(s); //lookup variable
0765:                        } else {//second case, page static
0766:                            JxpPage page = context.getCurrentPage();
0767:                            if (page.hasStaticVariable(s)) {
0768:                                current = page.getStaticVariable(s);
0769:                            } else {
0770:                                //third case, resolve class
0771:                                current = resolveClass(s);
0772:                                if (current == null) {
0773:                                    throw new NoSuchFieldException("Variable "
0774:                                            + s + " has not been declared");
0775:                                }
0776:                            }
0777:                        }
0778:                    } else {
0779:                        current = resolveField(current, s);
0780:                    }
0781:                }
0782:                return current;
0783:            }
0784:
0785:            /**
0786:             * Concat the ASTName to a dotted name notation
0787:             * @param name the ASTName object
0788:             * @return the dotted name string
0789:             */
0790:            private String toDottedName(AstName name) {
0791:                return StringUtils.concat((List) name.getData(), ".");
0792:            }
0793:
0794:            /**
0795:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstArguments, java.lang.Object)
0796:             */
0797:            public Object visit(AstArguments node, Object data)
0798:                    throws Exception {
0799:                throw new IllegalStateException(
0800:                        "visit(AstArguments, Object) should not be called");
0801:            }
0802:
0803:            /**
0804:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstArrayAllocationExpression, java.lang.Object)
0805:             */
0806:            public Object visit(AstArrayAllocationExpression node, Object data)
0807:                    throws Exception {
0808:                String className = toDottedName((AstName) node.jjtGetChild(0));
0809:                Class type = resolveClass(className);
0810:                if (type == null) {
0811:                    throw generateProcessingException(
0812:                            new ClassNotFoundException(
0813:                                    "No definition found for " + className),
0814:                            node);
0815:                }
0816:                SimpleNode n = (SimpleNode) node.jjtGetChild(1);
0817:                if (n instanceof  AstArrayDims) {
0818:                    int[] dims = resolveArrayDims((AstArrayDims) n,
0819:                            getCurrentContext());
0820:                    return Array.newInstance(type, dims);
0821:                } else { //must be ArrayInitializer
0822:                    return n.jjtAccept(this , type);
0823:                }
0824:            }
0825:
0826:            /**
0827:             * (non-Javadoc)
0828:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstArrayDims, java.lang.Object)
0829:             */
0830:            public Object visit(AstArrayDims node, Object data)
0831:                    throws Exception {
0832:                throw generateProcessingException(new IllegalStateException(
0833:                        "AstArrayDims are not supposed to be called"), node);
0834:            }
0835:
0836:            /**
0837:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstArrayInitializer, java.lang.Object)
0838:             */
0839:            public Object visit(AstArrayInitializer node, Object data)
0840:                    throws Exception {
0841:                Class type = (data instanceof  Class) ? (Class) data
0842:                        : Object.class;
0843:                int dim = node.jjtGetNumChildren();
0844:                List l = new ArrayList();
0845:                Class elementType = null;
0846:                for (int i = 0; i < dim; i++) {
0847:                    Object element = node.jjtGetChild(i).jjtAccept(this , type);
0848:                    //make sure the element type is correct
0849:                    if (element != null) {
0850:                        elementType = element.getClass(); //save for latter
0851:                        if (!elementType.isArray()) {//must be primitive - check it
0852:                            if (!type.isAssignableFrom(element.getClass())) {
0853:                                throw generateProcessingException(
0854:                                        new IllegalArgumentException(
0855:                                                "Illegal element " + element
0856:                                                        + " in "
0857:                                                        + type.getName()
0858:                                                        + " array"),
0859:                                        (SimpleNode) node.jjtGetChild(i));
0860:                            }
0861:                        }
0862:                    } else {
0863:                        if (type.isPrimitive()) {
0864:                            throw generateProcessingException(
0865:                                    new IllegalArgumentException(
0866:                                            "Illegal element " + element
0867:                                                    + " in " + type.getName()
0868:                                                    + " array"),
0869:                                    (SimpleNode) node.jjtGetChild(i));
0870:                        }
0871:                    }
0872:                    l.add(element);
0873:                }
0874:                if (elementType != null) {
0875:                    Object[] array = (Object[]) Array.newInstance(elementType,
0876:                            l.size());
0877:                    return l.toArray(array);
0878:                } else {
0879:                    return l.toArray();
0880:                }
0881:            }
0882:
0883:            /**
0884:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstArrayReference, java.lang.Object)
0885:             */
0886:            public Object visit(AstArrayReference node, Object data)
0887:                    throws Exception {
0888:                Object obj = node.jjtGetChild(0).jjtAccept(this , data);
0889:                if (obj != null && obj.getClass().isArray()) {
0890:                    Object dimObj = node.jjtGetChild(1).jjtAccept(this , data);
0891:                    int dim = 0;
0892:                    if (dimObj instanceof  Number) {
0893:                        dim = ((Number) dimObj).intValue();
0894:                    } else {
0895:                        throw generateProcessingException(
0896:                                new IllegalArgumentException(
0897:                                        "Invalid index type "
0898:                                                + dimObj.getClass()
0899:                                                + " for array"), node);
0900:                    }
0901:                    if (_logger.isLoggable(Level.FINEST)) {
0902:                        _logger.finest("Resolving array reference of " + obj
0903:                                + "[" + dim + "]");
0904:                    }
0905:                    return Array.get(obj, dim);
0906:                } else {
0907:                    throw generateProcessingException(
0908:                            new IllegalArgumentException(
0909:                                    "Cannot get array referernce of non-array "
0910:                                            + obj), node);
0911:                }
0912:            }
0913:
0914:            /**
0915:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstAssertStatement, java.lang.Object)
0916:             */
0917:            public Object visit(AstAssertStatement node, Object data)
0918:                    throws Exception {
0919:                for (int i = 0; i < node.jjtGetNumChildren(); i++) {
0920:                    Boolean assertion = Evaluator.toBoolean(node.jjtGetChild(i)
0921:                            .jjtAccept(this , data));
0922:                    if (!assertion.booleanValue()) {
0923:                        throw generateProcessingException(new AssertionError(
0924:                                "Assertion error "), (SimpleNode) node
0925:                                .jjtGetChild(i));
0926:                    }
0927:                }
0928:                return Boolean.TRUE;
0929:            }
0930:
0931:            /**
0932:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstAssignExpression, java.lang.Object)
0933:             */
0934:            public Object visit(AstAssignExpression node, Object data)
0935:                    throws Exception {
0936:                Object value = node.jjtGetChild(1).jjtAccept(this , data);
0937:                return assign((SimpleNode) node.jjtGetChild(0), value);
0938:            }
0939:
0940:            /**
0941:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstAndAssignExpression, java.lang.Object)
0942:             */
0943:            public Object visit(AstBitwiseAndAssignExpression node, Object data)
0944:                    throws Exception {
0945:                Object origValue = node.jjtGetChild(0).jjtAccept(this , data), value = node
0946:                        .jjtGetChild(1).jjtAccept(this , data);
0947:                return assign((SimpleNode) node.jjtGetChild(0), Evaluator
0948:                        .bitwiseAnd(origValue, value));
0949:            }
0950:
0951:            /**
0952:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstBitAndExpression, java.lang.Object)
0953:             */
0954:            public Object visit(AstBitwiseAndExpression node, Object data)
0955:                    throws Exception {
0956:                return Evaluator.bitwiseAnd(node.jjtGetChild(0).jjtAccept(this ,
0957:                        data), node.jjtGetChild(1).jjtAccept(this , data));
0958:            }
0959:
0960:            /**
0961:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstTildeUnaryExpression, java.lang.Object)
0962:             */
0963:            public Object visit(AstBitwiseComplementExpression node, Object data)
0964:                    throws Exception {
0965:                return Evaluator.bitwiseComplement(node.jjtGetChild(0)
0966:                        .jjtAccept(this , data));
0967:            }
0968:
0969:            /**
0970:             * (non-Javadoc)
0971:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstBitwiseOrAssignExpression, java.lang.Object)
0972:             */
0973:            public Object visit(AstBitwiseOrAssignExpression node, Object data)
0974:                    throws Exception {
0975:                Object origValue = node.jjtGetChild(0).jjtAccept(this , data), value = node
0976:                        .jjtGetChild(1).jjtAccept(this , data);
0977:                return assign((SimpleNode) node.jjtGetChild(0), Evaluator
0978:                        .bitwiseOr(origValue, value));
0979:            }
0980:
0981:            /**
0982:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstInclusiveOrExpression, java.lang.Object)
0983:             */
0984:            public Object visit(AstBitwiseOrExpression node, Object data)
0985:                    throws Exception {
0986:                return Evaluator.bitwiseOr(node.jjtGetChild(0).jjtAccept(this ,
0987:                        data), node.jjtGetChild(1).jjtAccept(this , data));
0988:            }
0989:
0990:            /**
0991:             * (non-Javadoc)
0992:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstBitwiseXOrAssignExpression, java.lang.Object)
0993:             */
0994:            public Object visit(AstBitwiseXOrAssignExpression node, Object data)
0995:                    throws Exception {
0996:                Object origValue = node.jjtGetChild(0).jjtAccept(this , data), value = node
0997:                        .jjtGetChild(1).jjtAccept(this , data);
0998:                return assign((SimpleNode) node.jjtGetChild(0), Evaluator
0999:                        .bitwiseXOr(origValue, value));
1000:            }
1001:
1002:            /**
1003:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstExclusiveOrExpression, java.lang.Object)
1004:             */
1005:            public Object visit(AstBitwiseXOrExpression node, Object data)
1006:                    throws Exception {
1007:                return Evaluator.bitwiseXOr(node.jjtGetChild(0).jjtAccept(this ,
1008:                        data), node.jjtGetChild(1).jjtAccept(this , data));
1009:            }
1010:
1011:            /**
1012:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstBlock, java.lang.Object)
1013:             */
1014:            public Object visit(AstBlock node, Object data) throws Exception {
1015:                JxpProcessingContext context = getCurrentContext();
1016:                int scope = context.getNametableStack().newScope();
1017:                Object obj = null;
1018:                SimpleNode childNode = null;
1019:                int i = 0;
1020:                try {
1021:                    for (i = 0; i < node.jjtGetNumChildren(); i++) {
1022:                        childNode = (SimpleNode) node.jjtGetChild(i);
1023:                        obj = childNode.jjtAccept(this , data);
1024:                        if (obj instanceof  Control) {
1025:                            break;
1026:                        }
1027:                    }
1028:                } catch (ProcessingException pe) {
1029:                    throw pe;
1030:                } catch (Exception e) {
1031:                    throw generateProcessingException(e, childNode);
1032:                } finally {
1033:                    context.getNametableStack().closeScope(scope);
1034:                }
1035:                return obj;
1036:            }
1037:
1038:            /**
1039:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstBreakStatement, java.lang.Object)
1040:             */
1041:            public Object visit(AstBreakStatement node, Object data)
1042:                    throws Exception {
1043:                return Control.BREAK;
1044:            }
1045:
1046:            /**
1047:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstCase, java.lang.Object)
1048:             */
1049:            public Object visit(AstCase node, Object data) throws Exception {
1050:                throw generateProcessingException(new IllegalStateException(
1051:                        "Switch case: are not suppossed to be called"), node);
1052:            }
1053:
1054:            /**
1055:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstCastExpression, java.lang.Object)
1056:             */
1057:            public Object visit(AstCastExpression node, Object data)
1058:                    throws Exception {
1059:                return node.jjtGetChild(1).jjtAccept(this , data);
1060:            }
1061:
1062:            /**
1063:             * {@inheritDoc}
1064:             */
1065:            public Object visit(AstCatchBlock node, Object data)
1066:                    throws Exception {
1067:                throw generateProcessingException(new IllegalStateException(
1068:                        "This should not be called"), node);
1069:            }
1070:
1071:            /**
1072:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstConditionalAndExpression, java.lang.Object)
1073:             */
1074:            public Object visit(AstConditionalAndExpression node, Object data)
1075:                    throws Exception {
1076:                Boolean b1 = Evaluator.toBoolean(node.jjtGetChild(0).jjtAccept(
1077:                        this , data));
1078:                if (!b1.booleanValue()) {
1079:                    return Boolean.FALSE;
1080:                }
1081:                Boolean b2 = Evaluator.toBoolean(node.jjtGetChild(1).jjtAccept(
1082:                        this , data));
1083:                if (!b2.booleanValue()) {
1084:                    return Boolean.FALSE;
1085:                } else {
1086:                    return Boolean.TRUE;
1087:                }
1088:            }
1089:
1090:            /**
1091:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstConditionalOrExpression, java.lang.Object)
1092:             */
1093:            public Object visit(AstConditionalOrExpression node, Object data)
1094:                    throws Exception {
1095:                Boolean b1 = Evaluator.toBoolean(node.jjtGetChild(0).jjtAccept(
1096:                        this , data));
1097:                if (b1.booleanValue()) {
1098:                    return Boolean.TRUE;
1099:                }
1100:                Boolean b2 = Evaluator.toBoolean(node.jjtGetChild(1).jjtAccept(
1101:                        this , data));
1102:                if (b2.booleanValue()) {
1103:                    return Boolean.TRUE;
1104:                } else {
1105:                    return Boolean.FALSE;
1106:                }
1107:            }
1108:
1109:            /**
1110:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstContent, java.lang.Object)
1111:             */
1112:            public Object visit(AstContent node, Object data) throws Exception {
1113:                Object content = node.getData();
1114:                print(content);
1115:                return content;
1116:            }
1117:
1118:            /**
1119:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstContinueStatement, java.lang.Object)
1120:             */
1121:            public Object visit(AstContinueStatement node, Object data)
1122:                    throws Exception {
1123:                return Control.CONTINUE;
1124:            }
1125:
1126:            /**
1127:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstSlashAssignExpression, java.lang.Object)
1128:             */
1129:            public Object visit(AstDivideAssignExpression node, Object data)
1130:                    throws Exception {
1131:                Object origValue = node.jjtGetChild(0).jjtAccept(this , data), value = node
1132:                        .jjtGetChild(1).jjtAccept(this , data);
1133:                return assign((SimpleNode) node.jjtGetChild(0), Evaluator
1134:                        .divide(origValue, value));
1135:            }
1136:
1137:            /**
1138:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstSlashExpression, java.lang.Object)
1139:             */
1140:            public Object visit(AstDivideExpression node, Object data)
1141:                    throws Exception {
1142:                return Evaluator.divide(node.jjtGetChild(0).jjtAccept(this ,
1143:                        data), node.jjtGetChild(1).jjtAccept(this , data));
1144:            }
1145:
1146:            /**
1147:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstDoStatement, java.lang.Object)
1148:             */
1149:            public Object visit(AstDoStatement node, Object data)
1150:                    throws Exception {
1151:                Node condition = node.jjtGetChild(1);
1152:                Boolean b = null;
1153:                Object returnValue = null;
1154:                do {
1155:                    returnValue = node.jjtGetChild(0).jjtAccept(this , data);
1156:                    if (returnValue instanceof  Control) {
1157:                        if (returnValue == Control.CONTINUE) {
1158:                            returnValue = null;
1159:                        } else if (returnValue == Control.BREAK) {
1160:                            returnValue = null;
1161:                            break;
1162:                        } else { //must be return w/wo object
1163:                            break;
1164:                        }
1165:                    }
1166:                    b = Evaluator.toBoolean(condition.jjtAccept(this , data));
1167:                } while (b.booleanValue());
1168:                return returnValue;
1169:            }
1170:
1171:            /**
1172:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstEmptyStatement, java.lang.Object)
1173:             */
1174:            public Object visit(AstEmptyStatement node, Object data)
1175:                    throws Exception {
1176:                return null;
1177:            }
1178:
1179:            /**
1180:             * @see org.onemind.jxp.parser.JxpParserVisitor#visit(jxp.parser.AstEQExpression, java.lang.Object)
1181:             */
1182:            public Object visit(AstEQExpression node, Object data)
1183:                    throws Exception {
1184:                Object o1 = node.jjtGetChild(0).jjtAccept(this , data), o2 = node
1185:                        .jjtGetChild(1).jjtAccept(this , data);
1186:                return Evaluator.eq(o1, o2);
1187:            }
1188:
1189:            /**
1190:             * (non-Javadoc)
1191:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstField, java.lang.Object)
1192:             */
1193:            public Object visit(AstField node, Object data) throws Exception {
1194:                throw generateProcessingException(
1195:                        new IllegalStateException(
1196:                                "visit(AstField, Object) is not supposed to be called"),
1197:                        node);
1198:            }
1199:
1200:            /**
1201:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstFieldDeclaration, java.lang.Object)
1202:             */
1203:            public Object visit(AstFieldDeclaration node, Object data)
1204:                    throws Exception {
1205:                Boolean isStatic = (node.getData() == null) ? Boolean.FALSE
1206:                        : Boolean.TRUE;
1207:                Object[] passOn = new Object[] { node.jjtGetChild(0), isStatic };
1208:                //ignore the type               
1209:                for (int i = 1; i < node.jjtGetNumChildren(); i++) {
1210:                    node.jjtGetChild(i).jjtAccept(this , passOn);
1211:                }
1212:                return null;
1213:            }
1214:
1215:            /**
1216:             * (non-Javadoc)
1217:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstFieldReference, java.lang.Object)
1218:             */
1219:            public Object visit(AstFieldReference node, Object data)
1220:                    throws Exception {
1221:                Object o1 = node.jjtGetChild(0).jjtAccept(this , data);
1222:                String fieldName = (String) ((SimpleNode) node.jjtGetChild(1))
1223:                        .getData();
1224:                return resolveField(o1, fieldName);
1225:            }
1226:
1227:            /**
1228:             * {@inheritDoc}
1229:             */
1230:            public Object visit(AstFinallyBlock node, Object data)
1231:                    throws Exception {
1232:                return node.jjtGetChild(0).jjtAccept(this , data);
1233:                //pass on
1234:            }
1235:
1236:            /**
1237:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstForInit, java.lang.Object)
1238:             */
1239:            public Object visit(AstForInit node, Object data) throws Exception {
1240:                return node.childrenAccept(this , data);
1241:            }
1242:
1243:            /**
1244:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstFormalParameter, java.lang.Object)
1245:             */
1246:            public Object visit(AstFormalParameter node, Object data)
1247:                    throws Exception {
1248:                throw generateProcessingException(
1249:                        new IllegalStateException(
1250:                                "visit(AstFormalParameter, Object) are not supposed to be called"),
1251:                        node);
1252:            }
1253:
1254:            /**
1255:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstFormalParameters, java.lang.Object)
1256:             */
1257:            public Object visit(AstFormalParameters node, Object data)
1258:                    throws Exception {
1259:                throw generateProcessingException(
1260:                        new UnsupportedOperationException(
1261:                                "Unsupported Language Feature"), node);
1262:            }
1263:
1264:            /**
1265:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstForStatement, java.lang.Object)
1266:             */
1267:            public Object visit(AstForStatement node, Object data)
1268:                    throws Exception {
1269:                JxpProcessingContext context = getCurrentContext();
1270:                SimpleNode forInit = null, forCondition = null, forUpdate = null, statements = null;
1271:                for (int i = 0; i < node.jjtGetNumChildren() - 1; i++) {
1272:                    SimpleNode n = (SimpleNode) node.jjtGetChild(i);
1273:                    if (n instanceof  AstForInit) {
1274:                        forInit = n;
1275:                    } else if (n instanceof  AstForUpdate) {
1276:                        forUpdate = n;
1277:                    } else {
1278:                        forCondition = n;
1279:                    }
1280:                }
1281:                statements = (SimpleNode) node.jjtGetChild(node
1282:                        .jjtGetNumChildren() - 1);
1283:                int newscope = context.getNametableStack().newScope(); //this must be in front of for init
1284:                if (forInit != null) {
1285:                    forInit.jjtAccept(this , data);
1286:                }
1287:                Boolean condition = Boolean.TRUE;
1288:                if (forCondition != null) {
1289:                    condition = Evaluator.toBoolean(forCondition.jjtAccept(
1290:                            this , data));
1291:                }
1292:                Object returnValue = null;
1293:                try {
1294:                    while (condition.booleanValue()) {
1295:                        returnValue = statements.jjtAccept(this , data);
1296:                        if (returnValue == Control.CONTINUE) {
1297:                            returnValue = null;
1298:                            //let it pass
1299:                        } else if (returnValue == Control.BREAK) {
1300:                            returnValue = null;
1301:                            break;
1302:                        } else if (returnValue instanceof  Control) { //must be return w/wo object
1303:                            break;
1304:                        }
1305:                        if (forUpdate != null) {
1306:                            forUpdate.jjtAccept(this , data);
1307:                        }
1308:                        if (forCondition != null) {
1309:                            condition = Evaluator.toBoolean(forCondition
1310:                                    .jjtAccept(this , data));
1311:                        }
1312:                    }
1313:                } finally {
1314:                    context.getNametableStack().closeScope(newscope);
1315:                }
1316:                return returnValue;
1317:            }
1318:
1319:            /**
1320:             * (non-Javadoc)
1321:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstForUpdate, java.lang.Object)
1322:             */
1323:            public Object visit(AstForUpdate node, Object data)
1324:                    throws Exception {
1325:                return node.childrenAccept(this , data);
1326:            }
1327:
1328:            /**
1329:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstGEExpression, java.lang.Object)
1330:             */
1331:            public Object visit(AstGEExpression node, Object data)
1332:                    throws Exception {
1333:                Object o1 = node.jjtGetChild(0).jjtAccept(this , data), o2 = node
1334:                        .jjtGetChild(1).jjtAccept(this , data);
1335:                return Evaluator.ge(o1, o2);
1336:            }
1337:
1338:            /**
1339:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstGTExpression, java.lang.Object)
1340:             */
1341:            public Object visit(AstGTExpression node, Object data)
1342:                    throws Exception {
1343:                Object o1 = node.jjtGetChild(0).jjtAccept(this , data), o2 = node
1344:                        .jjtGetChild(1).jjtAccept(this , data);
1345:                return Evaluator.gt(o1, o2);
1346:            }
1347:
1348:            /**
1349:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstHookExpression, java.lang.Object)
1350:             */
1351:            public Object visit(AstHookExpression node, Object data)
1352:                    throws Exception {
1353:                Object returnValue = node.jjtGetChild(0).jjtAccept(this , data);
1354:                if (returnValue instanceof  Boolean) {
1355:                    if (Boolean.TRUE.equals(returnValue)) {
1356:                        return node.jjtGetChild(1).jjtAccept(this , data);
1357:                    } else {
1358:                        return node.jjtGetChild(2).jjtAccept(this , data);
1359:                    }
1360:                } else {
1361:                    throw generateProcessingException(
1362:                            new IllegalArgumentException(
1363:                                    "condition of hook expression is not a boolean expression"),
1364:                            node);
1365:                }
1366:            }
1367:
1368:            /**
1369:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstIfStatement, java.lang.Object)
1370:             */
1371:            public Object visit(AstIfStatement node, Object data)
1372:                    throws Exception {
1373:                Boolean condition = Evaluator.toBoolean(node.jjtGetChild(0)
1374:                        .jjtAccept(this , data));
1375:                if (condition.booleanValue()) {
1376:                    return node.jjtGetChild(1).jjtAccept(this , data);
1377:                } else {
1378:                    if (node.jjtGetNumChildren() > 2) {
1379:                        return node.jjtGetChild(2).jjtAccept(this , data);
1380:                    } else {
1381:                        return null;
1382:                    }
1383:                }
1384:            }
1385:
1386:            /**
1387:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstImportDeclaration, java.lang.Object)
1388:             */
1389:            public Object visit(AstImportDeclaration node, Object data)
1390:                    throws Exception {
1391:                JxpProcessingContext context = getCurrentContext();
1392:                String packageName = toDottedName((AstName) node.jjtGetChild(0));
1393:                String className = (String) node.getData();
1394:                String importName = packageName + "." + className;
1395:                context.getImports().addImport(importName);
1396:                if (_logger.isLoggable(Level.FINEST)) {
1397:                    _logger.finest("Add import " + importName);
1398:                    _logger.finest(context.getImports().getPackages()
1399:                            .toString());
1400:                }
1401:                return null;
1402:            }
1403:
1404:            /**
1405:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstInstanceOfExpression, java.lang.Object)
1406:             */
1407:            public Object visit(AstInstanceOfExpression node, Object data)
1408:                    throws Exception {
1409:                Object obj = node.jjtGetChild(0).jjtAccept(this , data); //the object
1410:                if (obj == null) {
1411:                    return Boolean.FALSE; //always false
1412:                } else {
1413:                    Class c = (Class) node.jjtGetChild(1).jjtAccept(this , data);
1414:                    return Boolean.valueOf(c.isInstance(obj));
1415:                }
1416:            }
1417:
1418:            /**
1419:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstJxpDocument, java.lang.Object)
1420:             */
1421:            public Object visit(AstJxpDocument node, Object data)
1422:                    throws Exception {
1423:                int i = 0;
1424:                int n = node.jjtGetNumChildren();
1425:                Object returnValue = null;
1426:                SimpleNode statement = null;
1427:                try {
1428:                    while (i < n) {
1429:                        statement = (SimpleNode) node.jjtGetChild(i);
1430:                        returnValue = statement.jjtAccept(this , data);
1431:                        if (returnValue instanceof  Control) {
1432:                            return returnValue;
1433:                        }
1434:                        i++;
1435:                    }
1436:                } catch (ProcessingException pe) {
1437:                    throw pe;
1438:                } catch (Exception e) {
1439:                    throw generateProcessingException(e, statement);
1440:                }
1441:                return null;
1442:            }
1443:
1444:            /**
1445:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstLabeledStatement, java.lang.Object)
1446:             */
1447:            public Object visit(AstLabeledStatement node, Object data)
1448:                    throws Exception {
1449:                throw generateProcessingException(
1450:                        new UnsupportedOperationException(
1451:                                "Labeled statement: Unsupported Language Feature"),
1452:                        node);
1453:            }
1454:
1455:            /**
1456:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstLEExpression, java.lang.Object)
1457:             */
1458:            public Object visit(AstLEExpression node, Object data)
1459:                    throws Exception {
1460:                Object o1 = node.jjtGetChild(0).jjtAccept(this , data), o2 = node
1461:                        .jjtGetChild(1).jjtAccept(this , data);
1462:                return Evaluator.le(o1, o2);
1463:            }
1464:
1465:            /**
1466:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstLiteral, java.lang.Object)
1467:             */
1468:            public Object visit(AstLiteral node, Object data) throws Exception {
1469:                return node.getData();
1470:            }
1471:
1472:            /**
1473:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstBangUnaryExpression, java.lang.Object)
1474:             */
1475:            public Object visit(AstLogicalComplementExpression node, Object data)
1476:                    throws Exception {
1477:                Boolean b = Evaluator.toBoolean(node.jjtGetChild(0).jjtAccept(
1478:                        this , data));
1479:                return Boolean.valueOf(!b.booleanValue());
1480:            }
1481:
1482:            /**
1483:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstLShiftAssignExpression, java.lang.Object)
1484:             */
1485:            public Object visit(AstLShiftAssignExpression node, Object data)
1486:                    throws Exception {
1487:                Object origValue = node.jjtGetChild(0).jjtAccept(this , data), value = node
1488:                        .jjtGetChild(1).jjtAccept(this , data);
1489:                return assign((SimpleNode) node.jjtGetChild(0), Evaluator
1490:                        .leftShift(origValue, value));
1491:            }
1492:
1493:            /**
1494:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstLShiftExpression, java.lang.Object)
1495:             */
1496:            public Object visit(AstLShiftExpression node, Object data)
1497:                    throws Exception {
1498:                return Evaluator.leftShift(node.jjtGetChild(0).jjtAccept(this ,
1499:                        data), node.jjtGetChild(1).jjtAccept(this , data));
1500:            }
1501:
1502:            /**
1503:             * (non-Javadoc)
1504:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstLTExpression, java.lang.Object)
1505:             */
1506:            public Object visit(AstLTExpression node, Object data)
1507:                    throws Exception {
1508:                Object o1 = node.jjtGetChild(0).jjtAccept(this , data), o2 = node
1509:                        .jjtGetChild(1).jjtAccept(this , data);
1510:                return Evaluator.lt(o1, o2);
1511:            }
1512:
1513:            /**
1514:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstMethodCall, java.lang.Object)
1515:             */
1516:            public Object visit(AstMethodCall node, Object data)
1517:                    throws Exception {
1518:                String methodName = (String) node.getData();
1519:                Object[] args = resolveArguments((AstArguments) node
1520:                        .jjtGetChild(0), getCurrentContext());
1521:                if (args.length == 0) {
1522:                    if (methodName.equals("flush")) {
1523:                        flush();
1524:                        return null;
1525:                    }
1526:                } else if (args[0] instanceof  String && args.length == 1) {
1527:                    /*
1528:                     if (methodName.equals("process"))
1529:                     {
1530:                     return processCall((String) args[0]);
1531:                     } else
1532:                     */
1533:                    if (methodName.equals("include")) {
1534:                        return includeCall((String) args[0]);
1535:                    }
1536:                }
1537:                try {
1538:                    return invokeMethod(this , methodName, args);
1539:                } catch (ProcessingException e) {
1540:                    throw e;
1541:                } catch (InvocationTargetException e) {
1542:                    Throwable t = e.getTargetException();
1543:                    throw generateProcessingException(t, node);
1544:                } catch (Exception e) {
1545:                    throw generateProcessingException(e, node);
1546:                }
1547:            }
1548:
1549:            /**
1550:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstMethodDeclaration, java.lang.Object)
1551:             */
1552:            public Object visit(AstFunctionDeclaration node, Object data)
1553:                    throws Exception {
1554:                int i = 0;
1555:                SimpleNode declarator = null;
1556:                do {
1557:                    declarator = (SimpleNode) node.jjtGetChild(i++);
1558:                } while (!(declarator instanceof  AstFunctionDeclarator));
1559:                //child is FunctionDeclarator now
1560:                SimpleNode block = null;
1561:                int n = node.jjtGetNumChildren();
1562:                if (i < n) {
1563:                    do {
1564:                        block = (SimpleNode) node.jjtGetChild(i++);
1565:                    } while (!(block instanceof  AstBlock) && i < n);
1566:                }
1567:                return getCurrentContext().getUserDefinedFunctions().put(
1568:                        (String) declarator.getData(),
1569:                        new JxpUserDefinedFunction((SimpleNode) declarator
1570:                                .jjtGetChild(0), (AstBlock) block));
1571:            }
1572:
1573:            /**
1574:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstMethodDeclarator, java.lang.Object)
1575:             */
1576:            public Object visit(AstFunctionDeclarator node, Object data)
1577:                    throws Exception {
1578:                throw generateProcessingException(
1579:                        new IllegalStateException(
1580:                                "visit(AstFunctionDeclarator,Object) is not meant to be called."),
1581:                        node);
1582:            }
1583:
1584:            /**
1585:             * (non-Javadoc)
1586:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstMethodInvocation, java.lang.Object)
1587:             */
1588:            public Object visit(AstMethodInvocation node, Object data)
1589:                    throws Exception {
1590:                //      the prefix node
1591:                Object obj = node.jjtGetChild(0).jjtAccept(this , data);
1592:                SimpleNode methodCall = (SimpleNode) node.jjtGetChild(1);
1593:                String methodName = (String) methodCall.getData();
1594:                if (obj == null) {
1595:                    throw generateProcessingException(new NullPointerException(
1596:                            "Cannot invoke method " + methodName
1597:                                    + "(...) of null at "), node);
1598:                }
1599:                Object[] args = resolveArguments((AstArguments) methodCall
1600:                        .jjtGetChild(0), getCurrentContext());
1601:                try {
1602:                    return invokeMethod(obj, methodName, args);
1603:                } catch (InvocationTargetException e) {
1604:                    Throwable t = e.getTargetException();
1605:                    throw generateProcessingException(t, node);
1606:                } catch (Exception e) {
1607:                    throw generateProcessingException(e, node);
1608:                }
1609:            }
1610:
1611:            /**
1612:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstMinusAssignExpression, java.lang.Object)
1613:             */
1614:            public Object visit(AstMinusAssignExpression node, Object data)
1615:                    throws Exception {
1616:                Object origValue = node.jjtGetChild(0).jjtAccept(this , data), value = node
1617:                        .jjtGetChild(1).jjtAccept(this , data);
1618:                return assign((SimpleNode) node.jjtGetChild(0), Evaluator
1619:                        .minus(origValue, value));
1620:            }
1621:
1622:            /**
1623:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstMinusExpression, java.lang.Object)
1624:             */
1625:            public Object visit(AstMinusExpression node, Object data)
1626:                    throws Exception {
1627:                return Evaluator.minus(node.jjtGetChild(0)
1628:                        .jjtAccept(this , data), node.jjtGetChild(1).jjtAccept(
1629:                        this , data));
1630:            }
1631:
1632:            /**
1633:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstStarAssignExpression, java.lang.Object)
1634:             */
1635:            public Object visit(AstMultiplyAssignExpression node, Object data)
1636:                    throws Exception {
1637:                Object origValue = node.jjtGetChild(0).jjtAccept(this , data), value = node
1638:                        .jjtGetChild(1).jjtAccept(this , data);
1639:                return assign((SimpleNode) node.jjtGetChild(0), Evaluator
1640:                        .multiply(origValue, value));
1641:            }
1642:
1643:            /**
1644:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstMultiplyExpression, java.lang.Object)
1645:             */
1646:            public Object visit(AstMultiplyExpression node, Object data)
1647:                    throws Exception {
1648:                return Evaluator.multiply(node.jjtGetChild(0).jjtAccept(this ,
1649:                        data), node.jjtGetChild(1).jjtAccept(this , data));
1650:            }
1651:
1652:            /**
1653:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstName, java.lang.Object)
1654:             */
1655:            public Object visit(AstName node, Object data) throws Exception {
1656:                List l = (List) node.getData();
1657:                try {
1658:                    return resolveName(l);
1659:                } catch (Exception e) {
1660:                    throw generateProcessingException(e, node);
1661:                }
1662:            }
1663:
1664:            /**
1665:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstNameList, java.lang.Object)
1666:             */
1667:            public Object visit(AstNameList node, Object data) throws Exception {
1668:                throw generateProcessingException(
1669:                        new IllegalStateException(
1670:                                "visit(ASTNameList, Object) not supposed to be called"),
1671:                        node);
1672:            }
1673:
1674:            /**
1675:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstNEExpression, java.lang.Object)
1676:             */
1677:            public Object visit(AstNEExpression node, Object data)
1678:                    throws Exception {
1679:                Object o1 = node.jjtGetChild(0).jjtAccept(this , data), o2 = node
1680:                        .jjtGetChild(1).jjtAccept(this , data);
1681:                return Evaluator.ne(o1, o2);
1682:            }
1683:
1684:            /**
1685:             * (non-Javadoc)
1686:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstObjectAllocationExpression, java.lang.Object)
1687:             */
1688:            public Object visit(AstObjectAllocationExpression node, Object data)
1689:                    throws Exception {
1690:                String className = toDottedName((AstName) node.jjtGetChild(0));
1691:                Class type = getCurrentContext().resolveClass(className);
1692:                if (type == null) {
1693:                    throw generateProcessingException(
1694:                            new ClassNotFoundException(
1695:                                    "No definition found for " + className),
1696:                            node);
1697:                }
1698:                Object[] args = resolveArguments((AstArguments) node
1699:                        .jjtGetChild(1), getCurrentContext());
1700:                try {
1701:                    return instantiate(type, args);
1702:                } catch (InvocationTargetException e) {
1703:                    Throwable t = e.getTargetException();
1704:                    throw generateProcessingException(t, node);
1705:                } catch (Exception e) {
1706:                    throw generateProcessingException(e, node);
1707:                }
1708:            }
1709:
1710:            /**
1711:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstPlusAssignExpression, java.lang.Object)
1712:             */
1713:            public Object visit(AstPlusAssignExpression node, Object data)
1714:                    throws Exception {
1715:                Object origValue = node.jjtGetChild(0).jjtAccept(this , data), value = node
1716:                        .jjtGetChild(1).jjtAccept(this , data);
1717:                return assign((SimpleNode) node.jjtGetChild(0), Evaluator.plus(
1718:                        origValue, value));
1719:            }
1720:
1721:            /**
1722:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstPlusExpression, java.lang.Object)
1723:             */
1724:            public Object visit(AstPlusExpression node, Object data)
1725:                    throws Exception {
1726:                Object o1 = node.jjtGetChild(0).jjtAccept(this , data), o2 = node
1727:                        .jjtGetChild(1).jjtAccept(this , data);
1728:                return Evaluator.plus(o1, o2);
1729:            }
1730:
1731:            /**
1732:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstPostfixDecrementExpression, java.lang.Object)
1733:             */
1734:            public Object visit(AstPostDecrementExpression node, Object data)
1735:                    throws Exception {
1736:                Object returnValue = node.jjtGetChild(0).jjtAccept(this , data);
1737:                Object newValue = Evaluator.minus(returnValue, ONE);
1738:                if (resolveAssignmentTarget((SimpleNode) node.jjtGetChild(0),
1739:                        false) != null) {
1740:                    assign((SimpleNode) node.jjtGetChild(0), newValue);
1741:                }
1742:                return returnValue;
1743:            }
1744:
1745:            /**
1746:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstPostfixIncrementExpression, java.lang.Object)
1747:             */
1748:            public Object visit(AstPostIncrementExpression node, Object data)
1749:                    throws Exception {
1750:                Object returnValue = node.jjtGetChild(0).jjtAccept(this , data);
1751:                Object newValue = Evaluator.plus(returnValue, ONE);
1752:                if (resolveAssignmentTarget((SimpleNode) node.jjtGetChild(0),
1753:                        false) != null) {
1754:                    assign((SimpleNode) node.jjtGetChild(0), newValue);
1755:                }
1756:                return returnValue;
1757:            }
1758:
1759:            /**
1760:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstPreDecrementExpression, java.lang.Object)
1761:             */
1762:            public Object visit(AstPreDecrementExpression node, Object data)
1763:                    throws Exception {
1764:                Object returnValue = node.jjtGetChild(0).jjtAccept(this , data);
1765:                Object newValue = Evaluator.minus(returnValue, ONE);
1766:                //TODO: improve performance
1767:                if (resolveAssignmentTarget((SimpleNode) node.jjtGetChild(0),
1768:                        false) != null) {
1769:                    assign((SimpleNode) node.jjtGetChild(0), newValue);
1770:                }
1771:                return newValue;
1772:            }
1773:
1774:            /**
1775:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstPreIncrementExpression, java.lang.Object)
1776:             */
1777:            public Object visit(AstPreIncrementExpression node, Object data)
1778:                    throws Exception {
1779:                Object returnValue = node.jjtGetChild(0).jjtAccept(this , data);
1780:                Object newValue = Evaluator.plus(returnValue, ONE);
1781:                //TODO: improve performance
1782:                if (resolveAssignmentTarget((SimpleNode) node.jjtGetChild(0),
1783:                        false) != null) {
1784:                    assign((SimpleNode) node.jjtGetChild(0), newValue);
1785:                }
1786:                return newValue;
1787:            }
1788:
1789:            /**
1790:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstPrimaryExpression, java.lang.Object)
1791:             */
1792:            public Object visit(AstPrimaryExpression node, Object data)
1793:                    throws Exception {
1794:                throw generateProcessingException(
1795:                        new IllegalStateException(
1796:                                "visit(AstPrimaryExpression, Object) not supposed to be called."),
1797:                        node);
1798:            }
1799:
1800:            /**
1801:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstPrimarySuffix, java.lang.Object)
1802:             */
1803:            public Object visit(AstPrimarySuffix node, Object data)
1804:                    throws Exception {
1805:                throw generateProcessingException(
1806:                        new IllegalStateException(
1807:                                "visit(AstPrimarySuffix, Object) not supposed to be called."),
1808:                        node);
1809:            }
1810:
1811:            /**
1812:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstPrimitiveType, java.lang.Object)
1813:             */
1814:            public Object visit(AstPrimitiveType node, Object data)
1815:                    throws Exception {
1816:                throw generateProcessingException(
1817:                        new IllegalStateException(
1818:                                "visit(AstPrimitiveType, Object) not supposed to be called."),
1819:                        node);
1820:            }
1821:
1822:            /**
1823:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstPrintStatement, java.lang.Object)
1824:             */
1825:            public Object visit(AstPrintStatement node, Object data)
1826:                    throws Exception {
1827:                print(node.jjtGetChild(0).jjtAccept(this , data));
1828:                return null;
1829:            }
1830:
1831:            /**
1832:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstRemainderExpression, java.lang.Object)
1833:             */
1834:            public Object visit(AstRemainderExpression node, Object data)
1835:                    throws Exception {
1836:                return Evaluator.remainder(node.jjtGetChild(0).jjtAccept(this ,
1837:                        data), node.jjtGetChild(1).jjtAccept(this , data));
1838:            }
1839:
1840:            /**
1841:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstRemAssignExpression, java.lang.Object)
1842:             */
1843:            public Object visit(AstRemAssignExpression node, Object data)
1844:                    throws Exception {
1845:                Object origValue = node.jjtGetChild(0).jjtAccept(this , data), value = node
1846:                        .jjtGetChild(1).jjtAccept(this , data);
1847:                return assign((SimpleNode) node.jjtGetChild(0), Evaluator
1848:                        .remainder(origValue, value));
1849:            }
1850:
1851:            /**
1852:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstReturnStatement, java.lang.Object)
1853:             */
1854:            public Object visit(AstReturnStatement node, Object data)
1855:                    throws Exception {
1856:                if (node.jjtGetNumChildren() > 0) {
1857:                    return new Control(node.jjtGetChild(0)
1858:                            .jjtAccept(this , data));
1859:                } else {
1860:                    return Control.RETURN;
1861:                }
1862:            }
1863:
1864:            /**
1865:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstRSignedShiftAssignExpression, java.lang.Object)
1866:             */
1867:            public Object visit(AstRSignedShiftAssignExpression node,
1868:                    Object data) throws Exception {
1869:                Object origValue = node.jjtGetChild(0).jjtAccept(this , data), value = node
1870:                        .jjtGetChild(1).jjtAccept(this , data);
1871:                return assign((SimpleNode) node.jjtGetChild(0), Evaluator
1872:                        .rightSignedShift(origValue, value));
1873:            }
1874:
1875:            /**
1876:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstRSignedShiftExpression, java.lang.Object)
1877:             */
1878:            public Object visit(AstRSignedShiftExpression node, Object data)
1879:                    throws Exception {
1880:                return Evaluator.rightUnsignedShift(node.jjtGetChild(0)
1881:                        .jjtAccept(this , data), node.jjtGetChild(1).jjtAccept(
1882:                        this , data));
1883:            }
1884:
1885:            /**
1886:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstRUnsignedShiftAssignExpression, java.lang.Object)
1887:             */
1888:            public Object visit(AstRUnsignedShiftAssignExpression node,
1889:                    Object data) throws Exception {
1890:                Object origValue = node.jjtGetChild(0).jjtAccept(this , data), value = node
1891:                        .jjtGetChild(1).jjtAccept(this , data);
1892:                return assign((SimpleNode) node.jjtGetChild(0), Evaluator
1893:                        .rightUnsignedShift(origValue, value));
1894:            }
1895:
1896:            /**
1897:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstRUnsignedShiftExpression, java.lang.Object)
1898:             */
1899:            public Object visit(AstRUnsignedShiftExpression node, Object data)
1900:                    throws Exception {
1901:                return Evaluator.rightUnsignedShift(node.jjtGetChild(0)
1902:                        .jjtAccept(this , data), node.jjtGetChild(1).jjtAccept(
1903:                        this , data));
1904:            }
1905:
1906:            /**
1907:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstStatementExpressionList, java.lang.Object)
1908:             */
1909:            public Object visit(AstStatementExpressionList node, Object data)
1910:                    throws Exception {
1911:                throw generateProcessingException(
1912:                        new IllegalStateException(
1913:                                "visit(AstStatementExpressionList, Object) not supposed to be called."),
1914:                        node);
1915:            }
1916:
1917:            /**
1918:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstSwitchStatement, java.lang.Object)
1919:             */
1920:            public Object visit(AstSwitchStatement node, Object data)
1921:                    throws Exception {
1922:                Object switchValue = node.jjtGetChild(0).jjtAccept(this , data); //resolve the value first
1923:                if (switchValue == null) {
1924:                    throw generateProcessingException(
1925:                            new IllegalArgumentException(
1926:                                    "Switch value cannot be null"), node);
1927:                }
1928:                int n = node.jjtGetNumChildren();
1929:                boolean matchCase = false;
1930:                for (int i = 1; i < n; i++) {
1931:                    AstCase case_ = (AstCase) node.jjtGetChild(i);
1932:                    int caseChildren = case_.jjtGetNumChildren();
1933:                    if (!matchCase) //haven't match before
1934:                    {//try to match the case
1935:                        if (caseChildren == 1) {//must be the default: calse
1936:                            matchCase = true;
1937:                        } else {
1938:                            Object caseValue = case_.jjtGetChild(0).jjtAccept(
1939:                                    this , null);
1940:                            if (caseValue == null) {
1941:                                throw generateProcessingException(
1942:                                        new IllegalArgumentException(
1943:                                                "Switch case value cannot be null"),
1944:                                        case_);
1945:                            }
1946:                            if (switchValue.equals(caseValue)) {
1947:                                matchCase = true;
1948:                            }
1949:                        }
1950:                    }
1951:                    if (matchCase) {
1952:                        Object obj = case_.jjtGetChild(caseChildren - 1)
1953:                                .jjtAccept(this , null);
1954:                        if (obj == Control.BREAK) {
1955:                            return null;
1956:                        } else if (obj instanceof  Control) {//either return or exit
1957:                            return obj;
1958:                        } //else just continue to fall through	            
1959:                    }
1960:                }
1961:                return null;
1962:            }
1963:
1964:            /**
1965:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstSynchronizedStatement, java.lang.Object)
1966:             */
1967:            public Object visit(AstSynchronizedStatement node, Object data)
1968:                    throws Exception {
1969:                Object obj = node.jjtGetChild(0).jjtAccept(this , data);
1970:                if (obj == null) {
1971:                    throw generateProcessingException(
1972:                            new IllegalArgumentException(
1973:                                    "Cannot synchronize on null"), node);
1974:                } else {
1975:                    synchronized (obj) {
1976:                        return node.jjtGetChild(1).jjtAccept(this , data);
1977:                    }
1978:                }
1979:            }
1980:
1981:            /**
1982:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstThrowStatement, java.lang.Object)
1983:             */
1984:            public Object visit(AstThrowStatement node, Object data)
1985:                    throws Exception {
1986:                Object o = node.jjtGetChild(0).jjtAccept(this , data);
1987:                if (o instanceof  Exception) {
1988:                    throw (Exception) o;
1989:                } else {
1990:                    throw generateProcessingException(
1991:                            new IllegalArgumentException(
1992:                                    "Cannot throw non-exception " + o), node);
1993:                }
1994:            }
1995:
1996:            /**
1997:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstTryStatement, java.lang.Object)
1998:             */
1999:            public Object visit(AstTryStatement node, Object data)
2000:                    throws Exception {
2001:                int n = node.jjtGetNumChildren();
2002:                int i = 0;
2003:                try {
2004:                    SimpleNode block = (SimpleNode) node.jjtGetChild(0);
2005:                    return block.jjtAccept(this , data);
2006:                } catch (Throwable e) {
2007:                    JxpProcessingContext context = getCurrentContext();
2008:                    Throwable realCause = e;
2009:                    if (realCause instanceof  ProcessingException
2010:                            && realCause.getCause() != null) {
2011:                        realCause = realCause.getCause();
2012:                    }
2013:                    for (i = 1; i < n; i++) {
2014:                        SimpleNode handlerBlock = (SimpleNode) node
2015:                                .jjtGetChild(i);
2016:                        if (handlerBlock instanceof  AstCatchBlock) {
2017:                            //catchblock
2018:                            //SimpleNode formalParameter = (SimpleNode) handlerBlock.jjtGetChild(0);
2019:                            AstType type = (AstType) handlerBlock
2020:                                    .jjtGetChild(0);
2021:                            Class c = (Class) type.jjtAccept(this , data);
2022:                            if (c.isAssignableFrom(realCause.getClass())) {
2023:                                int scope = context.getNametableStack()
2024:                                        .newScope();
2025:                                try {
2026:                                    AstVariableDeclaratorId id = (AstVariableDeclaratorId) handlerBlock
2027:                                            .jjtGetChild(1);
2028:                                    context.getNametableStack().declare(
2029:                                            (String) id.getData(), realCause);
2030:                                    return handlerBlock.jjtGetChild(2)
2031:                                            .jjtAccept(this , data); //execute the catch block
2032:                                } catch (Exception eAgain) {
2033:                                    //again
2034:                                    throw generateProcessingException(eAgain,
2035:                                            (SimpleNode) handlerBlock
2036:                                                    .jjtGetChild(1));
2037:                                } finally {
2038:                                    context.getNametableStack().closeScope(
2039:                                            scope);
2040:                                }
2041:                            }
2042:                        }
2043:                    } //exception has no handler
2044:                    if (e instanceof  ProcessingException) {
2045:                        throw (ProcessingException) e; //rethrown - should be because of block
2046:                    } else {
2047:                        throw new IllegalStateException(
2048:                                "Should be ProcessingException after try block");
2049:                    }
2050:                } finally {
2051:                    if (i < n) { //still something un
2052:                        SimpleNode block = (SimpleNode) node.jjtGetChild(n - 1);
2053:                        if (block instanceof  AstFinallyBlock) {
2054:                            block.jjtAccept(this , data);
2055:                        }
2056:                    }
2057:                }
2058:            }
2059:
2060:            /**
2061:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstUnaryMinusExpression, java.lang.Object)
2062:             */
2063:            public Object visit(AstUnaryMinusExpression node, Object data)
2064:                    throws Exception {
2065:                return Evaluator.negate(node.jjtGetChild(0).jjtAccept(this ,
2066:                        data));
2067:            }
2068:
2069:            /**
2070:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstUnaryPlusExpression, java.lang.Object)
2071:             */
2072:            public Object visit(AstUnaryPlusExpression node, Object data)
2073:                    throws Exception {
2074:                return node.jjtGetChild(0).jjtAccept(this , data);
2075:            }
2076:
2077:            /**
2078:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstVariableDeclarator, java.lang.Object)
2079:             */
2080:            public Object visit(AstVariableDeclarator node, Object data)
2081:                    throws Exception {
2082:                Object[] passOn = (Object[]) data;
2083:                Object value = null;
2084:                if (node.jjtGetNumChildren() > 1) { //has initializer
2085:                    value = node.jjtGetChild(1).jjtAccept(this , null);
2086:                } else {
2087:                    AstType type = (AstType) passOn[0];
2088:                    if (type.jjtGetChild(0) instanceof  AstPrimitiveType) {
2089:                        AstPrimitiveType primitive = (AstPrimitiveType) type
2090:                                .jjtGetChild(0);
2091:                        value = PRIMITIVE_DEFAULTS.get(primitive.getData());
2092:                    }
2093:                }
2094:                String variableName = (String) ((AstVariableDeclaratorId) node
2095:                        .jjtGetChild(0)).getData();
2096:                if (((Boolean) passOn[1]).booleanValue()) {//static variable flag, pass from visit(AstFieldDeclaration)
2097:                    JxpPage page = getCurrentContext().getCurrentPage();
2098:                    if (!page.hasStaticVariable(variableName)) {
2099:                        page.declareStaticVariable(variableName, value);
2100:                    }
2101:                    return value;
2102:                } else {
2103:                    getCurrentContext().getNametableStack().declare(
2104:                            variableName, value);
2105:                    return value;
2106:                }
2107:            }
2108:
2109:            /**
2110:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstWhileStatement, java.lang.Object)
2111:             */
2112:            public Object visit(AstWhileStatement node, Object data)
2113:                    throws Exception {
2114:                Node condition = node.jjtGetChild(0);
2115:                Boolean b = Evaluator
2116:                        .toBoolean(condition.jjtAccept(this , data));
2117:                Object returnValue = null;
2118:                while (b.booleanValue()) {
2119:                    returnValue = node.jjtGetChild(1).jjtAccept(this , data);
2120:                    if (returnValue instanceof  Control) {
2121:                        if (returnValue == Control.CONTINUE) {
2122:                            returnValue = null; //clear up
2123:                        } else if (returnValue == Control.BREAK) {
2124:                            returnValue = null; //clear up
2125:                            break;
2126:                        } else { //must be return w/wo object
2127:                            break;
2128:                        }
2129:                    }
2130:                    b = Evaluator.toBoolean(condition.jjtAccept(this , data));
2131:                }
2132:                return returnValue;
2133:            }
2134:
2135:            /**
2136:             * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.SimpleNode, java.lang.Object)
2137:             */
2138:            public Object visit(SimpleNode node, Object data) throws Exception {
2139:                throw new IllegalStateException("Illegal state");
2140:            }
2141:
2142:            /**
2143:             * Flush the writer
2144:             * @throws IOException if there's io exception
2145:             */
2146:            public void flush() throws IOException {
2147:                getCurrentContext().getWriter().flush();
2148:            }
2149:
2150:            /** 
2151:             * {@inheritDoc}
2152:             * @todo support array type
2153:             * TODO support array type
2154:             */
2155:            public Object visit(AstType node, Object data) throws Exception {
2156:                Node child = node.jjtGetChild(0);
2157:                Class c = null;
2158:                if (child instanceof  AstName) {
2159:                    AstName name = (AstName) child;
2160:                    String className = toDottedName(name);
2161:                    c = getCurrentContext().resolveClass(className);
2162:                    if (c == null) {
2163:                        throw generateProcessingException(
2164:                                new ClassNotFoundException("Class " + className
2165:                                        + " not found"), node);
2166:                    }
2167:                } else {//primitive type
2168:                    c = (Class) ((AstPrimitiveType) child).getData();
2169:                }
2170:                //TODO: work on the dimension
2171:                return c;
2172:            }
2173:
2174:            /**
2175:             * Get the method stats
2176:             * @return the method stats
2177:             */
2178:            public Counter getMethodStats() {
2179:                return _methodStats;
2180:            }
2181:
2182:            /** 
2183:             * {@inheritDoc}
2184:             */
2185:            public Object visit(AstVariableDeclaratorId node, Object data)
2186:                    throws Exception {
2187:                // TODO Auto-generated method stub
2188:                throw generateProcessingException(
2189:                        new IllegalStateException(
2190:                                "visit(AstVariableDeclaratorId,Object) should not be called directly"),
2191:                        node);
2192:            }
2193:
2194:            /** 
2195:             * {@inheritDoc}
2196:             */
2197:            public Object visit(AstExitStatement node, Object data)
2198:                    throws Exception {
2199:                return Control.EXIT;
2200:            }
2201:
2202:            /** 
2203:             * {@inheritDoc}
2204:             */
2205:            public Object visit(AstStaticImportDeclaration node, Object data)
2206:                    throws Exception {
2207:                JxpProcessingContext context = getCurrentContext();
2208:                AstName name = (AstName) node.jjtGetChild(0);
2209:                String className = toDottedName(name);
2210:                Class c = context.resolveClass(className);
2211:                if (c == null) {
2212:                    throw generateProcessingException(
2213:                            new IllegalArgumentException(
2214:                                    "Cannot resolve class " + className), node);
2215:                }
2216:                StaticImport si = StaticImportUtils.getStaticImport(c);
2217:                context.addStaticImport(si);
2218:                Iterator it = si.getStaticFields().entrySet().iterator();
2219:                NametableStack ntStack = context.getNametableStack();
2220:                while (it.hasNext()) {
2221:                    Map.Entry entry = (Map.Entry) it.next();
2222:                    ntStack.declare((String) entry.getKey(), entry.getValue());
2223:                }
2224:                return null;
2225:            }
2226:
2227:            /** 
2228:             * {@inheritDoc}
2229:             */
2230:            public Object visit(AstVariableParameters node, Object data)
2231:                    throws Exception {
2232:                throw generateProcessingException(
2233:                        new IllegalStateException(
2234:                                "visit(AstVariableParameters) should not be called directly"),
2235:                        node);
2236:            }
2237:
2238:            /** 
2239:             * {@inheritDoc}
2240:             */
2241:            public Object visit(AstEnhancedForStatement node, Object data)
2242:                    throws Exception {
2243:                JxpProcessingContext context = getCurrentContext();
2244:                String variable = (String) node.getData();
2245:                Node statements = node.jjtGetChild(2);
2246:                Object colObj = node.jjtGetChild(1).jjtAccept(this , data);
2247:                if (colObj instanceof  Collection) {//must be
2248:                    Object returnValue = null;
2249:                    Iterator it = ((Collection) colObj).iterator();
2250:                    int newscope = context.getNametableStack().newScope();
2251:                    try {
2252:                        context.getNametableStack().declare(variable, null);
2253:                        while (it.hasNext()) {
2254:                            assignVariable(variable, it.next());
2255:                            returnValue = statements.jjtAccept(this , data);
2256:                            if (returnValue == Control.CONTINUE) {
2257:                                returnValue = null;
2258:                                //let it pass
2259:                            } else if (returnValue == Control.BREAK) {
2260:                                returnValue = null;
2261:                                break;
2262:                            } else if (returnValue instanceof  Control) { //must be return w/wo object
2263:                                break;
2264:                            }
2265:                        }
2266:                        return returnValue;
2267:                    } finally {
2268:                        context.getNametableStack().closeScope(newscope);
2269:                    }
2270:                } else {
2271:                    throw generateProcessingException(
2272:                            new IllegalArgumentException(
2273:                                    "Expression for enhanced for loop must be collection, get "
2274:                                            + colObj + " instead"), node);
2275:                }
2276:            }
2277:
2278:            public void setDoMethodStats(boolean flag) {
2279:                doMethodStats = flag;
2280:            }
2281:
2282:            public Object visit(AstNamedArgument node, Object data)
2283:                    throws Exception {
2284:                return node; //process it later
2285:            }
2286:
2287:            /**
2288:             * Get current environment
2289:             * @return the environment
2290:             */
2291:            public Map getEnvironment() {
2292:                return getCurrentContext().getNametableStack().asMap();
2293:            }
2294:
2295:            /**
2296:             * Return the checkFunctionArgumentType
2297:             * @return the checkFunctionArgumentType.
2298:             */
2299:            protected final boolean isCheckFunctionArgumentType() {
2300:                return _checkFunctionArgumentType;
2301:            }
2302:
2303:            /**
2304:             * Set the checkFunctionArgumentType
2305:             * @param checkFunctionArgumentType The checkFunctionArgumentType to set.
2306:             */
2307:            protected final void setCheckFunctionArgumentType(
2308:                    boolean checkFunctionArgumentType) {
2309:                _checkFunctionArgumentType = checkFunctionArgumentType;
2310:            }
2311:
2312:            public Object visit(AstPageDirective node, Object data)
2313:                    throws Exception {
2314:                Map m = (Map) node.getData();
2315:                if (m.containsKey("import")) {
2316:                    String imports = (String) m.get("import");
2317:                    JxpProcessingContext context = getCurrentContext();
2318:                    StringTokenizer st = new StringTokenizer(imports, ",");
2319:                    while (st.hasMoreTokens()) {
2320:                        String im = st.nextToken();
2321:                        context.getImports().addImport(im);
2322:                    }
2323:                }
2324:                return null;
2325:            }
2326:
2327:            public Object visit(AstIncludeDirective node, Object data)
2328:                    throws Exception {
2329:                return null;
2330:            }
2331:
2332:            public Object visit(AstIsEmptyExpression node, Object data)
2333:                    throws Exception {
2334:                Object obj = node.jjtGetChild(0).jjtAccept(this, data);
2335:                return Boolean.valueOf(StringUtils.isNullOrEmpty(obj));
2336:            }
2337:
2338:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.