View Javadoc
1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
4    *
5    * This program and the accompanying materials are dual-licensed under
6    * either the terms of the Eclipse Public License v1.0 as published by
7    * the Eclipse Foundation
8    *
9    *   or (per the licensee's choosing)
10   *
11   * under the terms of the GNU Lesser General Public License version 2.1
12   * as published by the Free Software Foundation.
13   */
14  package ch.qos.logback.core.joran.spi;
15  
16  import java.util.ArrayList;
17  import java.util.List;
18  
19  public class CaseCombinator {
20  
21      List<String> combinations(String in) {
22          int length = in.length();
23          List<String> permutationsList = new ArrayList<String>();
24  
25          int totalCombinations = computeTotalNumerOfCombinations(in, length);
26  
27          for (int j = 0; j < totalCombinations; j++) {
28              StringBuilder newCombination = new StringBuilder();
29              int pos = 0;
30              for (int i = 0; i < length; i++) {
31                  char c = in.charAt(i);
32                  if (isEnglishLetter(c)) {
33                      c = permute(c, j, pos);
34                      pos++;
35                  }
36                  newCombination.append(c);
37              }
38              permutationsList.add(newCombination.toString());
39          }
40          return permutationsList;
41  
42      }
43  
44      private char permute(char c, int permutation, int position) {
45          int mask = 1 << position;
46          boolean shouldBeInUpperCase = (permutation & mask) != 0;
47          boolean isEffectivelyUpperCase = isUpperCase(c);
48          if (shouldBeInUpperCase && !isEffectivelyUpperCase)
49              return toUpperCase(c);
50          if (!shouldBeInUpperCase && isEffectivelyUpperCase)
51              return toLowerCase(c);
52          return c;
53      }
54  
55      private int computeTotalNumerOfCombinations(String in, int length) {
56          int count = 0;
57          for (int i = 0; i < length; i++) {
58              char c = in.charAt(i);
59              if (isEnglishLetter(c))
60                  count++;
61          }
62          // return 2^count (2 to the power of count)
63          return (1 << count);
64      }
65  
66      private char toUpperCase(char c) {
67          if ('A' <= c && c <= 'Z') {
68              return c;
69          }
70          if ('a' <= c && c <= 'z') {
71              return (char) ((int) c + 'A' - 'a');
72          }
73          // code should never reach this point
74          return c;
75      }
76  
77      private char toLowerCase(char c) {
78          if ('a' <= c && c <= 'z') {
79              return c;
80          }
81          if ('A' <= c && c <= 'Z') {
82              return (char) ((int) c + 'a' - 'A');
83          }
84          // code should never reach this point
85          return c;
86      }
87  
88      private boolean isEnglishLetter(char c) {
89          if ('a' <= c && c <= 'z')
90              return true;
91  
92          if ('A' <= c && c <= 'Z')
93              return true;
94          return false;
95      }
96  
97      private boolean isUpperCase(char c) {
98          return ('A' <= c && c <= 'Z');
99      }
100 }