Source Code Cross Referenced for TemplateProcessor.java in  » Build » invicta » net » sf » invicta » template » 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 » Build » invicta » net.sf.invicta.template 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package net.sf.invicta.template;
002:
003:        import java.util.ArrayList;
004:        import java.util.HashMap;
005:        import java.util.Iterator;
006:        import java.util.List;
007:        import java.util.Map;
008:        import java.util.StringTokenizer;
009:
010:        import net.sf.invicta.InvictaException;
011:        import net.sf.invicta.handler.InvictaHandler;
012:
013:        import sun.misc.Service;
014:
015:        /**
016:         * TemplateProcessor facility.
017:         * Based on TLA generic Template processing mechanism. 
018:         * TODO: Add support for an escape char (\).
019:         */
020:        public class TemplateProcessor {
021:            protected static final char HANDLER_SEPERATOR = ';';
022:            protected static final String EXTRA_SEPERATOR = ";";
023:            protected static final String EXTRA_MAP_SEPERATOR = "=";
024:            protected static final char ESCAPE = '%';
025:            protected static final char PLACEHOLDER_START = '{';
026:            protected static final char PLACEHOLDER_END = '}';
027:
028:            protected static Map handlers = new HashMap();
029:
030:            static {
031:                Iterator handlersIt = Service.providers(InvictaHandler.class);
032:                while (handlersIt.hasNext()) {
033:                    InvictaHandler handler = (InvictaHandler) handlersIt.next();
034:                    handlers.put(handler.getName(), handler);
035:                }
036:            }
037:
038:            /**
039:             * Retrieve TemplateHandler object for the given handler name.
040:             */
041:            protected static InvictaHandler getHandler(String handler) {
042:                return (InvictaHandler) handlers.get(handler);
043:            }
044:
045:            /**
046:             * Generic mechanism for creating part of the templates result. The template
047:             * is compiled into an array (list) of instructions that are executed
048:             * sequentially. The object retuned by each instruction is appended to the
049:             * result. Can throw an exception in case of error.
050:             * @author tla
051:             */
052:            protected static abstract class Instruction {
053:                public abstract Object handle(Object[][] parameters,
054:                        Object context) throws InvictaException,
055:                        InvictaException;
056:            }
057:
058:            /**
059:             * Static instruction that is consturcted with a text string that should be
060:             * added to the result in this specific location.
061:             * @author tla
062:             */
063:            protected static class StaticInstruction extends Instruction {
064:                private String text;
065:
066:                public StaticInstruction(String text) {
067:                    this .text = text;
068:                }
069:
070:                public Object handle(Object[][] parameters, Object context)
071:                        throws InvictaException {
072:                    return this .text;
073:                }
074:            }
075:
076:            /**
077:             * Dynamic instruction that is resolved using the supplied parameters. 
078:             * The key is used to find the parameter to use in this instruction (can
079:             * be null, when no parameter is needed). TemplateHandler, if supplied is called
080:             * with the parameter matched by the key (or null if there is no key). The
081:             * extra information is passed as a parameter to the handler. The format if
082:             * given is converted into a MessageFormat formating instruction and called
083:             * on the result of the handler/key.
084:             * @author tla
085:             */
086:            protected static class DynamicInstruction extends Instruction {
087:                protected String key = null;
088:                protected int position = -1;
089:                protected List extra = null;
090:
091:                public DynamicInstruction(String key, List extra) {
092:                    this .key = key;
093:                    // If the key is an int convert it and use it for optimized a
094:                    // access in case of position based placeholder.
095:                    try {
096:                        this .position = Integer.parseInt(key);
097:                    } catch (NumberFormatException e) {
098:                        // Ignore!
099:                    }
100:                    this .extra = extra;
101:                }
102:
103:                public Object handle(Object[][] parameters, Object context)
104:                        throws InvictaException {
105:                    Object object = null;
106:
107:                    boolean found = false;
108:                    // If a key is not empty, find the parameter matching the key.
109:                    if (!"".equals(key)) {
110:                        if (parameters == null)
111:                            throw new InvictaTemplateException(
112:                                    "Parameter "
113:                                            + key
114:                                            + " is needed, but no parameters were given");
115:                        if (position >= 0 && position < parameters.length) {
116:                            // If the key is a number, position will contain it in 
117:                            // number form. If it is a valid index into parameters use
118:                            // it as a hint of where to start looking for. This is an
119:                            // optimization of position based parameters.
120:                            int index = position;
121:                            for (int i = 0; i < parameters.length; i++) {
122:                                Object[] pair = parameters[index];
123:                                if (key.equals(pair[0])) {
124:                                    object = pair[1];
125:                                    found = true;
126:                                    break;
127:                                }
128:                                index = (index + 1) % parameters.length;
129:                            }
130:                        } else {
131:                            // Find the parameter by sequentially comparing the keys
132:                            // of the parameters.
133:                            for (int i = 0; i < parameters.length; i++) {
134:                                Object[] pair = parameters[i];
135:                                if (key.equals(pair[0])) {
136:                                    object = pair[1];
137:                                    found = true;
138:                                    break;
139:                                }
140:                            }
141:                        }
142:                    }
143:
144:                    if (!found) {
145:
146:                        // Find the handler for this name. 
147:                        InvictaHandler handler = (InvictaHandler) getHandler(key);
148:
149:                        if (handler == null)
150:                            throw new InvictaTemplateException(
151:                                    "Can't find parameter or handler named "
152:                                            + key);
153:
154:                        Map extraMap = lookForExtraMap(extra);
155:
156:                        if (extraMap == null)
157:                            object = handler.handle(context, extra);
158:                        else
159:                            object = handler.handle(context, extraMap);
160:
161:                    }
162:
163:                    // Nulls are not allowed. If the handler wants to allow nulls, they
164:                    // must be converted to something else (e.g. empty string).			
165:                    if (object == null)
166:                        throw new InvictaTemplateException(
167:                                "Got null result for '" + key + "'");
168:
169:                    return object;
170:                }
171:
172:                /**
173:                 * @param extra
174:                 * @return
175:                 */
176:                private Map lookForExtraMap(List extra) {
177:                    Map extraMap = new HashMap();
178:                    for (Iterator iter = extra.iterator(); iter.hasNext();) {
179:                        String param = (String) iter.next();
180:                        int equal = param.indexOf(EXTRA_MAP_SEPERATOR);
181:                        if (equal == -1)
182:                            return null;
183:                        extraMap.put(param.substring(0, equal), param
184:                                .substring(equal + 1));
185:                    }
186:
187:                    return extraMap;
188:                }
189:
190:            }
191:
192:            /**
193:             *  The  template compiled into an sequence of Instruction objects.
194:             */
195:            protected Instruction[] compiledFormat;
196:
197:            /**
198:             * The original template supplied.
199:             */
200:            protected String template;
201:
202:            /**
203:             * Context for the current template format
204:             */
205:            protected Object context;
206:
207:            /**
208:             * TemplateProcessor constructor using the given template.
209:             * @param template
210:             * @throws InvictaTemplateExceptioneption A runtime exception throws in case the
211:             * template parsing fails.
212:             */
213:            public TemplateProcessor(String template)
214:                    throws InvictaTemplateException {
215:                this (template, null);
216:            }
217:
218:            /**
219:             * TemplateProcessor constructor using the given template.
220:             * @param template	 
221:             * @throws InvictaTemplateExceptioneption A runtime exception throws in case the
222:             * template parsing fails.
223:             */
224:            public TemplateProcessor(String template, Object context)
225:                    throws InvictaTemplateException {
226:                this .template = template;
227:                this .context = context;
228:
229:                ArrayList compiledFormat = new ArrayList();
230:
231:                int length = template.length();
232:                int position = 0; // Current position in the template.
233:                try {
234:                    while (position < length) {
235:                        // Find the next escape sequence.
236:                        int beginIndex = template.indexOf(ESCAPE, position);
237:                        // If not found or found as the last character of the string.
238:                        // The rest of the string should be added as is.
239:                        if ((beginIndex == -1) || (beginIndex == length - 1)) {
240:                            compiledFormat.add(new StaticInstruction(template
241:                                    .substring(position)));
242:                            break;
243:                        }
244:
245:                        // If the next character is not the openning character, this
246:                        // is not really a placeholder, the string up to this character
247:                        // is added as is.
248:                        int nextIndex = beginIndex + 1;
249:                        char nextChar = template.charAt(nextIndex);
250:                        if (nextChar != PLACEHOLDER_START) {
251:                            if (nextChar == ESCAPE) {
252:                                // This is an escape sequence. Skip the second escape
253:                                // character.
254:
255:                                // Do Nothing.
256:                            } else {
257:                                // Otherwise skip the second character too.
258:                                nextIndex++;
259:                            }
260:
261:                            compiledFormat.add(new StaticInstruction(template
262:                                    .substring(position, nextIndex)));
263:
264:                            position = beginIndex + 2;
265:                            continue;
266:                        }
267:
268:                        // Find the end of the placeholder. Scream if not found.
269:                        int endIndex = template.indexOf(PLACEHOLDER_END,
270:                                beginIndex);
271:                        if (endIndex == -1) {
272:                            throw new InvictaTemplateException(
273:                                    "Can't find end of placeholder");
274:                        }
275:
276:                        // If there are characters before the beginning of the placeholder
277:                        // add them now.
278:                        if (position != beginIndex) {
279:                            compiledFormat.add(new StaticInstruction(template
280:                                    .substring(position, beginIndex)));
281:                        }
282:
283:                        String key = template.substring(beginIndex + 2,
284:                                endIndex);
285:
286:                        List extra = new ArrayList();
287:
288:                        // find possible extra information for handler.					
289:                        int semicolon = key.indexOf(HANDLER_SEPERATOR);
290:                        if (semicolon != -1) {
291:                            String extraString = key.substring(semicolon + 1);
292:                            StringTokenizer st = new StringTokenizer(
293:                                    extraString, EXTRA_SEPERATOR);
294:                            while (st.hasMoreTokens()) {
295:                                String extraParam = st.nextToken().trim();
296:                                extra.add(extraParam);
297:                            }
298:
299:                            key = key.substring(0, semicolon);
300:                        }
301:
302:                        DynamicInstruction instruction = new DynamicInstruction(
303:                                key, extra);
304:
305:                        compiledFormat.add(instruction);
306:
307:                        // Jump to the end of the placeholder.
308:                        position = endIndex + 1;
309:                    }
310:
311:                    // We save the compiled instruction list as an array for speed.
312:                    this .compiledFormat = (Instruction[]) compiledFormat
313:                            .toArray(new Instruction[compiledFormat.size()]);
314:                } catch (Throwable problem) {
315:                    // A problem was found when parsing the template. Wrap with an 
316:                    // appropriate exception. The format attempt is the given template
317:                    // since we couldn't even parse it.
318:                    throw new InvictaTemplateException("Can't parse template: "
319:                            + problem.getMessage(), problem, template);
320:
321:                }
322:            }
323:
324:            /**
325:             * Format the template represented by this object.
326:             * @param parameters The parameters to use when formatting the template.
327:             * Should be an array of arrays. The first element of each inner array is
328:             * the key name and the second is the value to use for that key.
329:             * @param buffer The formatted string is appended to this buffer.
330:             * @throws InvictaTemplateExceptioneption A runtime exception throws in case the
331:             * formatting fails.
332:             */
333:            public void format(Object[][] parameters, StringBuffer buffer)
334:                    throws InvictaTemplateException {
335:                Throwable problem = null;
336:                for (int i = 0; i < compiledFormat.length; i++) {
337:                    Instruction instruction = compiledFormat[i];
338:                    try {
339:                        buffer.append(instruction.handle(parameters, context));
340:                    } catch (Throwable t) {
341:                        problem = t;
342:                    }
343:                }
344:                if (problem != null) {
345:                    throw new InvictaTemplateException(
346:                            "Can't format template: " + problem.getMessage(),
347:                            problem, buffer.toString());
348:                }
349:            }
350:
351:            /**
352:             * Format the template represented by this object.
353:             * @param parameters The parameters to use when formatting the template.
354:             * Should be an array of arrays. The first element of each inner array is
355:             * the key name and the second is the value to use for that key.
356:             * @return String The formatted String.
357:             * @throws InvictaTemplateExceptioneption A runtime exception throws in case the
358:             * formatting fails.
359:             */
360:            public String format(Object[][] parameters)
361:                    throws InvictaTemplateException {
362:                StringBuffer buffer = new StringBuffer();
363:                format(parameters, buffer);
364:                return buffer.toString();
365:            }
366:
367:            static protected String[] conversion = new String[] { "0", "1",
368:                    "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12",
369:                    "13", "14", "15", "16", "17", "18", "19" };
370:
371:            /**
372:             * Transform position based parameters to key based parameters by making
373:             * each position into a key of the same value.
374:             * @param array The array to transform
375:             * @return Object[][] key based parameters in the format expected by
376:             * TemplateProcessor
377:             */
378:            public static Object[][] positionToKey(Object[] array) {
379:                if (array == null)
380:                    return null;
381:                Object[][] parameters = new Object[array.length][2];
382:                for (int i = 0; i < array.length; i++) {
383:                    parameters[i][0] = conversion[i];
384:                    parameters[i][1] = array[i];
385:                }
386:                return parameters;
387:            }
388:
389:            /**
390:             * Utility method for constructing a method and formatting together.
391:             * @param template TemplateProcessor format to use.
392:             * @param parameters Parameters used to format the template, can be null.
393:             * @param buffer The buffer to append the formatted String to.
394:             * @throws InvictaTemplateExceptioneption A runtime exception throws in case the
395:             * formatting fails.
396:             */
397:            public static void format(String template, Object[][] parameters,
398:                    StringBuffer buffer) throws InvictaTemplateException {
399:                new TemplateProcessor(template).format(parameters, buffer);
400:            }
401:
402:            /**
403:             * Utility method for constructing a method and formatting together.
404:             * @param template TemplateProcessor format to use.
405:             * @param parameters Parameters used to format the template, can be null.	  
406:             * @return String The formatted String.
407:             * @throws InvictaTemplateExceptioneption A runtime exception throws in case the
408:             * formatting fails.
409:             */
410:            public static String format(String template, Object[][] parameters)
411:                    throws InvictaTemplateException {
412:                return new TemplateProcessor(template).format(parameters);
413:            }
414:
415:            /**
416:             * Returns the context.
417:             * @return Object
418:             */
419:            public Object getContext() {
420:                return context;
421:            }
422:
423:            /**
424:             * Sets the context.
425:             * @param context The context to set
426:             */
427:            public void setContext(Object context) {
428:                this.context = context;
429:            }
430:
431:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.