001    package org.apache.myfaces.tobago.renderkit;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one or more
005     * contributor license agreements.  See the NOTICE file distributed with
006     * this work for additional information regarding copyright ownership.
007     * The ASF licenses this file to You under the Apache License, Version 2.0
008     * (the "License"); you may not use this file except in compliance with
009     * the License.  You may obtain a copy of the License at
010     *
011     *      http://www.apache.org/licenses/LICENSE-2.0
012     *
013     * Unless required by applicable law or agreed to in writing, software
014     * distributed under the License is distributed on an "AS IS" BASIS,
015     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016     * See the License for the specific language governing permissions and
017     * limitations under the License.
018     */
019    
020    import org.apache.commons.logging.Log;
021    import org.apache.commons.logging.LogFactory;
022    import org.apache.commons.lang.StringUtils;
023    import static org.apache.myfaces.tobago.TobagoConstants.ATTR_LABEL;
024    import static org.apache.myfaces.tobago.TobagoConstants.ATTR_VALUE;
025    import static org.apache.myfaces.tobago.TobagoConstants.RENDERER_TYPE_LABEL;
026    
027    import javax.faces.component.UIComponent;
028    import java.util.Locale;
029    
030    public final class LabelWithAccessKey {
031    
032      private static final Log LOG = LogFactory.getLog(LabelWithAccessKey.class);
033    
034      private String text;
035      private Character accessKey;
036      private int pos = -1;
037      public static final char INDICATOR = '_';
038      public static final String ESCAPED_INDICATOR = "__";
039    
040      public LabelWithAccessKey(UIComponent component) {
041        Object value;
042        if (RENDERER_TYPE_LABEL.equals(component.getRendererType())) {
043          value = component.getAttributes().get(ATTR_VALUE);
044        } else {
045          value = component.getAttributes().get(ATTR_LABEL);
046        }
047        text = (value == null) ? null : String.valueOf(value);
048        setup(text);
049      }
050    
051      private void findIndicator(String label, int index, int escapedIndicatorCount) {
052        index = label.indexOf(INDICATOR, index);
053        if (index == -1) {
054          text = label;
055        } else if (index == label.length() - 1) {
056          LOG.warn(INDICATOR + " in label is last char, this is not allowed"
057              + "label='" + label + "'.");
058          text = label.substring(0, label.length() - 1);
059          pos = -1;
060        } else if (label.charAt(index+1) == INDICATOR) {
061          escapedIndicatorCount++;
062          findIndicator(label, index+2, escapedIndicatorCount);
063        } else {
064          text = label.substring(0, index)
065                + label.substring(index + 1);
066          accessKey = text.charAt(index);
067          pos = index - escapedIndicatorCount;
068        }
069      }
070    
071      public void setup(String label) {
072        if (label != null) {
073          findIndicator(label, 0, 0);
074          text = StringUtils.replace(text, ESCAPED_INDICATOR, String.valueOf(INDICATOR));
075        } else {
076          if (accessKey != null && text != null) {
077            pos = text.toLowerCase(Locale.ENGLISH).indexOf(
078                Character.toLowerCase(accessKey.charValue()));
079          }
080        }
081      }
082    
083      public String getText() {
084        return text;
085      }
086    
087      public Character getAccessKey() {
088        return accessKey;
089      }
090    
091      public int getPos() {
092        return pos;
093      }
094    
095      public void setText(String text) {
096        this.text = text;
097      }
098    
099      public void setAccessKey(Character accessKey) {
100        this.accessKey = accessKey;
101      }
102    
103    }