click-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From med...@apache.org
Subject svn commit: r927042 - in /click/trunk/click: extras/src/org/apache/click/extras/control/ template/src/template/page/
Date Wed, 24 Mar 2010 13:03:24 GMT
Author: medgar
Date: Wed Mar 24 13:03:24 2010
New Revision: 927042

URL: http://svn.apache.org/viewvc?rev=927042&view=rev
Log:
Menu refactoring to use MenuFactory pattern, added support for loading arbitary attributes
e.g. as visible and enabled from the XML.

Added:
    click/trunk/click/extras/src/org/apache/click/extras/control/MenuFactory.java
Modified:
    click/trunk/click/extras/src/org/apache/click/extras/control/Menu.java
    click/trunk/click/extras/src/org/apache/click/extras/control/menu.dtd
    click/trunk/click/template/src/template/page/BasePage.java
    click/trunk/click/template/src/template/page/BorderPage.java

Modified: click/trunk/click/extras/src/org/apache/click/extras/control/Menu.java
URL: http://svn.apache.org/viewvc/click/trunk/click/extras/src/org/apache/click/extras/control/Menu.java?rev=927042&r1=927041&r2=927042&view=diff
==============================================================================
--- click/trunk/click/extras/src/org/apache/click/extras/control/Menu.java (original)
+++ click/trunk/click/extras/src/org/apache/click/extras/control/Menu.java Wed Mar 24 13:03:24
2010
@@ -70,12 +70,20 @@ import org.w3c.dom.NodeList;
  *
  * To include the root menu item in your page, simply use the default Menu constructor:
  *
- * <pre class="codeJava">
- * <span class="kw">public class</span> MenuPage <span class="kw">extends</span>
Page {
+ * <pre class="prettyprint">
+ * public class BorderPage extends Page {
  *
- *     <span class="kw">public</span> Menu rootMenu = Menu.getRootMenu();
+ *     &#64;Bindable public Menu rootMenu;
  *
- *     <span class="kw">public</span> ActionLink logoutLink = <span class="kw">new</span>
ActionLink(<span class="kw">this</span>, <span class="st">"onLogoutClick"</span>);
+ *     public BorderPage() {
+ *         MenuFactory menuFactory = new MenuFactory();
+ *         rootMenu = menuFactory.getRootMenu();
+ *     }
+ *
+ *     &#64;Override
+ *     public String getTemplate() {
+ *         return "/border-template.htm";
+ *     }
  *
  * } </pre>
  *
@@ -168,6 +176,8 @@ import org.w3c.dom.NodeList;
  * <pre class="codeConfig">
  * &lt;!-- The Menu (menu.xml) Document Type Definition. --&gt;
  * &lt;!ELEMENT <span class="red">menu</span> (<span class="st">menu</span>*)&gt;
+ *     &lt;!ATTLIST <span class="red">menu</span> <span class="st">id</span>
ID #IMPLIED&gt;
+ *     &lt;!ATTLIST <span class="red">menu</span> <span class="st">name</span>
CDATA #IMPLIED&gt;
  *     &lt;!ATTLIST <span class="red">menu</span> <span class="st">label</span>
CDATA #IMPLIED&gt;
  *     &lt;!ATTLIST <span class="red">menu</span> <span class="st">path</span>
CDATA #IMPLIED&gt;
  *     &lt;!ATTLIST <span class="red">menu</span> <span class="st">target</span>
CDATA #IMPLIED&gt;
@@ -197,7 +207,7 @@ import org.w3c.dom.NodeList;
  */
 public class Menu extends AbstractControl {
 
-    // -------------------------------------------------------------- Constants
+    // Constants --------------------------------------------------------------
 
     private static final long serialVersionUID = 1L;
 
@@ -213,18 +223,18 @@ public class Menu extends AbstractContro
         + "<script type=\"text/javascript\" src=\"{0}/click/extras-control{1}.js\"></script>\n"
         + "<script type=\"text/javascript\">addLoadEvent(function() '{ initMenu();'
});</script>\n";
 
-    // -------------------------------------------------------- Class Variables
+    // Class Variables --------------------------------------------------------
 
     /** The cached root Menu as defined in <tt>menu.xml</tt>. */
     protected static Menu rootMenu;
 
-    // ----------------------------------------------------- Instance Variables
+    // Instance Variables -----------------------------------------------------
 
     /** The menu security access controller. */
     protected transient AccessController accessController;
 
     /** The list of submenu items. */
-    protected List children = new ArrayList();
+    protected List<Menu> children = new ArrayList<Menu>();
 
     /**
      * The menu path is to an external page flag, by default this value is false.
@@ -248,13 +258,13 @@ public class Menu extends AbstractContro
      * The list of valid page paths. If any of these page paths match the
      * current request then the Menu item will be selected.
      */
-    protected List pages = new ArrayList();
+    protected List<String> pages = new ArrayList<String>();
 
     /** The menu path. */
     protected String path;
 
     /** The list of valid role names. */
-    protected List roles = new ArrayList();
+    protected List<String> roles = new ArrayList<String>();
 
     /** The menu separator flag. */
     protected boolean separator;
@@ -265,13 +275,7 @@ public class Menu extends AbstractContro
     /** The tooltip title attribute. */
     protected String title = "";
 
-    /** Visibility flag. Used to hide menu items at runtime */
-    protected boolean visible = true;
-
-    /** Enable flag. Used to disable menu items at runtime. Disabled menu items might be
still visible */
-    protected boolean enabled = true;
-    
-    // ----------------------------------------------------------- Constructors
+    // Constructors -----------------------------------------------------------
 
     /**
      * Create a new Menu instance.
@@ -330,6 +334,7 @@ public class Menu extends AbstractContro
      * @param menuElement the menu-item XML Element
      * @param accessController the menu access controller
      */
+    @Deprecated
     protected Menu(Element menuElement, AccessController accessController) {
         if (menuElement == null) {
             throw new IllegalArgumentException("Null menuElement parameter");
@@ -366,16 +371,6 @@ public class Menu extends AbstractContro
             setSeparator(true);
         }
 
-        String visibilityAtr = menuElement.getAttribute("visible");
-        if ("false".equalsIgnoreCase(visibilityAtr)) {
-            setVisible(false);
-        }
-
-        String enablingAtr = menuElement.getAttribute("enabled");
-        if ("false".equalsIgnoreCase(enablingAtr)) {
-            setEnabled(false);
-        }
-        
         String pagesValue = menuElement.getAttribute("pages");
         if (!StringUtils.isBlank(pagesValue)) {
             StringTokenizer tokenizer = new StringTokenizer(pagesValue, ",");
@@ -404,17 +399,18 @@ public class Menu extends AbstractContro
         }
     }
 
-    // ---------------------------------------------------- Constructor Methods
+    // Constructor Methods ----------------------------------------------------
 
     /**
      * Return root menu item defined in the WEB-INF/menu.xml or classpath
-     * menu.xml, and which uses JEE Role Based Access Control (RBAController).
+     * menu.xml, and which uses JEE Role Based Access Control (RoleAccessController).
      *
      * @see RoleAccessController
      *
      * @return the root menu item defined in the WEB-INF/menu.xml file or menu.xml
      * in the root classpath
      */
+    @Deprecated
     public static Menu getRootMenu() {
         return getRootMenu(new RoleAccessController());
     }
@@ -427,6 +423,7 @@ public class Menu extends AbstractContro
      * @return the root menu item defined in the WEB-INF/menu.xml file or menu.xml
      * in the root classpath
      */
+    @Deprecated
     public static Menu getRootMenu(AccessController accessController) {
         if (accessController == null) {
             throw new IllegalArgumentException("Null accessController parameter");
@@ -450,27 +447,7 @@ public class Menu extends AbstractContro
         return loadedMenu;
     }
 
-    /**
-     * Finds the first Menu item that has the specified path.
-     * 
-     * @param path the path to find the Menu item
-     * @return the first Menu item, or null if not found.
-     */
-    public static Menu findMenuItem(String path) {
-        if (rootMenu != null) {
-            List children = rootMenu.getChildren();
-            for (int i = 0; i < children.size(); i++) {
-                Menu menu = (Menu) children.get(i);
-                String itemPath = menu.getPath();
-                if (itemPath != null && itemPath.equals(path)) {
-                    return menu;
-                }
-            }
-        }
-        return null;
-    }
-
-    // ------------------------------------------------------ Public Attributes
+    // Public Attributes ------------------------------------------------------
 
     /**
      * Return the menu access controller.
@@ -495,7 +472,7 @@ public class Menu extends AbstractContro
      *
      * @return the list of submenu items
      */
-    public List getChildren() {
+    public List<Menu> getChildren() {
         return children;
     }
 
@@ -566,7 +543,7 @@ public class Menu extends AbstractContro
      *
      * @return the list of valid Page paths
      */
-    public List getPages() {
+    public List<String> getPages() {
         return pages;
     }
 
@@ -576,7 +553,7 @@ public class Menu extends AbstractContro
      *
      * @param pages the list of valid Page paths
      */
-    public void setPages(List pages) {
+    public void setPages(List<String> pages) {
         this.pages = pages;
     }
 
@@ -603,7 +580,7 @@ public class Menu extends AbstractContro
      *
      * @return the list of valid roles for the Menu item
      */
-    public List getRoles() {
+    public List<String> getRoles() {
         return roles;
     }
 
@@ -612,7 +589,7 @@ public class Menu extends AbstractContro
      *
      * @param roles the list of valid roles for the Menu item
      */
-    public void setRoles(List roles) {
+    public void setRoles(List<String> roles) {
         this.roles = roles;
     }
 
@@ -644,7 +621,7 @@ public class Menu extends AbstractContro
         }
 
         for (int i = 0, size = getChildren().size(); i < size; i++) {
-            Menu menu = (Menu) getChildren().get(i);
+            Menu menu = getChildren().get(i);
             if (menu.isSelected()) {
                 selected = true;
             }
@@ -654,6 +631,23 @@ public class Menu extends AbstractContro
     }
 
     /**
+     * Return the selected child menu, or null if no child menu is selected.
+     *
+     * @return the selected child menu
+     */
+    public Menu getSelectedChild() {
+        if (isSelected()) {
+            for (int i = 0, size = getChildren().size(); i < size; i++) {
+                Menu menu = getChildren().get(i);
+                if (menu.isSelected()) {
+                    return menu;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
      * Return true if the Menu item is a separator.
      *
      * @return true if the Menu item is a separator
@@ -691,7 +685,7 @@ public class Menu extends AbstractContro
         HttpServletRequest request = getContext().getRequest();
 
         for (int i = 0, size = getRoles().size(); i < size; i++) {
-            String rolename = (String) getRoles().get(i);
+            String rolename = getRoles().get(i);
             if (getAccessController().hasAccess(request, rolename)) {
                 return true;
             }
@@ -711,7 +705,7 @@ public class Menu extends AbstractContro
      */
     public boolean isUserInChildMenuRoles() {
          for (int i = 0, size = getChildren().size(); i < size; i++) {
-            Menu child = (Menu) getChildren().get(i);
+            Menu child = getChildren().get(i);
             if (child.isUserInRoles()) {
                 return true;
             }
@@ -757,49 +751,6 @@ public class Menu extends AbstractContro
     }
 
     /**
-     * Return the visibility flag of the Menu item.<p/>
-     * <i>Note:</i> default, all Menu items are visible.
-     * 
-     * @return the visibility flag of the Menu item.
-     */
-    public boolean isVisible() {
-        return visible;
-    }
-
-    /**
-     * Set the visibility flag of the Menu item. <p/>
-     * <i>Note:</i> changing this flag won't trigger the visibility on the page.
It is the duty of
-     * the rendering template for the Menu to take this flag in consideration when rendering.
-     *
-     * @param visible the visibility flag of the menu item.
-     */
-    public void setVisible(boolean visible) {
-        this.visible = visible;
-    }
-
-    /**
-     * Return the enabling flag of the Menu item. <p/>
-     * <i>Note:</i> default, all Menu items are enabled.
-     *
-     * @return he enabling flag of the Menu item.
-     */
-    public boolean isEnabled() {
-        return enabled;
-    }
-
-    /**
-     * Set the enabling flag of the Menu item. <p/>
-     * <i>Note:</i> changing this flag won't trigger the disabling on the page.
It is the duty of
-     * the rendering template for the Menu to take this flag in consideration when rendering,
and
-     * e.g. grey it out.
-     *
-     * @param enabled the enabling flag of the menu item.
-     */
-    public void setEnabled(boolean enabled) {
-        this.enabled = enabled;
-    }
-
-    /**
      * Return the Menu HTML head imports statements for the following
      * resources:
      * <p/>
@@ -842,24 +793,14 @@ public class Menu extends AbstractContro
         }
     }
 
-    /**
-     * This method returns null.
-     *
-     * @see org.apache.click.Control#getId()
-     *
-     * @return null
-     */
-    public String getId() {
-        return null;
-    }
-
-    // --------------------------------------------------------- Public Methods
+    // Public Methods ---------------------------------------------------------
 
     /**
      * This sets the parent to be null.
      *
      * @see org.apache.click.Control#onDestroy()
      */
+    @Override
     public void onDestroy() {
         setParent(null);
     }
@@ -873,6 +814,7 @@ public class Menu extends AbstractContro
      *
      * @param buffer the specified buffer to render the control's output to
      */
+    @Override
     public void render(HtmlStringBuffer buffer) {
 
         if (isSeparator()) {
@@ -881,6 +823,15 @@ public class Menu extends AbstractContro
         } else {
             buffer.elementStart("a");
 
+            String id = getAttribute("id");
+            if (id != null) {
+                buffer.appendAttribute("id", id);
+            }
+
+            if (getName() != null) {
+                buffer.appendAttribute("name", getName());
+            }
+
             String href = getHref();
             buffer.appendAttribute("href", href);
 
@@ -950,32 +901,14 @@ public class Menu extends AbstractContro
      *
      * @return an HTML anchor tag representation of the menu item
      */
+    @Override
     public String toString() {
         HtmlStringBuffer buffer = new HtmlStringBuffer();
         render(buffer);
         return buffer.toString();
     }
 
-    // --------------------------------------------------------- Public Methods
-
-    /**
-     * Return the selected child menu, or null if no child menu is selected.
-     *
-     * @return the selected child menu
-     */
-    public Menu getSelectedChild() {
-        if (isSelected()) {
-            for (int i = 0, size = getChildren().size(); i < size; i++) {
-                Menu menu = (Menu) getChildren().get(i);
-                if (menu.isSelected()) {
-                    return menu;
-                }
-            }
-        }
-        return null;
-    }
-
-    // ------------------------------------------------------ Protected Methods
+    // Protected Methods ------------------------------------------------------
 
     /**
      * Return a copy of the Applications root Menu as defined in the
@@ -987,6 +920,7 @@ public class Menu extends AbstractContro
      * @param accessController the menu access controller
      * @return a copy of the application's root Menu
      */
+    @Deprecated
     protected static Menu loadRootMenu(AccessController accessController) {
         if (accessController == null) {
             throw new IllegalArgumentException("Null accessController parameter");

Added: click/trunk/click/extras/src/org/apache/click/extras/control/MenuFactory.java
URL: http://svn.apache.org/viewvc/click/trunk/click/extras/src/org/apache/click/extras/control/MenuFactory.java?rev=927042&view=auto
==============================================================================
--- click/trunk/click/extras/src/org/apache/click/extras/control/MenuFactory.java (added)
+++ click/trunk/click/extras/src/org/apache/click/extras/control/MenuFactory.java Wed Mar
24 13:03:24 2010
@@ -0,0 +1,307 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.click.extras.control;
+
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletContext;
+
+import org.apache.click.Context;
+import org.apache.click.extras.security.AccessController;
+import org.apache.click.extras.security.RoleAccessController;
+import org.apache.click.service.ConfigService;
+import org.apache.click.util.ClickUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.Validate;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * TODO documentation.
+ */
+public class MenuFactory {
+
+    // Constants --------------------------------------------------------------
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * The menu configuration filename: &nbsp; "<tt>/WEB-INF/menu.xml</tt>".
+     */
+    protected static final String DEFAULT_CONFIG_FILE = "/WEB-INF/menu.xml";
+
+    // Class Variables --------------------------------------------------------
+
+    /** The cached root Menu as defined in <tt>menu.xml</tt>. */
+    protected static Menu CACHED_ROOT_MENU;
+
+    /** The default Menu XML attributes loaded into menu properties. */
+    protected static Set<String> DEFAULT_ATTRIBUTES;
+
+    static {
+        DEFAULT_ATTRIBUTES = new HashSet<String>();
+        DEFAULT_ATTRIBUTES.add("name");
+        DEFAULT_ATTRIBUTES.add("label");
+        DEFAULT_ATTRIBUTES.add("path");
+        DEFAULT_ATTRIBUTES.add("target");
+        DEFAULT_ATTRIBUTES.add("title");
+        DEFAULT_ATTRIBUTES.add("imageSrc");
+        DEFAULT_ATTRIBUTES.add("external");
+        DEFAULT_ATTRIBUTES.add("separator");
+        DEFAULT_ATTRIBUTES.add("roles");
+        DEFAULT_ATTRIBUTES.add("pages");
+    }
+
+    // Public Methods ---------------------------------------------------------
+
+    /**
+    * Return root menu item defined in the WEB-INF/menu.xml or classpath
+     * menu.xml, creating menu items using the Menu class and the JEE
+     * RollAccessController.
+     *
+     * @see RoleAccessController
+     *
+     * @return the root menu item defined in the WEB-INF/menu.xml file or menu.xml
+     * in the root classpath
+     */
+    public Menu getRootMenu() {
+        return getRootMenu(Menu.class, new RoleAccessController());
+    }
+
+    /**
+    * Return root menu item defined in the WEB-INF/menu.xml or classpath
+     * menu.xml, creating menu items using the provided Menu class and the JEE
+     * RollAccessController.
+     *
+     * @param menuClass the menu class to create new Menu instances from
+     * @return the root menu item defined in the WEB-INF/menu.xml file or menu.xml
+     * in the root classpath
+     */
+    public Menu getRootMenu(Class<? extends Menu> menuClass) {
+        return getRootMenu(new RoleAccessController());
+    }
+
+    /**
+    * Return root menu item defined in the WEB-INF/menu.xml or classpath
+     * menu.xml, creating menu items using the Menu class and the provided
+     * AccessController.
+     *
+     * @param accessController the menu access controller
+     * @return the root menu item defined in the WEB-INF/menu.xml file or menu.xml
+     * in the root classpath
+     */
+    public Menu getRootMenu(AccessController accessController) {
+        return getRootMenu(Menu.class, accessController);
+    }
+
+    /**
+    * Return root menu item defined in the WEB-INF/menu.xml or classpath
+     * menu.xml, creating menu items using the provided Menu class and the
+     * AccessController.
+     *
+     * @param menuClass the menu class to create new Menu instances from
+     * @param accessController the menu access controller
+     * @return the root menu item defined in the WEB-INF/menu.xml file or menu.xml
+     * in the root classpath
+     */
+    public Menu getRootMenu(Class<? extends Menu> menuClass, AccessController accessController)
{
+
+        Validate.notNull(menuClass, "Null menuClass parameter");
+        Validate.notNull(accessController, "Null accessController parameter");
+
+        // If menu is cached return it
+        if (CACHED_ROOT_MENU != null) {
+            return CACHED_ROOT_MENU;
+        }
+
+        try {
+            Menu loadedMenu = loadFromMenuXml(menuClass, accessController);
+
+            ServletContext servletContext = Context.getThreadLocalContext().getServletContext();
+            ConfigService configService = ClickUtils.getConfigService(servletContext);
+
+            if (configService.isProductionMode() || configService.isProfileMode()) {
+                // Cache menu in production modes
+                CACHED_ROOT_MENU = loadedMenu;
+            }
+
+            return loadedMenu;
+
+        } catch (Exception e) {
+            String msg = "Error initializing rootMenu for class: " + menuClass;
+            throw new RuntimeException(msg, e);
+        }
+    }
+
+    // Protected Methods ------------------------------------------------------
+
+    /**
+     * Return a copy of the Applications root Menu as defined in the
+     * configuration file "<tt>/WEB-INF/menu.xml</tt>", with the Control
+     * name <tt>"rootMenu"</tt>.
+     * <p/>
+     * The returned root menu is always selected.
+     *
+     * @param menuClass the menu class to instantiate
+     * @param accessController the menu access controller
+     * @return a copy of the application's root Menu
+     * @throws InstantiationException if the menu instance could not be created
+     * @throws IllegalAccessException if the menu instance could not be created
+     */
+    protected Menu loadFromMenuXml(Class<? extends Menu> menuClass,
+            AccessController accessController)
+            throws InstantiationException, IllegalAccessException {
+
+        Validate.notNull(menuClass, "Null menuClass parameter");
+        Validate.notNull(accessController, "Null accessController parameter");
+
+        Context context = Context.getThreadLocalContext();
+
+        Menu rootMenu = menuClass.newInstance();
+        rootMenu.setName("rootMenu");
+        rootMenu.setAccessController(accessController);
+
+        ServletContext servletContext = context.getServletContext();
+        InputStream inputStream =
+            servletContext.getResourceAsStream(DEFAULT_CONFIG_FILE);
+
+        if (inputStream == null) {
+            inputStream = ClickUtils.getResourceAsStream("/menu.xml", Menu.class);
+            String msg =
+                "could not find configuration file:" + DEFAULT_CONFIG_FILE
+                + " or menu.xml on classpath";
+            throw new RuntimeException(msg);
+        }
+
+        Document document = ClickUtils.buildDocument(inputStream);
+
+        Element rootElm = document.getDocumentElement();
+
+        NodeList list = rootElm.getChildNodes();
+
+        for (int i = 0; i < list.getLength(); i++) {
+            Node node = list.item(i);
+            if (node instanceof Element) {
+                Menu childMenu = buildMenu((Element) node, menuClass, accessController);
+                rootMenu.getChildren().add(childMenu);
+            }
+        }
+
+        return rootMenu;
+    }
+
+    /**
+     * Build a new Menu from the given menu item XML Element and recurse through
+     * all the menu-items children.
+     *
+     * @param menuElement the menu item XML Element
+     * @param menuClass the menu class to instantiate
+     * @param accessController the menu access controller
+     * @return new Menu instance for the given XML menuElement
+     * @throws InstantiationException if the menu instance could not be created
+     * @throws IllegalAccessException if the menu instance could not be created
+     */
+    protected Menu buildMenu(Element menuElement, Class<? extends Menu> menuClass,
+            AccessController accessController)
+            throws InstantiationException, IllegalAccessException {
+
+        Validate.notNull(menuElement, "Null menuElement parameter");
+        Validate.notNull(menuClass, "Null menuClass parameter");
+        Validate.notNull(accessController, "Null accessController parameter");
+
+        Menu menu = menuClass.newInstance();
+
+        menu.setName(menuElement.getAttribute("name"));
+
+        menu.setAccessController(accessController);
+
+        menu.setLabel(menuElement.getAttribute("label"));
+
+        menu.setImageSrc(menuElement.getAttribute("imageSrc"));
+
+        menu.setPath(menuElement.getAttribute("path"));
+
+        String titleAtr = menuElement.getAttribute("title");
+        if (StringUtils.isNotBlank(titleAtr)) {
+            menu.setTitle(titleAtr);
+        }
+
+        String targetAtr = menuElement.getAttribute("target");
+        if (StringUtils.isNotBlank(targetAtr)) {
+            menu.setTarget(targetAtr);
+        }
+
+        String externalAtr = menuElement.getAttribute("external");
+        if ("true".equalsIgnoreCase(externalAtr)) {
+            menu.setExternal(true);
+        }
+
+        String separatorAtr = menuElement.getAttribute("separator");
+        if ("true".equalsIgnoreCase(separatorAtr)) {
+            menu.setSeparator(true);
+        }
+
+        String pagesValue = menuElement.getAttribute("pages");
+        if (!StringUtils.isBlank(pagesValue)) {
+            StringTokenizer tokenizer = new StringTokenizer(pagesValue, ",");
+            while (tokenizer.hasMoreTokens()) {
+                String path = tokenizer.nextToken().trim();
+                path = (path.startsWith("/")) ? path : "/" + path;
+                menu.getPages().add(path);
+            }
+        }
+
+        String rolesValue = menuElement.getAttribute("roles");
+        if (!StringUtils.isBlank(rolesValue)) {
+            StringTokenizer tokenizer = new StringTokenizer(rolesValue, ",");
+            while (tokenizer.hasMoreTokens()) {
+                menu.getRoles().add(tokenizer.nextToken().trim());
+            }
+        }
+
+        // Load other attributes
+        NamedNodeMap attributeNodeMap = menuElement.getAttributes();
+        for (int i = 0; i < attributeNodeMap.getLength(); i++) {
+            Node attribute = attributeNodeMap.item(i);
+            String name = attribute.getNodeName();
+            if (!DEFAULT_ATTRIBUTES.contains(name)) {
+                String value = attribute.getNodeValue();
+                menu.getAttributes().put(name, value);
+            }
+        }
+
+        NodeList childElements = menuElement.getChildNodes();
+        for (int i = 0, size = childElements.getLength(); i < size; i++) {
+            Node node = childElements.item(i);
+            if (node instanceof Element) {
+                Menu childMenu = buildMenu((Element) node, menuClass, accessController);
+                menu.getChildren().add(childMenu);
+            }
+        }
+
+        return menu;
+    }
+
+}

Modified: click/trunk/click/extras/src/org/apache/click/extras/control/menu.dtd
URL: http://svn.apache.org/viewvc/click/trunk/click/extras/src/org/apache/click/extras/control/menu.dtd?rev=927042&r1=927041&r2=927042&view=diff
==============================================================================
--- click/trunk/click/extras/src/org/apache/click/extras/control/menu.dtd (original)
+++ click/trunk/click/extras/src/org/apache/click/extras/control/menu.dtd Wed Mar 24 13:03:24
2010
@@ -21,6 +21,8 @@
 
 <!-- The Menu (menu.xml) Document Type Definition. -->
 <!ELEMENT menu (menu*)>
+    <!ATTLIST menu id ID #IMPLIED>
+    <!ATTLIST menu name CDATA #IMPLIED>
     <!ATTLIST menu label CDATA #IMPLIED>
     <!ATTLIST menu path CDATA #IMPLIED>
     <!ATTLIST menu target CDATA #IMPLIED>
@@ -28,7 +30,5 @@
     <!ATTLIST menu imageSrc CDATA #IMPLIED>
     <!ATTLIST menu external (true|false) "false">
     <!ATTLIST menu separator (true|false) "false">
-    <!ATTLIST menu visible (true|false) "true">
-    <!ATTLIST menu enabled (true|false) "true">
     <!ATTLIST menu roles CDATA #IMPLIED>
     <!ATTLIST menu pages CDATA #IMPLIED>

Modified: click/trunk/click/template/src/template/page/BasePage.java
URL: http://svn.apache.org/viewvc/click/trunk/click/template/src/template/page/BasePage.java?rev=927042&r1=927041&r2=927042&view=diff
==============================================================================
--- click/trunk/click/template/src/template/page/BasePage.java (original)
+++ click/trunk/click/template/src/template/page/BasePage.java Wed Mar 24 13:03:24 2010
@@ -10,6 +10,8 @@ import org.apache.click.Page;
  */
 public class BasePage extends Page {
 
+    private static final long serialVersionUID = 1L;
+
     private Logger logger;
 
     /**

Modified: click/trunk/click/template/src/template/page/BorderPage.java
URL: http://svn.apache.org/viewvc/click/trunk/click/template/src/template/page/BorderPage.java?rev=927042&r1=927041&r2=927042&view=diff
==============================================================================
--- click/trunk/click/template/src/template/page/BorderPage.java (original)
+++ click/trunk/click/template/src/template/page/BorderPage.java Wed Mar 24 13:03:24 2010
@@ -1,10 +1,18 @@
 package template.page;
 
 import org.apache.click.extras.control.Menu;
+import org.apache.click.extras.control.MenuFactory;
 
 public class BorderPage extends BasePage {
 
-    public Menu rootMenu = Menu.getRootMenu();
+    private static final long serialVersionUID = 1L;
+
+    public Menu rootMenu;
+
+    public BorderPage() {
+        MenuFactory menuFactory = new MenuFactory();
+        rootMenu = menuFactory.getRootMenu();
+    }
 
     /**
      * @see #getTemplate()



Mime
View raw message