Example usage for java.lang CharSequence charAt

List of usage examples for java.lang CharSequence charAt

Introduction

In this page you can find the example usage for java.lang CharSequence charAt.

Prototype

char charAt(int index);

Source Link

Document

Returns the char value at the specified index.

Usage

From source file:org.apache.commons.lang3.StringUtils.java

/**
 * <p>Find the Levenshtein distance between two Strings if it's less than or equal to a given 
 * threshold.</p>//from  w  w w . j  a v  a 2  s.  co  m
 *
 * <p>This is the number of changes needed to change one String into
 * another, where each change is a single character modification (deletion,
 * insertion or substitution).</p>
 *
 * <p>This implementation follows from Algorithms on Strings, Trees and Sequences by Dan Gusfield
 * and Chas Emerick's implementation of the Levenshtein distance algorithm from
 * <a href="http://www.merriampark.com/ld.htm">http://www.merriampark.com/ld.htm</a></p>
 *
 * <pre>
 * StringUtils.getLevenshteinDistance(null, *, *)             = IllegalArgumentException
 * StringUtils.getLevenshteinDistance(*, null, *)             = IllegalArgumentException
 * StringUtils.getLevenshteinDistance(*, *, -1)               = IllegalArgumentException
 * StringUtils.getLevenshteinDistance("","", 0)               = 0
 * StringUtils.getLevenshteinDistance("aaapppp", "", 8)       = 7
 * StringUtils.getLevenshteinDistance("aaapppp", "", 7)       = 7
 * StringUtils.getLevenshteinDistance("aaapppp", "", 6))      = -1
 * StringUtils.getLevenshteinDistance("elephant", "hippo", 7) = 7
 * StringUtils.getLevenshteinDistance("elephant", "hippo", 6) = -1
 * StringUtils.getLevenshteinDistance("hippo", "elephant", 7) = 7
 * StringUtils.getLevenshteinDistance("hippo", "elephant", 6) = -1
 * </pre>
 *
 * @param s  the first String, must not be null
 * @param t  the second String, must not be null
 * @param threshold the target threshold, must not be negative
 * @return result distance, or {@code -1} if the distance would be greater than the threshold
 * @throws IllegalArgumentException if either String input {@code null} or negative threshold
 */
public static int getLevenshteinDistance(CharSequence s, CharSequence t, int threshold) {
    if (s == null || t == null) {
        throw new IllegalArgumentException("Strings must not be null");
    }
    if (threshold < 0) {
        throw new IllegalArgumentException("Threshold must not be negative");
    }

    /*
    This implementation only computes the distance if it's less than or equal to the
    threshold value, returning -1 if it's greater.  The advantage is performance: unbounded
    distance is O(nm), but a bound of k allows us to reduce it to O(km) time by only 
    computing a diagonal stripe of width 2k + 1 of the cost table.
    It is also possible to use this to compute the unbounded Levenshtein distance by starting
    the threshold at 1 and doubling each time until the distance is found; this is O(dm), where
    d is the distance.
            
    One subtlety comes from needing to ignore entries on the border of our stripe
    eg.
    p[] = |#|#|#|*
    d[] =  *|#|#|#|
    We must ignore the entry to the left of the leftmost member
    We must ignore the entry above the rightmost member
            
    Another subtlety comes from our stripe running off the matrix if the strings aren't
    of the same size.  Since string s is always swapped to be the shorter of the two, 
    the stripe will always run off to the upper right instead of the lower left of the matrix.
            
    As a concrete example, suppose s is of length 5, t is of length 7, and our threshold is 1.
    In this case we're going to walk a stripe of length 3.  The matrix would look like so:
            
       1 2 3 4 5
    1 |#|#| | | |
    2 |#|#|#| | |
    3 | |#|#|#| |
    4 | | |#|#|#|
    5 | | | |#|#|
    6 | | | | |#|
    7 | | | | | |
            
    Note how the stripe leads off the table as there is no possible way to turn a string of length 5
    into one of length 7 in edit distance of 1.
            
    Additionally, this implementation decreases memory usage by using two 
    single-dimensional arrays and swapping them back and forth instead of allocating
    an entire n by m matrix.  This requires a few minor changes, such as immediately returning 
    when it's detected that the stripe has run off the matrix and initially filling the arrays with
    large values so that entries we don't compute are ignored.
            
    See Algorithms on Strings, Trees and Sequences by Dan Gusfield for some discussion.
     */

    int n = s.length(); // length of s
    int m = t.length(); // length of t

    // if one string is empty, the edit distance is necessarily the length of the other
    if (n == 0) {
        return m <= threshold ? m : -1;
    } else if (m == 0) {
        return n <= threshold ? n : -1;
    }

    if (n > m) {
        // swap the two strings to consume less memory
        CharSequence tmp = s;
        s = t;
        t = tmp;
        n = m;
        m = t.length();
    }

    int p[] = new int[n + 1]; // 'previous' cost array, horizontally
    int d[] = new int[n + 1]; // cost array, horizontally
    int _d[]; // placeholder to assist in swapping p and d

    // fill in starting table values
    int boundary = Math.min(n, threshold) + 1;
    for (int i = 0; i < boundary; i++) {
        p[i] = i;
    }
    // these fills ensure that the value above the rightmost entry of our 
    // stripe will be ignored in following loop iterations
    Arrays.fill(p, boundary, p.length, Integer.MAX_VALUE);
    Arrays.fill(d, Integer.MAX_VALUE);

    // iterates through t
    for (int j = 1; j <= m; j++) {
        char t_j = t.charAt(j - 1); // jth character of t
        d[0] = j;

        // compute stripe indices, constrain to array size
        int min = Math.max(1, j - threshold);
        int max = Math.min(n, j + threshold);

        // the stripe may lead off of the table if s and t are of different sizes
        if (min > max) {
            return -1;
        }

        // ignore entry left of leftmost
        if (min > 1) {
            d[min - 1] = Integer.MAX_VALUE;
        }

        // iterates through [min, max] in s
        for (int i = min; i <= max; i++) {
            if (s.charAt(i - 1) == t_j) {
                // diagonally left and up
                d[i] = p[i - 1];
            } else {
                // 1 + minimum of cell to the left, to the top, diagonally left and up
                d[i] = 1 + Math.min(Math.min(d[i - 1], p[i]), p[i - 1]);
            }
        }

        // copy current distance counts to 'previous row' distance counts
        _d = p;
        p = d;
        d = _d;
    }

    // if p[n] is greater than the threshold, there's no guarantee on it being the correct
    // distance
    if (p[n] <= threshold) {
        return p[n];
    } else {
        return -1;
    }
}

From source file:org.telegram.ui.PassportActivity.java

private void createAddressInterface(Context context) {
    languageMap = new HashMap<>();
    try {/*from  w  w  w  .j av a 2s  .c o  m*/
        BufferedReader reader = new BufferedReader(
                new InputStreamReader(context.getResources().getAssets().open("countries.txt")));
        String line;
        while ((line = reader.readLine()) != null) {
            String[] args = line.split(";");
            languageMap.put(args[1], args[2]);
        }
        reader.close();
    } catch (Exception e) {
        FileLog.e(e);
    }

    topErrorCell = new TextInfoPrivacyCell(context);
    topErrorCell.setBackgroundDrawable(
            Theme.getThemedDrawable(context, R.drawable.greydivider_top, Theme.key_windowBackgroundGrayShadow));
    topErrorCell.setPadding(0, AndroidUtilities.dp(7), 0, 0);
    linearLayout2.addView(topErrorCell,
            LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
    checkTopErrorCell(true);

    if (currentDocumentsType != null) {
        if (currentDocumentsType.type instanceof TLRPC.TL_secureValueTypeRentalAgreement) {
            actionBar.setTitle(LocaleController.getString("ActionBotDocumentRentalAgreement",
                    R.string.ActionBotDocumentRentalAgreement));
        } else if (currentDocumentsType.type instanceof TLRPC.TL_secureValueTypeBankStatement) {
            actionBar.setTitle(LocaleController.getString("ActionBotDocumentBankStatement",
                    R.string.ActionBotDocumentBankStatement));
        } else if (currentDocumentsType.type instanceof TLRPC.TL_secureValueTypeUtilityBill) {
            actionBar.setTitle(LocaleController.getString("ActionBotDocumentUtilityBill",
                    R.string.ActionBotDocumentUtilityBill));
        } else if (currentDocumentsType.type instanceof TLRPC.TL_secureValueTypePassportRegistration) {
            actionBar.setTitle(LocaleController.getString("ActionBotDocumentPassportRegistration",
                    R.string.ActionBotDocumentPassportRegistration));
        } else if (currentDocumentsType.type instanceof TLRPC.TL_secureValueTypeTemporaryRegistration) {
            actionBar.setTitle(LocaleController.getString("ActionBotDocumentTemporaryRegistration",
                    R.string.ActionBotDocumentTemporaryRegistration));
        }

        headerCell = new HeaderCell(context);
        headerCell.setText(LocaleController.getString("PassportDocuments", R.string.PassportDocuments));
        headerCell.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
        linearLayout2.addView(headerCell,
                LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));

        documentsLayout = new LinearLayout(context);
        documentsLayout.setOrientation(LinearLayout.VERTICAL);
        linearLayout2.addView(documentsLayout,
                LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));

        uploadDocumentCell = new TextSettingsCell(context);
        uploadDocumentCell.setBackgroundDrawable(Theme.getSelectorDrawable(true));
        linearLayout2.addView(uploadDocumentCell,
                LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
        uploadDocumentCell.setOnClickListener(v -> {
            uploadingFileType = UPLOADING_TYPE_DOCUMENTS;
            openAttachMenu();
        });

        bottomCell = new TextInfoPrivacyCell(context);
        bottomCell.setBackgroundDrawable(
                Theme.getThemedDrawable(context, R.drawable.greydivider, Theme.key_windowBackgroundGrayShadow));

        if (currentBotId != 0) {
            noAllDocumentsErrorText = LocaleController.getString("PassportAddAddressUploadInfo",
                    R.string.PassportAddAddressUploadInfo);
        } else {
            if (currentDocumentsType.type instanceof TLRPC.TL_secureValueTypeRentalAgreement) {
                noAllDocumentsErrorText = LocaleController.getString("PassportAddAgreementInfo",
                        R.string.PassportAddAgreementInfo);
            } else if (currentDocumentsType.type instanceof TLRPC.TL_secureValueTypeUtilityBill) {
                noAllDocumentsErrorText = LocaleController.getString("PassportAddBillInfo",
                        R.string.PassportAddBillInfo);
            } else if (currentDocumentsType.type instanceof TLRPC.TL_secureValueTypePassportRegistration) {
                noAllDocumentsErrorText = LocaleController.getString("PassportAddPassportRegistrationInfo",
                        R.string.PassportAddPassportRegistrationInfo);
            } else if (currentDocumentsType.type instanceof TLRPC.TL_secureValueTypeTemporaryRegistration) {
                noAllDocumentsErrorText = LocaleController.getString("PassportAddTemporaryRegistrationInfo",
                        R.string.PassportAddTemporaryRegistrationInfo);
            } else if (currentDocumentsType.type instanceof TLRPC.TL_secureValueTypeBankStatement) {
                noAllDocumentsErrorText = LocaleController.getString("PassportAddBankInfo",
                        R.string.PassportAddBankInfo);
            } else {
                noAllDocumentsErrorText = "";
            }
        }

        CharSequence text = noAllDocumentsErrorText;
        if (documentsErrors != null) {
            String errorText;
            if ((errorText = documentsErrors.get("files_all")) != null) {
                SpannableStringBuilder stringBuilder = new SpannableStringBuilder(errorText);
                stringBuilder.append("\n\n");
                stringBuilder.append(noAllDocumentsErrorText);
                text = stringBuilder;
                stringBuilder.setSpan(
                        new ForegroundColorSpan(Theme.getColor(Theme.key_windowBackgroundWhiteRedText3)), 0,
                        errorText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                errorsValues.put("files_all", "");
            }
        }
        bottomCell.setText(text);
        linearLayout2.addView(bottomCell,
                LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));

        if (currentDocumentsType.translation_required) {
            headerCell = new HeaderCell(context);
            headerCell.setText(LocaleController.getString("PassportTranslation", R.string.PassportTranslation));
            headerCell.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
            linearLayout2.addView(headerCell,
                    LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));

            translationLayout = new LinearLayout(context);
            translationLayout.setOrientation(LinearLayout.VERTICAL);
            linearLayout2.addView(translationLayout,
                    LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));

            uploadTranslationCell = new TextSettingsCell(context);
            uploadTranslationCell.setBackgroundDrawable(Theme.getSelectorDrawable(true));
            linearLayout2.addView(uploadTranslationCell,
                    LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
            uploadTranslationCell.setOnClickListener(v -> {
                uploadingFileType = UPLOADING_TYPE_TRANSLATION;
                openAttachMenu();
            });

            bottomCellTranslation = new TextInfoPrivacyCell(context);
            bottomCellTranslation.setBackgroundDrawable(Theme.getThemedDrawable(context, R.drawable.greydivider,
                    Theme.key_windowBackgroundGrayShadow));

            if (currentBotId != 0) {
                noAllTranslationErrorText = LocaleController.getString("PassportAddTranslationUploadInfo",
                        R.string.PassportAddTranslationUploadInfo);
            } else {
                if (currentDocumentsType.type instanceof TLRPC.TL_secureValueTypeRentalAgreement) {
                    noAllTranslationErrorText = LocaleController.getString(
                            "PassportAddTranslationAgreementInfo",
                            R.string.PassportAddTranslationAgreementInfo);
                } else if (currentDocumentsType.type instanceof TLRPC.TL_secureValueTypeUtilityBill) {
                    noAllTranslationErrorText = LocaleController.getString("PassportAddTranslationBillInfo",
                            R.string.PassportAddTranslationBillInfo);
                } else if (currentDocumentsType.type instanceof TLRPC.TL_secureValueTypePassportRegistration) {
                    noAllTranslationErrorText = LocaleController.getString(
                            "PassportAddTranslationPassportRegistrationInfo",
                            R.string.PassportAddTranslationPassportRegistrationInfo);
                } else if (currentDocumentsType.type instanceof TLRPC.TL_secureValueTypeTemporaryRegistration) {
                    noAllTranslationErrorText = LocaleController.getString(
                            "PassportAddTranslationTemporaryRegistrationInfo",
                            R.string.PassportAddTranslationTemporaryRegistrationInfo);
                } else if (currentDocumentsType.type instanceof TLRPC.TL_secureValueTypeBankStatement) {
                    noAllTranslationErrorText = LocaleController.getString("PassportAddTranslationBankInfo",
                            R.string.PassportAddTranslationBankInfo);
                } else {
                    noAllTranslationErrorText = "";
                }
            }

            text = noAllTranslationErrorText;
            if (documentsErrors != null) {
                String errorText;
                if ((errorText = documentsErrors.get("translation_all")) != null) {
                    SpannableStringBuilder stringBuilder = new SpannableStringBuilder(errorText);
                    stringBuilder.append("\n\n");
                    stringBuilder.append(noAllTranslationErrorText);
                    text = stringBuilder;
                    stringBuilder.setSpan(
                            new ForegroundColorSpan(Theme.getColor(Theme.key_windowBackgroundWhiteRedText3)), 0,
                            errorText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                    errorsValues.put("translation_all", "");
                }
            }
            bottomCellTranslation.setText(text);
            linearLayout2.addView(bottomCellTranslation,
                    LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
        }
    } else {
        actionBar.setTitle(LocaleController.getString("PassportAddress", R.string.PassportAddress));
    }

    headerCell = new HeaderCell(context);
    headerCell.setText(LocaleController.getString("PassportAddressHeader", R.string.PassportAddressHeader));
    headerCell.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
    linearLayout2.addView(headerCell,
            LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));

    inputFields = new EditTextBoldCursor[FIELD_ADDRESS_COUNT];
    for (int a = 0; a < FIELD_ADDRESS_COUNT; a++) {
        final EditTextBoldCursor field = new EditTextBoldCursor(context);
        inputFields[a] = field;

        ViewGroup container = new FrameLayout(context) {

            private StaticLayout errorLayout;
            float offsetX;

            @Override
            protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
                int width = MeasureSpec.getSize(widthMeasureSpec) - AndroidUtilities.dp(34);
                errorLayout = field.getErrorLayout(width);
                if (errorLayout != null) {
                    int lineCount = errorLayout.getLineCount();
                    if (lineCount > 1) {
                        int height = AndroidUtilities.dp(64)
                                + (errorLayout.getLineBottom(lineCount - 1) - errorLayout.getLineBottom(0));
                        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
                    }
                    if (LocaleController.isRTL) {
                        float maxW = 0;
                        for (int a = 0; a < lineCount; a++) {
                            float l = errorLayout.getLineLeft(a);
                            if (l != 0) {
                                offsetX = 0;
                                break;
                            }
                            maxW = Math.max(maxW, errorLayout.getLineWidth(a));
                            if (a == lineCount - 1) {
                                offsetX = width - maxW;
                            }
                        }
                    }
                }
                super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            }

            @Override
            protected void onDraw(Canvas canvas) {
                if (errorLayout != null) {
                    canvas.save();
                    canvas.translate(AndroidUtilities.dp(21) + offsetX,
                            field.getLineY() + AndroidUtilities.dp(3));
                    errorLayout.draw(canvas);
                    canvas.restore();
                }
            }
        };
        container.setWillNotDraw(false);
        linearLayout2.addView(container,
                LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
        container.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));

        if (a == FIELD_ADDRESS_COUNT - 1) {
            extraBackgroundView = new View(context);
            extraBackgroundView.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
            linearLayout2.addView(extraBackgroundView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 6));
        }

        if (documentOnly && currentDocumentsType != null) {
            container.setVisibility(View.GONE);
            if (extraBackgroundView != null) {
                extraBackgroundView.setVisibility(View.GONE);
            }
        }

        inputFields[a].setTag(a);
        inputFields[a].setSupportRtlHint(true);
        inputFields[a].setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
        inputFields[a].setHintColor(Theme.getColor(Theme.key_windowBackgroundWhiteHintText));
        inputFields[a].setHeaderHintColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlueHeader));
        inputFields[a].setTransformHintToHeader(true);
        inputFields[a].setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
        inputFields[a].setBackgroundDrawable(null);
        inputFields[a].setCursorColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
        inputFields[a].setCursorSize(AndroidUtilities.dp(20));
        inputFields[a].setCursorWidth(1.5f);
        inputFields[a].setLineColors(Theme.getColor(Theme.key_windowBackgroundWhiteInputField),
                Theme.getColor(Theme.key_windowBackgroundWhiteInputFieldActivated),
                Theme.getColor(Theme.key_windowBackgroundWhiteRedText3));
        if (a == FIELD_COUNTRY) {
            inputFields[a].setOnTouchListener((v, event) -> {
                if (getParentActivity() == null) {
                    return false;
                }
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    CountrySelectActivity fragment = new CountrySelectActivity(false);
                    fragment.setCountrySelectActivityDelegate((name, shortName) -> {
                        inputFields[FIELD_COUNTRY].setText(name);
                        currentCitizeship = shortName;
                    });
                    presentFragment(fragment);
                }
                return true;
            });
            inputFields[a].setInputType(0);
            inputFields[a].setFocusable(false);
        } else {
            inputFields[a].setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
            inputFields[a].setImeOptions(EditorInfo.IME_ACTION_NEXT | EditorInfo.IME_FLAG_NO_EXTRACT_UI);
        }
        String value;
        final String key;
        switch (a) {
        case FIELD_STREET1:
            inputFields[a].setHintText(LocaleController.getString("PassportStreet1", R.string.PassportStreet1));
            key = "street_line1";
            break;
        case FIELD_STREET2:
            inputFields[a].setHintText(LocaleController.getString("PassportStreet2", R.string.PassportStreet2));
            key = "street_line2";
            break;
        case FIELD_CITY:
            inputFields[a].setHintText(LocaleController.getString("PassportCity", R.string.PassportCity));
            key = "city";
            break;
        case FIELD_STATE:
            inputFields[a].setHintText(LocaleController.getString("PassportState", R.string.PassportState));
            key = "state";
            break;
        case FIELD_COUNTRY:
            inputFields[a].setHintText(LocaleController.getString("PassportCountry", R.string.PassportCountry));
            key = "country_code";
            break;
        case FIELD_POSTCODE:
            inputFields[a]
                    .setHintText(LocaleController.getString("PassportPostcode", R.string.PassportPostcode));
            key = "post_code";
            break;
        default:
            continue;
        }
        setFieldValues(currentValues, inputFields[a], key);
        if (a == FIELD_POSTCODE) {
            inputFields[a].addTextChangedListener(new TextWatcher() {

                private boolean ignore;

                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {

                }

                @Override
                public void afterTextChanged(Editable s) {
                    if (ignore) {
                        return;
                    }
                    ignore = true;
                    boolean error = false;
                    for (int a = 0; a < s.length(); a++) {
                        char ch = s.charAt(a);
                        if (!(ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9'
                                || ch == '-' || ch == ' ')) {
                            error = true;
                            break;
                        }
                    }
                    ignore = false;
                    if (error) {
                        field.setErrorText(LocaleController.getString("PassportUseLatinOnly",
                                R.string.PassportUseLatinOnly));
                    } else {
                        checkFieldForError(field, key, s, false);
                    }
                }
            });
            InputFilter[] inputFilters = new InputFilter[1];
            inputFilters[0] = new InputFilter.LengthFilter(10);
            inputFields[a].setFilters(inputFilters);
        } else {
            inputFields[a].addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {

                }

                @Override
                public void afterTextChanged(Editable s) {
                    checkFieldForError(field, key, s, false);
                }
            });
        }

        inputFields[a].setSelection(inputFields[a].length());
        inputFields[a].setPadding(0, 0, 0, 0);
        inputFields[a]
                .setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
        container.addView(inputFields[a], LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 64,
                Gravity.LEFT | Gravity.TOP, 21, 0, 21, 0));

        inputFields[a].setOnEditorActionListener((textView, i, keyEvent) -> {
            if (i == EditorInfo.IME_ACTION_NEXT) {
                int num = (Integer) textView.getTag();
                num++;
                if (num < inputFields.length) {
                    if (inputFields[num].isFocusable()) {
                        inputFields[num].requestFocus();
                    } else {
                        inputFields[num]
                                .dispatchTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, 0, 0, 0));
                        textView.clearFocus();
                        AndroidUtilities.hideKeyboard(textView);
                    }
                }
                return true;
            }
            return false;
        });
    }

    sectionCell = new ShadowSectionCell(context);
    linearLayout2.addView(sectionCell,
            LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));

    if (documentOnly && currentDocumentsType != null) {
        headerCell.setVisibility(View.GONE);
        sectionCell.setVisibility(View.GONE);
    }

    if ((currentBotId != 0 || currentDocumentsType == null) && currentTypeValue != null && !documentOnly
            || currentDocumentsTypeValue != null) {
        if (currentDocumentsTypeValue != null) {
            addDocumentViews(currentDocumentsTypeValue.files);
            addTranslationDocumentViews(currentDocumentsTypeValue.translation);
        }
        sectionCell.setBackgroundDrawable(
                Theme.getThemedDrawable(context, R.drawable.greydivider, Theme.key_windowBackgroundGrayShadow));

        TextSettingsCell settingsCell1 = new TextSettingsCell(context);
        settingsCell1.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteRedText3));
        settingsCell1.setBackgroundDrawable(Theme.getSelectorDrawable(true));
        if (currentDocumentsType == null) {
            settingsCell1.setText(LocaleController.getString("PassportDeleteInfo", R.string.PassportDeleteInfo),
                    false);
        } else {
            settingsCell1.setText(
                    LocaleController.getString("PassportDeleteDocument", R.string.PassportDeleteDocument),
                    false);
        }
        linearLayout2.addView(settingsCell1,
                LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
        settingsCell1.setOnClickListener(v -> createDocumentDeleteAlert());

        sectionCell = new ShadowSectionCell(context);
        sectionCell.setBackgroundDrawable(Theme.getThemedDrawable(context, R.drawable.greydivider_bottom,
                Theme.key_windowBackgroundGrayShadow));
        linearLayout2.addView(sectionCell,
                LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
    } else {
        sectionCell.setBackgroundDrawable(Theme.getThemedDrawable(context, R.drawable.greydivider_bottom,
                Theme.key_windowBackgroundGrayShadow));
        if (documentOnly && currentDocumentsType != null) {
            bottomCell.setBackgroundDrawable(Theme.getThemedDrawable(context, R.drawable.greydivider_bottom,
                    Theme.key_windowBackgroundGrayShadow));
        }
    }
    updateUploadText(UPLOADING_TYPE_DOCUMENTS);
    updateUploadText(UPLOADING_TYPE_TRANSLATION);
}

From source file:org.telegram.ui.PassportActivity.java

private void createIdentityInterface(final Context context) {
    languageMap = new HashMap<>();
    try {/*from   www . j  a va  2s.  c o m*/
        BufferedReader reader = new BufferedReader(
                new InputStreamReader(context.getResources().getAssets().open("countries.txt")));
        String line;
        while ((line = reader.readLine()) != null) {
            String[] args = line.split(";");
            languageMap.put(args[1], args[2]);
        }
        reader.close();
    } catch (Exception e) {
        FileLog.e(e);
    }

    topErrorCell = new TextInfoPrivacyCell(context);
    topErrorCell.setBackgroundDrawable(
            Theme.getThemedDrawable(context, R.drawable.greydivider_top, Theme.key_windowBackgroundGrayShadow));
    topErrorCell.setPadding(0, AndroidUtilities.dp(7), 0, 0);
    linearLayout2.addView(topErrorCell,
            LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
    checkTopErrorCell(true);

    if (currentDocumentsType != null) {
        headerCell = new HeaderCell(context);
        if (documentOnly) {
            headerCell.setText(LocaleController.getString("PassportDocuments", R.string.PassportDocuments));
        } else {
            headerCell.setText(LocaleController.getString("PassportRequiredDocuments",
                    R.string.PassportRequiredDocuments));
        }
        headerCell.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
        linearLayout2.addView(headerCell,
                LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));

        frontLayout = new LinearLayout(context);
        frontLayout.setOrientation(LinearLayout.VERTICAL);
        linearLayout2.addView(frontLayout,
                LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));

        uploadFrontCell = new TextDetailSettingsCell(context);
        uploadFrontCell.setBackgroundDrawable(Theme.getSelectorDrawable(true));
        linearLayout2.addView(uploadFrontCell,
                LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
        uploadFrontCell.setOnClickListener(v -> {
            uploadingFileType = UPLOADING_TYPE_FRONT;
            openAttachMenu();
        });

        reverseLayout = new LinearLayout(context);
        reverseLayout.setOrientation(LinearLayout.VERTICAL);
        linearLayout2.addView(reverseLayout,
                LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));

        boolean divider = currentDocumentsType.selfie_required;

        uploadReverseCell = new TextDetailSettingsCell(context);
        uploadReverseCell.setBackgroundDrawable(Theme.getSelectorDrawable(true));
        uploadReverseCell.setTextAndValue(
                LocaleController.getString("PassportReverseSide", R.string.PassportReverseSide),
                LocaleController.getString("PassportReverseSideInfo", R.string.PassportReverseSideInfo),
                divider);
        linearLayout2.addView(uploadReverseCell,
                LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
        uploadReverseCell.setOnClickListener(v -> {
            uploadingFileType = UPLOADING_TYPE_REVERSE;
            openAttachMenu();
        });

        if (currentDocumentsType.selfie_required) {
            selfieLayout = new LinearLayout(context);
            selfieLayout.setOrientation(LinearLayout.VERTICAL);
            linearLayout2.addView(selfieLayout,
                    LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));

            uploadSelfieCell = new TextDetailSettingsCell(context);
            uploadSelfieCell.setBackgroundDrawable(Theme.getSelectorDrawable(true));
            uploadSelfieCell.setTextAndValue(
                    LocaleController.getString("PassportSelfie", R.string.PassportSelfie),
                    LocaleController.getString("PassportSelfieInfo", R.string.PassportSelfieInfo),
                    currentType.translation_required);
            linearLayout2.addView(uploadSelfieCell,
                    LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
            uploadSelfieCell.setOnClickListener(v -> {
                uploadingFileType = UPLOADING_TYPE_SELFIE;
                openAttachMenu();
            });
        }

        bottomCell = new TextInfoPrivacyCell(context);
        bottomCell.setBackgroundDrawable(
                Theme.getThemedDrawable(context, R.drawable.greydivider, Theme.key_windowBackgroundGrayShadow));
        bottomCell.setText(
                LocaleController.getString("PassportPersonalUploadInfo", R.string.PassportPersonalUploadInfo));
        linearLayout2.addView(bottomCell,
                LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));

        if (currentDocumentsType.translation_required) {
            headerCell = new HeaderCell(context);
            headerCell.setText(LocaleController.getString("PassportTranslation", R.string.PassportTranslation));
            headerCell.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
            linearLayout2.addView(headerCell,
                    LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));

            translationLayout = new LinearLayout(context);
            translationLayout.setOrientation(LinearLayout.VERTICAL);
            linearLayout2.addView(translationLayout,
                    LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));

            uploadTranslationCell = new TextSettingsCell(context);
            uploadTranslationCell.setBackgroundDrawable(Theme.getSelectorDrawable(true));
            linearLayout2.addView(uploadTranslationCell,
                    LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
            uploadTranslationCell.setOnClickListener(v -> {
                uploadingFileType = UPLOADING_TYPE_TRANSLATION;
                openAttachMenu();
            });

            bottomCellTranslation = new TextInfoPrivacyCell(context);
            bottomCellTranslation.setBackgroundDrawable(Theme.getThemedDrawable(context, R.drawable.greydivider,
                    Theme.key_windowBackgroundGrayShadow));

            if (currentBotId != 0) {
                noAllTranslationErrorText = LocaleController.getString("PassportAddTranslationUploadInfo",
                        R.string.PassportAddTranslationUploadInfo);
            } else {
                if (currentDocumentsType.type instanceof TLRPC.TL_secureValueTypePassport) {
                    noAllTranslationErrorText = LocaleController.getString("PassportAddPassportInfo",
                            R.string.PassportAddPassportInfo);
                } else if (currentDocumentsType.type instanceof TLRPC.TL_secureValueTypeInternalPassport) {
                    noAllTranslationErrorText = LocaleController.getString("PassportAddInternalPassportInfo",
                            R.string.PassportAddInternalPassportInfo);
                } else if (currentDocumentsType.type instanceof TLRPC.TL_secureValueTypeIdentityCard) {
                    noAllTranslationErrorText = LocaleController.getString("PassportAddIdentityCardInfo",
                            R.string.PassportAddIdentityCardInfo);
                } else if (currentDocumentsType.type instanceof TLRPC.TL_secureValueTypeDriverLicense) {
                    noAllTranslationErrorText = LocaleController.getString("PassportAddDriverLicenceInfo",
                            R.string.PassportAddDriverLicenceInfo);
                } else {
                    noAllTranslationErrorText = "";
                }
            }

            CharSequence text = noAllTranslationErrorText;
            if (documentsErrors != null) {
                String errorText;
                if ((errorText = documentsErrors.get("translation_all")) != null) {
                    SpannableStringBuilder stringBuilder = new SpannableStringBuilder(errorText);
                    stringBuilder.append("\n\n");
                    stringBuilder.append(noAllTranslationErrorText);
                    text = stringBuilder;
                    stringBuilder.setSpan(
                            new ForegroundColorSpan(Theme.getColor(Theme.key_windowBackgroundWhiteRedText3)), 0,
                            errorText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                    errorsValues.put("translation_all", "");
                }
            }
            bottomCellTranslation.setText(text);
            linearLayout2.addView(bottomCellTranslation,
                    LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
        }
    } else if (Build.VERSION.SDK_INT >= 18) {
        scanDocumentCell = new TextSettingsCell(context);
        scanDocumentCell.setBackgroundDrawable(Theme.getSelectorDrawable(true));
        scanDocumentCell.setText(
                LocaleController.getString("PassportScanPassport", R.string.PassportScanPassport), false);
        linearLayout2.addView(scanDocumentCell,
                LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
        scanDocumentCell.setOnClickListener(v -> {
            if (Build.VERSION.SDK_INT >= 23 && getParentActivity()
                    .checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                getParentActivity().requestPermissions(new String[] { Manifest.permission.CAMERA }, 22);
                return;
            }
            MrzCameraActivity fragment = new MrzCameraActivity();
            fragment.setDelegate(result -> {
                if (!TextUtils.isEmpty(result.firstName)) {
                    inputFields[FIELD_NAME].setText(result.firstName);
                }
                if (!TextUtils.isEmpty(result.middleName)) {
                    inputFields[FIELD_MIDNAME].setText(result.middleName);
                }
                if (!TextUtils.isEmpty(result.lastName)) {
                    inputFields[FIELD_SURNAME].setText(result.lastName);
                }
                if (result.gender != MrzRecognizer.Result.GENDER_UNKNOWN) {
                    switch (result.gender) {
                    case MrzRecognizer.Result.GENDER_MALE:
                        currentGender = "male";
                        inputFields[FIELD_GENDER]
                                .setText(LocaleController.getString("PassportMale", R.string.PassportMale));
                        break;
                    case MrzRecognizer.Result.GENDER_FEMALE:
                        currentGender = "female";
                        inputFields[FIELD_GENDER]
                                .setText(LocaleController.getString("PassportFemale", R.string.PassportFemale));
                        break;
                    }
                }
                if (!TextUtils.isEmpty(result.nationality)) {
                    currentCitizeship = result.nationality;
                    String country = languageMap.get(currentCitizeship);
                    if (country != null) {
                        inputFields[FIELD_CITIZENSHIP].setText(country);
                    }
                }
                if (!TextUtils.isEmpty(result.issuingCountry)) {
                    currentResidence = result.issuingCountry;
                    String country = languageMap.get(currentResidence);
                    if (country != null) {
                        inputFields[FIELD_RESIDENCE].setText(country);
                    }
                }
                if (result.birthDay > 0 && result.birthMonth > 0 && result.birthYear > 0) {
                    inputFields[FIELD_BIRTHDAY].setText(String.format(Locale.US, "%02d.%02d.%d",
                            result.birthDay, result.birthMonth, result.birthYear));
                }
            });
            presentFragment(fragment);
        });

        bottomCell = new TextInfoPrivacyCell(context);
        bottomCell.setBackgroundDrawable(
                Theme.getThemedDrawable(context, R.drawable.greydivider, Theme.key_windowBackgroundGrayShadow));
        bottomCell.setText(
                LocaleController.getString("PassportScanPassportInfo", R.string.PassportScanPassportInfo));
        linearLayout2.addView(bottomCell,
                LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
    }

    headerCell = new HeaderCell(context);
    if (documentOnly) {
        headerCell.setText(LocaleController.getString("PassportDocument", R.string.PassportDocument));
    } else {
        headerCell.setText(LocaleController.getString("PassportPersonal", R.string.PassportPersonal));
    }
    headerCell.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
    linearLayout2.addView(headerCell,
            LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));

    int count = currentDocumentsType != null ? FIELD_IDENTITY_COUNT : FIELD_IDENTITY_NODOC_COUNT;
    inputFields = new EditTextBoldCursor[count];

    for (int a = 0; a < count; a++) {
        final EditTextBoldCursor field = new EditTextBoldCursor(context);
        inputFields[a] = field;

        ViewGroup container = new FrameLayout(context) {

            private StaticLayout errorLayout;
            private float offsetX;

            @Override
            protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
                int width = MeasureSpec.getSize(widthMeasureSpec) - AndroidUtilities.dp(34);
                errorLayout = field.getErrorLayout(width);
                if (errorLayout != null) {
                    int lineCount = errorLayout.getLineCount();
                    if (lineCount > 1) {
                        int height = AndroidUtilities.dp(64)
                                + (errorLayout.getLineBottom(lineCount - 1) - errorLayout.getLineBottom(0));
                        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
                    }
                    if (LocaleController.isRTL) {
                        float maxW = 0;
                        for (int a = 0; a < lineCount; a++) {
                            float l = errorLayout.getLineLeft(a);
                            if (l != 0) {
                                offsetX = 0;
                                break;
                            }
                            maxW = Math.max(maxW, errorLayout.getLineWidth(a));
                            if (a == lineCount - 1) {
                                offsetX = width - maxW;
                            }
                        }
                    }
                }
                super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            }

            @Override
            protected void onDraw(Canvas canvas) {
                if (errorLayout != null) {
                    canvas.save();
                    canvas.translate(AndroidUtilities.dp(21) + offsetX,
                            field.getLineY() + AndroidUtilities.dp(3));
                    errorLayout.draw(canvas);
                    canvas.restore();
                }
            }
        };
        container.setWillNotDraw(false);
        linearLayout2.addView(container, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 64));
        container.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));

        if (a == count - 1) {
            extraBackgroundView = new View(context);
            extraBackgroundView.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
            linearLayout2.addView(extraBackgroundView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 6));
        }

        if (documentOnly && currentDocumentsType != null && a < FIELD_CARDNUMBER) {
            container.setVisibility(View.GONE);
            if (extraBackgroundView != null) {
                extraBackgroundView.setVisibility(View.GONE);
            }
        }

        inputFields[a].setTag(a);
        inputFields[a].setSupportRtlHint(true);
        inputFields[a].setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
        inputFields[a].setHintColor(Theme.getColor(Theme.key_windowBackgroundWhiteHintText));
        inputFields[a].setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
        inputFields[a].setHeaderHintColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlueHeader));
        inputFields[a].setTransformHintToHeader(true);
        inputFields[a].setBackgroundDrawable(null);
        inputFields[a].setCursorColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
        inputFields[a].setCursorSize(AndroidUtilities.dp(20));
        inputFields[a].setCursorWidth(1.5f);
        inputFields[a].setLineColors(Theme.getColor(Theme.key_windowBackgroundWhiteInputField),
                Theme.getColor(Theme.key_windowBackgroundWhiteInputFieldActivated),
                Theme.getColor(Theme.key_windowBackgroundWhiteRedText3));
        if (a == FIELD_CITIZENSHIP || a == FIELD_RESIDENCE) {
            inputFields[a].setOnTouchListener((v, event) -> {
                if (getParentActivity() == null) {
                    return false;
                }
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    CountrySelectActivity fragment = new CountrySelectActivity(false);
                    fragment.setCountrySelectActivityDelegate((name, shortName) -> {
                        int field12 = (Integer) v.getTag();
                        final EditTextBoldCursor editText = inputFields[field12];
                        if (field12 == FIELD_CITIZENSHIP) {
                            currentCitizeship = shortName;
                        } else {
                            currentResidence = shortName;
                        }
                        editText.setText(name);
                    });
                    presentFragment(fragment);
                }
                return true;
            });
            inputFields[a].setInputType(0);
        } else if (a == FIELD_BIRTHDAY || a == FIELD_EXPIRE) {
            inputFields[a].setOnTouchListener((v, event) -> {
                if (getParentActivity() == null) {
                    return false;
                }
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    Calendar calendar = Calendar.getInstance();
                    int year = calendar.get(Calendar.YEAR);
                    int monthOfYear = calendar.get(Calendar.MONTH);
                    int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
                    try {
                        final EditTextBoldCursor field1 = (EditTextBoldCursor) v;
                        int num = (Integer) field1.getTag();
                        int minYear;
                        int maxYear;
                        int currentYearDiff;
                        String title;
                        if (num == FIELD_EXPIRE) {
                            title = LocaleController.getString("PassportSelectExpiredDate",
                                    R.string.PassportSelectExpiredDate);
                            minYear = 0;
                            maxYear = 20;
                            currentYearDiff = 0;
                        } else {
                            title = LocaleController.getString("PassportSelectBithdayDate",
                                    R.string.PassportSelectBithdayDate);
                            minYear = -120;
                            maxYear = 0;
                            currentYearDiff = -18;
                        }
                        int selectedDay = -1;
                        int selectedMonth = -1;
                        int selectedYear = -1;
                        String args[] = field1.getText().toString().split("\\.");
                        if (args.length == 3) {
                            selectedDay = Utilities.parseInt(args[0]);
                            selectedMonth = Utilities.parseInt(args[1]);
                            selectedYear = Utilities.parseInt(args[2]);
                        }
                        AlertDialog.Builder builder = AlertsCreator.createDatePickerDialog(context, minYear,
                                maxYear, currentYearDiff, selectedDay, selectedMonth, selectedYear, title,
                                num == FIELD_EXPIRE, (year1, month, dayOfMonth1) -> {
                                    if (num == FIELD_EXPIRE) {
                                        currentExpireDate[0] = year1;
                                        currentExpireDate[1] = month + 1;
                                        currentExpireDate[2] = dayOfMonth1;
                                    }
                                    field1.setText(String.format(Locale.US, "%02d.%02d.%d", dayOfMonth1,
                                            month + 1, year1));
                                });
                        if (num == FIELD_EXPIRE) {
                            builder.setNegativeButton(LocaleController.getString("PassportSelectNotExpire",
                                    R.string.PassportSelectNotExpire), (dialog, which) -> {
                                        currentExpireDate[0] = currentExpireDate[1] = currentExpireDate[2] = 0;
                                        field1.setText(LocaleController.getString("PassportNoExpireDate",
                                                R.string.PassportNoExpireDate));
                                    });
                        }
                        showDialog(builder.create());
                    } catch (Exception e) {
                        FileLog.e(e);
                    }
                }
                return true;
            });
            inputFields[a].setInputType(0);
            inputFields[a].setFocusable(false);
        } else if (a == FIELD_GENDER) {
            inputFields[a].setOnTouchListener((v, event) -> {
                if (getParentActivity() == null) {
                    return false;
                }
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
                    builder.setTitle(
                            LocaleController.getString("PassportSelectGender", R.string.PassportSelectGender));
                    builder.setItems(
                            new CharSequence[] {
                                    LocaleController.getString("PassportMale", R.string.PassportMale),
                                    LocaleController.getString("PassportFemale", R.string.PassportFemale) },
                            (dialogInterface, i) -> {
                                if (i == 0) {
                                    currentGender = "male";
                                    inputFields[FIELD_GENDER].setText(
                                            LocaleController.getString("PassportMale", R.string.PassportMale));
                                } else if (i == 1) {
                                    currentGender = "female";
                                    inputFields[FIELD_GENDER].setText(LocaleController
                                            .getString("PassportFemale", R.string.PassportFemale));
                                }
                            });
                    builder.setPositiveButton(LocaleController.getString("Cancel", R.string.Cancel), null);
                    showDialog(builder.create());
                }
                return true;
            });
            inputFields[a].setInputType(0);
            inputFields[a].setFocusable(false);
        } else {
            inputFields[a].setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
            inputFields[a].setImeOptions(EditorInfo.IME_ACTION_NEXT | EditorInfo.IME_FLAG_NO_EXTRACT_UI);
        }
        String value;
        final String key;
        HashMap<String, String> values;
        switch (a) {
        case FIELD_NAME:
            if (currentType.native_names) {
                inputFields[a].setHintText(
                        LocaleController.getString("PassportNameLatin", R.string.PassportNameLatin));
            } else {
                inputFields[a].setHintText(LocaleController.getString("PassportName", R.string.PassportName));
            }
            key = "first_name";
            values = currentValues;
            break;
        case FIELD_MIDNAME:
            if (currentType.native_names) {
                inputFields[a].setHintText(
                        LocaleController.getString("PassportMidnameLatin", R.string.PassportMidnameLatin));
            } else {
                inputFields[a]
                        .setHintText(LocaleController.getString("PassportMidname", R.string.PassportMidname));
            }
            key = "middle_name";
            values = currentValues;
            break;
        case FIELD_SURNAME:
            if (currentType.native_names) {
                inputFields[a].setHintText(
                        LocaleController.getString("PassportSurnameLatin", R.string.PassportSurnameLatin));
            } else {
                inputFields[a]
                        .setHintText(LocaleController.getString("PassportSurname", R.string.PassportSurname));
            }
            key = "last_name";
            values = currentValues;
            break;
        case FIELD_BIRTHDAY:
            inputFields[a]
                    .setHintText(LocaleController.getString("PassportBirthdate", R.string.PassportBirthdate));
            key = "birth_date";
            values = currentValues;
            break;
        case FIELD_GENDER:
            inputFields[a].setHintText(LocaleController.getString("PassportGender", R.string.PassportGender));
            key = "gender";
            values = currentValues;
            break;
        case FIELD_CITIZENSHIP:
            inputFields[a].setHintText(
                    LocaleController.getString("PassportCitizenship", R.string.PassportCitizenship));
            key = "country_code";
            values = currentValues;
            break;
        case FIELD_RESIDENCE:
            inputFields[a]
                    .setHintText(LocaleController.getString("PassportResidence", R.string.PassportResidence));
            key = "residence_country_code";
            values = currentValues;
            break;
        case FIELD_CARDNUMBER:
            inputFields[a].setHintText(
                    LocaleController.getString("PassportDocumentNumber", R.string.PassportDocumentNumber));
            key = "document_no";
            values = currentDocumentValues;
            break;
        case FIELD_EXPIRE:
            inputFields[a].setHintText(LocaleController.getString("PassportExpired", R.string.PassportExpired));
            key = "expiry_date";
            values = currentDocumentValues;
            break;
        default:
            continue;
        }
        setFieldValues(values, inputFields[a], key);
        inputFields[a].setSelection(inputFields[a].length());
        if (a == FIELD_NAME || a == FIELD_SURNAME || a == FIELD_MIDNAME) {
            inputFields[a].addTextChangedListener(new TextWatcher() {

                private boolean ignore;

                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {

                }

                @Override
                public void afterTextChanged(Editable s) {
                    if (ignore) {
                        return;
                    }
                    int num = (Integer) field.getTag();
                    boolean error = false;
                    for (int a = 0; a < s.length(); a++) {
                        char ch = s.charAt(a);
                        if (!(ch >= '0' && ch <= '9' || ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z'
                                || ch == ' ' || ch == '\'' || ch == ',' || ch == '.' || ch == '&' || ch == '-'
                                || ch == '/')) {
                            error = true;
                            break;
                        }
                    }
                    if (error && !allowNonLatinName) {
                        field.setErrorText(LocaleController.getString("PassportUseLatinOnly",
                                R.string.PassportUseLatinOnly));
                    } else {
                        nonLatinNames[num] = error;
                        checkFieldForError(field, key, s, false);
                    }
                }
            });
        } else {
            inputFields[a].addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {

                }

                @Override
                public void afterTextChanged(Editable s) {
                    checkFieldForError(field, key, s, values == currentDocumentValues);
                    int field12 = (Integer) field.getTag();
                    final EditTextBoldCursor editText = inputFields[field12];
                    if (field12 == FIELD_RESIDENCE) {
                        checkNativeFields(true);
                    }
                }
            });
        }

        inputFields[a].setPadding(0, 0, 0, 0);
        inputFields[a]
                .setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
        container.addView(inputFields[a], LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT,
                LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP, 21, 0, 21, 0));

        inputFields[a].setOnEditorActionListener((textView, i, keyEvent) -> {
            if (i == EditorInfo.IME_ACTION_NEXT) {
                int num = (Integer) textView.getTag();
                num++;
                if (num < inputFields.length) {
                    if (inputFields[num].isFocusable()) {
                        inputFields[num].requestFocus();
                    } else {
                        inputFields[num]
                                .dispatchTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, 0, 0, 0));
                        textView.clearFocus();
                        AndroidUtilities.hideKeyboard(textView);
                    }
                }
                return true;
            }
            return false;
        });
    }

    sectionCell2 = new ShadowSectionCell(context);
    linearLayout2.addView(sectionCell2,
            LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));

    headerCell = new HeaderCell(context);
    headerCell.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
    linearLayout2.addView(headerCell,
            LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));

    inputExtraFields = new EditTextBoldCursor[FIELD_NATIVE_COUNT];
    for (int a = 0; a < FIELD_NATIVE_COUNT; a++) {
        final EditTextBoldCursor field = new EditTextBoldCursor(context);
        inputExtraFields[a] = field;

        ViewGroup container = new FrameLayout(context) {

            private StaticLayout errorLayout;
            private float offsetX;

            @Override
            protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
                int width = MeasureSpec.getSize(widthMeasureSpec) - AndroidUtilities.dp(34);
                errorLayout = field.getErrorLayout(width);
                if (errorLayout != null) {
                    int lineCount = errorLayout.getLineCount();
                    if (lineCount > 1) {
                        int height = AndroidUtilities.dp(64)
                                + (errorLayout.getLineBottom(lineCount - 1) - errorLayout.getLineBottom(0));
                        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
                    }
                    if (LocaleController.isRTL) {
                        float maxW = 0;
                        for (int a = 0; a < lineCount; a++) {
                            float l = errorLayout.getLineLeft(a);
                            if (l != 0) {
                                offsetX = 0;
                                break;
                            }
                            maxW = Math.max(maxW, errorLayout.getLineWidth(a));
                            if (a == lineCount - 1) {
                                offsetX = width - maxW;
                            }
                        }
                    }
                }
                super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            }

            @Override
            protected void onDraw(Canvas canvas) {
                if (errorLayout != null) {
                    canvas.save();
                    canvas.translate(AndroidUtilities.dp(21) + offsetX,
                            field.getLineY() + AndroidUtilities.dp(3));
                    errorLayout.draw(canvas);
                    canvas.restore();
                }
            }
        };
        container.setWillNotDraw(false);
        linearLayout2.addView(container, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 64));
        container.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));

        if (a == FIELD_NATIVE_COUNT - 1) {
            extraBackgroundView2 = new View(context);
            extraBackgroundView2.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
            linearLayout2.addView(extraBackgroundView2,
                    LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 6));
        }

        inputExtraFields[a].setTag(a);
        inputExtraFields[a].setSupportRtlHint(true);
        inputExtraFields[a].setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
        inputExtraFields[a].setHintColor(Theme.getColor(Theme.key_windowBackgroundWhiteHintText));
        inputExtraFields[a].setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
        inputExtraFields[a].setHeaderHintColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlueHeader));
        inputExtraFields[a].setTransformHintToHeader(true);
        inputExtraFields[a].setBackgroundDrawable(null);
        inputExtraFields[a].setCursorColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
        inputExtraFields[a].setCursorSize(AndroidUtilities.dp(20));
        inputExtraFields[a].setCursorWidth(1.5f);
        inputExtraFields[a].setLineColors(Theme.getColor(Theme.key_windowBackgroundWhiteInputField),
                Theme.getColor(Theme.key_windowBackgroundWhiteInputFieldActivated),
                Theme.getColor(Theme.key_windowBackgroundWhiteRedText3));
        inputExtraFields[a].setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
        inputExtraFields[a].setImeOptions(EditorInfo.IME_ACTION_NEXT | EditorInfo.IME_FLAG_NO_EXTRACT_UI);

        String value;
        final String key;
        HashMap<String, String> values;
        switch (a) {
        case FIELD_NATIVE_NAME:
            key = "first_name_native";
            values = currentValues;
            break;
        case FIELD_NATIVE_MIDNAME:
            key = "middle_name_native";
            values = currentValues;
            break;
        case FIELD_NATIVE_SURNAME:
            key = "last_name_native";
            values = currentValues;
            break;
        default:
            continue;
        }
        setFieldValues(values, inputExtraFields[a], key);
        inputExtraFields[a].setSelection(inputExtraFields[a].length());
        if (a == FIELD_NATIVE_NAME || a == FIELD_NATIVE_SURNAME || a == FIELD_NATIVE_MIDNAME) {
            inputExtraFields[a].addTextChangedListener(new TextWatcher() {

                private boolean ignore;

                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {

                }

                @Override
                public void afterTextChanged(Editable s) {
                    if (ignore) {
                        return;
                    }
                    checkFieldForError(field, key, s, false);
                }
            });
        }

        inputExtraFields[a].setPadding(0, 0, 0, 0);
        inputExtraFields[a]
                .setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
        container.addView(inputExtraFields[a], LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT,
                LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP, 21, 0, 21, 0));

        inputExtraFields[a].setOnEditorActionListener((textView, i, keyEvent) -> {
            if (i == EditorInfo.IME_ACTION_NEXT) {
                int num = (Integer) textView.getTag();
                num++;
                if (num < inputExtraFields.length) {
                    if (inputExtraFields[num].isFocusable()) {
                        inputExtraFields[num].requestFocus();
                    } else {
                        inputExtraFields[num]
                                .dispatchTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, 0, 0, 0));
                        textView.clearFocus();
                        AndroidUtilities.hideKeyboard(textView);
                    }
                }
                return true;
            }
            return false;
        });
    }

    nativeInfoCell = new TextInfoPrivacyCell(context);
    linearLayout2.addView(nativeInfoCell,
            LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));

    if ((currentBotId != 0 || currentDocumentsType == null) && currentTypeValue != null && !documentOnly
            || currentDocumentsTypeValue != null) {
        if (currentDocumentsTypeValue != null) {
            addDocumentViews(currentDocumentsTypeValue.files);
            if (currentDocumentsTypeValue.front_side instanceof TLRPC.TL_secureFile) {
                addDocumentViewInternal((TLRPC.TL_secureFile) currentDocumentsTypeValue.front_side,
                        UPLOADING_TYPE_FRONT);
            }
            if (currentDocumentsTypeValue.reverse_side instanceof TLRPC.TL_secureFile) {
                addDocumentViewInternal((TLRPC.TL_secureFile) currentDocumentsTypeValue.reverse_side,
                        UPLOADING_TYPE_REVERSE);
            }
            if (currentDocumentsTypeValue.selfie instanceof TLRPC.TL_secureFile) {
                addDocumentViewInternal((TLRPC.TL_secureFile) currentDocumentsTypeValue.selfie,
                        UPLOADING_TYPE_SELFIE);
            }
            addTranslationDocumentViews(currentDocumentsTypeValue.translation);
        }

        TextSettingsCell settingsCell1 = new TextSettingsCell(context);
        settingsCell1.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteRedText3));
        settingsCell1.setBackgroundDrawable(Theme.getSelectorDrawable(true));
        if (currentDocumentsType == null) {
            settingsCell1.setText(LocaleController.getString("PassportDeleteInfo", R.string.PassportDeleteInfo),
                    false);
        } else {
            settingsCell1.setText(
                    LocaleController.getString("PassportDeleteDocument", R.string.PassportDeleteDocument),
                    false);
        }
        linearLayout2.addView(settingsCell1,
                LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
        settingsCell1.setOnClickListener(v -> createDocumentDeleteAlert());

        nativeInfoCell.setBackgroundDrawable(
                Theme.getThemedDrawable(context, R.drawable.greydivider, Theme.key_windowBackgroundGrayShadow));

        sectionCell = new ShadowSectionCell(context);
        sectionCell.setBackgroundDrawable(Theme.getThemedDrawable(context, R.drawable.greydivider_bottom,
                Theme.key_windowBackgroundGrayShadow));
        linearLayout2.addView(sectionCell,
                LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
    } else {
        nativeInfoCell.setBackgroundDrawable(Theme.getThemedDrawable(context, R.drawable.greydivider_bottom,
                Theme.key_windowBackgroundGrayShadow));
    }

    updateInterfaceStringsForDocumentType();
    checkNativeFields(false);
}

From source file:com.sjdf.platform.xss.StringUtils.java

/**
 * <p>/*from   ww w.j a  va  2s. c om*/
 * Find the Levenshtein distance between two Strings if it's less than or
 * equal to a given threshold.
 * </p>
 * <p/>
 * <p>
 * This is the number of changes needed to change one String into another,
 * where each change is a single character modification (deletion, insertion
 * or substitution).
 * </p>
 * <p/>
 * <p>
 * This implementation follows from Algorithms on Strings, Trees and
 * Sequences by Dan Gusfield and Chas Emerick's implementation of the
 * Levenshtein distance algorithm from <a
 * href="http://www.merriampark.com/ld.htm"
 * >http://www.merriampark.com/ld.htm</a>
 * </p>
 * <p/>
 * <pre>
 * StringUtils.getLevenshteinDistance(null, *, *)             = IllegalArgumentException
 * StringUtils.getLevenshteinDistance(*, null, *)             = IllegalArgumentException
 * StringUtils.getLevenshteinDistance(*, *, -1)               = IllegalArgumentException
 * StringUtils.getLevenshteinDistance("","", 0)               = 0
 * StringUtils.getLevenshteinDistance("aaapppp", "", 8)       = 7
 * StringUtils.getLevenshteinDistance("aaapppp", "", 7)       = 7
 * StringUtils.getLevenshteinDistance("aaapppp", "", 6))      = -1
 * StringUtils.getLevenshteinDistance("elephant", "hippo", 7) = 7
 * StringUtils.getLevenshteinDistance("elephant", "hippo", 6) = -1
 * StringUtils.getLevenshteinDistance("hippo", "elephant", 7) = 7
 * StringUtils.getLevenshteinDistance("hippo", "elephant", 6) = -1
 * </pre>
 *
 * @param ss        the first String, must not be null
 * @param tt        the second String, must not be null
 * @param threshold the target threshold, must not be negative
 * @return result distance, or {@code -1} if the distance would be greater
 * than the threshold
 * @throws IllegalArgumentException if either String input {@code null} or negative threshold
 */
public static int getLevenshteinDistance(CharSequence ss, CharSequence tt, int threshold) {
    CharSequence s = ss, t = tt;
    if (s == null || t == null) {
        throw new IllegalArgumentException("Strings must not be null");
    }
    if (threshold < 0) {
        throw new IllegalArgumentException("Threshold must not be negative");
    }

    /**
     * This implementation only computes the distance if it's less than or
     * equal to the threshold value, returning -1 if it's greater. The
     * advantage is performance: unbounded distance is O(nm), but a bound of
     * k allows us to reduce it to O(km) time by only computing a diagonal
     * stripe of width 2k + 1 of the cost table. It is also possible to use
     * this to compute the unbounded Levenshtein distance by starting the
     * threshold at 1 and doubling each time until the distance is found;
     * this is O(dm), where d is the distance.
     *
     * One subtlety comes from needing to ignore entries on the border of
     * our stripe eg. p[] = |#|#|#|* d[] = *|#|#|#| We must ignore the entry
     * to the left of the leftmost member We must ignore the entry above the
     * rightmost member
     *
     * Another subtlety comes from our stripe running off the matrix if the
     * strings aren't of the same size. Since string s is always swapped to
     * be the shorter of the two, the stripe will always run off to the
     * upper right instead of the lower left of the matrix.
     *
     * As a concrete example, suppose s is of length 5, t is of length 7,
     * and our threshold is 1. In this case we're going to walk a stripe of
     * length 3. The matrix would look like so:
     *
     * 1 2 3 4 5 1 |#|#| | | | 2 |#|#|#| | | 3 | |#|#|#| | 4 | | |#|#|#| 5 |
     * | | |#|#| 6 | | | | |#| 7 | | | | | |
     *
     * Note how the stripe leads off the table as there is no possible way
     * to turn a string of length 5 into one of length 7 in edit distance of
     * 1.
     *
     * Additionally, this implementation decreases memory usage by using two
     * single-dimensional arrays and swapping them back and forth instead of
     * allocating an entire n by m matrix. This requires a few minor
     * changes, such as immediately returning when it's detected that the
     * stripe has run off the matrix and initially filling the arrays with
     * large values so that entries we don't compute are ignored.
     *
     * See Algorithms on Strings, Trees and Sequences by Dan Gusfield for
     * some discussion.
     */

    int n = s.length();
    int m = t.length();

    // if one string is empty, the edit distance is necessarily the length
    // of the other
    if (n == 0) {
        return m <= threshold ? m : -1;
    } else if (m == 0) {
        return n <= threshold ? n : -1;
    }

    if (n > m) {
        // swap the two strings to consume less memory
        CharSequence tmp = s;
        s = t;
        t = tmp;
        n = m;
        m = t.length();
    }

    int[] p = new int[n + 1];
    int[] d = new int[n + 1];
    int[] pd;

    // fill in starting table values
    int boundary = Math.min(n, threshold) + 1;
    for (int i = 0; i < boundary; i++) {
        p[i] = i;
    }
    // these fills ensure that the value above the rightmost entry of our
    // stripe will be ignored in following loop iterations
    Arrays.fill(p, boundary, p.length, Integer.MAX_VALUE);
    Arrays.fill(d, Integer.MAX_VALUE);

    // iterates through t
    for (int j = 1; j <= m; j++) {
        char tj = t.charAt(j - 1);
        d[0] = j;

        // compute stripe indices, constrain to array size
        int min = Math.max(1, j - threshold);
        int max = Math.min(n, j + threshold);

        // the stripe may lead off of the table if s and t are of different
        // sizes
        if (min > max) {
            return -1;
        }

        // ignore entry left of leftmost
        if (min > 1) {
            d[min - 1] = Integer.MAX_VALUE;
        }

        // iterates through [min, max] in s
        for (int i = min; i <= max; i++) {
            if (s.charAt(i - 1) == tj) {
                // diagonally left and up
                d[i] = p[i - 1];
            } else {
                // 1 + minimum of cell to the left, to the top, diagonally
                // left and up
                d[i] = 1 + Math.min(Math.min(d[i - 1], p[i]), p[i - 1]);
            }
        }

        // copy current distance counts to 'previous row' distance counts
        pd = p;
        p = d;
        d = pd;
    }

    // if p[n] is greater than the threshold, there's no guarantee on it
    // being the correct
    // distance
    if (p[n] <= threshold) {
        return p[n];
    } else {
        return -1;
    }
}

From source file:com.rdm.common.util.StringUtils.java

/**
 * <p>Find the Levenshtein distance between two Strings if it's less than or equal to a given
 * threshold.</p>//w  ww  .  java 2  s.c  om
 *
 * <p>This is the number of changes needed to change one String into
 * another, where each change is a single character modification (deletion,
 * insertion or substitution).</p>
 *
 * <p>This implementation follows from Algorithms on Strings, Trees and Sequences by Dan Gusfield
 * and Chas Emerick's implementation of the Levenshtein distance algorithm from
 * <a href="http://www.merriampark.com/ld.htm">http://www.merriampark.com/ld.htm</a></p>
 *
 * <pre>
 * StringUtils.getLevenshteinDistance(null, *, *)             = IllegalArgumentException
 * StringUtils.getLevenshteinDistance(*, null, *)             = IllegalArgumentException
 * StringUtils.getLevenshteinDistance(*, *, -1)               = IllegalArgumentException
 * StringUtils.getLevenshteinDistance("","", 0)               = 0
 * StringUtils.getLevenshteinDistance("aaapppp", "", 8)       = 7
 * StringUtils.getLevenshteinDistance("aaapppp", "", 7)       = 7
 * StringUtils.getLevenshteinDistance("aaapppp", "", 6))      = -1
 * StringUtils.getLevenshteinDistance("elephant", "hippo", 7) = 7
 * StringUtils.getLevenshteinDistance("elephant", "hippo", 6) = -1
 * StringUtils.getLevenshteinDistance("hippo", "elephant", 7) = 7
 * StringUtils.getLevenshteinDistance("hippo", "elephant", 6) = -1
 * </pre>
 *
 * @param s  the first String, must not be null
 * @param t  the second String, must not be null
 * @param threshold the target threshold, must not be negative
 * @return result distance, or {@code -1} if the distance would be greater than the threshold
 * @throws IllegalArgumentException if either String input {@code null} or negative threshold
 */
public static int getLevenshteinDistance(CharSequence s, CharSequence t, final int threshold) {
    if (s == null || t == null) {
        throw new IllegalArgumentException("Strings must not be null");
    }
    if (threshold < 0) {
        throw new IllegalArgumentException("Threshold must not be negative");
    }

    /*
    This implementation only computes the distance if it's less than or equal to the
    threshold value, returning -1 if it's greater.  The advantage is performance: unbounded
    distance is O(nm), but a bound of k allows us to reduce it to O(km) time by only
    computing a diagonal stripe of width 2k + 1 of the cost table.
    It is also possible to use this to compute the unbounded Levenshtein distance by starting
    the threshold at 1 and doubling each time until the distance is found; this is O(dm), where
    d is the distance.
            
    One subtlety comes from needing to ignore entries on the border of our stripe
    eg.
    p[] = |#|#|#|*
    d[] =  *|#|#|#|
    We must ignore the entry to the left of the leftmost member
    We must ignore the entry above the rightmost member
            
    Another subtlety comes from our stripe running off the matrix if the strings aren't
    of the same size.  Since string s is always swapped to be the shorter of the two,
    the stripe will always run off to the upper right instead of the lower left of the matrix.
            
    As a concrete example, suppose s is of length 5, t is of length 7, and our threshold is 1.
    In this case we're going to walk a stripe of length 3.  The matrix would look like so:
            
       1 2 3 4 5
    1 |#|#| | | |
    2 |#|#|#| | |
    3 | |#|#|#| |
    4 | | |#|#|#|
    5 | | | |#|#|
    6 | | | | |#|
    7 | | | | | |
            
    Note how the stripe leads off the table as there is no possible way to turn a string of length 5
    into one of length 7 in edit distance of 1.
            
    Additionally, this implementation decreases memory usage by using two
    single-dimensional arrays and swapping them back and forth instead of allocating
    an entire n by m matrix.  This requires a few minor changes, such as immediately returning
    when it's detected that the stripe has run off the matrix and initially filling the arrays with
    large values so that entries we don't compute are ignored.
            
    See Algorithms on Strings, Trees and Sequences by Dan Gusfield for some discussion.
     */

    int n = s.length(); // length of s
    int m = t.length(); // length of t

    // if one string is empty, the edit distance is necessarily the length of the other
    if (n == 0) {
        return m <= threshold ? m : -1;
    } else if (m == 0) {
        return n <= threshold ? n : -1;
    }

    if (n > m) {
        // swap the two strings to consume less memory
        final CharSequence tmp = s;
        s = t;
        t = tmp;
        n = m;
        m = t.length();
    }

    int p[] = new int[n + 1]; // 'previous' cost array, horizontally
    int d[] = new int[n + 1]; // cost array, horizontally
    int _d[]; // placeholder to assist in swapping p and d

    // fill in starting table values
    final int boundary = Math.min(n, threshold) + 1;
    for (int i = 0; i < boundary; i++) {
        p[i] = i;
    }
    // these fills ensure that the value above the rightmost entry of our
    // stripe will be ignored in following loop iterations
    Arrays.fill(p, boundary, p.length, Integer.MAX_VALUE);
    Arrays.fill(d, Integer.MAX_VALUE);

    // iterates through t
    for (int j = 1; j <= m; j++) {
        final char t_j = t.charAt(j - 1); // jth character of t
        d[0] = j;

        // compute stripe indices, constrain to array size
        final int min = Math.max(1, j - threshold);
        final int max = (j > Integer.MAX_VALUE - threshold) ? n : Math.min(n, j + threshold);

        // the stripe may lead off of the table if s and t are of different sizes
        if (min > max) {
            return -1;
        }

        // ignore entry left of leftmost
        if (min > 1) {
            d[min - 1] = Integer.MAX_VALUE;
        }

        // iterates through [min, max] in s
        for (int i = min; i <= max; i++) {
            if (s.charAt(i - 1) == t_j) {
                // diagonally left and up
                d[i] = p[i - 1];
            } else {
                // 1 + minimum of cell to the left, to the top, diagonally left and up
                d[i] = 1 + Math.min(Math.min(d[i - 1], p[i]), p[i - 1]);
            }
        }

        // copy current distance counts to 'previous row' distance counts
        _d = p;
        p = d;
        d = _d;
    }

    // if p[n] is greater than the threshold, there's no guarantee on it being the correct
    // distance
    if (p[n] <= threshold) {
        return p[n];
    }
    return -1;
}

From source file:net.bluehack.ui.ChatActivity.java

private void searchLinks(final CharSequence charSequence, final boolean force) {
    if (currentEncryptedChat != null && (MessagesController.getInstance().secretWebpagePreview == 0
            || AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) < 46)) {
        return;/* w  ww.j  a v  a  2  s.  com*/
    }
    if (force && foundWebPage != null) {
        if (foundWebPage.url != null) {
            int index = TextUtils.indexOf(charSequence, foundWebPage.url);
            char lastChar = 0;
            boolean lenEqual = false;
            if (index == -1) {
                if (foundWebPage.display_url != null) {
                    index = TextUtils.indexOf(charSequence, foundWebPage.display_url);
                    lenEqual = index != -1
                            && index + foundWebPage.display_url.length() == charSequence.length();
                    lastChar = index != -1 && !lenEqual
                            ? charSequence.charAt(index + foundWebPage.display_url.length())
                            : 0;
                }
            } else {
                lenEqual = index + foundWebPage.url.length() == charSequence.length();
                lastChar = !lenEqual ? charSequence.charAt(index + foundWebPage.url.length()) : 0;
            }
            if (index != -1 && (lenEqual || lastChar == ' ' || lastChar == ',' || lastChar == '.'
                    || lastChar == '!' || lastChar == '/')) {
                return;
            }
        }
        pendingLinkSearchString = null;
        showReplyPanel(false, null, null, foundWebPage, false, true);
    }
    Utilities.searchQueue.postRunnable(new Runnable() {
        @Override
        public void run() {
            if (linkSearchRequestId != 0) {
                ConnectionsManager.getInstance().cancelRequest(linkSearchRequestId, true);
                linkSearchRequestId = 0;
            }
            ArrayList<CharSequence> urls = null;
            CharSequence textToCheck;
            try {
                Matcher m = AndroidUtilities.WEB_URL.matcher(charSequence);
                while (m.find()) {
                    if (m.start() > 0) {
                        if (charSequence.charAt(m.start() - 1) == '@') {
                            continue;
                        }
                    }
                    if (urls == null) {
                        urls = new ArrayList<>();
                    }
                    urls.add(charSequence.subSequence(m.start(), m.end()));
                }
                if (urls != null && foundUrls != null && urls.size() == foundUrls.size()) {
                    boolean clear = true;
                    for (int a = 0; a < urls.size(); a++) {
                        if (!TextUtils.equals(urls.get(a), foundUrls.get(a))) {
                            clear = false;
                        }
                    }
                    if (clear) {
                        return;
                    }
                }
                foundUrls = urls;
                if (urls == null) {
                    AndroidUtilities.runOnUIThread(new Runnable() {
                        @Override
                        public void run() {
                            if (foundWebPage != null) {
                                showReplyPanel(false, null, null, foundWebPage, false, true);
                                foundWebPage = null;
                            }
                        }
                    });
                    return;
                }
                textToCheck = TextUtils.join(" ", urls);
            } catch (Exception e) {
                FileLog.e("tmessages", e);
                String text = charSequence.toString().toLowerCase();
                if (charSequence.length() < 13 || !text.contains("http://") && !text.contains("https://")) {
                    AndroidUtilities.runOnUIThread(new Runnable() {
                        @Override
                        public void run() {
                            if (foundWebPage != null) {
                                showReplyPanel(false, null, null, foundWebPage, false, true);
                                foundWebPage = null;
                            }
                        }
                    });
                    return;
                }
                textToCheck = charSequence;
            }

            if (currentEncryptedChat != null && MessagesController.getInstance().secretWebpagePreview == 2) {
                AndroidUtilities.runOnUIThread(new Runnable() {
                    @Override
                    public void run() {
                        AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
                        builder.setTitle(LocaleController.getString("AppName", R.string.AppName));
                        builder.setPositiveButton(LocaleController.getString("OK", R.string.OK),
                                new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        MessagesController.getInstance().secretWebpagePreview = 1;
                                        ApplicationLoader.applicationContext
                                                .getSharedPreferences("mainconfig", Activity.MODE_PRIVATE)
                                                .edit()
                                                .putInt("secretWebpage2",
                                                        MessagesController.getInstance().secretWebpagePreview)
                                                .commit();
                                        foundUrls = null;
                                        searchLinks(charSequence, force);
                                    }
                                });
                        builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
                        builder.setMessage(LocaleController.getString("SecretLinkPreviewAlert",
                                R.string.SecretLinkPreviewAlert));
                        showDialog(builder.create());

                        MessagesController.getInstance().secretWebpagePreview = 0;
                        ApplicationLoader.applicationContext
                                .getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).edit()
                                .putInt("secretWebpage2", MessagesController.getInstance().secretWebpagePreview)
                                .commit();
                    }
                });
                return;
            }

            final TLRPC.TL_messages_getWebPagePreview req = new TLRPC.TL_messages_getWebPagePreview();
            if (textToCheck instanceof String) {
                req.message = (String) textToCheck;
            } else {
                req.message = textToCheck.toString();
            }
            linkSearchRequestId = ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
                @Override
                public void run(final TLObject response, final TLRPC.TL_error error) {
                    AndroidUtilities.runOnUIThread(new Runnable() {
                        @Override
                        public void run() {
                            linkSearchRequestId = 0;
                            if (error == null) {
                                if (response instanceof TLRPC.TL_messageMediaWebPage) {
                                    foundWebPage = ((TLRPC.TL_messageMediaWebPage) response).webpage;
                                    if (foundWebPage instanceof TLRPC.TL_webPage
                                            || foundWebPage instanceof TLRPC.TL_webPagePending) {
                                        if (foundWebPage instanceof TLRPC.TL_webPagePending) {
                                            pendingLinkSearchString = req.message;
                                        }
                                        if (currentEncryptedChat != null
                                                && foundWebPage instanceof TLRPC.TL_webPagePending) {
                                            foundWebPage.url = req.message;
                                        }
                                        showReplyPanel(true, null, null, foundWebPage, false, true);
                                    } else {
                                        if (foundWebPage != null) {
                                            showReplyPanel(false, null, null, foundWebPage, false, true);
                                            foundWebPage = null;
                                        }
                                    }
                                } else {
                                    if (foundWebPage != null) {
                                        showReplyPanel(false, null, null, foundWebPage, false, true);
                                        foundWebPage = null;
                                    }
                                }
                            }
                        }
                    });
                }
            });
            ConnectionsManager.getInstance().bindRequestToGuid(linkSearchRequestId, classGuid);
        }
    });
}

From source file:kr.wdream.ui.ChatActivity.java

private void searchLinks(final CharSequence charSequence, final boolean force) {
    if (currentEncryptedChat != null && (MessagesController.getInstance().secretWebpagePreview == 0
            || AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) < 46)) {
        return;/*ww  w .  ja va  2  s  .  com*/
    }
    if (force && foundWebPage != null) {
        if (foundWebPage.url != null) {
            int index = TextUtils.indexOf(charSequence, foundWebPage.url);
            char lastChar = 0;
            boolean lenEqual = false;
            if (index == -1) {
                if (foundWebPage.display_url != null) {
                    index = TextUtils.indexOf(charSequence, foundWebPage.display_url);
                    lenEqual = index != -1
                            && index + foundWebPage.display_url.length() == charSequence.length();
                    lastChar = index != -1 && !lenEqual
                            ? charSequence.charAt(index + foundWebPage.display_url.length())
                            : 0;
                }
            } else {
                lenEqual = index + foundWebPage.url.length() == charSequence.length();
                lastChar = !lenEqual ? charSequence.charAt(index + foundWebPage.url.length()) : 0;
            }
            if (index != -1 && (lenEqual || lastChar == ' ' || lastChar == ',' || lastChar == '.'
                    || lastChar == '!' || lastChar == '/')) {
                return;
            }
        }
        pendingLinkSearchString = null;
        showReplyPanel(false, null, null, foundWebPage, false, true);
    }
    Utilities.searchQueue.postRunnable(new Runnable() {
        @Override
        public void run() {
            if (linkSearchRequestId != 0) {
                ConnectionsManager.getInstance().cancelRequest(linkSearchRequestId, true);
                linkSearchRequestId = 0;
            }
            ArrayList<CharSequence> urls = null;
            CharSequence textToCheck;
            try {
                Matcher m = AndroidUtilities.WEB_URL.matcher(charSequence);
                while (m.find()) {
                    if (m.start() > 0) {
                        if (charSequence.charAt(m.start() - 1) == '@') {
                            continue;
                        }
                    }
                    if (urls == null) {
                        urls = new ArrayList<>();
                    }
                    urls.add(charSequence.subSequence(m.start(), m.end()));
                }
                if (urls != null && foundUrls != null && urls.size() == foundUrls.size()) {
                    boolean clear = true;
                    for (int a = 0; a < urls.size(); a++) {
                        if (!TextUtils.equals(urls.get(a), foundUrls.get(a))) {
                            clear = false;
                        }
                    }
                    if (clear) {
                        return;
                    }
                }
                foundUrls = urls;
                if (urls == null) {
                    AndroidUtilities.runOnUIThread(new Runnable() {
                        @Override
                        public void run() {
                            if (foundWebPage != null) {
                                showReplyPanel(false, null, null, foundWebPage, false, true);
                                foundWebPage = null;
                            }
                        }
                    });
                    return;
                }
                textToCheck = TextUtils.join(" ", urls);
            } catch (Exception e) {
                FileLog.e("tmessages", e);
                String text = charSequence.toString().toLowerCase();
                if (charSequence.length() < 13 || !text.contains("http://") && !text.contains("https://")) {
                    AndroidUtilities.runOnUIThread(new Runnable() {
                        @Override
                        public void run() {
                            if (foundWebPage != null) {
                                showReplyPanel(false, null, null, foundWebPage, false, true);
                                foundWebPage = null;
                            }
                        }
                    });
                    return;
                }
                textToCheck = charSequence;
            }

            if (currentEncryptedChat != null && MessagesController.getInstance().secretWebpagePreview == 2) {
                AndroidUtilities.runOnUIThread(new Runnable() {
                    @Override
                    public void run() {
                        AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
                        builder.setTitle(
                                LocaleController.getString("AppName", kr.wdream.storyshop.R.string.AppName));
                        builder.setPositiveButton(
                                LocaleController.getString("OK", kr.wdream.storyshop.R.string.OK),
                                new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        MessagesController.getInstance().secretWebpagePreview = 1;
                                        ApplicationLoader.applicationContext
                                                .getSharedPreferences("mainconfig", Activity.MODE_PRIVATE)
                                                .edit()
                                                .putInt("secretWebpage2",
                                                        MessagesController.getInstance().secretWebpagePreview)
                                                .commit();
                                        foundUrls = null;
                                        searchLinks(charSequence, force);
                                    }
                                });
                        builder.setNegativeButton(
                                LocaleController.getString("Cancel", kr.wdream.storyshop.R.string.Cancel),
                                null);
                        builder.setMessage(LocaleController.getString("SecretLinkPreviewAlert",
                                kr.wdream.storyshop.R.string.SecretLinkPreviewAlert));
                        showDialog(builder.create());

                        MessagesController.getInstance().secretWebpagePreview = 0;
                        ApplicationLoader.applicationContext
                                .getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).edit()
                                .putInt("secretWebpage2", MessagesController.getInstance().secretWebpagePreview)
                                .commit();
                    }
                });
                return;
            }

            final TLRPC.TL_messages_getWebPagePreview req = new TLRPC.TL_messages_getWebPagePreview();
            if (textToCheck instanceof String) {
                req.message = (String) textToCheck;
            } else {
                req.message = textToCheck.toString();
            }
            linkSearchRequestId = ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
                @Override
                public void run(final TLObject response, final TLRPC.TL_error error) {
                    AndroidUtilities.runOnUIThread(new Runnable() {
                        @Override
                        public void run() {
                            linkSearchRequestId = 0;
                            if (error == null) {
                                if (response instanceof TLRPC.TL_messageMediaWebPage) {
                                    foundWebPage = ((TLRPC.TL_messageMediaWebPage) response).webpage;
                                    if (foundWebPage instanceof TLRPC.TL_webPage
                                            || foundWebPage instanceof TLRPC.TL_webPagePending) {
                                        if (foundWebPage instanceof TLRPC.TL_webPagePending) {
                                            pendingLinkSearchString = req.message;
                                        }
                                        if (currentEncryptedChat != null
                                                && foundWebPage instanceof TLRPC.TL_webPagePending) {
                                            foundWebPage.url = req.message;
                                        }
                                        showReplyPanel(true, null, null, foundWebPage, false, true);
                                    } else {
                                        if (foundWebPage != null) {
                                            showReplyPanel(false, null, null, foundWebPage, false, true);
                                            foundWebPage = null;
                                        }
                                    }
                                } else {
                                    if (foundWebPage != null) {
                                        showReplyPanel(false, null, null, foundWebPage, false, true);
                                        foundWebPage = null;
                                    }
                                }
                            }
                        }
                    });
                }
            });
            ConnectionsManager.getInstance().bindRequestToGuid(linkSearchRequestId, classGuid);
        }
    });
}

From source file:bfile.util.StringUtils.java

/**
 * <p>Find the Levenshtein distance between two Strings if it's less than or equal to a given
 * threshold.</p>/*w  w  w .  j  a va 2  s  .com*/
 *
 * <p>This is the number of changes needed to change one String into
 * another, where each change is a single character modification (deletion,
 * insertion or substitution).</p>
 *
 * <p>This implementation follows from Algorithms on Strings, Trees and Sequences by Dan Gusfield
 * and Chas Emerick's implementation of the Levenshtein distance algorithm from
 * <a href="http://www.merriampark.com/ld.htm">http://www.merriampark.com/ld.htm</a></p>
 *
 * <pre>
 * StringUtils.getLevenshteinDistance(null, *, *)             = IllegalArgumentException
 * StringUtils.getLevenshteinDistance(*, null, *)             = IllegalArgumentException
 * StringUtils.getLevenshteinDistance(*, *, -1)               = IllegalArgumentException
 * StringUtils.getLevenshteinDistance("","", 0)               = 0
 * StringUtils.getLevenshteinDistance("aaapppp", "", 8)       = 7
 * StringUtils.getLevenshteinDistance("aaapppp", "", 7)       = 7
 * StringUtils.getLevenshteinDistance("aaapppp", "", 6))      = -1
 * StringUtils.getLevenshteinDistance("elephant", "hippo", 7) = 7
 * StringUtils.getLevenshteinDistance("elephant", "hippo", 6) = -1
 * StringUtils.getLevenshteinDistance("hippo", "elephant", 7) = 7
 * StringUtils.getLevenshteinDistance("hippo", "elephant", 6) = -1
 * </pre>
 *
 * @param s  the first String, must not be null
 * @param t  the second String, must not be null
 * @param threshold the target threshold, must not be negative
 * @return result distance, or {@code -1} if the distance would be greater than the threshold
 * @throws IllegalArgumentException if either String input {@code null} or negative threshold
 */
public static int getLevenshteinDistance(CharSequence s, CharSequence t, final int threshold) {
    if (s == null || t == null) {
        throw new IllegalArgumentException("Strings must not be null");
    }
    if (threshold < 0) {
        throw new IllegalArgumentException("Threshold must not be negative");
    }

    /*
    This implementation only computes the distance if it's less than or equal to the
    threshold value, returning -1 if it's greater.  The advantage is performance: unbounded
    distance is O(nm), but a bound of k allows us to reduce it to O(km) time by only
    computing a diagonal stripe of width 2k + 1 of the cost table.
    It is also possible to use this to compute the unbounded Levenshtein distance by starting
    the threshold at 1 and doubling each time until the distance is found; this is O(dm), where
    d is the distance.
    One subtlety comes from needing to ignore entries on the border of our stripe
    eg.
    p[] = |#|#|#|*
    d[] =  *|#|#|#|
    We must ignore the entry to the left of the leftmost member
    We must ignore the entry above the rightmost member
    Another subtlety comes from our stripe running off the matrix if the strings aren't
    of the same size.  Since string s is always swapped to be the shorter of the two,
    the stripe will always run off to the upper right instead of the lower left of the matrix.
    As a concrete example, suppose s is of length 5, t is of length 7, and our threshold is 1.
    In this case we're going to walk a stripe of length 3.  The matrix would look like so:
       1 2 3 4 5
    1 |#|#| | | |
    2 |#|#|#| | |
    3 | |#|#|#| |
    4 | | |#|#|#|
    5 | | | |#|#|
    6 | | | | |#|
    7 | | | | | |
    Note how the stripe leads off the table as there is no possible way to turn a string of length 5
    into one of length 7 in edit distance of 1.
    Additionally, this implementation decreases memory usage by using two
    single-dimensional arrays and swapping them back and forth instead of allocating
    an entire n by m matrix.  This requires a few minor changes, such as immediately returning
    when it's detected that the stripe has run off the matrix and initially filling the arrays with
    large values so that entries we don't compute are ignored.
    See Algorithms on Strings, Trees and Sequences by Dan Gusfield for some discussion.
     */

    int n = s.length(); // length of s
    int m = t.length(); // length of t

    // if one string is empty, the edit distance is necessarily the length of the other
    if (n == 0) {
        return m <= threshold ? m : -1;
    } else if (m == 0) {
        return n <= threshold ? n : -1;
    }
    // no need to calculate the distance if the length difference is greater than the threshold
    else if (Math.abs(n - m) > threshold) {
        return -1;
    }

    if (n > m) {
        // swap the two strings to consume less memory
        final CharSequence tmp = s;
        s = t;
        t = tmp;
        n = m;
        m = t.length();
    }

    int p[] = new int[n + 1]; // 'previous' cost array, horizontally
    int d[] = new int[n + 1]; // cost array, horizontally
    int _d[]; // placeholder to assist in swapping p and d

    // fill in starting table values
    final int boundary = Math.min(n, threshold) + 1;
    for (int i = 0; i < boundary; i++) {
        p[i] = i;
    }
    // these fills ensure that the value above the rightmost entry of our
    // stripe will be ignored in following loop iterations
    Arrays.fill(p, boundary, p.length, Integer.MAX_VALUE);
    Arrays.fill(d, Integer.MAX_VALUE);

    // iterates through t
    for (int j = 1; j <= m; j++) {
        final char t_j = t.charAt(j - 1); // jth character of t
        d[0] = j;

        // compute stripe indices, constrain to array size
        final int min = Math.max(1, j - threshold);
        final int max = j > Integer.MAX_VALUE - threshold ? n : Math.min(n, j + threshold);

        // the stripe may lead off of the table if s and t are of different sizes
        if (min > max) {
            return -1;
        }

        // ignore entry left of leftmost
        if (min > 1) {
            d[min - 1] = Integer.MAX_VALUE;
        }

        // iterates through [min, max] in s
        for (int i = min; i <= max; i++) {
            if (s.charAt(i - 1) == t_j) {
                // diagonally left and up
                d[i] = p[i - 1];
            } else {
                // 1 + minimum of cell to the left, to the top, diagonally left and up
                d[i] = 1 + Math.min(Math.min(d[i - 1], p[i]), p[i - 1]);
            }
        }

        // copy current distance counts to 'previous row' distance counts
        _d = p;
        p = d;
        d = _d;
    }

    // if p[n] is greater than the threshold, there's no guarantee on it being the correct
    // distance
    if (p[n] <= threshold) {
        return p[n];
    }
    return -1;
}

From source file:com.clark.func.Functions.java

/**
 * <p>// ww w  .ja v a  2  s  .  com
 * Checks if the CharSequence contains only ASCII printable characters.
 * </p>
 * 
 * <p>
 * <code>null</code> will return <code>false</code>. An empty CharSequence
 * (length()=0) will return <code>true</code>.
 * </p>
 * 
 * <pre>
 * isAsciiPrintable(null)     = false
 * isAsciiPrintable("")       = true
 * isAsciiPrintable(" ")      = true
 * isAsciiPrintable("Ceki")   = true
 * isAsciiPrintable("ab2c")   = true
 * isAsciiPrintable("!ab-c~") = true
 * isAsciiPrintable("\u0020") = true
 * isAsciiPrintable("\u0021") = true
 * isAsciiPrintable("\u007e") = true
 * isAsciiPrintable("\u007f") = false
 * isAsciiPrintable("Ceki G\u00fclc\u00fc") = false
 * </pre>
 * 
 * @param cs
 *            the CharSequence to check, may be null
 * @return <code>true</code> if every character is in the range 32 thru 126
 * @since 2.1
 * @since 3.0 Changed signature from isAsciiPrintable(String) to
 *        isAsciiPrintable(CharSequence)
 */
public static boolean isAsciiPrintable(CharSequence cs) {
    if (cs == null) {
        return false;
    }
    int sz = cs.length();
    for (int i = 0; i < sz; i++) {
        if (isAsciiPrintable(cs.charAt(i)) == false) {
            return false;
        }
    }
    return true;
}

From source file:com.clark.func.Functions.java

/**
 * <p>/*from   w w w.  ja va 2  s.c  o  m*/
 * Checks if the CharSequence contains only unicode digits. A decimal point
 * is not a unicode digit and returns false.
 * </p>
 * 
 * <p>
 * <code>null</code> will return <code>false</code>. An empty CharSequence
 * (length()=0) will return <code>true</code>.
 * </p>
 * 
 * <pre>
 * isNumeric(null)   = false
 * isNumeric("")     = true
 * isNumeric("  ")   = false
 * isNumeric("123")  = true
 * isNumeric("12 3") = false
 * isNumeric("ab2c") = false
 * isNumeric("12-3") = false
 * isNumeric("12.3") = false
 * </pre>
 * 
 * @param cs
 *            the CharSequence to check, may be null
 * @return <code>true</code> if only contains digits, and is non-null
 * @since 3.0 Changed signature from isNumeric(String) to
 *        isNumeric(CharSequence)
 */
public static boolean isNumeric(CharSequence cs) {
    if (cs == null) {
        return false;
    }
    int sz = cs.length();
    for (int i = 0; i < sz; i++) {
        if (Character.isDigit(cs.charAt(i)) == false) {
            return false;
        }
    }
    return true;
}