Sat, 16 Dec 2017 20:19:28 +0100
implements automatic menu generation from module information
1.1 --- a/src/java/de/uapcore/lightpit/AbstractLightPITServlet.java Fri Dec 15 17:39:54 2017 +0100 1.2 +++ b/src/java/de/uapcore/lightpit/AbstractLightPITServlet.java Sat Dec 16 20:19:28 2017 +0100 1.3 @@ -33,6 +33,8 @@ 1.4 import javax.servlet.http.HttpServlet; 1.5 import javax.servlet.http.HttpServletRequest; 1.6 import javax.servlet.http.HttpServletResponse; 1.7 +import org.slf4j.Logger; 1.8 +import org.slf4j.LoggerFactory; 1.9 1.10 /** 1.11 * A special implementation of a HTTPServlet which is focused on implementing 1.12 @@ -40,16 +42,43 @@ 1.13 */ 1.14 public abstract class AbstractLightPITServlet extends HttpServlet { 1.15 1.16 + private static final Logger LOG = LoggerFactory.getLogger(AbstractLightPITServlet.class); 1.17 + 1.18 + 1.19 + /** 1.20 + * Gives implementing modules access to the {@link ModuleManager}. 1.21 + * @return the module manager 1.22 + */ 1.23 + protected final ModuleManager getModuleManager() { 1.24 + return (ModuleManager) getServletContext().getAttribute(ModuleManager.SC_ATTR_NAME); 1.25 + } 1.26 + 1.27 + private void addPathInformation(HttpServletRequest req) { 1.28 + final String path = req.getServletPath()+"/"+req.getPathInfo(); 1.29 + req.setAttribute(Constants.REQ_ATTR_PATH, path); 1.30 + } 1.31 + 1.32 + private void forwardToFullView(HttpServletRequest req, HttpServletResponse resp) 1.33 + throws IOException, ServletException { 1.34 + 1.35 + addPathInformation(req); 1.36 + 1.37 + final ModuleManager mm = getModuleManager(); 1.38 + req.setAttribute(Constants.REQ_ATTR_MENU, mm.getMainMenu()); 1.39 + 1.40 + req.getRequestDispatcher(Functions.jspPath("full.jsp")).forward(req, resp); 1.41 + } 1.42 + 1.43 @Override 1.44 protected final void doGet(HttpServletRequest req, HttpServletResponse resp) 1.45 throws ServletException, IOException { 1.46 - 1.47 - resp.getWriter().println("It works!"); 1.48 + forwardToFullView(req, resp); 1.49 } 1.50 1.51 @Override 1.52 protected final void doPost(HttpServletRequest req, HttpServletResponse resp) 1.53 throws ServletException, IOException { 1.54 + 1.55 + forwardToFullView(req, resp); 1.56 } 1.57 - 1.58 }
2.1 --- a/src/java/de/uapcore/lightpit/Constants.java Fri Dec 15 17:39:54 2017 +0100 2.2 +++ b/src/java/de/uapcore/lightpit/Constants.java Sat Dec 16 20:19:28 2017 +0100 2.3 @@ -28,11 +28,19 @@ 2.4 */ 2.5 package de.uapcore.lightpit; 2.6 2.7 +import static de.uapcore.lightpit.Functions.fullyQualifiedName; 2.8 + 2.9 /** 2.10 * Contains all constants used by the this application. 2.11 */ 2.12 -public abstract class Constants { 2.13 - public static final String HOME_NODE = "/home/"; 2.14 +public final class Constants { 2.15 + public static final String JSP_PATH_PREFIX = "/WEB-INF/view/"; 2.16 2.17 - public static final String JSP_PATH_PREFIX = "/WEB-INF/view/"; 2.18 + public static final String REQ_ATTR_MENU = fullyQualifiedName(AbstractLightPITServlet.class, "mainMenu"); 2.19 + public static final String REQ_ATTR_PATH = fullyQualifiedName(AbstractLightPITServlet.class, "path"); 2.20 + 2.21 + /** 2.22 + * This class is not instantiatable. 2.23 + */ 2.24 + private Constants() {} 2.25 }
3.1 --- a/src/java/de/uapcore/lightpit/Functions.java Fri Dec 15 17:39:54 2017 +0100 3.2 +++ b/src/java/de/uapcore/lightpit/Functions.java Sat Dec 16 20:19:28 2017 +0100 3.3 @@ -28,12 +28,52 @@ 3.4 */ 3.5 package de.uapcore.lightpit; 3.6 3.7 +import org.slf4j.Logger; 3.8 +import org.slf4j.LoggerFactory; 3.9 + 3.10 /** 3.11 * Contains common static functions. 3.12 */ 3.13 -public class Functions { 3.14 +public final class Functions { 3.15 + 3.16 + private static final Logger LOG = LoggerFactory.getLogger(Functions.class); 3.17 3.18 public static String jspPath(String filename) { 3.19 return Constants.JSP_PATH_PREFIX + filename; 3.20 } 3.21 + 3.22 + public static String fullyQualifiedName(String base, String name) { 3.23 + return base+"."+name; 3.24 + } 3.25 + 3.26 + public static String fullyQualifiedName(Class clazz, String name) { 3.27 + return fullyQualifiedName(clazz.getName(), name); 3.28 + } 3.29 + 3.30 + /** 3.31 + * Returns the module path of the given LightPIT Servlet module. 3.32 + * 3.33 + * If you specify a malformed LightPIT servlet, which does not have a module 3.34 + * annotation, the path to the <code>/error/404.html</code> page is returned. 3.35 + * 3.36 + * @param clazz the servlet class 3.37 + * @return the module path 3.38 + */ 3.39 + public static String modulePathOf(Class<? extends AbstractLightPITServlet> clazz) { 3.40 + LightPITModule moduleInfo = clazz.getAnnotation(LightPITModule.class); 3.41 + if (moduleInfo == null) { 3.42 + LOG.warn( 3.43 + "{} is a LightPIT Servlet but is missing the module annotation.", 3.44 + clazz.getName() 3.45 + ); 3.46 + return "/error/404.html"; 3.47 + } else { 3.48 + return moduleInfo.modulePath(); 3.49 + } 3.50 + } 3.51 + 3.52 + /** 3.53 + * This class is not instantiatable. 3.54 + */ 3.55 + private Functions() {} 3.56 }
4.1 --- a/src/java/de/uapcore/lightpit/LightPITModule.java Fri Dec 15 17:39:54 2017 +0100 4.2 +++ b/src/java/de/uapcore/lightpit/LightPITModule.java Sat Dec 16 20:19:28 2017 +0100 4.3 @@ -58,4 +58,20 @@ 4.4 * @return an array of class names of required modules 4.5 */ 4.6 String[] requires() default {}; 4.7 + 4.8 + /** 4.9 + * The path for this module, which will be used for the menu entry. 4.10 + * 4.11 + * This path must adhere to the URL pattern of the Servlet but must not 4.12 + * contain any starting or trailing slashes. 4.13 + * 4.14 + * @return the relative module path 4.15 + */ 4.16 + String modulePath(); 4.17 + 4.18 + /** 4.19 + * Returns the properties key for the menu label. 4.20 + * @return the properties key relative to the base name 4.21 + */ 4.22 + String menuKey() default "menuLabel"; 4.23 }
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/src/java/de/uapcore/lightpit/Menu.java Sat Dec 16 20:19:28 2017 +0100 5.3 @@ -0,0 +1,82 @@ 5.4 +/* 5.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 5.6 + * 5.7 + * Copyright 2017 Mike Becker. All rights reserved. 5.8 + * 5.9 + * Redistribution and use in source and binary forms, with or without 5.10 + * modification, are permitted provided that the following conditions are met: 5.11 + * 5.12 + * 1. Redistributions of source code must retain the above copyright 5.13 + * notice, this list of conditions and the following disclaimer. 5.14 + * 5.15 + * 2. Redistributions in binary form must reproduce the above copyright 5.16 + * notice, this list of conditions and the following disclaimer in the 5.17 + * documentation and/or other materials provided with the distribution. 5.18 + * 5.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 5.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 5.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 5.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 5.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 5.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 5.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 5.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 5.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 5.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 5.29 + * POSSIBILITY OF SUCH DAMAGE. 5.30 + * 5.31 + */ 5.32 +package de.uapcore.lightpit; 5.33 + 5.34 +import java.util.ArrayList; 5.35 +import java.util.Collections; 5.36 +import java.util.List; 5.37 + 5.38 +/** 5.39 + * Maps a resource key for the menu label to the path name for the underlying 5.40 + * site. 5.41 + * 5.42 + * Objects of this class are internally instantiated by the 5.43 + * {@link ModuleManager}. 5.44 + */ 5.45 +public class Menu extends MenuEntry { 5.46 + 5.47 + private final List<MenuEntry> entries = new ArrayList<>(); 5.48 + private final List<MenuEntry> immutableEntries = Collections.unmodifiableList(entries); 5.49 + 5.50 + public Menu() { 5.51 + super(); 5.52 + } 5.53 + 5.54 + public Menu(ResourceKey resourceKey, String pathName) { 5.55 + super(resourceKey, pathName); 5.56 + } 5.57 + 5.58 + /** 5.59 + * Sets a new list of menu entries for this menu. 5.60 + * 5.61 + * @param entries the list of new menu entries 5.62 + */ 5.63 + public void setEntries(List<MenuEntry> entries) { 5.64 + // in case the given list is immutable, we copy the contents 5.65 + this.entries.clear(); 5.66 + this.entries.addAll(entries); 5.67 + } 5.68 + 5.69 + /** 5.70 + * Retrieves an immutable list of menu entries for this menu. 5.71 + * 5.72 + * @return the list of menu entries 5.73 + */ 5.74 + public List<MenuEntry> getEntries() { 5.75 + return immutableEntries; 5.76 + } 5.77 + 5.78 + /** 5.79 + * Adds a new menu entry to this menu. 5.80 + * @param entry the menu entry to add 5.81 + */ 5.82 + public void addMenuEntry(MenuEntry entry) { 5.83 + entries.add(entry); 5.84 + } 5.85 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/src/java/de/uapcore/lightpit/MenuEntry.java Sat Dec 16 20:19:28 2017 +0100 6.3 @@ -0,0 +1,87 @@ 6.4 +/* 6.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 6.6 + * 6.7 + * Copyright 2017 Mike Becker. All rights reserved. 6.8 + * 6.9 + * Redistribution and use in source and binary forms, with or without 6.10 + * modification, are permitted provided that the following conditions are met: 6.11 + * 6.12 + * 1. Redistributions of source code must retain the above copyright 6.13 + * notice, this list of conditions and the following disclaimer. 6.14 + * 6.15 + * 2. Redistributions in binary form must reproduce the above copyright 6.16 + * notice, this list of conditions and the following disclaimer in the 6.17 + * documentation and/or other materials provided with the distribution. 6.18 + * 6.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 6.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 6.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 6.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 6.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 6.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 6.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 6.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 6.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 6.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 6.29 + * POSSIBILITY OF SUCH DAMAGE. 6.30 + * 6.31 + */ 6.32 +package de.uapcore.lightpit; 6.33 + 6.34 +/** 6.35 + * Maps a resource key for the menu label to the path name for the underlying 6.36 + * site. 6.37 + * 6.38 + * Objects of this class are internally instantiated by the 6.39 + * {@link ModuleManager}. 6.40 + */ 6.41 +public class MenuEntry { 6.42 + 6.43 + private ResourceKey resourceKey; 6.44 + private String pathName; 6.45 + 6.46 + public MenuEntry() { 6.47 + } 6.48 + 6.49 + public MenuEntry(ResourceKey resourceKey, String pathName) { 6.50 + this.resourceKey = resourceKey; 6.51 + this.pathName = pathName; 6.52 + } 6.53 + 6.54 + /** 6.55 + * Sets the resource key, which is used to look up the menu label. 6.56 + * 6.57 + * @param resourceKey the key for the resource bundle 6.58 + */ 6.59 + public void setResourceKey(ResourceKey resourceKey) { 6.60 + this.resourceKey = resourceKey; 6.61 + } 6.62 + 6.63 + /** 6.64 + * Retrieves the resource key. 6.65 + * 6.66 + * @return the key for the resource bundle 6.67 + */ 6.68 + public ResourceKey getResourceKey() { 6.69 + return resourceKey; 6.70 + } 6.71 + 6.72 + /** 6.73 + * Sets the path name of the web page accessed via this menu entry. 6.74 + * 6.75 + * @param pathName path name relative to the context path 6.76 + */ 6.77 + public void setPathName(String pathName) { 6.78 + this.pathName = pathName; 6.79 + } 6.80 + 6.81 + /** 6.82 + * Retrieves the path name of the web page accessed via this menu entry. 6.83 + * 6.84 + * @return path name relative to the context path 6.85 + */ 6.86 + public String getPathName() { 6.87 + return pathName; 6.88 + } 6.89 + 6.90 +}
7.1 --- a/src/java/de/uapcore/lightpit/ModuleManager.java Fri Dec 15 17:39:54 2017 +0100 7.2 +++ b/src/java/de/uapcore/lightpit/ModuleManager.java Sat Dec 16 20:19:28 2017 +0100 7.3 @@ -28,6 +28,10 @@ 7.4 */ 7.5 package de.uapcore.lightpit; 7.6 7.7 +import java.util.ArrayList; 7.8 +import java.util.Collections; 7.9 +import java.util.List; 7.10 +import java.util.Optional; 7.11 import javax.servlet.Registration; 7.12 import javax.servlet.ServletContext; 7.13 import javax.servlet.ServletContextEvent; 7.14 @@ -40,7 +44,7 @@ 7.15 * Scans registered servlets for LightPIT modules. 7.16 */ 7.17 @WebListener 7.18 -public class ModuleManager implements ServletContextListener { 7.19 +public final class ModuleManager implements ServletContextListener { 7.20 7.21 private static final Logger LOG = LoggerFactory.getLogger(ModuleManager.class); 7.22 7.23 @@ -48,8 +52,10 @@ 7.24 * The attribute name in the servlet context under which an instance of this class can be found. 7.25 */ 7.26 public static final String SC_ATTR_NAME = ModuleManager.class.getName(); 7.27 + private ServletContext sc; 7.28 7.29 - private ServletContext sc; 7.30 + private final List<Menu> mainMenu = new ArrayList<>(); 7.31 + private final List<Menu> immutableMainMenu = Collections.unmodifiableList(mainMenu); 7.32 7.33 @Override 7.34 public void contextInitialized(ServletContextEvent sce) { 7.35 @@ -61,12 +67,10 @@ 7.36 7.37 @Override 7.38 public void contextDestroyed(ServletContextEvent sce) { 7.39 - assert sc != null && sc.equals(sce.getServletContext()); 7.40 - sc.removeAttribute(SC_ATTR_NAME); 7.41 unloadAll(); 7.42 } 7.43 7.44 - private boolean isRegisteredAsModule(Registration reg) { 7.45 + private Optional<LightPITModule> getModuleInfo(Registration reg) { 7.46 try { 7.47 final Class scclass = Class.forName(reg.getClassName()); 7.48 7.49 @@ -86,19 +90,36 @@ 7.50 ); 7.51 } 7.52 7.53 - return lpservlet && lpmodule; 7.54 + if (lpservlet && lpmodule) { 7.55 + final Class<? extends AbstractLightPITServlet> clazz = scclass; 7.56 + final LightPITModule moduleInfo = clazz.getAnnotation(LightPITModule.class); 7.57 + return Optional.of(moduleInfo); 7.58 + } else { 7.59 + return Optional.empty(); 7.60 + } 7.61 } catch (ClassNotFoundException ex) { 7.62 LOG.error( 7.63 "Servlet registration refers to class {} which cannot be found by the class loader (Reason: {})", 7.64 reg.getClassName(), 7.65 ex.getMessage() 7.66 ); 7.67 - return false; 7.68 + return Optional.empty(); 7.69 } 7.70 } 7.71 7.72 + private void addModuleToMenu(LightPITModule moduleInfo) { 7.73 + final Menu menu = new Menu( 7.74 + new ResourceKey(moduleInfo.bundleBaseName(), moduleInfo.menuKey()), 7.75 + moduleInfo.modulePath() 7.76 + ); 7.77 + mainMenu.add(menu); 7.78 + } 7.79 + 7.80 private void handleServletRegistration(String name, Registration reg) { 7.81 - if (isRegisteredAsModule(reg)) { 7.82 + final Optional<LightPITModule> moduleInfo = getModuleInfo(reg); 7.83 + if (moduleInfo.isPresent()) { 7.84 + addModuleToMenu(moduleInfo.get()); 7.85 + 7.86 LOG.info("Module detected: {}", name); 7.87 } else { 7.88 LOG.debug("Servlet {} is no module, skipping.", name); 7.89 @@ -117,6 +138,15 @@ 7.90 * Unloads all found modules. 7.91 */ 7.92 public void unloadAll() { 7.93 + mainMenu.clear(); 7.94 LOG.info("All modules unloaded."); 7.95 } 7.96 + 7.97 + /** 7.98 + * Returns the main menu. 7.99 + * @return a list of menus belonging to the main menu 7.100 + */ 7.101 + public List<Menu> getMainMenu() { 7.102 + return immutableMainMenu; 7.103 + } 7.104 }
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/src/java/de/uapcore/lightpit/ResourceKey.java Sat Dec 16 20:19:28 2017 +0100 8.3 @@ -0,0 +1,62 @@ 8.4 +/* 8.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 8.6 + * 8.7 + * Copyright 2017 Mike Becker. All rights reserved. 8.8 + * 8.9 + * Redistribution and use in source and binary forms, with or without 8.10 + * modification, are permitted provided that the following conditions are met: 8.11 + * 8.12 + * 1. Redistributions of source code must retain the above copyright 8.13 + * notice, this list of conditions and the following disclaimer. 8.14 + * 8.15 + * 2. Redistributions in binary form must reproduce the above copyright 8.16 + * notice, this list of conditions and the following disclaimer in the 8.17 + * documentation and/or other materials provided with the distribution. 8.18 + * 8.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 8.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 8.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 8.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 8.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 8.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 8.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 8.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 8.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 8.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 8.29 + * POSSIBILITY OF SUCH DAMAGE. 8.30 + * 8.31 + */ 8.32 +package de.uapcore.lightpit; 8.33 + 8.34 +/** 8.35 + * Fully specifies a resource key by the bundle and the key name. 8.36 + */ 8.37 +public final class ResourceKey { 8.38 + private String bundle; 8.39 + private String key; 8.40 + 8.41 + public ResourceKey() { 8.42 + 8.43 + } 8.44 + 8.45 + public ResourceKey(String bundle, String key) { 8.46 + this.bundle = bundle; 8.47 + this.key = key; 8.48 + } 8.49 + 8.50 + public void setBundle(String bundle) { 8.51 + this.bundle = bundle; 8.52 + } 8.53 + 8.54 + public String getBundle() { 8.55 + return bundle; 8.56 + } 8.57 + 8.58 + public void setKey(String key) { 8.59 + this.key = key; 8.60 + } 8.61 + 8.62 + public String getKey() { 8.63 + return key; 8.64 + } 8.65 +}
9.1 --- a/src/java/de/uapcore/lightpit/modules/HomeModule.java Fri Dec 15 17:39:54 2017 +0100 9.2 +++ b/src/java/de/uapcore/lightpit/modules/HomeModule.java Sat Dec 16 20:19:28 2017 +0100 9.3 @@ -28,7 +28,6 @@ 9.4 */ 9.5 package de.uapcore.lightpit.modules; 9.6 9.7 -import de.uapcore.lightpit.Constants; 9.8 import de.uapcore.lightpit.LightPITModule; 9.9 import de.uapcore.lightpit.AbstractLightPITServlet; 9.10 import javax.servlet.annotation.WebServlet; 9.11 @@ -37,12 +36,13 @@ 9.12 * Entry point for the application. 9.13 */ 9.14 @LightPITModule( 9.15 - bundleBaseName = "de.uapcore.lightpit.resources.home_localization" 9.16 + bundleBaseName = "de.uapcore.lightpit.resources.localization.home", 9.17 + modulePath = "home" 9.18 ) 9.19 @WebServlet( 9.20 name = "HomeModule", 9.21 - urlPatterns = Constants.HOME_NODE+"*" 9.22 + urlPatterns = "/home/*" 9.23 ) 9.24 -public class HomeModule extends AbstractLightPITServlet { 9.25 +public final class HomeModule extends AbstractLightPITServlet { 9.26 9.27 }
10.1 --- a/src/java/de/uapcore/lightpit/modules/VersionsModule.java Fri Dec 15 17:39:54 2017 +0100 10.2 +++ b/src/java/de/uapcore/lightpit/modules/VersionsModule.java Sat Dec 16 20:19:28 2017 +0100 10.3 @@ -34,12 +34,13 @@ 10.4 10.5 10.6 @LightPITModule( 10.7 - bundleBaseName = "de.uapcore.lightpit.resources.versions_localization" 10.8 + bundleBaseName = "de.uapcore.lightpit.resources.localization.versions", 10.9 + modulePath = "versions" 10.10 ) 10.11 @WebServlet( 10.12 name = "VersionsModule", 10.13 urlPatterns = "/versions/*" 10.14 ) 10.15 -public class VersionsModule extends AbstractLightPITServlet { 10.16 +public final class VersionsModule extends AbstractLightPITServlet { 10.17 10.18 }
11.1 --- a/src/java/de/uapcore/lightpit/resources/home_localization.properties Fri Dec 15 17:39:54 2017 +0100 11.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 11.3 @@ -1,24 +0,0 @@ 11.4 -# Copyright 2017 Mike Becker. All rights reserved. 11.5 -# 11.6 -# Redistribution and use in source and binary forms, with or without 11.7 -# modification, are permitted provided that the following conditions are met: 11.8 -# 11.9 -# 1. Redistributions of source code must retain the above copyright 11.10 -# notice, this list of conditions and the following disclaimer. 11.11 -# 11.12 -# 2. Redistributions in binary form must reproduce the above copyright 11.13 -# notice, this list of conditions and the following disclaimer in the 11.14 -# documentation and/or other materials provided with the distribution. 11.15 -# 11.16 -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 11.17 -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 11.18 -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 11.19 -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 11.20 -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 11.21 -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 11.22 -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 11.23 -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 11.24 -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 11.25 -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 11.26 - 11.27 -home.title = Start Page
12.1 --- a/src/java/de/uapcore/lightpit/resources/home_localization_de.properties Fri Dec 15 17:39:54 2017 +0100 12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 12.3 @@ -1,24 +0,0 @@ 12.4 -# Copyright 2017 Mike Becker. All rights reserved. 12.5 -# 12.6 -# Redistribution and use in source and binary forms, with or without 12.7 -# modification, are permitted provided that the following conditions are met: 12.8 -# 12.9 -# 1. Redistributions of source code must retain the above copyright 12.10 -# notice, this list of conditions and the following disclaimer. 12.11 -# 12.12 -# 2. Redistributions in binary form must reproduce the above copyright 12.13 -# notice, this list of conditions and the following disclaimer in the 12.14 -# documentation and/or other materials provided with the distribution. 12.15 -# 12.16 -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 12.17 -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 12.18 -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 12.19 -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 12.20 -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 12.21 -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 12.22 -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 12.23 -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 12.24 -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 12.25 -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 12.26 - 12.27 -home.title = Startseite
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/src/java/de/uapcore/lightpit/resources/localization/home.properties Sat Dec 16 20:19:28 2017 +0100 13.3 @@ -0,0 +1,24 @@ 13.4 +# Copyright 2017 Mike Becker. All rights reserved. 13.5 +# 13.6 +# Redistribution and use in source and binary forms, with or without 13.7 +# modification, are permitted provided that the following conditions are met: 13.8 +# 13.9 +# 1. Redistributions of source code must retain the above copyright 13.10 +# notice, this list of conditions and the following disclaimer. 13.11 +# 13.12 +# 2. Redistributions in binary form must reproduce the above copyright 13.13 +# notice, this list of conditions and the following disclaimer in the 13.14 +# documentation and/or other materials provided with the distribution. 13.15 +# 13.16 +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 13.17 +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 13.18 +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 13.19 +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 13.20 +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 13.21 +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 13.22 +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 13.23 +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 13.24 +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 13.25 +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13.26 + 13.27 +menuLabel = Home
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/src/java/de/uapcore/lightpit/resources/localization/home_de.properties Sat Dec 16 20:19:28 2017 +0100 14.3 @@ -0,0 +1,24 @@ 14.4 +# Copyright 2017 Mike Becker. All rights reserved. 14.5 +# 14.6 +# Redistribution and use in source and binary forms, with or without 14.7 +# modification, are permitted provided that the following conditions are met: 14.8 +# 14.9 +# 1. Redistributions of source code must retain the above copyright 14.10 +# notice, this list of conditions and the following disclaimer. 14.11 +# 14.12 +# 2. Redistributions in binary form must reproduce the above copyright 14.13 +# notice, this list of conditions and the following disclaimer in the 14.14 +# documentation and/or other materials provided with the distribution. 14.15 +# 14.16 +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 14.17 +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14.18 +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 14.19 +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 14.20 +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 14.21 +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 14.22 +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 14.23 +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 14.24 +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 14.25 +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 14.26 + 14.27 +menuLabel = Startseite
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/src/java/de/uapcore/lightpit/resources/localization/versions.properties Sat Dec 16 20:19:28 2017 +0100 15.3 @@ -0,0 +1,24 @@ 15.4 +# Copyright 2017 Mike Becker. All rights reserved. 15.5 +# 15.6 +# Redistribution and use in source and binary forms, with or without 15.7 +# modification, are permitted provided that the following conditions are met: 15.8 +# 15.9 +# 1. Redistributions of source code must retain the above copyright 15.10 +# notice, this list of conditions and the following disclaimer. 15.11 +# 15.12 +# 2. Redistributions in binary form must reproduce the above copyright 15.13 +# notice, this list of conditions and the following disclaimer in the 15.14 +# documentation and/or other materials provided with the distribution. 15.15 +# 15.16 +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15.17 +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15.18 +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 15.19 +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 15.20 +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 15.21 +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 15.22 +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 15.23 +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 15.24 +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 15.25 +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 15.26 + 15.27 +menuLabel = Versions
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 16.2 +++ b/src/java/de/uapcore/lightpit/resources/localization/versions_de.properties Sat Dec 16 20:19:28 2017 +0100 16.3 @@ -0,0 +1,24 @@ 16.4 +# Copyright 2017 Mike Becker. All rights reserved. 16.5 +# 16.6 +# Redistribution and use in source and binary forms, with or without 16.7 +# modification, are permitted provided that the following conditions are met: 16.8 +# 16.9 +# 1. Redistributions of source code must retain the above copyright 16.10 +# notice, this list of conditions and the following disclaimer. 16.11 +# 16.12 +# 2. Redistributions in binary form must reproduce the above copyright 16.13 +# notice, this list of conditions and the following disclaimer in the 16.14 +# documentation and/or other materials provided with the distribution. 16.15 +# 16.16 +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16.17 +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16.18 +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16.19 +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 16.20 +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16.21 +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 16.22 +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 16.23 +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 16.24 +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 16.25 +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 16.26 + 16.27 +menuLabel = Versionen
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/web/WEB-INF/view/full.jsp Sat Dec 16 20:19:28 2017 +0100 17.3 @@ -0,0 +1,69 @@ 17.4 +<%-- 17.5 +DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 17.6 + 17.7 +Copyright 2017 Mike Becker. All rights reserved. 17.8 + 17.9 +Redistribution and use in source and binary forms, with or without 17.10 +modification, are permitted provided that the following conditions are met: 17.11 + 17.12 +1. Redistributions of source code must retain the above copyright 17.13 +notice, this list of conditions and the following disclaimer. 17.14 + 17.15 +2. Redistributions in binary form must reproduce the above copyright 17.16 +notice, this list of conditions and the following disclaimer in the 17.17 +documentation and/or other materials provided with the distribution. 17.18 + 17.19 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17.20 +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17.21 +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17.22 +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 17.23 +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 17.24 +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 17.25 +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 17.26 +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 17.27 +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 17.28 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 17.29 +--%> 17.30 +<%@page contentType="text/html" pageEncoding="UTF-8" trimDirectiveWhitespaces="true" %> 17.31 +<%@page import="de.uapcore.lightpit.Constants" %> 17.32 +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 17.33 +<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> 17.34 +<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> 17.35 + 17.36 +<%-- Define an alias for the main menu --%> 17.37 +<c:set scope="page" var="mainMenu" value="${requestScope[Constants.REQ_ATTR_MENU]}"/> 17.38 + 17.39 +<!DOCTYPE html> 17.40 +<html> 17.41 + <head> 17.42 + <base href="${pageContext.request.scheme}://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/"> 17.43 + <title>LightPIT - TODO: current menu</title> 17.44 + <meta charset="UTF-8"> 17.45 + <link rel="stylesheet" href="lightpit.css" type="text/css"> 17.46 + </head> 17.47 + <body> 17.48 + 17.49 + <div id="mainMenu"> 17.50 + <c:forEach var="menuEntry" items="${mainMenu}"> 17.51 + <div class="menuEntry" 17.52 + <c:if test="${fn:contains(requestScope[Constants.REQ_ATTR_PATH], menuEntry.pathName)}"> 17.53 + data-active 17.54 + </c:if> 17.55 + > 17.56 + <a href="${menuEntry.pathName}"> 17.57 + <fmt:bundle basename="${menuEntry.resourceKey.bundle}"> 17.58 + <fmt:message key="${menuEntry.resourceKey.key}" /> 17.59 + </fmt:bundle> 17.60 + </a> 17.61 + </div> 17.62 + </c:forEach> 17.63 + 17.64 + </div> 17.65 + <div id="subMenu"> 17.66 + 17.67 + </div> 17.68 + <div id="content-area"> 17.69 + TODO: content fragment 17.70 + </div> 17.71 + </body> 17.72 +</html>
18.1 --- a/web/WEB-INF/view/home.jsp Fri Dec 15 17:39:54 2017 +0100 18.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 18.3 @@ -1,43 +0,0 @@ 18.4 -<%-- 18.5 -DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 18.6 - 18.7 -Copyright 2017 Mike Becker. All rights reserved. 18.8 - 18.9 -Redistribution and use in source and binary forms, with or without 18.10 -modification, are permitted provided that the following conditions are met: 18.11 - 18.12 -1. Redistributions of source code must retain the above copyright 18.13 -notice, this list of conditions and the following disclaimer. 18.14 - 18.15 -2. Redistributions in binary form must reproduce the above copyright 18.16 -notice, this list of conditions and the following disclaimer in the 18.17 -documentation and/or other materials provided with the distribution. 18.18 - 18.19 -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18.20 -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18.21 -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18.22 -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18.23 -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18.24 -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 18.25 -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 18.26 -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 18.27 -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 18.28 -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 18.29 ---%> 18.30 -<%@page contentType="text/html" pageEncoding="UTF-8" 18.31 - trimDirectiveWhitespaces="true" %> 18.32 -<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> 18.33 - 18.34 -<fmt:setBundle basename="de.uapcore.lightpit.resources.home_localization" 18.35 - var="bundle" /> 18.36 - 18.37 -<!DOCTYPE html> 18.38 -<html> 18.39 - <head> 18.40 - <title>LightPIT - <fmt:message key="home.title" bundle="${bundle}" /></title> 18.41 - <meta charset="UTF-8"> 18.42 - </head> 18.43 - <body> 18.44 - <div>It will work, someday...</div> 18.45 - </body> 18.46 -</html>
19.1 --- a/web/index.jsp Fri Dec 15 17:39:54 2017 +0100 19.2 +++ b/web/index.jsp Sat Dec 16 20:19:28 2017 +0100 19.3 @@ -24,8 +24,9 @@ 19.4 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 19.5 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 19.6 --%> 19.7 -<%@page import="de.uapcore.lightpit.Constants" %> 19.8 +<%@page import="de.uapcore.lightpit.Functions" %> 19.9 +<%@page import="de.uapcore.lightpit.modules.HomeModule" %> 19.10 <% 19.11 response.setStatus(response.SC_MOVED_TEMPORARILY); 19.12 -response.setHeader("Location", "."+Constants.HOME_NODE); 19.13 +response.setHeader("Location", "./"+Functions.modulePathOf(HomeModule.class)); 19.14 %>
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/web/lightpit.css Sat Dec 16 20:19:28 2017 +0100 20.3 @@ -0,0 +1,85 @@ 20.4 +/* 20.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 20.6 + * 20.7 + * Copyright 2017 Mike Becker. All rights reserved. 20.8 + * 20.9 + * Redistribution and use in source and binary forms, with or without 20.10 + * modification, are permitted provided that the following conditions are met: 20.11 + * 20.12 + * 1. Redistributions of source code must retain the above copyright 20.13 + * notice, this list of conditions and the following disclaimer. 20.14 + * 20.15 + * 2. Redistributions in binary form must reproduce the above copyright 20.16 + * notice, this list of conditions and the following disclaimer in the 20.17 + * documentation and/or other materials provided with the distribution. 20.18 + * 20.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 20.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 20.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 20.29 + * POSSIBILITY OF SUCH DAMAGE. 20.30 + * 20.31 + */ 20.32 + 20.33 +html { 20.34 + background: #f8f8f8; 20.35 +} 20.36 + 20.37 +body { 20.38 + background: white; 20.39 + font-family: sans-serif; 20.40 + 20.41 + border-color: #505050; 20.42 + border-style: solid; 20.43 + border-width: 1pt; 20.44 + 20.45 + color: black; 20.46 +} 20.47 + 20.48 +a { 20.49 + color: #3030f8; 20.50 + text-decoration: none; 20.51 +} 20.52 + 20.53 +#mainMenu, #mainMenuEntries { 20.54 + width: 100%; 20.55 + display: flex; 20.56 + flex-flow: row wrap; 20.57 +} 20.58 + 20.59 +#mainMenu { 20.60 + background: #f0f0f5; 20.61 +} 20.62 + 20.63 +#subMenu { 20.64 + background: #f7f7ff; 20.65 + 20.66 + border-image: linear-gradient(to right, #606060, rgba(60,60,60,.1)); 20.67 + border-image-slice: 1; 20.68 + border-top-style: solid; 20.69 + border-top-width: 1pt; 20.70 + border-bottom-style: solid; 20.71 + border-bottom-width: 1pt; 20.72 +} 20.73 + 20.74 +.menuEntry { 20.75 + padding: .25em 1em .25em 1em; 20.76 +} 20.77 + 20.78 +#mainMenu .menuEntry[data-active] { 20.79 + background: #e0e0e5; 20.80 +} 20.81 + 20.82 +#subMenu .menuEntry[data-active] { 20.83 + background: #e7e7ef 20.84 +} 20.85 + 20.86 +#content-area { 20.87 + padding: 1em; 20.88 +}