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.lang.StringUtils;
021    import org.slf4j.Logger;
022    import org.slf4j.LoggerFactory;
023    import org.apache.myfaces.tobago.component.Attributes;
024    import org.apache.myfaces.tobago.component.RendererTypes;
025    
026    import javax.faces.component.UIComponent;
027    import java.util.Locale;
028    
029    public final class LabelWithAccessKey {
030    
031      private static final Logger LOG = LoggerFactory.getLogger(LabelWithAccessKey.class);
032    
033      private String text;
034      private Character accessKey;
035      private int pos = -1;
036      public static final char INDICATOR = '_';
037      public static final String ESCAPED_INDICATOR = "__";
038    
039      public LabelWithAccessKey(UIComponent component) {
040        Object value;
041        if (RendererTypes.LABEL.equals(component.getRendererType())) {
042          value = component.getAttributes().get(Attributes.VALUE);
043        } else {
044          value = component.getAttributes().get(Attributes.LABEL);
045        }
046        text = (value == null) ? null : String.valueOf(value);
047        setup(text);
048      }
049    
050      private void findIndicator(String label, int index, int escapedIndicatorCount) {
051        index = label.indexOf(INDICATOR, index);
052        if (index == -1) {
053          text = label;
054        } else if (index == label.length() - 1) {
055          LOG.warn(INDICATOR + " in label is last char, this is not allowed"
056              + "label='" + label + "'.");
057          text = label.substring(0, label.length() - 1);
058          pos = -1;
059        } else if (label.charAt(index + 1) == INDICATOR) {
060          escapedIndicatorCount++;
061          findIndicator(label, index + 2, escapedIndicatorCount);
062        } else {
063          text = label.substring(0, index)
064              + label.substring(index + 1);
065          accessKey = text.charAt(index);
066          pos = index - escapedIndicatorCount;
067        }
068      }
069    
070      public void setup(String label) {
071        if (label != null) {
072          findIndicator(label, 0, 0);
073          text = StringUtils.replace(text, ESCAPED_INDICATOR, String.valueOf(INDICATOR));
074        } else {
075          if (accessKey != null && text != null) {
076            pos = text.toLowerCase(Locale.ENGLISH).indexOf(
077                Character.toLowerCase(accessKey.charValue()));
078          }
079        }
080      }
081    
082      public void reset() {
083        text = null;
084        accessKey = null;
085        pos = -1;
086      }
087    
088      public String getText() {
089        return text;
090      }
091    
092      public Character getAccessKey() {
093        return accessKey;
094      }
095    
096      public int getPos() {
097        return pos;
098      }
099    
100      public void setText(String text) {
101        this.text = text;
102      }
103    
104      public void setAccessKey(Character accessKey) {
105        this.accessKey = accessKey;
106      }
107    
108    }