diff --git a/scm-core/src/main/java/sonia/scm/template/TemplateHandler.java b/scm-core/src/main/java/sonia/scm/template/TemplateHandler.java new file mode 100644 index 0000000000..0a06b0c6f5 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/template/TemplateHandler.java @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of SCM-Manager; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.template; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; +import java.io.Writer; + +import java.util.Map; + +/** + * + * @author Sebastian Sdorra + */ +public interface TemplateHandler +{ + + /** + * Method description + * + * + * @param templateName + * @param writer + * @param params + * + * @throws IOException + */ + public void render(String templateName, Writer writer, + Map params) + throws IOException; +} diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index 6601cf1bcf..f608734e2f 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -101,6 +101,12 @@ 1.0 + + freemarker + freemarker + 2.3.9 + + diff --git a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java index a8ddb07c51..75e8c9a164 100644 --- a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java +++ b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java @@ -64,6 +64,9 @@ import sonia.scm.security.MessageDigestEncryptionHandler; import sonia.scm.security.SecurityContext; import sonia.scm.store.JAXBStoreFactory; import sonia.scm.store.StoreFactory; +import sonia.scm.template.FreemarkerTemplateHandler; +import sonia.scm.template.TemplateHandler; +import sonia.scm.template.TemplateServlet; import sonia.scm.user.UserManager; import sonia.scm.user.xml.XmlUserManager; import sonia.scm.util.DebugServlet; @@ -112,6 +115,9 @@ public class ScmServletModule extends ServletModule /** Field description */ public static final String PATTERN_DEBUG = "/debug.html"; + /** Field description */ + public static final String PATTERN_INDEX = "/index.html"; + /** Field description */ public static final String PATTERN_PAGE = "*.html"; @@ -227,6 +233,10 @@ public class ScmServletModule extends ServletModule // plugin resources serve(PATTERN_PLUGIN_SCRIPT).with(ScriptResourceServlet.class); + // template + bind(TemplateHandler.class).to(FreemarkerTemplateHandler.class); + serve(PATTERN_INDEX, "/").with(TemplateServlet.class); + // jersey Map params = new HashMap(); diff --git a/scm-webapp/src/main/java/sonia/scm/template/FreemarkerTemplateHandler.java b/scm-webapp/src/main/java/sonia/scm/template/FreemarkerTemplateHandler.java new file mode 100644 index 0000000000..c90205f4bf --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/template/FreemarkerTemplateHandler.java @@ -0,0 +1,158 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of SCM-Manager; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.template; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.inject.Inject; +import com.google.inject.Singleton; + +import freemarker.template.Configuration; +import freemarker.template.Template; +import freemarker.template.TemplateException; + +import org.slf4j.LoggerFactory; + +import sonia.scm.ConfigurationException; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.Writer; + +import java.util.Locale; +import java.util.Map; + +import javax.servlet.ServletContext; +import org.slf4j.Logger; + +/** + * + * @author Sebastian Sdorra + */ +@Singleton +public class FreemarkerTemplateHandler implements TemplateHandler +{ + + /** Field description */ + public static final String DIRECTORY_TEMPLATES = "/"; + + /** Field description */ + public static final String ENCODING = "UTF-8"; + + /** Field description */ + public static final String EXTENSION = ".html"; + + /** the logger for FreemarkerTemplateHandler */ + private static final Logger logger = + LoggerFactory.getLogger(FreemarkerTemplateHandler.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param servletContext + */ + @Inject + public FreemarkerTemplateHandler(ServletContext servletContext) + { + try + { + configuration = new Configuration(); + + String path = servletContext.getRealPath(DIRECTORY_TEMPLATES); + + configuration.setDirectoryForTemplateLoading(new File(path)); + configuration.setEncoding(Locale.ENGLISH, ENCODING); + } + catch (IOException ex) + { + throw new ConfigurationException( + "could not create FreemarkerTemplateHandler", ex); + } + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param templateName + * @param writer + * @param params + * + * @throws IOException + */ + @Override + public void render(String templateName, Writer writer, + Map params) + throws IOException + { + if (!templateName.endsWith(EXTENSION)) + { + templateName = templateName.concat(EXTENSION); + } + + Template template = configuration.getTemplate(templateName, ENCODING); + + if (template == null) + { + throw new FileNotFoundException( + "file ".concat(templateName).concat(" not found")); + } + else + { + try + { + template.process(params, writer); + } + catch (TemplateException ex) + { + logger.error("could not render template ".concat(templateName), ex); + + throw new IOException(ex); + } + } + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private Configuration configuration; +} diff --git a/scm-webapp/src/main/java/sonia/scm/template/TemplateServlet.java b/scm-webapp/src/main/java/sonia/scm/template/TemplateServlet.java new file mode 100644 index 0000000000..b66fd9dea0 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/template/TemplateServlet.java @@ -0,0 +1,174 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of SCM-Manager; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.template; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.inject.Inject; +import com.google.inject.Singleton; + +import sonia.scm.SCMContextProvider; +import sonia.scm.util.IOUtil; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; +import java.io.Writer; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * @author Sebastian Sdorra + */ +@Singleton +public class TemplateServlet extends HttpServlet +{ + + /** Field description */ + private static final long serialVersionUID = 3578555653924091546L; + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * + * @param context + * @param templateHandler + */ + @Inject + public TemplateServlet(SCMContextProvider context, + TemplateHandler templateHandler) + { + this.templateHandler = templateHandler; + this.version = context.getVersion(); + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param request + * @param response + * + * @throws IOException + * @throws ServletException + */ + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException + { + Map params = new HashMap(); + String contextPath = request.getContextPath(); + + params.put("contextPath", contextPath); + params.put("version", version); + + Locale l = request.getLocale(); + + if (l == null) + { + l = Locale.ENGLISH; + } + + String locale = l.toString(); + + params.put("locale", locale); + + String shortLocale = locale; + int i = shortLocale.indexOf("_"); + + if (i > 0) + { + shortLocale = shortLocale.substring(0, i); + } + + params.put("shortLocale", shortLocale); + + String templateName = getTemplateName(contextPath, request.getRequestURI()); + Writer writer = null; + + try + { + writer = response.getWriter(); + templateHandler.render(templateName, writer, params); + } + finally + { + IOUtil.close(writer); + } + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param contextPath + * @param requestURI + * + * @return + */ + private String getTemplateName(String contextPath, String requestURI) + { + String path = requestURI.substring(contextPath.length()); + + if (path.endsWith("/")) + { + path = path.concat("index.html"); + } + + return path; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private TemplateHandler templateHandler; + + /** Field description */ + private String version; +} diff --git a/scm-webapp/src/main/webapp/index.html b/scm-webapp/src/main/webapp/index.html index 8c77f5e65c..be1b9245aa 100644 --- a/scm-webapp/src/main/webapp/index.html +++ b/scm-webapp/src/main/webapp/index.html @@ -64,7 +64,10 @@ - + <#if shortLocale != 'en'> + + + SCM-WebAPP @@ -99,7 +102,7 @@ © SCM Manager
- Impressum + ${version}