|
| 1 | +/* |
| 2 | + * © 2021. TU Dortmund University, |
| 3 | + * Institute of Energy Systems, Energy Efficiency and Energy Economics, |
| 4 | + * Research group Distribution grid planning and operation |
| 5 | +*/ |
| 6 | +package edu.ie3.util.naming; |
| 7 | + |
| 8 | +import edu.ie3.util.StringUtils; |
| 9 | +import java.util.Arrays; |
| 10 | +import java.util.LinkedList; |
| 11 | +import java.util.Objects; |
| 12 | +import java.util.stream.Collectors; |
| 13 | + |
| 14 | +public class Naming { |
| 15 | + private static final String DELIMITER_REGEX = "[_\\-|]"; |
| 16 | + |
| 17 | + /** |
| 18 | + * Builds a naming from a collection of single words. We assume, that all words are yet |
| 19 | + * de-composed. This means, they only comply with {@link NamingConvention#FLAT}. Components, that |
| 20 | + * contain one of the known delimiters (_, -, |) are neglected. |
| 21 | + * |
| 22 | + * @param singleWords The single words, which shall compose the naming later |
| 23 | + * @return Proper naming object |
| 24 | + */ |
| 25 | + public static Naming from(String... singleWords) { |
| 26 | + /* Go through all single words, make them lower case and filter out those, that contain one of known delimiters */ |
| 27 | + LinkedList<String> components = |
| 28 | + Arrays.stream(singleWords) |
| 29 | + .map(String::toLowerCase) |
| 30 | + .filter(entry -> !entry.matches(".*" + DELIMITER_REGEX + ".*")) |
| 31 | + .collect(Collectors.toCollection(LinkedList::new)); |
| 32 | + |
| 33 | + String flatCase = String.join("", components); |
| 34 | + String upperFlatCase = |
| 35 | + components.stream().map(String::toUpperCase).collect(Collectors.joining("")); |
| 36 | + String camelCase = String.join("", camelCasing(components)); |
| 37 | + String pascalCase = |
| 38 | + components.stream().map(StringUtils::capitalize).collect(Collectors.joining("")); |
| 39 | + String snakeCase = String.join("_", components); |
| 40 | + String screamingSnakeCase = |
| 41 | + components.stream().map(String::toUpperCase).collect(Collectors.joining("_")); |
| 42 | + String camelSnakeCase = String.join("_", camelCasing(components)); |
| 43 | + String pascalSnakeCase = |
| 44 | + components.stream().map(StringUtils::capitalize).collect(Collectors.joining("_")); |
| 45 | + String kebabCase = String.join("-", components); |
| 46 | + String donerCase = String.join("|", components); |
| 47 | + String screamingKebabCase = |
| 48 | + components.stream().map(String::toUpperCase).collect(Collectors.joining("-")); |
| 49 | + String trainCase = |
| 50 | + components.stream().map(StringUtils::capitalize).collect(Collectors.joining("-")); |
| 51 | + |
| 52 | + return new Naming( |
| 53 | + flatCase, |
| 54 | + upperFlatCase, |
| 55 | + camelCase, |
| 56 | + pascalCase, |
| 57 | + snakeCase, |
| 58 | + screamingSnakeCase, |
| 59 | + camelSnakeCase, |
| 60 | + pascalSnakeCase, |
| 61 | + kebabCase, |
| 62 | + donerCase, |
| 63 | + screamingKebabCase, |
| 64 | + trainCase); |
| 65 | + } |
| 66 | + |
| 67 | + /** |
| 68 | + * Adjust the case of the first letter of each component to comply with the rules of camel casing: |
| 69 | + * |
| 70 | + * <ul> |
| 71 | + * <li>The first letter is always small case |
| 72 | + * <li>A letter, that follows a digit is always small case |
| 73 | + * <li>A letter, that follows a single letter component is always small case |
| 74 | + * <li>All other first letters are upper case |
| 75 | + * </ul> |
| 76 | + * |
| 77 | + * @param components The small case components |
| 78 | + * @return A {@link LinkedList} with properly capitalized components |
| 79 | + */ |
| 80 | + private static LinkedList<String> camelCasing(LinkedList<String> components) { |
| 81 | + LinkedList<String> output = new LinkedList<>(); |
| 82 | + |
| 83 | + /* The first letter is always not capitalized */ |
| 84 | + boolean blockCapitalization = true; |
| 85 | + for (String component : components) { |
| 86 | + output.add(blockCapitalization ? component : StringUtils.capitalize(component)); |
| 87 | + /* The next component is not capitalized, if the last one ends with a digit or is only one character */ |
| 88 | + blockCapitalization = component.matches("\\d$") || component.length() == 1; |
| 89 | + } |
| 90 | + return output; |
| 91 | + } |
| 92 | + |
| 93 | + private final String flatCase; |
| 94 | + private final String upperFlatCase; |
| 95 | + private final String camelCase; |
| 96 | + private final String pascalCase; |
| 97 | + private final String snakeCase; |
| 98 | + private final String screamingSnakeCase; |
| 99 | + private final String camelSnakeCase; |
| 100 | + private final String pascalSnakeCase; |
| 101 | + private final String kebabCase; |
| 102 | + private final String donerCase; |
| 103 | + private final String screamingKebabCase; |
| 104 | + private final String trainCase; |
| 105 | + |
| 106 | + private Naming( |
| 107 | + String flatCase, |
| 108 | + String upperFlatCase, |
| 109 | + String camelCase, |
| 110 | + String pascalCase, |
| 111 | + String snakeCase, |
| 112 | + String screamingSnakeCase, |
| 113 | + String camelSnakeCase, |
| 114 | + String pascalSnakeCase, |
| 115 | + String kebabCase, |
| 116 | + String donerCase, |
| 117 | + String screamingKebabCase, |
| 118 | + String trainCase) { |
| 119 | + this.flatCase = flatCase; |
| 120 | + this.upperFlatCase = upperFlatCase; |
| 121 | + this.camelCase = camelCase; |
| 122 | + this.pascalCase = pascalCase; |
| 123 | + this.snakeCase = snakeCase; |
| 124 | + this.screamingSnakeCase = screamingSnakeCase; |
| 125 | + this.camelSnakeCase = camelSnakeCase; |
| 126 | + this.pascalSnakeCase = pascalSnakeCase; |
| 127 | + this.kebabCase = kebabCase; |
| 128 | + this.donerCase = donerCase; |
| 129 | + this.screamingKebabCase = screamingKebabCase; |
| 130 | + this.trainCase = trainCase; |
| 131 | + } |
| 132 | + |
| 133 | + public String flatCase() { |
| 134 | + return flatCase; |
| 135 | + } |
| 136 | + |
| 137 | + public String upperFlatCase() { |
| 138 | + return upperFlatCase; |
| 139 | + } |
| 140 | + |
| 141 | + public String camelCase() { |
| 142 | + return camelCase; |
| 143 | + } |
| 144 | + |
| 145 | + public String pascalCase() { |
| 146 | + return pascalCase; |
| 147 | + } |
| 148 | + |
| 149 | + public String snakeCase() { |
| 150 | + return snakeCase; |
| 151 | + } |
| 152 | + |
| 153 | + public String screamingSnakeCase() { |
| 154 | + return screamingSnakeCase; |
| 155 | + } |
| 156 | + |
| 157 | + public String camelSnakeCase() { |
| 158 | + return camelSnakeCase; |
| 159 | + } |
| 160 | + |
| 161 | + public String pascalSnakeCase() { |
| 162 | + return pascalSnakeCase; |
| 163 | + } |
| 164 | + |
| 165 | + public String kebabCase() { |
| 166 | + return kebabCase; |
| 167 | + } |
| 168 | + |
| 169 | + public String donerCase() { |
| 170 | + return donerCase; |
| 171 | + } |
| 172 | + |
| 173 | + public String screamingKebabCase() { |
| 174 | + return screamingKebabCase; |
| 175 | + } |
| 176 | + |
| 177 | + public String trainCase() { |
| 178 | + return trainCase; |
| 179 | + } |
| 180 | + |
| 181 | + /** |
| 182 | + * Get the naming as the given convention. |
| 183 | + * |
| 184 | + * @param convention The desired convention |
| 185 | + * @return The naming |
| 186 | + */ |
| 187 | + public String as(NamingConvention convention) { |
| 188 | + switch (convention) { |
| 189 | + case FLAT: |
| 190 | + return flatCase(); |
| 191 | + case CAMEL: |
| 192 | + return camelCase(); |
| 193 | + case DONER: |
| 194 | + return donerCase(); |
| 195 | + case KEBAB: |
| 196 | + return kebabCase(); |
| 197 | + case SNAKE: |
| 198 | + return snakeCase(); |
| 199 | + case TRAIN: |
| 200 | + return trainCase(); |
| 201 | + case PASCAL: |
| 202 | + return pascalCase(); |
| 203 | + case UPPER_FLAT: |
| 204 | + return upperFlatCase(); |
| 205 | + case CAMEL_SNAKE: |
| 206 | + return camelSnakeCase(); |
| 207 | + case PASCAL_SNAKE: |
| 208 | + return pascalSnakeCase(); |
| 209 | + case SCREAMING_KEBAB: |
| 210 | + return screamingKebabCase(); |
| 211 | + case SCREAMING_SNAKE: |
| 212 | + return screamingSnakeCase(); |
| 213 | + default: |
| 214 | + throw new IllegalArgumentException( |
| 215 | + "The naming convention '" |
| 216 | + + convention |
| 217 | + + "', you requested, is currently not supported."); |
| 218 | + } |
| 219 | + } |
| 220 | + |
| 221 | + @Override |
| 222 | + public boolean equals(Object o) { |
| 223 | + if (this == o) return true; |
| 224 | + if (!(o instanceof Naming)) return false; |
| 225 | + Naming naming = (Naming) o; |
| 226 | + return flatCase.equals(naming.flatCase) |
| 227 | + && upperFlatCase.equals(naming.upperFlatCase) |
| 228 | + && camelCase.equals(naming.camelCase) |
| 229 | + && pascalCase.equals(naming.pascalCase) |
| 230 | + && snakeCase.equals(naming.snakeCase) |
| 231 | + && screamingSnakeCase.equals(naming.screamingSnakeCase) |
| 232 | + && camelSnakeCase.equals(naming.camelSnakeCase) |
| 233 | + && pascalSnakeCase.equals(naming.pascalSnakeCase) |
| 234 | + && kebabCase.equals(naming.kebabCase) |
| 235 | + && donerCase.equals(naming.donerCase) |
| 236 | + && screamingKebabCase.equals(naming.screamingKebabCase) |
| 237 | + && trainCase.equals(naming.trainCase); |
| 238 | + } |
| 239 | + |
| 240 | + @Override |
| 241 | + public int hashCode() { |
| 242 | + return Objects.hash( |
| 243 | + flatCase, |
| 244 | + upperFlatCase, |
| 245 | + camelCase, |
| 246 | + pascalCase, |
| 247 | + snakeCase, |
| 248 | + screamingSnakeCase, |
| 249 | + camelSnakeCase, |
| 250 | + pascalSnakeCase, |
| 251 | + kebabCase, |
| 252 | + donerCase, |
| 253 | + screamingKebabCase, |
| 254 | + trainCase); |
| 255 | + } |
| 256 | + |
| 257 | + @Override |
| 258 | + public String toString() { |
| 259 | + return "Naming{" + "camelCase='" + camelCase + '\'' + '}'; |
| 260 | + } |
| 261 | +} |
0 commit comments