SymbolGenerationUtils.java
1 /* 2 * Copyright (C) 2022 github.com/REAndroid 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 // Copied and modified from AOSP 18 package com.reandroid.common; 19 20 import com.reandroid.utils.collection.CollectionUtil; 21 22 import java.util.Set; 23 24 public class SymbolGenerationUtils { 25 26 public static String generateLowercase(int index) { 27 return generate(index, false); 28 } 29 public static String generateMixedCase(int index) { 30 return generate(index, true); 31 } 32 public static String generate(int index, boolean mixedCase) { 33 int size = 1; 34 int number = index + 1; 35 int maximumNumberOfCharacters = mixedCase ? TOTAL_CHARACTERS : LOWERCASE_AND_SUFFIX; 36 int firstNumberOfCharacters = maximumNumberOfCharacters - SUFFIX_LENGTH; 37 38 int availableCharacters; 39 for(availableCharacters = firstNumberOfCharacters; number > availableCharacters; ++size) { 40 number = (number - 1) / availableCharacters; 41 availableCharacters = maximumNumberOfCharacters; 42 } 43 44 char[] characters = new char[size]; 45 number = index + 1; 46 int i = 0; 47 availableCharacters = firstNumberOfCharacters; 48 49 int firstLetterPadding; 50 for(firstLetterPadding = SUFFIX_LENGTH; number > availableCharacters; firstLetterPadding = 0) { 51 characters[i++] = CHARACTERS[(number - 1) % availableCharacters + firstLetterPadding]; 52 number = (number - 1) / availableCharacters; 53 availableCharacters = maximumNumberOfCharacters; 54 } 55 56 characters[i] = CHARACTERS[number - 1 + firstLetterPadding]; 57 58 String symbol = new String(characters); 59 if(isReserved(symbol)) { 60 return generate(index + 1, mixedCase); 61 } 62 return symbol; 63 } 64 private static boolean isReserved(String symbol) { 65 return symbol.length() > 1 && RESERVED_NAMES.contains(symbol); 66 } 67 68 static { 69 70 char[] charArray = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 71 .toCharArray(); 72 73 CHARACTERS = charArray; 74 int length = charArray.length; 75 TOTAL_CHARACTERS = length; 76 LOWERCASE_AND_SUFFIX = length - 26; 77 SUFFIX_LENGTH = 10; 78 79 RESERVED_NAMES = CollectionUtil.newHashSet( 80 "boolean", "byte", "char", 81 "double", "float", "int", 82 "long", "short", "void", "it", 83 "by", "class"); 84 } 85 86 private static final char[] CHARACTERS; 87 private static final int TOTAL_CHARACTERS; 88 private static final int LOWERCASE_AND_SUFFIX; 89 private static final int SUFFIX_LENGTH; 90 91 private static final Set<String> RESERVED_NAMES; 92 }