├── src ├── parser-tests │ ├── ignore.txt │ ├── superfast │ │ ├── ignore.txt │ │ ├── test04.txt │ │ ├── test03.txt │ │ ├── test06.txt │ │ ├── test02.txt │ │ ├── test07.txt │ │ ├── test05.txt │ │ └── test01.txt │ ├── test36.txt │ ├── test06.txt │ ├── test31.txt │ ├── test26.txt │ ├── test05.txt │ ├── test07.txt │ ├── test34.txt │ ├── test04.txt │ ├── test09.txt │ ├── test45.txt │ ├── test27.txt │ ├── test35.txt │ ├── test41.txt │ ├── test10.txt │ ├── test44.txt │ ├── parsers.properties │ ├── test02.txt │ ├── test15.txt │ ├── test33.txt │ ├── test03.txt │ ├── test12.txt │ ├── test11.txt │ ├── test08.txt │ ├── test16.txt │ ├── test29.txt │ ├── test30.txt │ ├── test42.txt │ ├── test32.txt │ ├── test40.txt │ ├── test13.txt │ ├── test01.txt │ ├── test39.txt │ ├── test28.txt │ ├── test22.txt │ ├── test43.txt │ ├── test24.txt │ ├── test25.txt │ ├── test19.txt │ ├── test18.txt │ ├── test21.txt │ ├── test17.txt │ ├── test23.txt │ ├── test20.txt │ └── readme.txt ├── main │ └── java │ │ └── com │ │ └── opensymphony │ │ ├── module │ │ └── sitemesh │ │ │ ├── html │ │ │ ├── tokenizer │ │ │ │ ├── .cvsignore │ │ │ │ └── TagTokenizer.java │ │ │ ├── StateChangeListener.java │ │ │ ├── TagRule.java │ │ │ ├── rules │ │ │ │ ├── PageBuilder.java │ │ │ │ ├── FramesetRule.java │ │ │ │ ├── ParameterExtractingRule.java │ │ │ │ ├── TitleExtractingRule.java │ │ │ │ ├── HeadExtractingRule.java │ │ │ │ ├── ContentBlockExtractingRule.java │ │ │ │ ├── MetaTagRule.java │ │ │ │ ├── HtmlAttributesRule.java │ │ │ │ ├── TagReplaceRule.java │ │ │ │ ├── BodyTagRule.java │ │ │ │ ├── MSOfficeDocumentPropertiesRule.java │ │ │ │ └── RegexReplacementTextFilter.java │ │ │ ├── TextFilter.java │ │ │ ├── HTMLProcessorContext.java │ │ │ ├── StateTransitionRule.java │ │ │ ├── Text.java │ │ │ └── util │ │ │ │ └── StringSitemeshBuffer.java │ │ │ ├── parser │ │ │ └── SuperFastSimplePageParser.java │ │ │ ├── scalability │ │ │ ├── outputlength │ │ │ │ ├── NoopOutputLengthObserver.java │ │ │ │ ├── OutputLengthObserver.java │ │ │ │ ├── MaxOutputLengthExceeded.java │ │ │ │ └── ExceptionThrowingOutputLengthObserver.java │ │ │ ├── ScalabilitySupport.java │ │ │ ├── secondarystorage │ │ │ │ └── NoopSecondaryStorage.java │ │ │ └── NoopScalabilitySupport.java │ │ │ ├── multipass │ │ │ ├── ExtractPropertyTag.java │ │ │ └── MultipassFilter.java │ │ │ ├── filter │ │ │ ├── PageFilter.java │ │ │ ├── NullWriter.java │ │ │ ├── SitemeshPrintWriter.java │ │ │ └── PageRequestWrapper.java │ │ │ ├── taglib │ │ │ ├── decorator │ │ │ │ ├── UseHTMLPageTEI.java │ │ │ │ ├── BodyTag.java │ │ │ │ ├── UsePageTEI.java │ │ │ │ ├── HeadTag.java │ │ │ │ ├── TitleTag.java │ │ │ │ ├── UsePageTag.java │ │ │ │ └── DivTag.java │ │ │ └── page │ │ │ │ └── ParamTag.java │ │ │ ├── PageParserSelector.java │ │ │ ├── factory │ │ │ └── sitemesh-default.xml │ │ │ ├── SitemeshBufferWriter.java │ │ │ └── mapper │ │ │ └── NullDecoratorMapper.java │ │ └── sitemesh │ │ ├── webapp │ │ ├── package.html │ │ ├── ContainerTweaks.java │ │ └── decorator │ │ │ ├── NoDecorator.java │ │ │ └── ExternalDispatchedDecorator.java │ │ ├── compatability │ │ ├── package.html │ │ ├── HTMLPage2Content.java │ │ └── DecoratorMapper2DecoratorSelector.java │ │ ├── Decorator.java │ │ ├── SiteMeshContext.java │ │ ├── DecoratorSelector.java │ │ ├── ContentProcessor.java │ │ └── Content.java ├── docs │ ├── images │ │ ├── overview.gif │ │ └── flowdiagram.gif │ ├── cache.jsp.txt │ ├── flow.html │ ├── style.jsp.txt │ └── api.css ├── etc │ ├── blank │ │ ├── index.jsp │ │ ├── WEB-INF │ │ │ ├── decorators.xml │ │ │ └── web.xml │ │ └── decorators │ │ │ ├── panel.jsp │ │ │ ├── main.jsp │ │ │ └── printable.jsp │ └── dtd │ │ ├── sitemesh_1_5_decorators.dtd │ │ └── sitemesh_1_0_decorators.dtd └── test │ └── java │ └── com │ └── opensymphony │ └── module │ └── sitemesh │ ├── scalability │ ├── secondarystorage │ │ ├── TeeWriter.java │ │ └── InMemorySecondaryStorage.java │ ├── MockFilterConfig.java │ └── outputlength │ │ └── ExceptionThrowingOutputLengthObserverTest.java │ └── html │ └── CustomTagTest.java ├── example ├── src │ └── main │ │ └── webapp │ │ ├── .cvsignore │ │ ├── tiny-panel.html │ │ ├── meta2.html │ │ ├── counter.jsp │ │ ├── agent.jsp │ │ ├── meta.html │ │ ├── decorators │ │ ├── test-ie.jsp │ │ ├── test.jsp │ │ ├── test-lynx.jsp │ │ ├── test-ns.jsp │ │ ├── test-opera.jsp │ │ ├── printable.jsp │ │ ├── panel.jsp │ │ ├── black.jsp │ │ └── main.css │ │ ├── counter-syntaxerror.jsp │ │ ├── google.html │ │ ├── WEB-INF │ │ ├── web.xml │ │ └── decorators.xml │ │ ├── random.pl │ │ ├── inline.jsp │ │ ├── badpanel.html │ │ ├── badsource.html │ │ ├── index.html │ │ ├── toggledecorator.jsp │ │ └── mandelbrot.pl └── build.gradle ├── gradle.properties ├── testsuite ├── src │ ├── webapp │ │ ├── simple │ │ │ ├── page3.jsp │ │ │ ├── page5.jsp │ │ │ ├── page2.jsp │ │ │ ├── page4.jsp │ │ │ ├── multiple-set-content-type.jsp │ │ │ ├── static.html │ │ │ ├── page1.jsp │ │ │ ├── exclude.jsp │ │ │ ├── exclude │ │ │ │ └── page1.jsp │ │ │ └── page6.jsp │ │ ├── basic │ │ │ ├── text.txt │ │ │ ├── text.unknown │ │ │ ├── error-500.jsp │ │ │ ├── error-exception.jsp │ │ │ ├── page.jsp │ │ │ ├── notmodified.html │ │ │ └── text.jsp │ │ ├── WEB-INF │ │ │ ├── .cvsignore │ │ │ ├── orion-web.xml │ │ │ ├── src │ │ │ │ └── testsuite │ │ │ │ │ └── servlets │ │ │ │ │ ├── ForwardServlet.java │ │ │ │ │ ├── StandardServlet.java │ │ │ │ │ ├── ContentLengthServlet.java │ │ │ │ │ ├── DifferentWaysOfSpecifyingContentType.java │ │ │ │ │ └── OutputServlet.java │ │ │ ├── test-tags.tld │ │ │ ├── weblogic.xml │ │ │ └── sitemesh.xml │ │ ├── redirect │ │ │ ├── simple-forward.jsp │ │ │ ├── simple-include.jsp │ │ │ ├── simple-redirect.jsp │ │ │ ├── simple-rdforward.jsp │ │ │ ├── simple-rdinclude.jsp │ │ │ └── page.jsp │ │ ├── request │ │ │ ├── inline.jsp │ │ │ ├── function.jsp │ │ │ ├── default.jsp │ │ │ ├── decorator-inline.jsp │ │ │ └── decorator-main.jsp │ │ ├── binary │ │ │ └── harry_potter.gif │ │ ├── inline │ │ │ ├── panel1.jsp │ │ │ ├── panel2.jsp │ │ │ ├── page1.jsp │ │ │ ├── page2.jsp │ │ │ ├── page3.jsp │ │ │ ├── page7.jsp │ │ │ ├── page7.html │ │ │ ├── page4.jsp │ │ │ ├── page5.jsp │ │ │ ├── page6.jsp │ │ │ ├── dec-5.jsp │ │ │ ├── dec-6.jsp │ │ │ ├── page8.jsp │ │ │ ├── dec-panel.jsp │ │ │ ├── dec-7.jsp │ │ │ ├── dec-2.jsp │ │ │ ├── dec-3.jsp │ │ │ └── dec-1.jsp │ │ ├── welcomepage │ │ │ └── default.jsp │ │ ├── default.jsp │ │ ├── velocity │ │ │ └── velocity.jsp │ │ ├── contentlength │ │ │ └── page-decorator-none.jsp │ │ ├── freemarker │ │ │ └── freemarker.jsp │ │ ├── multipass │ │ │ ├── content.html │ │ │ ├── expected-result.html │ │ │ └── decorator.jsp │ │ ├── errorpage-200.jsp │ │ └── decorators │ │ │ ├── velocity.vm │ │ │ ├── freemarker.ftl │ │ │ └── simple.jsp │ └── java │ │ └── testsuite │ │ ├── config │ │ ├── ConfigException.java │ │ └── Application.java │ │ └── sitemesh │ │ ├── VelocityDecoratorTest.java │ │ ├── FreemarkerDecoratorTest.java │ │ ├── WelcomePageTest.java │ │ ├── MultipassTest.java │ │ ├── BinaryFileTest.java │ │ ├── RedirectTest.java │ │ └── JettyWebServer.java ├── .gitignore ├── lib │ ├── jaxp.jar │ ├── jtidy.jar │ ├── ant-1.6.5.jar │ ├── crimson.jar │ ├── electricxml.jar │ ├── junit-3.8.1.jar │ ├── log4j-core.jar │ ├── cargo-ant-0.8.jar │ ├── httpunit-1.6.1.jar │ ├── jasper-runtime.jar │ ├── jetty-4.2.21.jar │ ├── oscore-2.2.4.jar │ ├── commons-logging.jar │ ├── jasper-compiler.jar │ └── cargo-core-uberjar-0.8.jar ├── embedded │ └── tomcat │ │ ├── lib │ │ ├── catalina.jar │ │ ├── jsp-api.jar │ │ ├── commons-el.jar │ │ ├── servlet-api.jar │ │ ├── tomcat-coyote.jar │ │ ├── tomcat-http.jar │ │ ├── tomcat-util.jar │ │ ├── commons-logging.jar │ │ ├── commons-modeler.jar │ │ ├── jasper-compiler.jar │ │ ├── jasper-runtime.jar │ │ ├── naming-factory.jar │ │ ├── catalina-optional.jar │ │ ├── naming-resources.jar │ │ ├── servlets-default.jar │ │ └── jasper-compiler-jdt.jar │ │ └── conf │ │ ├── context.xml │ │ └── tomcat-users.xml └── .cvsignore ├── settings.gradle ├── docs ├── images │ ├── overview.gif │ └── flowdiagram.gif ├── cache.jsp.txt ├── flow.html ├── style.jsp.txt ├── api │ ├── package-list │ ├── script.js │ └── com │ │ └── opensymphony │ │ ├── module │ │ └── sitemesh │ │ │ ├── taglib │ │ │ ├── package-frame.html │ │ │ └── page │ │ │ │ └── package-frame.html │ │ │ ├── velocity │ │ │ └── package-frame.html │ │ │ ├── freemarker │ │ │ └── package-frame.html │ │ │ ├── html │ │ │ ├── util │ │ │ │ └── package-frame.html │ │ │ └── tokenizer │ │ │ │ └── package-frame.html │ │ │ ├── factory │ │ │ └── package-frame.html │ │ │ └── tapestry │ │ │ └── package-frame.html │ │ └── sitemesh │ │ ├── webapp │ │ ├── package-frame.html │ │ └── decorator │ │ │ └── package-frame.html │ │ ├── package-frame.html │ │ └── compatability │ │ └── package-frame.html └── dtd │ ├── sitemesh_1_5_decorators.dtd │ └── sitemesh_1_0_decorators.dtd ├── lib ├── mockito-all-1.9.5.jar └── maven-resolver-ant-tasks-1.4.0-uber.jar ├── www └── index.html ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── .cvsignore ├── continuous-integration.xml └── .github └── workflows └── gradle.yml /src/parser-tests/ignore.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/parser-tests/superfast/ignore.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /example/src/main/webapp/.cvsignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | version=2.7.0-SNAPSHOT 2 | -------------------------------------------------------------------------------- /testsuite/src/webapp/simple/page3.jsp: -------------------------------------------------------------------------------- 1 | Hello world 3 -------------------------------------------------------------------------------- /testsuite/src/webapp/basic/text.txt: -------------------------------------------------------------------------------- 1 | This is a plain page. -------------------------------------------------------------------------------- /testsuite/src/webapp/WEB-INF/.cvsignore: -------------------------------------------------------------------------------- 1 | work 2 | classes 3 | -------------------------------------------------------------------------------- /testsuite/src/webapp/basic/text.unknown: -------------------------------------------------------------------------------- 1 | This is a plain page. -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'sitemesh' 2 | 3 | include ':example' -------------------------------------------------------------------------------- /testsuite/src/webapp/basic/error-500.jsp: -------------------------------------------------------------------------------- 1 | <% response.sendError( 500 ); %> -------------------------------------------------------------------------------- /testsuite/.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | tmp 3 | test-results 4 | embedded/tomcat/work 5 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/html/tokenizer/.cvsignore: -------------------------------------------------------------------------------- 1 | Lexer.java 2 | -------------------------------------------------------------------------------- /testsuite/src/webapp/redirect/simple-forward.jsp: -------------------------------------------------------------------------------- 1 | <% pageContext.forward( "page.jsp" ); %> -------------------------------------------------------------------------------- /testsuite/src/webapp/redirect/simple-include.jsp: -------------------------------------------------------------------------------- 1 | <% pageContext.include( "page.jsp" ); %> 2 | -------------------------------------------------------------------------------- /testsuite/src/webapp/redirect/simple-redirect.jsp: -------------------------------------------------------------------------------- 1 | <% response.sendRedirect( "page.jsp" ); %> -------------------------------------------------------------------------------- /testsuite/lib/jaxp.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/lib/jaxp.jar -------------------------------------------------------------------------------- /testsuite/src/webapp/simple/page5.jsp: -------------------------------------------------------------------------------- 1 | <%= "\u0126\u0118\u0139\u0139\u0150" %> world 5 2 | 3 | -------------------------------------------------------------------------------- /docs/images/overview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/docs/images/overview.gif -------------------------------------------------------------------------------- /testsuite/lib/jtidy.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/lib/jtidy.jar -------------------------------------------------------------------------------- /docs/images/flowdiagram.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/docs/images/flowdiagram.gif -------------------------------------------------------------------------------- /lib/mockito-all-1.9.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/lib/mockito-all-1.9.5.jar -------------------------------------------------------------------------------- /src/parser-tests/test36.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/src/parser-tests/test36.txt -------------------------------------------------------------------------------- /testsuite/lib/ant-1.6.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/lib/ant-1.6.5.jar -------------------------------------------------------------------------------- /testsuite/lib/crimson.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/lib/crimson.jar -------------------------------------------------------------------------------- /src/docs/images/overview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/src/docs/images/overview.gif -------------------------------------------------------------------------------- /testsuite/lib/electricxml.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/lib/electricxml.jar -------------------------------------------------------------------------------- /testsuite/lib/junit-3.8.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/lib/junit-3.8.1.jar -------------------------------------------------------------------------------- /testsuite/lib/log4j-core.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/lib/log4j-core.jar -------------------------------------------------------------------------------- /testsuite/src/webapp/basic/error-exception.jsp: -------------------------------------------------------------------------------- 1 | <% 2 | if ( true ) throw new Exception( "Some exception" ); 3 | %> -------------------------------------------------------------------------------- /testsuite/src/webapp/simple/page2.jsp: -------------------------------------------------------------------------------- 1 | Simple page2 2 | 3 |

Hello world 2

4 | 5 | -------------------------------------------------------------------------------- /www/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | This is the default project content. 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/docs/images/flowdiagram.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/src/docs/images/flowdiagram.gif -------------------------------------------------------------------------------- /testsuite/lib/cargo-ant-0.8.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/lib/cargo-ant-0.8.jar -------------------------------------------------------------------------------- /testsuite/lib/httpunit-1.6.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/lib/httpunit-1.6.1.jar -------------------------------------------------------------------------------- /testsuite/lib/jasper-runtime.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/lib/jasper-runtime.jar -------------------------------------------------------------------------------- /testsuite/lib/jetty-4.2.21.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/lib/jetty-4.2.21.jar -------------------------------------------------------------------------------- /testsuite/lib/oscore-2.2.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/lib/oscore-2.2.4.jar -------------------------------------------------------------------------------- /docs/cache.jsp.txt: -------------------------------------------------------------------------------- 1 | <% 2 | response.setHeader("Cache-Control", "public"); 3 | response.setHeader("Pragma", "cache"); 4 | %> -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /testsuite/lib/commons-logging.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/lib/commons-logging.jar -------------------------------------------------------------------------------- /testsuite/lib/jasper-compiler.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/lib/jasper-compiler.jar -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | target 3 | out 4 | *.iml 5 | *.ipr 6 | *.iws 7 | .idea 8 | dist 9 | .gradle 10 | .DS_Store 11 | -------------------------------------------------------------------------------- /src/docs/cache.jsp.txt: -------------------------------------------------------------------------------- 1 | <% 2 | response.setHeader("Cache-Control", "public"); 3 | response.setHeader("Pragma", "cache"); 4 | %> -------------------------------------------------------------------------------- /.cvsignore: -------------------------------------------------------------------------------- 1 | build 2 | dist 3 | target 4 | velocity.log* 5 | maven.log* 6 | clover 7 | *.i* 8 | .classpath 9 | .project 10 | -------------------------------------------------------------------------------- /testsuite/embedded/tomcat/lib/catalina.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/embedded/tomcat/lib/catalina.jar -------------------------------------------------------------------------------- /testsuite/embedded/tomcat/lib/jsp-api.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/embedded/tomcat/lib/jsp-api.jar -------------------------------------------------------------------------------- /testsuite/lib/cargo-core-uberjar-0.8.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/lib/cargo-core-uberjar-0.8.jar -------------------------------------------------------------------------------- /testsuite/src/webapp/request/inline.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="function.jsp"%> 2 | 3 | inline.jsp, request: <%= dumpRequest(request) %> 4 | -------------------------------------------------------------------------------- /lib/maven-resolver-ant-tasks-1.4.0-uber.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/lib/maven-resolver-ant-tasks-1.4.0-uber.jar -------------------------------------------------------------------------------- /testsuite/embedded/tomcat/lib/commons-el.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/embedded/tomcat/lib/commons-el.jar -------------------------------------------------------------------------------- /testsuite/src/webapp/binary/harry_potter.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/src/webapp/binary/harry_potter.gif -------------------------------------------------------------------------------- /testsuite/src/webapp/redirect/simple-rdforward.jsp: -------------------------------------------------------------------------------- 1 | <% application.getRequestDispatcher( "/redirect/page.jsp" ).forward( request, response ); %> -------------------------------------------------------------------------------- /testsuite/src/webapp/redirect/simple-rdinclude.jsp: -------------------------------------------------------------------------------- 1 | <% application.getRequestDispatcher( "/redirect/page.jsp" ).include( request, response ); %> -------------------------------------------------------------------------------- /testsuite/.cvsignore: -------------------------------------------------------------------------------- 1 | build 2 | dist 3 | target 4 | velocity.log* 5 | maven.log* 6 | clover 7 | test-results 8 | tmp 9 | results.html 10 | -------------------------------------------------------------------------------- /testsuite/embedded/tomcat/lib/servlet-api.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/embedded/tomcat/lib/servlet-api.jar -------------------------------------------------------------------------------- /testsuite/embedded/tomcat/lib/tomcat-coyote.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/embedded/tomcat/lib/tomcat-coyote.jar -------------------------------------------------------------------------------- /testsuite/embedded/tomcat/lib/tomcat-http.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/embedded/tomcat/lib/tomcat-http.jar -------------------------------------------------------------------------------- /testsuite/embedded/tomcat/lib/tomcat-util.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/embedded/tomcat/lib/tomcat-util.jar -------------------------------------------------------------------------------- /testsuite/src/webapp/inline/panel1.jsp: -------------------------------------------------------------------------------- 1 | 2 | panel 1 3 | 4 | The first panel 5 | 6 | -------------------------------------------------------------------------------- /testsuite/src/webapp/inline/panel2.jsp: -------------------------------------------------------------------------------- 1 | 2 | panel 2 3 | 4 | The second panel 5 | 6 | -------------------------------------------------------------------------------- /testsuite/src/webapp/simple/page4.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" %> 2 | <%= "\u0126\u0118\u0139\u0139\u0150" %> world 4 3 | 4 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/sitemesh/webapp/package.html: -------------------------------------------------------------------------------- 1 | 2 |

Provides integration of SiteMesh with Java web-applications.

3 | -------------------------------------------------------------------------------- /testsuite/embedded/tomcat/lib/commons-logging.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/embedded/tomcat/lib/commons-logging.jar -------------------------------------------------------------------------------- /testsuite/embedded/tomcat/lib/commons-modeler.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/embedded/tomcat/lib/commons-modeler.jar -------------------------------------------------------------------------------- /testsuite/embedded/tomcat/lib/jasper-compiler.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/embedded/tomcat/lib/jasper-compiler.jar -------------------------------------------------------------------------------- /testsuite/embedded/tomcat/lib/jasper-runtime.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/embedded/tomcat/lib/jasper-runtime.jar -------------------------------------------------------------------------------- /testsuite/embedded/tomcat/lib/naming-factory.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/embedded/tomcat/lib/naming-factory.jar -------------------------------------------------------------------------------- /testsuite/embedded/tomcat/lib/catalina-optional.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/embedded/tomcat/lib/catalina-optional.jar -------------------------------------------------------------------------------- /testsuite/embedded/tomcat/lib/naming-resources.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/embedded/tomcat/lib/naming-resources.jar -------------------------------------------------------------------------------- /testsuite/embedded/tomcat/lib/servlets-default.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/embedded/tomcat/lib/servlets-default.jar -------------------------------------------------------------------------------- /testsuite/embedded/tomcat/lib/jasper-compiler-jdt.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sitemesh/sitemesh2/HEAD/testsuite/embedded/tomcat/lib/jasper-compiler-jdt.jar -------------------------------------------------------------------------------- /testsuite/src/webapp/basic/page.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 | SiteMesh plain page 4 | 5 | 6 |

Plain page

7 | 8 | -------------------------------------------------------------------------------- /testsuite/src/webapp/basic/notmodified.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | SiteMesh plain page 4 | 5 | 6 |

Plain page

7 | 8 | -------------------------------------------------------------------------------- /testsuite/src/webapp/simple/multiple-set-content-type.jsp: -------------------------------------------------------------------------------- 1 | START 2 | <% response.setContentType("text/html");%> 3 | MIDDLE 4 | <% response.setContentType("text/html");%> 5 | END -------------------------------------------------------------------------------- /example/src/main/webapp/tiny-panel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | I'm a panel 4 | 5 | 6 | Hello, I'm a tiny little panel. 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/etc/blank/index.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 | Hello world! 4 | 5 | 6 | 7 |

Hello world!

8 | 9 | -------------------------------------------------------------------------------- /testsuite/src/webapp/request/function.jsp: -------------------------------------------------------------------------------- 1 | <%! 2 | String dumpRequest(HttpServletRequest req) { 3 | return req.getRequestURI() + "|" + req.getQueryString(); 4 | } 5 | %> 6 | -------------------------------------------------------------------------------- /testsuite/src/webapp/inline/page1.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 | content 1 4 | 5 | 6 | 7 |

page 1 content

8 | 9 | 10 | -------------------------------------------------------------------------------- /testsuite/src/webapp/inline/page2.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 | content 2 4 | 5 | 6 | 7 |

page 2 content

8 | 9 | 10 | -------------------------------------------------------------------------------- /testsuite/src/webapp/inline/page3.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 | content 3 4 | 5 | 6 | 7 |

page 3 content

8 | 9 | 10 | -------------------------------------------------------------------------------- /testsuite/src/webapp/inline/page7.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 | content 7 jsp 4 | 5 | 6 | 7 |

Page 7 jsp content

8 | 9 | 10 | -------------------------------------------------------------------------------- /testsuite/src/webapp/simple/static.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Simple page 4 | 5 | 6 | 7 |

Hello world

8 | 9 | 10 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/sitemesh/compatability/package.html: -------------------------------------------------------------------------------- 1 | 2 |

Compatibility classes to enable easy migration of SiteMesh 1 and 2 applications to SiteMesh 3.

3 | 4 | -------------------------------------------------------------------------------- /testsuite/src/webapp/simple/page1.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 | Simple page1 4 | 5 | 6 | 7 |

Hello world 1

8 | 9 | 10 | -------------------------------------------------------------------------------- /testsuite/src/webapp/inline/page7.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | content 7 static 4 | 5 | 6 | 7 |

Page 7 static content

8 | 9 | 10 | -------------------------------------------------------------------------------- /testsuite/src/webapp/redirect/page.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 | Another page 4 | 5 | 6 | 7 |

A different page

8 | 9 | 10 | -------------------------------------------------------------------------------- /testsuite/src/webapp/simple/exclude.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 | Undecorated Page 4 | 5 | 6 | 7 |

Hello world!

8 | 9 | 10 | -------------------------------------------------------------------------------- /example/src/main/webapp/meta2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | META Test 4 | 5 | 6 | 7 |

This page is where you were redirected!

8 | 9 | 10 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/html/StateChangeListener.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.html; 2 | 3 | public interface StateChangeListener { 4 | void stateFinished(); 5 | } 6 | -------------------------------------------------------------------------------- /src/parser-tests/test06.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | Hello world 3 3 | ~~~ TITLE ~~~ 4 | 5 | ~~~ PROPERTIES ~~~ 6 | 7 | title= 8 | 9 | 10 | ~~~ HEAD ~~~ 11 | 12 | 13 | ~~~ BODY ~~~ 14 | Hello world 3 -------------------------------------------------------------------------------- /testsuite/src/webapp/simple/exclude/page1.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 | Undecorated Page 4 | 5 | 6 | 7 |

Hello world

8 | 9 | 10 | -------------------------------------------------------------------------------- /testsuite/src/webapp/welcomepage/default.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 | Welcome Page 4 | 5 | 6 | 7 |

Welcome to the page

8 | 9 | 10 | -------------------------------------------------------------------------------- /testsuite/src/webapp/basic/text.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/plain" %> 2 | <%-- This page should be written using the writeoriginal method, as no decorator is mapped for text/plain --%> 3 | This is a plain page. -------------------------------------------------------------------------------- /testsuite/src/webapp/request/default.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="function.jsp"%> 2 | 3 | 4 | 5 | default.jsp, request: <%= dumpRequest(request) %> 6 | -------------------------------------------------------------------------------- /example/src/main/webapp/counter.jsp: -------------------------------------------------------------------------------- 1 | <%! int count=0; %> 2 | 3 | 4 | JSP counter 5 | 6 | 7 | 8 | 9 | The current count is... <%= ++count %> 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /testsuite/src/webapp/simple/page6.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Simple page6 5 | 6 | 7 | 8 |

Hello world 6

9 | 10 | 11 | -------------------------------------------------------------------------------- /testsuite/src/webapp/default.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 | SiteMesh test suite 4 | 5 | 6 | 7 |

SiteMesh test suite!

8 | 9 |

<%= new java.util.Date().getTime() %>

10 | 11 | 12 | -------------------------------------------------------------------------------- /example/src/main/webapp/agent.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 | Agent Test 4 | 5 | 6 | 7 |

This page will have a different decorator applied depending on the browser being used to access it.

8 | 9 | 10 | -------------------------------------------------------------------------------- /src/parser-tests/test31.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | 5 | 6 | ~~~ TITLE ~~~ 7 | 8 | 9 | ~~~ PROPERTIES ~~~ 10 | 11 | title= 12 | body.bgcolor=black 13 | 14 | ~~~ HEAD ~~~ 15 | 16 | 17 | ~~~ BODY ~~~ 18 | -------------------------------------------------------------------------------- /example/src/main/webapp/meta.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | META Test 4 | 5 | 6 | 7 | 8 |

You shouldn't be seeing this page for long.

9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/sitemesh/Decorator.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.sitemesh; 2 | 3 | /** 4 | * @author Joe Walnes 5 | * @since SiteMesh 3 6 | */ 7 | public interface Decorator { 8 | void render(Content content, SiteMeshContext context); 9 | } 10 | -------------------------------------------------------------------------------- /src/parser-tests/test26.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | 5 | blahblah 6 | 7 | 8 | ~~~ TITLE ~~~ 9 | ~~~ PROPERTIES ~~~ 10 | title= 11 | ~~~ HEAD ~~~ 12 | ~~~ BODY ~~~ 13 | blahblah -------------------------------------------------------------------------------- /testsuite/src/webapp/velocity/velocity.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 | Simple Velocity Page 4 | 5 | 6 | 7 |

Hello Velocity world

8 |

<%= "\u0126\u0118\u0139\u0139\u0150" %>

9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/parser/SuperFastSimplePageParser.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.parser; 2 | 3 | /** 4 | * @deprecated Renamed to PartialPageParser 5 | */ 6 | @Deprecated 7 | public class SuperFastSimplePageParser extends PartialPageParser { 8 | } 9 | -------------------------------------------------------------------------------- /testsuite/src/webapp/contentlength/page-decorator-none.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" %> 2 | 3 | 4 | Simple page1 5 | 6 | 7 | 8 | <%= "\u0126\u0118\u0139\u0139\u0150" %> world 4 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /testsuite/src/webapp/freemarker/freemarker.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 | Simple Freemarker Page 4 | 5 | 6 | 7 |

Hello Freemarker World

8 |

<%= "\u0126\u0118\u0139\u0139\u0150" %>

9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/sitemesh/SiteMeshContext.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.sitemesh; 2 | 3 | /** 4 | * @author Joe Walnes 5 | * @since SiteMesh 3 6 | */ 7 | public interface SiteMeshContext { 8 | void setContentType(String contentType); 9 | String getContentType(); 10 | } 11 | -------------------------------------------------------------------------------- /src/parser-tests/test05.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | Simple page2 3 | 4 |

Hello world 2

5 | 6 | ~~~ TITLE ~~~ 7 | 8 | Simple page2 9 | 10 | ~~~ PROPERTIES ~~~ 11 | 12 | title=Simple page2 13 | 14 | ~~~ HEAD ~~~ 15 | 16 | 17 | ~~~ BODY ~~~ 18 | 19 |

Hello world 2

-------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /docs/flow.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | SiteMesh Flow Diagram 4 | 5 | 6 |

7 | This diagram shows the flow of control within SiteMesh. 8 |

9 | 10 |

11 | 12 | 13 | -------------------------------------------------------------------------------- /src/docs/flow.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | SiteMesh Flow Diagram 4 | 5 | 6 |

7 | This diagram shows the flow of control within SiteMesh. 8 |

9 | 10 |

11 | 12 | 13 | -------------------------------------------------------------------------------- /src/parser-tests/superfast/test04.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 |

This is a pretty simple page.

4 | 5 |

Bye.

6 | 7 | ~~~ TITLE ~~~ 8 | 9 | ~~~ PROPERTIES ~~~ 10 | 11 | title= 12 | 13 | ~~~ HEAD ~~~ 14 | 15 | ~~~ BODY ~~~ 16 | 17 |

This is a pretty simple page.

18 | 19 |

Bye.

20 | -------------------------------------------------------------------------------- /src/parser-tests/test07.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | panel 1 4 | 5 | The first panel 6 | 7 | 8 | ~~~ TITLE ~~~ 9 | 10 | panel 1 11 | 12 | ~~~ PROPERTIES ~~~ 13 | 14 | title=panel 1 15 | 16 | ~~~ HEAD ~~~ 17 | 18 | 19 | ~~~ BODY ~~~ 20 | 21 | The first panel -------------------------------------------------------------------------------- /testsuite/src/webapp/multipass/content.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Some title 4 | 5 | 6 | 7 | [
A
] 8 | [
B
] 9 | [
C
] 10 | [
D
] 11 | 12 | 13 | -------------------------------------------------------------------------------- /testsuite/src/webapp/errorpage-200.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true" %><% response.setStatus(200); // as HttpWebUnit dies when you send a 500 error, then set to 200 just for testing! %> 2 | [-- An error has occurred --] 3 | <%= exception %> 4 | -------------------------------------------------------------------------------- /testsuite/src/webapp/inline/page4.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib prefix="page" uri="http://www.opensymphony.com/sitemesh/page" %> 2 | 3 | 4 | 5 | Inline 4 6 | 7 | 8 | 9 |

Hello

10 | 11 | 12 | 13 |

Bye

14 | 15 | 16 | -------------------------------------------------------------------------------- /src/etc/blank/WEB-INF/decorators.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | /* 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /testsuite/src/webapp/decorators/velocity.vm: -------------------------------------------------------------------------------- 1 | 2 | 3 | [:: $title ::] 4 | 7 | $head 8 | 9 | 10 | 11 | 12 | 13 |
$body
14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /example/src/main/webapp/decorators/test-ie.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %> 2 | 3 | 4 | <decorator:title default="Mysterious page..." /> 5 | 6 | 7 | 8 | 9 | 10 | 11 |

(IE version)

12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /example/src/main/webapp/decorators/test.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %> 2 | 3 | 4 | <decorator:title default="Mysterious page..." /> 5 | 6 | 7 | 8 | 9 | 10 | 11 |

(Default version)

12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /testsuite/src/webapp/decorators/freemarker.ftl: -------------------------------------------------------------------------------- 1 | 2 | 3 | [:: ${title} ::] 4 | 7 | $head 8 | 9 | 10 | 11 | 12 | 13 |
${body}
14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /example/src/main/webapp/decorators/test-lynx.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %> 2 | 3 | 4 | <decorator:title default="Mysterious page..." /> 5 | 6 | 7 | 8 | 9 | 10 | 11 |

(Lynx version)

12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /example/src/main/webapp/decorators/test-ns.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %> 2 | 3 | 4 | <decorator:title default="Mysterious page..." /> 5 | 6 | 7 | 8 | 9 | 10 | 11 |

(Netscape version)

12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /example/src/main/webapp/decorators/test-opera.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %> 2 | 3 | 4 | <decorator:title default="Mysterious page..." /> 5 | 6 | 7 | 8 | 9 | 10 | 11 |

(Opera version)

12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/parser-tests/test34.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | Hello World! HTML 5 | 6 | 7 |

Hello World! HTML

8 | 9 | 10 | ~~~ TITLE ~~~ 11 | 12 | Hello World! HTML 13 | 14 | ~~~ PROPERTIES ~~~ 15 | 16 | title=Hello World! HTML 17 | 18 | ~~~ HEAD ~~~ 19 | 20 | ~~~ BODY ~~~ 21 | 22 |

Hello World! HTML

-------------------------------------------------------------------------------- /example/src/main/webapp/counter-syntaxerror.jsp: -------------------------------------------------------------------------------- 1 | <%! int count=0; %> 2 | 3 | 4 | JSP counter 5 | 6 | 7 | 8 | 9 | The current count is... <%= ++count %> 10 | <% int foo=((Sttring)request.getAttribute("foo")).length(); %> 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /testsuite/src/webapp/request/decorator-inline.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %> 2 | <%@ include file="function.jsp"%> 3 | 4 | 5 | decorator-panel.jsp, request: <%= dumpRequest(request) %> 6 | 7 | decorator-panel.jsp, page.request: <%= dumpRequest(p.getRequest()) %> 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/parser-tests/test04.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | Simple page1 5 | 6 | 7 | 8 |

Hello world 1

9 | 10 | 11 | 12 | ~~~ TITLE ~~~ 13 | 14 | Simple page1 15 | 16 | ~~~ PROPERTIES ~~~ 17 | 18 | title=Simple page1 19 | 20 | ~~~ HEAD ~~~ 21 | 22 | 23 | ~~~ BODY ~~~ 24 | 25 |

Hello world 1

-------------------------------------------------------------------------------- /src/parser-tests/test09.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 |
3 | 4 | 5 |
6 | 7 | Bye
8 | ~~~ TITLE ~~~ 9 | 10 | ~~~ PROPERTIES ~~~ 11 | title= 12 | 13 | ~~~ HEAD ~~~ 14 | 15 | 16 | ~~~ BODY ~~~ 17 | 18 |
19 | 20 | 21 |
22 | 23 | Bye
-------------------------------------------------------------------------------- /src/parser-tests/test45.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | 5 | 6 | Support 7 | 8 | 9 | ~~~ TITLE ~~~ 10 | 11 | Support 12 | 13 | ~~~ PROPERTIES ~~~ 14 | 15 | meta.author=Someone 16 | title=Support 17 | 18 | ~~~ HEAD ~~~ 19 | 20 | 21 | 22 | ~~~ BODY ~~~ 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/parser-tests/test27.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | Here's some title 4 | 5 | 6 | 7 | ~~~ TITLE ~~~ 8 | 9 | Here's some title 10 | 11 | ~~~ PROPERTIES ~~~ 12 | 13 | title=Here's some title 14 | meta.author=Joe 15 | 16 | ~~~ HEAD ~~~ 17 | 18 | 19 | 20 | ~~~ BODY ~~~ 21 | -------------------------------------------------------------------------------- /src/parser-tests/test35.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 5 | my title 6 | 7 | hi 8 | 9 | 10 | ~~~ TITLE ~~~ 11 | 12 | my title 13 | 14 | ~~~ PROPERTIES ~~~ 15 | 16 | title=my title 17 | notonnewline=yo 18 | newline=hello 19 | anotherline=bye 20 | 21 | ~~~ HEAD ~~~ 22 | 23 | ~~~ BODY ~~~ 24 | 25 | hi -------------------------------------------------------------------------------- /src/parser-tests/test41.txt: -------------------------------------------------------------------------------- 1 | This test illustrates http://jira.opensymphony.com/browse/SIM-216. 2 | If tags are not matched, Sitemesh used to throw a NoSuchElementException. Handle unmatched tags 3 | 4 | ~~~ INPUT ~~~ 5 | Tongor 6 | 7 | ~~~ TITLE ~~~ 8 | 9 | 10 | ~~~ PROPERTIES ~~~ 11 | 12 | title= 13 | 14 | ~~~ HEAD ~~~ 15 | 16 | 17 | 18 | ~~~ BODY ~~~ 19 | Tongor 20 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/scalability/outputlength/NoopOutputLengthObserver.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.scalability.outputlength; 2 | 3 | /** 4 | */ 5 | public class NoopOutputLengthObserver implements OutputLengthObserver 6 | { 7 | public void nChars(long n) 8 | { 9 | } 10 | 11 | public void nBytes(long n) 12 | { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/parser-tests/test10.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | page title 5 | second title - THIS IS WRONG 6 | 7 | 8 |

PAGE BODY

9 | 10 | 11 | ~~~ TITLE ~~~ 12 | 13 | page title 14 | 15 | ~~~ PROPERTIES ~~~ 16 | 17 | title=page title 18 | 19 | ~~~ HEAD ~~~ 20 | 21 | 22 | ~~~ BODY ~~~ 23 | 24 |

PAGE BODY

-------------------------------------------------------------------------------- /src/parser-tests/test44.txt: -------------------------------------------------------------------------------- 1 | This test illustrates http://jira.opensymphony.com/browse/SIM-241 2 | Closing the HEAD tag without a corresponding opening tag throws and ArrayOutOfBoundsException 3 | 4 | ~~~ INPUT ~~~ 5 | 6 | 7 | 8 | ~~~ TITLE ~~~ 9 | 10 | 11 | ~~~ PROPERTIES ~~~ 12 | 13 | title= 14 | 15 | ~~~ HEAD ~~~ 16 | 17 | 18 | ~~~ BODY ~~~ 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /example/src/main/webapp/decorators/printable.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %> 2 | 3 | 4 | <decorator:title /> 5 | 6 | 7 | 8 | 9 |

10 |

(printable version)

11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/parser-tests/parsers.properties: -------------------------------------------------------------------------------- 1 | parser.html.class=com.opensymphony.module.sitemesh.parser.HTMLPageParser 2 | parser.html.tests=src/parser-tests 3 | 4 | parser.fast.class=com.opensymphony.module.sitemesh.parser.FastPageParser 5 | parser.fast.tests=src/parser-tests/superfast 6 | 7 | parser.superfast.class=com.opensymphony.module.sitemesh.parser.PartialPageParser 8 | parser.superfast.tests=src/parser-tests/superfast -------------------------------------------------------------------------------- /docs/style.jsp.txt: -------------------------------------------------------------------------------- 1 | <% 2 | String userAgent = request.getHeader("User-Agent"); 3 | 4 | if (userAgent != null && userAgent.indexOf("MSIE") == -1) { 5 | out.print(""); 6 | } 7 | else { 8 | out.print(""); 9 | } 10 | %> -------------------------------------------------------------------------------- /src/docs/style.jsp.txt: -------------------------------------------------------------------------------- 1 | <% 2 | String userAgent = request.getHeader("User-Agent"); 3 | 4 | if (userAgent != null && userAgent.indexOf("MSIE") == -1) { 5 | out.print(""); 6 | } 7 | else { 8 | out.print(""); 9 | } 10 | %> -------------------------------------------------------------------------------- /src/parser-tests/superfast/test03.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | 5 | 6 |

This is a pretty simple page.

7 | 8 |

Bye.

9 | 10 | 11 | 12 | 13 | ~~~ TITLE ~~~ 14 | 15 | ~~~ PROPERTIES ~~~ 16 | 17 | title= 18 | body.bgcolor=black 19 | 20 | ~~~ HEAD ~~~ 21 | 22 | ~~~ BODY ~~~ 23 | 24 |

This is a pretty simple page.

25 | 26 |

Bye.

27 | -------------------------------------------------------------------------------- /src/etc/blank/decorators/panel.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %> 2 | 3 |

4 | 5 | 6 | 9 | 10 | 11 | 14 | 15 |
7 | 8 |
12 | 13 |
16 |

-------------------------------------------------------------------------------- /src/etc/blank/decorators/main.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %> 2 | 3 | 4 | 5 | My Site - <decorator:title default="Welcome!" /> 6 | 7 | 8 | 9 | 10 | 11 |

(printable version)

12 | 13 | -------------------------------------------------------------------------------- /testsuite/embedded/tomcat/conf/context.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WEB-INF/web.xml 6 | 7 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /example/src/main/webapp/decorators/panel.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %> 2 | 3 |

4 | 5 | 6 | 9 | 10 | 11 | 14 | 15 |
7 | 8 |
12 | 13 |
16 |

17 | 18 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/sitemesh/DecoratorSelector.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.sitemesh; 2 | 3 | /** 4 | * Selects an appropriate Decorator for the Content. 5 | *
6 | * Note: Since SiteMesh 3, this replaces the DecoratorMapper. 7 | * 8 | * @author Joe Walnes 9 | * @since SiteMesh 3 10 | */ 11 | public interface DecoratorSelector { 12 | 13 | Decorator selectDecorator(Content content, SiteMeshContext context); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/parser-tests/superfast/test06.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | 5 | hello 6 | 7 | 8 |

This is a pretty simple page.

9 |

Bye.

10 | 11 | 12 | 13 | ~~~ TITLE ~~~ 14 | 15 | ~~~ PROPERTIES ~~~ 16 | 17 | title= 18 | page.blah=hello 19 | 20 | ~~~ HEAD ~~~ 21 | 22 | ~~~ BODY ~~~ 23 | 24 |

This is a pretty simple page.

25 |

Bye.

26 | -------------------------------------------------------------------------------- /src/parser-tests/test02.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | Hi. 4 | 5 |
6 | 7 | 8 |
9 | 10 | Bye
11 | 12 | ~~~ TITLE ~~~ 13 | ~~~ PROPERTIES ~~~ 14 | title= 15 | 16 | 17 | ~~~ HEAD ~~~ 18 | 19 | 20 | ~~~ BODY ~~~ 21 | Hi. 22 | 23 |
24 | 25 | 26 |
27 | 28 | Bye
-------------------------------------------------------------------------------- /testsuite/src/webapp/inline/page5.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib prefix="page" uri="http://www.opensymphony.com/sitemesh/page" %> 2 | 3 | 4 | 5 | content 5 6 | 7 | 8 | 9 |

page 5 content

10 | 11 | 12 | Some more inline stuff. 13 | 14 | 15 |

Bye

16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/parser-tests/test15.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | 5 |

This is a pretty simple page.

6 | 7 |

Bye.

8 | 9 | ~~~ TITLE ~~~ 10 | 11 | ~~~ PROPERTIES ~~~ 12 | 13 | title= 14 | meta.blah=cheese 15 | 16 | ~~~ HEAD ~~~ 17 | 18 | ~~~ BODY ~~~ 19 | 20 | 21 | 22 |

This is a pretty simple page.

23 | 24 |

Bye.

25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/parser-tests/test33.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | Here's some title 4 | 5 | 6 | 7 | ~~~ TITLE ~~~ 8 | 9 | Here's some title 10 | 11 | ~~~ PROPERTIES ~~~ 12 | 13 | xmlns\:prefix=www.opensymphony.com 14 | title=Here's some title 15 | meta.author=Joe 16 | 17 | ~~~ HEAD ~~~ 18 | 19 | 20 | 21 | ~~~ BODY ~~~ -------------------------------------------------------------------------------- /testsuite/src/webapp/inline/page6.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib prefix="page" uri="http://www.opensymphony.com/sitemesh/page" %> 2 | 3 | 4 | 5 | content 6 6 | 7 | 8 | 9 |

page 6 content

10 | 11 | 12 | <%= "\u0126\u0118\u0139\u0139\u0150" %> 13 | 14 | 15 |

Bye

16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /example/src/main/webapp/decorators/black.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %> 2 | 3 | 4 | <decorator:title default="Mysterious page..." /> 5 | 6 | 7 | 8 | 9 |
10 |

11 |
12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /example/src/main/webapp/google.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Google search 4 | 5 | 6 | 7 |
8 | Google 9 | 10 |
11 | 12 | 13 |
14 | 15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /src/parser-tests/test03.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | SiteMesh test suite 5 | 6 | 7 | 8 |

SiteMesh test suite!

9 | 10 |

Now

11 | 12 | 13 | 14 | 15 | ~~~ TITLE ~~~ 16 | 17 | SiteMesh test suite 18 | 19 | ~~~ PROPERTIES ~~~ 20 | 21 | title=SiteMesh test suite 22 | 23 | ~~~ HEAD ~~~ 24 | 25 | 26 | ~~~ BODY ~~~ 27 | 28 |

SiteMesh test suite!

29 | 30 |

Now

-------------------------------------------------------------------------------- /src/etc/blank/decorators/printable.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %> 2 | 3 | 4 | 5 | <decorator:title default="Welcome!" /> 6 | 7 | 8 | 9 | 10 | Printed on <%=new java.util.Date()%>.
11 |
12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /testsuite/src/webapp/multipass/expected-result.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Some title 5 | 6 | 7 | 8 | {
C
} 9 |
10 | 11 | 12 | [] 13 | [
B
] 14 | [] 15 | [
D
] 16 | 17 |
18 | {
A
} 19 | {
B
} 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/html/TagRule.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.html; 2 | 3 | public interface TagRule { 4 | void setContext(HTMLProcessorContext context); 5 | 6 | /** 7 | * Called by the HTMLProcessor to determine if a rule should be called for a given tag. 8 | * 9 | * The name parameter will always be passed in lowercase. 10 | */ 11 | boolean shouldProcess(String name); 12 | 13 | void process(Tag tag); 14 | } 15 | -------------------------------------------------------------------------------- /testsuite/src/java/testsuite/config/ConfigException.java: -------------------------------------------------------------------------------- 1 | package testsuite.config; 2 | 3 | /** 4 | * Exception thrown when reading config. 5 | * 6 | * @author Joe Walnes 7 | */ 8 | public class ConfigException extends Exception { 9 | 10 | private Exception cause; 11 | 12 | public ConfigException( String msg, Exception cause ) { 13 | super( msg ); 14 | this.cause = cause; 15 | } 16 | 17 | public Throwable getCause() { 18 | return cause; 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/sitemesh/ContentProcessor.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.sitemesh; 2 | 3 | import com.opensymphony.module.sitemesh.SitemeshBuffer; 4 | 5 | import java.io.IOException; 6 | 7 | /** 8 | * @author Joe Walnes 9 | * @since SiteMesh 3 10 | */ 11 | public interface ContentProcessor { 12 | 13 | boolean handles(SiteMeshContext context); 14 | boolean handles(String contentType); 15 | 16 | Content build(SitemeshBuffer buffer, SiteMeshContext context) throws IOException; 17 | } 18 | -------------------------------------------------------------------------------- /testsuite/embedded/tomcat/conf/tomcat-users.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /testsuite/src/webapp/inline/dec-5.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %> 2 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/page" prefix="page" %> 3 | 4 | 5 | 6 | {inline5} <decorator:title /> 7 | 8 | 9 | 10 | 11 |

12 | 13 |
14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /testsuite/src/webapp/inline/dec-6.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %> 2 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/page" prefix="page" %> 3 | 4 | 5 | 6 | {inline6} <decorator:title /> 7 | 8 | 9 | 10 | 11 |

12 | 13 |
14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /testsuite/src/webapp/multipass/decorator.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %> 2 | 3 | 4 | <decorator:title/> 5 | 6 | 7 | 8 | {} 9 |
10 | 11 |
12 | {} 13 | {} 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/multipass/ExtractPropertyTag.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.multipass; 2 | 3 | import com.opensymphony.module.sitemesh.taglib.decorator.PropertyTag; 4 | import com.opensymphony.module.sitemesh.Page; 5 | 6 | public class ExtractPropertyTag extends PropertyTag { 7 | 8 | public int doEndTag() { 9 | Page page = getPage(); 10 | page.addProperty("_sitemesh.removefrompage." + getProperty(), "true"); 11 | return super.doEndTag(); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/parser-tests/superfast/test02.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 |

This is a pretty simple page.

12 | 13 |

Bye.

14 | 15 | 16 | 17 | 18 | ~~~ TITLE ~~~ 19 | 20 | ~~~ PROPERTIES ~~~ 21 | 22 | title= 23 | 24 | ~~~ HEAD ~~~ 25 | 26 | 29 | 30 | ~~~ BODY ~~~ 31 | 32 |

This is a pretty simple page.

33 | 34 |

Bye.

35 | -------------------------------------------------------------------------------- /src/parser-tests/test12.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | 5 | Some page 6 | 7 | 8 | 9 |

This is a pretty simple page.

10 | 11 |

Bye.

12 | 13 | 14 | This should be ignored!! 15 | 16 | 17 | ~~~ TITLE ~~~ 18 | 19 | Some page 20 | 21 | ~~~ PROPERTIES ~~~ 22 | 23 | title=Some page 24 | body.bgcolor=black 25 | 26 | ~~~ HEAD ~~~ 27 | 28 | ~~~ BODY ~~~ 29 | 30 |

This is a pretty simple page.

31 | 32 |

Bye.

33 | 34 | 35 | -------------------------------------------------------------------------------- /src/parser-tests/test11.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | 5 | Some page 6 | WRONG TITLE 7 | 8 | 9 | 10 |

This is a pretty simple page.

11 | 12 |

Bye.

13 | 14 | 15 | 16 | 17 | ~~~ TITLE ~~~ 18 | 19 | Some page 20 | 21 | ~~~ PROPERTIES ~~~ 22 | 23 | title=Some page 24 | body.bgcolor=black 25 | 26 | ~~~ HEAD ~~~ 27 | 28 | ~~~ BODY ~~~ 29 | 30 |

This is a pretty simple page.

31 | 32 |

Bye.

33 | 34 | 35 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/html/rules/PageBuilder.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.html.rules; 2 | 3 | /** 4 | * Allows a TagRule to add information to a Page object. 5 | * 6 | * The standard HTML processing rules bundled with SiteMesh use this interface instead of direct coupling to the HTMLPage 7 | * class, allowing the rules to be used for HTML processing in applications outside of SiteMesh. 8 | * 9 | * @author Joe Walnes 10 | */ 11 | public interface PageBuilder { 12 | void addProperty(String key, String value); 13 | } 14 | -------------------------------------------------------------------------------- /src/parser-tests/test08.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | Here's some title 3 | 4 |
5 | 6 | 7 |
8 | 9 | Bye
10 | ~~~ TITLE ~~~ 11 | 12 | Here's some title 13 | 14 | ~~~ PROPERTIES ~~~ 15 | 16 | title=Here's some title 17 | meta.author=Joe 18 | 19 | ~~~ HEAD ~~~ 20 | 21 | 22 | ~~~ BODY ~~~ 23 | 24 | 25 |
26 | 27 | 28 |
29 | 30 | Bye
-------------------------------------------------------------------------------- /example/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'war' 3 | id "org.gretty" version "4.1.4" 4 | } 5 | 6 | gretty.contextPath = '/' 7 | 8 | defaultTasks 'jettyRun' 9 | 10 | description = 'SiteMesh2: Example Web-app' 11 | 12 | repositories { 13 | maven { 14 | name = 'Central Portal Snapshots' 15 | url = 'https://central.sonatype.com/repository/maven-snapshots/' 16 | content { 17 | includeModule('opensymphony', 'sitemesh') 18 | } 19 | } 20 | mavenCentral() 21 | } 22 | 23 | dependencies { 24 | implementation "opensymphony:sitemesh:${rootProject.version}" 25 | } 26 | -------------------------------------------------------------------------------- /src/parser-tests/test16.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 |

This is a pretty simple page.

12 | 13 |

Bye.

14 | 15 | ~~~ TITLE ~~~ 16 | 17 | ~~~ PROPERTIES ~~~ 18 | 19 | title= 20 | meta.blah=cheese 21 | 22 | ~~~ HEAD ~~~ 23 | 24 | 27 | 28 | ~~~ BODY ~~~ 29 | 30 | 31 | 32 |

This is a pretty simple page.

33 | 34 |

Bye.

35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/parser-tests/test29.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | 11 | 12 | 13 | 14 | ~~~ TITLE ~~~ 15 | 16 | ~~~ PROPERTIES ~~~ 17 | 18 | title= 19 | 20 | ~~~ HEAD ~~~ 21 | 22 | 29 | 30 | ~~~ BODY ~~~ 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/parser-tests/test30.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | 11 | 12 | 13 | 14 | ~~~ TITLE ~~~ 15 | 16 | ~~~ PROPERTIES ~~~ 17 | 18 | title= 19 | 20 | ~~~ HEAD ~~~ 21 | 22 | 29 | 30 | ~~~ BODY ~~~ 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/parser-tests/superfast/test07.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | 5 | 8 | 9 |

Some markup

10 |
11 | 12 | 13 |

This is a pretty simple page.

14 |

Bye.

15 | 16 | 17 | 18 | ~~~ TITLE ~~~ 19 | 20 | ~~~ PROPERTIES ~~~ 21 | 22 | title= 23 | page.blah=

Some markup

24 | 25 | ~~~ HEAD ~~~ 26 | 27 | 30 | 31 | ~~~ BODY ~~~ 32 | 33 |

This is a pretty simple page.

34 |

Bye.

35 | -------------------------------------------------------------------------------- /src/parser-tests/test42.txt: -------------------------------------------------------------------------------- 1 | This test illustrates http://jira.opensymphony.com/browse/SIM-180. 2 | Header content after a tag gets treated as part of the body 3 | 4 | ~~~ INPUT ~~~ 5 | 6 | 7 | Blah 8 | Etc. 9 | 12 | 13 | 14 | Blah blah blah 15 | 16 | 17 | ~~~ TITLE ~~~ 18 | 19 | Blah 20 | 21 | ~~~ PROPERTIES ~~~ 22 | 23 | title=Blah 24 | page.contentblah=Etc. 25 | 26 | ~~~ HEAD ~~~ 27 | 28 | 31 | 32 | 33 | ~~~ BODY ~~~ 34 | Blah blah blah 35 | -------------------------------------------------------------------------------- /example/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | sitemesh 9 | com.opensymphony.sitemesh.webapp.SiteMeshFilter 10 | 11 | 12 | 13 | sitemesh 14 | /* 15 | 16 | -------------------------------------------------------------------------------- /src/parser-tests/test32.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | "); 7 | window.document.writeln (""); 8 | } 9 | 10 | 11 | 12 | 13 | ~~~ TITLE ~~~ 14 | 15 | ~~~ PROPERTIES ~~~ 16 | 17 | title= 18 | 19 | ~~~ HEAD ~~~ 20 | "); 23 | window.document.writeln (""); 24 | } 25 | 26 | 27 | 28 | ~~~ BODY ~~~ 29 | 30 | 31 | -------------------------------------------------------------------------------- /example/src/main/webapp/random.pl: -------------------------------------------------------------------------------- 1 | #!perl 2 | 3 | $n = int (rand 1000) + 1; 4 | $hour = (localtime)[2]; 5 | 6 | if ($hour > 3 && $hour < 12) { 7 | $t = "morning"; 8 | } 9 | elsif ($hour < 19) { 10 | $t = "afternoon"; 11 | } 12 | elsif ($hour < 21) { 13 | $t = "evening"; 14 | } 15 | else { 16 | $t = "night"; 17 | } 18 | 19 | print <<"EOF"; 20 | Content-type: text/html 21 | 22 | 23 | 24 | Random number $n 25 | 26 | 27 | 28 | The full power of Perl is being harnessed to generate the number of 29 | $n! 30 | 31 |

32 | 33 | Have a nice $t. 34 | 35 | 36 | 37 | EOF 38 | 39 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/html/TextFilter.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.html; 2 | 3 | /** 4 | * TextFilters can be added to the HTMLProcessor (or specific States) and allow a simple means of filtering text content. 5 | * 6 | *

More than one TextFilter may be added to each HTMLProcessor/State and they will be called in the order they were added.

7 | * 8 | * @author Joe Walnes 9 | * 10 | * @see HTMLProcessor 11 | * @see State 12 | * @see com.opensymphony.module.sitemesh.html.rules.RegexReplacementTextFilter 13 | */ 14 | public interface TextFilter { 15 | 16 | String filter(String content); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /testsuite/src/webapp/WEB-INF/orion-web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | -------------------------------------------------------------------------------- /testsuite/src/webapp/request/decorator-main.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %> 2 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/page" prefix="page" %> 3 | <%@ include file="function.jsp"%> 4 | 5 | 6 | 7 | decorator-main.jsp, request: <%= dumpRequest(request) %> 8 | 9 | decorator-main.jsp, page.request before applyDecorator: <%= dumpRequest(p.getRequest()) %> 10 | 11 | 12 | 13 | 14 | decorator-main.jsp, page.request after applyDecorator: <%= dumpRequest(p.getRequest()) %> 15 | -------------------------------------------------------------------------------- /testsuite/src/webapp/WEB-INF/src/testsuite/servlets/ForwardServlet.java: -------------------------------------------------------------------------------- 1 | package testsuite.servlets; 2 | 3 | import jakarta.servlet.ServletException; 4 | import jakarta.servlet.http.HttpServletResponse; 5 | import jakarta.servlet.http.HttpServletRequest; 6 | import jakarta.servlet.http.HttpServlet; 7 | import java.io.IOException; 8 | 9 | public class ForwardServlet extends HttpServlet { 10 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 11 | String targetUrl = request.getParameter("target"); 12 | request.getRequestDispatcher(targetUrl).forward(request, response); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /testsuite/src/webapp/inline/page8.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib prefix="page" uri="http://www.opensymphony.com/sitemesh/page" %> 2 | <%@ taglib prefix="test" uri="test-tags" %> 3 | 4 | 5 | 6 | content 8 7 | 8 | 9 | 10 | 11 | 12 | 13 | Inline Title 14 | 15 | Some inline stuff. 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/etc/blank/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | sitemesh 10 | com.opensymphony.sitemesh.webapp.SiteMeshFilter 11 | 12 | 13 | 14 | sitemesh 15 | /* 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/html/HTMLProcessorContext.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.html; 2 | 3 | import com.opensymphony.module.sitemesh.SitemeshBuffer; 4 | import com.opensymphony.module.sitemesh.SitemeshBufferFragment; 5 | import com.opensymphony.module.sitemesh.html.util.CharArray; 6 | 7 | public interface HTMLProcessorContext { 8 | 9 | SitemeshBuffer getSitemeshBuffer(); 10 | 11 | State currentState(); 12 | void changeState(State newState); 13 | 14 | void pushBuffer(SitemeshBufferFragment.Builder fragment); 15 | SitemeshBufferFragment.Builder currentBuffer(); 16 | SitemeshBufferFragment.Builder popBuffer(); 17 | } 18 | -------------------------------------------------------------------------------- /testsuite/src/webapp/WEB-INF/test-tags.tld: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 1.0 10 | 1.2 11 | sitemesh-page 12 | test-tags 13 | SiteMesh Test Tags 14 | 15 | 16 | testTag 17 | jakarta.servlet.jsp.tagext.BodyTagSupport 18 | JSP 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/html/rules/FramesetRule.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.html.rules; 2 | 3 | import com.opensymphony.module.sitemesh.html.BasicRule; 4 | import com.opensymphony.module.sitemesh.html.Tag; 5 | 6 | public class FramesetRule extends BasicRule { 7 | 8 | private final PageBuilder page; 9 | 10 | public FramesetRule(PageBuilder page) { 11 | super(new String[] {"frame", "frameset"}); 12 | this.page = page; 13 | } 14 | 15 | public void process(Tag tag) { 16 | context.currentBuffer().delete(tag.getPosition(), tag.getLength()); 17 | page.addProperty("frameset", "true"); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /testsuite/src/webapp/decorators/simple.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %> 2 | 3 | 4 | [:: <decorator:title default="MySite" /> ::] 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/parser-tests/test40.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | 5 | Support 6 | 7 | 8 | 9 |

Empty at the moment. See contact.

10 | 11 | 12 | 13 | ~~~ TITLE ~~~ 14 | 15 | Support 16 | 17 | ~~~ PROPERTIES ~~~ 18 | 19 | title=Support 20 | mce_editor_0_formatSelect=

21 | mce_editor_0_styleSelect= 22 | meshcmsmodules=gallery_pooh_1999 23 | 24 | ~~~ HEAD ~~~ 25 | 26 | ~~~ BODY ~~~ 27 | 28 |

Empty at the moment. See contact.

29 | 30 | -------------------------------------------------------------------------------- /testsuite/src/webapp/inline/dec-panel.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %> 2 | 3 | 4 | 5 | 10 | 11 | 12 | 17 | 18 |
6 | 7 | "> 8 | 9 |
13 | 14 | 15 | 16 |
19 |
-------------------------------------------------------------------------------- /src/parser-tests/test13.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | 5 | Some page 6 | 7 | 8 | 9 |

This is a pretty simple page.

10 | 11 |

Bye.

12 | 13 | 16 | 17 | This should be here 18 | 19 | 20 | 21 | 22 | ~~~ TITLE ~~~ 23 | 24 | Some page 25 | 26 | ~~~ PROPERTIES ~~~ 27 | 28 | title=Some page 29 | body.bgcolor=black 30 | 31 | ~~~ HEAD ~~~ 32 | 33 | ~~~ BODY ~~~ 34 | 35 |

This is a pretty simple page.

36 | 37 |

Bye.

38 | 39 | 42 | 43 | This should be here 44 | 45 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/filter/PageFilter.java: -------------------------------------------------------------------------------- 1 | /* This software is published under the terms of the OpenSymphony Software 2 | * License version 1.1, of which a copy has been included with this 3 | * distribution in the LICENSE.txt file. */ 4 | package com.opensymphony.module.sitemesh.filter; 5 | 6 | import com.opensymphony.sitemesh.webapp.SiteMeshFilter; 7 | 8 | /** 9 | * @deprecated Use {@link com.opensymphony.sitemesh.webapp.SiteMeshFilter} instead. 10 | * 11 | * @author Joe Walnes 12 | * @author Scott Farquhar 13 | * @version $Revision: 1.17 $ 14 | */ 15 | public class PageFilter extends SiteMeshFilter { 16 | 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/parser-tests/superfast/test05.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | 5 | Some page 6 | 7 | 10 | 11 | 12 | 13 |

This is a pretty simple page.

14 | 15 |

Bye.

16 | 17 | ~~~ TITLE ~~~ 18 | 19 | Some page 20 | 21 | ~~~ PROPERTIES ~~~ 22 | 23 | title=Some page 24 | meta.author=Someone 25 | body.bgcolor=black 26 | 27 | ~~~ HEAD ~~~ 28 | 29 | 30 | 33 | 34 | ~~~ BODY ~~~ 35 | 36 |

This is a pretty simple page.

37 | 38 |

Bye.

39 | -------------------------------------------------------------------------------- /src/parser-tests/test01.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | 5 | Some page 6 | 7 | 10 | 11 | 12 | 13 |

This is a pretty simple page.

14 | 15 |

Bye.

16 | 17 | 18 | 19 | 20 | ~~~ TITLE ~~~ 21 | 22 | Some page 23 | 24 | ~~~ PROPERTIES ~~~ 25 | 26 | title=Some page 27 | meta.author=Someone 28 | body.bgcolor=black 29 | 30 | ~~~ HEAD ~~~ 31 | 32 | 33 | 36 | 37 | ~~~ BODY ~~~ 38 | 39 |

This is a pretty simple page.

40 | 41 |

Bye.

42 | -------------------------------------------------------------------------------- /src/parser-tests/test39.txt: -------------------------------------------------------------------------------- 1 | This test proves that http://jira.opensymphony.com/browse/SIM-206 isn't a problem anymore. 2 | 3 | ~~~ INPUT ~~~ 4 | 5 | 6 | 8 | 9 | 10 | Some page 11 | 12 | 13 | 14 |

This is a pretty simple page with an XML processing instruction header.

15 | 16 | 17 | 18 | 19 | ~~~ TITLE ~~~ 20 | 21 | Some page 22 | 23 | ~~~ PROPERTIES ~~~ 24 | 25 | title=Some page 26 | 27 | ~~~ HEAD ~~~ 28 | 29 | 30 | ~~~ BODY ~~~ 31 | 32 |

This is a pretty simple page with an XML processing instruction header.

33 | 34 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/filter/NullWriter.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.filter; 2 | 3 | import java.io.IOException; 4 | import java.io.Writer; 5 | 6 | /** 7 | * Just to keep super constructor for PrintWriter happy - it's never actually used. 8 | */ 9 | public class NullWriter extends Writer 10 | { 11 | public void write(char cbuf[], int off, int len) throws IOException 12 | { 13 | throw new UnsupportedOperationException(); 14 | } 15 | 16 | public void flush() throws IOException { 17 | throw new UnsupportedOperationException(); 18 | } 19 | 20 | public void close() throws IOException { 21 | throw new UnsupportedOperationException(); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/html/rules/ParameterExtractingRule.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.html.rules; 2 | 3 | import com.opensymphony.module.sitemesh.html.BasicRule; 4 | import com.opensymphony.module.sitemesh.html.Tag; 5 | 6 | public class ParameterExtractingRule extends BasicRule{ 7 | 8 | private final PageBuilder page; 9 | 10 | public ParameterExtractingRule(PageBuilder page) { 11 | super("parameter"); 12 | this.page = page; 13 | } 14 | 15 | public void process(Tag tag) { 16 | context.currentBuffer().delete(tag.getPosition(), tag.getLength()); 17 | page.addProperty("page." + tag.getAttributeValue("name", false), tag.getAttributeValue("value", false)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/parser-tests/superfast/test01.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | 5 | Some page 6 | 7 | 10 | 11 | 12 | 13 |

This is a pretty simple page.

14 | 15 |

Bye.

16 | 17 | 18 | 19 | 20 | ~~~ TITLE ~~~ 21 | 22 | Some page 23 | 24 | ~~~ PROPERTIES ~~~ 25 | 26 | title=Some page 27 | meta.author=Someone 28 | body.bgcolor=black 29 | 30 | ~~~ HEAD ~~~ 31 | 32 | 33 | 36 | 37 | ~~~ BODY ~~~ 38 | 39 |

This is a pretty simple page.

40 | 41 |

Bye.

42 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/html/rules/TitleExtractingRule.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.html.rules; 2 | 3 | import com.opensymphony.module.sitemesh.html.BlockExtractingRule; 4 | import com.opensymphony.module.sitemesh.html.Tag; 5 | 6 | public class TitleExtractingRule extends BlockExtractingRule { 7 | 8 | private final PageBuilder page; 9 | 10 | private boolean seenTitle; 11 | 12 | public TitleExtractingRule(PageBuilder page) { 13 | super(false, "title"); 14 | this.page = page; 15 | } 16 | 17 | protected void end(Tag tag) { 18 | if (!seenTitle) { 19 | page.addProperty("title", getCurrentBufferContent()); 20 | seenTitle = true; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/scalability/outputlength/OutputLengthObserver.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.scalability.outputlength; 2 | 3 | /** 4 | * An interface that observes the length of output as it is written to streams and writers 5 | * and hence allows action to be taken if its too much 6 | */ 7 | public interface OutputLengthObserver 8 | { 9 | /** 10 | * The {@link java.io.OutputStream is about to write n bytes} 11 | * @param n the number of bytes about to be written 12 | */ 13 | void nBytes(long n); 14 | 15 | /** 16 | * The {@link java.io.Writer is about to write n characters} 17 | * @param n the number of characters about to be written 18 | */ 19 | void nChars(long n); 20 | } 21 | -------------------------------------------------------------------------------- /testsuite/src/webapp/WEB-INF/src/testsuite/servlets/StandardServlet.java: -------------------------------------------------------------------------------- 1 | package testsuite.servlets; 2 | 3 | import com.opensymphony.module.sitemesh.RequestConstants; 4 | 5 | import jakarta.servlet.ServletException; 6 | import jakarta.servlet.http.HttpServlet; 7 | import jakarta.servlet.http.HttpServletRequest; 8 | import jakarta.servlet.http.HttpServletResponse; 9 | import java.io.IOException; 10 | 11 | public class StandardServlet extends HttpServlet { 12 | 13 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 14 | response.setContentType("text/html"); 15 | response.getWriter().println("standard stuffbody"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /example/src/main/webapp/inline.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/page" prefix="page" %> 2 | 3 | 4 | Inline decorator example 5 | 6 | 7 |

This is a sample of an inline decorator.

8 | 9 | 10 | 11 | 12 | Inline content 13 | Some inline stuff. 14 | 15 | 16 | 17 | Some more inline stuff. 18 | 19 | 20 |

This is a sample of an inline decorator accessing external content.

21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/parser-tests/test28.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | Application Test 5 | 6 | 7 | 8 |

Application Test

9 | 10 |
11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | ~~~ TITLE ~~~ 20 | 21 | Application Test 22 | 23 | ~~~ PROPERTIES ~~~ 24 | 25 | title=Application Test 26 | 27 | ~~~ HEAD ~~~ 28 | ~~~ BODY ~~~ 29 | 30 |

Application Test

31 | 32 |
33 | 34 | 35 | 36 | 37 |
-------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/scalability/ScalabilitySupport.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.scalability; 2 | 3 | import com.opensymphony.module.sitemesh.scalability.outputlength.OutputLengthObserver; 4 | import com.opensymphony.module.sitemesh.scalability.secondarystorage.SecondaryStorage; 5 | 6 | /** 7 | * This is really an internal interface to give out to SiteMesh methods so 8 | * that it takes a single parameter and not four parameters. Its a view of the scalability 9 | * support as configured by the host application. 10 | */ 11 | public interface ScalabilitySupport 12 | { 13 | OutputLengthObserver getOutputLengthObserver(); 14 | 15 | SecondaryStorage getSecondaryStorage(); 16 | 17 | int getInitialBufferSize(); 18 | 19 | boolean isMaxOutputLengthExceededThrown(); 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/html/rules/HeadExtractingRule.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.html.rules; 2 | 3 | import com.opensymphony.module.sitemesh.SitemeshBuffer; 4 | import com.opensymphony.module.sitemesh.SitemeshBufferFragment; 5 | import com.opensymphony.module.sitemesh.html.BlockExtractingRule; 6 | import com.opensymphony.module.sitemesh.html.util.CharArray; 7 | 8 | public class HeadExtractingRule extends BlockExtractingRule { 9 | 10 | private final SitemeshBufferFragment.Builder head; 11 | 12 | public HeadExtractingRule(SitemeshBufferFragment.Builder head) { 13 | super(false, "head"); 14 | this.head = head; 15 | } 16 | 17 | protected SitemeshBufferFragment.Builder createBuffer(SitemeshBuffer sitemeshBuffer) { 18 | return head; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/taglib/decorator/UseHTMLPageTEI.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Title: UseHTMLPageTEI 3 | * Description: 4 | * 5 | * This software is published under the terms of the OpenSymphony Software 6 | * License version 1.1, of which a copy has been included with this 7 | * distribution in the LICENSE.txt file. 8 | */ 9 | 10 | package com.opensymphony.module.sitemesh.taglib.decorator; 11 | 12 | /** 13 | * TagExtraInfo implementation to expose HTMLPage object as variable. 14 | * 15 | * @author Joe Walnes 16 | * @version $Revision: 1.1 $ 17 | * 18 | * @see UsePageTag 19 | * @see UsePageTEI 20 | */ 21 | public class UseHTMLPageTEI extends UsePageTEI { 22 | protected String getType() { 23 | return "com.opensymphony.module.sitemesh.HTMLPage"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/parser-tests/test22.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | 5 | Some page 6 | 7 | 10 | 11 | 12 | 13 |

This is a pretty simple page.

14 | 15 |

Bye.

16 | 17 | 18 | 19 | 20 | ~~~ TITLE ~~~ 21 | 22 | Some page 23 | 24 | ~~~ PROPERTIES ~~~ 25 | 26 | title=Some page 27 | meta.author=Someone 28 | body.bgcolor=black 29 | decorator=something 30 | language=en 31 | 32 | ~~~ HEAD ~~~ 33 | 34 | 35 | 38 | 39 | ~~~ BODY ~~~ 40 | 41 |

This is a pretty simple page.

42 | 43 |

Bye.

44 | 45 | 46 | -------------------------------------------------------------------------------- /testsuite/src/webapp/WEB-INF/src/testsuite/servlets/ContentLengthServlet.java: -------------------------------------------------------------------------------- 1 | package testsuite.servlets; 2 | 3 | import jakarta.servlet.ServletException; 4 | import jakarta.servlet.http.HttpServlet; 5 | import jakarta.servlet.http.HttpServletRequest; 6 | import jakarta.servlet.http.HttpServletResponse; 7 | import java.io.IOException; 8 | 9 | public class ContentLengthServlet extends HttpServlet { 10 | 11 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 12 | response.setContentType("text/html"); 13 | int length = Integer.parseInt(request.getParameter("content-length")); 14 | response.setContentLength(length); 15 | for (int i=0; i< length; i++) 16 | { 17 | response.getWriter().write("a"); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/html/rules/ContentBlockExtractingRule.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.html.rules; 2 | 3 | import com.opensymphony.module.sitemesh.html.BlockExtractingRule; 4 | import com.opensymphony.module.sitemesh.html.Tag; 5 | 6 | public class ContentBlockExtractingRule extends BlockExtractingRule { 7 | 8 | private final PageBuilder page; 9 | 10 | private String contentBlockId; 11 | 12 | public ContentBlockExtractingRule(PageBuilder page) { 13 | super(false, "content"); 14 | this.page = page; 15 | } 16 | 17 | protected void start(Tag tag) { 18 | contentBlockId = tag.getAttributeValue("tag", false); 19 | } 20 | 21 | protected void end(Tag tag) { 22 | page.addProperty("page." + contentBlockId, getCurrentBufferContent()); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /testsuite/src/webapp/WEB-INF/weblogic.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | encoding 13 | UTF-8 14 | 15 | 16 | compilerSupportsEncoding 17 | false 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/scalability/secondarystorage/NoopSecondaryStorage.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.scalability.secondarystorage; 2 | 3 | import java.io.Writer; 4 | 5 | /** 6 | * A secondary storage that does nothing. 7 | */ 8 | public class NoopSecondaryStorage implements SecondaryStorage 9 | { 10 | public long getMemoryLimitBeforeUse() 11 | { 12 | return -1; 13 | } 14 | 15 | public void write(int c) 16 | { 17 | } 18 | 19 | public void write(char[] chars, int off, int len) 20 | { 21 | } 22 | 23 | public void write(String str, int off, int len) 24 | { 25 | } 26 | 27 | public void write(String str) 28 | { 29 | } 30 | 31 | public void writeTo(Writer out) 32 | { 33 | 34 | } 35 | 36 | public void cleanUp() 37 | { 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /example/src/main/webapp/badpanel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | SiteMesh Sample Site 4 | 5 | 6 | 7 | 8 |

Welcome to the SiteMesh sample...

9 | 10 |

Samples

11 | 12 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /example/src/main/webapp/badsource.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | SiteMesh Sample Site 4 | 5 | 6 | 7 | 8 |

Welcome to the SiteMesh sample...

9 | 10 |

Samples

11 | 12 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/PageParserSelector.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh; 2 | 3 | /** 4 | * @author Joe Walnes 5 | */ 6 | public interface PageParserSelector { 7 | 8 | /** 9 | * Determine whether a Page of given content-type should be parsed or not. 10 | */ 11 | boolean shouldParsePage(String contentType); 12 | 13 | /** 14 | * Create a PageParser suitable for the given content-type. 15 | * 16 | *

For example, if the supplied parameter is text/html 17 | * a parser shall be returned that can parse HTML accordingly.

Never returns null. 18 | * 19 | * @param contentType The MIME content-type of the data to be parsed 20 | * @return Appropriate PageParser for reading data 21 | * 22 | */ 23 | PageParser getPageParser(String contentType); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /example/src/main/webapp/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | SiteMesh Sample Site 4 | 5 | 6 | 7 |

Welcome to the SiteMesh sample...

8 | 9 |

Samples

10 | 11 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/parser-tests/test43.txt: -------------------------------------------------------------------------------- 1 | This test illustrates http://jira.opensymphony.com/browse/SIM-172 2 | Unclosed quotes cause parsing problem (note unclosed quote after the first 'area' tag) 3 | 4 | ~~~ INPUT ~~~ 5 | 6 | 7 | 8 | 9 | 10 | 11 | ~~~ TITLE ~~~ 12 | 13 | 14 | 15 | ~~~ PROPERTIES ~~~ 16 | 17 | title= 18 | 19 | ~~~ HEAD ~~~ 20 | 21 | 22 | ~~~ BODY ~~~ 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/html/rules/MetaTagRule.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.html.rules; 2 | 3 | import com.opensymphony.module.sitemesh.html.BasicRule; 4 | import com.opensymphony.module.sitemesh.html.Tag; 5 | 6 | public class MetaTagRule extends BasicRule { 7 | 8 | private final PageBuilder page; 9 | 10 | public MetaTagRule(PageBuilder page) { 11 | super("meta"); 12 | this.page = page; 13 | } 14 | 15 | public void process(Tag tag) { 16 | if (tag.hasAttribute("name", false)) { 17 | page.addProperty("meta." + tag.getAttributeValue("name", false), tag.getAttributeValue("content", false)); 18 | } else if (tag.hasAttribute("http-equiv", false)) { 19 | page.addProperty("meta.http-equiv." + tag.getAttributeValue("http-equiv", false), tag.getAttributeValue("content", false)); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/parser-tests/test24.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | 5 | Some page 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 |

This is a pretty simple page.

16 | 17 |

Bye.

18 | 19 | 20 | 21 | 22 | ~~~ TITLE ~~~ 23 | 24 | Some page 25 | 26 | ~~~ PROPERTIES ~~~ 27 | 28 | title=Some page 29 | meta.author=Someone 30 | body.bgcolor=black 31 | meta.http-equiv.content-type=text/html 32 | 33 | ~~~ HEAD ~~~ 34 | 35 | 36 | 39 | 40 | 41 | ~~~ BODY ~~~ 42 | 43 |

This is a pretty simple page.

44 | 45 |

Bye.

46 | 47 | 48 | -------------------------------------------------------------------------------- /docs/api/package-list: -------------------------------------------------------------------------------- 1 | com.opensymphony.module.sitemesh 2 | com.opensymphony.module.sitemesh.factory 3 | com.opensymphony.module.sitemesh.filter 4 | com.opensymphony.module.sitemesh.freemarker 5 | com.opensymphony.module.sitemesh.html 6 | com.opensymphony.module.sitemesh.html.rules 7 | com.opensymphony.module.sitemesh.html.tokenizer 8 | com.opensymphony.module.sitemesh.html.util 9 | com.opensymphony.module.sitemesh.mapper 10 | com.opensymphony.module.sitemesh.multipass 11 | com.opensymphony.module.sitemesh.parser 12 | com.opensymphony.module.sitemesh.taglib 13 | com.opensymphony.module.sitemesh.taglib.decorator 14 | com.opensymphony.module.sitemesh.taglib.page 15 | com.opensymphony.module.sitemesh.tapestry 16 | com.opensymphony.module.sitemesh.util 17 | com.opensymphony.module.sitemesh.velocity 18 | com.opensymphony.sitemesh 19 | com.opensymphony.sitemesh.compatability 20 | com.opensymphony.sitemesh.webapp 21 | com.opensymphony.sitemesh.webapp.decorator 22 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/html/rules/HtmlAttributesRule.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.html.rules; 2 | 3 | import com.opensymphony.module.sitemesh.html.BasicRule; 4 | import com.opensymphony.module.sitemesh.html.Tag; 5 | 6 | public class HtmlAttributesRule extends BasicRule{ 7 | 8 | private final PageBuilder page; 9 | 10 | public HtmlAttributesRule(PageBuilder page) { 11 | super("html"); 12 | this.page = page; 13 | } 14 | 15 | public void process(Tag tag) { 16 | if (tag.getType() == Tag.OPEN) { 17 | context.currentBuffer().markStart(tag.getPosition() + tag.getLength()); 18 | for (int i = 0; i < tag.getAttributeCount(); i++) { 19 | page.addProperty(tag.getAttributeName(i), tag.getAttributeValue(i)); 20 | } 21 | } else { 22 | context.currentBuffer().end(tag.getPosition()); 23 | } 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/parser-tests/test25.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | 17 | 18 | 19 | 20 | ~~~ TITLE ~~~ 21 | 22 | ~~~ PROPERTIES ~~~ 23 | 24 | title= 25 | 26 | ~~~ HEAD ~~~ 27 | 28 | 41 | 42 | ~~~ BODY ~~~ 43 | 44 | 45 | -------------------------------------------------------------------------------- /docs/api/script.js: -------------------------------------------------------------------------------- 1 | function show(type) 2 | { 3 | count = 0; 4 | for (var key in methods) { 5 | var row = document.getElementById(key); 6 | if ((methods[key] & type) != 0) { 7 | row.style.display = ''; 8 | row.className = (count++ % 2) ? rowColor : altColor; 9 | } 10 | else 11 | row.style.display = 'none'; 12 | } 13 | updateTabs(type); 14 | } 15 | 16 | function updateTabs(type) 17 | { 18 | for (var value in tabs) { 19 | var sNode = document.getElementById(tabs[value][0]); 20 | var spanNode = sNode.firstChild; 21 | if (value == type) { 22 | sNode.className = activeTableTab; 23 | spanNode.innerHTML = tabs[value][1]; 24 | } 25 | else { 26 | sNode.className = tableTab; 27 | spanNode.innerHTML = "" + tabs[value][1] + ""; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /example/src/main/webapp/toggledecorator.jsp: -------------------------------------------------------------------------------- 1 | <%! boolean toggle; %> 2 | 3 | 4 | Toggled Decorator 5 | "> 6 | <% toggle = !toggle; %> 7 | 8 | 9 | 10 |

This page is an example of how a Decorator can be chosen by the actual page itself.

11 | 12 |

Within the HTML is a <meta> tag that states which Decorator to use. 13 | A bit of JSP alternates the value of this tag on each request.

14 | 15 |

The top of the page looks like this:

16 | 17 |
18 | <%! boolean toggle; %>
19 | <html>
20 |   <head>
21 |     <title>Toggled Decorator</title>
22 |     <meta name="decorator" content="<%= toggle ? "black" : "main" %>">
23 |     <% toggle = !toggle; %>
24 |   </head>
25 |   ...
26 | 		
27 | 28 |

Refresh this page! (and again and again)

29 | 30 | 31 | -------------------------------------------------------------------------------- /example/src/main/webapp/mandelbrot.pl: -------------------------------------------------------------------------------- 1 | #!perl 2 | 3 | sub mandelbrot { 4 | $Cols=79; $Lines=30; 5 | $MaxIter=16; 6 | $MinRe=-2.0; $MaxRe=1.0; 7 | $MinIm=-1.0; $MaxIm=1.0; 8 | @chars=(' ','.',',','-',':','/','=','H','O','A','M','%','&','$','#','@','_'); 9 | my $result = "\n"; 10 | for($Im=$MinIm;$Im<=$MaxIm;$Im+=($MaxIm-$MinIm)/$Lines) 11 | { for($Re=$MinRe;$Re<=$MaxRe;$Re+=($MaxRe-$MinRe)/$Cols) 12 | { $zr=$Re; $zi=$Im; 13 | for($n=0;$n<$MaxIter;$n++) 14 | { $a=$zr*$zr; $b=$zi*$zi; 15 | if($a+$b>4.0) { last; } 16 | $zi=2*$zr*$zi+$Im; $zr=$a-$b+$Re; 17 | } 18 | $result .= $chars[$n]; 19 | } 20 | $result .= "\n"; 21 | } 22 | $result; 23 | } 24 | 25 | my $m = mandelbrot(); 26 | 27 | print "Content-type: text/html\n\n"; 28 | 29 | print <<"EOF"; 30 | 31 | 32 | Perl Mandelbrot 33 | 34 | 35 |

I am a Perl CGI

36 | 37 |
38 | 			$m
39 | 		
40 | 41 | 42 | 43 | EOF 44 | 45 | -------------------------------------------------------------------------------- /src/test/java/com/opensymphony/module/sitemesh/scalability/secondarystorage/TeeWriter.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.scalability.secondarystorage; 2 | 3 | import java.io.IOException; 4 | import java.io.Writer; 5 | 6 | /** 7 | */ 8 | class TeeWriter extends Writer 9 | { 10 | 11 | private final Writer out; 12 | private final Writer out2; 13 | 14 | public TeeWriter(Writer out, Writer out2) 15 | { 16 | super(out); 17 | this.out = out; 18 | this.out2 = out2; 19 | } 20 | 21 | @Override 22 | public void write(char[] cbuf, int off, int len) throws IOException 23 | { 24 | out.write(cbuf,off,len); 25 | out2.write(cbuf,off,len); 26 | } 27 | 28 | @Override 29 | public void flush() throws IOException 30 | { 31 | out.flush(); 32 | out2.flush(); 33 | } 34 | 35 | @Override 36 | public void close() throws IOException 37 | { 38 | out.close(); 39 | out2.close(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/scalability/outputlength/MaxOutputLengthExceeded.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.scalability.outputlength; 2 | 3 | /** 4 | * An exception that is thrown if the maximum output length is exceeded. 5 | */ 6 | public class MaxOutputLengthExceeded extends RuntimeException 7 | { 8 | private final long maxOutputLength; 9 | private final int maximumOutputExceededHttpCode; 10 | 11 | public MaxOutputLengthExceeded(final long maxOutputLength, final int maximumOutputExceededHttpCode) 12 | { 13 | super("The maximum output length of " + maxOutputLength + " bytes has been exceeded"); 14 | this.maxOutputLength = maxOutputLength; 15 | this.maximumOutputExceededHttpCode = maximumOutputExceededHttpCode; 16 | } 17 | 18 | public long getMaxOutputLength() 19 | { 20 | return maxOutputLength; 21 | } 22 | 23 | public int getMaximumOutputExceededHttpCode() 24 | { 25 | return maximumOutputExceededHttpCode; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /example/src/main/webapp/decorators/main.css: -------------------------------------------------------------------------------- 1 | body, td, p { 2 | font: normal x-small verdana, arial, helvetica, sans-serif; 3 | } 4 | 5 | .panelTitle { 6 | background-color: #003399; 7 | color:#eeeeee; 8 | font-weight: bold; 9 | border-color: #3366ff #000033 #000033 #3366ff; 10 | border-width: 1; 11 | border-style: solid; 12 | padding: 1; 13 | } 14 | 15 | .panelBody { 16 | background-color: #eeeeee; 17 | border-color: black; 18 | border-width: 0 1 1 1; 19 | border-style: solid; 20 | padding: 2; 21 | } 22 | 23 | #pageTitle { 24 | background-color: #003399; 25 | color:#eeeeee; 26 | font-weight: bold; 27 | font-size: large; 28 | border-color: #3366ff #000033 #000033 #3366ff; 29 | border-width: 1; 30 | border-style: solid; 31 | padding: 1; 32 | text-align: center; 33 | } 34 | 35 | #footer { 36 | background-color:#999999; 37 | font-size: xx-small; 38 | text-align: center; 39 | color: white; 40 | border-color: #666666 #cccccc #cccccc #666666; 41 | border-width: 1; 42 | border-style: solid; 43 | padding: 1; 44 | } 45 | 46 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/sitemesh/webapp/ContainerTweaks.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.sitemesh.webapp; 2 | 3 | import com.opensymphony.module.sitemesh.util.Container; 4 | 5 | /** 6 | * Provides details of which tweaks should be used in SiteMesh - necessary because containers behave subtly different. 7 | * 8 | * @author Joe Walnes 9 | * @since SiteMesh 3 10 | */ 11 | public class ContainerTweaks { 12 | 13 | // TODO: Externalize these into a config file (optional of course!), allowing users to change them at runtime if needed. 14 | 15 | private final int container = Container.get(); 16 | 17 | public boolean shouldAutoCreateSession() { 18 | return false; 19 | // return container == Container.TOMCAT; - this is removed due to SIM-151. 20 | } 21 | 22 | public boolean shouldLogUnhandledExceptions() { 23 | return container == Container.TOMCAT; 24 | } 25 | 26 | public boolean shouldIgnoreIllegalStateExceptionOnErrorPage() { 27 | return container == Container.WEBLOGIC; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /testsuite/src/java/testsuite/sitemesh/VelocityDecoratorTest.java: -------------------------------------------------------------------------------- 1 | package testsuite.sitemesh; 2 | 3 | import com.meterware.httpunit.WebResponse; 4 | import electric.xml.Document; 5 | import testsuite.tester.WebTest; 6 | 7 | /** 8 | * @author Mathias Bogaert 9 | * @version $Revision: 1.3 $ 10 | */ 11 | public class VelocityDecoratorTest extends WebTest { 12 | public void testVelocityDecoratedPage() throws Exception { 13 | WebResponse rs = wc.getResponse( baseUrl + "/velocity/velocity.jsp" ); 14 | Document doc = getDocument( rs ); 15 | assertEquals( "[:: Simple Velocity Page ::]", rs.getTitle() ); 16 | assertEquals( "Hello Velocity world", doc.getElementWithId( "p1" ).getText().toString() ); 17 | assertEquals( "footer", doc.getElementWithId( "footer" ).getText().toString() ); 18 | assertEquals( "Simple Velocity Page", doc.getElementWithId( "header" ).getText().toString() ); 19 | assertEquals( "\u0126\u0118\u0139\u0139\u0150", doc.getElementWithId( "i18n" ).getText().toString() ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /testsuite/src/webapp/inline/dec-7.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %> 2 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/page" prefix="page" %> 3 | 4 | 5 | 6 | {inline7} <decorator:title /> 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 21 | 24 | 27 | 28 | 29 | 32 | 33 |
14 | 15 |
19 | 20 | 22 | 23 | 25 | 26 |
34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /docs/api/com/opensymphony/module/sitemesh/taglib/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | com.opensymphony.module.sitemesh.taglib (OpenSymphony SiteMesh 2.5 API) 7 | 8 | 9 | 10 | 11 | 12 |

com.opensymphony.module.sitemesh.taglib

13 |
14 |

Classes

15 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/taglib/decorator/BodyTag.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Title: BodyTag 3 | * Description: 4 | * 5 | * This software is published under the terms of the OpenSymphony Software 6 | * License version 1.1, of which a copy has been included with this 7 | * distribution in the LICENSE.txt file. 8 | */ 9 | 10 | package com.opensymphony.module.sitemesh.taglib.decorator; 11 | 12 | import com.opensymphony.module.sitemesh.taglib.AbstractTag; 13 | 14 | /** 15 | * Write original Page body to out. 16 | * 17 | * @author Joe Walnes 18 | * @author Scott Farquhar 19 | * @version $Revision: 1.2 $ 20 | * 21 | * @see com.opensymphony.module.sitemesh.HTMLPage#writeBody(java.io.Writer) 22 | */ 23 | public class BodyTag extends AbstractTag { 24 | public final int doEndTag() { 25 | try { 26 | getPage().writeBody(getOut()); 27 | } 28 | catch (Exception e) { 29 | trace(e); 30 | } 31 | return EVAL_PAGE; 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /testsuite/src/java/testsuite/sitemesh/FreemarkerDecoratorTest.java: -------------------------------------------------------------------------------- 1 | package testsuite.sitemesh; 2 | 3 | import com.meterware.httpunit.WebResponse; 4 | import electric.xml.Document; 5 | import testsuite.tester.WebTest; 6 | 7 | /** 8 | * @author Richard Hallier 9 | * @version $Revision: 1.2 $ 10 | */ 11 | public class FreemarkerDecoratorTest extends WebTest { 12 | public void testFreemarkerDecoratedPage() throws Exception { 13 | WebResponse rs = wc.getResponse( baseUrl + "/freemarker/freemarker.jsp" ); 14 | Document doc = getDocument( rs ); 15 | assertEquals( "[:: Simple Freemarker Page ::]", rs.getTitle() ); 16 | assertEquals( "Hello Freemarker World", doc.getElementWithId( "p1" ).getText().toString() ); 17 | assertEquals( "footer", doc.getElementWithId( "footer" ).getText().toString() ); 18 | assertEquals( "Simple Freemarker Page", doc.getElementWithId( "header" ).getText().toString() ); 19 | assertEquals( "\u0126\u0118\u0139\u0139\u0150", doc.getElementWithId( "i18n" ).getText().toString() ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/html/StateTransitionRule.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.html; 2 | 3 | public class StateTransitionRule extends BasicRule { 4 | 5 | private final State newState; 6 | private final boolean writeEnclosingTag; 7 | 8 | private State lastState; 9 | 10 | public StateTransitionRule(String tagName, State newState) { 11 | this(tagName, newState, true); 12 | } 13 | 14 | public StateTransitionRule(String tagName, State newState, boolean writeEnclosingTag) { 15 | super(tagName); 16 | this.newState = newState; 17 | this.writeEnclosingTag = writeEnclosingTag; 18 | } 19 | 20 | public void process(Tag tag) { 21 | if (tag.getType() == Tag.OPEN) { 22 | lastState = context.currentState(); 23 | context.changeState(newState); 24 | newState.addRule(this); 25 | } else if (tag.getType() == Tag.CLOSE && lastState != null) { 26 | context.changeState(lastState); 27 | lastState = null; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /docs/api/com/opensymphony/module/sitemesh/velocity/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | com.opensymphony.module.sitemesh.velocity (OpenSymphony SiteMesh 2.5 API) 7 | 8 | 9 | 10 | 11 | 12 |

com.opensymphony.module.sitemesh.velocity

13 |
14 |

Classes

15 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/api/com/opensymphony/module/sitemesh/freemarker/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | com.opensymphony.module.sitemesh.freemarker (OpenSymphony SiteMesh 2.5 API) 7 | 8 | 9 | 10 | 11 | 12 |

com.opensymphony.module.sitemesh.freemarker

13 |
14 |

Classes

15 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/java/com/opensymphony/module/sitemesh/scalability/MockFilterConfig.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.scalability; 2 | 3 | import jakarta.servlet.FilterConfig; 4 | import jakarta.servlet.ServletContext; 5 | import java.util.Enumeration; 6 | import java.util.Hashtable; 7 | import java.util.Map; 8 | 9 | /** 10 | */ 11 | class MockFilterConfig implements FilterConfig 12 | { 13 | 14 | final Map properties; 15 | 16 | MockFilterConfig(Map properties) 17 | { 18 | this.properties = properties; 19 | } 20 | 21 | public String getFilterName() 22 | { 23 | throw new UnsupportedOperationException("Not implemented"); 24 | } 25 | 26 | public ServletContext getServletContext() 27 | { 28 | throw new UnsupportedOperationException("Not implemented"); 29 | } 30 | 31 | public String getInitParameter(String s) 32 | { 33 | return properties.get(s); 34 | } 35 | 36 | public Enumeration getInitParameterNames() 37 | { 38 | return new Hashtable(properties).keys(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /example/src/main/webapp/WEB-INF/decorators.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | /exclude.jsp 7 | /exclude/* 8 | 9 | 10 | 11 | /* 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | /velocity.html 22 | 23 | 24 | 25 | /freemarker.html 26 | 27 | 28 | 29 | /agent.jsp 30 | 31 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/html/Text.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.html; 2 | 3 | import com.opensymphony.module.sitemesh.SitemeshBufferFragment; 4 | 5 | /** 6 | * Text returned by HTMLTagTokenizer. 7 | * 8 | * @see com.opensymphony.module.sitemesh.html.tokenizer.TokenHandler 9 | * @see com.opensymphony.module.sitemesh.html.tokenizer.TagTokenizer 10 | * 11 | * @author Joe Walnes 12 | */ 13 | public interface Text { 14 | 15 | /** 16 | * Get the complete contents of the text block, preserving original formatting. 17 | * 18 | * This has a slight overhead in that it needs to construct a String. For improved performance, use writeTo() instead. 19 | */ 20 | String getContents(); 21 | 22 | /** 23 | * Write out the complete contents of the text block, preserving original formatting. 24 | */ 25 | void writeTo(SitemeshBufferFragment.Builder buffer, int position); 26 | 27 | /** 28 | * The position of the text 29 | */ 30 | int getPosition(); 31 | 32 | /** 33 | * The length of the text 34 | */ 35 | int getLength(); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/html/rules/TagReplaceRule.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.html.rules; 2 | 3 | import com.opensymphony.module.sitemesh.html.BasicRule; 4 | import com.opensymphony.module.sitemesh.html.Tag; 5 | import com.opensymphony.module.sitemesh.html.CustomTag; 6 | 7 | /** 8 | * Very simple rule for replacing all occurences of one tag with another. 9 | * 10 | *

For example, to convert all <b> tags to <strong>:

11 | *

html.addRule(new TagReplaceRule("b", "strong"));

12 | * 13 | * @author Joe Walnes 14 | */ 15 | public class TagReplaceRule extends BasicRule { 16 | 17 | private final String newTagName; 18 | 19 | public TagReplaceRule(String originalTagName, String newTagName) { 20 | super(originalTagName); 21 | this.newTagName = newTagName; 22 | } 23 | 24 | public void process(Tag tag) { 25 | currentBuffer().delete(tag.getPosition(), tag.getLength()); 26 | CustomTag customTag = new CustomTag(tag); 27 | customTag.setName(newTagName); 28 | customTag.writeTo(currentBuffer(), tag.getPosition()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/parser-tests/test19.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | 5 | Some page 6 | 7 | 10 | 11 | 12 | 13 |

Here's some src code:

14 | 15 | 25 | 26 |

Bye.

27 | 28 | 29 | ignore this! 30 | 31 | 32 | ~~~ TITLE ~~~ 33 | 34 | Some page 35 | 36 | ~~~ PROPERTIES ~~~ 37 | 38 | title=Some page 39 | meta.author=Someone 40 | body.bgcolor=black 41 | 42 | ~~~ HEAD ~~~ 43 | 44 | 45 | 48 | 49 | ~~~ BODY ~~~ 50 | 51 |

Here's some src code:

52 | 53 | 63 | 64 |

Bye.

65 | 66 | -------------------------------------------------------------------------------- /testsuite/src/java/testsuite/sitemesh/WelcomePageTest.java: -------------------------------------------------------------------------------- 1 | package testsuite.sitemesh; 2 | 3 | import testsuite.tester.WebTest; 4 | import com.meterware.httpunit.WebResponse; 5 | import electric.xml.Document; 6 | 7 | /** 8 | * Test that the default welcome pages work ok (i.e. default.jsp). 9 | * 10 | * @author Joe Walnes 11 | */ 12 | public class WelcomePageTest extends WebTest { 13 | 14 | public void testWelcomePage() throws Exception { 15 | checkPage( "/welcomepage/" ); 16 | } 17 | 18 | public void testWelcomePageWithoutTrailingSlash() throws Exception { 19 | checkPage( "/welcomepage" ); 20 | } 21 | 22 | private void checkPage( String path ) throws Exception { 23 | WebResponse rs = wc.getResponse( baseUrl + path ); 24 | Document doc = getDocument( rs ); 25 | assertEquals( "[:: Welcome Page ::]", rs.getTitle() ); 26 | assertEquals( "Welcome to the page", doc.getElementWithId( "p1" ).getText().toString() ); 27 | assertEquals( "footer", doc.getElementWithId( "footer" ).getText().toString() ); 28 | assertEquals( "Welcome Page", doc.getElementWithId( "header" ).getText().toString() ); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/parser-tests/test18.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | 5 | Some page 6 | 7 | 10 | 11 | 12 | 13 |

Here's some src code:

14 | 15 | 16 | 17 | 18 | XXX 19 | 20 | 21 | This is something. 22 | 23 | 24 | 25 | 26 |

Bye.

27 | 28 | 29 | ignore this! 30 | 31 | 32 | ~~~ TITLE ~~~ 33 | 34 | Some page 35 | 36 | ~~~ PROPERTIES ~~~ 37 | 38 | title=Some page 39 | meta.author=Someone 40 | body.bgcolor=black 41 | 42 | ~~~ HEAD ~~~ 43 | 44 | 45 | 48 | 49 | ~~~ BODY ~~~ 50 | 51 |

Here's some src code:

52 | 53 | 54 | 55 | 56 | XXX 57 | 58 | 59 | This is something. 60 | 61 | 62 | 63 | 64 |

Bye.

65 | 66 | -------------------------------------------------------------------------------- /src/parser-tests/test21.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | 5 | Some page 6 | 7 | 10 | 11 | 12 | 13 |

Here's some src code:

14 | 15 | 17 | 18 | XXX 19 | 20 | 21 | This is something. 22 | 23 | 24 | ]]> 25 | 26 |

Bye.

27 | 28 | 29 | ignore this! 30 | 31 | 32 | ~~~ TITLE ~~~ 33 | 34 | Some page 35 | 36 | ~~~ PROPERTIES ~~~ 37 | 38 | title=Some page 39 | meta.author=Someone 40 | body.bgcolor=black 41 | 42 | ~~~ HEAD ~~~ 43 | 44 | 45 | 48 | 49 | ~~~ BODY ~~~ 50 | 51 |

Here's some src code:

52 | 53 | 55 | 56 | XXX 57 | 58 | 59 | This is something. 60 | 61 | 62 | ]]> 63 | 64 |

Bye.

65 | 66 | -------------------------------------------------------------------------------- /testsuite/src/webapp/inline/dec-2.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %> 2 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/page" prefix="page" %> 3 | 4 | 5 | 6 | {inline2} <decorator:title /> 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 23 | 26 | 31 | 32 | 33 | 36 | 37 |
14 | 15 |
19 | 20 | 21 | 22 | 24 | 25 | 27 | 28 | 29 | 30 |
38 | 39 | 40 | -------------------------------------------------------------------------------- /src/parser-tests/test17.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | 5 | Some page 6 | 7 | 10 | 11 | 12 | 13 |

Here's some src code:

14 | 15 |

16 |      <html>
17 |        <head>
18 |          <title>XXX</title>
19 |        </head>
20 |        <body>
21 |          This is something.
22 |        </body>
23 |      </html>
24 |    
25 | 26 |

Bye.

27 | 28 | 29 | ignore this! 30 | 31 | 32 | ~~~ TITLE ~~~ 33 | 34 | Some page 35 | 36 | ~~~ PROPERTIES ~~~ 37 | 38 | title=Some page 39 | meta.author=Someone 40 | body.bgcolor=black 41 | 42 | ~~~ HEAD ~~~ 43 | 44 | 45 | 48 | 49 | ~~~ BODY ~~~ 50 | 51 |

Here's some src code:

52 | 53 |

54 |      <html>
55 |        <head>
56 |          <title>XXX</title>
57 |        </head>
58 |        <body>
59 |          This is something.
60 |        </body>
61 |      </html>
62 |    
63 | 64 |

Bye.

65 | 66 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/taglib/decorator/UsePageTEI.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Title: UsePageTEI 3 | * Description: 4 | * 5 | * This software is published under the terms of the OpenSymphony Software 6 | * License version 1.1, of which a copy has been included with this 7 | * distribution in the LICENSE.txt file. 8 | */ 9 | 10 | package com.opensymphony.module.sitemesh.taglib.decorator; 11 | 12 | import jakarta.servlet.jsp.tagext.TagData; 13 | import jakarta.servlet.jsp.tagext.TagExtraInfo; 14 | import jakarta.servlet.jsp.tagext.VariableInfo; 15 | 16 | /** 17 | * TagExtraInfo implementation to expose Page object as variable. 18 | * 19 | * @author Joe Walnes 20 | * @version $Revision: 1.1 $ 21 | * 22 | * @see UsePageTag 23 | * @see UseHTMLPageTEI 24 | */ 25 | public class UsePageTEI extends TagExtraInfo { 26 | protected String getType() { 27 | return "com.opensymphony.module.sitemesh.Page"; 28 | } 29 | 30 | public VariableInfo[] getVariableInfo(TagData data) { 31 | String id = data.getAttributeString("id"); 32 | return new VariableInfo[] {new VariableInfo(id, getType(), true, VariableInfo.AT_END)}; 33 | } 34 | } -------------------------------------------------------------------------------- /src/parser-tests/test23.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | 5 | Some page 6 | 7 | 10 | 11 | 12 | 13 |

This is a pretty simple page.

14 | 15 | xy 16 | xy 17 | 18 | x 19 | This is some more content.... 20 | Woo.xxxy 21 |

Bye.

22 | 23 | 24 | 25 | 26 | ~~~ TITLE ~~~ 27 | 28 | Some page 29 | 30 | ~~~ PROPERTIES ~~~ 31 | 32 | title=Some page 33 | meta.author=Someone 34 | body.bgcolor=black 35 | page.icon=thing.gif 36 | page.category=news 37 | page.somecontent=\n This is some more content.... \n Woo. 38 | page.more=xxx 39 | 40 | ~~~ HEAD ~~~ 41 | 42 | 43 | 46 | 47 | ~~~ BODY ~~~ 48 | 49 |

This is a pretty simple page.

50 | 51 | xy 52 | xy 53 | 54 | xy 55 |

Bye.

56 | 57 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/factory/sitemesh-default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/parser-tests/test20.txt: -------------------------------------------------------------------------------- 1 | ~~~ INPUT ~~~ 2 | 3 | 4 | 5 | Some page 6 | 7 | 10 | 11 | 12 | 13 |

Here's some src code:

14 | 15 | 25 | 26 |

Bye.

27 | 28 | 29 | ignore this! 30 | 31 | 32 | ~~~ TITLE ~~~ 33 | 34 | Some page 35 | 36 | ~~~ PROPERTIES ~~~ 37 | 38 | title=Some page 39 | meta.author=Someone 40 | body.bgcolor=black 41 | 42 | ~~~ HEAD ~~~ 43 | 44 | 45 | 48 | 49 | ~~~ BODY ~~~ 50 | 51 |

Here's some src code:

52 | 53 | 63 | 64 |

Bye.

65 | 66 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/taglib/page/ParamTag.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Title: ParamTag 3 | * Description: 4 | * 5 | * This software is published under the terms of the OpenSymphony Software 6 | * License version 1.1, of which a copy has been included with this 7 | * distribution in the LICENSE.txt file. 8 | */ 9 | 10 | package com.opensymphony.module.sitemesh.taglib.page; 11 | 12 | import jakarta.servlet.jsp.tagext.BodyTagSupport; 13 | import jakarta.servlet.jsp.tagext.Tag; 14 | 15 | /** 16 | * Add a parameter to the inline Decorator, as if specified in the Page. 17 | * 18 | * @author Joe Walnes 19 | * @version $Revision: 1.2 $ 20 | */ 21 | public class ParamTag extends BodyTagSupport { 22 | private String name; 23 | 24 | public void setName(String name) { 25 | this.name = name; 26 | } 27 | 28 | public int doAfterBody() { 29 | Tag parent = findAncestorWithClass(this, ApplyDecoratorTag.class); 30 | if (parent instanceof ApplyDecoratorTag) { 31 | ApplyDecoratorTag t = (ApplyDecoratorTag)parent; 32 | t.addParam(name, getBodyContent().getString()); 33 | } 34 | return SKIP_BODY; 35 | } 36 | } -------------------------------------------------------------------------------- /testsuite/src/webapp/inline/dec-3.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %> 2 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/page" prefix="page" %> 3 | 4 | 5 | 6 | {inline3} <decorator:title /> 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 21 | 24 | 29 | 30 | 31 | 34 | 35 |
14 | 15 |
19 | 20 | 22 | 23 | 25 | 26 |
27 | 28 |
36 | 37 | 38 | -------------------------------------------------------------------------------- /docs/api/com/opensymphony/module/sitemesh/html/util/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | com.opensymphony.module.sitemesh.html.util (OpenSymphony SiteMesh 2.5 API) 7 | 8 | 9 | 10 | 11 | 12 |

com.opensymphony.module.sitemesh.html.util

13 |
14 |

Classes

15 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /docs/api/com/opensymphony/module/sitemesh/taglib/page/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | com.opensymphony.module.sitemesh.taglib.page (OpenSymphony SiteMesh 2.5 API) 7 | 8 | 9 | 10 | 11 | 12 |

com.opensymphony.module.sitemesh.taglib.page

13 |
14 |

Classes

15 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/scalability/NoopScalabilitySupport.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.scalability; 2 | 3 | import com.opensymphony.module.sitemesh.scalability.outputlength.NoopOutputLengthObserver; 4 | import com.opensymphony.module.sitemesh.scalability.outputlength.OutputLengthObserver; 5 | import com.opensymphony.module.sitemesh.scalability.secondarystorage.NoopSecondaryStorage; 6 | import com.opensymphony.module.sitemesh.scalability.secondarystorage.SecondaryStorage; 7 | 8 | /** 9 | */ 10 | public class NoopScalabilitySupport implements ScalabilitySupport 11 | { 12 | private OutputLengthObserver outputLengthObserver = new NoopOutputLengthObserver(); 13 | private SecondaryStorage secondaryStorage = new NoopSecondaryStorage(); 14 | 15 | public OutputLengthObserver getOutputLengthObserver() 16 | { 17 | return outputLengthObserver; 18 | } 19 | 20 | public SecondaryStorage getSecondaryStorage() 21 | { 22 | return secondaryStorage; 23 | } 24 | 25 | public int getInitialBufferSize() 26 | { 27 | return 8 * 1024; 28 | } 29 | 30 | public boolean isMaxOutputLengthExceededThrown() 31 | { 32 | return false; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/SitemeshBufferWriter.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh; 2 | 3 | import com.opensymphony.module.sitemesh.util.CharArrayWriter; 4 | 5 | import java.io.IOException; 6 | import java.io.Writer; 7 | import java.util.TreeMap; 8 | 9 | /** 10 | * A char array writer that caches other sitemesh buffers written to it, so that it doesn't have to continually copy 11 | * them from buffer to buffer. 12 | */ 13 | public class SitemeshBufferWriter extends CharArrayWriter implements SitemeshWriter { 14 | 15 | private final TreeMap fragments = new TreeMap(); 16 | 17 | public SitemeshBufferWriter() { 18 | } 19 | 20 | public SitemeshBufferWriter(int initialSize) { 21 | super(initialSize); 22 | } 23 | 24 | public Writer getUnderlyingWriter() { 25 | return this; 26 | } 27 | 28 | public boolean writeSitemeshBufferFragment(SitemeshBufferFragment bufferFragment) throws IOException { 29 | fragments.put(count, bufferFragment); 30 | return false; 31 | } 32 | 33 | public SitemeshBuffer getSitemeshBuffer() { 34 | return new DefaultSitemeshBuffer(buf, count, fragments); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/docs/api.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #FFFFFF; 3 | } 4 | 5 | .TableHeadingColor { 6 | background: #99CCFF; 7 | } 8 | 9 | .TableSubHeadingColor { 10 | background: #BBBBBB; 11 | color: #FFFFFF; /* Dark grey */ 12 | } 13 | 14 | .TableRowColor { 15 | background: #EFEFEF; /* White */ 16 | } 17 | 18 | /* Font used in left-hand frame lists */ 19 | .FrameTitleFont { 20 | font-size: normal; 21 | font-family: normal; 22 | color: #000000; 23 | } 24 | 25 | .FrameHeadingFont { 26 | font-size: normal; 27 | font-family: normal; 28 | color: #000000; 29 | } 30 | 31 | .FrameItemFont { 32 | font-size: normal; 33 | font-family: normal; 34 | color: #000000; 35 | } 36 | 37 | /* Navigation bar fonts and colors */ 38 | .NavBarCell1 { 39 | background-color: #DDDDDD; 40 | } 41 | /* Light mauve */ 42 | .NavBarCell1Rev { 43 | background-color: #888888; 44 | } 45 | /* Dark Blue */ 46 | .NavBarFont1 { 47 | font-family: Arial, Helvetica, sans-serif; 48 | color: #000000; 49 | } 50 | 51 | .NavBarFont1Rev { 52 | font-family: Arial, Helvetica, sans-serif; 53 | color: #FFFFFF; 54 | } 55 | 56 | .NavBarCell2 { 57 | font-family: Arial, Helvetica, sans-serif; 58 | background-color: #FFFFFF; 59 | } 60 | 61 | .NavBarCell3 { 62 | font-family: Arial, Helvetica, sans-serif; 63 | background-color: #FFFFFF; 64 | } -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/filter/SitemeshPrintWriter.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.filter; 2 | 3 | import com.opensymphony.module.sitemesh.SitemeshBufferFragment; 4 | import com.opensymphony.module.sitemesh.SitemeshBufferWriter; 5 | import com.opensymphony.module.sitemesh.SitemeshBuffer; 6 | import com.opensymphony.module.sitemesh.SitemeshWriter; 7 | 8 | import java.io.IOException; 9 | import java.io.PrintWriter; 10 | import java.io.Writer; 11 | 12 | /** 13 | * A sitemesh print writer 14 | */ 15 | public class SitemeshPrintWriter extends PrintWriter implements SitemeshWriter { 16 | 17 | private final SitemeshWriter sitemeshWriter; 18 | 19 | public SitemeshPrintWriter(SitemeshWriter sitemeshWriter) { 20 | super(sitemeshWriter.getUnderlyingWriter()); 21 | this.sitemeshWriter = sitemeshWriter; 22 | } 23 | 24 | public Writer getUnderlyingWriter() 25 | { 26 | return this; 27 | } 28 | 29 | public boolean writeSitemeshBufferFragment(SitemeshBufferFragment bufferFragment) throws IOException { 30 | return sitemeshWriter.writeSitemeshBufferFragment(bufferFragment); 31 | } 32 | 33 | public SitemeshBuffer getSitemeshBuffer() { 34 | return sitemeshWriter.getSitemeshBuffer(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/taglib/decorator/HeadTag.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Title: HeadTag 3 | * Description: 4 | * 5 | * This software is published under the terms of the OpenSymphony Software 6 | * License version 1.1, of which a copy has been included with this 7 | * distribution in the LICENSE.txt file. 8 | */ 9 | 10 | package com.opensymphony.module.sitemesh.taglib.decorator; 11 | 12 | import java.io.IOException; 13 | 14 | import jakarta.servlet.jsp.JspException; 15 | 16 | import com.opensymphony.module.sitemesh.HTMLPage; 17 | import com.opensymphony.module.sitemesh.taglib.AbstractTag; 18 | 19 | /** 20 | * Write original HTMLPage head to out. 21 | * 22 | * @author Joe Walnes 23 | * @version $Revision: 1.3 $ 24 | * 25 | * @see com.opensymphony.module.sitemesh.HTMLPage#writeHead(java.io.Writer) 26 | */ 27 | public class HeadTag extends AbstractTag { 28 | public final int doEndTag() throws JspException 29 | { 30 | HTMLPage htmlPage = (HTMLPage)getPage(); 31 | try 32 | { 33 | htmlPage.writeHead(getOut()); 34 | } 35 | catch(IOException e) 36 | { 37 | throw new JspException("Error writing head element: " + e.toString(), e); 38 | } 39 | return EVAL_PAGE; 40 | } 41 | } -------------------------------------------------------------------------------- /src/test/java/com/opensymphony/module/sitemesh/scalability/outputlength/ExceptionThrowingOutputLengthObserverTest.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.scalability.outputlength; 2 | 3 | import junit.framework.TestCase; 4 | 5 | /** 6 | */ 7 | public class ExceptionThrowingOutputLengthObserverTest extends TestCase 8 | { 9 | public void testNBytes() throws Exception 10 | { 11 | ExceptionThrowingOutputLengthObserver observer = new ExceptionThrowingOutputLengthObserver(25, 1234); 12 | observer.nBytes(3); 13 | observer.nBytes(6); 14 | try 15 | { 16 | observer.nBytes(100); 17 | fail("Should have thrown MaxOutputLengthExceeded"); 18 | } 19 | catch (MaxOutputLengthExceeded expected) 20 | { 21 | } 22 | } 23 | 24 | public void testNChars() throws Exception 25 | { 26 | ExceptionThrowingOutputLengthObserver observer = new ExceptionThrowingOutputLengthObserver(10, 1234); 27 | observer.nChars(4); 28 | observer.nChars(1); 29 | try 30 | { 31 | observer.nChars(1); 32 | fail("Should have thrown MaxOutputLengthExceeded"); 33 | } 34 | catch (MaxOutputLengthExceeded expected) 35 | { 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/scalability/outputlength/ExceptionThrowingOutputLengthObserver.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.scalability.outputlength; 2 | 3 | /** 4 | * An implementation that throws {@link MaxOutputLengthExceeded} exceptions 5 | */ 6 | public class ExceptionThrowingOutputLengthObserver implements OutputLengthObserver 7 | { 8 | private final long maxOutputLength; 9 | private final int maximumOutputExceededHttpCode; 10 | private long soFar; 11 | 12 | 13 | public ExceptionThrowingOutputLengthObserver(final long maxOutputLength, final int maximumOutputExceededHttpCode) 14 | { 15 | this.maxOutputLength = maxOutputLength; 16 | this.maximumOutputExceededHttpCode = maximumOutputExceededHttpCode; 17 | } 18 | 19 | public void nBytes(long n) 20 | { 21 | if (soFar + n > maxOutputLength) 22 | { 23 | throw new MaxOutputLengthExceeded(maxOutputLength, maximumOutputExceededHttpCode); 24 | } 25 | soFar += n; 26 | } 27 | 28 | public void nChars(long n) 29 | { 30 | if (soFar + (n * 2) > maxOutputLength) 31 | { 32 | throw new MaxOutputLengthExceeded(maxOutputLength, maximumOutputExceededHttpCode); 33 | } 34 | soFar += (n * 2); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /continuous-integration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /testsuite/src/java/testsuite/config/Application.java: -------------------------------------------------------------------------------- 1 | package testsuite.config; 2 | 3 | import java.io.File; 4 | 5 | /** 6 | * Representation of application to be deployed and tested. 7 | * 8 | * @author Joe Walnes 9 | */ 10 | public class Application { 11 | 12 | private String name; 13 | private File warLocation, earLocation; 14 | 15 | public Application( String name, File warLocation, File earLocation ) { 16 | this.name = name; 17 | this.warLocation = warLocation; 18 | this.earLocation = earLocation; 19 | } 20 | 21 | /** 22 | * Name of application (e.g. SiteMesh) 23 | */ 24 | public String getName() { return name; } 25 | 26 | /** 27 | * Where web-app .war is located. 28 | */ 29 | public File getWarLocation() { return warLocation; } 30 | 31 | /** 32 | * Where .ear containing web-app is located. 33 | */ 34 | public File getEarLocation() { return earLocation; } 35 | 36 | public String toString() { 37 | StringBuffer result = new StringBuffer(); 38 | result.append( "{ Application : \n name=" ); 39 | result.append( name ); 40 | result.append( "\n warLocation=" ); 41 | result.append( warLocation ); 42 | result.append( "\n earLocation=" ); 43 | result.append( earLocation ); 44 | result.append( "\n}" ); 45 | return result.toString(); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/sitemesh/webapp/decorator/NoDecorator.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.sitemesh.webapp.decorator; 2 | 3 | import com.opensymphony.sitemesh.Content; 4 | import com.opensymphony.sitemesh.webapp.SiteMeshWebAppContext; 5 | 6 | import jakarta.servlet.ServletContext; 7 | import jakarta.servlet.ServletException; 8 | import jakarta.servlet.http.HttpServletRequest; 9 | import jakarta.servlet.http.HttpServletResponse; 10 | import java.io.IOException; 11 | import java.io.PrintWriter; 12 | 13 | /** 14 | * If no decorator is to be applied to a page, this will ensure the original content gets written out. 15 | * 16 | * @author Joe Walnes 17 | * @since SiteMesh 3.0 18 | */ 19 | public class NoDecorator extends BaseWebAppDecorator { 20 | 21 | protected void render(Content content, HttpServletRequest request, HttpServletResponse response, 22 | ServletContext servletContext, SiteMeshWebAppContext webAppContext) 23 | throws IOException, ServletException { 24 | 25 | PrintWriter writer; 26 | if (webAppContext.isUsingStream()) { 27 | writer = new PrintWriter(response.getOutputStream()); 28 | } else { 29 | writer = response.getWriter(); 30 | } 31 | content.writeOriginal(writer); 32 | writer.flush(); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /testsuite/src/webapp/inline/dec-1.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %> 2 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/page" prefix="page" %> 3 | 4 | 5 | 6 | {inline1} <decorator:title /> 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 25 | 28 | 34 | 35 | 36 | 39 | 40 |
14 | 15 |
19 | 20 | Inline internal content 1 21 |

Something inside something one

22 |
:-)

:-D
23 |
24 |
26 | 27 | 29 | 30 |

Something inside something two

31 |
:-)

:-D
32 |
33 |
41 | 42 | 43 | -------------------------------------------------------------------------------- /src/test/java/com/opensymphony/module/sitemesh/scalability/secondarystorage/InMemorySecondaryStorage.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.scalability.secondarystorage; 2 | 3 | import java.io.IOException; 4 | import java.io.StringWriter; 5 | import java.io.Writer; 6 | 7 | /** 8 | */ 9 | public class InMemorySecondaryStorage implements SecondaryStorage 10 | { 11 | private StringWriter sw = new StringWriter(); 12 | private final long memoryLimitBeforeUse; 13 | 14 | public InMemorySecondaryStorage(final long memoryLimitBeforeUse) 15 | { 16 | this.memoryLimitBeforeUse = memoryLimitBeforeUse; 17 | } 18 | 19 | public long getMemoryLimitBeforeUse() 20 | { 21 | return memoryLimitBeforeUse; 22 | } 23 | 24 | public void write(int c) 25 | { 26 | sw.write(c); 27 | } 28 | 29 | public void write(char[] chars, int off, int len) 30 | { 31 | sw.write(chars, off, len); 32 | } 33 | 34 | public void write(String str, int off, int len) 35 | { 36 | sw.write(str, off, len); 37 | } 38 | 39 | public void write(String str) 40 | { 41 | sw.write(str); 42 | } 43 | 44 | public void writeTo(Writer out) throws IOException 45 | { 46 | out.write(sw.toString()); 47 | } 48 | 49 | public void cleanUp() 50 | { 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /.github/workflows/gradle.yml: -------------------------------------------------------------------------------- 1 | name: Build and Publish SiteMesh 2 | 3 | on: 4 | push: 5 | tags: 6 | - '*' 7 | branches: 8 | - '**' 9 | 10 | jobs: 11 | build-gradle-project: 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - name: Checkout project sources 16 | uses: actions/checkout@v3 17 | 18 | - name: Set up JDK 17 with cache 19 | uses: actions/setup-java@v3 20 | with: 21 | distribution: 'temurin' 22 | java-version: '17' 23 | cache: 'gradle' 24 | 25 | - name: Restore gradle.properties 26 | env: 27 | GRADLE_PROPERTIES: ${{ secrets.GRADLE_PROPERTIES }} 28 | shell: bash 29 | run: | 30 | mkdir -p ~/.gradle/ 31 | echo "${GRADLE_PROPERTIES}" > ~/.gradle/gradle.properties 32 | 33 | - name: Run tests 34 | run: ./gradlew --no-daemon clean test 35 | 36 | # Snapshot flow (any non-tag push) 37 | - name: Publish SNAPSHOT to Central 38 | if: ${{ !startsWith(github.ref, 'refs/tags/') }} 39 | run: ./gradlew --no-daemon publishToSonatype 40 | 41 | # Release flow (tag push) 42 | - name: Close and Release to Central 43 | if: ${{ startsWith(github.ref, 'refs/tags/') }} 44 | run: ./gradlew --no-daemon publishToSonatype closeAndReleaseSonatypeStagingRepository 45 | -------------------------------------------------------------------------------- /testsuite/src/webapp/WEB-INF/src/testsuite/servlets/DifferentWaysOfSpecifyingContentType.java: -------------------------------------------------------------------------------- 1 | package testsuite.servlets; 2 | 3 | import com.opensymphony.module.sitemesh.RequestConstants; 4 | 5 | import jakarta.servlet.http.HttpServlet; 6 | import jakarta.servlet.http.HttpServletRequest; 7 | import jakarta.servlet.http.HttpServletResponse; 8 | import jakarta.servlet.ServletException; 9 | import java.io.IOException; 10 | 11 | public class DifferentWaysOfSpecifyingContentType extends HttpServlet { 12 | 13 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 14 | if ("yes".equals(request.getParameter("kill"))) { 15 | request.setAttribute(RequestConstants.DISABLE_BUFFER_AND_DECORATION, Boolean.TRUE); 16 | } 17 | 18 | String approach = request.getParameter("approach"); 19 | 20 | if ("setContentType".equals(approach)) { 21 | response.setContentType("text/html"); 22 | } else if ("addHeader".equals(approach)) { 23 | response.addHeader("Content-type", "text/html"); 24 | } else if ("setHeader".equals(approach)) { 25 | response.setHeader("Content-type", "text/html"); 26 | } 27 | 28 | response.getWriter().println("content-typebody"); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/parser-tests/readme.txt: -------------------------------------------------------------------------------- 1 | The files in this directory are used to test the HTMLPageParser. 2 | 3 | The layout of the files is like this: 4 | 5 | ~~~ INPUT ~~~ 6 | 7 | 8 | 9 | Some page 10 | 11 | 14 | 15 | 16 | 17 |

This is a pretty simple page.

18 | 19 |

Bye.

20 | 21 | 22 | 23 | 24 | ~~~ TITLE ~~~ 25 | 26 | Some page 27 | 28 | ~~~ PROPERTIES ~~~ 29 | 30 | meta.author=Someone 31 | body.bgcolor=black 32 | 33 | ~~~ HEAD ~~~ 34 | 35 | 38 | 39 | ~~~ BODY ~~~ 40 | 41 |

This is a pretty simple page.

42 | 43 |

Bye.

44 | 45 | 46 | Each block is identified by ~~~ BLAH ~~~ and lasts until either the next block starts or the end of the file. 47 | 48 | The INPUT block is fed into the parser, and then TITLE, PROPERTIES, HEAD and BODY blocks are compared to the results of the parser. Blocks will have leading and trailing whitespace ignored during the comparison. The PROPERTIES block takes the syntax of a standard java properties file. 49 | 50 | To add a new test, just place a new file called 'test??.txt' in this directory. 51 | 52 | File names listed in ignore.txt will be skipped. -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/html/tokenizer/TagTokenizer.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.html.tokenizer; 2 | 3 | /** 4 | * Splits a chunk of HTML into 'text' and 'tag' tokens, for easy processing. Is VERY tolerant to badly formed HTML. 5 | *
6 | *

Usage

7 | *
8 | * You need to supply a custom {@link TokenHandler} that will receive callbacks as text and tags are processed. 9 | *
10 | *
char[] input = ...;
11 |  * HTMLTagTokenizer tokenizer = new HTMLTagTokenizer(input);
12 |  * TokenHandler handler = new MyTokenHandler();
13 |  * tokenizer.start(handler);
14 | * 15 | * @author Joe Walnes 16 | * @see TokenHandler 17 | * @see com.opensymphony.module.sitemesh.parser.HTMLPageParser 18 | */ 19 | public class TagTokenizer { 20 | 21 | private final char[] input; 22 | private final int length; 23 | 24 | public TagTokenizer(char[] input) { 25 | this(input, input.length); 26 | } 27 | 28 | public TagTokenizer(char[] input, int length) { 29 | this.input = input; 30 | this.length = length; 31 | } 32 | 33 | public TagTokenizer(String input) { 34 | this(input.toCharArray()); 35 | } 36 | 37 | public void start(TokenHandler handler) { 38 | Parser parser = new Parser(input, length, handler); 39 | parser.start(); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/sitemesh/Content.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.sitemesh; 2 | 3 | import java.io.IOException; 4 | import java.io.Writer; 5 | 6 | /** 7 | * @author Joe Walnes 8 | * @since SiteMesh 3 9 | */ 10 | public interface Content { 11 | 12 | /** 13 | * Write out the original unprocessed content. 14 | */ 15 | void writeOriginal(Writer writer) throws IOException; 16 | 17 | /** 18 | * Write the contents of the <body> tag. 19 | */ 20 | void writeBody(Writer out) throws IOException; 21 | 22 | /** 23 | * Write the contents of the <head> tag. 24 | */ 25 | void writeHead(Writer out) throws IOException; 26 | 27 | /** 28 | * Get the Title of the document 29 | */ 30 | String getTitle(); 31 | 32 | 33 | /** 34 | * Get a property embedded into the Page as a String. 35 | * 36 | * @param name Name of property 37 | * @return Property value 38 | */ 39 | String getProperty(String name); 40 | 41 | 42 | /** 43 | * Get all available property keys for the Page. 44 | * 45 | * @return Property keys 46 | */ 47 | String[] getPropertyKeys(); 48 | 49 | /** 50 | * Manually add a property to page. 51 | */ 52 | void addProperty(String name, String value); 53 | 54 | } 55 | -------------------------------------------------------------------------------- /testsuite/src/java/testsuite/sitemesh/MultipassTest.java: -------------------------------------------------------------------------------- 1 | package testsuite.sitemesh; 2 | 3 | import java.io.IOException; 4 | import java.net.MalformedURLException; 5 | import java.text.SimpleDateFormat; 6 | import java.util.Date; 7 | import java.util.regex.Pattern; 8 | import java.util.regex.Matcher; 9 | 10 | import org.xml.sax.SAXException; 11 | 12 | import com.meterware.httpunit.*; 13 | import testsuite.tester.WebTest; 14 | 15 | import jakarta.servlet.http.HttpServletResponse; 16 | 17 | /** 18 | * Tests multipass feature of SM. 19 | * 20 | * @author Joe Walnes 21 | */ 22 | public class MultipassTest extends WebTest { 23 | 24 | public void testExtractsSelectedDivsFromContentOnSecondPass() throws Exception { 25 | String expected = get(baseUrl + "/multipass/expected-result.html"); 26 | String actual = get(baseUrl + "/multipass/content.html"); 27 | assertEquals(expected, actual); 28 | } 29 | 30 | private String get(String path) throws Exception { 31 | WebResponse rs = wc.getResponse(path); 32 | assertEquals(200, rs.getResponseCode() ); 33 | return trimBlankLines(rs.getText()); 34 | } 35 | 36 | private String trimBlankLines(String text) { 37 | Pattern pattern = Pattern.compile("^[ \\t]*$", Pattern.MULTILINE); 38 | return pattern.matcher(text).replaceAll(""); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/taglib/decorator/TitleTag.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Title: TitleTag 3 | * Description: 4 | * 5 | * This software is published under the terms of the OpenSymphony Software 6 | * License version 1.1, of which a copy has been included with this 7 | * distribution in the LICENSE.txt file. 8 | */ 9 | 10 | package com.opensymphony.module.sitemesh.taglib.decorator; 11 | 12 | import com.opensymphony.module.sitemesh.taglib.AbstractTag; 13 | 14 | /** 15 | * Write the Page <title> value to out. 16 | * 17 | * @author Joe Walnes 18 | * @version $Revision: 1.3 $ 19 | * 20 | * @see com.opensymphony.module.sitemesh.HTMLPage#getTitle() 21 | */ 22 | public class TitleTag extends AbstractTag { 23 | private String defaultTitle = null; 24 | 25 | /** Value to write if no title is found (optional). */ 26 | public void setDefault(String defaultTitle) { 27 | this.defaultTitle = defaultTitle; 28 | } 29 | 30 | public final int doEndTag() { 31 | try { 32 | String title = getPage().getTitle(); 33 | if (title == null || title.trim().length() == 0) title = defaultTitle; 34 | if (title != null) getOut().write(title); 35 | } 36 | catch (Exception e) { 37 | trace(e); 38 | } 39 | return EVAL_PAGE; 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /docs/dtd/sitemesh_1_5_decorators.dtd: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 23 | 24 | 27 | 28 | 31 | 32 | 33 | 37 | 38 | 43 | 44 | 48 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/html/rules/BodyTagRule.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.html.rules; 2 | 3 | import com.opensymphony.module.sitemesh.SitemeshBufferFragment; 4 | import com.opensymphony.module.sitemesh.html.BasicRule; 5 | import com.opensymphony.module.sitemesh.html.Tag; 6 | import com.opensymphony.module.sitemesh.html.util.CharArray; 7 | 8 | public class BodyTagRule extends BasicRule { 9 | 10 | private final PageBuilder page; 11 | private final SitemeshBufferFragment.Builder body; 12 | 13 | public BodyTagRule(PageBuilder page, SitemeshBufferFragment.Builder body) { 14 | super("body"); 15 | this.page = page; 16 | this.body = body; 17 | } 18 | 19 | public void process(Tag tag) { 20 | if (tag.getType() == Tag.OPEN || tag.getType() == Tag.EMPTY) { 21 | context.currentBuffer().setStart(tag.getPosition() + tag.getLength()); 22 | for (int i = 0; i < tag.getAttributeCount(); i++) { 23 | page.addProperty("body." + tag.getAttributeName(i), tag.getAttributeValue(i)); 24 | } 25 | body.markStart(tag.getPosition() + tag.getLength()); 26 | } else { 27 | body.end(tag.getPosition()); 28 | context.pushBuffer(SitemeshBufferFragment.builder()); // unused buffer: everything after is discarded. 29 | } 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/sitemesh/compatability/HTMLPage2Content.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.sitemesh.compatability; 2 | 3 | import com.opensymphony.module.sitemesh.HTMLPage; 4 | import com.opensymphony.sitemesh.Content; 5 | 6 | import java.io.IOException; 7 | import java.io.Writer; 8 | 9 | /** 10 | * Adapts a SiteMesh 2 {@link HTMLPage} to a SiteMesh 3 {@link Content}. 11 | * 12 | * @author Joe Walnes 13 | * @since SiteMesh 3 14 | */ 15 | public class HTMLPage2Content implements Content { 16 | private final HTMLPage page; 17 | 18 | public HTMLPage2Content(HTMLPage page) { 19 | this.page = page; 20 | } 21 | 22 | public void writeOriginal(Writer out) throws IOException { 23 | page.writePage(out); 24 | } 25 | 26 | public void writeBody(Writer out) throws IOException { 27 | page.writeBody(out); 28 | } 29 | 30 | public void writeHead(Writer out) throws IOException { 31 | page.writeHead(out); 32 | } 33 | 34 | public String getTitle() { 35 | return page.getTitle(); 36 | } 37 | 38 | public String getProperty(String name) { 39 | return page.getProperty(name); 40 | } 41 | 42 | public String[] getPropertyKeys() { 43 | return page.getPropertyKeys(); 44 | } 45 | 46 | public void addProperty(String name, String value) { 47 | page.addProperty(name, value); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/etc/dtd/sitemesh_1_5_decorators.dtd: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 23 | 24 | 27 | 28 | 31 | 32 | 33 | 37 | 38 | 43 | 44 | 48 | -------------------------------------------------------------------------------- /docs/api/com/opensymphony/module/sitemesh/factory/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | com.opensymphony.module.sitemesh.factory (OpenSymphony SiteMesh 2.5 API) 7 | 8 | 9 | 10 | 11 | 12 |

com.opensymphony.module.sitemesh.factory

13 |
14 |

Classes

15 | 19 |

Exceptions

20 | 23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/taglib/decorator/UsePageTag.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Title: UsePageTag 3 | * Description: 4 | * 5 | * This software is published under the terms of the OpenSymphony Software 6 | * License version 1.1, of which a copy has been included with this 7 | * distribution in the LICENSE.txt file. 8 | */ 9 | 10 | package com.opensymphony.module.sitemesh.taglib.decorator; 11 | 12 | import com.opensymphony.module.sitemesh.taglib.AbstractTag; 13 | 14 | import jakarta.servlet.jsp.JspException; 15 | import jakarta.servlet.jsp.PageContext; 16 | 17 | /** 18 | * Expose the Page as a bean to the page which can then be accessed 19 | * from scriptlets. 20 | * 21 | *

Depending on the TEI used, the object will be 22 | * {@link com.opensymphony.module.sitemesh.Page} or 23 | * {@link com.opensymphony.module.sitemesh.HTMLPage}.

24 | * 25 | * @author Joe Walnes 26 | * @version $Revision: 1.1 $ 27 | * 28 | * @see UsePageTEI 29 | * @see UseHTMLPageTEI 30 | */ 31 | public class UsePageTag extends AbstractTag { 32 | private String id = null; 33 | 34 | /** Set name of variable the Page will be set as. */ 35 | public void setId(String id) { 36 | this.id = id; 37 | } 38 | 39 | public final int doEndTag() throws JspException { 40 | pageContext.setAttribute(id, getPage(), PageContext.PAGE_SCOPE); 41 | return EVAL_PAGE; 42 | } 43 | } -------------------------------------------------------------------------------- /testsuite/src/java/testsuite/sitemesh/BinaryFileTest.java: -------------------------------------------------------------------------------- 1 | package testsuite.sitemesh; 2 | 3 | import testsuite.tester.WebTest; 4 | import com.meterware.httpunit.WebResponse; 5 | 6 | import java.io.FileInputStream; 7 | import java.io.BufferedInputStream; 8 | import java.io.InputStream; 9 | 10 | /** 11 | * Test binary files on sitemesh 12 | * 13 | * @author Scott Farquhar 14 | */ 15 | public class BinaryFileTest extends WebTest { 16 | 17 | public void testImageIsDownloadedIntact() throws Exception { 18 | InputStream fis = new BufferedInputStream(new FileInputStream("src/webapp/binary/harry_potter.gif")); 19 | WebResponse rs = wc.getResponse(baseUrl + "/binary/harry_potter.gif"); 20 | InputStream wis = rs.getInputStream(); 21 | 22 | int f, w, count = 0; 23 | while (true) { 24 | count++; 25 | f = fis.read(); 26 | w = wis.read(); 27 | if (f == w && w == -1) { 28 | //end of stream, everything went well. 29 | return; 30 | } else if (f == w) { 31 | //matching up so far 32 | continue; 33 | } else { 34 | //not matching. 35 | fail("Binary file did not match at byte " + count + ". Web returned '" + w + "'. File returned '" + f + "'"); 36 | } 37 | 38 | 39 | } 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /docs/api/com/opensymphony/module/sitemesh/tapestry/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | com.opensymphony.module.sitemesh.tapestry (OpenSymphony SiteMesh 2.5 API) 7 | 8 | 9 | 10 | 11 | 12 |

com.opensymphony.module.sitemesh.tapestry

13 |
14 |

Classes

15 | 21 |
22 | 23 | 24 | -------------------------------------------------------------------------------- /docs/api/com/opensymphony/sitemesh/webapp/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | com.opensymphony.sitemesh.webapp (OpenSymphony SiteMesh 2.5 API) 7 | 8 | 9 | 10 | 11 | 12 |

com.opensymphony.sitemesh.webapp

13 |
14 |

Classes

15 | 21 |
22 | 23 | 24 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/sitemesh/webapp/decorator/ExternalDispatchedDecorator.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.sitemesh.webapp.decorator; 2 | 3 | import jakarta.servlet.ServletContext; 4 | 5 | /** 6 | * Decorator that dispatches to another path in A DIFFERENT WEB-APP in the same Servlet Container (such as a JSP or path mapped to a Servlet). 7 | *
8 | * The Content and SiteMeshContext objects are passed to the decorator using the HttpServletRequest attributes 9 | * {@link #CONTENT_KEY} and {@link #CONTEXT_KEY}. 10 | *
11 | * To dispatch to a decorator in the same web-app, use {@link DispatchedDecorator}. 12 | * 13 | * @author Joe Walnes 14 | * @since SiteMesh 3.0 15 | */ 16 | public class ExternalDispatchedDecorator extends DispatchedDecorator { 17 | 18 | private final String webApp; 19 | 20 | public ExternalDispatchedDecorator(String path, String webApp) { 21 | super(path); 22 | this.webApp = webApp; 23 | } 24 | 25 | protected ServletContext locateWebApp(ServletContext context) { 26 | ServletContext externalContext = context.getContext(webApp); 27 | if (externalContext != null) { 28 | return externalContext; 29 | } else { 30 | // in a security conscious environment, the servlet container 31 | // may return null for a given URL 32 | throw new SecurityException("Cannot obtain ServletContext for web-app : " + webApp); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /testsuite/src/webapp/WEB-INF/sitemesh.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/html/rules/MSOfficeDocumentPropertiesRule.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.html.rules; 2 | 3 | import com.opensymphony.module.sitemesh.html.BlockExtractingRule; 4 | import com.opensymphony.module.sitemesh.html.Tag; 5 | 6 | /** 7 | * Extracts the extra properties saved in HTML from MS Office applications (Word and Excel), 8 | * such as Author, Company, Version, etc. 9 | * 10 | * @author Joe Walnes 11 | */ 12 | public class MSOfficeDocumentPropertiesRule extends BlockExtractingRule { 13 | 14 | private final PageBuilder page; 15 | private boolean inDocumentProperties; 16 | 17 | public MSOfficeDocumentPropertiesRule(PageBuilder page) { 18 | super(true); 19 | this.page = page; 20 | } 21 | 22 | public boolean shouldProcess(String name) { 23 | return (inDocumentProperties && name.startsWith("o:")) || name.equals("o:documentproperties"); 24 | } 25 | 26 | public void process(Tag tag) { 27 | if (tag.getName().equals("o:DocumentProperties")) { 28 | inDocumentProperties = (tag.getType() == Tag.OPEN); 29 | } else { 30 | super.process(tag); 31 | } 32 | } 33 | 34 | protected void start(Tag tag) { 35 | } 36 | 37 | protected void end(Tag tag) { 38 | String name = tag.getName().substring(2); 39 | page.addProperty("office.DocumentProperties." + name, getCurrentBufferContent()); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /testsuite/src/webapp/WEB-INF/src/testsuite/servlets/OutputServlet.java: -------------------------------------------------------------------------------- 1 | package testsuite.servlets; 2 | 3 | import com.opensymphony.module.sitemesh.RequestConstants; 4 | 5 | import jakarta.servlet.ServletException; 6 | import jakarta.servlet.http.HttpServlet; 7 | import jakarta.servlet.http.HttpServletRequest; 8 | import jakarta.servlet.http.HttpServletResponse; 9 | import java.io.IOException; 10 | import java.io.OutputStreamWriter; 11 | import java.io.PrintWriter; 12 | 13 | public class OutputServlet extends HttpServlet { 14 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 15 | if ("yes".equals(request.getParameter("kill"))) { 16 | request.setAttribute(RequestConstants.DISABLE_BUFFER_AND_DECORATION, Boolean.TRUE); 17 | } 18 | 19 | String mode = request.getParameter("out"); 20 | PrintWriter pw = null; 21 | 22 | if (mode.equals("stream")) { 23 | OutputStreamWriter osw = new OutputStreamWriter(response.getOutputStream()); 24 | pw = new PrintWriter(osw); 25 | } 26 | 27 | if (pw == null) { 28 | pw = response.getWriter(); 29 | } 30 | response.setContentType("text/html"); 31 | pw.println("Servlet using " + mode + ""); 32 | pw.println("This is a servlet using " + mode + " to output"); 33 | pw.flush(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/html/rules/RegexReplacementTextFilter.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.html.rules; 2 | 3 | import com.opensymphony.module.sitemesh.html.TextFilter; 4 | 5 | import java.util.regex.Pattern; 6 | import java.util.regex.Matcher; 7 | 8 | /** 9 | * TextFilter that substitutes content using a JDK 1.4 regular expression. 10 | * 11 | *

Example

12 | * 13 | * This will substitute 'Google:Blah' for a link to a google search. 14 | * 15 | *
HTMLProcessor processor = new HTMLProcessor(in, out);
16 |  * processor.addTextFilter(new RegexReplacementTextFilter("Google:([a-zA-Z]+)", "$1"));
17 |  * // add more TextFilters and TagRules
18 |  * processor.process();
19 | * 20 | * @author Joe Walnes 21 | */ 22 | public class RegexReplacementTextFilter implements TextFilter { 23 | 24 | private final Pattern regex; 25 | private final String replacement; 26 | 27 | public RegexReplacementTextFilter(String regex, String replacement) { 28 | this.regex = Pattern.compile(regex); 29 | this.replacement = replacement; 30 | } 31 | 32 | public RegexReplacementTextFilter(Pattern regex, String replacement) { 33 | this.regex = regex; 34 | this.replacement = replacement; 35 | } 36 | 37 | public String filter(String text) { 38 | Matcher matcher = regex.matcher(text); 39 | return matcher.replaceAll(replacement); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /docs/api/com/opensymphony/module/sitemesh/html/tokenizer/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | com.opensymphony.module.sitemesh.html.tokenizer (OpenSymphony SiteMesh 2.5 API) 7 | 8 | 9 | 10 | 11 | 12 |

com.opensymphony.module.sitemesh.html.tokenizer

13 |
14 |

Interfaces

15 | 18 |

Classes

19 | 23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/multipass/MultipassFilter.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.multipass; 2 | 3 | import com.opensymphony.module.sitemesh.Page; 4 | import com.opensymphony.module.sitemesh.PageParser; 5 | import com.opensymphony.module.sitemesh.PageParserSelector; 6 | import com.opensymphony.sitemesh.webapp.SiteMeshFilter; 7 | import com.opensymphony.module.sitemesh.filter.PageResponseWrapper; 8 | 9 | import jakarta.servlet.RequestDispatcher; 10 | import jakarta.servlet.ServletException; 11 | import jakarta.servlet.http.HttpServletRequest; 12 | import jakarta.servlet.http.HttpServletResponse; 13 | import java.io.IOException; 14 | 15 | public class MultipassFilter extends SiteMeshFilter { 16 | 17 | protected void writeDecorator(final HttpServletResponse response, final Page page, RequestDispatcher dispatcher, HttpServletRequest request) throws ServletException, IOException { 18 | PageResponseWrapper pageResponse = new PageResponseWrapper(response, request, new PageParserSelector() { 19 | public boolean shouldParsePage(String contentType) { 20 | return true; 21 | } 22 | 23 | public PageParser getPageParser(String contentType) { 24 | return new MultipassReplacementPageParser(page, response); 25 | } 26 | }); 27 | pageResponse.activateSiteMesh("text/html", ""); 28 | dispatcher.include(request, pageResponse); 29 | pageResponse.getPage(); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/filter/PageRequestWrapper.java: -------------------------------------------------------------------------------- 1 | /* This software is published under the terms of the OpenSymphony Software 2 | * License version 1.1, of which a copy has been included with this 3 | * distribution in the LICENSE.txt file. */ 4 | package com.opensymphony.module.sitemesh.filter; 5 | 6 | import jakarta.servlet.RequestDispatcher; 7 | import jakarta.servlet.http.HttpServletRequest; 8 | import jakarta.servlet.http.HttpServletRequestWrapper; 9 | 10 | /** 11 | * Will wrap a request for the {@link RequestDispatcherWrapper}. 12 | * 13 | * @author Joseph B. Ottinger 14 | * @version $Revision: 1.4 $ 15 | */ 16 | public class PageRequestWrapper extends HttpServletRequestWrapper { 17 | private static final boolean SUPPRESS_IF_MODIFIED_HEADER = true; //todo - pull this from a config file 18 | 19 | public PageRequestWrapper(HttpServletRequest request) { 20 | super(request); 21 | } 22 | 23 | public RequestDispatcher getRequestDispatcher(String s) { 24 | return new RequestDispatcherWrapper(super.getRequestDispatcher(s)); 25 | } 26 | 27 | public String getHeader(String string) { 28 | // suppress 'if-modified-since' header, so that decorators can modify the response. 29 | if (SUPPRESS_IF_MODIFIED_HEADER && "IF-MODIFIED-SINCE".equalsIgnoreCase(string)) { 30 | return ""; 31 | } 32 | else { 33 | return super.getHeader(string); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /docs/api/com/opensymphony/sitemesh/webapp/decorator/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | com.opensymphony.sitemesh.webapp.decorator (OpenSymphony SiteMesh 2.5 API) 7 | 8 | 9 | 10 | 11 | 12 |

com.opensymphony.sitemesh.webapp.decorator

13 |
14 |

Classes

15 | 21 |
22 | 23 | 24 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/taglib/decorator/DivTag.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Title: DivTag 3 | * Description: 4 | * 5 | * This software is published under the terms of the OpenSymphony Software 6 | * License version 1.1, of which a copy has been included with this 7 | * distribution in the LICENSE.txt file. 8 | */ 9 | 10 | package com.opensymphony.module.sitemesh.taglib.decorator; 11 | 12 | import java.io.IOException; 13 | 14 | import jakarta.servlet.jsp.JspException; 15 | 16 | import com.opensymphony.module.sitemesh.HTMLPage; 17 | import com.opensymphony.module.sitemesh.taglib.AbstractTag; 18 | 19 | /** 20 | * Write a HTMLPage div to out. 21 | * 22 | * @author mouyang 23 | * @version $Revision: 1.3 $ 24 | * 25 | * @see com.opensymphony.module.sitemesh.HTMLPage#writeHead(java.io.Writer) 26 | */ 27 | public class DivTag extends AbstractTag { 28 | protected String divId; 29 | 30 | public String getId() { 31 | return divId; 32 | } 33 | 34 | public void setId(String divId) { 35 | this.divId = divId; 36 | } 37 | public final int doEndTag() throws JspException 38 | { 39 | try 40 | { 41 | String divBody = getPage().getProperty("div." + divId); 42 | if (divBody != null) { 43 | getOut().write(divBody.substring(divBody.indexOf('>') + 1, divBody.lastIndexOf('<'))); 44 | } 45 | } 46 | catch(IOException e) 47 | { 48 | throw new JspException("Error writing head element: " + e.toString(), e); 49 | } 50 | return EVAL_PAGE; 51 | } 52 | } -------------------------------------------------------------------------------- /testsuite/src/java/testsuite/sitemesh/RedirectTest.java: -------------------------------------------------------------------------------- 1 | package testsuite.sitemesh; 2 | 3 | import testsuite.tester.WebTest; 4 | import com.meterware.httpunit.WebResponse; 5 | import electric.xml.Document; 6 | 7 | /** 8 | * Test no problems with redirections, forwards and includes. 9 | * 10 | * @author Joe Walnes 11 | */ 12 | public class RedirectTest extends WebTest { 13 | 14 | public void testRedirectedPage() throws Exception { 15 | checkPage( "/redirect/simple-redirect.jsp" ); 16 | } 17 | 18 | public void testRequestDispatcherForwardedPage() throws Exception { 19 | checkPage( "/redirect/simple-rdforward.jsp" ); 20 | } 21 | 22 | public void testRequestDispatcherIncludedPage() throws Exception { 23 | checkPage( "/redirect/simple-rdinclude.jsp" ); 24 | } 25 | 26 | public void testPageContextForwardedPage() throws Exception { 27 | checkPage( "/redirect/simple-forward.jsp" ); 28 | } 29 | 30 | public void testPageContextIncludedPage() throws Exception { 31 | checkPage( "/redirect/simple-include.jsp" ); 32 | } 33 | 34 | private void checkPage(String path) throws Exception { 35 | WebResponse rs = wc.getResponse( baseUrl + path ); 36 | Document doc = getDocument( rs ); 37 | assertEquals( "[:: Another page ::]", rs.getTitle() ); 38 | assertEquals( "A different page", doc.getElementWithId( "p1" ).getText().toString() ); 39 | assertEquals( "footer", doc.getElementWithId( "footer" ).getText().toString() ); 40 | assertEquals( "Another page", doc.getElementWithId( "header" ).getText().toString() ); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /docs/dtd/sitemesh_1_0_decorators.dtd: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 23 | 24 | 25 | 29 | 30 | 31 | 35 | 36 | 37 | 41 | 42 | 43 | 47 | 48 | 49 | 53 | -------------------------------------------------------------------------------- /src/etc/dtd/sitemesh_1_0_decorators.dtd: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 23 | 24 | 25 | 29 | 30 | 31 | 35 | 36 | 37 | 41 | 42 | 43 | 47 | 48 | 49 | 53 | -------------------------------------------------------------------------------- /docs/api/com/opensymphony/sitemesh/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | com.opensymphony.sitemesh (OpenSymphony SiteMesh 2.5 API) 7 | 8 | 9 | 10 | 11 | 12 |

com.opensymphony.sitemesh

13 |
14 |

Interfaces

15 | 22 |
23 | 24 | 25 | -------------------------------------------------------------------------------- /testsuite/src/java/testsuite/sitemesh/JettyWebServer.java: -------------------------------------------------------------------------------- 1 | package testsuite.sitemesh; 2 | 3 | import org.mortbay.http.SocketListener; 4 | import org.mortbay.jetty.Server; 5 | import org.mortbay.jetty.servlet.WebApplicationContext; 6 | 7 | import java.io.IOException; 8 | 9 | public class JettyWebServer { 10 | private Server server; 11 | 12 | public JettyWebServer(int port, String pathToWebApp) throws IOException { 13 | server = new Server(); 14 | SocketListener listener = new SocketListener(); 15 | listener.setPort(port); 16 | server.addListener(listener); 17 | 18 | WebApplicationContext context = new WebApplicationContext(pathToWebApp); 19 | context.setContextPath("/"); 20 | 21 | // This will load classes from primordial classloader first. 22 | // Avoids having to copy classes into WEB-INF/classes when running from the IDE. 23 | context.setClassLoaderJava2Compliant(true); 24 | 25 | server.addContext(null, context); 26 | } 27 | 28 | public void start() { 29 | try { 30 | server.start(); 31 | } catch (Exception e) { 32 | e.printStackTrace(); 33 | throw new RuntimeException("Cannot start server", e); 34 | } 35 | } 36 | 37 | public void stop() { 38 | try { 39 | server.stop(); 40 | } catch (Exception e) { 41 | throw new RuntimeException("Cannot stop server", e); 42 | } 43 | } 44 | 45 | public static void main(String[] args) throws IOException { 46 | JettyWebServer server = new JettyWebServer(9912, "dist/webapp"); 47 | server.start(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/mapper/NullDecoratorMapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Title: NullDecoratorMapper 3 | * Description: 4 | * 5 | * This software is published under the terms of the OpenSymphony Software 6 | * License version 1.1, of which a copy has been included with this 7 | * distribution in the LICENSE.txt file. 8 | */ 9 | 10 | package com.opensymphony.module.sitemesh.mapper; 11 | 12 | import com.opensymphony.module.sitemesh.Config; 13 | import com.opensymphony.module.sitemesh.Decorator; 14 | import com.opensymphony.module.sitemesh.DecoratorMapper; 15 | import com.opensymphony.module.sitemesh.Page; 16 | 17 | import jakarta.servlet.http.HttpServletRequest; 18 | import java.util.Properties; 19 | 20 | /** 21 | * The NullDecoratorMapper represents the top-level DecoratorMapper that 22 | * is finally delegated to if no other DecoratorMapper has intervened. 23 | * It is used so the parent property does not have to be checked by 24 | * other DecoratorMappers (null object pattern). 25 | * 26 | * @author Joe Walnes 27 | * @version $Revision: 1.1 $ 28 | * 29 | * @see com.opensymphony.module.sitemesh.DecoratorMapper 30 | */ 31 | public class NullDecoratorMapper implements DecoratorMapper { 32 | 33 | /** Does nothing. */ 34 | public void init(Config config, Properties properties, DecoratorMapper parent) { 35 | } 36 | 37 | /** Returns null. */ 38 | public Decorator getDecorator(HttpServletRequest request, Page page) { 39 | return null; 40 | } 41 | 42 | /** Returns null. */ 43 | public Decorator getNamedDecorator(HttpServletRequest request, String name) { 44 | return null; 45 | } 46 | } -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/sitemesh/compatability/DecoratorMapper2DecoratorSelector.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.sitemesh.compatability; 2 | 3 | import com.opensymphony.module.sitemesh.DecoratorMapper; 4 | import com.opensymphony.sitemesh.Content; 5 | import com.opensymphony.sitemesh.Decorator; 6 | import com.opensymphony.sitemesh.DecoratorSelector; 7 | import com.opensymphony.sitemesh.SiteMeshContext; 8 | import com.opensymphony.sitemesh.webapp.SiteMeshWebAppContext; 9 | import com.opensymphony.sitemesh.webapp.decorator.NoDecorator; 10 | 11 | import jakarta.servlet.http.HttpServletRequest; 12 | 13 | /** 14 | * Adapts a SiteMesh 2 {@link DecoratorMapper} to a SiteMesh 2 {@link DecoratorSelector}. 15 | * 16 | * @author Joe Walnes 17 | * @since SiteMesh 3 18 | */ 19 | public class DecoratorMapper2DecoratorSelector implements DecoratorSelector { 20 | 21 | private final DecoratorMapper decoratorMapper; 22 | 23 | public DecoratorMapper2DecoratorSelector(DecoratorMapper decoratorMapper) { 24 | this.decoratorMapper = decoratorMapper; 25 | } 26 | 27 | public Decorator selectDecorator(Content content, SiteMeshContext context) { 28 | SiteMeshWebAppContext webAppContext = (SiteMeshWebAppContext) context; 29 | HttpServletRequest request = webAppContext.getRequest(); 30 | com.opensymphony.module.sitemesh.Decorator decorator = 31 | decoratorMapper.getDecorator(request, new Content2HTMLPage(content, request)); 32 | if (decorator == null || decorator.getPage() == null) { 33 | return new NoDecorator(); 34 | } else { 35 | return new OldDecorator2NewDecorator(decorator); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /docs/api/com/opensymphony/sitemesh/compatability/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | com.opensymphony.sitemesh.compatability (OpenSymphony SiteMesh 2.5 API) 7 | 8 | 9 | 10 | 11 | 12 |

com.opensymphony.sitemesh.compatability

13 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/test/java/com/opensymphony/module/sitemesh/html/CustomTagTest.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.html; 2 | 3 | import junit.framework.TestCase; 4 | 5 | public class CustomTagTest extends TestCase { 6 | 7 | public void testWritesOutUserDefinedTag() { 8 | assertEquals("", new CustomTag("hello", Tag.EMPTY).getContents()); 9 | assertEquals("", new CustomTag("hello", Tag.OPEN).getContents()); 10 | assertEquals("", new CustomTag("hello", Tag.CLOSE).getContents()); 11 | } 12 | 13 | public void testWritesAttributes() { 14 | CustomTag tag = new CustomTag("hello", Tag.EMPTY); 15 | tag.addAttribute("color", "green"); 16 | tag.addAttribute("stuff", null); 17 | assertEquals("", tag.getContents()); 18 | } 19 | 20 | public void testAllowsAttributesToBeManipulated() { 21 | CustomTag tag = new CustomTag("hello", Tag.OPEN); 22 | assertEquals("", tag.getContents()); 23 | 24 | tag.addAttribute("a", "aaa"); 25 | tag.addAttribute("b", "bbb"); 26 | assertEquals("", tag.getContents()); 27 | 28 | tag.removeAttribute("b", false); 29 | assertEquals("", tag.getContents()); 30 | 31 | tag.setAttributeValue("a", false, "zzz"); 32 | assertEquals("", tag.getContents()); 33 | 34 | tag.addAttribute("c", "ccc"); 35 | int index = tag.getAttributeIndex("c", true); 36 | assertEquals(1, index); 37 | assertEquals("ccc", tag.getAttributeValue(index)); 38 | assertEquals("c", tag.getAttributeName(index)); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/opensymphony/module/sitemesh/html/util/StringSitemeshBuffer.java: -------------------------------------------------------------------------------- 1 | package com.opensymphony.module.sitemesh.html.util; 2 | 3 | import com.opensymphony.module.sitemesh.SitemeshBuffer; 4 | import com.opensymphony.module.sitemesh.SitemeshBufferFragment; 5 | import com.opensymphony.module.sitemesh.scalability.secondarystorage.SecondaryStorage; 6 | 7 | import java.io.IOException; 8 | import java.io.Writer; 9 | 10 | /** 11 | * SitemeshBuffer that is a string 12 | */ 13 | public class StringSitemeshBuffer implements SitemeshBuffer { 14 | private final String buffer; 15 | 16 | public StringSitemeshBuffer(String buffer) { 17 | this.buffer = buffer; 18 | } 19 | 20 | public char[] getCharArray() { 21 | return buffer.toCharArray(); 22 | } 23 | 24 | public int getBufferLength() { 25 | return buffer.length(); 26 | } 27 | 28 | public int getTotalLength() { 29 | return buffer.length(); 30 | } 31 | 32 | public int getTotalLength(int start, int length) { 33 | return length; 34 | } 35 | 36 | public void writeTo(Writer writer, int start, int length) throws IOException { 37 | writer.write(buffer, start, length); 38 | } 39 | 40 | public boolean hasFragments() { 41 | return false; 42 | } 43 | 44 | public static SitemeshBufferFragment createBufferFragment(String buffer) 45 | { 46 | return new SitemeshBufferFragment(new StringSitemeshBuffer(buffer), 0, buffer.length()); 47 | } 48 | 49 | public boolean hasSecondaryStorage() 50 | { 51 | return false; 52 | } 53 | 54 | public SecondaryStorage getSecondaryStorage() 55 | { 56 | return null; 57 | } 58 | } 59 | --------------------------------------------------------------------------------