Author: jdonnerstag Date: Thu Dec 2 20:58:51 2010 New Revision: 1041581 URL: http://svn.apache.org/viewvc?rev=1041581&view=rev Log: - javadoc improvements - replace some constants with enum - added basic support for <!DOCTYPE ..> detection which is needed for HTML5 support
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/html/MarkupUtil.java wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/DoctypeExpectedResult_1.html wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/DoctypeExpectedResult_2.html wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/Doctype_1.html wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/Doctype_1.java wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/Doctype_2.html wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/Doctype_2.java Modified: wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/io/XmlReader.java wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/AbstractMarkupParser.java wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/MarkupFactory.java wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/MarkupResourceStream.java wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/TagUtils.java wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/loader/DefaultMarkupLoader.java wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/loader/IMarkupLoader.java wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/loader/InheritedMarkupMarkupLoader.java wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/loader/SimpleMarkupLoader.java wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/parser/IXmlPullParser.java wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/parser/XmlPullParser.java wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/parser/filter/RootMarkupFilter.java wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/WicketNamespaceTest.java wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/parser/XmlPullParserTest.java Modified: wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/io/XmlReader.java URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/io/XmlReader.java?rev=1041581&r1=1041580&r2=1041581&view=diff ============================================================================== --- wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/io/XmlReader.java (original) +++ wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/io/XmlReader.java Thu Dec 2 20:58:51 2010 @@ -24,8 +24,6 @@ import java.io.Reader; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.apache.wicket.util.string.AppendingStringBuffer; - /** * This is a simple XmlReader. Its only purpose is to read the xml decl string from the input and @@ -46,7 +44,7 @@ public final class XmlReader extends Rea private String encoding; /** Null or if found in the markup, the whole <?xml ...?> string */ - private String xmlDeclarationString; + private CharSequence xmlDeclarationString; /** The input stream to read the data from */ private final InputStream inputStream; @@ -87,7 +85,7 @@ public final class XmlReader extends Rea * * @return if null, then JVM default */ - public String getEncoding() + public final String getEncoding() { return encoding; } @@ -97,7 +95,7 @@ public final class XmlReader extends Rea * * @return Null, if not found. */ - public String getXmlDeclaration() + public final CharSequence getXmlDeclaration() { return xmlDeclarationString; } @@ -150,7 +148,7 @@ public final class XmlReader extends Rea * The xmlDecl string * @return The encoding. Null, if not found */ - private final String determineEncoding(final String string) + private final String determineEncoding(final CharSequence string) { // Does the string match the <?xml .. ?> pattern final Matcher matcher = encodingPattern.matcher(string); @@ -192,7 +190,7 @@ public final class XmlReader extends Rea throws IOException { // Max one line - final AppendingStringBuffer pushBack = new AppendingStringBuffer(readAheadSize); + final StringBuilder pushBack = new StringBuilder(readAheadSize); // The current char from the markup file int value; Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/AbstractMarkupParser.java URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/AbstractMarkupParser.java?rev=1041581&r1=1041580&r2=1041581&view=diff ============================================================================== --- wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/AbstractMarkupParser.java (original) +++ wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/AbstractMarkupParser.java Thu Dec 2 20:58:51 2010 @@ -184,6 +184,7 @@ public abstract class AbstractMarkupPars markupResourceStream.setEncoding(xmlParser.getEncoding()); markupResourceStream.setXmlDeclaration(xmlParser.getXmlDeclaration()); + markupResourceStream.setDoctype(xmlParser.getDoctype()); if (xmlParser.getXmlDeclaration() == null) { @@ -285,6 +286,7 @@ public abstract class AbstractMarkupPars markup.getMarkupResourceStream().setEncoding(xmlParser.getEncoding()); markup.getMarkupResourceStream().setXmlDeclaration(xmlParser.getXmlDeclaration()); + markup.getMarkupResourceStream().setDoctype(xmlParser.getDoctype()); final MarkupStream markupStream = new MarkupStream(markup); markupStream.setCurrentIndex(markup.size() - 1); @@ -350,7 +352,7 @@ public abstract class AbstractMarkupPars Pattern preBlock = Pattern.compile("<pre>.*?</pre>", Pattern.DOTALL | Pattern.MULTILINE); Matcher m = preBlock.matcher(rawMarkup); int lastend = 0; - StringBuilder sb = null; + StringBuilder sb = null; while (true) { boolean matched = m.find(); Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/MarkupFactory.java URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/MarkupFactory.java?rev=1041581&r1=1041580&r2=1041581&view=diff ============================================================================== --- wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/MarkupFactory.java (original) +++ wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/MarkupFactory.java Thu Dec 2 20:58:51 2010 @@ -32,8 +32,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * Markup loading essentially is an self-sustaining modul of Wicket. MarkupFactory is the entry - * point into that modul and provides all the means to change defaults. + * Factory to load markup either from from cache or from a resource. In case of markup inheritance, + * merging the markup is managed transparently. * * @author Juergen Donnerstag */ Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/MarkupResourceStream.java URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/MarkupResourceStream.java?rev=1041581&r1=1041580&r2=1041581&view=diff ============================================================================== --- wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/MarkupResourceStream.java (original) +++ wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/MarkupResourceStream.java Thu Dec 2 20:58:51 2010 @@ -19,6 +19,8 @@ package org.apache.wicket.markup; import java.io.IOException; import java.io.InputStream; import java.util.Locale; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.apache.wicket.Component; import org.apache.wicket.util.lang.Bytes; @@ -26,6 +28,7 @@ import org.apache.wicket.util.lang.Wicke import org.apache.wicket.util.resource.IFixedLocationResourceStream; import org.apache.wicket.util.resource.IResourceStream; import org.apache.wicket.util.resource.ResourceStreamNotFoundException; +import org.apache.wicket.util.string.Strings; import org.apache.wicket.util.time.Time; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,6 +45,8 @@ public class MarkupResourceStream implem private static final Logger log = LoggerFactory.getLogger(MarkupResourceStream.class); + private static final Pattern DOCTYPE_REGEX = Pattern.compile("!DOCTYPE\\s+(.*)\\s*"); + /** The associated markup resource stream */ private final IResourceStream resourceStream; @@ -61,7 +66,7 @@ public class MarkupResourceStream implem private Markup baseMarkup; /** If found in the markup, the <?xml ...?> string */ - private String xmlDeclaration; + private CharSequence xmlDeclaration; /** The encoding as found in <?xml ... encoding="" ?>. Null, else */ private String encoding; @@ -75,6 +80,9 @@ public class MarkupResourceStream implem /** == wicket namespace name + ":id" */ private String wicketId; + /** HTML5 http://www.w3.org/TR/html5-diff/#doctype */ + private String doctype; + /** * Construct. * @@ -240,7 +248,7 @@ public class MarkupResourceStream implem */ public String getXmlDeclaration() { - return xmlDeclaration; + return (xmlDeclaration == null ? null : xmlDeclaration.toString()); } /** @@ -307,7 +315,7 @@ public class MarkupResourceStream implem * @param xmlDeclaration * xmlDeclaration */ - final void setXmlDeclaration(final String xmlDeclaration) + final void setXmlDeclaration(final CharSequence xmlDeclaration) { this.xmlDeclaration = xmlDeclaration; } @@ -395,4 +403,44 @@ public class MarkupResourceStream implem return "(unknown resource)"; } } + + /** + * Gets doctype. + * + * @return The doctype excluding 'DOCTYPE' + */ + public final String getDoctype() + { + return doctype; + } + + /** + * Sets doctype. + * + * @param doctype + * doctype + */ + public final void setDoctype(final CharSequence doctype) + { + if (Strings.isEmpty(doctype) == false) + { + String doc = doctype.toString().replaceAll("[\n\r]+", ""); + doc = doc.replaceAll("\\s+", " "); + Matcher matcher = DOCTYPE_REGEX.matcher(doc); + if (matcher.matches() == false) + { + throw new MarkupException("Invalid DOCTYPE: '" + doctype + "'"); + } + this.doctype = matcher.group(1).trim(); + } + } + + /** + * @see href http://www.w3.org/TR/html5-diff/#doctype + * @return True, if doctype == <!DOCTYPE html> + */ + public boolean isHtml5() + { + return "html".equalsIgnoreCase(doctype); + } } Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/TagUtils.java URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/TagUtils.java?rev=1041581&r1=1041580&r2=1041581&view=diff ============================================================================== --- wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/TagUtils.java (original) +++ wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/TagUtils.java Thu Dec 2 20:58:51 2010 @@ -50,4 +50,33 @@ public class TagUtils { return ("head".equalsIgnoreCase(tag.getName()) && (tag.getNamespace() == null)); } + + /** + * + * @param markup + * @param i + * @return True if the markup element at index 'i' is a WicketTag + */ + public static final boolean isWicketTag(final IMarkupFragment markup, final int i) + { + MarkupElement elem = markup.get(i); + return elem instanceof WicketTag; + } + + /** + * + * @param markup + * @param i + * @return True if the markup element at index 'i' is a <wicket:extend> tag + */ + public static final boolean isExtendTag(final IMarkupFragment markup, final int i) + { + MarkupElement elem = markup.get(i); + if (elem instanceof WicketTag) + { + WicketTag wtag = (WicketTag)elem; + return wtag.isExtendTag(); + } + return false; + } } \ No newline at end of file Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/html/MarkupUtil.java URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/html/MarkupUtil.java?rev=1041581&view=auto ============================================================================== --- wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/html/MarkupUtil.java (added) +++ wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/html/MarkupUtil.java Thu Dec 2 20:58:51 2010 @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.wicket.markup.html; + +import org.apache.wicket.MarkupContainer; +import org.apache.wicket.Page; +import org.apache.wicket.WicketRuntimeException; +import org.apache.wicket.markup.MarkupResourceStream; +import org.apache.wicket.util.lang.Args; +import org.apache.wicket.util.visit.IVisit; +import org.apache.wicket.util.visit.IVisitor; + +/** + * HTML5 helper + * + * @author Juergen Donnerstag + */ +public class MarkupUtil +{ + /** + * + * @param container + * @return True if the Page and all it's Panels, Borders etc. have HTML5 compliant markup. HTML5 + * markup is identified by <DOCTYPE html> + */ + public final static boolean isMarkupHtml5Compliant(final MarkupContainer container) + { + Args.notNull(container, "container"); + + Page page = container.getPage(); + if (page == null) + { + throw new WicketRuntimeException("Component not attached to Page. Component: " + + container.toString()); + } + + final boolean rtn[] = new boolean[] { true }; + page.visitChildren(MarkupContainer.class, new IVisitor<MarkupContainer, Void>() + { + public void component(final MarkupContainer comp, final IVisit<Void> visit) + { + MarkupResourceStream rs = comp.getAssociatedMarkup().getMarkupResourceStream(); + if (rs.isHtml5() == false) + { + rtn[0] = false; + visit.stop(); + } + } + }); + + return rtn[0]; + } +} Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/loader/DefaultMarkupLoader.java URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/loader/DefaultMarkupLoader.java?rev=1041581&r1=1041580&r2=1041581&view=diff ============================================================================== --- wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/loader/DefaultMarkupLoader.java (original) +++ wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/loader/DefaultMarkupLoader.java Thu Dec 2 20:58:51 2010 @@ -24,11 +24,8 @@ import org.apache.wicket.markup.MarkupRe import org.apache.wicket.util.resource.ResourceStreamNotFoundException; /** - * This is Wickets default markup loader. It uses the InheritedMarkupMarkupLoader and - * SimpleMarkupLoader to load the markup associated with a MarkupContainer. - * - * @see InheritedMarkupMarkupLoader - * @see SimpleMarkupLoader + * This is Wickets default markup loader. It uses the {...@link InheritedMarkupMarkupLoader} and + * {...@link SimpleMarkupLoader} to load the markup associated with a {...@link MarkupContainer}. * * @author Juergen Donnerstag */ @@ -42,6 +39,9 @@ public class DefaultMarkupLoader impleme } /** + * Uses {...@link SimpleMarkupLoader} to load the resource(s), read it and check if markup + * inheritance applies. If yes, load the required other markup and merge them using + * {...@link InheritedMarkupMarkupLoader}. * * @see org.apache.wicket.markup.loader.IMarkupLoader#loadMarkup(org.apache.wicket.MarkupContainer, * org.apache.wicket.markup.MarkupResourceStream, Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/loader/IMarkupLoader.java URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/loader/IMarkupLoader.java?rev=1041581&r1=1041580&r2=1041581&view=diff ============================================================================== --- wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/loader/IMarkupLoader.java (original) +++ wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/loader/IMarkupLoader.java Thu Dec 2 20:58:51 2010 @@ -21,19 +21,23 @@ import java.io.IOException; import org.apache.wicket.MarkupContainer; import org.apache.wicket.markup.Markup; import org.apache.wicket.markup.MarkupCache; +import org.apache.wicket.markup.MarkupFactory; import org.apache.wicket.markup.MarkupParser; import org.apache.wicket.markup.MarkupResourceStream; import org.apache.wicket.util.resource.ResourceStreamNotFoundException; /** - * IMarkupLoader are loading the actual markup for a specific Wicket container and resource stream. - * In case of markup inheritance it means that 2+ markup files must be read and merged. In order to - * be flexible the interface has been designed in a way that multiple IMarkupLoader can be chained - * to easily build up more complex loaders. + * IMarkupLoader are loading the markup for a specific Wicket container and resource stream. By + * default that is a file. But e.g. in case of markup inheritance it means that 2+ markup files must + * be read and merged. In order to be flexible the interface has been designed in a way that + * multiple IMarkupLoader can be chained to easily build up more complex loaders. + * <p> + * As a Wicket user you should not need to use any markup loader directly. Instead use + * {...@link MarkupFactory#getMarkup(MarkupContainer, boolean)}. * * @see MarkupCache * @see MarkupParser - * @see MarkupParserFactory + * @see MarkupFactory * * @author Juergen Donnerstag */ @@ -55,7 +59,7 @@ public interface IMarkupLoader * @throws IOException * @throws ResourceStreamNotFoundException */ - Markup loadMarkup(final MarkupContainer container, - final MarkupResourceStream markupResourceStream, final IMarkupLoader baseLoader, - final boolean enforceReload) throws IOException, ResourceStreamNotFoundException; + Markup loadMarkup(final MarkupContainer container, MarkupResourceStream markupResourceStream, + IMarkupLoader baseLoader, boolean enforceReload) throws IOException, + ResourceStreamNotFoundException; } \ No newline at end of file Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/loader/InheritedMarkupMarkupLoader.java URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/loader/InheritedMarkupMarkupLoader.java?rev=1041581&r1=1041580&r2=1041581&view=diff ============================================================================== --- wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/loader/InheritedMarkupMarkupLoader.java (original) +++ wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/loader/InheritedMarkupMarkupLoader.java Thu Dec 2 20:58:51 2010 @@ -21,12 +21,11 @@ import java.io.IOException; import org.apache.wicket.MarkupContainer; import org.apache.wicket.markup.IMarkupFragment; import org.apache.wicket.markup.Markup; -import org.apache.wicket.markup.MarkupElement; import org.apache.wicket.markup.MarkupFactory; import org.apache.wicket.markup.MarkupNotFoundException; import org.apache.wicket.markup.MarkupResourceStream; import org.apache.wicket.markup.MergedMarkup; -import org.apache.wicket.markup.WicketTag; +import org.apache.wicket.markup.TagUtils; import org.apache.wicket.util.resource.ResourceStreamNotFoundException; /** @@ -45,6 +44,8 @@ public class InheritedMarkupMarkupLoader } /** + * Load the markup from the resource stream with the base MarkupLoader provided, than check if + * markup inheritance must be applied. If yes, than load the base markup and merge them. * * @see org.apache.wicket.markup.loader.IMarkupLoader#loadMarkup(org.apache.wicket.MarkupContainer, * org.apache.wicket.markup.MarkupResourceStream, @@ -56,28 +57,7 @@ public class InheritedMarkupMarkupLoader { // read and parse the markup Markup markup = baseLoader.loadMarkup(container, markupResourceStream, null, enforceReload); - markup = checkForMarkupInheritance(container, markup, enforceReload); - return markup; - } - /** - * The markup has just been loaded and now we check if markup inheritance applies, which is if - * <wicket:extend> is found in the markup. If yes, than load the base markups and merge the - * markup elements to create an updated (merged) list of markup elements. - * - * @param container - * The original requesting markup container - * @param markup - * The markup to checked for inheritance - * @param enforceReload - * The cache will be ignored and all, including inherited markup files, will be - * reloaded. Whatever is in the cache, it will be ignored - * @return A markup object with the the base markup elements resolved. - * @TODO move into IMarkupLoader - */ - private Markup checkForMarkupInheritance(final MarkupContainer container, final Markup markup, - final boolean enforceReload) - { // Check if markup contains <wicket:extend> which tells us that // we need to read the inherited markup as well. int extendIndex = requiresBaseMarkup(markup); @@ -87,8 +67,8 @@ public class InheritedMarkupMarkupLoader return markup; } + // Load the base markup final Markup baseMarkup = getBaseMarkup(container, markup, enforceReload); - if (baseMarkup == Markup.NO_MARKUP) { throw new MarkupNotFoundException( @@ -105,6 +85,8 @@ public class InheritedMarkupMarkupLoader } /** + * Load the base markup + * * @param container * @param markup * @param enforceReload @@ -113,7 +95,6 @@ public class InheritedMarkupMarkupLoader private Markup getBaseMarkup(final MarkupContainer container, final Markup markup, final boolean enforceReload) { - final Class<?> location = markup.getMarkupResourceStream().getMarkupClass().getSuperclass(); // get the base markup @@ -127,22 +108,16 @@ public class InheritedMarkupMarkupLoader * * @param markup * @return == 0, if no wicket:extend was found - * @TODO move into IMarkupLoader */ private int requiresBaseMarkup(final IMarkupFragment markup) { for (int i = 0; i < markup.size(); i++) { - MarkupElement elem = markup.get(i); - if (elem instanceof WicketTag) + if (TagUtils.isExtendTag(markup, i)) { - WicketTag wtag = (WicketTag)elem; - if (wtag.isExtendTag()) - { - // Ok, inheritance is on and we must get the - // inherited markup as well. - return i; - } + // Ok, inheritance is on and we must get the + // inherited markup as well. + return i; } } return -1; Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/loader/SimpleMarkupLoader.java URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/loader/SimpleMarkupLoader.java?rev=1041581&r1=1041580&r2=1041581&view=diff ============================================================================== --- wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/loader/SimpleMarkupLoader.java (original) +++ wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/loader/SimpleMarkupLoader.java Thu Dec 2 20:58:51 2010 @@ -21,12 +21,12 @@ import java.io.IOException; import org.apache.wicket.MarkupContainer; import org.apache.wicket.markup.Markup; import org.apache.wicket.markup.MarkupFactory; +import org.apache.wicket.markup.MarkupParser; import org.apache.wicket.markup.MarkupResourceStream; import org.apache.wicket.util.resource.ResourceStreamNotFoundException; /** - * Load the markup via the MarkupParser, not more, not less. Caching is provided separately as well - * as Inherited-Markup merging. + * Load the markup from the resource stream provided * * @author Juergen Donnerstag */ @@ -40,6 +40,8 @@ public class SimpleMarkupLoader implemen } /** + * Uses {...@link MarkupFactory#newMarkupParser(MarkupResourceStream)} and + * {...@link MarkupParser#parse()} to load the Markup. * * @see org.apache.wicket.markup.loader.IMarkupLoader#loadMarkup(org.apache.wicket.MarkupContainer, * org.apache.wicket.markup.MarkupResourceStream, Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/parser/IXmlPullParser.java URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/parser/IXmlPullParser.java?rev=1041581&r1=1041580&r2=1041581&view=diff ============================================================================== --- wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/parser/IXmlPullParser.java (original) +++ wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/parser/IXmlPullParser.java Thu Dec 2 20:58:51 2010 @@ -32,6 +32,36 @@ import org.apache.wicket.util.resource.R */ public interface IXmlPullParser { + /** The last element found */ + public enum ELEMENT_TYPE { + /** next() must be called at least once for the Type to be valid */ + NOT_INITIALIZED, + + /** <name ...> */ + TAG, + + /** Tag body in between two tags */ + BODY, + + /** <!-- ... --> */ + COMMENT, + + /** <!--[if ] ... --> */ + CONDITIONAL_COMMENT, + + /** <![CDATA[ .. ]]> */ + CDATA, + + /** <?...> */ + PROCESSING_INSTRUCTION, + + /** <!DOCTYPE ...> */ + DOCTYPE, + + /** all other tags which look like <!.. > */ + SPECIAL_TAG, + } + /** * Return the encoding applied while reading the markup resource. The encoding is determined by * analyzing the <?xml version=".." encoding=".." ?> tag. @@ -45,7 +75,14 @@ public interface IXmlPullParser * * @return Null, if not found. */ - String getXmlDeclaration(); + CharSequence getXmlDeclaration(); + + /** + * Gets the <!DOCTYPE ...> tag if found in the markup + * + * @return Null, if not found + */ + CharSequence getDoctype(); /** * Wicket dissects the markup into Wicket relevant tags and raw markup, which is not further @@ -119,7 +156,7 @@ public interface IXmlPullParser * @return o, if end of file. Else a TAG, COMMENT etc. * @throws ParseException */ - int next() throws ParseException; + ELEMENT_TYPE next() throws ParseException; /** * Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/parser/XmlPullParser.java URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/parser/XmlPullParser.java?rev=1041581&r1=1041580&r2=1041581&view=diff ============================================================================== --- wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/parser/XmlPullParser.java (original) +++ wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/parser/XmlPullParser.java Thu Dec 2 20:58:51 2010 @@ -39,30 +39,6 @@ import org.apache.wicket.util.resource.R */ public final class XmlPullParser implements IXmlPullParser { - /** next() must be called at least once for the Type to be valid */ - public static final int NOT_INITIALIZED = 0; - - /** <name ...> */ - public static final int TAG = 1; - - /** Tag body in between two tags */ - public static final int BODY = 2; - - /** <!-- ... --> */ - public static final int COMMENT = 3; - - /** <!--[if ] ... --> */ - public static final int CONDITIONAL_COMMENT = 4; - - /** <![CDATA[ .. ]]> */ - public static final int CDATA = 5; - - /** <?...> */ - public static final int PROCESSING_INSTRUCTION = 6; - - /** all other tags which look like <!.. > */ - public static final int SPECIAL_TAG = 7; - /** * Reads the xml data from an input stream and converts the chars according to its encoding * (<?xml ... encoding="..." ?>) @@ -81,8 +57,11 @@ public final class XmlPullParser impleme /** The last substring selected from the input */ private CharSequence lastText; + /** Everything in between <!DOCTYPE ... > */ + private CharSequence doctype; + /** The type of what is in lastText */ - private int lastType = NOT_INITIALIZED; + private ELEMENT_TYPE lastType = ELEMENT_TYPE.NOT_INITIALIZED; /** If lastType == TAG, than ... */ private XmlTag lastTag; @@ -98,7 +77,7 @@ public final class XmlPullParser impleme * * @see org.apache.wicket.markup.parser.IXmlPullParser#getEncoding() */ - public String getEncoding() + public final String getEncoding() { return xmlReader.getEncoding(); } @@ -107,13 +86,22 @@ public final class XmlPullParser impleme * * @see org.apache.wicket.markup.parser.IXmlPullParser#getXmlDeclaration() */ - public String getXmlDeclaration() + public final CharSequence getXmlDeclaration() { return xmlReader.getXmlDeclaration(); } /** * + * @see org.apache.wicket.markup.parser.IXmlPullParser#getDoctype() + */ + public final CharSequence getDoctype() + { + return doctype; + } + + /** + * * @see org.apache.wicket.markup.parser.IXmlPullParser#getInputFromPositionMarker(int) */ public final CharSequence getInputFromPositionMarker(final int toPos) @@ -161,7 +149,7 @@ public final class XmlPullParser impleme input.setPosition(pos); lastText = input.getSubstring(startIndex, pos); - lastType = BODY; + lastType = ELEMENT_TYPE.BODY; // Check that the tag is properly closed lastPos = input.find('>', lastPos + tagNameLen); @@ -187,12 +175,12 @@ public final class XmlPullParser impleme * @return XXX * @throws ParseException */ - public final int next() throws ParseException + public final ELEMENT_TYPE next() throws ParseException { // Reached end of markup file? if (input.getPosition() >= input.size()) { - return NOT_INITIALIZED; + return ELEMENT_TYPE.NOT_INITIALIZED; } if (skipUntilText != null) @@ -212,13 +200,13 @@ public final class XmlPullParser impleme // There is no next matching tag. lastText = input.getSubstring(-1); input.setPosition(input.size()); - lastType = BODY; + lastType = ELEMENT_TYPE.BODY; return lastType; } lastText = input.getSubstring(openBracketIndex); input.setPosition(openBracketIndex); - lastType = BODY; + lastType = ELEMENT_TYPE.BODY; return lastType; } @@ -306,7 +294,7 @@ public final class XmlPullParser impleme // Move to position after the tag input.setPosition(closeBracketIndex + 1); - lastType = TAG; + lastType = ELEMENT_TYPE.TAG; return lastType; } else @@ -342,13 +330,13 @@ public final class XmlPullParser impleme pos += 3; lastText = input.getSubstring(openBracketIndex, pos); - lastType = COMMENT; + lastType = ELEMENT_TYPE.COMMENT; // Conditional comment? E.g. "<!--[if IE]><a href='test.html'>my link</a><![endif]-->" if (tagText.startsWith("!--[if ") && tagText.endsWith("]") && lastText.toString().endsWith("<![endif]-->")) { - lastType = CONDITIONAL_COMMENT; + lastType = ELEMENT_TYPE.CONDITIONAL_COMMENT; // Actually it is no longer a comment. It is now // up to the browser to select the section appropriate. @@ -365,7 +353,7 @@ public final class XmlPullParser impleme // "<!--[if IE]><a href='test.html'>my link</a><![endif]-->" if (tagText.equals("![endif]--")) { - lastType = CONDITIONAL_COMMENT; + lastType = ELEMENT_TYPE.CONDITIONAL_COMMENT; input.setPosition(closeBracketIndex + 1); return; } @@ -401,14 +389,26 @@ public final class XmlPullParser impleme input.setPosition(closeBracketIndex + 1); lastText = tagText; - lastType = CDATA; + lastType = ELEMENT_TYPE.CDATA; return; } } if (tagText.charAt(0) == '?') { - lastType = PROCESSING_INSTRUCTION; + lastType = ELEMENT_TYPE.PROCESSING_INSTRUCTION; + + // Move to position after the tag + input.setPosition(closeBracketIndex + 1); + return; + } + + if (tagText.startsWith("!DOCTYPE")) + { + lastType = ELEMENT_TYPE.DOCTYPE; + + // Get the tagtext between open and close brackets + doctype = input.getSubstring(openBracketIndex + 1, closeBracketIndex); // Move to position after the tag input.setPosition(closeBracketIndex + 1); @@ -416,7 +416,7 @@ public final class XmlPullParser impleme } // Move to position after the tag - lastType = SPECIAL_TAG; + lastType = ELEMENT_TYPE.SPECIAL_TAG; input.setPosition(closeBracketIndex + 1); } @@ -442,7 +442,7 @@ public final class XmlPullParser impleme */ public final MarkupElement nextTag() throws ParseException { - while (next() != NOT_INITIALIZED) + while (next() != ELEMENT_TYPE.NOT_INITIALIZED) { switch (lastType) { Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/parser/filter/RootMarkupFilter.java URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/parser/filter/RootMarkupFilter.java?rev=1041581&r1=1041580&r2=1041581&view=diff ============================================================================== --- wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/parser/filter/RootMarkupFilter.java (original) +++ wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/parser/filter/RootMarkupFilter.java Thu Dec 2 20:58:51 2010 @@ -21,7 +21,7 @@ import java.text.ParseException; import org.apache.wicket.markup.MarkupElement; import org.apache.wicket.markup.parser.IMarkupFilter; import org.apache.wicket.markup.parser.IXmlPullParser; -import org.apache.wicket.markup.parser.XmlPullParser; +import org.apache.wicket.markup.parser.IXmlPullParser.ELEMENT_TYPE; /** @@ -48,10 +48,10 @@ public final class RootMarkupFilter impl */ public final MarkupElement nextTag() throws ParseException { - int type; - while ((type = next()) != XmlPullParser.TAG) + ELEMENT_TYPE type; + while ((type = next()) != ELEMENT_TYPE.TAG) { - if (type == 0) + if (type == ELEMENT_TYPE.NOT_INITIALIZED) { return null; } @@ -81,7 +81,7 @@ public final class RootMarkupFilter impl * @return The next XML element * @throws ParseException */ - private int next() throws ParseException + private ELEMENT_TYPE next() throws ParseException { return parser.next(); } Added: wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/DoctypeExpectedResult_1.html URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/DoctypeExpectedResult_1.html?rev=1041581&view=auto ============================================================================== --- wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/DoctypeExpectedResult_1.html (added) +++ wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/DoctypeExpectedResult_1.html Thu Dec 2 20:58:51 2010 @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<!-- + ==================================================================== + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<html> +<body> + <span wicket:id="label">my label test</span> +</body> +</html> Added: wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/DoctypeExpectedResult_2.html URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/DoctypeExpectedResult_2.html?rev=1041581&view=auto ============================================================================== --- wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/DoctypeExpectedResult_2.html (added) +++ wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/DoctypeExpectedResult_2.html Thu Dec 2 20:58:51 2010 @@ -0,0 +1,20 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<!-- + ==================================================================== + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<html> +<body> + <span wicket:id="label">my label test</span> +</body> +</html> Added: wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/Doctype_1.html URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/Doctype_1.html?rev=1041581&view=auto ============================================================================== --- wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/Doctype_1.html (added) +++ wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/Doctype_1.html Thu Dec 2 20:58:51 2010 @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<!-- + ==================================================================== + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<html> +<body> + <span wicket:id="label">xxx</span> +</body> +</html> Added: wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/Doctype_1.java URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/Doctype_1.java?rev=1041581&view=auto ============================================================================== --- wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/Doctype_1.java (added) +++ wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/Doctype_1.java Thu Dec 2 20:58:51 2010 @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.wicket.markup; + +import org.apache.wicket.markup.html.WebPage; +import org.apache.wicket.markup.html.basic.Label; + + +/** + * Mock page for testing. + * + * @author Chris Turner + */ +public class Doctype_1 extends WebPage +{ + private static final long serialVersionUID = 1L; + + /** + * Construct. + * + */ + public Doctype_1() + { + add(new Label("label", "my label test")); + } +} Added: wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/Doctype_2.html URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/Doctype_2.html?rev=1041581&view=auto ============================================================================== --- wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/Doctype_2.html (added) +++ wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/Doctype_2.html Thu Dec 2 20:58:51 2010 @@ -0,0 +1,20 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<!-- + ==================================================================== + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<html> +<body> + <span wicket:id="label">xxx</span> +</body> +</html> Added: wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/Doctype_2.java URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/Doctype_2.java?rev=1041581&view=auto ============================================================================== --- wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/Doctype_2.java (added) +++ wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/Doctype_2.java Thu Dec 2 20:58:51 2010 @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.wicket.markup; + +import org.apache.wicket.markup.html.WebPage; +import org.apache.wicket.markup.html.basic.Label; + + +/** + * Mock page for testing. + * + * @author Chris Turner + */ +public class Doctype_2 extends WebPage +{ + private static final long serialVersionUID = 1L; + + /** + * Construct. + * + */ + public Doctype_2() + { + add(new Label("label", "my label test")); + } +} Modified: wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/WicketNamespaceTest.java URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/WicketNamespaceTest.java?rev=1041581&r1=1041580&r2=1041581&view=diff ============================================================================== --- wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/WicketNamespaceTest.java (original) +++ wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/WicketNamespaceTest.java Thu Dec 2 20:58:51 2010 @@ -81,4 +81,31 @@ public class WicketNamespaceTest extends executeTest(WicketNamespace_6.class, "WicketNamespaceExpectedResult_6.html"); } + /** + * @throws Exception + */ + public void testDoctype_1() throws Exception + { + executeTest(Doctype_1.class, "DoctypeExpectedResult_1.html"); + MarkupResourceStream rs = MarkupFactory.get() + .getMarkup(tester.getLastRenderedPage(), true) + .getMarkupResourceStream(); + assertEquals("html", rs.getDoctype()); + assertEquals(true, rs.isHtml5()); + } + + /** + * @throws Exception + */ + public void testDoctype_2() throws Exception + { + executeTest(Doctype_2.class, "DoctypeExpectedResult_2.html"); + MarkupResourceStream rs = MarkupFactory.get() + .getMarkup(tester.getLastRenderedPage(), true) + .getMarkupResourceStream(); + assertEquals( + rs.getDoctype(), + "html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\""); + assertEquals(false, rs.isHtml5()); + } } Modified: wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/parser/XmlPullParserTest.java URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/parser/XmlPullParserTest.java?rev=1041581&r1=1041580&r2=1041581&view=diff ============================================================================== --- wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/parser/XmlPullParserTest.java (original) +++ wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/parser/XmlPullParserTest.java Thu Dec 2 20:58:51 2010 @@ -22,6 +22,7 @@ import java.text.ParseException; import junit.framework.TestCase; import org.apache.wicket.markup.MarkupElement; +import org.apache.wicket.markup.parser.IXmlPullParser.ELEMENT_TYPE; import org.apache.wicket.util.resource.StringResourceStream; /** @@ -347,21 +348,21 @@ public class XmlPullParserTest extends T { final XmlPullParser parser = new XmlPullParser(); parser.parse("<!--[if IE]><a href='test.html'>my link</a><![endif]-->"); - int type = parser.next(); - assertEquals(type, XmlPullParser.CONDITIONAL_COMMENT); + ELEMENT_TYPE type = parser.next(); + assertEquals(type, ELEMENT_TYPE.CONDITIONAL_COMMENT); type = parser.next(); - assertEquals(type, XmlPullParser.TAG); + assertEquals(type, ELEMENT_TYPE.TAG); assertTrue(((XmlTag)parser.getElement()).isOpen()); type = parser.next(); - assertEquals(type, XmlPullParser.BODY); + assertEquals(type, ELEMENT_TYPE.BODY); type = parser.next(); - assertEquals(type, XmlPullParser.TAG); + assertEquals(type, ELEMENT_TYPE.TAG); assertEquals("a", ((XmlTag)parser.getElement()).getName()); assertTrue(((XmlTag)parser.getElement()).isClose()); type = parser.next(); - assertEquals(type, XmlPullParser.CONDITIONAL_COMMENT); + assertEquals(type, ELEMENT_TYPE.CONDITIONAL_COMMENT); type = parser.next(); - assertEquals(0, type); + assertEquals(type, ELEMENT_TYPE.NOT_INITIALIZED); } /** @@ -386,4 +387,17 @@ public class XmlPullParserTest extends T assertTrue(tag.isOpen()); assertEquals("filter_mapping", tag.getName()); } + + /** + * + * @throws Exception + */ + public final void testDoctype() throws Exception + { + final XmlPullParser parser = new XmlPullParser(); + parser.parse("<!DOCTYPE html>"); + ELEMENT_TYPE type = parser.next(); + assertEquals(ELEMENT_TYPE.DOCTYPE, type); + assertEquals("!DOCTYPE html", parser.getDoctype()); + } }