You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2011/10/25 21:18:48 UTC
svn commit: r1188867 - in /tapestry/tapestry5/trunk/tapestry-core/src:
main/java/org/apache/tapestry5/internal/dynamic/
main/java/org/apache/tapestry5/internal/services/
test/java/org/apache/tapestry5/internal/services/
test/resources/org/apache/tapest...
Author: hlship
Date: Tue Oct 25 19:18:47 2011
New Revision: 1188867
URL: http://svn.apache.org/viewvc?rev=1188867&view=rev
Log:
TAP5-1720: Supply a "<!DOCTYPE html>" for any component template that doesn't have a specific <!DOCTYPE>
Added:
tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/internal/services/html_entities.tml
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/dynamic/DynamicTemplateParserImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/dynamic/DynamicTemplateSaxParser.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DTDData.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/SaxTemplateParser.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/TemplateParser.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/TemplateParserImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/XMLTokenStream.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/TemplateParserImplTest.java
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/dynamic/DynamicTemplateParserImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/dynamic/DynamicTemplateParserImpl.java?rev=1188867&r1=1188866&r2=1188867&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/dynamic/DynamicTemplateParserImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/dynamic/DynamicTemplateParserImpl.java Tue Oct 25 19:18:47 2011
@@ -14,9 +14,8 @@
package org.apache.tapestry5.internal.dynamic;
-import java.util.Map;
-
import org.apache.tapestry5.internal.services.PageSource;
+import org.apache.tapestry5.internal.services.TemplateParser;
import org.apache.tapestry5.ioc.Resource;
import org.apache.tapestry5.ioc.annotations.PostInjection;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
@@ -28,6 +27,8 @@ import org.apache.tapestry5.services.Upd
import org.apache.tapestry5.services.dynamic.DynamicTemplate;
import org.apache.tapestry5.services.dynamic.DynamicTemplateParser;
+import java.util.Map;
+
public class DynamicTemplateParserImpl implements DynamicTemplateParser, UpdateListener
{
private final Map<Resource, DynamicTemplate> cache = CollectionFactory.newConcurrentMap();
@@ -38,10 +39,13 @@ public class DynamicTemplateParserImpl i
private final URLChangeTracker tracker;
- public DynamicTemplateParserImpl(ClasspathURLConverter converter, BindingSource bindingSource, PageSource pageSource)
+ private final TemplateParser componentTemplateParser;
+
+ public DynamicTemplateParserImpl(ClasspathURLConverter converter, BindingSource bindingSource, PageSource pageSource, TemplateParser componentTemplateParser)
{
this.bindingSource = bindingSource;
this.pageSource = pageSource;
+ this.componentTemplateParser = componentTemplateParser;
tracker = new URLChangeTracker(converter);
}
@@ -69,7 +73,7 @@ public class DynamicTemplateParserImpl i
private DynamicTemplate doParse(Resource resource)
{
- return new DynamicTemplateSaxParser(resource, bindingSource).parse();
+ return new DynamicTemplateSaxParser(resource, bindingSource, componentTemplateParser.getDTDURLMappings()).parse();
}
public void checkForUpdates()
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/dynamic/DynamicTemplateSaxParser.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/dynamic/DynamicTemplateSaxParser.java?rev=1188867&r1=1188866&r2=1188867&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/dynamic/DynamicTemplateSaxParser.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/dynamic/DynamicTemplateSaxParser.java Tue Oct 25 19:18:47 2011
@@ -14,15 +14,6 @@
package org.apache.tapestry5.internal.dynamic;
-import java.net.URL;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.xml.namespace.QName;
-
import org.apache.tapestry5.Binding;
import org.apache.tapestry5.BindingConstants;
import org.apache.tapestry5.Block;
@@ -44,7 +35,16 @@ import org.apache.tapestry5.services.Bin
import org.apache.tapestry5.services.dynamic.DynamicDelegate;
import org.apache.tapestry5.services.dynamic.DynamicTemplate;
-/** Does the heavy lifting for {@link DynamicTemplateParserImpl}. */
+import javax.xml.namespace.QName;
+import java.net.URL;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Does the heavy lifting for {@link DynamicTemplateParserImpl}.
+ */
public class DynamicTemplateSaxParser
{
private final Resource resource;
@@ -53,8 +53,6 @@ public class DynamicTemplateSaxParser
private final XMLTokenStream tokenStream;
- private final Map<String, URL> publicIdToURL = Collections.emptyMap();
-
private static final Pattern PARAM_ID_PATTERN = Pattern.compile("^param:(\\p{Alpha}\\w*)$",
Pattern.CASE_INSENSITIVE);
@@ -69,7 +67,7 @@ public class DynamicTemplateSaxParser
}
};
- public DynamicTemplateSaxParser(Resource resource, BindingSource bindingSource)
+ public DynamicTemplateSaxParser(Resource resource, BindingSource bindingSource, Map<String, URL> publicIdToURL)
{
this.resource = resource;
this.bindingSource = bindingSource;
@@ -84,8 +82,7 @@ public class DynamicTemplateSaxParser
tokenStream.parse();
return toDynamicTemplate(root());
- }
- catch (Exception ex)
+ } catch (Exception ex)
{
throw new TapestryException(String.format("Failure parsing dynamic template %s: %s", resource,
InternalUtils.toMessage(ex)), tokenStream.getLocation(), ex);
@@ -219,7 +216,7 @@ public class DynamicTemplateSaxParser
}
private static DynamicTemplateElement createElementWriterElement(final String elementURI, final String elementName,
- final List<DynamicTemplateAttribute> attributes, List<DynamicTemplateElement> body)
+ final List<DynamicTemplateAttribute> attributes, List<DynamicTemplateElement> body)
{
final Flow<DynamicTemplateElement> bodyFlow = F.flow(body).reverse();
@@ -269,8 +266,7 @@ public class DynamicTemplateSaxParser
Block block = delegate.getBlock(blockId);
queue.push((RenderCommand) block);
- }
- catch (Exception ex)
+ } catch (Exception ex)
{
throw new TapestryException(String.format(
"Exception rendering block '%s' as part of dynamic template: %s", blockId,
@@ -443,7 +439,7 @@ public class DynamicTemplateSaxParser
}
private static Mapper<DynamicDelegate, String> createExpansionExtractor(final String expression,
- final Location location, final BindingSource bindingSource)
+ final Location location, final BindingSource bindingSource)
{
return new Mapper<DynamicDelegate, String>()
{
@@ -458,8 +454,7 @@ public class DynamicTemplateSaxParser
Object boundValue = binding.get();
return boundValue == null ? null : boundValue.toString();
- }
- catch (Throwable t)
+ } catch (Throwable t)
{
throw new TapestryException(InternalUtils.toMessage(t), location, t);
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DTDData.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DTDData.java?rev=1188867&r1=1188866&r2=1188867&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DTDData.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DTDData.java Tue Oct 25 19:18:47 2011
@@ -1,4 +1,4 @@
-// Copyright 2009 The Apache Software Foundation
+// Copyright 2009, 2011 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -19,14 +19,17 @@ import org.xml.sax.ext.LexicalHandler;
/**
* A capturing of the data from
* {@link LexicalHandler#startDTD(String, String, String)}.
- *
+ *
* @since 5.2.0
*/
-public interface DTDData
+public class DTDData
{
- String getRootName();
+ public final String rootName, publicId, systemId;
- String getPublicId();
-
- String getSystemId();
+ public DTDData(String rootName, String publicId, String systemId)
+ {
+ this.rootName = rootName;
+ this.publicId = publicId;
+ this.systemId = systemId;
+ }
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/SaxTemplateParser.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/SaxTemplateParser.java?rev=1188867&r1=1188866&r2=1188867&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/SaxTemplateParser.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/SaxTemplateParser.java Tue Oct 25 19:18:47 2011
@@ -1,4 +1,4 @@
-// Copyright 2009 The Apache Software Foundation
+// Copyright 2009, 2011 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -293,8 +293,8 @@ public class SaxTemplateParser
{
DTDData dtdInfo = tokenStream.getDTDInfo();
- tokenAccumulator.add(new DTDToken(dtdInfo.getRootName(), dtdInfo.getPublicId(), dtdInfo
- .getSystemId(), getLocation()));
+ tokenAccumulator.add(new DTDToken(dtdInfo.rootName, dtdInfo.publicId, dtdInfo
+ .systemId, getLocation()));
}
private Location getLocation()
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/TemplateParser.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/TemplateParser.java?rev=1188867&r1=1188866&r2=1188867&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/TemplateParser.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/TemplateParser.java Tue Oct 25 19:18:47 2011
@@ -1,4 +1,4 @@
-// Copyright 2006, 2008 The Apache Software Foundation
+// Copyright 2006, 2008, 2011 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ import org.apache.tapestry5.ioc.Resource
import org.apache.tapestry5.ioc.annotations.UsesMappedConfiguration;
import java.net.URL;
+import java.util.Map;
/**
* Parses a resource into a {@link org.apache.tapestry5.internal.parser.ComponentTemplate}. The service's configuration
@@ -37,4 +38,13 @@ public interface TemplateParser
* @throws RuntimeException if the resource does not exist, or if there is any kind of parse error
*/
ComponentTemplate parseTemplate(Resource templateResource);
+
+ /**
+ * Returns a mapping from URL string to a local equivalent URL, used to avoid attempting to pull
+ * well-known DTDs down over the wire while parsing XML.
+ *
+ * @since 5.3
+ */
+ Map<String, URL> getDTDURLMappings();
}
+
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/TemplateParserImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/TemplateParserImpl.java?rev=1188867&r1=1188866&r2=1188867&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/TemplateParserImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/TemplateParserImpl.java Tue Oct 25 19:18:47 2011
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008, 2009, 2010 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009, 2010, 2011 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,9 +14,6 @@
package org.apache.tapestry5.internal.services;
-import java.net.URL;
-import java.util.Map;
-
import org.apache.tapestry5.SymbolConstants;
import org.apache.tapestry5.internal.parser.ComponentTemplate;
import org.apache.tapestry5.ioc.Invokable;
@@ -24,11 +21,14 @@ import org.apache.tapestry5.ioc.Operatio
import org.apache.tapestry5.ioc.Resource;
import org.apache.tapestry5.ioc.annotations.Symbol;
+import java.net.URL;
+import java.util.Map;
+
/**
* Parses Tapestry XML template files into {@link ComponentTemplate} instances.
* A new instance of {@link SaxTemplateParser} is created for each document
* parsed.
- *
+ *
* @since 5.1.0.0
*/
public class TemplateParserImpl implements TemplateParser
@@ -41,8 +41,8 @@ public class TemplateParserImpl implemen
public TemplateParserImpl(Map<String, URL> configuration,
- @Symbol(SymbolConstants.COMPRESS_WHITESPACE)
- boolean defaultCompressWhitespace, OperationTracker tracker)
+ @Symbol(SymbolConstants.COMPRESS_WHITESPACE)
+ boolean defaultCompressWhitespace, OperationTracker tracker)
{
this.configuration = configuration;
this.defaultCompressWhitespace = defaultCompressWhitespace;
@@ -62,4 +62,9 @@ public class TemplateParserImpl implemen
}
});
}
+
+ public Map<String, URL> getDTDURLMappings()
+ {
+ return configuration;
+ }
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/XMLTokenStream.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/XMLTokenStream.java?rev=1188867&r1=1188866&r2=1188867&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/XMLTokenStream.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/XMLTokenStream.java Tue Oct 25 19:18:47 2011
@@ -37,6 +37,11 @@ import java.util.Map;
*/
public class XMLTokenStream
{
+
+ public static final String TRANSITIONAL_DOCTYPE = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">";
+
+ private static final DTDData HTML5_DTD_DATA = new DTDData("html", null, null);
+
private final class SaxHandler implements LexicalHandler, EntityResolver, ContentHandler
{
private Locator locator;
@@ -62,7 +67,10 @@ public class XMLTokenStream
if (cachedLocation == null)
{
- cachedLocation = new LocationImpl(resource, line);
+ // lineOffset accounts for the extra line when a doctype is injected. The line number reported
+ // from the XML parser inlcudes the phantom doctype line, the lineOffset is used to subtract one
+ // to get the real line number.
+ cachedLocation = new LocationImpl(resource, line + lineOffset);
}
return cachedLocation;
@@ -138,6 +146,7 @@ public class XMLTokenStream
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
{
+ characters(ch, start, length);
}
public void startDTD(final String name, final String publicId, final String systemId)
@@ -145,26 +154,12 @@ public class XMLTokenStream
{
insideDTD = true;
- DTDData data = new DTDData()
+ if (!ignoreDTD)
{
+ DTDData data = html5DTD ? HTML5_DTD_DATA : new DTDData(name, publicId, systemId);
- public String getSystemId()
- {
- return html5DTD ? null : systemId;
- }
-
- public String getRootName()
- {
- return name;
- }
-
- public String getPublicId()
- {
- return html5DTD ? null : publicId;
- }
- };
-
- add(XMLTokenType.DTD).dtdData = data;
+ add(XMLTokenType.DTD).dtdData = data;
+ }
}
public void endDocument() throws SAXException
@@ -182,12 +177,21 @@ public class XMLTokenStream
this.locator = locator;
}
+ /**
+ * Checks for the extra namespace injected when the transitional doctype is injected (which
+ * occurs when the template contains no doctype).
+ */
+ private boolean ignoreURI(String uri)
+ {
+ return ignoreDTD && uri.equals("http://www.w3.org/1999/xhtml");
+ }
+
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException
{
XMLToken token = add(XMLTokenType.START_ELEMENT);
- token.uri = uri;
+ token.uri = ignoreURI(uri) ? "" : uri;
token.localName = localName;
token.qName = qName;
@@ -227,6 +231,11 @@ public class XMLTokenStream
public void startPrefixMapping(String prefix, String uri) throws SAXException
{
+ if (ignoreDTD && prefix.equals("") && uri.equals("http://www.w3.org/1999/xhtml"))
+ {
+ return;
+ }
+
namespaceMappings.add(new NamespaceMapping(prefix, uri));
}
@@ -270,7 +279,9 @@ public class XMLTokenStream
private Location exceptionLocation;
- private boolean html5DTD;
+ private boolean html5DTD, ignoreDTD;
+
+ private int lineOffset;
public XMLTokenStream(Resource resource, Map<String, URL> publicIdToURL)
{
@@ -314,60 +325,95 @@ public class XMLTokenStream
}
}
- private InputStream openStream() throws IOException
+ enum State
{
+ MAYBE_XML, MAYBE_DOCTYPE, JUST_COPY
+ }
+ private InputStream openStream() throws IOException
+ {
InputStream rawStream = resource.openStream();
InputStreamReader rawReader = new InputStreamReader(rawStream);
LineNumberReader reader = new LineNumberReader(rawReader);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream(5000);
+ PrintWriter writer = new PrintWriter(bos);
+
+ State state = State.MAYBE_XML;
+
try
{
- String firstLine = reader.readLine();
-
- if ("<!DOCTYPE html>".equalsIgnoreCase(firstLine))
+ while (true)
{
- // When we hit the doctype later, ignore the transitional PUBLIC and SYSTEM ids and
- // treat it like a proper HTML5 doctype.
- html5DTD = true;
- return substituteTransitionalDoctype(reader);
- }
+ String line = reader.readLine();
- // Open a fresh stream for the parser to operate on.
+ if (line == null)
+ {
+ break;
+ }
- return resource.openStream();
+ switch (state)
+ {
- } finally
- {
- reader.close();
- }
- }
+ case MAYBE_XML:
- private InputStream substituteTransitionalDoctype(LineNumberReader reader) throws IOException
- {
- ByteArrayOutputStream bos = new ByteArrayOutputStream(5000);
- PrintWriter writer = new PrintWriter(bos);
+ if (line.toLowerCase().startsWith("<?xml"))
+ {
+ writer.println(line);
+ state = State.MAYBE_DOCTYPE;
+ continue;
+ }
- writer.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
+ case MAYBE_DOCTYPE:
- while (true)
- {
- String line = reader.readLine();
- if (line == null)
- {
- break;
- }
+ if (line.trim().length() == 0)
+ {
+ writer.println(line);
+ continue;
+ }
- writer.println(line);
- }
+ String lineLower = line.toLowerCase();
+
+ if (lineLower.equals("<!doctype html>"))
+ {
+ html5DTD = true;
+ writer.println(TRANSITIONAL_DOCTYPE);
+ state = State.JUST_COPY;
+ continue;
+ }
+
+
+ if (lineLower.startsWith("<!doctype"))
+ {
+ writer.println(line);
+ state = State.JUST_COPY;
+ continue;
+ }
- writer.close();
+ // No doctype, let's provide one.
+
+ ignoreDTD = true;
+ lineOffset = -1;
+ writer.println(TRANSITIONAL_DOCTYPE);
+
+ state = State.JUST_COPY;
+
+ // And drop down to writing out the actual line, and all following lines.
+
+ case JUST_COPY:
+ writer.println(line);
+ }
+ }
+ } finally
+ {
+ writer.close();
+ reader.close();
+ }
return new ByteArrayInputStream(bos.toByteArray());
}
-
private XMLToken token()
{
return tokens.get(cursor);
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/TemplateParserImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/TemplateParserImplTest.java?rev=1188867&r1=1188866&r2=1188867&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/TemplateParserImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/TemplateParserImplTest.java Tue Oct 25 19:18:47 2011
@@ -985,4 +985,22 @@ public class TemplateParserImplTest exte
assertMessageContains(ex, "Extension point 'batman' is already defined for this template.");
}
}
+
+ @Test
+ public void html_entities_inside_template_without_doctype_are_allowed() throws Exception
+ {
+
+ List<TemplateToken> tokens = tokens("html_entities.tml");
+
+ assertEquals(tokens.size(), 3);
+
+ StartElementToken token0 = get(tokens, 0);
+
+ assertEquals(token0.name, "html");
+
+ TextToken token1 = get(tokens, 1);
+
+ assertEquals(token1.text, "\n[\u00A0]\n");
+
+ }
}
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/internal/services/html_entities.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/internal/services/html_entities.tml?rev=1188867&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/internal/services/html_entities.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/internal/services/html_entities.tml Tue Oct 25 19:18:47 2011
@@ -0,0 +1,3 @@
+<html>
+ [ ]
+</html>
\ No newline at end of file