Source Code Cross Referenced for ViewRender.java in  » Web-Framework » RSF » uk » org » ponder » rsf » renderer » 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 » Web Framework » RSF » uk.org.ponder.rsf.renderer 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Created on Aug 7, 2005
003:         */
004:        package uk.org.ponder.rsf.renderer;
005:
006:        import java.util.HashMap;
007:        import java.util.HashSet;
008:        import java.util.Iterator;
009:        import java.util.List;
010:        import java.util.Map;
011:        import java.util.Set;
012:
013:        import uk.org.ponder.arrayutil.ListUtil;
014:        import uk.org.ponder.messageutil.TargettedMessageList;
015:        import uk.org.ponder.rsf.components.UIBranchContainer;
016:        import uk.org.ponder.rsf.components.UIComponent;
017:        import uk.org.ponder.rsf.components.UIContainer;
018:        import uk.org.ponder.rsf.content.ContentTypeInfo;
019:        import uk.org.ponder.rsf.renderer.decorator.DecoratorManager;
020:        import uk.org.ponder.rsf.template.XMLCompositeViewTemplate;
021:        import uk.org.ponder.rsf.template.XMLLump;
022:        import uk.org.ponder.rsf.template.XMLLumpList;
023:        import uk.org.ponder.rsf.template.XMLLumpMMap;
024:        import uk.org.ponder.rsf.template.XMLViewTemplate;
025:        import uk.org.ponder.rsf.util.RSFUtil;
026:        import uk.org.ponder.rsf.util.SplitID;
027:        import uk.org.ponder.rsf.view.View;
028:        import uk.org.ponder.rsf.view.ViewTemplate;
029:        import uk.org.ponder.streamutil.write.PrintOutputStream;
030:        import uk.org.ponder.stringutil.CharWrap;
031:        import uk.org.ponder.util.Logger;
032:        import uk.org.ponder.xml.XMLUtil;
033:        import uk.org.ponder.xml.XMLWriter;
034:
035:        /**
036:         * Encapsulates the request-specific process of rendering a view - a
037:         * request-scope bean containing the implementation of the IKAT rendering
038:         * algorithm.
039:         * 
040:         * @author Antranig Basman (antranig@caret.cam.ac.uk)
041:         * 
042:         */
043:        public class ViewRender {
044:            private XMLViewTemplate roott;
045:            private XMLLumpMMap globalmap;
046:
047:            private View view;
048:            private RenderSystem renderer;
049:            private PrintOutputStream pos;
050:            private XMLWriter xmlw;
051:
052:            // a map of UIBranchContainer to XMLLump
053:            private Map branchmap;
054:            private XMLLumpMMap collected = new XMLLumpMMap();
055:
056:            private XMLLump messagelump;
057:
058:            private TargettedMessageList messagelist;
059:            // a map of HTMLLumps to StringList of messages due to be delivered to
060:            // that component when it is reached (registered with a FORID prefix)
061:            private MessageTargetMap messagetargets;
062:            private MessageRenderer messagerenderer;
063:            private String globalmessagetarget;
064:            private boolean rendereddeadletters;
065:            private ContentTypeInfo contenttypeinfo;
066:            private IDAssigner IDassigner;
067:            private DecoratorManager decoratormanager;
068:            private boolean debugrender;
069:            private RenderSystemContext rsc;
070:
071:            public void setViewTemplate(ViewTemplate viewtemplateo) {
072:                if (viewtemplateo instanceof  XMLCompositeViewTemplate) {
073:                    XMLCompositeViewTemplate viewtemplate = (XMLCompositeViewTemplate) viewtemplateo;
074:                    roott = viewtemplate.roottemplate;
075:                    globalmap = viewtemplate.globalmap;
076:                    collected.aggregate(viewtemplate.mustcollectmap);
077:                } else {
078:                    roott = (XMLViewTemplate) viewtemplateo;
079:                    globalmap = roott.globalmap;
080:                }
081:
082:            }
083:
084:            public void setView(View view) {
085:                this .view = view;
086:            }
087:
088:            public void setRenderSystem(RenderSystem renderer) {
089:                this .renderer = renderer;
090:            }
091:
092:            public void setContentTypeInfo(ContentTypeInfo contenttypeinfo) {
093:                this .contenttypeinfo = contenttypeinfo;
094:            }
095:
096:            public void setMessages(TargettedMessageList messages) {
097:                this .messagelist = messages;
098:            }
099:
100:            public void setGlobalMessageTarget(String globalmessagetarget) {
101:                this .globalmessagetarget = globalmessagetarget;
102:            }
103:
104:            public void setMessageRenderer(MessageRenderer messagerenderer) {
105:                this .messagerenderer = messagerenderer;
106:            }
107:
108:            public void setDecoratorManager(DecoratorManager decoratormanager) {
109:                this .decoratormanager = decoratormanager;
110:            }
111:
112:            public void setDebugRender(boolean debugrender) {
113:                this .debugrender = debugrender;
114:            }
115:
116:            private void collectContributions() {
117:                Set seenset = new HashSet();
118:                for (Iterator lumpit = branchmap.values().iterator(); lumpit
119:                        .hasNext();) {
120:                    XMLLump headlump = (XMLLump) lumpit.next();
121:                    if (!seenset.contains(headlump.parent)) {
122:                        collected.aggregate(headlump.parent.collectmap);
123:                        seenset.add(headlump.parent);
124:                    }
125:                }
126:            }
127:
128:            private void debugGlobalTargets() {
129:                renderer.renderDebugMessage(rsc,
130:                        "All global branch targets in resolution set:");
131:                for (Iterator globalit = globalmap.iterator(); globalit
132:                        .hasNext();) {
133:                    String key = (String) globalit.next();
134:                    if (key.indexOf(':') != -1) {
135:                        renderer.renderDebugMessage(rsc, "Branch key " + key);
136:                        XMLLumpList res = globalmap.headsForID(key);
137:                        for (int i = 0; i < res.size(); ++i) {
138:                            renderer.renderDebugMessage(rsc, "\t"
139:                                    + res.lumpAt(i).toString());
140:                        }
141:                    }
142:                }
143:                renderer.renderDebugMessage(rsc, "");
144:            }
145:
146:            public void render(PrintOutputStream pos) {
147:                IDassigner = new IDAssigner(
148:                        debugrender ? ContentTypeInfo.ID_FORCE
149:                                : contenttypeinfo.IDStrategy);
150:                UIBranchContainer messagecomponent = UIBranchContainer.make(
151:                        view.viewroot, MessageTargetter.RSF_MESSAGES);
152:                branchmap = BranchResolver.resolveBranches(globalmap,
153:                        view.viewroot, roott.rootlump);
154:                view.viewroot.remove(messagecomponent);
155:                messagelump = (XMLLump) branchmap.get(messagecomponent);
156:                collectContributions();
157:                messagetargets = MessageTargetter.targetMessages(branchmap,
158:                        view, messagelist, globalmessagetarget);
159:                String declaration = contenttypeinfo.get().declaration;
160:                if (declaration != null)
161:                    pos.print(declaration);
162:                this .pos = pos;
163:                this .xmlw = new XMLWriter(pos);
164:                rsc = new RenderSystemContext(debugrender, view, pos, xmlw,
165:                        IDassigner, collected);
166:                rendereddeadletters = false;
167:                if (debugrender) {
168:                    debugGlobalTargets();
169:                }
170:                renderRecurse(view.viewroot, roott.rootlump,
171:                        roott.lumps[roott.roottagindex]);
172:            }
173:
174:            private void renderContainer(UIContainer child, XMLLump targetlump) {
175:                // may have jumped template file
176:                XMLViewTemplate t2 = targetlump.parent;
177:                XMLLump firstchild = t2.lumps[targetlump.open_end.lumpindex + 1];
178:                if (child instanceof  UIBranchContainer) {
179:                    dumpBranchHead((UIBranchContainer) child, targetlump);
180:                } else {
181:                    renderer.renderComponent(rsc, child, targetlump);
182:                }
183:                renderRecurse(child, targetlump, firstchild);
184:            }
185:
186:            private void renderRecurse(UIContainer basecontainer,
187:                    XMLLump parentlump, XMLLump baselump) {
188:
189:                int renderindex = baselump.lumpindex;
190:                int basedepth = parentlump.nestingdepth;
191:                XMLViewTemplate tl = parentlump.parent;
192:                Set rendered = null;
193:                if (debugrender) {
194:                    rendered = new HashSet();
195:                }
196:
197:                while (true) {
198:                    // continue scanning along this template section until we either each
199:                    // the last lump, or the recursion level.
200:                    renderindex = RenderUtil.dumpScan(tl.lumps, renderindex,
201:                            basedepth, pos, true, false);
202:                    if (renderindex == tl.lumps.length)
203:                        break;
204:                    XMLLump lump = tl.lumps[renderindex];
205:                    if (lump.nestingdepth < basedepth)
206:                        break;
207:
208:                    String id = lump.rsfID;
209:                    if (id == null) {
210:                        throw new IllegalArgumentException(
211:                                "Fatal internal error during rendering - no rsf:id found on stopping tag "
212:                                        + lump);
213:                    }
214:                    if (id.startsWith(XMLLump.ELISION_PREFIX)) {
215:                        id = id.substring(XMLLump.ELISION_PREFIX.length());
216:                    }
217:                    boolean ismessagefor = id.startsWith(XMLLump.FORID_PREFIX);
218:
219:                    if (!ismessagefor && SplitID.isSplit(id)) {
220:                        // we have entered a repetitive domain, by diagnosis of the template.
221:                        // Seek in the component tree for the child list that must be here
222:                        // at this component, and process them in order, looking them up in
223:                        // the forward map, which must ALSO be here.
224:                        String prefix = SplitID.getPrefix(id);
225:                        List children = fetchComponents(basecontainer, prefix);
226:                        // these are all children with the same prefix, which will be rendered
227:                        // synchronously.
228:                        if (children != null) {
229:                            for (int i = 0; i < children.size(); ++i) {
230:                                UIComponent child = (UIComponent) children
231:                                        .get(i);
232:                                if (child instanceof  UIContainer) {
233:                                    XMLLump targetlump = (XMLLump) branchmap
234:                                            .get(child);
235:                                    if (targetlump != null) {
236:                                        if (debugrender) {
237:                                            renderComment("Branching for "
238:                                                    + child.getFullID()
239:                                                    + " from " + lump + " to "
240:                                                    + targetlump);
241:                                        }
242:                                        renderContainer((UIContainer) child,
243:                                                targetlump);
244:                                        if (debugrender) {
245:                                            renderComment("Branch returned for "
246:                                                    + child.getFullID()
247:                                                    + " to "
248:                                                    + lump
249:                                                    + " from "
250:                                                    + targetlump);
251:                                        }
252:                                    } else {
253:                                        if (debugrender) {
254:                                            renderer
255:                                                    .renderDebugMessage(
256:                                                            rsc,
257:                                                            "No matching template branch found for branch container with full ID "
258:                                                                    + child
259:                                                                            .getFullID()
260:                                                                    + " rendering from parent template branch "
261:                                                                    + baselump
262:                                                                            .toString());
263:                                        }
264:                                    }
265:                                } else { // repetitive leaf
266:                                    XMLLump targetlump = findChild(parentlump,
267:                                            child);
268:                                    // this case may trigger if there are suffix-specific renderers
269:                                    // but no fallback.
270:                                    if (targetlump == null) {
271:                                        renderer
272:                                                .renderDebugMessage(
273:                                                        rsc,
274:                                                        "Repetitive leaf with full ID "
275:                                                                + child
276:                                                                        .getFullID()
277:                                                                + " could not be rendered from parent template branch "
278:                                                                + baselump
279:                                                                        .toString());
280:                                        continue;
281:                                    }
282:                                    int renderend = renderer.renderComponent(
283:                                            rsc, child, targetlump);
284:                                    boolean wasopentag = tl.lumps[renderend].nestingdepth >= targetlump.nestingdepth;
285:                                    UIContainer newbase = child instanceof  UIContainer ? (UIContainer) child
286:                                            : basecontainer;
287:                                    if (wasopentag) {
288:                                        renderRecurse(newbase, targetlump,
289:                                                tl.lumps[renderend]);
290:                                        renderend = targetlump.close_tag.lumpindex + 1;
291:                                    }
292:                                    if (i != children.size() - 1) {
293:                                        // at this point, magically locate any "glue" that matches the
294:                                        // transition
295:                                        // from this component to the next in the template, and scan
296:                                        // along
297:                                        // until we reach the next component with a matching id prefix.
298:                                        // NB transition matching is not implemented and may never be.
299:                                        RenderUtil.dumpScan(tl.lumps,
300:                                                renderend,
301:                                                targetlump.nestingdepth - 1,
302:                                                pos, false, false);
303:                                        // we discard any index reached by this dump, continuing the
304:                                        // controlled sequence as long as there are any children.
305:                                        // given we are in the middle of a sequence here, we expect to
306:                                        // see nothing perverse like components or forms, at most static
307:                                        // things (needing rewriting?)
308:                                        // TODO: split of beginning logic from renderComponent that
309:                                        // deals
310:                                        // with static rewriting, and somehow fix this call to dumpScan
311:                                        // so that it can invoke it. Not urgent, we currently only have
312:                                        // the TINIEST text forming repetition glue.
313:                                    } else {
314:                                        RenderUtil.dumpScan(tl.lumps,
315:                                                renderend,
316:                                                targetlump.nestingdepth, pos,
317:                                                true, false);
318:                                    }
319:                                }
320:
321:                            } // end for each repetitive child
322:                        } else {
323:                            if (debugrender) {
324:                                renderer
325:                                        .renderDebugMessage(
326:                                                rsc,
327:                                                "No branch container with prefix "
328:                                                        + prefix
329:                                                        + ": found at "
330:                                                        + RSFUtil
331:                                                                .reportPath(basecontainer)
332:                                                        + " at template position "
333:                                                        + baselump.toString()
334:                                                        + ", skipping");
335:                            }
336:                        }
337:                        // at this point, magically locate the "postamble" from lump, and
338:                        // reset the index.
339:
340:                        XMLLump finallump = lump.uplump.getFinal(prefix);
341:                        //parentlump.downmap.getFinal(prefix);
342:                        XMLLump closefinal = finallump.close_tag;
343:                        renderindex = closefinal.lumpindex + 1;
344:                        if (debugrender) {
345:                            renderComment("Stack returned from branch for ID "
346:                                    + id + " to " + baselump.toString()
347:                                    + ": skipping from " + lump.toString()
348:                                    + " to " + closefinal.toString());
349:                        }
350:                    } else if (ismessagefor) {
351:                        TargettedMessageList messages = messagetargets
352:                                .getMessages(lump);
353:                        if (messages == null)
354:                            messages = new TargettedMessageList();
355:                        if (!rendereddeadletters) {
356:                            rendereddeadletters = true;
357:                            TargettedMessageList deadmessages = messagetargets
358:                                    .getMessages(MessageTargetter.DEAD_LETTERS);
359:                            if (deadmessages != null) {
360:                                messages.addMessages(deadmessages);
361:                            }
362:                        }
363:                        if (messages.size() != 0) {
364:                            if (messagelump == null) {
365:                                Logger.log
366:                                        .warn("No message template is configured (containing branch with rsf id rsf-messages:)");
367:                            } else {
368:                                UIBranchContainer messagebranch = messagerenderer
369:                                        .renderMessageList(messages);
370:                                renderContainer(messagebranch, messagelump);
371:                            }
372:                        }
373:                        XMLLump closelump = lump.close_tag;
374:                        renderindex = closelump.lumpindex + 1;
375:                    } else {
376:                        // no colon - continue template-driven.
377:                        // it is a single, irrepitable component - just render it, and skip
378:                        // on, or skip completely if there is no peer in the component tree.
379:                        UIComponent component = null;
380:                        if (id != null) {
381:                            if (debugrender) {
382:                                rendered.add(id);
383:                            }
384:                            component = fetchComponent(basecontainer, id);
385:                        }
386:                        // Form rendering is now subject to "fairly normal" branch rendering logic
387:                        // That is, a UIContainer may now also be a leaf
388:                        if (component instanceof  UIContainer) {
389:                            renderContainer((UIContainer) component, lump);
390:                            renderindex = lump.close_tag.lumpindex + 1;
391:                        } else {
392:                            // if we find a leaf component, render it.
393:                            renderindex = renderer.renderComponent(rsc,
394:                                    component, lump);
395:                        }
396:                    } // end if unrepeatable component.
397:                    if (renderindex == tl.lumps.length) {
398:                        // deal with the case where component was root element - Ryan of
399:                        // 11/10/06
400:                        break;
401:                    }
402:                }
403:                if (debugrender) {
404:                    UIComponent[] flatchildren = basecontainer.flatChildren();
405:                    for (int i = 0; i < flatchildren.length; ++i) {
406:                        UIComponent child = flatchildren[i];
407:                        if (!(child.ID.indexOf(':') != -1)
408:                                && !rendered.contains(child.ID)) {
409:                            renderer
410:                                    .renderDebugMessage(
411:                                            rsc,
412:                                            "Leaf child component "
413:                                                    + child.getClass()
414:                                                            .getName()
415:                                                    + " with full ID "
416:                                                    + child.getFullID()
417:                                                    + " could not be found within template "
418:                                                    + baselump.toString());
419:                        }
420:                    }
421:                }
422:            }
423:
424:            private void renderComment(String string) {
425:                pos.print("<!-- " + string + "-->");
426:
427:            }
428:
429:            private UIComponent fetchComponent(UIContainer basecontainer,
430:                    String id) {
431:                if (id.startsWith(XMLLump.MSG_PREFIX)) {
432:                    String key = id.substring(XMLLump.MSG_PREFIX.length());
433:                    return messagerenderer.renderMessage(key);
434:                }
435:                while (basecontainer != null) {
436:                    UIComponent togo = basecontainer.getComponent(id);
437:                    if (togo != null)
438:                        return togo;
439:                    basecontainer = basecontainer.parent;
440:                }
441:                return null;
442:            }
443:
444:            private static List fetchComponents(UIContainer basecontainer,
445:                    String id) {
446:                Object togo = null;
447:                while (basecontainer != null) {
448:                    togo = basecontainer.getComponents(id);
449:                    if (togo != null)
450:                        break;
451:                    basecontainer = basecontainer.parent;
452:                }
453:                return togo == null ? null
454:                        : (togo instanceof  List ? (List) togo : ListUtil
455:                                .instance(togo));
456:            }
457:
458:            private XMLLump findChild(XMLLump sourcescope, UIComponent child) {
459:                // if child is not a container, there can be no lookahead in resolution,
460:                // and it must resolve to a component in THIS container which either
461:                // matches exactly or in prefix.
462:                SplitID split = new SplitID(child.ID);
463:                XMLLumpList headlumps = sourcescope.downmap
464:                        .headsForID(child.ID);
465:                if (headlumps == null) {
466:                    headlumps = sourcescope.downmap.headsForID(split.prefix
467:                            + SplitID.SEPARATOR);
468:                    // if (headlumps.size() == 0) {
469:                    // throw UniversalRuntimeException.accumulate(new IOException(),
470:                    // "Error in template file: peer for component with ID " + child.ID
471:                    // + " not found in scope " + sourcescope.toDebugString());
472:                    // }
473:                }
474:                return headlumps == null ? null : headlumps.lumpAt(0);
475:            }
476:
477:            private void dumpBranchHead(UIBranchContainer branch,
478:                    XMLLump targetlump) {
479:                HashMap attrcopy = new HashMap();
480:                attrcopy.putAll(targetlump.attributemap);
481:                IDassigner.adjustForID(attrcopy, branch);
482:                decoratormanager.decorate(branch.decorators, targetlump
483:                        .getTag(), attrcopy);
484:                // TODO: normalise this silly space business
485:                pos.write(targetlump.parent.buffer, targetlump.start,
486:                        targetlump.length - 1);
487:                XMLUtil.dumpAttributes(attrcopy, xmlw);
488:                pos.print(">");
489:            }
490:
491:            public static String debugLump(XMLLump debug) {
492:                XMLLump[] lumps = debug.parent.lumps;
493:                CharWrap message = new CharWrap();
494:                message.append("Lump index " + debug.lumpindex + " (line "
495:                        + debug.line + " column " + debug.column + ") ");
496:                int frontpoint = debug.lumpindex - 5;
497:                if (frontpoint < 0)
498:                    frontpoint = 0;
499:                int endpoint = debug.lumpindex + 5;
500:                if (frontpoint > lumps.length)
501:                    frontpoint = lumps.length;
502:                for (int i = frontpoint; i < endpoint; ++i) {
503:                    if (i == debug.lumpindex) {
504:                        message.append("(*)");
505:                    }
506:                    XMLLump lump = lumps[i];
507:                    message.append(lump.parent.buffer, lump.start, lump.length);
508:                }
509:                if (debug.downmap != null) {
510:                    message.append("\nDownmap here: ").append(
511:                            debug.downmap.getHeadsDebug());
512:                }
513:                return message.toString();
514:            }
515:
516:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.