Source Code Cross Referenced for MergedMarkup.java in  » J2EE » wicket » wicket » markup » 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 » J2EE » wicket » wicket.markup 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * $Id: MergedMarkup.java 460559 2006-05-08 16:02:10Z jdonnerstag $ $Revision:
003:         * 4913 $ $Date: 2006-05-08 18:02:10 +0200 (Mon, 08 May 2006) $
004:         * 
005:         * ==============================================================================
006:         * Licensed under the Apache License, Version 2.0 (the "License"); you may not
007:         * use this file except in compliance with the License. You may obtain a copy of
008:         * the License at
009:         * 
010:         * http://www.apache.org/licenses/LICENSE-2.0
011:         * 
012:         * Unless required by applicable law or agreed to in writing, software
013:         * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
014:         * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
015:         * License for the specific language governing permissions and limitations under
016:         * the License.
017:         */
018:        package wicket.markup;
019:
020:        import org.apache.commons.logging.Log;
021:        import org.apache.commons.logging.LogFactory;
022:
023:        import wicket.Page;
024:        import wicket.WicketRuntimeException;
025:        import wicket.markup.parser.XmlTag;
026:        import wicket.markup.parser.filter.HtmlHeaderSectionHandler;
027:        import wicket.util.string.Strings;
028:
029:        /**
030:         * A Markup class which represents merged markup, as it is required for markup
031:         * inheritance.
032:         * <p>
033:         * The Markups are merged at load time. Deep markup hierarchies are supported.
034:         * Multiple inheritance is not.
035:         * <p>
036:         * The markup resource file, which is associated with the markup, will be the
037:         * resource of the requested markup file. The base markup resources are not.
038:         * <p>
039:         * Base Markup must have a &lt;wicket:hild/&gt; tag which the position where the
040:         * derived markup is inserted. From the derived markup all tags in between
041:         * &lt;wicket:extend&gt; and &lt;/wicket:extend&gt; will be inserted.
042:         * <p>
043:         * In addition, all &lt;wicket:head> regions are copied as well as the body
044:         * onLoad attribute. This allows to develop completely self-contained plug &
045:         * play components including javascript etc.
046:         * 
047:         * @author Juergen Donnerstag
048:         */
049:        public class MergedMarkup extends Markup {
050:            private final static Log log = LogFactory
051:                    .getLog(MergedMarkup.class);
052:
053:            /**
054:             * Merge inherited and base markup.
055:             * 
056:             * @param markup
057:             *            The inherited markup
058:             * @param baseMarkup
059:             *            The base markup
060:             * @param extendIndex
061:             *            Index where <wicket:extend> has been found
062:             */
063:            MergedMarkup(final Markup markup, final Markup baseMarkup,
064:                    int extendIndex) {
065:                // Copy settings from derived markup
066:                setResource(markup.getResource());
067:                setXmlDeclaration(markup.getXmlDeclaration());
068:                setEncoding(markup.getEncoding());
069:                setWicketNamespace(markup.getWicketNamespace());
070:
071:                if (log.isDebugEnabled()) {
072:                    String derivedResource = Strings.afterLast(markup
073:                            .getResource().toString(), '/');
074:                    String baseResource = Strings.afterLast(baseMarkup
075:                            .getResource().toString(), '/');
076:                    log.debug("Merge markup: derived markup: "
077:                            + derivedResource + "; base markup: "
078:                            + baseResource);
079:                }
080:
081:                // Merge derived and base markup
082:                merge(markup, baseMarkup, extendIndex);
083:
084:                // Initialize internals based on new markup
085:                initialize();
086:
087:                if (log.isDebugEnabled()) {
088:                    log.debug("Merge markup: " + toDebugString());
089:                }
090:            }
091:
092:            /**
093:             * Return the body onLoad attribute of the markup
094:             * 
095:             * @param markup
096:             * @return onLoad attribute
097:             */
098:            private String getBodyOnLoadString(final Markup markup) {
099:                int i = 0;
100:
101:                // The markup must have a <wicket:head> region, else copying the
102:                // body onLoad attributes doesn't make sense
103:                for (; i < markup.size(); i++) {
104:                    MarkupElement elem = markup.get(i);
105:                    if (elem instanceof  WicketTag) {
106:                        WicketTag tag = (WicketTag) elem;
107:                        if (tag.isClose() && tag.isHeadTag()) {
108:                            // Ok, we found <wicket:head>
109:                            break;
110:                        } else if (tag.isMajorWicketComponentTag()) {
111:                            // Short cut: We found <wicket:panel> or <wicket:border>.
112:                            // There certainly will be no <wicket:head> later on.
113:                            return null;
114:                        }
115:                    } else if (elem instanceof  ComponentTag) {
116:                        ComponentTag tag = (ComponentTag) elem;
117:                        if (TagUtils.isBodyTag(tag)) {
118:                            // Short cut: We found <body> but no <wicket:head>.
119:                            // There certainly will be no <wicket:head> later on.
120:                            return null;
121:                        }
122:                    }
123:                }
124:
125:                // Found </wicket:head> => get body onLoad
126:                for (; i < markup.size(); i++) {
127:                    MarkupElement elem = markup.get(i);
128:                    if (elem instanceof  ComponentTag) {
129:                        ComponentTag tag = (ComponentTag) elem;
130:                        if (tag.isOpen() && TagUtils.isBodyTag(tag)) {
131:                            String onLoad = tag.getAttributes().getString(
132:                                    "onload");
133:                            return onLoad;
134:                        }
135:                    }
136:                }
137:
138:                return null;
139:            }
140:
141:            /**
142:             * Merge inherited and base markup.
143:             * 
144:             * @param markup
145:             *            The inherited markup
146:             * @param baseMarkup
147:             *            The base markup
148:             * @param extendIndex
149:             *            Index where <wicket:extend> has been found
150:             */
151:            private void merge(final Markup markup, final Markup baseMarkup,
152:                    int extendIndex) {
153:                // True if either <wicket:head> or <head> has been processed
154:                boolean wicketHeadProcessed = false;
155:
156:                // Add all elements from the base markup to the new list
157:                // until <wicket:child/> is found. Convert <wicket:child/>
158:                // into <wicket:child> and add it as well.
159:                WicketTag childTag = null;
160:                int baseIndex = 0;
161:                for (; baseIndex < baseMarkup.size(); baseIndex++) {
162:                    MarkupElement element = baseMarkup.get(baseIndex);
163:                    if (element instanceof  RawMarkup) {
164:                        // Add the element to the merged list
165:                        addMarkupElement(element);
166:                        continue;
167:                    }
168:
169:                    final ComponentTag tag = (ComponentTag) element;
170:
171:                    // Make sure all tags of the base markup remember where they are
172:                    // from
173:                    if ((baseMarkup.getResource() != null)
174:                            && (tag.getMarkupClass() == null)) {
175:                        tag.setMarkupClass(baseMarkup.getResource()
176:                                .getMarkupClass());
177:                    }
178:
179:                    if (element instanceof  WicketTag) {
180:                        WicketTag wtag = (WicketTag) element;
181:
182:                        // Found wicket.child in base markup. In case of 3+ level
183:                        // inheritance make sure the child tag is not from one of the
184:                        // deeper levels
185:                        if (wtag.isChildTag()
186:                                && (tag.getMarkupClass() == baseMarkup
187:                                        .getResource().getMarkupClass())) {
188:                            if (wtag.isOpenClose()) {
189:                                // <wicket:child /> => <wicket:child>...</wicket:child>
190:                                childTag = wtag;
191:                                WicketTag childOpenTag = (WicketTag) wtag
192:                                        .mutable();
193:                                childOpenTag.getXmlTag().setType(XmlTag.OPEN);
194:                                childOpenTag.setMarkupClass(baseMarkup
195:                                        .getResource().getMarkupClass());
196:                                addMarkupElement(childOpenTag);
197:                                break;
198:                            } else if (wtag.isOpen()) {
199:                                // <wicket:child>
200:                                addMarkupElement(wtag);
201:                                break;
202:                            } else {
203:                                throw new WicketRuntimeException(
204:                                        "Did not expect a </wicket:child> tag in "
205:                                                + baseMarkup.toString());
206:                            }
207:                        }
208:
209:                        // Process the head of the extended markup only once
210:                        if (wicketHeadProcessed == false) {
211:                            // if </wicket:head> in base markup
212:                            if (wtag.isClose() && wtag.isHeadTag()) {
213:                                wicketHeadProcessed = true;
214:
215:                                // Add the current close tag
216:                                addMarkupElement(wtag);
217:
218:                                // Add the <wicket:head> body from the derived markup.
219:                                copyWicketHead(markup, extendIndex);
220:
221:                                // Do not add the current tag. It has already been
222:                                // added.
223:                                continue;
224:                            }
225:
226:                            // if <wicket:panel> or ... in base markup
227:                            if (wtag.isOpen()
228:                                    && wtag.isMajorWicketComponentTag()) {
229:                                wicketHeadProcessed = true;
230:
231:                                // Add the <wicket:head> body from the derived markup.
232:                                copyWicketHead(markup, extendIndex);
233:                            }
234:                        }
235:                    }
236:
237:                    // Process the head of the extended markup only once
238:                    if (wicketHeadProcessed == false) {
239:                        // if <head> in base markup
240:                        if ((tag.isClose() && TagUtils.isHeadTag(tag))
241:                                || (tag.isOpen() && TagUtils.isBodyTag(tag))) {
242:                            wicketHeadProcessed = true;
243:
244:                            // Add the <wicket:head> body from the derived markup.
245:                            copyWicketHead(markup, extendIndex);
246:                        }
247:                    }
248:
249:                    // Make sure the body onLoad attribute from the extended markup is
250:                    // copied to the new markup
251:                    if (tag.isOpen() && TagUtils.isBodyTag(tag)) {
252:                        // Get the body onLoad attribute from derived markup
253:                        final String onLoad = getBodyOnLoadString(markup);
254:
255:                        String onLoadBase = tag.getAttributes().getString(
256:                                "onload");
257:                        if (onLoadBase == null) {
258:                            if (onLoad != null) {
259:                                ComponentTag mutableTag = tag.mutable();
260:                                mutableTag.getAttributes()
261:                                        .put("onload", onLoad);
262:                                element = mutableTag;
263:                            }
264:                        } else if (onLoad != null) {
265:                            onLoadBase += onLoad;
266:                            ComponentTag mutableTag = tag.mutable();
267:                            mutableTag.getAttributes()
268:                                    .put("onload", onLoadBase);
269:                            element = mutableTag;
270:                        }
271:                    }
272:
273:                    // Add the element to the merged list
274:                    addMarkupElement(element);
275:                }
276:
277:                if (baseIndex == baseMarkup.size()) {
278:                    throw new WicketRuntimeException(
279:                            "Expected to find <wicket:child/> in base markup: "
280:                                    + baseMarkup.toString());
281:                }
282:
283:                // Now append all elements from the derived markup starting with
284:                // <wicket:extend> until </wicket:extend> to the list
285:                for (; extendIndex < markup.size(); extendIndex++) {
286:                    MarkupElement element = markup.get(extendIndex);
287:                    addMarkupElement(element);
288:
289:                    if (element instanceof  WicketTag) {
290:                        WicketTag wtag = (WicketTag) element;
291:                        if (wtag.isExtendTag() && wtag.isClose()) {
292:                            break;
293:                        }
294:                    }
295:                }
296:
297:                if (extendIndex == markup.size()) {
298:                    throw new WicketRuntimeException(
299:                            "Missing close tag </wicket:extend> in derived markup: "
300:                                    + markup.toString());
301:                }
302:
303:                // If <wicket:child> than skip the body and find </wicket:child>
304:                if (((ComponentTag) baseMarkup.get(baseIndex)).isOpen()) {
305:                    for (baseIndex++; baseIndex < baseMarkup.size(); baseIndex++) {
306:                        MarkupElement element = baseMarkup.get(baseIndex);
307:                        if (element instanceof  WicketTag) {
308:                            WicketTag tag = (WicketTag) element;
309:                            if (tag.isChildTag() && tag.isClose()) {
310:                                // Ok, skipped the childs content
311:                                tag.setMarkupClass(baseMarkup.getResource()
312:                                        .getMarkupClass());
313:                                addMarkupElement(tag);
314:                                break;
315:                            } else {
316:                                throw new WicketRuntimeException(
317:                                        "Wicket tags like <wicket:xxx> are not allowed in between <wicket:child> and </wicket:child> tags: "
318:                                                + markup.toString());
319:                            }
320:                        } else if (element instanceof  ComponentTag) {
321:                            throw new WicketRuntimeException(
322:                                    "Wicket tags identified by wicket:id are not allowed in between <wicket:child> and </wicket:child> tags: "
323:                                            + markup.toString());
324:                        }
325:                    }
326:
327:                    // </wicket:child> not found
328:                    if (baseIndex == baseMarkup.size()) {
329:                        throw new WicketRuntimeException(
330:                                "Expected to find </wicket:child> in base markup: "
331:                                        + baseMarkup.toString());
332:                    }
333:                } else {
334:                    // And now all remaining elements from the derived markup.
335:                    // But first add </wicket:child>
336:                    WicketTag childCloseTag = (WicketTag) childTag.mutable();
337:                    childCloseTag.getXmlTag().setType(XmlTag.CLOSE);
338:                    childCloseTag.setMarkupClass(baseMarkup.getResource()
339:                            .getMarkupClass());
340:                    addMarkupElement(childCloseTag);
341:                }
342:
343:                for (baseIndex++; baseIndex < baseMarkup.size(); baseIndex++) {
344:                    MarkupElement element = baseMarkup.get(baseIndex);
345:                    addMarkupElement(element);
346:
347:                    // Make sure all tags of the base markup remember where they are
348:                    // from
349:                    if ((element instanceof  ComponentTag)
350:                            && (baseMarkup.getResource() != null)) {
351:                        ComponentTag tag = (ComponentTag) element;
352:                        tag.setMarkupClass(baseMarkup.getResource()
353:                                .getMarkupClass());
354:                    }
355:                }
356:
357:                // Automatically add <head> if missing and required. On a Page
358:                // it must enclose ALL of the <wicket:head> tags.
359:                // Note: HtmlHeaderSectionHandler does something similar, but because
360:                // markup filters are not called for merged markup again, ...
361:                if (Page.class.isAssignableFrom(markup.getResource()
362:                        .getMarkupClass())) {
363:                    // Find the position inside the markup for first <wicket:head>,
364:                    // last </wicket:head> and <head>
365:                    int hasOpenWicketHead = -1;
366:                    int hasCloseWicketHead = -1;
367:                    int hasHead = -1;
368:                    for (int i = 0; i < size(); i++) {
369:                        MarkupElement element = get(i);
370:
371:                        if ((hasOpenWicketHead == -1)
372:                                && (element instanceof  WicketTag)
373:                                && ((WicketTag) element).isHeadTag()) {
374:                            hasOpenWicketHead = i;
375:                        } else if ((element instanceof  WicketTag)
376:                                && ((WicketTag) element).isHeadTag()
377:                                && ((WicketTag) element).isClose()) {
378:                            hasCloseWicketHead = i;
379:                        } else if ((hasHead == -1)
380:                                && (element instanceof  ComponentTag)
381:                                && TagUtils.isHeadTag((ComponentTag) element)) {
382:                            hasHead = i;
383:                        } else if ((hasHead != -1) && (hasOpenWicketHead != -1)) {
384:                            break;
385:                        }
386:                    }
387:
388:                    // If a <head> tag is missing, insert it automatically
389:                    if ((hasOpenWicketHead != -1) && (hasHead == -1)) {
390:                        final XmlTag headOpenTag = new XmlTag();
391:                        headOpenTag.setName("head");
392:                        headOpenTag.setType(XmlTag.OPEN);
393:                        final ComponentTag openTag = new ComponentTag(
394:                                headOpenTag);
395:                        openTag.setId(HtmlHeaderSectionHandler.HEADER_ID);
396:
397:                        final XmlTag headCloseTag = new XmlTag();
398:                        headCloseTag.setName(headOpenTag.getName());
399:                        headCloseTag.setType(XmlTag.CLOSE);
400:                        final ComponentTag closeTag = new ComponentTag(
401:                                headCloseTag);
402:                        closeTag.setOpenTag(openTag);
403:                        closeTag.setId(HtmlHeaderSectionHandler.HEADER_ID);
404:
405:                        addMarkupElement(hasOpenWicketHead, openTag);
406:                        addMarkupElement(hasCloseWicketHead + 2, closeTag);
407:                    }
408:                }
409:            }
410:
411:            /**
412:             * Append the wicket:head regions from the extended markup to the current
413:             * markup
414:             * 
415:             * @param markup
416:             * @param extendIndex
417:             */
418:            private void copyWicketHead(final Markup markup, int extendIndex) {
419:                boolean copy = false;
420:                for (int i = 0; i < extendIndex; i++) {
421:                    MarkupElement elem = markup.get(i);
422:                    if (elem instanceof  WicketTag) {
423:                        WicketTag etag = (WicketTag) elem;
424:                        if (etag.isHeadTag()) {
425:                            if (etag.isOpen()) {
426:                                copy = true;
427:                            } else {
428:                                addMarkupElement(elem);
429:                                break;
430:                            }
431:                        }
432:                    }
433:
434:                    if (copy == true) {
435:                        addMarkupElement(elem);
436:                    }
437:                }
438:            }
439:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.