You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2011/05/16 22:45:22 UTC

svn commit: r1103883 - in /myfaces/tomahawk/trunk/sandbox/core20/src/main: java/org/apache/myfaces/custom/passwordStrength/ resources/META-INF/resources/oam.custom.passwordStrength.css/ resources/META-INF/resources/oam.custom.passwordStrength/ resource...

Author: lu4242
Date: Mon May 16 20:45:21 2011
New Revision: 1103883

URL: http://svn.apache.org/viewvc?rev=1103883&view=rev
Log:
TOMAHAWK-1590 Move s:passwordStrength to sandbox for JSF 2 module

Added:
    myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/passwordStrength/
    myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/passwordStrength/AbstractPasswordStrengthComponent.java
    myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/passwordStrength/PasswordStrengthRenderer.java
    myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/passwordStrength/TextIndicatorType.java
    myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/resources/oam.custom.passwordStrength/
    myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/resources/oam.custom.passwordStrength.css/
    myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/resources/oam.custom.passwordStrength.css/passwordStrength.css
    myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/resources/oam.custom.passwordStrength/dojoProgressBarProvider.js
    myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/resources/oam.custom.passwordStrength/genericProgressbarProvider.js
    myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/resources/oam.custom.passwordStrength/passwordStrength.js
    myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/org/
    myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/org/apache/
    myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/org/apache/myfaces/
    myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/org/apache/myfaces/custom/
    myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/org/apache/myfaces/custom/passwordStrength/
    myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/org/apache/myfaces/custom/passwordStrength/resource/
    myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/org/apache/myfaces/custom/passwordStrength/resource/PasswordStrength.properties
    myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/org/apache/myfaces/custom/passwordStrength/resource/PasswordStrength_ar.properties

Added: myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/passwordStrength/AbstractPasswordStrengthComponent.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/passwordStrength/AbstractPasswordStrengthComponent.java?rev=1103883&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/passwordStrength/AbstractPasswordStrengthComponent.java (added)
+++ myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/passwordStrength/AbstractPasswordStrengthComponent.java Mon May 16 20:45:21 2011
@@ -0,0 +1,161 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.custom.passwordStrength;
+
+import javax.faces.component.html.HtmlInputText;
+
+import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFComponent;
+import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
+import org.apache.myfaces.component.AlignProperty;
+
+/**
+ * The passwordStrength component is needed by the web sites 
+ * which ask the user to enter a powerful password for the 
+ * purpose of the registration stuff. 
+ * <p>
+ * The component enables its user to know the strength of the password 
+ * while (he/she) types it before even submit the form to the server 
+ * [please see the screenshots].            
+ * </p>
+ * <p>
+ * The component enables its user to define his custom security policy
+ * for his password in an easy manner.
+ * </p>
+ * <p>
+ * The component also have 2 types of presenting the password strength.
+ * Till now the strength can be represented as text or progressbar.
+ * </p>
+ * 
+ *   
+ */
+@JSFComponent(
+   name = "s:passwordStrength",
+   clazz = "org.apache.myfaces.custom.passwordStrength.PasswordStrengthComponent",
+   tagClass = "org.apache.myfaces.custom.passwordStrength.PasswordStrengthTag")
+public abstract class AbstractPasswordStrengthComponent extends HtmlInputText 
+    implements AlignProperty{ 
+
+    public static String COMPONENT_TYPE = "org.apache.myfaces.PasswordStrength";
+
+    public static String DEFAULT_RENDERER_TYPE = "org.apache.myfaces.PasswordStrength";
+    
+    public static String COMPONENT_FAMILY = "org.apache.myfaces.PasswordStrength";
+        
+    /**
+     * This flag {true | false} determines whether to show the details (left characters). 
+     * default is true
+     * 
+     */
+    @JSFProperty
+    public abstract String getShowDetails();
+    
+    /**
+     * This flag determines the indicator type. It can be {text or bar}. Default is text
+     * 
+     */
+    @JSFProperty
+    public abstract String getStrengthIndicatorType();        
+
+    /**
+     * The prefered length of the password
+     * 
+     */
+    @JSFProperty
+    public abstract String getPreferredPasswordLength();
+    
+    /**
+     * The prefix of the component message
+     * 
+     */
+    @JSFProperty
+    public abstract String getPrefixText();
+    
+    /**
+     * The text strength descriptions
+     * 
+     */
+    @JSFProperty
+    public abstract String getTextStrengthDescriptions();
+    
+    /**
+     * This string determines the expression of the custom security rule of the password
+     * <p>
+     * Note that the expression has the following format :
+     * </p>
+     * <p>
+     * *******************************************************
+     * </p>
+     * <p>
+     * S (Number)  N (Number) A (Number)
+     * </p>
+     * <ul>
+     * <li>Where S stands for Symbols</li>
+     * <li>Where N stands for Numbers</li>
+     * <li>Where A stands for Alphabets</li>
+     * </ul>
+     * <p>
+     * *******************************************************
+     * </p>
+     * <p>
+     * For example) A4N2S3A2
+     * Means that the password will be as following :
+     * </p>
+     * <ul>
+     * <li>4 or more Alphabets followed by</li>
+     * <li>2 or more Numbers followed by</li>
+     * <li>3 or more Symbols followed by</li>
+     * <li>2 or more Alphabets</li>
+     * </ul>
+     * <p>
+     * *******************************************************
+     * </p>
+     * <p>
+     * Note also that the useCustomSecurity should be set to true.
+     * </p>
+     * 
+     */
+    @JSFProperty
+    public abstract String getCustomSecurityExpression();
+
+    /**
+     * This flag determines whether to user custom security rules instead
+     * of just depending on the password length. The default is false.
+     * 
+     */
+    @JSFProperty
+    public abstract String getUseCustomSecurity();
+    
+    /**
+     * This attribute determines the penalty ratio that will decrease the password 
+     * Strength if the custom security expression is not met. Note also that the 
+     * useCustomSecurity should be set to true to apply this flag. Possible values 
+     * from 0 to 100. Default value is 50.
+     * 
+     */
+    @JSFProperty
+    public abstract String getPenaltyRatio();
+    
+    /**
+     * HTML: Specifies the horizontal alignment of this element. Deprecated in HTML 4.01.
+     * 
+     */
+    @JSFProperty
+    public abstract String getAlign();    
+    
+}

Added: myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/passwordStrength/PasswordStrengthRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/passwordStrength/PasswordStrengthRenderer.java?rev=1103883&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/passwordStrength/PasswordStrengthRenderer.java (added)
+++ myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/passwordStrength/PasswordStrengthRenderer.java Mon May 16 20:45:21 2011
@@ -0,0 +1,501 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.custom.passwordStrength;
+
+import java.io.IOException;
+import java.util.Map;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIInput;
+import javax.faces.component.html.HtmlInputText;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.faces.event.ComponentSystemEvent;
+import javax.faces.event.ComponentSystemEventListener;
+import javax.faces.event.ListenerFor;
+import javax.faces.render.Renderer;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFRenderer;
+import org.apache.myfaces.renderkit.html.util.AddResource;
+import org.apache.myfaces.renderkit.html.util.AddResourceFactory;
+import org.apache.myfaces.shared_tomahawk.renderkit.JSFAttr;
+import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
+import org.apache.myfaces.shared_tomahawk.util.MessageUtils;
+import org.apache.myfaces.tomahawk.application.PreRenderViewAddResourceEvent;
+import org.apache.myfaces.tomahawk.util.TomahawkResourceUtils;
+
+/**
+ * 
+ */
+@JSFRenderer(renderKitId = "HTML_BASIC",
+     family = "org.apache.myfaces.PasswordStrength",
+     type = "org.apache.myfaces.PasswordStrength")
+@ListenerFor(systemEventClass=PreRenderViewAddResourceEvent.class)
+public class PasswordStrengthRenderer extends Renderer implements ComponentSystemEventListener {
+
+    private static String PASSWORD_STRENGTH_LIBRARY = "oam.custom.passwordStrength";
+    private static String PASSWORD_STRENGTH_CSS_LIBRARY = "oam.custom.passwordStrength.css";
+
+    public void processEvent(ComponentSystemEvent event )
+    {
+        FacesContext context = FacesContext.getCurrentInstance();
+        String javascriptLocation = (String)event.getComponent().getAttributes().get(JSFAttr.JAVASCRIPT_LOCATION);
+        String styleLocation = (String) event.getComponent().getAttributes().get(
+                JSFAttr.STYLE_LOCATION);
+        if (StringUtils.isBlank(styleLocation)) {
+            TomahawkResourceUtils.addOutputStylesheetResource(context, PASSWORD_STRENGTH_CSS_LIBRARY, "passwordStrength.css"); 
+            //addResource.addStyleSheet(context, AddResource.HEADER_BEGIN,
+            //        PasswordStrengthRenderer.class, "css/passwordStrength.css");
+        }
+        if(javascriptLocation == null)
+        {
+            TomahawkResourceUtils.addOutputScriptResource(context, PASSWORD_STRENGTH_LIBRARY, "genericProgressbarProvider.js");
+            TomahawkResourceUtils.addOutputScriptResource(context, PASSWORD_STRENGTH_LIBRARY, "passwordStrength.js");
+            //addResource.addJavaScriptAtPosition(context,
+            //        AddResource.HEADER_BEGIN, javascriptLocation
+            //        + "/genericProgressbarProvider.js");
+            //addResource.addJavaScriptAtPosition(context,
+            //        AddResource.HEADER_BEGIN, javascriptLocation
+            //        + "/passwordStrength.js");
+
+        }
+    }
+
+    /**
+     * Returns a valid javascript var name depending on the given
+     * client id of the component
+     *
+     * @param context
+     * @param component
+     * @return
+     */
+    private String getJavascriptVar(FacesContext context, UIComponent component) {
+        return JAVASCRIPT_VAR_PREFIX + component.getClientId(context).replaceAll("\\:", "_");
+    }
+
+    ;
+
+    private void addResources(FacesContext context, UIComponent component,
+                              ResponseWriter writer) throws IOException {
+        PasswordStrengthComponent passwordStrength = (PasswordStrengthComponent) component;
+        AddResource addResource = AddResourceFactory.getInstance(context);
+
+        // Load the css style ...
+        String styleLocation = (String) component.getAttributes().get(
+                JSFAttr.STYLE_LOCATION);
+        if (StringUtils.isNotBlank(styleLocation)) {
+            addResource.addStyleSheet(context, AddResource.HEADER_BEGIN,
+                    styleLocation + "/passwordStrength.css");
+        } else {
+            //addResource.addStyleSheet(context, AddResource.HEADER_BEGIN,
+            //        PasswordStrengthRenderer.class, "css/passwordStrength.css");
+        }
+
+        // Load the JS file ...
+        String javascriptLocation = (String) component.getAttributes().get(
+                JSFAttr.JAVASCRIPT_LOCATION);
+        if (javascriptLocation != null) {
+            addResource.addJavaScriptAtPosition(context,
+                    AddResource.HEADER_BEGIN, javascriptLocation
+                    + "/genericProgressbarProvider.js");
+            addResource.addJavaScriptAtPosition(context,
+                    AddResource.HEADER_BEGIN, javascriptLocation
+                    + "/passwordStrength.js");
+        } else {
+            //addResource.addJavaScriptAtPosition(context,
+            //        AddResource.HEADER_BEGIN, PasswordStrengthRenderer.class,
+            //        "genericProgressbarProvider.js");
+            //addResource.addJavaScriptAtPosition(context,
+            //        AddResource.HEADER_BEGIN, PasswordStrengthRenderer.class,
+            //        "passwordStrength.js");
+        }
+
+
+        //Add Initialization stuff ...
+        String messageId = getMessageID(context, passwordStrength);
+        writer.write("<script type=\"text/javascript\">");
+        writer.write("var " + getJavascriptVar(context, component) + " = new " + JAVASCRIPT_CLASS + "();");
+        //fixme onload handler
+        String addOnStartUP = "window.addEventListener('load',function() {"
+                + getJavascriptVar(context, component)
+                + ".startUpPasswordStrength('"
+                + messageId
+                + "'); }, false);";
+        writer.write(addOnStartUP);
+        writer.write("</script>");
+    }
+
+    private String getMessageID(FacesContext context,
+                                PasswordStrengthComponent passwordStrength) {
+        String clientID = passwordStrength.getClientId(context);
+        String messageId = "";
+        if (TextIndicatorType.TEXT
+                .equalsIgnoreCase(getStrengthIndicatorTypeValue(passwordStrength))) {
+            messageId = getIndicatorMessageId(clientID);
+        } else {
+            messageId = getProgressBarContainerID(clientID);
+        }
+        return messageId;
+    }
+
+
+
+    private void renderStartDiv(UIComponent component, ResponseWriter writer)
+            throws IOException {
+        writer.startElement(HTML.DIV_ELEM, component);
+        writer.startElement(HTML.TABLE_ELEM, component);
+        writer.startElement(HTML.TR_ELEM, component);
+        writer.startElement(HTML.TD_ELEM, component);
+    }
+
+    private void renderEndDiv(UIComponent component, ResponseWriter writer)
+            throws IOException {
+        writer.endElement(HTML.TD_ELEM);
+        writer.endElement(HTML.TR_ELEM);
+        writer.endElement(HTML.TABLE_ELEM);
+        writer.endElement(HTML.DIV_ELEM);
+    }
+
+    private String getDefaultTextDesc() {
+        return MessageUtils.getMessage(BUNDLE_BASE_NAME,
+                MessageUtils.getCurrentLocale(),
+                "org.apache.myfaces.custom.passwordStrength.DESC", null)
+                .getDetail();
+    }
+
+    private String getDefaultShowDetails() {
+        return "true";
+    }
+
+    private String getDefaultUseCustomSecurity() {
+        return "false";
+    }
+
+    private String getDefaultCustomSecurityRule() {
+        return "A1";
+    }
+
+    private String getDefaultPenaltyRatio() {
+        return "50";
+    }
+
+    private String getDefaultPrefix() {
+        return MessageUtils.getMessage(BUNDLE_BASE_NAME,
+                MessageUtils.getCurrentLocale(),
+                "org.apache.myfaces.custom.passwordStrength.PREFIX", null)
+                .getDetail();
+    }
+
+    private String getLeftCharactersString() {
+        return "'" + MessageUtils.getMessage(BUNDLE_BASE_NAME,
+                MessageUtils.getCurrentLocale(),
+                "org.apache.myfaces.custom.passwordStrength.LEFT_CHARS", null)
+                .getDetail() + "'";
+    }
+
+    private String getDefaultStrengthIndicatorType() {
+        return TextIndicatorType.TEXT;
+    }
+
+    private void createTextSpan(PasswordStrengthComponent passwordStrength,
+                                FacesContext context, String clientID) throws IOException {
+        ResponseWriter writer = context.getResponseWriter();
+        String preferredLength = passwordStrength.getPreferredPasswordLength();
+        String prefixText = (passwordStrength.getPrefixText() == null) ? "'" + getDefaultPrefix() + "'"
+                : "'" + passwordStrength.getPrefixText() + "'";
+        String textStrengthDescriptions = (passwordStrength
+                .getTextStrengthDescriptions() == null) ? "'"
+                + getDefaultTextDesc() + "'" : "'"
+                + passwordStrength.getTextStrengthDescriptions() + "'";
+        String textID = "'" + clientID + "'";
+        String showDetails = (passwordStrength.getShowDetails() == null) ? "'"
+                + getDefaultShowDetails() + "'" : "'"
+                + passwordStrength.getShowDetails().toLowerCase() + "'";
+        String useCustomSecurity = (passwordStrength.getUseCustomSecurity() == null) ? "'"
+                + getDefaultUseCustomSecurity() + "'"
+                : "'" + passwordStrength.getUseCustomSecurity().toLowerCase()
+                + "'";
+        String customSecurityExpression = (passwordStrength
+                .getCustomSecurityExpression() == null) ? "'"
+                + getDefaultCustomSecurityRule() + "'" : "'"
+                + passwordStrength.getCustomSecurityExpression() + "'";
+        String penaltyRatio = (passwordStrength
+                .getPenaltyRatio() == null) ? "'"
+                + getDefaultPenaltyRatio() + "'" : "'"
+                + passwordStrength.getPenaltyRatio() + "'";
+        writer.startElement(HTML.SPAN_ELEM, passwordStrength);
+        writer.startElement(HTML.INPUT_ELEM, passwordStrength);
+        writer.writeAttribute(HTML.TYPE_ATTR, "password", HTML.TYPE_ATTR);
+        writer.writeAttribute(HTML.ID_ATTR, clientID, HTML.ID_ATTR);
+        writer.writeAttribute(HTML.NAME_ATTR, clientID, HTML.NAME_ATTR);
+        String value = "";
+        Object objValue = ((UIInput) passwordStrength).getSubmittedValue();
+        if (objValue != null) {
+            value = passwordStrength.getValue().toString();
+        }
+        writer.writeAttribute("value", value, "value");
+  
+        String onKeyUpString = createOnKeyUpString(context,
+                passwordStrength, textID, preferredLength, prefixText,
+                textStrengthDescriptions, true, showDetails, useCustomSecurity,
+                customSecurityExpression, penaltyRatio);
+        String onKeyUpAttr = passwordStrength.getOnkeyup();
+        passwordStrength.setOnkeyup(constructJSFunction(onKeyUpString, onKeyUpAttr));
+
+        String onBlurString = getOnBlurString(context, passwordStrength);
+        String onBlurAttr = passwordStrength.getOnblur();
+        passwordStrength.setOnblur(constructJSFunction(onBlurString, onBlurAttr));
+        
+        HtmlRendererUtils.renderHTMLAttributes(writer, passwordStrength, HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
+        if (isDisabled(context, passwordStrength))
+        {
+            writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null);
+        }
+        
+        writer.endElement(HTML.INPUT_ELEM);
+        writer.endElement(HTML.SPAN_ELEM);
+    }
+    
+    /**
+     * Concatenates two javascript functions.  One of which is usually supplied as an attribute
+     * of this component's tag.  The other one is the script created by this component.
+     */
+    private String constructJSFunction(String function, String attrFunction)
+    {
+        if(attrFunction != null && attrFunction.length() > 0) 
+        {
+            if(!attrFunction.endsWith(";"))
+            {
+                attrFunction += ";";
+            }
+            return (function+attrFunction);
+        }
+        else
+        {
+            return function;
+        }
+    }
+
+    /**
+     * creates a custom progress bar
+     */
+    private void createProgressbar(UIComponent component,
+                                   FacesContext context, ResponseWriter writer) throws IOException {
+        String clientID = component.getClientId(context);
+        writer.startElement(HTML.DIV_ELEM, component);
+        writer.writeAttribute(HTML.ID_ATTR, getProgressBarContainerID(clientID),
+                HTML.ID_ATTR);
+        writer.writeAttribute(HTML.CLASS_ATTR, "org_apache_myfaces_passwordStrength_progress",
+                HTML.CLASS_ATTR);
+
+        /*inner progress bar*/
+        writer.startElement(HTML.DIV_ELEM, component);
+        writer.writeAttribute(HTML.ID_ATTR, getProgressBarID(clientID),
+                HTML.ID_ATTR);
+        /*subcomponent per css definition we can use a simple class*/
+        writer.writeAttribute(HTML.CLASS_ATTR, "progressStart",
+                HTML.CLASS_ATTR);
+        /*inner progress bar end*/
+        writer.endElement(HTML.DIV_ELEM);
+        writer.endElement(HTML.DIV_ELEM);
+    }
+
+    private void createTextIndicatorMessage(UIComponent component,
+                                            FacesContext context, ResponseWriter writer) throws IOException {
+        String clientID = component.getClientId(context);
+        writer.startElement(HTML.SPAN_ELEM, component);
+        writer.writeAttribute(HTML.ID_ATTR, getIndicatorMessageId(clientID),
+                HTML.ID_ATTR);
+        writer.writeAttribute(HTML.CLASS_ATTR, "org_apache_myfaces_passwordStrength_progress_indicatorMessage",
+                HTML.CLASS_ATTR);
+        writer.endElement(HTML.SPAN_ELEM);
+    }
+
+    private void createIndicatorSpan(UIComponent component,
+                                     FacesContext context, ResponseWriter writer) throws IOException {
+        PasswordStrengthComponent passwordStrength = (PasswordStrengthComponent) component;
+        String clientID = passwordStrength.getClientId(context);
+        String strengthIndicatorType = getStrengthIndicatorTypeValue(passwordStrength);
+        writer.endElement(HTML.TD_ELEM);
+        writer.startElement(HTML.TD_ELEM, component);
+        if (TextIndicatorType.TEXT.equalsIgnoreCase(strengthIndicatorType)) { //It is a text ...
+            createTextIndicatorMessage(component, context, writer);
+        } else { //It is a progressbar ...     
+            //createProgressBarSpan(component, context, writer);
+            createProgressbar(component, context, writer);
+        }
+        writer.endElement(HTML.TD_ELEM);
+        writer.endElement(HTML.TR_ELEM);
+        writer.startElement(HTML.TR_ELEM, component);
+        writer.startElement(HTML.TD_ELEM, component);
+        writer.startElement("div", component);
+        writer.writeAttribute("id", getleftCharsMessageId(clientID), "id");
+        writer.endElement("div");
+    }
+
+    private String getStrengthIndicatorType(
+            PasswordStrengthComponent passwordStrength) {
+        return (passwordStrength.getStrengthIndicatorType() == null) ? "'"
+                + getDefaultStrengthIndicatorType() + "'" : "'"
+                + passwordStrength.getStrengthIndicatorType() + "'";
+    }
+
+    private String getStrengthIndicatorTypeValue(
+            PasswordStrengthComponent passwordStrength) {
+        return (passwordStrength.getStrengthIndicatorType() == null) ? getDefaultStrengthIndicatorType()
+                : passwordStrength.getStrengthIndicatorType();
+    }
+
+
+    private void createHTMLComponents(FacesContext facesContext,
+                                      UIComponent component, ResponseWriter writer, String clientID)
+            throws IOException {
+        PasswordStrengthComponent passwordStrength = (PasswordStrengthComponent) component;
+        renderStartDiv(component, writer);
+        createTextSpan(passwordStrength, facesContext, clientID);
+        createIndicatorSpan(component, facesContext, writer);
+        renderEndDiv(component, writer);
+    }
+
+    public void encodeBegin(FacesContext context, UIComponent component)
+            throws IOException {
+        RendererUtils.checkParamValidity(context, component,
+                PasswordStrengthComponent.class);
+        if (HtmlRendererUtils.isDisplayValueOnly(component)
+                || isDisabled(context, component)) {
+            super.encodeEnd(context, component);
+            return;
+        }
+        String clientID = component.getClientId(context);
+        ResponseWriter writer = context.getResponseWriter();
+        addResources(context, component, writer);
+        createHTMLComponents(context, component, writer, clientID);
+    }
+
+    public void encodeEnd(FacesContext context, UIComponent component)
+            throws IOException {
+    }
+
+    public void decode(FacesContext context, UIComponent component) {
+        Map requestMap = context.getExternalContext().getRequestParameterMap();
+        String clientID = component.getClientId(context);
+        String newValue = (String) requestMap.get(clientID);
+        ((UIInput) component).setSubmittedValue(newValue);
+    }
+
+    protected boolean isDisabled(FacesContext facesContext,
+                                 UIComponent component) {
+        if (component instanceof HtmlInputText) {
+            return ((HtmlInputText) component).isDisabled();
+        } else {
+            return org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils
+                    .getBooleanAttribute(component, HTML.DISABLED_ATTR, false);
+        }
+    }
+
+    private String createOnKeyUpString(FacesContext context,
+                                       UIComponent component, String textID, String preferredLength,
+                                       String prefix, String textStrengthDescriptions,
+                                       boolean showMessageIndicator, String showDetails,
+                                       String useCustomSecurity, String customSecurityExpression,
+                                       String penaltyRatio) {
+        PasswordStrengthComponent passwordStrength = (PasswordStrengthComponent) component;
+        String clientID = component.getClientId(context);
+        String showMessageIndicatorString = "";
+        String strengthIndicatorType = getStrengthIndicatorType(passwordStrength);
+        String progressBarId = "'" + getProgressBarID(clientID) + "'";
+        String indicatorMessageID = "'" + getIndicatorMessageId(clientID) + "'";
+        String leftCharsMessageID = "'" + getleftCharsMessageId(clientID) + "'";
+        if (showMessageIndicator == true) {
+            showMessageIndicatorString = getJavascriptVar(context, component) + ".show('"
+                    + getMessageID(context, passwordStrength) + "');";
+        }
+        return updateStatusValue(context, component, textID, preferredLength, prefix,
+                textStrengthDescriptions, indicatorMessageID,
+                leftCharsMessageID, showMessageIndicatorString,
+                strengthIndicatorType, progressBarId, showDetails,
+                getLeftCharactersString(), useCustomSecurity,
+                customSecurityExpression, penaltyRatio);
+    }
+
+    private String updateStatusValue(FacesContext context,
+                                     UIComponent component,
+                                     String textID, String preferredLength,
+                                     String prefix, String textStrengthDescriptions,
+                                     String indicatorMessageID, String leftCharsMessageID,
+                                     String showMessageIndicatorString,
+                                     String strengthIndicatorType, String progressBarId,
+                                     String showDetails, String leftCharactersString,
+                                     String useCustomSecurity, String customSecurityExpression,
+                                     String penaltyRatio) {
+        return getJavascriptVar(context, component) + ".updateStatusValue("
+                + textID + "," + preferredLength + ", "
+                + prefix + ", " + textStrengthDescriptions + ", "
+                + indicatorMessageID + ", " + leftCharsMessageID + ", "
+                + strengthIndicatorType + ", " + progressBarId + ", "
+                + showDetails + ", " + leftCharactersString + ", "
+                + useCustomSecurity + ", " + customSecurityExpression + ", "
+                + penaltyRatio
+                + ");"
+                + showMessageIndicatorString;
+    }
+
+    private String getIndicatorMessageId(String clientID) {
+        return clientID + "indicatorMessage";
+    }
+
+    private String getleftCharsMessageId(String clientID) {
+        return clientID + "leftCharsMessage";
+    }
+
+    private String getProgressBarID(String clientID) {
+        return clientID + PROGRESSBAR_SUFFIX;
+    }
+
+    private String getProgressBarContainerID(String clientID) {
+        return getProgressBarID(clientID) + PROGRESSBAR_CONTAINER_SUFFIX;
+    }
+
+    private String getOnBlurString(FacesContext context, UIComponent component) {
+        PasswordStrengthComponent passwordStrength = (PasswordStrengthComponent) component;
+        String clientID = passwordStrength.getClientId(context);
+        return getJavascriptVar(context, component) + ".hide('" + getMessageID(context, passwordStrength) + "');" + getJavascriptVar(context, component) + ".hide('"
+                + getleftCharsMessageId(clientID) + "');";
+    }
+
+    final String BUNDLE_BASE_NAME = "org.apache.myfaces.custom.passwordStrength.resource.PasswordStrength";
+    final String DEFAULT_PROGRESSBAR_WIDTH = "150";
+    final String DEFAULT_PROGRESSBAR_HEIGHT = "20";
+    final String PROGRESSBAR_SUFFIX = "_PROGRESSBAR";
+    final String PROGRESSBAR_CONTAINER_SUFFIX = "_CONTAINER";
+    final String DEFAULT_PROGRESSBAR_VALUE = "20";
+    /**
+     * Package and class declaration
+     * for the underlying namespaced
+     * javasript class
+     */
+    static final String JAVASCRIPT_CLASS = "org.apache.myfaces.passwordStrength";
+    /**
+     * pseudo namespacing of the javascript var to avoid potential conflicts
+     */
+    static final String JAVASCRIPT_VAR_PREFIX = "myfaces_";
+}

Added: myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/passwordStrength/TextIndicatorType.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/passwordStrength/TextIndicatorType.java?rev=1103883&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/passwordStrength/TextIndicatorType.java (added)
+++ myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/passwordStrength/TextIndicatorType.java Mon May 16 20:45:21 2011
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.custom.passwordStrength;
+
+public interface TextIndicatorType {
+    public String PROGRESSBAR = "bar";
+    public String TEXT = "text";    
+}

Added: myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/resources/oam.custom.passwordStrength.css/passwordStrength.css
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/resources/oam.custom.passwordStrength.css/passwordStrength.css?rev=1103883&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/resources/oam.custom.passwordStrength.css/passwordStrength.css (added)
+++ myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/resources/oam.custom.passwordStrength.css/passwordStrength.css Mon May 16 20:45:21 2011
@@ -0,0 +1,66 @@
+.org_apache_myfaces_passwordStrength_progress_indicatorMessage {
+    color: white;
+    background: gray;
+    font-size: 12px;
+    padding: 3;
+}
+
+/**
+* core class with a default width style
+* basically the progress container styleclass
+*/
+.org_apache_myfaces_passwordStrength_progress {
+    float: left;
+    border: 1px solid silver;
+    width: 100px;
+    height: 20px;
+    margin-top: 0px;
+    margin-bottom: 0px; /*v-center for ie6*/
+    display: block;
+    overflow: hidden;
+}
+
+/**
+color definition for the progress start
+*/
+.org_apache_myfaces_passwordStrength_progress .progressVeryWeak,
+    .org_apache_myfaces_passwordStrength_progress .progressStrong,
+    .org_apache_myfaces_passwordStrength_progress .progressWeak,
+    .org_apache_myfaces_passwordStrength_progress .progressPoor {
+    background-color: blue; /*only the left border must be set*/
+    border: 0px;
+    width: 1px;
+    height: 20px;
+    margin-left: 0px;
+    margin-top: 0px;
+    margin-bottom: 0px; /*v-center for ie6*/
+    display: block;
+}
+
+/**
+* Valid color setting if not overridden
+*/
+.org_apache_myfaces_passwordStrength_progress .progressStrong {
+    background-color: green;
+
+}
+
+/**
+* Weak color setting
+*/
+.org_apache_myfaces_passwordStrength_progress .progressVeryWeak {
+    background-color: #ff8c00;
+
+}
+
+.org_apache_myfaces_passwordStrength_progress .progressWeak {
+    background-color: yellow;
+
+}
+
+/**
+* Invalid color setting
+*/
+.org_apache_myfaces_passwordStrength_progress .progressPoor {
+    background-color: red;
+}

Added: myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/resources/oam.custom.passwordStrength/dojoProgressBarProvider.js
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/resources/oam.custom.passwordStrength/dojoProgressBarProvider.js?rev=1103883&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/resources/oam.custom.passwordStrength/dojoProgressBarProvider.js (added)
+++ myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/resources/oam.custom.passwordStrength/dojoProgressBarProvider.js Mon May 16 20:45:21 2011
@@ -0,0 +1,35 @@
+/**
+ * Generic progress bar provider which provides the progress bar for the dojo toolkit
+ */
+if ('undefined' == typeof(org)) {
+    org = {};
+}
+if ('undefined' == typeof(org.apache)) {
+    org.apache = {};
+}
+if ('undefined' == typeof(org.apache.myfaces)) {
+    org.apache.myfaces = {};
+}
+if ('undefined' == typeof(org.apache.myfaces.dojoProgressbarProvider)) {
+    /**
+     * Encapsulation class
+     * for the refactured code
+     * from the main class
+     *
+     */
+    org.apache.myfaces.dojoProgressbarProvider = function(passwordStrength) {
+    };
+    /**
+     * increases the progress bar value
+     * @param passwordStrength
+     * @param progressBarID
+     * @param degree
+     */
+    org.apache.myfaces.dojoProgressbarProvider.prototype.increaseProgressBar = function (progressBarID, degree) {
+        var currentValue = degree * 10;
+        dojo.widget.byId(progressBarID).setMaxProgressValue(10, true);
+        dojo.widget.byId(progressBarID).setProgressValue(currentValue, true);
+        dojo.widget.byId(progressBarID).render();
+    };
+}
+;
\ No newline at end of file

Added: myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/resources/oam.custom.passwordStrength/genericProgressbarProvider.js
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/resources/oam.custom.passwordStrength/genericProgressbarProvider.js?rev=1103883&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/resources/oam.custom.passwordStrength/genericProgressbarProvider.js (added)
+++ myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/resources/oam.custom.passwordStrength/genericProgressbarProvider.js Mon May 16 20:45:21 2011
@@ -0,0 +1,48 @@
+/**
+ * Generic progress bar provider which provides the progress bar for the dojo toolkit
+ */
+if ('undefined' == typeof(org)) {
+    org = {};
+}
+if ('undefined' == typeof(org.apache)) {
+    org.apache = {};
+}
+if ('undefined' == typeof(org.apache.myfaces)) {
+    org.apache.myfaces = {};
+}
+if ('undefined' == typeof(org.apache.myfaces.dojoProgressbarProvider)) {
+    /**
+     * Encapsulation class
+     * for the refactured code
+     * from the main class
+     *
+     */
+    org.apache.myfaces.dojoProgressbarProvider = function() {
+    };
+    /**
+     * increases the progress bar value
+     * @param passwordStrength
+     * @param progressBarID
+     * @param degree
+     */
+    org.apache.myfaces.dojoProgressbarProvider.prototype.increaseProgressBar = function (progressBarID, degree) {
+        var indicatorOuter = document.getElementById(progressBarID + "_CONTAINER");
+        var indicatorInner = document.getElementById(progressBarID);
+        /*fetch the width as numeric value*/
+        var maxWidth = parseInt(indicatorOuter.offsetWidth);
+        var currentValue = Math.round(maxWidth * degree);//FIXME degree
+        if (degree == 1) {
+            indicatorInner.className = "progressStrong";
+            indicatorInner.style.width = maxWidth + "px";
+        } else if (0.75 > degree && degree > 0.25) {
+            indicatorInner.className = "progressVeryWeak";
+            indicatorInner.style.width = currentValue + "px";
+        } else if (1 > degree && degree > 0.75) {
+            indicatorInner.className = "progressWeak";
+            indicatorInner.style.width = currentValue + "px";
+        } else {
+            indicatorInner.className = "progressPoor";
+            indicatorInner.style.width = currentValue + "px";
+        }
+    };
+}

Added: myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/resources/oam.custom.passwordStrength/passwordStrength.js
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/resources/oam.custom.passwordStrength/passwordStrength.js?rev=1103883&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/resources/oam.custom.passwordStrength/passwordStrength.js (added)
+++ myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/resources/oam.custom.passwordStrength/passwordStrength.js Mon May 16 20:45:21 2011
@@ -0,0 +1,338 @@
+/*reserve the namespace, we omit dojo provide to
+ get rid of the last dojo references*/
+if ('undefined' == typeof(org)) {
+    org = {};
+}
+if ('undefined' == typeof(org.apache)) {
+    org.apache = {};
+}
+if ('undefined' == typeof(org.apache.myfaces)) {
+    org.apache.myfaces = {};
+}
+if ('undefined' == typeof(org.apache.myfaces.passwordStrength)) {
+    org.apache.myfaces.passwordStrength = function() {
+    };
+    org.apache.myfaces.passwordStrength.prototype.hide = function(id) {
+        if (document.getElementById) {
+            obj = document.getElementById(id);
+            obj.style.display = "none";
+        }
+    };
+    org.apache.myfaces.passwordStrength.prototype.show = function(id) {
+        if (document.getElementById) {
+            obj = document.getElementById(id);
+            obj.style.display = "";
+        }
+    };
+    org.apache.myfaces.passwordStrength.prototype.startUpPasswordStrength = function(objID) {
+        this.hide(objID);
+    };
+    org.apache.myfaces.passwordStrength.prototype.increaseProgressBar = function (progressBarID, degree) {
+        /*var currentValue = degree * 10;
+        dojo.widget.byId(progressBarID).setMaxProgressValue(10, true);
+        dojo.widget.byId(progressBarID).setProgressValue(currentValue, true);
+        dojo.widget.byId(progressBarID).render();
+        */
+        org.apache.myfaces.dojoProgressbarProvider.prototype.increaseProgressBar(progressBarID, degree);
+    };
+    org.apache.myfaces.passwordStrength.prototype.getPasswordStrengthText = function (degree, tokens) {
+        var index = Math.round(degree * tokens.length) - 1;
+        if (index <= 0) return tokens[0];
+        return tokens[ index ];
+    };
+    org.apache.myfaces.passwordStrength.prototype.isAlpha = function(sText) {
+        for (c = 0; c < sText.length; c ++) {
+            alpha = ( sText.charCodeAt(c) >= 65 &&
+                      sText.charCodeAt(c) <= 90 ) ||
+                    ( sText.charCodeAt(c) >= 97 &&
+                      sText.charCodeAt(c) <= 122 )
+            if (!alpha) {
+                return false;
+            }
+        }
+        return true;
+    };
+    org.apache.myfaces.passwordStrength.prototype.isNumeric = function(sText) {
+        var ValidChars = "0123456789";
+        var IsNumber = true;
+        var Char;
+        for (i = 0; i < sText.length && IsNumber == true; i++) {
+            Char = sText.charAt(i);
+            if (ValidChars.indexOf(Char) == -1) {
+                IsNumber = false;
+            }
+        }
+        return IsNumber;
+    };
+    org.apache.myfaces.passwordStrength.prototype.isSymbol = function(sText) {
+        var iChars = "!@#$%^&*()+=-[]\';,./{}|\":<>? ";
+        for (var i = 0; i < sText.length; i++) {
+            if (iChars.indexOf(sText.charAt(i)) != -1) {
+                return true;
+            }
+        }
+        return false;
+    };
+    org.apache.myfaces.passwordStrength.prototype.trimString = function(s) {
+        var l = 0;
+        var r = s.length - 1;
+        while (l < s.length && s.charAt(l) == ' ')
+        {
+            l++;
+        }
+        while (r > l && s.charAt(r) == ' ')
+        {
+            r -= 1;
+        }
+        return s.substring(l, r + 1);
+    };
+    /**
+     * This method checks whether the character is a valid password Strength
+     * character pattern ...
+     */
+    org.apache.myfaces.passwordStrength.prototype.isValidCharacterPattern = function(character) {
+        if (character != 'S' && character != 's' &&
+            character != 'A' && character != 'a' &&
+            character != 'N' && character != 'n') {
+            return false;
+        }
+        return true;
+    };
+    org.apache.myfaces.passwordStrength.prototype.isSymbolCharacterPattern = function(character) {
+        if (character == 'S' || character == 's')
+            return true;
+        return false;
+    };
+    org.apache.myfaces.passwordStrength.prototype.isNumberCharacterPattern = function(character) {
+        if (character == 'N' || character == 'n')
+            return true;
+        return false;
+    };
+    org.apache.myfaces.passwordStrength.prototype.isAlphaCharacterPattern = function(character) {
+        if (character == 'A' || character == 'a')
+            return true;
+        return false;
+    };
+    /**
+     * This org.apache.myfaces.passwordStrength.prototype.checks whether the index is a valid index of
+     * the password string ...
+     */
+    org.apache.myfaces.passwordStrength.prototype.isValidRange = function (passwordString, index) {
+        if (index >= passwordString.length) {
+            return false;
+        }
+        return true;
+    };
+    /**
+     * This org.apache.myfaces.passwordStrength.prototype.check whether the password string has a valid
+     * sequence of symbols ...
+     * count :- is the number of expected symbols.
+     * passwordString :- the src password string.
+     * currentCharacterIndex :- the current character index of the password string.
+     * Return the current password string character index if succeeded else
+     * return -1.
+     */
+    org.apache.myfaces.passwordStrength.prototype.validSymbolSequence = function(count, passwordString, currentCharacterIndex) {
+        //Consume symbol characters ...
+        for (j = 0; j < count; ++j) {
+            if (!this.isValidRange(passwordString, currentCharacterIndex)) {
+                return -1;
+            }
+            if (!this.isSymbol(passwordString.charAt(currentCharacterIndex++)))
+                return -1;
+        }
+		//Check whether there are more character of this type ...
+        while (currentCharacterIndex < passwordString.length) {
+            if (this.isSymbol(passwordString.charAt(currentCharacterIndex))) {
+                currentCharacterIndex++;
+            } else {
+                break;
+            }
+        }
+        return currentCharacterIndex;
+    };
+    /**
+     * This org.apache.myfaces.passwordStrength.prototype.check whether the password string has a valid
+     * sequence of numbers ...
+     * count :- is the number of expected numbers.
+     * passwordString :- the src password string.
+     * currentCharacterIndex :- the current character index of the password string.
+     * Return the current password string character index if succeeded else
+     * return -1.
+     */
+    org.apache.myfaces.passwordStrength.prototype.validNumberSequence = function(count, passwordString, currentCharacterIndex) {
+        for (j = 0; j < count; ++j) {
+            if (!this.isValidRange(passwordString, currentCharacterIndex)) {
+                return -1;
+            }
+            if (!this.isNumeric(passwordString.charAt(currentCharacterIndex++)))
+                return -1;
+        }
+		//Check whether there are more character of this type ...
+        while (currentCharacterIndex < passwordString.length) {
+            if (this.isNumeric(passwordString.charAt(currentCharacterIndex))) {
+                currentCharacterIndex++;
+            } else {
+                break;
+            }
+        }
+        return currentCharacterIndex;
+    };
+    /**
+     * This org.apache.myfaces.passwordStrength.prototype.check whether the password string has a valid
+     * sequence of alphabets ...
+     * count :- is the number of expected alphabets.
+     * passwordString :- the src password string.
+     * currentCharacterIndex :- the current character index of the password string.
+     * Return the current password string character index if succeeded else
+     * return -1.
+     */
+    org.apache.myfaces.passwordStrength.prototype.validAlphaSequence = function(count, passwordString, currentCharacterIndex) {
+        for (j = 0; j < count; ++j) {
+            if (!this.isValidRange(passwordString, currentCharacterIndex)) {
+                return -1;
+            }
+            if (!this.isAlpha(passwordString.charAt(currentCharacterIndex++)))
+                return -1;
+        }
+		//Check whether there are more character of this type ...
+        while (currentCharacterIndex < passwordString.length) {
+            if (this.isAlpha(passwordString.charAt(currentCharacterIndex))) {
+                currentCharacterIndex++;
+            } else {
+                break;
+            }
+        }
+        return currentCharacterIndex;
+    };
+    /**
+     * This method check whether the password string complies
+     * with the pattern specified ...
+     * Note that the pattern has the following format :
+     * S <<Number>>  N <<Number>> A<<Number>>
+     * Where S stands for Symbols
+     * Where N stands for Numbers
+     * Where A stands for Alphabets
+     ****************************************************
+     * For example) A4N2S3A2
+     * Means that the password will be as following :
+     * 4 or more Alphabets followed by
+     * 2 or more Numbers followed by
+     * 3 or more Symbols followed by
+     * 2 or more Alphabets
+     ****************************************************
+     */
+    org.apache.myfaces.passwordStrength.prototype.checkPattern = function(passwordString, patternString) {
+        var INVALID_PATTERN = "Invalid pattern";
+        var INVALID_PATTERN_LENGTH = "Invalid pattern length";
+        var currentCharacterIndex = 0;
+        var patternLength = patternString.length;
+        if (this.trimString(patternString).length % 2 != 0) {
+            alert(INVALID_PATTERN_LENGTH);
+            return false;
+        }
+        for (var i = 0; i < patternLength; i += 2) {
+            var character = patternString.charAt(i);
+            var count = patternString.charAt(i + 1);
+            var retval;
+
+		//Check pattern format ...
+            if (!this.isNumeric(count)) {
+                alert(INVALID_PATTERN);
+                return false;
+            }
+            if (!this.isValidCharacterPattern(character)) {
+                alert(INVALID_PATTERN);
+                return false;
+            }
+
+		//Validate the pattern ...
+            if (this.isSymbolCharacterPattern(character)) {
+                retval = this.validSymbolSequence(count, passwordString, currentCharacterIndex);
+                if (retval == -1) {
+                    return false;
+                }
+            }
+            else if (this.isNumberCharacterPattern(character)) {
+                retval = this.validNumberSequence(count, passwordString, currentCharacterIndex);
+                if (retval == -1) {
+                    return false;
+                }
+            }
+            else if (this.isAlphaCharacterPattern(character)) {
+                retval = this.validAlphaSequence(count, passwordString, currentCharacterIndex);
+                if (retval == -1) {
+                    return false;
+                }
+            }
+            currentCharacterIndex = retval;
+        }
+
+	//The pattern is valid ...
+        return true;
+    };
+    org.apache.myfaces.passwordStrength.prototype.calculatePasswordStrengthDegree = function(passwordString, patternString,
+                                                                                             preferredLength, useCustomSecurity,
+                                                                                             penaltyRatio) {
+        var currentLength = passwordString.length;
+        var strength = (currentLength / preferredLength);
+        if (strength > 1) strength = 1;
+        if (useCustomSecurity == "true") {
+            //If the pattern is not satisified decrease the power by the penalty ...
+            if (!this.checkPattern(passwordString, patternString)) {
+                return strength * (penaltyRatio / 100);
+            }
+        }
+        return strength;
+    };
+
+
+//This method is used for online updating the status of the textbox ...
+    org.apache.myfaces.passwordStrength.prototype.updateStatusValue = function(textID, preferredLength,
+                                                                               prefixText, passwordDesc,
+                                                                               indicatorMessageID, leftCharsMessageID,
+                                                                               strengthIndicatorType, progressBarId,
+                                                                               showDetails, leftCharactersString,
+                                                                               useCustomSecurity, patternString,
+                                                                               penaltyRatio) {
+        //Get the current message content ...
+        var content = document.getElementById(textID).value;
+        var currentStatus = prefixText;
+        var degree = this.calculatePasswordStrengthDegree(content, patternString,
+                preferredLength, useCustomSecurity,
+                penaltyRatio);
+        /**
+         * Check whether to display the strength indicator as a text or as bar ...
+         */
+        if (strengthIndicatorType == "text") {
+            var tokens = passwordDesc.split(";");
+            currentStatus += this.getPasswordStrengthText(degree, tokens);
+            if (document.all) {
+                document.getElementById(indicatorMessageID).innerText = currentStatus;
+            } else {
+                document.getElementById(indicatorMessageID).textContent = currentStatus;
+            }
+        }
+        else { /*Here we are dealing with bar*/
+            this.increaseProgressBar(progressBarId, degree);
+        }
+        /**
+         * Here display the left characters message part ...
+         */
+        if (content.length == 0) {
+            this.hide(leftCharsMessageID);
+        } else if (showDetails == "true" && content.length < preferredLength) {
+            this.show(leftCharsMessageID);
+            var diff = (preferredLength - content.length);
+            var charLeft = diff + " " + leftCharactersString;
+            if (document.all) {
+                document.getElementById(leftCharsMessageID).innerText = charLeft;
+            } else {
+                document.getElementById(leftCharsMessageID).textContent = charLeft;
+            }
+        } else {
+            this.hide(leftCharsMessageID);
+        }
+    };
+}
+;

Added: myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/org/apache/myfaces/custom/passwordStrength/resource/PasswordStrength.properties
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/org/apache/myfaces/custom/passwordStrength/resource/PasswordStrength.properties?rev=1103883&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/org/apache/myfaces/custom/passwordStrength/resource/PasswordStrength.properties (added)
+++ myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/org/apache/myfaces/custom/passwordStrength/resource/PasswordStrength.properties Mon May 16 20:45:21 2011
@@ -0,0 +1,3 @@
+org.apache.myfaces.custom.passwordStrength.DESC = Very Poor;Weak;Average;Strong;Excellent
+org.apache.myfaces.custom.passwordStrength.PREFIX = Strength :
+org.apache.myfaces.custom.passwordStrength.LEFT_CHARS = characters are left

Added: myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/org/apache/myfaces/custom/passwordStrength/resource/PasswordStrength_ar.properties
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/org/apache/myfaces/custom/passwordStrength/resource/PasswordStrength_ar.properties?rev=1103883&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/org/apache/myfaces/custom/passwordStrength/resource/PasswordStrength_ar.properties (added)
+++ myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/org/apache/myfaces/custom/passwordStrength/resource/PasswordStrength_ar.properties Mon May 16 20:45:21 2011
@@ -0,0 +1,3 @@
+org.apache.myfaces.custom.passwordStrength.DESC = \u0636\u0639\u064a\u0641\u0629 \u062c\u062f\u0627;\u0636\u0639\u064a\u0641\u0629;\u0645\u062a\u0648\u0633\u0637\u0629;\u0642\u0648\u064a\u0629;\u0642\u0648\u064a\u0629 \u062c\u062f\u0627
+org.apache.myfaces.custom.passwordStrength.PREFIX = \u0627\u0644\u062f\u0631\u062c\u0629 : 
+org.apache.myfaces.custom.passwordStrength.LEFT_CHARS = : \u0639\u062f\u062f \u0627\u0644\u062d\u0631\u0648\u0641 \u0627\u0644\u0645\u062a\u0628\u0642\u064a\u0629