You are viewing a plain text version of this content. The canonical link for it is here.
Posted to adffaces-commits@incubator.apache.org by aw...@apache.org on 2006/08/01 19:59:31 UTC
svn commit: r427701 [2/2] - in /incubator/adffaces/trunk/trinidad:
trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/
trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/menu/
Added: incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/menu/MenuNode.java
URL: http://svn.apache.org/viewvc/incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/menu/MenuNode.java?rev=427701&view=auto
==============================================================================
--- incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/menu/MenuNode.java (added)
+++ incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/menu/MenuNode.java Tue Aug 1 12:59:30 2006
@@ -0,0 +1,804 @@
+/*
+ * @(#)MenuNode.java
+ *
+ * Copyright 2006 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.myfaces.trinidadinternal.menu;
+
+import java.util.List;
+
+import java.util.Map;
+
+import javax.faces.context.FacesContext;
+import javax.faces.webapp.UIComponentTag;
+
+import org.xml.sax.Attributes;
+
+import org.apache.myfaces.trinidad.model.XMLMenuModel;
+
+/**
+ * Code generic to a Menu Nodes of the menu model.
+ *
+ * IMPORTANT NOTE: even internally, values that support EL expressions
+ * should use the "get" methods to obtain values.
+ *
+ * @author Kris McQueen and Gary Kind
+ */
+
+public class MenuNode
+{
+ /**
+ * Constructs a MenuNode
+ */
+ public MenuNode()
+ {}
+
+ /**
+ * Set the menu item's label.
+ *
+ * @param label - String name shown in the menu item
+ */
+ public void setLabel(String label)
+ {
+ _label = label;
+ }
+
+ /**
+ * Get the menu item's label
+ *
+ * This could either be a string value set directly in
+ * the metadata or an EL expression string. In the case
+ * of an EL expression, we need to get its bound value.
+ *
+ * @return label as a String
+ */
+ public String getLabel()
+ {
+ if (_bundleKey != null && _bundleName != null)
+ {
+ // Load the resource bundle based on the locale of the
+ // current request. If the locale has not changed, this
+ // method just returns.
+ MenuUtils.loadBundle(_bundleName, _bundleKey + getHandlerId());
+ }
+
+ if ( _label != null
+ && UIComponentTag.isValueReference(_label)
+ )
+ {
+ _label = _evalElStr(_label);
+ }
+ return _label;
+ }
+
+ /**
+ * Set the icon used by the menu item.
+ *
+ * @param icon - the String URI to the icon.
+ */
+ public void setIcon(String icon)
+ {
+ _icon = icon;
+ }
+
+ /**
+ * Get the icon used by the menu item
+ * This could either be a string value set directly in
+ * the metadata or an EL expression string. In the case
+ * of an EL expression, we need to get its bound value.
+ *
+ * @return icon - the String URI to the icon.
+ */
+ public String getIcon()
+ {
+ return MenuUtils.evalString(_icon);
+ }
+
+ /**
+ * Sets the rendered attribute of the menu item.
+ * If false, menu item will not appear.
+ *
+ * @param rendered - boolean that toggles the visible state of the XMLMenuModel
+ * item.
+ */
+ public void setRendered(boolean rendered)
+ {
+ _renderedStr = rendered ? "true" : "false";
+ }
+
+ /**
+ * Gets the rendered attribute of the menu item.
+ * If false, menu item will not appear.
+ *
+ * @return boolean indicating whether or not the menu item is visible.
+ */
+ public boolean getRendered()
+ {
+ boolean rendered = MenuUtils.evalBoolean(_renderedStr, true);
+ return rendered;
+ }
+
+ /**
+ * Sets the disabled attribute of the menu item.
+ * If true, menu item will not appear greyed-out and clicking
+ * on it will have no effect
+ *
+ * @param disabled - boolean that toggles the enabled/disabled state of the
+ * menu item.
+ */
+ public void setDisabled(boolean disabled)
+ {
+ _disabledStr = disabled ? "true" : "false";
+ }
+
+ /**
+ * Gets the disabled attribute of the menu item.
+ * If true, menu item will not appear greyed-out and clicking
+ * on it will have no effect
+ *
+ * @return boolean indicating whether or not the menu item is disabled.
+ */
+ public boolean getDisabled()
+ {
+ boolean disabled = MenuUtils.evalBoolean(_disabledStr, false);
+ return disabled;
+ }
+
+ /**
+ * Sets the visible attribute of the menu item.
+ * If false, menu item will not appear
+ *
+ * @param visible - boolean that toggles the visible state of the
+ * menu item.
+ */
+ public void setVisible(boolean visible)
+ {
+ _visibleStr = visible ? "true" : "false";
+ }
+
+ /**
+ * Gets the visible attribute of the menu item.
+ * If false, menu item will not appear
+ *
+ * @return boolean indicating whether or not the menu item is visible.
+ */
+ public boolean getVisible()
+ {
+ boolean visible = MenuUtils.evalBoolean(_visibleStr, true);
+ return visible;
+ }
+
+ /**
+ * Sets the defaultFocusPath attribute of the menu item.
+ *
+ * @param defaultFocusPath - boolean that tells the XMLMenuModel model that
+ * the focus path to this node should be used in cases where the focus path
+ * is not determinable by the XMLMenuModel model.
+ */
+ public void setDefaultFocusPath(boolean defaultFocusPath)
+ {
+ _defaultFocusPathStr = defaultFocusPath ? "true" : "false";
+ }
+
+ /**
+ * Gets the defaultFocusPath attribute of the menu item.
+ *
+ * @return boolean indicating whether or not this is the focus path to use,
+ * by default, in cases where there are duplicate paths to this node and
+ * the focus path is not determinable by the XMLMenuModel model.
+ */
+ public boolean getDefaultFocusPath()
+ {
+ boolean defaultFocusPath = MenuUtils.evalBoolean(_defaultFocusPathStr,
+ false);
+ return defaultFocusPath;
+ }
+
+ /**
+ * Get the List of menu item's children.
+ *
+ * @return List of menu item's children
+ */
+ public List getChildren()
+ {
+ return _children;
+ }
+
+ /**
+ * Set the List of menu item's children.
+ *
+ * @param children - List of MenuNode children for this MenuNode
+ */
+ public void setChildren(List children)
+ {
+ _children = children;
+ }
+
+ /**
+ * Gets the readOnly state of the node.
+ *
+ * @return the node's readOnly state as a boolean.
+ */
+ public boolean getReadOnly()
+ {
+ boolean readOnly = MenuUtils.evalBoolean(_readOnlyStr, false);
+ return readOnly;
+ }
+
+ /**
+ * Sets the the value of the readOnly attribute of the node.
+ *
+ * @param readOnly - boolean setting readOnly state of the node
+ */
+ public void setReadOnly(boolean readOnly)
+ {
+ _readOnlyStr = readOnly ? "true" : "false";
+ }
+
+ /**
+ * Sets the value of the node's focusViewId property.
+ *
+ * @param focusViewId - string value of the Node's "focusViewId" property.
+ */
+ public void setFocusViewId(String focusViewId)
+ {
+ _focusViewId = focusViewId;
+ }
+
+ /**
+ * Gets the value of the node's focusViewId property.
+ *
+ * @return string - the value of the Node's "focusViewId" property.
+ */
+ public String getFocusViewId()
+ {
+ return _focusViewId;
+ }
+
+ /**
+ * Sets the rendered attribute of the menu item.
+ * If false, menu item will not appear.
+ *
+ * Called only from MenuContentHandlerImpl during parsing of metadata.
+ *
+ * @param renderedStr - string representing a boolean value
+ */
+ public void setRendered(String renderedStr)
+ {
+ _renderedStr = renderedStr;
+ }
+
+ /**
+ * Sets the disabled attribute of the menu item.
+ * If false, menu item will appear in a disabled state.
+ *
+ * @param disabledStr - string representing a boolean value or
+ * an EL Expression
+ */
+ public void setDisabled(String disabledStr)
+ {
+ _disabledStr = disabledStr;
+ }
+
+ /**
+ * Sets the readOnly attribute of the menu item.
+ * If false, menu item will appear in a readOnly state.
+ *
+ * @param readOnlyStr - string representing a boolean value or EL
+ * expression.
+ */
+ public void setReadOnly(String readOnlyStr)
+ {
+ _readOnlyStr = readOnlyStr;
+ }
+
+ /**
+ * Sets the visible attribute of the menu item.
+ * If false, menu item will not appear.
+ *
+ * @param visibleStr - string representing a boolean value or
+ * an EL Expression
+ */
+ public void setVisible(String visibleStr)
+ {
+ _visibleStr = visibleStr;
+ }
+
+ /**
+ * Sets the defaultFocusPath attribute of the menu item.
+ *
+ * Called only from MenuContentHandlerImpl during parsing of metadata.
+ *
+ * @param defaultFocusPathStr - string representing a boolean value
+ */
+ public void setDefaultFocusPath(String defaultFocusPathStr)
+ {
+ _defaultFocusPathStr = defaultFocusPathStr;
+ }
+
+ /**
+ * setAccessKey - Takes either a single character String or
+ * an EL expression and sets the value of the accessKey attribute
+ * of the node.
+ *
+ * @param accessKey - Single character String or EL expression
+ * representing the label's access key.
+ */
+ public void setAccessKey (String accessKey)
+ {
+ if ( accessKey != null
+ && UIComponentTag.isValueReference(accessKey)
+ )
+ {
+ // EL Expression
+ _accessKey = accessKey;
+ }
+ else
+ {
+ // accessKey cannot be more than one character
+ if (accessKey != null && accessKey.length() > 1)
+ return;
+
+ _accessKey = accessKey;
+ }
+ }
+
+ /**
+ * setAccessKey - Takes a single character and sets the value of the
+ * accessKey attribute of the node.
+ *
+ * @param accessKey - Single character label access key.
+ */
+ public void setAccessKey (char accessKey)
+ {
+ char[] charArray = {'\0'};
+
+ charArray[0] = accessKey;
+ _accessKey = String.copyValueOf(charArray);
+ }
+
+ /**
+ * getAccessKey - get the label's accessKey as a char.
+ *
+ * @return the access key of the label as a char.
+ */
+ public char getAccessKey()
+ {
+ String accessKeyStr = MenuUtils.evalString(_accessKey);
+
+ if (accessKeyStr == null || accessKeyStr.length() > 1)
+ return '\0';
+
+ return accessKeyStr.charAt(0);
+ }
+
+ /**
+ * setLabelAndAccessKey - Takes either an EL expression or a
+ * String representing the label and accessKey together, and
+ * sets the label and the accessKey separately.
+ *
+ * @param labelAndAccessKey - either and EL Expression or
+ * a String representing the label and accessKey together.
+ */
+ public void setLabelAndAccessKey(String labelAndAccessKey)
+ {
+ int ampIdx = 0;
+ _labelAndAccessKeyEL = false;
+
+ // if EL expression, set it and the label to the same thing
+ if ( labelAndAccessKey != null
+ && UIComponentTag.isValueReference(labelAndAccessKey)
+ )
+ {
+ _labelAndAccessKey = labelAndAccessKey;
+ _labelAndAccessKeyEL = true;
+ _accessKey = null;
+ }
+ else if ( labelAndAccessKey == null
+ || (ampIdx = labelAndAccessKey.indexOf('&')) == -1
+ )
+ {
+ // String is null or a label w/o an accesskey
+ _label = labelAndAccessKey;
+ _accessKey = null;
+ }
+ else if (ampIdx == (labelAndAccessKey.length() - 1))
+ {
+ // & is last character, strip it.
+ _label = labelAndAccessKey.substring(0, ampIdx);
+ _accessKey = null;
+ }
+ else
+ {
+ // We have a string with an accessKey somewhere
+ _splitLabelAndAccessKey(labelAndAccessKey);
+ }
+ }
+
+ /**
+ * getLabelAndAccessKey - get the label and accessKey together
+ * in a single string.
+ *
+ * @return a String containing (representing) the label and accessKey
+ * together.
+ */
+ public String getLabelAndAccessKey()
+ {
+ // If labelAndAccessKey is an EL expression
+ // we get it and process it, set the label
+ // and the accessKey, null out labelAndAccessKey
+ // and set labelAndAccessKeyEL to false
+ if (_labelAndAccessKeyEL)
+ {
+ _labelAndAccessKey = _evalElStr(_labelAndAccessKey);
+ setLabelAndAccessKey(_labelAndAccessKey);
+ _labelAndAccessKey = null;
+ _labelAndAccessKeyEL = false;
+ }
+ // Now it is a simple string, so we have already
+ // set the label and accessKey. We get both the
+ // label and accessKey, construct a labelAndAccessKey
+ // and return it.
+ String label = getLabel(); // This is a simple string
+
+ if (_accessKey == null)
+ return label; // String is just the label
+
+ return _joinLabelAndAccessKey(label, _accessKey);
+ }
+
+ /**
+ * setId - sets the id of the node.
+ *
+ * @param id - the identifier for the node component
+ */
+ public void setId (String id)
+ {
+ _id = id;
+ }
+
+ /**
+ * getId - gets the id of the node.
+ *
+ * @return - String identifier for the node component.
+ */
+ public String getId()
+ {
+ return _id;
+ }
+
+ /*===========================================================================
+ * getRefNode(), doAction(), & getDestination() are never called. They
+ * are just here so that the same methods in itemNode.java and GroupNode.java
+ * will compile.
+ * ==========================================================================
+ */
+ /**
+ * Get the node whose id matches this node's
+ * idref attribute value.
+ *
+ * @return the MenuNode whose id matches this
+ * node's idref attribute value.
+ */
+ public MenuNode getRefNode()
+ {
+ return this;
+ }
+
+ /**
+ * Called by the Default ActionListener
+ * when a menu node is clicked/selected.
+ *
+ * @return String outcome or viewId used
+ * during a POST for navigation.
+ */
+ public String doAction()
+ {
+ // Call the doAction method of my idref node
+ return getRefNode().doAction();
+ }
+
+ /**
+ * Get the Destination URL of a page for a
+ * GET.
+ *
+ * @return String URL of a page.
+ */
+ public String getDestination()
+ {
+ // Call the doAction method of my idref node
+ return getRefNode().getDestination();
+ }
+
+ /**
+ * Get the value of a custom attribute. This needs to be
+ * public so that the menu model can call into the node
+ * to get the value of a custom attribute.
+ *
+ * @param name String name of the custom attribute
+ * @return Object value of the matching node
+ */
+ public Object getCustomProperty(String name)
+ {
+ String value = _customPropList.getValue(name);
+
+ if ( value != null
+ && UIComponentTag.isValueReference(value)
+ )
+ {
+ return MenuUtils.getBoundValue(value);
+ }
+
+ return value;
+ }
+
+ /**
+ * Get the Attributes containing the custom attributes on this node. This
+ * needs to be public so that the menu model can get them.
+ *
+ * @return Attributes list containing the custom attributes on this node
+ */
+ public Attributes getCustomPropList()
+ {
+ return _customPropList;
+ }
+
+ /**
+ * Set the list of custom attributes.
+ *
+ * @param attrList Attributes List for this node from MenuContentHandlerImpl
+ */
+ protected void setCustomPropList(Attributes attrList)
+ {
+ _customPropList = attrList;
+ }
+
+ /**
+ * setResBundleKey - sets the name of the resource bundle used in
+ * obtaining the node's label text. Used, along with the handerId,
+ * to identify and get a string from the proper resource bundle.
+ *
+ * @param bundleKey - String name of the resource bundle.
+ */
+ protected void setResBundleKey(String bundleKey)
+ {
+ _bundleKey = bundleKey;
+ }
+
+ /**
+ * setResBundleKey - sets the name of the resource bundle used in
+ * obtaining the node's label text. Used, along with the handerId,
+ * to identify and get a string from the proper resource bundle.
+ *
+ * @param bundleName - String name of the resource bundle.
+ */
+ protected void setResBundleName(String bundleName)
+ {
+ _bundleName = bundleName;
+ }
+
+ /**
+ * setHandlerId - sets the MenuContentHandlerImpl's handlerId on the node.
+ * Used, along with the bundleKey, to identify and get a string from the
+ * proper resource bundle.
+ *
+ * @param handlerId String uniquely identifying the specific
+ * MenuContentHandlerImpl that created this node.
+ */
+ protected void setHandlerId(String handlerId)
+ {
+ _handlerId = handlerId;
+ }
+
+ /**
+ * Notifies the root model that this node has been selected on a POST
+ *
+ * @param selectedNode - The currently selected menu item.
+ */
+ protected void postSelectedNode(MenuNode selectedNode)
+ {
+ getRootModel().setCurrentlyPostedNode(selectedNode);
+ }
+
+ /**
+ * Set the MenuContentHandlerImpl's id.
+ *
+ * This is appended to the node's id in getId() to
+ * ensure that each node's id is unique.
+ *
+ * @return String object id of the MenuContentHandlerImpl
+ */
+ protected String getHandlerId()
+ {
+ return _handlerId;
+ }
+
+ /**
+ * Get the top-level, root menu model, which contains
+ * the entire menu tree.
+ *
+ * @return root, top-level XMLMenuModel
+ */
+ protected XMLMenuModel getRootModel()
+ {
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ Map requestMap = facesContext.getExternalContext().getRequestMap();
+
+ return (XMLMenuModel) requestMap.get(getRootModelUri());
+ }
+
+ /**
+ * Get the top-level, root menu model's Uri.
+ *
+ * @return root, top-level XMLMenuModel's Uri
+ */
+ public String getRootModelUri()
+ {
+ return _rootModelUri;
+ }
+
+ /**
+ * Sets the root menu Model's Uri.
+ * <p>
+ * This is always only the top-level, root model's Uri.
+ * We do this because the MenuContentHandlerImpl and nodes need to be able
+ * to call into the root model to:
+ * <ul>
+ * <li>notify them root menu model of the currently selected node on a POST
+ * </ul>
+ *
+ * @param rootModelUri - String the root, top-level menu model's Uri.
+ */
+ public void setRootModelUri(String rootModelUri)
+ {
+ _rootModelUri = rootModelUri;
+ }
+
+ /**
+ * _joinLabelAndAccessKey - takes a string label and string accessKey
+ * and combines them into a single labelAndAccessKey string.
+ *
+ * @param label - String with node's label.
+ * @param accessKey - One character String which is the label's accessKey.
+ * @return
+ */
+ private String _joinLabelAndAccessKey(String label, String accessKey)
+ {
+ char[] keyArray = label.toCharArray();
+ int len = label.length();
+ int lentimes2 = len*2;
+ char[] keyArray2 = new char[lentimes2];
+ int i, j = 0;
+ boolean accessKeyFound = false;
+
+ // find the first occurrence of a single Ampersand
+ for (i=0, j=0; i < len; i++, j++)
+ {
+ // AccessKey
+ if ( keyArray[i] == accessKey.charAt(0)
+ && !accessKeyFound
+ )
+ {
+ keyArray2[j] = '&';
+ j++;
+ accessKeyFound = true;
+ }
+
+ keyArray2[j] = keyArray[i];
+
+ // Ampersand as regular character
+ // double it up.
+ if (keyArray[i] == '&')
+ {
+ j++;
+ keyArray2[j] = keyArray[i];
+ }
+ }
+
+ String combinedLabel = new String(keyArray2, 0, j);
+ return combinedLabel;
+ }
+
+ /**
+ * _splitLabelAndAccessKey - takes a string containing a label
+ * and an accessKey and breaks separates it and sets the label
+ * and the accessKey separately.
+ *
+ * @param labelAndAccessKey - String holding both a label and
+ * accessKey.
+ */
+ private void _splitLabelAndAccessKey(String labelAndAccessKey)
+ {
+ char[] keyArray = labelAndAccessKey.toCharArray();
+ int len = labelAndAccessKey.length();
+ char[] keyArray2 = new char[len];
+ int i, j = 0;
+ boolean accessKeyFound = false;
+
+ for (i=0, j=0; i < len ; i++, j++)
+ {
+ if (keyArray[i] == '&')
+ {
+ i++;
+
+ if (!accessKeyFound && keyArray[i] != '&')
+ {
+ // We have our accessKey
+ _accessKey = labelAndAccessKey.substring(i, i+1);
+ accessKeyFound = true;
+ }
+ }
+
+ keyArray2[j] = keyArray[i];
+ }
+
+ String label = new String(keyArray2, 0, j);
+ _label = label;
+ }
+
+ /**
+ * _evalElStr - Evaluate an EL expression string.
+ *
+ * @param str - the EL expression
+ * @return the bound value of the El expression as a String
+ */
+ private String _evalElStr(String str)
+ {
+ // Check to see if EL expression gets its value from a
+ // resource bundle.
+ String elVar = str.substring(2, str.indexOf('.'));
+
+ if ( _bundleKey != null
+ && _bundleKey.equals(elVar)
+ )
+ {
+ // we have an EL expression to get a value from a
+ // resource bundle
+ elVar = str.substring(0, str.indexOf('.'));
+ String elKey = str.substring(str.indexOf('.'));
+ String elStr = elVar + getHandlerId() + elKey;
+ String elVal = (String)MenuUtils.getBoundValue(elStr);
+ return elVal;
+ }
+ else
+ {
+ // We have some other EL expression
+ return (String)MenuUtils.getBoundValue(str);
+ }
+ }
+
+ private String _label = null;
+ private String _icon = null;
+ private List _children = null;
+ private String _focusViewId = null;
+ private String _renderedStr = null;
+ private String _disabledStr = null;
+ private String _visibleStr = null;
+ private String _readOnlyStr = null;
+ private String _handlerId = null;
+ private String _bundleKey = null;
+ private String _bundleName = null;
+ private String _accessKey = null;
+ private String _id = null;
+ private boolean _labelAndAccessKeyEL = false;
+ private String _labelAndAccessKey = null;
+ private String _defaultFocusPathStr = null;
+
+ // Map for Custom attributes (properties)
+ private Attributes _customPropList = null;
+
+ // Menu model Uri's
+ private String _rootModelUri = null;
+}
Added: incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/menu/MenuUtils.java
URL: http://svn.apache.org/viewvc/incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/menu/MenuUtils.java?rev=427701&view=auto
==============================================================================
--- incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/menu/MenuUtils.java (added)
+++ incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/menu/MenuUtils.java Tue Aug 1 12:59:30 2006
@@ -0,0 +1,403 @@
+/*
+ * @(#)MenuUtils.java
+ *
+ *
+ * Copyright 2006 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.myfaces.trinidadinternal.menu;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.Set;
+
+import javax.faces.context.FacesContext;
+import javax.faces.el.ValueBinding;
+
+import javax.faces.webapp.UIComponentTag;
+
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+
+/**
+ * Menu Utilities used by the Menu Model internal code.
+ * All classes are package private.
+ *
+ * @author Gary Kind
+ */
+class MenuUtils
+{
+ MenuUtils() {}
+
+ //=======================================================================
+ // Bound Value/EL Binding utilities
+ //=======================================================================
+
+ /**
+ * Gets the bound value of an EL expression
+ *
+ * @param elExpression - String representing an EL expression
+ */
+ static Object getBoundValue(String elExpression)
+ {
+ Object retVal = null;
+
+ try
+ {
+ // Value of rendered is EL method binding, so we
+ // need to evaluate it
+ FacesContext ctx = FacesContext.getCurrentInstance();
+ ValueBinding binding =
+ ctx.getApplication().createValueBinding(elExpression);
+ retVal = binding.getValue(ctx);
+ }
+ catch (Exception ex)
+ {
+ _LOG.severe("EL Expression " + elExpression +
+ " is invalid or returned a bad value.\n", ex);
+ return null;
+ }
+ return retVal;
+ }
+
+ /**
+ * Evaluate an attribute value string representing a boolean value
+ * and return its boolean value. There are 3 possible valid values for
+ * boolStr:
+ * o EL Expression (that returns a boolean)
+ * o the string "true"
+ * o the string "false"
+ *
+ * In the case of another string being passed in, the default value
+ * of the attribute is returned.
+ *
+ * @param boolStr - String to be evaluated into a boolean.
+ * @param defaultVal - The default boolean value to be returned in the case
+ * where and invalid boolstr is passed in.
+ * @return boolean value equivalent of boolStr
+ */
+ static boolean evalBoolean (String boolStr, boolean defaultVal)
+ {
+ if ( boolStr != null
+ && UIComponentTag.isValueReference(boolStr)
+ )
+ {
+ Boolean bValue = (Boolean) getBoundValue(boolStr);
+ return bValue.booleanValue();
+ }
+ else
+ {
+ if ("true".equals(boolStr) || "false".equals(boolStr))
+ return (Boolean.valueOf(boolStr)).booleanValue();
+ else
+ return defaultVal;
+ }
+ }
+
+ /**
+ * Evaluate a string representing an EL expression.
+ *
+ * @param propVal - string to be evaluated.
+ * @return the string bound value of the EL Expression
+ */
+ static String evalString(String propVal)
+ {
+ if ( propVal != null
+ && UIComponentTag.isValueReference(propVal)
+ )
+ {
+ String elVal = (String) getBoundValue(propVal);
+ return elVal;
+ }
+ return propVal;
+ }
+
+ /**
+ * Evaluate a string representing an EL expression.
+ *
+ * @param propVal - string to be evaluated.
+ * @return the int bound value of the EL Expression
+ */
+ static int evalInt(String propVal)
+ {
+ if ( propVal != null
+ && UIComponentTag.isValueReference(propVal)
+ )
+ {
+ Integer elVal = (Integer) getBoundValue(propVal);
+ return elVal.intValue();
+ }
+ return Integer.parseInt(propVal);
+ }
+
+ /**
+ * Create a ResourceBundle and put it on the Session map.
+ *
+ * @param resBundle - String containing name of class containing the resource
+ * bundle.
+ * @param key - ThreadLocal key for the resource bundle being put on the
+ * sessionMap
+ */
+ static void loadBundle(String resBundle, ThreadLocal key)
+ {
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ Map applicationMap = facesContext.getExternalContext().getApplicationMap();
+
+ // Get the request Locale
+ Locale requestLocale = facesContext.getExternalContext().getRequestLocale();
+
+ // Make sure it is not null
+ if (requestLocale == null)
+ {
+ requestLocale = facesContext.getViewRoot().getLocale();
+
+ if (requestLocale == null)
+ {
+ requestLocale = facesContext.getApplication().getDefaultLocale();
+ }
+ }
+
+ // Is there a bundle with this key already on the session map?
+ _BundleMap bundleMap = (_BundleMap) applicationMap.get((String) key.get());
+
+ // if so, get its locale. If the locale has not
+ // changed, just return, i.e. use the existing bundle
+ if (bundleMap != null)
+ {
+ Locale bundleLocale = bundleMap.getLocale();
+
+ if (bundleLocale == null)
+ {
+ ResourceBundle rb = bundleMap.getBundle();
+ bundleLocale = rb.getLocale();
+ }
+
+ if (requestLocale == bundleLocale)
+ {
+ // the bundle on the applicationMap is ok so just return
+ return;
+ }
+ }
+
+ String bundleName = null;
+
+ if (resBundle != null)
+ {
+ // if _bundleName is an EL, then get its value
+ if (UIComponentTag.isValueReference(resBundle))
+ {
+ bundleName = (String)MenuUtils.getBoundValue(resBundle);
+ }
+ else
+ {
+ bundleName = resBundle ;
+ }
+ }
+
+ final ResourceBundle bundle;
+
+ try
+ {
+ bundle = ResourceBundle.getBundle(bundleName, requestLocale);
+ }
+ catch (MissingResourceException e)
+ {
+ _LOG.severe("Resource bundle " + bundleName + " could not be found.", e);
+ return;
+ }
+
+ // Put the bundle in the map. At this point the key is
+ // unique because of the handler Id we inserted when loadBundle
+ // was called.
+ applicationMap.put((String)key.get(), new _BundleMap(bundle, requestLocale));
+ }
+
+ /**
+ * Create a ResourceBundle and put it on the Session map.
+ * The key is made into a ThreadLocal to ensure that this the resource
+ * bundle is threadsafe.
+ *
+ * @param resBundleName - String containing name of class containing the
+ * resource bundle.
+ * @param resBundleKey - String key for the resource bundle being put on the
+ * sessionMap
+ */
+ static void loadBundle(String resBundleName, String resBundleKey)
+ {
+ ThreadLocal bundleKey = new ThreadLocal();
+
+ bundleKey.set(resBundleKey);
+ loadBundle(resBundleName, bundleKey);
+ }
+
+ /**
+ * Map containing a resource bundle and its key that is placed
+ * on the http request map. This resource bundle is used by the menu
+ * model metadata to externalize strings, such as tab labels, for
+ * translation.
+ */
+ static private class _BundleMap implements Map
+ {
+ private ResourceBundle _bundle;
+ private Locale _locale;
+ private List _values;
+ Object retVal = null;
+
+ public _BundleMap(ResourceBundle bundle)
+ {
+ _bundle = bundle;
+ _locale = bundle.getLocale();
+ }
+
+ public _BundleMap(ResourceBundle bundle, Locale locale)
+ {
+ _bundle = bundle;
+ _locale = locale;
+ }
+
+ //Optimized methods
+ public Object get(Object key)
+ {
+ try
+ {
+ return _bundle.getObject(key.toString());
+ }
+ catch (Exception e)
+ {
+ return "!!!" + key + "!!!";
+ }
+ }
+
+ public boolean isEmpty()
+ {
+ return !_bundle.getKeys().hasMoreElements();
+ }
+
+ public boolean containsKey(Object key)
+ {
+ return _bundle.getObject(key.toString()) != null;
+ }
+
+ //Unoptimized methods
+ public Collection values()
+ {
+ if (_values == null)
+ {
+ _values = new ArrayList();
+ for (Enumeration enumer = _bundle.getKeys();
+ enumer.hasMoreElements(); )
+ {
+ String v = _bundle.getString((String)enumer.nextElement());
+ _values.add(v);
+ }
+ }
+ return _values;
+ }
+
+ public int size()
+ {
+ return values().size();
+ }
+
+ public boolean containsValue(Object value)
+ {
+ return values().contains(value);
+ }
+
+ public Set entrySet()
+ {
+ Set set = new HashSet();
+
+ for (Enumeration enumer = _bundle.getKeys(); enumer.hasMoreElements(); )
+ {
+ final String k = (String)enumer.nextElement();
+ set.add(new Map.Entry()
+ {
+ public Object getKey()
+ {
+ return k;
+ }
+
+ public Object getValue()
+ {
+ return _bundle.getObject(k);
+ }
+
+ public Object setValue(Object value)
+ {
+ throw new UnsupportedOperationException(
+ this.getClass().getName() + " UnsupportedOperationException");
+ }
+ });
+ }
+ return set;
+ }
+
+ public Set keySet()
+ {
+ Set set = new HashSet();
+ for (Enumeration enumer = _bundle.getKeys(); enumer.hasMoreElements(); )
+ {
+ set.add(enumer.nextElement());
+ }
+ return set;
+ }
+
+ //Unsupported methods
+ public Object remove(Object key)
+ {
+ throw new UnsupportedOperationException(this.getClass().getName()
+ + " UnsupportedOperationException");
+ }
+
+ public void putAll(Map t)
+ {
+ throw new UnsupportedOperationException(this.getClass().getName()
+ + " UnsupportedOperationException");
+ }
+
+ public Object put(Object key, Object value)
+ {
+ throw new UnsupportedOperationException(this.getClass().getName()
+ + " UnsupportedOperationException");
+ }
+
+ public void clear()
+ {
+ throw new UnsupportedOperationException(this.getClass().getName()
+ + " UnsupportedOperationException");
+ }
+
+ public ResourceBundle getBundle()
+ {
+ return _bundle;
+ }
+
+ public Locale getLocale()
+ {
+ return _locale;
+ }
+ } // endclass _BundleMap
+
+ private final static TrinidadLogger _LOG =
+ TrinidadLogger.createTrinidadLogger(MenuUtils.class);
+}
+