portals-jetspeed-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rwat...@apache.org
Subject svn commit: r209305 [6/10] - in /portals/jetspeed-2/branches/MENUS_BRANCH: components/locator/src/java/org/apache/jetspeed/profiler/impl/ components/page-manager/ components/page-manager/src/java/META-INF/ components/page-manager/src/java/org/apache/je...
Date Tue, 05 Jul 2005 18:58:14 GMT
Added: portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/MenuImpl.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/MenuImpl.java?rev=209305&view=auto
==============================================================================
--- portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/MenuImpl.java (added)
+++ portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/MenuImpl.java Tue Jul  5 11:58:05 2005
@@ -0,0 +1,1051 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.jetspeed.portalsite.impl;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Locale;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.jetspeed.om.common.GenericMetadata;
+import org.apache.jetspeed.om.folder.Folder;
+import org.apache.jetspeed.om.folder.MenuDefinition;
+import org.apache.jetspeed.om.folder.MenuExcludeDefinition;
+import org.apache.jetspeed.om.folder.MenuIncludeDefinition;
+import org.apache.jetspeed.om.folder.MenuOptionsDefinition;
+import org.apache.jetspeed.om.folder.MenuSeparatorDefinition;
+import org.apache.jetspeed.om.page.Page;
+import org.apache.jetspeed.page.document.Node;
+import org.apache.jetspeed.page.document.NodeNotFoundException;
+import org.apache.jetspeed.portalsite.Menu;
+import org.apache.jetspeed.portalsite.MenuElement;
+import org.apache.jetspeed.portalsite.MenuOption;
+import org.apache.jetspeed.portalsite.PortalSiteRequestContext;
+import org.apache.jetspeed.portalsite.menu.DefaultMenuDefinition;
+import org.apache.jetspeed.portalsite.menu.DefaultMenuOptionsDefinition;
+import org.apache.jetspeed.portalsite.view.SiteView;
+
+/**
+ * This class implements the portal-site menu elements
+ * constructed and returned to decorators.
+ * 
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id$
+ */
+public class MenuImpl extends MenuElementImpl implements Menu, Cloneable
+{
+    /**
+     * definition - menu definition
+     */
+    private MenuDefinition definition;
+
+    /**
+     * elements - ordered list of menu elements that
+     *            make up this instaniated menu
+     */
+    private List elements;
+
+    /**
+     * elementRelative - flag that indicates whether any relative paths
+     *                   dependent on the current page in context were
+     *                   referenced while constructing menu elements:
+     *                   requires request, not session, caching
+     */
+    private boolean elementRelative;
+
+    /**
+     * MenuImpl - request/session context dependent constructor
+     *
+     * @param parent containing menu implementation
+     * @param definition menu definition
+     * @param context request context
+     * @param menus related menu definition names set
+     */
+    public MenuImpl(MenuImpl parent, MenuDefinition definition, PortalSiteRequestContextImpl context, Set menus)
+    {
+        super(parent);
+        this.definition = definition;
+
+        // get site view from context
+        SiteView view = ((PortalSiteSessionContextImpl)context.getSessionContext()).getSiteView();
+        if (view != null)
+        {
+            // define menu node for titles and metadata if options
+            // specifies a single visible page or folder proxy
+            String options = definition.getOptions();
+            Node optionProxy = null;
+            if ((options != null) && (options.indexOf(',') == -1))
+            {
+                try
+                {
+                    optionProxy = view.getNodeProxy(options, context.getPage(), true);
+                }
+                catch (NodeNotFoundException nnfe)
+                {
+                }
+                catch (SecurityException se)
+                {
+                }
+                if (optionProxy != null)
+                {
+                    setNode(optionProxy);
+                }
+            }
+
+            // construct menu elements from menu definition
+            // or nested menu definition elements; note that
+            // menu elements override menu options attribute
+            if ((definition.getMenuElements() == null) || definition.getMenuElements().isEmpty())
+            {
+                // if options optionProxy is a single folder, force
+                // options to include all folder children if not to
+                // be expanded with paths and depth inclusion is
+                // specified
+                List overrideOptionProxies = null;
+                if (optionProxy != null)
+                {
+                    if ((optionProxy instanceof Folder) && !definition.isPaths() && (definition.getDepth() != 0))
+                    {
+                        // override menu options with visible folder contents i
+                        List folderChildren = view.getNodeProxies("*", optionProxy, true);
+                        if ((folderChildren != null) && !folderChildren.isEmpty())
+                        {
+                            overrideOptionProxies = folderChildren;
+                        }
+                    }
+                    else
+                    {
+                        // override menu options with single folder/page/link
+                        overrideOptionProxies = new ArrayList(1);
+                        overrideOptionProxies.add(optionProxy);
+                    }
+                    
+                    if (overrideOptionProxies != null)
+                    {
+                        // set relative element flag if options path is relative
+                        elementRelative = (elementRelative || !options.startsWith(Folder.PATH_SEPARATOR));
+                    }
+                }
+
+                // menu defined only with menu definition options
+                this.elements = constructMenuElements(context, view, options, overrideOptionProxies, definition.getDepth(), definition.isPaths(), definition.isRegexp(), definition.getProfile(), definition.getOrder());
+            }
+            else
+            {
+                // limit cyclic references to this menu if named and
+                // referencable as root menu instance
+                boolean menuNameReferenced = false;
+                if ((definition.getName() != null) && (parent == null))
+                {
+                    if (menus == null)
+                    {
+                        menus = new HashSet(4);
+                    }
+                    menuNameReferenced = menus.add(definition.getName());
+                }
+                
+                // process menu elements in chunks between separators:
+                // separators are included only if menu options are
+                // generated after the separator and include/exclude
+                // merge/filter operations apply to options bounded
+                // by separators
+                MenuSeparatorImpl separator = null;
+                List separatedElements = null;
+
+                // process each defined menu element
+                Iterator menuElementsIter = definition.getMenuElements().iterator();
+                while (menuElementsIter.hasNext())
+                {
+                    Object menuElement = menuElementsIter.next();
+                    if (menuElement instanceof MenuOptionsDefinition)
+                    {
+                        // construct menu option elements from definition using
+                        // defaults from menu definition as appropriate
+                        MenuOptionsDefinition optionDefinition = (MenuOptionsDefinition)menuElement;
+                        String locatorName = optionDefinition.getProfile();
+                        if (locatorName == null)
+                        {
+                            locatorName = definition.getProfile();
+                        }
+                        String order = optionDefinition.getOrder();
+                        if (order == null)
+                        {
+                            order = definition.getOrder();
+                        }
+                        List optionsAndMenus = constructMenuElements(context, view, optionDefinition.getOptions(), null, optionDefinition.getDepth(), optionDefinition.isPaths(), optionDefinition.isRegexp(), locatorName, order);
+
+                        // append option and menu elements to current separator
+                        // elements list
+                        if (optionsAndMenus != null)
+                        {
+                            if (separatedElements == null)
+                            {
+                                separatedElements = optionsAndMenus;
+                            }
+                            else
+                            {
+                                appendMenuElements(optionsAndMenus, separatedElements);
+                            }
+                        }
+                    }
+                    else if (menuElement instanceof MenuSeparatorDefinition)
+                    {
+                        // append current separator and separated option/menu elements
+                        // to menu elements list if at least one option/menu
+                        // element exists: do not include disassociated separators in menu
+                        if ((separatedElements != null) && !separatedElements.isEmpty())
+                        {
+                            if (this.elements == null)
+                            {
+                                int initialSize = separatedElements.size();
+                                if (separator != null)
+                                {
+                                    initialSize++;
+                                }
+                                this.elements = new ArrayList(initialSize);
+                            }
+                            if (separator != null)
+                            {
+                                this.elements.add(separator);
+                            }
+                            this.elements.addAll(separatedElements);
+                        }
+
+                        // construct new separator and reset separator
+                        // option/menu elements list
+                        MenuSeparatorDefinition separatorDefinition = (MenuSeparatorDefinition)menuElement;
+                        separator = new MenuSeparatorImpl(this, separatorDefinition);
+                        if (separatedElements != null)
+                        {
+                            separatedElements.clear();
+                        }
+                    }
+                    else if (menuElement instanceof MenuDefinition)
+                    {
+                        // construct nested menu element from definition
+                        MenuDefinition menuDefinition = (MenuDefinition)menuElement;
+                        MenuImpl nestedMenu = new MenuImpl(this, menuDefinition, context, menus);
+
+                        // append menu element to current separated elements list
+                        if (separatedElements == null)
+                        {
+                            separatedElements = new ArrayList(1);
+                        }
+                        appendMenuElement(nestedMenu, separatedElements);
+
+                        // set relative element flag if nested menu is relative
+                        elementRelative = (elementRelative || nestedMenu.isElementRelative());
+                    }
+                    else if (menuElement instanceof MenuIncludeDefinition)
+                    {
+                        // include or nest referenced menu definition
+                        // assuming reference to menu is not cyclic
+                        MenuIncludeDefinition includeDefinition = (MenuIncludeDefinition)menuElement;
+                        if ((menus == null) || !menus.contains(includeDefinition.getName()))
+                        {
+                            // get named root menu from context, (menu may
+                            // not exist in this context so failure to
+                            // access menu is ignored)
+                            MenuImpl includeMenu = null;
+                            try
+                            {
+                                includeMenu = (MenuImpl)context.getMenu(includeDefinition.getName());
+                            }
+                            catch (NodeNotFoundException nnfe)
+                            {
+                            }
+                            catch (SecurityException se)
+                            {
+                            }
+                            if (includeMenu != null)
+                            {
+                                // nest menu or include elements, clone required
+                                // to support reparenting to this menu
+                                if (includeDefinition.isNest())
+                                {
+                                    // nest menu instance
+                                    try
+                                    {
+                                        // clone menu and reparent
+                                        includeMenu = (MenuImpl)includeMenu.clone();
+                                        includeMenu.setParentMenu(this);
+
+                                        // append menu element to current separated elements list
+                                        if (separatedElements == null)
+                                        {
+                                            separatedElements = new ArrayList(1);
+                                        }
+                                        appendMenuElement(includeMenu, separatedElements);
+                                    }
+                                    catch (CloneNotSupportedException cnse)
+                                    {
+                                    }
+                                }
+                                else
+                                {
+                                    // include menu elements
+                                    if ((includeMenu.getElements() != null) && !includeMenu.getElements().isEmpty())
+                                    {
+                                        Iterator elementsIter = includeMenu.getElements().iterator();
+                                        while (elementsIter.hasNext())
+                                        {
+                                            MenuElementImpl includeElement = (MenuElementImpl)elementsIter.next();
+                                            try
+                                            {
+                                                // clone menu element and reparent
+                                                includeElement = (MenuElementImpl)includeElement.clone();
+                                                includeElement.setParentMenu(this);
+                                                
+                                                // append menu element to current separated elements list
+                                                if (separatedElements == null)
+                                                {
+                                                    separatedElements = new ArrayList(includeMenu.getElements().size());
+                                                }
+                                                appendMenuElement(includeElement, separatedElements);
+                                            }
+                                            catch (CloneNotSupportedException cnse)
+                                            {
+                                            }
+                                        }
+                                    }
+                                }
+
+                                // set relative element flag if included menu is relative
+                                elementRelative = (elementRelative || includeMenu.isElementRelative());
+                            }
+                        }
+                    }
+                    else if (menuElement instanceof MenuExcludeDefinition)
+                    {
+                        // exclusion requires current separated elements
+                        if ((separatedElements != null) && !separatedElements.isEmpty())
+                        {
+                            // exclude top level referenced menu definition
+                            // options assuming reference to menu is not cyclic
+                            MenuExcludeDefinition excludeDefinition = (MenuExcludeDefinition)menuElement;
+                            if ((menus == null) || !menus.contains(excludeDefinition.getName()))
+                            {
+                                // get named root menu from context, (menu may
+                                // not exist in this context so failure to
+                                // access menu is ignored)
+                                MenuImpl excludeMenu = null;
+                                try
+                                {
+                                    excludeMenu = (MenuImpl)context.getMenu(excludeDefinition.getName());
+                                }
+                                catch (NodeNotFoundException nnfe)
+                                {
+                                }
+                                catch (SecurityException se)
+                                {
+                                }
+                                if (excludeMenu != null)
+                                {
+                                    // remove referenced menu options from current
+                                    // separated elements list
+                                    removeMenuElements(excludeMenu.getElements(), separatedElements);
+
+                                    // set relative element flag if excluded menu is relative
+                                    elementRelative = (elementRelative || excludeMenu.isElementRelative());
+                                }
+                            }
+                        }
+                    }
+                }
+
+                // append last separator and separated option/menu elements
+                // to menu elements list if at least one option/menu
+                // element exists: do not include trailing separators
+                if ((separatedElements != null) && !separatedElements.isEmpty())
+                {
+                    if (this.elements == null)
+                    {
+                        // use the separated elements as the menu elements
+                        // collection and insert the separator
+                        this.elements = separatedElements;
+                        if (separator != null)
+                        {
+                            this.elements.add(0, separator);
+                        }
+                    }
+                    else
+                    {
+                        // copy into existing menu elements collection
+                        if (separator != null)
+                        {
+                            this.elements.add(separator);
+                        }
+                        this.elements.addAll(separatedElements);
+                    }
+                }
+
+                // restore referencing for this menu if limited
+                if (menuNameReferenced)
+                {
+                    menus.remove(definition.getName());
+                }
+            }
+        }
+    }
+
+    /**
+     * MenuImpl - request/session context dependent constructor
+     *
+     * @param definition menu definition
+     * @param context request context
+     * @param menus related menu definition names set
+     */
+    public MenuImpl(MenuDefinition definition, PortalSiteRequestContextImpl context, Set menus)
+    {
+        this(null, definition, context, menus);
+    }
+
+    /**
+     * appendMenuElement - append to ordered list of unique menu
+     *                     option/menu elements
+     * 
+     * @param appendMenuElement option/menu element to append
+     * @param menuElements option/menu element list
+     */
+    private void appendMenuElement(MenuElementImpl appendMenuElement, List menuElements)
+    {
+        // make sure new menu element is unique and
+        // add to menu element list
+        if (appendMenuElement != null)
+        {
+            if (!menuElements.contains(appendMenuElement))
+            {
+                menuElements.add(appendMenuElement);
+            }
+        }
+    }
+    
+    /**
+     * appendMenuElements - append to ordered list of unique menu
+     *                      option/menu elements
+     * 
+     * @param appendMenuElements option/menu element list to append
+     * @param menuElements option/menu element list
+     */
+    private void appendMenuElements(List appendMenuElements, List menuElements)
+    {
+        // make sure new menu elements are unique and
+        // add to menu element list
+        if (appendMenuElements != null)
+        {
+            Iterator elementsIter = appendMenuElements.iterator();
+            while (elementsIter.hasNext())
+            {
+                appendMenuElement((MenuElementImpl)elementsIter.next(), menuElements);
+            }
+        }
+    }
+    
+    /**
+     * removeMenuElements - remove from ordered list of unique menu
+     *                      option/menu elements
+     * 
+     * @param removeMenuElements option/menu element list to remove
+     * @param menuElements option/menu element list
+     */
+    private void removeMenuElements(List removeMenuElements, List menuElements)
+    {
+        // remove equivalent menu elements from menu
+        // element list
+        if (removeMenuElements != null)
+        {
+            menuElements.removeAll(removeMenuElements);
+        }
+    }
+
+    /**
+     * constructMenuElements - construct ordered list of menu elements in
+     *                         context/site view using specified element
+     *                         selection parameters; also sets up the
+     *                         elementRelative flag while constructing the
+     *                         menu elements
+     * 
+     * @param context request context
+     * @param view context site view
+     * @param options option paths specification
+     * @param overrideElementProxies override menu element node proxies
+     * @param depth inclusion depth
+     * @param paths paths elements flag
+     * @param regexp regexp flag
+     * @param locatorName profile locator name
+     * @param order ordering patterns list
+     */
+    private List constructMenuElements(PortalSiteRequestContextImpl context, SiteView view, String options, List overrideElementProxies, int depth, boolean paths, boolean regexp, String locatorName, String order)
+    {
+        if (options != null)
+        {
+            // use override element proxies if specified; otherwise
+            // compute proxy list using specified menu options
+            List elementProxies = overrideElementProxies;
+            if (elementProxies == null)
+            {
+                // split multiple comma separated option paths from specified options 
+                String [] optionPaths = options.split(",");
+                
+                // use regexp processing if specified or simple
+                // path evaluation to retrieve list of proxies from
+                // the site view for the specified options
+                for (int i = 0; (i < optionPaths.length); i++)
+                {
+                    String optionPath = optionPaths[i].trim();
+                    if (optionPath.length() > 0)
+                    {
+                        // get proxies/proxy for path
+                        if (regexp)
+                        {
+                            // get list of visible proxies for path from view and append
+                            // to list if unique and pass profile locator name filter
+                            List pathProxies = null;
+                            try
+                            {
+                                pathProxies = view.getNodeProxies(optionPath, context.getPage(), true);
+                            }
+                            catch (NodeNotFoundException nnfe)
+                            {
+                            }
+                            catch (SecurityException se)
+                            {
+                            }
+                            if (pathProxies != null)
+                            {
+                                Iterator pathProxiesIter = pathProxies.iterator();
+                                while (pathProxiesIter.hasNext())
+                                {
+                                    Node pathProxy = (Node)pathProxiesIter.next();
+                                    if ((locatorName == null) || locatorName.equals(MenuOptionsDefinition.ANY_PROFILE_LOCATOR) ||
+                                        locatorName.equals(view.getProfileLocatorName(pathProxy)))
+                                    {
+                                        if (elementProxies == null)
+                                        {
+                                            elementProxies = new ArrayList();
+                                        }
+                                        appendMenuElementProxies(pathProxy, elementProxies);
+                                    }
+                                }
+                            }
+                        }
+                        else
+                        {
+                            // get visible proxy for path from view and append to
+                            // list if unique and pass profile locator name filter
+                            Node pathProxy = null;
+                            try
+                            {
+                                pathProxy = view.getNodeProxy(optionPath, context.getPage(), true);
+                            }
+                            catch (NodeNotFoundException nnfe)
+                            {
+                            }
+                            catch (SecurityException se)
+                            {
+                            }
+                            if ((pathProxy != null) &&
+                                ((locatorName == null) || locatorName.equals(MenuOptionsDefinition.ANY_PROFILE_LOCATOR) ||
+                                 locatorName.equals(view.getProfileLocatorName(pathProxy))))
+                            {
+                                if (elementProxies == null)
+                                {
+                                    elementProxies = new ArrayList();
+                                }
+                                appendMenuElementProxies(pathProxy, elementProxies);
+                            }
+                        }
+
+                        // set relative element flag if path is relative
+                        elementRelative = (elementRelative || !optionPath.startsWith(Folder.PATH_SEPARATOR));
+                    }
+                }
+
+                // retrun if no proxies available
+                if (elementProxies == null)
+                {
+                    return null;
+                }
+            }
+            
+            // sort elements proxies using url and/or names if order
+            // specified and more than one element proxy in list
+            if ((order != null) && (elementProxies.size() > 1))
+            {
+                // create ordered element proxies
+                List orderedElementProxies = new ArrayList(elementProxies.size());
+                
+                // split multiple comma separated elements orderings
+                // after converted to regexp pattern
+                String [] orderings = orderRegexpPattern(order).split(",");
+                
+                // copy ordered proxies per ordering
+                for (int i=0; ((i < orderings.length) && (elementProxies.size() > 1)); i++)
+                {
+                    String ordering = orderings[i].trim();
+                    if (ordering.length() > 0)
+                    {
+                        // get ordering pattern and matcher
+                        Pattern pattern = Pattern.compile(ordering);
+                        Matcher matcher = null;
+                        
+                        // use regular expression to match urls or names of
+                        // element proxies; matched proxies are removed and
+                        // placed in the ordered elements proxies list
+                        Iterator elementProxiesIter = elementProxies.iterator();
+                        while (elementProxiesIter.hasNext())
+                        {
+                            Node elementProxy = (Node)elementProxiesIter.next(); 
+                            
+                            // get url or name to test ordering match against
+                            String test = null;
+                            if (ordering.charAt(0) == Folder.PATH_SEPARATOR_CHAR)
+                            {
+                                test = elementProxy.getUrl();
+                            }
+                            else
+                            {
+                                test = elementProxy.getName();
+                            }
+                            
+                            // construct or reset ordering matcher
+                            if (matcher == null)
+                            {
+                                matcher = pattern.matcher(test);
+                            }
+                            else
+                            {
+                                matcher.reset(test);
+                            }
+                            
+                            // move proxy to ordered list if matched
+                            if (matcher.matches())
+                            {
+                                orderedElementProxies.add(elementProxy);
+                                elementProxiesIter.remove();
+                            }
+                        }
+                    }
+                }
+                
+                // copy remaining unordered proxies
+                orderedElementProxies.addAll(elementProxies);
+                
+                // replace element proxies with ordered list
+                elementProxies = orderedElementProxies;
+            }
+            
+            // expand paths if single page or folder element proxy
+            // has been specified in elements with no depth expansion
+            if (paths && (depth == 0) && (elementProxies.size() == 1) &&
+                ((elementProxies.get(0) instanceof Folder) || (elementProxies.get(0) instanceof Page)))
+            {
+                Node parentNode = ((Node)elementProxies.get(0)).getParent();
+                while (parentNode != null)
+                {
+                    elementProxies.add(0, parentNode);
+                    parentNode = parentNode.getParent();
+                }
+            }
+            
+            // convert elements proxies into menu elements
+            DefaultMenuOptionsDefinition defaultMenuOptionsDefinition = null;
+            ListIterator elementProxiesIter = elementProxies.listIterator();
+            while (elementProxiesIter.hasNext())
+            {
+                Node elementProxy = (Node)elementProxiesIter.next();
+                MenuElement menuElement = null;
+
+                // convert folders into nested menus if depth specified
+                // with no paths expansion, (negative depth values are
+                // interpreted as complete menu expansion)
+                if ((elementProxy instanceof Folder) && ((depth < 0) || (depth > 1)) && !paths)
+                {
+                    // construct menu definition and associated menu
+                    MenuDefinition nestedMenuDefinition = new DefaultMenuDefinition(elementProxy.getUrl(), depth - 1, locatorName);
+                    menuElement = new MenuImpl(this, nestedMenuDefinition, context, null);
+                }
+                else
+                {
+                    // construct shared default menu option definition and menu option
+                    if (defaultMenuOptionsDefinition == null)
+                    {
+                        defaultMenuOptionsDefinition = new DefaultMenuOptionsDefinition(options, depth, paths, regexp, locatorName, order);
+                    }
+                    menuElement = new MenuOptionImpl(this, elementProxy, defaultMenuOptionsDefinition);
+                }
+
+                // replace element proxy with menu element
+                elementProxiesIter.set(menuElement);
+            }
+            List menuElements = elementProxies;
+
+            // return list of menu elements constructed from element proxies
+            return menuElements;
+        }
+
+        // no options specified
+        return null;
+    }
+
+    /**
+     * appendMenuElementProxies - append to ordered list of unique menu
+     *                            element proxies
+     * 
+     * @param pathProxy menu element page, folder, or link proxy at path
+     * @param elementProxies element proxies list
+     */
+    private void appendMenuElementProxies(Node pathProxy, List elementProxies)
+    {
+        // make sure new proxy is unique and add
+        // to element proxies list
+        if (!elementProxies.contains(pathProxy))
+        {
+            elementProxies.add(pathProxy);
+        }
+    }
+    
+    /**
+     * clone - clone this instance
+     *
+     * @return unparented deep copy
+     */
+    public Object clone() throws CloneNotSupportedException
+    {
+        // clone this object
+        MenuImpl copy = (MenuImpl)super.clone();
+
+        // clone and reparent copy elements
+        if (copy.elements != null)
+        {
+            Iterator elementsIter = copy.elements.iterator();
+            copy.elements = new ArrayList(copy.elements.size());
+            while (elementsIter.hasNext())
+            {
+                MenuElementImpl elementCopy = (MenuElementImpl)((MenuElementImpl)elementsIter.next()).clone();
+                elementCopy.setParentMenu(copy);
+                copy.elements.add(elementCopy);
+            }
+        }
+        return copy;
+    }
+
+    /**
+     * getElementType - get type of menu element
+     *
+     * @return MENU_ELEMENT_TYPE
+     */
+    public String getElementType()
+    {
+        return MENU_ELEMENT_TYPE;
+    }
+
+    /**
+     * getName - get name of menu
+     *
+     * @return menu name
+     */
+    public String getName()
+    {
+        return definition.getName();
+    }
+
+    /**
+     * getTitle - get default title for menu element
+     *
+     * @return title text
+     */
+    public String getTitle()
+    {
+        // return definition title
+        String title = definition.getTitle();
+        if (title != null)
+        {
+            return title;
+        }
+        // return node or default title
+        return super.getTitle();
+    }
+
+    /**
+     * getShortTitle - get default short title for menu element
+     *
+     * @return short title text
+     */
+    public String getShortTitle()
+    {
+        // return definition short title
+        String title = definition.getShortTitle();
+        if (title != null)
+        {
+            return title;
+        }
+
+        // return node or default short title
+        return super.getShortTitle();
+    }
+
+    /**
+     * getTitle - get locale specific title for menu element
+     *            from metadata
+     *
+     * @param locale preferred locale
+     * @return title text
+     */
+    public String getTitle(Locale locale)
+    {
+        // return definition short title for preferred locale
+        String title = definition.getTitle(locale);
+        if (title != null)
+        {
+            return title;
+        }
+
+        // return node or default title for preferred locale
+        return super.getTitle(locale);
+    }
+
+    /**
+     * getShortTitle - get locale specific short title for menu
+     *                 element from metadata
+     *
+     * @param locale preferred locale
+     * @return short title text
+     */
+    public String getShortTitle(Locale locale)
+    {
+        // return definition short title for preferred locale
+        String title = definition.getShortTitle(locale);
+        if (title != null)
+        {
+            return title;
+        }
+
+        // return node or default short title for preferred locale
+        return super.getShortTitle(locale);
+    }
+
+    /**
+     * getMetadata - get generic metadata for menu element
+     *
+     * @return metadata
+     */    
+    public GenericMetadata getMetadata()
+    {
+        // return definition metadata
+        GenericMetadata metadata = definition.getMetadata();
+        if ((metadata != null) && (metadata.getFields() != null) && !metadata.getFields().isEmpty())
+        {
+            return metadata;
+        }
+
+        // return node metadata
+        return super.getMetadata();
+    }
+
+    /**
+     * getSkin - get skin name for menu element
+     *
+     * @return skin name
+     */
+    public String getSkin()
+    {
+        // get skin from definition or inherit from parent menu
+        String skin = definition.getSkin();
+        if (skin == null)
+        {
+            skin = super.getSkin();
+        }
+        return skin;
+    }
+
+    /**
+     * getUrl - get url of top level folder that defined
+     *          menu options; only available for menus
+     *          defined without multiple options, nested
+     *          menus, or separators
+     *
+     * @return folder url
+     */
+    public String getUrl()
+    {
+        // return url of node associated with menu
+        // option if defined
+        if (getNode() != null)
+        {
+            return getNode().getUrl();
+        }
+        return null;
+    }
+
+    /**
+     * isHidden - get hidden state of folder that defined
+     *            menu options; only available for menus
+     *            defined without multiple options, nested
+     *            menus, or separators
+     *
+     * @return hidden state
+     */
+    public boolean isHidden()
+    {
+        // return hidden state of node associated with
+        // menu option if defined
+        if (getNode() != null)
+        {
+            return getNode().isHidden();
+        }
+        return false;
+    }
+
+    /**
+     * isSelected - return true if an option or nested
+     *              menu within this menu are selected by
+     *              the specified request context
+     *
+     * @param context request context
+     * @return selected state
+     */
+    public boolean isSelected(PortalSiteRequestContext context)
+    {
+        // menu is selected if a selected element exists
+        return (getSelectedElement(context) != null);
+    }
+
+    /**
+     * getElements - get ordered list of menu elements that
+     *               are members of this menu; possibly contains
+     *               options, nested menus, or separators
+     *
+     * @return menu elements list
+     */
+    public List getElements()
+    {
+        return elements;
+    }
+
+    /**
+     * isElementRelative - get flag that indicates whether any relative paths
+     *                     dependent on the current page in context were
+     *                     referenced while constructing menu elements
+     *
+     * @return relative element status
+     */
+    public boolean isElementRelative()
+    {
+        return elementRelative;
+    }
+
+    /**
+     * getSelectedElement - return selected option or nested
+     *                      menu within this menu selected by
+     *                      the specified request context
+     *
+     * @return selected menu element
+     */
+    public MenuElement getSelectedElement(PortalSiteRequestContext context)
+    {
+        // test nested menu and option menu
+        // elements for selected status
+        if (elements != null)
+        {
+            Iterator elementsIter = elements.iterator();
+            while (elementsIter.hasNext())
+            {
+                MenuElement element = (MenuElement)elementsIter.next();
+                
+                // test element selected
+                boolean selected = false;
+                if (element instanceof MenuOption)
+                {
+                    selected = ((MenuOption)element).isSelected(context);
+                }
+                else if (element instanceof Menu)
+                {
+                    selected = ((Menu)element).isSelected(context);
+                }
+                
+                // return selected element
+                if (selected)
+                {
+                    return element;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * orderRegexpPattern - tests for and converts simple order wildcard
+     *                      and character class regular exressions to
+     *                      perl5/standard java pattern syntax
+     *
+     * @param regexp - candidate order regular expression
+     * @return - converted pattern
+     */
+    private static String orderRegexpPattern(String regexp)
+    {
+        // convert expression to pattern
+        StringBuffer pattern = null;
+        for (int i = 0, limit = regexp.length(); (i < limit); i++)
+        {
+            char regexpChar = regexp.charAt(i);
+            switch (regexpChar)
+            {
+                case '*':
+                case '.':
+                case '?':
+                case '[':
+                    if (pattern == null)
+                    {
+                        pattern = new StringBuffer(regexp.length()*2);
+                        pattern.append(regexp.substring(0, i));
+                    }
+                    switch (regexpChar)
+                    {
+                        case '*':
+                            pattern.append("[^"+Folder.PATH_SEPARATOR+"]*");
+                            break;
+                        case '.':
+                            pattern.append("\\.");
+                            break;
+                        case '?':
+                            pattern.append("[^"+Folder.PATH_SEPARATOR+"]");
+                            break;
+                        case '[':
+                            pattern.append('[');
+                            break;
+                    }
+                    break;
+                default:
+                    if (pattern != null)
+                    {
+                        pattern.append(regexpChar);
+                    }
+                    break;
+            }
+        }
+
+        // return converted pattern
+        if (pattern != null)
+            return pattern.toString();
+        return regexp;
+    }
+}

Propchange: portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/MenuImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/MenuOptionImpl.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/MenuOptionImpl.java?rev=209305&view=auto
==============================================================================
--- portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/MenuOptionImpl.java (added)
+++ portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/MenuOptionImpl.java Tue Jul  5 11:58:05 2005
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.jetspeed.portalsite.impl;
+
+import org.apache.jetspeed.om.folder.Folder;
+import org.apache.jetspeed.om.folder.MenuOptionsDefinition;
+import org.apache.jetspeed.om.page.Link;
+import org.apache.jetspeed.om.page.Page;
+import org.apache.jetspeed.page.document.Node;
+import org.apache.jetspeed.page.document.NodeNotFoundException;
+import org.apache.jetspeed.portalsite.MenuOption;
+import org.apache.jetspeed.portalsite.PortalSiteRequestContext;
+
+/**
+ * This class implements the portal-site menu option
+ * elements constructed and returned to decorators.
+ * 
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id$
+ */
+public class MenuOptionImpl extends MenuElementImpl implements MenuOption, Cloneable
+{
+    /**
+     * definition - menu option definition
+     */
+    private MenuOptionsDefinition definition;
+
+    /**
+     * MenuOptionImpl - constructor
+     *
+     * @param parent containing menu implementation
+     * @param node menu option node proxy
+     * @param definition menu option definition
+     */
+    public MenuOptionImpl(MenuImpl parent, Node node, MenuOptionsDefinition definition)
+    {
+        super(parent, node);
+        this.definition = definition;
+    }
+
+    /**
+     * getElementType - get type of menu element
+     *
+     * @return OPTION_ELEMENT_TYPE
+     */
+    public String getElementType()
+    {
+        return OPTION_ELEMENT_TYPE;
+    }
+
+    /**
+     * getType - get type of menu option
+     *
+     * @return FOLDER_OPTION_TYPE, PAGE_OPTION_TYPE, or
+     *         LINK_OPTION_TYPE
+     */
+    public String getType()
+    {
+        // return type of menu option node proxy
+        Node node = getNode();
+        if (node instanceof Page)
+        {
+            return PAGE_OPTION_TYPE;
+        }
+        else if (node instanceof Link)
+        {
+            return LINK_OPTION_TYPE;
+        }
+        else if (node instanceof Folder)
+        {
+            return FOLDER_OPTION_TYPE;
+        }
+        return null;
+    }
+
+    /**
+     * getSkin - get skin name for menu element
+     *
+     * @return skin name
+     */
+    public String getSkin()
+    {
+        // get skin from definition or inherit from parent menu
+        String skin = definition.getSkin();
+        if (skin == null)
+        {
+            skin = super.getSkin();
+        }
+        return skin;
+    }
+
+    /**
+     * getUrl - get url of menu option
+     *
+     * @return folder, page, or link url
+     */
+    public String getUrl()
+    {
+        return getNode().getUrl();
+    }
+
+    /**
+     * getTarget - get target for url of menu option
+     *
+     * @return url target
+     */
+    public String getTarget()
+    {
+        // only link nodes support target
+        Node node = getNode();
+        if (node instanceof Link)
+        {
+            return ((Link)node).getTarget();
+        }
+        return null;
+    }
+
+    /**
+     * isHidden - get hidden state of menu option
+     *
+     * @return hidden state
+     */
+    public boolean isHidden()
+    {
+        return getNode().isHidden();
+    }
+
+    /**
+     * isSelected - return true if menu option is selected by
+     *              the specified request context
+     *
+     * @param context request context
+     * @return selected state
+     */
+    public boolean isSelected(PortalSiteRequestContext context)
+    {
+        // compare the site view url of the page or
+        // folder menu option proxy with the url of
+        // the context request profiled page proxy
+        if (context != null)
+        {
+            // get request page
+            Page requestPage = null;
+            try
+            {
+                requestPage = context.getPage();
+            }
+            catch (NodeNotFoundException nnfe)
+            {
+            }
+            catch (SecurityException se)
+            {
+            }
+            if (requestPage != null)
+            {
+                // get selected status based or request page url
+                Node node = getNode();
+                if (node instanceof Page)
+                {
+                    // page urls must match the request page
+                    // urls to be considered selected
+                    return requestPage.getUrl().equals(node.getUrl());
+                }
+                else if (node instanceof Folder)
+                {
+                    // folder urls must be a prefix of the
+                    // request page urls to be considered
+                    // selected
+                    return requestPage.getUrl().startsWith(node.getUrl());
+                }
+            }
+        }
+        return false;
+    }
+}

Propchange: portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/MenuOptionImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/MenuSeparatorImpl.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/MenuSeparatorImpl.java?rev=209305&view=auto
==============================================================================
--- portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/MenuSeparatorImpl.java (added)
+++ portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/MenuSeparatorImpl.java Tue Jul  5 11:58:05 2005
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.jetspeed.portalsite.impl;
+
+import java.util.Locale;
+
+import org.apache.jetspeed.om.common.GenericMetadata;
+import org.apache.jetspeed.om.folder.MenuSeparatorDefinition;
+import org.apache.jetspeed.portalsite.MenuSeparator;
+
+/**
+ * This class implements the portal-site menu separator
+ * elements constructed and returned to decorators.
+ * 
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id$
+ */
+public class MenuSeparatorImpl extends MenuElementImpl implements MenuSeparator, Cloneable
+{
+    /**
+     * definition - menu separator definition
+     */
+    private MenuSeparatorDefinition definition;
+
+    /**
+     * MenuSeparatorImpl - constructor
+     *
+     * @param parent containing menu implementation
+     * @param definition menu separator definition
+     */
+    public MenuSeparatorImpl(MenuImpl parent, MenuSeparatorDefinition definition)
+    {
+        super(parent);
+        this.definition = definition;
+    }
+
+    /**
+     * getElementType - get type of menu element
+     *
+     * @return SEPARATOR_ELEMENT_TYPE
+     */
+    public String getElementType()
+    {
+        return SEPARATOR_ELEMENT_TYPE;
+    }
+
+    /**
+     * getTitle - get default title for menu element
+     *
+     * @return title text
+     */
+    public String getTitle()
+    {
+        // return definition title
+        String title = definition.getTitle();
+        if (title != null)
+        {
+            return title;
+        }
+
+        // return node or default title
+        return super.getTitle();
+    }
+
+    /**
+     * getText - get default text for menu separator
+     *
+     * @return text
+     */
+    public String getText()
+    {
+        // return definition text
+        return definition.getText();
+    }
+
+    /**
+     * getTitle - get locale specific title for menu element
+     *            from metadata
+     *
+     * @param locale preferred locale
+     * @return title text
+     */
+    public String getTitle(Locale locale)
+    {
+        // return definition short title for preferred locale
+        String title = definition.getTitle(locale);
+        if (title != null)
+        {
+            return title;
+        }
+
+        // return node or default title for preferred locale
+        return super.getTitle(locale);
+    }
+
+    /**
+     * getText - get locale specific text for menu separator
+     *           from metadata
+     *
+     * @param locale preferred locale
+     * @return text
+     */
+    public String getText(Locale locale)
+    {
+        // return definition text
+        return definition.getText(locale);
+    }
+
+    /**
+     * getMetadata - get generic metadata for menu element
+     *
+     * @return metadata
+     */    
+    public GenericMetadata getMetadata()
+    {
+        // return definition metadata
+        GenericMetadata metadata = definition.getMetadata();
+        if ((metadata != null) && (metadata.getFields() != null) && !metadata.getFields().isEmpty())
+        {
+            return metadata;
+        }
+
+        // return node metadata
+        return super.getMetadata();
+    }
+
+    /**
+     * getSkin - get skin name for menu element
+     *
+     * @return skin name
+     */
+    public String getSkin()
+    {
+        // get skin from definition or inherit from parent menu
+        String skin = definition.getSkin();
+        if (skin == null)
+        {
+            skin = super.getSkin();
+        }
+        return skin;
+    }
+}

Propchange: portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/MenuSeparatorImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/PortalSiteImpl.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/PortalSiteImpl.java?rev=209305&view=auto
==============================================================================
--- portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/PortalSiteImpl.java (added)
+++ portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/PortalSiteImpl.java Tue Jul  5 11:58:05 2005
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.jetspeed.portalsite.impl;
+
+import org.apache.jetspeed.page.PageManager;
+import org.apache.jetspeed.portalsite.PortalSite;
+import org.apache.jetspeed.portalsite.PortalSiteSessionContext;
+
+/**
+ * This class implements the portal-site component.
+ * 
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id$
+ */
+public class PortalSiteImpl implements PortalSite
+{
+    /**
+     * pageManager - PageManager component
+     */
+    private PageManager pageManager;
+
+    /**
+     * PortalSiteImpl - component constructor
+     *
+     * @param pageManager PageManager component instance
+     */
+    public PortalSiteImpl(PageManager pageManager)
+    {
+        this.pageManager = pageManager;
+    }
+
+    /**
+     * newSessionContext - create a new session context instance
+     *
+     * @return new session context instance
+     */
+    public PortalSiteSessionContext newSessionContext()
+    {
+        return new PortalSiteSessionContextImpl(pageManager);
+    }
+
+    /**
+     * getPageManager - return PageManager component instance
+     *
+     * @return PageManager instance
+     */
+    public PageManager getPageManager()
+    {
+        return pageManager;
+    }
+}

Propchange: portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/PortalSiteImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/PortalSiteRequestContextImpl.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/PortalSiteRequestContextImpl.java?rev=209305&view=auto
==============================================================================
--- portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/PortalSiteRequestContextImpl.java (added)
+++ portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/PortalSiteRequestContextImpl.java Tue Jul  5 11:58:05 2005
@@ -0,0 +1,427 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.jetspeed.portalsite.impl;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.jetspeed.om.folder.Folder;
+import org.apache.jetspeed.om.folder.MenuDefinition;
+import org.apache.jetspeed.om.page.Page;
+import org.apache.jetspeed.page.document.NodeException;
+import org.apache.jetspeed.page.document.NodeNotFoundException;
+import org.apache.jetspeed.page.document.NodeSet;
+import org.apache.jetspeed.portalsite.Menu;
+import org.apache.jetspeed.portalsite.PortalSiteRequestContext;
+import org.apache.jetspeed.portalsite.PortalSiteSessionContext;
+import org.apache.jetspeed.portalsite.view.SiteViewMenuDefinitionLocator;
+
+/**
+ * This class encapsulates managed request state for and
+ * interface to the portal-site component.
+ * 
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id$
+ */
+public class PortalSiteRequestContextImpl implements PortalSiteRequestContext
+{
+    /**
+     * sessionContext - component session state/interface
+     */
+    private PortalSiteSessionContextImpl sessionContext;
+
+    /**
+     * requestProfileLocators - map of request profile locators by locator names
+     */
+    private Map requestProfileLocators;
+
+    /**
+     * page - cached request profiled page proxy
+     */
+    private Page requestPage;
+
+    /**
+     * rootFolder - cached request profiled root folder proxy
+     */
+    private Folder requestRootFolder;
+
+    /**
+     * pageMenuDefinitionNames - cached menu definition names for request page
+     */
+    private Set pageMenuDefinitionNames;
+
+    /**
+     * menuDefinitionLocatorCache - cached menu definition locators for
+     *                              relative menus valid for request
+     */
+    private Map menuDefinitionLocatorCache;
+
+    /**
+     * PortalSiteRequestContextImpl - constructor
+     *
+     * @param sessionContext session context
+     * @param requestProfileLocators request profile locators
+     */
+    public PortalSiteRequestContextImpl(PortalSiteSessionContextImpl sessionContext, Map requestProfileLocators)
+    {
+        this.sessionContext = sessionContext;
+        this.requestProfileLocators = requestProfileLocators;
+    }
+
+    /**
+     * getSessionContext - get component session context
+     *
+     * @return component session context
+     */
+    public PortalSiteSessionContext getSessionContext()
+    {
+        return sessionContext;
+    }
+
+    /**
+     * getLocators - get profile locators by locator names
+     *  
+     * @return request profile locators
+     */
+    public Map getLocators()
+    {
+        return requestProfileLocators;
+    }
+
+    /**
+     * getManagedPage - get request profiled concrete page instance
+     *                  as managed by the page manager
+     *  
+     * @return managed page
+     * @throws NodeNotFoundException if page not found
+     * @throws SecurityException if page view access not granted
+     */
+    public Page getManagedPage() throws NodeNotFoundException
+    {
+        return sessionContext.getManagedPage(getPage());            
+    }
+
+    /**
+     * getPage - get request profiled page proxy
+     *  
+     * @return page proxy
+     * @throws NodeNotFoundException if page not found
+     * @throws SecurityException if page view access not granted
+     */
+    public Page getPage() throws NodeNotFoundException
+    {
+        // select request page from session context using
+        // request profile locators if not previously
+        // cached in this context
+        if (requestPage == null)
+        {
+            requestPage = sessionContext.selectRequestPage(requestProfileLocators);            
+        }
+        return requestPage;
+    }
+
+    /**
+     * getFolder - get folder proxy relative to request profiled page
+     *  
+     * @return page folder proxy
+     * @throws NodeNotFoundException if page not found
+     * @throws SecurityException if page view access not granted
+     */
+    public Folder getFolder() throws NodeNotFoundException
+    {
+        // return parent folder of request page
+        Page page = getPage();
+        if (page != null)
+        {
+            return (Folder)page.getParent();
+        }
+        return null;
+    }
+
+    /**
+     * getSiblingPages - get node set of sibling page proxies relative
+     *                   to request profiled page, (includes profiled
+     *                   page proxy)
+     *  
+     * @return sibling page proxies
+     * @throws NodeNotFoundException if page not found
+     * @throws SecurityException if page view access not granted
+     */
+    public NodeSet getSiblingPages() throws NodeNotFoundException
+    {
+        // return pages from parent folder of request page
+        Folder folder = getFolder();
+        if (folder != null)
+        {
+            try
+            {
+                return folder.getPages();
+            }
+            catch (NodeException ne)
+            {
+                NodeNotFoundException nnfe = new NodeNotFoundException("Sibling pages not found.");
+                nnfe.initCause(ne);
+                throw nnfe;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * getParentFolder - get parent folder proxy relative to request
+     *                   profiled page
+     *  
+     * @return parent folder proxy or null
+     * @throws NodeNotFoundException if page not found
+     * @throws SecurityException if page view access not granted
+     */
+    public Folder getParentFolder() throws NodeNotFoundException
+    {
+        // return parent folder of parent folder of request page
+        Folder folder = getFolder();
+        if (folder != null)
+        {
+            return (Folder)folder.getParent();
+        }
+        return null;
+    }
+
+    /**
+     * getSiblingFolders - get node set of sibling folder proxies relative
+     *                     to request profiled page, (includes profiled
+     *                     page folder proxy)
+     *  
+     * @return sibling folder proxies
+     * @throws NodeNotFoundException if page not found
+     * @throws SecurityException if page view access not granted
+     */
+    public NodeSet getSiblingFolders() throws NodeNotFoundException
+    {
+        // return folders from parent folder of request page
+        Folder folder = getFolder();
+        if (folder != null)
+        {
+            try
+            {
+                return folder.getFolders();
+            }
+            catch (NodeException ne)
+            {
+                NodeNotFoundException nnfe = new NodeNotFoundException("Sibling folders not found.");
+                nnfe.initCause(ne);
+                throw nnfe;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * getRootFolder - get root profiled folder proxy
+     *  
+     * @return parent folder proxy
+     * @throws NodeNotFoundException if page not found
+     * @throws SecurityException if page view access not granted
+     */
+    public Folder getRootFolder() throws NodeNotFoundException
+    {
+        // get request root folder from session context
+        // using request profile locators if not previously
+        // cached in this context
+        if (requestRootFolder == null)
+        {
+            requestRootFolder = sessionContext.getRequestRootFolder(requestProfileLocators);
+        }
+        return requestRootFolder;
+    }
+
+    /**
+     * getRootLinks - get node set of link proxies relative to
+     *                profiled root folder
+     *  
+     * @return root link proxies
+     * @throws NodeNotFoundException if page not found
+     * @throws SecurityException if page view access not granted
+     */
+    public NodeSet getRootLinks() throws NodeNotFoundException
+    {
+        // return links from request root folder
+        Folder rootFolder = getRootFolder();
+        if (rootFolder != null)
+        {
+            try
+            {
+                return rootFolder.getLinks();
+            }
+            catch (NodeException ne)
+            {
+                NodeNotFoundException nnfe = new NodeNotFoundException("Root links not found.");
+                nnfe.initCause(ne);
+                throw nnfe;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * getStandardMenuNames - get set of available standard menu names
+     *  
+     * @return menu names set
+     */
+    public Set getStandardMenuNames()
+    {
+        // return standard menu names defined for session
+        return sessionContext.getStandardMenuNames();
+    }
+
+    /**
+     * getCustomMenuNames - get set of custom menu names available as
+     *                      defined for the request profiled page and folder
+     *  
+     * @return menu names set
+     * @throws NodeNotFoundException if page not found
+     * @throws SecurityException if page view access not granted
+     */
+    public Set getCustomMenuNames() throws NodeNotFoundException
+    {
+        // access page to force request page resolution
+        Page page = getPage();
+
+        // return available menu definition names from
+        // current request page if not previously cached
+        // in this context
+        Set standardMenuNames = sessionContext.getStandardMenuNames();
+        if ((page != null) && (standardMenuNames != null) && (pageMenuDefinitionNames == null))
+        {
+            List locators = sessionContext.getMenuDefinitionLocators(page);
+            if (locators != null)
+            {
+                // get custom definition names
+                pageMenuDefinitionNames = new HashSet(locators.size());
+                Iterator locatorsIter = locators.iterator();
+                while (locatorsIter.hasNext())
+                {
+                    // get definition name; filter standard menu names
+                    String definitionName = ((SiteViewMenuDefinitionLocator)locatorsIter.next()).getName();
+                    if (!standardMenuNames.contains(definitionName))
+                    {
+                        pageMenuDefinitionNames.add(definitionName);
+                    }
+                }
+            }
+            else
+            {
+                pageMenuDefinitionNames = new HashSet(0);
+            }
+        }
+        return pageMenuDefinitionNames;
+    }
+
+    /**
+     * getMenu - get instantiated menu available for the request
+     *           profiled page and folder
+     *  
+     * @param name menu definition name
+     * @return menu instance
+     * @throws NodeNotFoundException if page not found
+     * @throws SecurityException if page view access not granted
+     */
+    public Menu getMenu(String name) throws NodeNotFoundException
+    {
+        // get menu initiating at menu definition root
+        // with no related menu definition names
+        return getMenu(name, null);
+    }
+
+    /**
+     * getMenu - get instantiated menu available for the request
+     *           profiled page and folder, avoiding cyclic
+     *           menu definition loops by propagating related menu
+     *           names set from menu construction
+     *
+     * @param name menu definition name
+     * @param names set of related menu definition names
+     * @return menu instance
+     * @throws NodeNotFoundException if page not found
+     * @throws SecurityException if page view access not granted
+     */
+    public Menu getMenu(String name, Set names) throws NodeNotFoundException
+    {
+        // access page to force request page resolution
+        Page page = getPage();
+        if ((page != null) && (name != null))
+        {
+            // get menu definition locator
+            SiteViewMenuDefinitionLocator locator = sessionContext.getMenuDefinitionLocator(page, name);
+            if (locator != null)
+            {
+                // lookup and return cached relative/request menus
+                if (menuDefinitionLocatorCache != null)
+                {
+                    MenuImpl menu = (MenuImpl)menuDefinitionLocatorCache.get(locator);
+                    if (menu != null)
+                    {
+                        return menu;
+                    }
+                }
+
+                // lookup and return cached absolute/session menus
+                if (sessionContext.getMenuDefinitionLocatorCache() != null)
+                {
+                    MenuImpl menu = (MenuImpl)sessionContext.getMenuDefinitionLocatorCache().get(locator);
+                    if (menu != null)
+                    {
+                        return menu;
+                    }
+                }
+
+                // construct new menu from menu definition in locator
+                // using current request context and propagating related
+                // names set to detect cyclic menu definitions
+                MenuImpl menu = new MenuImpl(locator.getMenuDefinition(), this, names);
+ 
+                // determine whether menu definition locator is
+                // relative/request or absolute/session cachable
+                // and cache accordingly
+                if (menu.isElementRelative())
+                {
+                    // cache relative menu for request
+                    if (menuDefinitionLocatorCache == null)
+                    {
+                        menuDefinitionLocatorCache = new HashMap(8);
+                    }
+                    menuDefinitionLocatorCache.put(locator, menu);
+                }
+                else
+                {
+                    // cache absolute menu for session
+                    if (sessionContext.getMenuDefinitionLocatorCache() == null)
+                    {
+                        sessionContext.setMenuDefinitionLocatorCache(new HashMap(8));
+                    }
+                    sessionContext.getMenuDefinitionLocatorCache().put(locator, menu);
+                }
+
+                // return new cached menu
+                return menu;
+            }
+        }
+        return null;
+    }
+}

Propchange: portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/PortalSiteRequestContextImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native



---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org


Mime
View raw message