Home | History | Annotate | Download | only in expected
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.inputmethod.keyboard.layout.expected;
     18 
     19 import com.android.inputmethod.keyboard.Key;
     20 import com.android.inputmethod.keyboard.internal.MoreKeySpec;
     21 import com.android.inputmethod.latin.common.Constants;
     22 import com.android.inputmethod.latin.common.StringUtils;
     23 
     24 import java.util.Locale;
     25 
     26 /**
     27  * This class represents an expected output of a key.
     28  *
     29  * There are two types of expected output, an integer code point and a string output text.
     30  */
     31 abstract class ExpectedKeyOutput {
     32     static ExpectedKeyOutput newInstance(final int code) {
     33         return new Code(code);
     34     }
     35 
     36     static ExpectedKeyOutput newInstance(final String outputText) {
     37         // If the <code>outputText</code> is one code point string, use {@link CodePoint} object.
     38         if (StringUtils.codePointCount(outputText) == 1) {
     39             return new Code(outputText.codePointAt(0));
     40         }
     41         return new Text(outputText);
     42     }
     43 
     44     abstract ExpectedKeyOutput toUpperCase(final Locale locale);
     45     abstract ExpectedKeyOutput preserveCase();
     46     abstract boolean hasSameKeyOutput(final String text);
     47     abstract boolean hasSameKeyOutput(final Key key);
     48     abstract boolean hasSameKeyOutput(final MoreKeySpec moreKeySpec);
     49     abstract boolean hasSameKeyOutput(final ExpectedKeyOutput output);
     50 
     51     /**
     52      * This class represents an integer code point.
     53      */
     54     private static class Code extends ExpectedKeyOutput {
     55         // UNICODE code point or a special negative value defined in {@link Constants}.
     56         private final int mCode;
     57 
     58         Code(final int code) { mCode = code; }
     59 
     60         @Override
     61         ExpectedKeyOutput toUpperCase(final Locale locale) {
     62             if (Constants.isLetterCode(mCode)) {
     63                 final String codeString = StringUtils.newSingleCodePointString(mCode);
     64                 // A letter may have an upper case counterpart that consists of multiple code
     65                 // points, for instance the upper case of "" is "SS".
     66                 return newInstance(StringUtils.toTitleCaseOfKeyLabel(codeString, locale));
     67             }
     68             // A special negative value has no upper case.
     69             return this;
     70         }
     71 
     72         @Override
     73         ExpectedKeyOutput preserveCase() {
     74             return new CasePreservedCode(mCode);
     75         }
     76 
     77         @Override
     78         boolean hasSameKeyOutput(final String text) {
     79             return StringUtils.codePointCount(text) == 1 && text.codePointAt(0) == mCode;
     80         }
     81 
     82         @Override
     83         boolean hasSameKeyOutput(final Key key) {
     84             return mCode == key.getCode();
     85         }
     86 
     87         @Override
     88         boolean hasSameKeyOutput(final MoreKeySpec moreKeySpec) {
     89             return mCode == moreKeySpec.mCode;
     90         }
     91 
     92         @Override
     93         boolean hasSameKeyOutput(final ExpectedKeyOutput output) {
     94             return (output instanceof Code) && mCode == ((Code)output).mCode;
     95         }
     96 
     97         @Override
     98         public String toString() {
     99             return Constants.isLetterCode(mCode) ? StringUtils.newSingleCodePointString(mCode)
    100                     : Constants.printableCode(mCode);
    101         }
    102 
    103         private static class CasePreservedCode extends Code {
    104             CasePreservedCode(final int code) { super(code); }
    105 
    106             @Override
    107             ExpectedKeyOutput toUpperCase(final Locale locale) { return this; }
    108 
    109             @Override
    110             ExpectedKeyOutput preserveCase() { return this; }
    111         }
    112     }
    113 
    114     /**
    115      * This class represents a string output text.
    116      */
    117     private static class Text extends ExpectedKeyOutput {
    118         private final String mText;
    119 
    120         Text(final String text) { mText = text; }
    121 
    122         @Override
    123         ExpectedKeyOutput toUpperCase(final Locale locale) {
    124             return newInstance(mText.toUpperCase(locale));
    125         }
    126 
    127         @Override
    128         ExpectedKeyOutput preserveCase() {
    129             return new CasePreservedText(mText);
    130         }
    131 
    132         @Override
    133         boolean hasSameKeyOutput(final String text) {
    134             return text.equals(text);
    135         }
    136 
    137         @Override
    138         boolean hasSameKeyOutput(final Key key) {
    139             return key.getCode() == Constants.CODE_OUTPUT_TEXT
    140                     && mText.equals(key.getOutputText());
    141         }
    142 
    143         @Override
    144         boolean hasSameKeyOutput(final MoreKeySpec moreKeySpec) {
    145             return moreKeySpec.mCode == Constants.CODE_OUTPUT_TEXT
    146                     && mText.equals(moreKeySpec.mOutputText);
    147         }
    148 
    149         @Override
    150         boolean hasSameKeyOutput(final ExpectedKeyOutput output) {
    151             return (output instanceof Text) && mText == ((Text)output).mText;
    152         }
    153 
    154         @Override
    155         public String toString() {
    156             return mText;
    157         }
    158 
    159         private static class CasePreservedText extends Text {
    160             CasePreservedText(final String text) { super(text); }
    161 
    162             @Override
    163             ExpectedKeyOutput toUpperCase(final Locale locale) { return this; }
    164 
    165             @Override
    166             ExpectedKeyOutput preserveCase() { return this; }
    167         }
    168     }
    169 }
    170