implements automatic menu generation from module information

Sat, 16 Dec 2017 20:19:28 +0100

author
Mike Becker <universe@uap-core.de>
date
Sat, 16 Dec 2017 20:19:28 +0100
changeset 10
89e3e6e28b69
parent 9
20a9b2bc9063
child 11
737ab27e37b3

implements automatic menu generation from module information

src/java/de/uapcore/lightpit/AbstractLightPITServlet.java file | annotate | diff | comparison | revisions
src/java/de/uapcore/lightpit/Constants.java file | annotate | diff | comparison | revisions
src/java/de/uapcore/lightpit/Functions.java file | annotate | diff | comparison | revisions
src/java/de/uapcore/lightpit/LightPITModule.java file | annotate | diff | comparison | revisions
src/java/de/uapcore/lightpit/Menu.java file | annotate | diff | comparison | revisions
src/java/de/uapcore/lightpit/MenuEntry.java file | annotate | diff | comparison | revisions
src/java/de/uapcore/lightpit/ModuleManager.java file | annotate | diff | comparison | revisions
src/java/de/uapcore/lightpit/ResourceKey.java file | annotate | diff | comparison | revisions
src/java/de/uapcore/lightpit/modules/HomeModule.java file | annotate | diff | comparison | revisions
src/java/de/uapcore/lightpit/modules/VersionsModule.java file | annotate | diff | comparison | revisions
src/java/de/uapcore/lightpit/resources/home_localization.properties file | annotate | diff | comparison | revisions
src/java/de/uapcore/lightpit/resources/home_localization_de.properties file | annotate | diff | comparison | revisions
src/java/de/uapcore/lightpit/resources/localization/home.properties file | annotate | diff | comparison | revisions
src/java/de/uapcore/lightpit/resources/localization/home_de.properties file | annotate | diff | comparison | revisions
src/java/de/uapcore/lightpit/resources/localization/versions.properties file | annotate | diff | comparison | revisions
src/java/de/uapcore/lightpit/resources/localization/versions_de.properties file | annotate | diff | comparison | revisions
web/WEB-INF/view/full.jsp file | annotate | diff | comparison | revisions
web/WEB-INF/view/home.jsp file | annotate | diff | comparison | revisions
web/index.jsp file | annotate | diff | comparison | revisions
web/lightpit.css file | annotate | diff | comparison | revisions
--- a/src/java/de/uapcore/lightpit/AbstractLightPITServlet.java	Fri Dec 15 17:39:54 2017 +0100
+++ b/src/java/de/uapcore/lightpit/AbstractLightPITServlet.java	Sat Dec 16 20:19:28 2017 +0100
@@ -33,6 +33,8 @@
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * A special implementation of a HTTPServlet which is focused on implementing
@@ -40,16 +42,43 @@
  */
 public abstract class AbstractLightPITServlet extends HttpServlet {
     
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractLightPITServlet.class);
+
+    
+    /**
+     * Gives implementing modules access to the {@link ModuleManager}.
+     * @return the module manager
+     */
+    protected final ModuleManager getModuleManager() {
+        return (ModuleManager) getServletContext().getAttribute(ModuleManager.SC_ATTR_NAME);
+    }
+    
+    private void addPathInformation(HttpServletRequest req) {
+        final String path = req.getServletPath()+"/"+req.getPathInfo();
+        req.setAttribute(Constants.REQ_ATTR_PATH, path);
+    }
+    
+    private void forwardToFullView(HttpServletRequest req, HttpServletResponse resp)
+            throws IOException, ServletException {
+        
+        addPathInformation(req);
+        
+        final ModuleManager mm = getModuleManager();
+        req.setAttribute(Constants.REQ_ATTR_MENU, mm.getMainMenu());
+        
+        req.getRequestDispatcher(Functions.jspPath("full.jsp")).forward(req, resp);
+    }
+    
     @Override
     protected final void doGet(HttpServletRequest req, HttpServletResponse resp)
             throws ServletException, IOException {
-        
-        resp.getWriter().println("It works!");
+        forwardToFullView(req, resp);
     }
 
     @Override
     protected final void doPost(HttpServletRequest req, HttpServletResponse resp)
             throws ServletException, IOException {
+        
+        forwardToFullView(req, resp);
     }
-    
 }
--- a/src/java/de/uapcore/lightpit/Constants.java	Fri Dec 15 17:39:54 2017 +0100
+++ b/src/java/de/uapcore/lightpit/Constants.java	Sat Dec 16 20:19:28 2017 +0100
@@ -28,11 +28,19 @@
  */
 package de.uapcore.lightpit;
 
+import static de.uapcore.lightpit.Functions.fullyQualifiedName;
+
 /**
  * Contains all constants used by the this application.
  */
-public abstract class Constants {
-    public static final String HOME_NODE = "/home/";
+public final class Constants {
+    public static final String JSP_PATH_PREFIX = "/WEB-INF/view/";
+    
+    public static final String REQ_ATTR_MENU = fullyQualifiedName(AbstractLightPITServlet.class, "mainMenu");
+    public static final String REQ_ATTR_PATH = fullyQualifiedName(AbstractLightPITServlet.class, "path");
     
-    public static final String JSP_PATH_PREFIX = "/WEB-INF/view/";
+    /**
+     * This class is not instantiatable.
+     */
+    private Constants() {}
 }
--- a/src/java/de/uapcore/lightpit/Functions.java	Fri Dec 15 17:39:54 2017 +0100
+++ b/src/java/de/uapcore/lightpit/Functions.java	Sat Dec 16 20:19:28 2017 +0100
@@ -28,12 +28,52 @@
  */
 package de.uapcore.lightpit;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 /**
  * Contains common static functions.
  */
-public class Functions {
+public final class Functions {
+    
+    private static final Logger LOG = LoggerFactory.getLogger(Functions.class);
 
     public static String jspPath(String filename) {
         return Constants.JSP_PATH_PREFIX + filename;
     }
+    
+    public static String fullyQualifiedName(String base, String name) {
+        return base+"."+name;
+    }
+    
+    public static String fullyQualifiedName(Class clazz, String name) {
+        return fullyQualifiedName(clazz.getName(), name);
+    }
+    
+    /**
+     * Returns the module path of the given LightPIT Servlet module.
+     * 
+     * If you specify a malformed LightPIT servlet, which does not have a module
+     * annotation, the path to the <code>/error/404.html</code> page is returned.
+     * 
+     * @param clazz the servlet class
+     * @return the module path
+     */
+    public static String modulePathOf(Class<? extends AbstractLightPITServlet> clazz) {
+        LightPITModule moduleInfo = clazz.getAnnotation(LightPITModule.class);
+        if (moduleInfo == null) {
+            LOG.warn(
+                    "{} is a LightPIT Servlet but is missing the module annotation.",
+                    clazz.getName()
+            );
+            return "/error/404.html";
+        } else {
+            return moduleInfo.modulePath();
+        }
+    }
+    
+    /**
+     * This class is not instantiatable.
+     */
+    private Functions() {}
 }
--- a/src/java/de/uapcore/lightpit/LightPITModule.java	Fri Dec 15 17:39:54 2017 +0100
+++ b/src/java/de/uapcore/lightpit/LightPITModule.java	Sat Dec 16 20:19:28 2017 +0100
@@ -58,4 +58,20 @@
      * @return an array of class names of required modules
      */
     String[] requires() default {};
+    
+    /**
+     * The path for this module, which will be used for the menu entry.
+     * 
+     * This path must adhere to the URL pattern of the Servlet but must not
+     * contain any starting or trailing slashes.
+     * 
+     * @return the relative module path
+     */
+    String modulePath();
+    
+    /**
+     * Returns the properties key for the menu label.
+     * @return the properties key relative to the base name
+     */
+    String menuKey() default "menuLabel";
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java/de/uapcore/lightpit/Menu.java	Sat Dec 16 20:19:28 2017 +0100
@@ -0,0 +1,82 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2017 Mike Becker. 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.
+ *
+ * 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 COPYRIGHT HOLDER 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.
+ * 
+ */
+package de.uapcore.lightpit;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Maps a resource key for the menu label to the path name for the underlying
+ * site.
+ * 
+ * Objects of this class are internally instantiated by the
+ * {@link ModuleManager}.
+ */
+public class Menu extends MenuEntry {
+    
+    private final List<MenuEntry> entries = new ArrayList<>();
+    private final List<MenuEntry> immutableEntries = Collections.unmodifiableList(entries);
+    
+    public Menu() {
+        super();
+    }
+    
+    public Menu(ResourceKey resourceKey, String pathName) {
+        super(resourceKey, pathName);
+    }
+
+    /**
+     * Sets a new list of menu entries for this menu.
+     * 
+     * @param entries the list of new menu entries
+     */
+    public void setEntries(List<MenuEntry> entries) {
+        // in case the given list is immutable, we copy the contents
+        this.entries.clear();
+        this.entries.addAll(entries);
+    }
+
+    /**
+     * Retrieves an immutable list of menu entries for this menu.
+     * 
+     * @return the list of menu entries
+     */
+    public List<MenuEntry> getEntries() {
+        return immutableEntries;
+    }
+    
+    /**
+     * Adds a new menu entry to this menu.
+     * @param entry the menu entry to add
+     */
+    public void addMenuEntry(MenuEntry entry) {
+        entries.add(entry);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java/de/uapcore/lightpit/MenuEntry.java	Sat Dec 16 20:19:28 2017 +0100
@@ -0,0 +1,87 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2017 Mike Becker. 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.
+ *
+ * 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 COPYRIGHT HOLDER 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.
+ * 
+ */
+package de.uapcore.lightpit;
+
+/**
+ * Maps a resource key for the menu label to the path name for the underlying
+ * site.
+ * 
+ * Objects of this class are internally instantiated by the
+ * {@link ModuleManager}.
+ */
+public class MenuEntry {
+    
+    private ResourceKey resourceKey;
+    private String pathName;
+
+    public MenuEntry() {
+    }
+
+    public MenuEntry(ResourceKey resourceKey, String pathName) {
+        this.resourceKey = resourceKey;
+        this.pathName = pathName;
+    }
+
+    /**
+     * Sets the resource key, which is used to look up the menu label.
+     * 
+     * @param resourceKey the key for the resource bundle
+     */
+    public void setResourceKey(ResourceKey resourceKey) {
+        this.resourceKey = resourceKey;
+    }
+
+    /**
+     * Retrieves the resource key.
+     * 
+     * @return the key for the resource bundle
+     */
+    public ResourceKey getResourceKey() {
+        return resourceKey;
+    }
+
+    /**
+     * Sets the path name of the web page accessed via this menu entry.
+     * 
+     * @param pathName path name relative to the context path
+     */
+    public void setPathName(String pathName) {
+        this.pathName = pathName;
+    }
+
+    /**
+     * Retrieves the path name of the web page accessed via this menu entry.
+     * 
+     * @return path name relative to the context path
+     */
+    public String getPathName() {
+        return pathName;
+    }
+    
+}
--- a/src/java/de/uapcore/lightpit/ModuleManager.java	Fri Dec 15 17:39:54 2017 +0100
+++ b/src/java/de/uapcore/lightpit/ModuleManager.java	Sat Dec 16 20:19:28 2017 +0100
@@ -28,6 +28,10 @@
  */
 package de.uapcore.lightpit;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
 import javax.servlet.Registration;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletContextEvent;
@@ -40,7 +44,7 @@
  * Scans registered servlets for LightPIT modules.
  */
 @WebListener
-public class ModuleManager implements ServletContextListener {
+public final class ModuleManager implements ServletContextListener {
     
     private static final Logger LOG = LoggerFactory.getLogger(ModuleManager.class);
     
@@ -48,8 +52,10 @@
      * The attribute name in the servlet context under which an instance of this class can be found.
      */
     public static final String SC_ATTR_NAME = ModuleManager.class.getName();
+    private ServletContext sc;
     
-    private ServletContext sc;
+    private final List<Menu> mainMenu = new ArrayList<>();
+    private final List<Menu> immutableMainMenu = Collections.unmodifiableList(mainMenu);
     
     @Override
     public void contextInitialized(ServletContextEvent sce) {
@@ -61,12 +67,10 @@
 
     @Override
     public void contextDestroyed(ServletContextEvent sce) {
-        assert sc != null && sc.equals(sce.getServletContext());
-        sc.removeAttribute(SC_ATTR_NAME);
         unloadAll();
     }
     
-    private boolean isRegisteredAsModule(Registration reg) {
+    private Optional<LightPITModule> getModuleInfo(Registration reg) {
         try {
             final Class scclass = Class.forName(reg.getClassName());
             
@@ -86,19 +90,36 @@
                 );
             }
             
-            return lpservlet && lpmodule;
+            if (lpservlet && lpmodule) {
+                final Class<? extends AbstractLightPITServlet> clazz = scclass;
+                final LightPITModule moduleInfo = clazz.getAnnotation(LightPITModule.class);
+                return Optional.of(moduleInfo);
+            } else {
+                return Optional.empty();
+            }
         } catch (ClassNotFoundException ex) {
             LOG.error(
                     "Servlet registration refers to class {} which cannot be found by the class loader (Reason: {})",
                     reg.getClassName(),
                     ex.getMessage()
             );
-            return false;
+            return Optional.empty();
         }        
     }
     
+    private void addModuleToMenu(LightPITModule moduleInfo) {
+        final Menu menu = new Menu(
+                new ResourceKey(moduleInfo.bundleBaseName(), moduleInfo.menuKey()),
+                moduleInfo.modulePath()
+        );
+        mainMenu.add(menu);
+    }
+    
     private void handleServletRegistration(String name, Registration reg) {
-        if (isRegisteredAsModule(reg)) {
+        final Optional<LightPITModule> moduleInfo = getModuleInfo(reg);
+        if (moduleInfo.isPresent()) {
+            addModuleToMenu(moduleInfo.get());
+            
             LOG.info("Module detected: {}", name);
         } else {
             LOG.debug("Servlet {} is no module, skipping.", name);
@@ -117,6 +138,15 @@
      * Unloads all found modules.
      */
     public void unloadAll() {
+        mainMenu.clear();
         LOG.info("All modules unloaded.");
     }
+
+    /**
+     * Returns the main menu.
+     * @return a list of menus belonging to the main menu
+     */
+    public List<Menu> getMainMenu() {
+        return immutableMainMenu;
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java/de/uapcore/lightpit/ResourceKey.java	Sat Dec 16 20:19:28 2017 +0100
@@ -0,0 +1,62 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2017 Mike Becker. 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.
+ *
+ * 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 COPYRIGHT HOLDER 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.
+ * 
+ */
+package de.uapcore.lightpit;
+
+/**
+ * Fully specifies a resource key by the bundle and the key name.
+ */
+public final class ResourceKey {
+    private String bundle;
+    private String key;
+    
+    public ResourceKey() {
+        
+    }
+
+    public ResourceKey(String bundle, String key) {
+        this.bundle = bundle;
+        this.key = key;
+    }
+
+    public void setBundle(String bundle) {
+        this.bundle = bundle;
+    }
+
+    public String getBundle() {
+        return bundle;
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
+    
+    public String getKey() {
+        return key;
+    }
+}
--- a/src/java/de/uapcore/lightpit/modules/HomeModule.java	Fri Dec 15 17:39:54 2017 +0100
+++ b/src/java/de/uapcore/lightpit/modules/HomeModule.java	Sat Dec 16 20:19:28 2017 +0100
@@ -28,7 +28,6 @@
  */
 package de.uapcore.lightpit.modules;
 
-import de.uapcore.lightpit.Constants;
 import de.uapcore.lightpit.LightPITModule;
 import de.uapcore.lightpit.AbstractLightPITServlet;
 import javax.servlet.annotation.WebServlet;
@@ -37,12 +36,13 @@
  * Entry point for the application.
  */
 @LightPITModule(
-        bundleBaseName = "de.uapcore.lightpit.resources.home_localization"
+        bundleBaseName = "de.uapcore.lightpit.resources.localization.home",
+        modulePath = "home"
 )
 @WebServlet(
         name = "HomeModule",
-        urlPatterns = Constants.HOME_NODE+"*"
+        urlPatterns = "/home/*"
 )
-public class HomeModule extends AbstractLightPITServlet {
+public final class HomeModule extends AbstractLightPITServlet {
     
 }
--- a/src/java/de/uapcore/lightpit/modules/VersionsModule.java	Fri Dec 15 17:39:54 2017 +0100
+++ b/src/java/de/uapcore/lightpit/modules/VersionsModule.java	Sat Dec 16 20:19:28 2017 +0100
@@ -34,12 +34,13 @@
 
 
 @LightPITModule(
-        bundleBaseName = "de.uapcore.lightpit.resources.versions_localization"
+        bundleBaseName = "de.uapcore.lightpit.resources.localization.versions",
+        modulePath = "versions"
 )
 @WebServlet(
         name = "VersionsModule",
         urlPatterns = "/versions/*"
 )
-public class VersionsModule extends AbstractLightPITServlet {
+public final class VersionsModule extends AbstractLightPITServlet {
     
 }
--- a/src/java/de/uapcore/lightpit/resources/home_localization.properties	Fri Dec 15 17:39:54 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-# Copyright 2017 Mike Becker. 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.
-#
-# 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 COPYRIGHT HOLDER 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. 
-
-home.title = Start Page
--- a/src/java/de/uapcore/lightpit/resources/home_localization_de.properties	Fri Dec 15 17:39:54 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-# Copyright 2017 Mike Becker. 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.
-#
-# 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 COPYRIGHT HOLDER 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. 
-
-home.title = Startseite
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java/de/uapcore/lightpit/resources/localization/home.properties	Sat Dec 16 20:19:28 2017 +0100
@@ -0,0 +1,24 @@
+# Copyright 2017 Mike Becker. 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.
+#
+# 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 COPYRIGHT HOLDER 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. 
+
+menuLabel = Home
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java/de/uapcore/lightpit/resources/localization/home_de.properties	Sat Dec 16 20:19:28 2017 +0100
@@ -0,0 +1,24 @@
+# Copyright 2017 Mike Becker. 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.
+#
+# 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 COPYRIGHT HOLDER 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. 
+
+menuLabel = Startseite
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java/de/uapcore/lightpit/resources/localization/versions.properties	Sat Dec 16 20:19:28 2017 +0100
@@ -0,0 +1,24 @@
+# Copyright 2017 Mike Becker. 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.
+#
+# 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 COPYRIGHT HOLDER 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. 
+
+menuLabel = Versions
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java/de/uapcore/lightpit/resources/localization/versions_de.properties	Sat Dec 16 20:19:28 2017 +0100
@@ -0,0 +1,24 @@
+# Copyright 2017 Mike Becker. 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.
+#
+# 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 COPYRIGHT HOLDER 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. 
+
+menuLabel = Versionen
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/WEB-INF/view/full.jsp	Sat Dec 16 20:19:28 2017 +0100
@@ -0,0 +1,69 @@
+<%-- 
+DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+Copyright 2017 Mike Becker. 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.
+
+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 COPYRIGHT HOLDER 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. 
+--%>
+<%@page contentType="text/html" pageEncoding="UTF-8" trimDirectiveWhitespaces="true" %>
+<%@page import="de.uapcore.lightpit.Constants" %>
+<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
+
+<%-- Define an alias for the main menu --%>
+<c:set scope="page" var="mainMenu" value="${requestScope[Constants.REQ_ATTR_MENU]}"/>
+
+<!DOCTYPE html>
+<html>
+    <head>
+        <base href="${pageContext.request.scheme}://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/">
+        <title>LightPIT - TODO: current menu</title>
+        <meta charset="UTF-8">
+        <link rel="stylesheet" href="lightpit.css" type="text/css">
+    </head>
+    <body>
+        
+        <div id="mainMenu">
+            <c:forEach var="menuEntry" items="${mainMenu}">
+                <div class="menuEntry"
+                     <c:if test="${fn:contains(requestScope[Constants.REQ_ATTR_PATH], menuEntry.pathName)}">
+                         data-active
+                     </c:if>
+                >
+                    <a href="${menuEntry.pathName}">
+                    <fmt:bundle basename="${menuEntry.resourceKey.bundle}">
+                        <fmt:message key="${menuEntry.resourceKey.key}" />
+                    </fmt:bundle>
+                    </a>
+                </div>
+            </c:forEach>
+            
+        </div>
+        <div id="subMenu">
+            
+        </div>
+        <div id="content-area">
+        TODO: content fragment
+        </div>
+    </body>
+</html>
--- a/web/WEB-INF/view/home.jsp	Fri Dec 15 17:39:54 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-<%-- 
-DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
-
-Copyright 2017 Mike Becker. 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.
-
-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 COPYRIGHT HOLDER 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. 
---%>
-<%@page contentType="text/html" pageEncoding="UTF-8"
-        trimDirectiveWhitespaces="true" %>
-<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
-
-<fmt:setBundle basename="de.uapcore.lightpit.resources.home_localization"
-               var="bundle" />
-
-<!DOCTYPE html>
-<html>
-    <head>
-        <title>LightPIT - <fmt:message key="home.title" bundle="${bundle}" /></title>
-        <meta charset="UTF-8">
-    </head>
-    <body>
-        <div>It will work, someday...</div>
-    </body>
-</html>
--- a/web/index.jsp	Fri Dec 15 17:39:54 2017 +0100
+++ b/web/index.jsp	Sat Dec 16 20:19:28 2017 +0100
@@ -24,8 +24,9 @@
 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. 
 --%>
-<%@page import="de.uapcore.lightpit.Constants" %>
+<%@page import="de.uapcore.lightpit.Functions" %>
+<%@page import="de.uapcore.lightpit.modules.HomeModule" %>
 <%
 response.setStatus(response.SC_MOVED_TEMPORARILY);
-response.setHeader("Location", "."+Constants.HOME_NODE);
+response.setHeader("Location", "./"+Functions.modulePathOf(HomeModule.class));
 %>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/lightpit.css	Sat Dec 16 20:19:28 2017 +0100
@@ -0,0 +1,85 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2017 Mike Becker. 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.
+ *
+ * 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 COPYRIGHT HOLDER 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.
+ * 
+ */
+
+html {
+    background: #f8f8f8;
+}
+
+body {
+    background: white;
+    font-family: sans-serif;
+    
+    border-color: #505050;
+    border-style: solid;
+    border-width: 1pt;
+    
+    color: black;
+}
+
+a {
+    color: #3030f8;
+    text-decoration: none;
+}
+
+#mainMenu, #mainMenuEntries {
+    width: 100%;
+    display: flex;
+    flex-flow: row wrap;
+}
+
+#mainMenu {
+    background: #f0f0f5;
+}
+
+#subMenu {
+    background: #f7f7ff;
+
+    border-image: linear-gradient(to right, #606060, rgba(60,60,60,.1));
+    border-image-slice: 1;
+    border-top-style: solid;
+    border-top-width: 1pt;
+    border-bottom-style: solid;
+    border-bottom-width: 1pt;
+}
+
+.menuEntry {
+    padding: .25em 1em .25em 1em;
+}
+
+#mainMenu .menuEntry[data-active] {
+    background: #e0e0e5;
+}
+
+#subMenu .menuEntry[data-active] {
+    background: #e7e7ef
+}
+
+#content-area {
+    padding: 1em;
+}

mercurial