001/** 002 * Logback: the reliable, generic, fast and flexible logging framework. 003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved. 004 * 005 * This program and the accompanying materials are dual-licensed under 006 * either the terms of the Eclipse Public License v1.0 as published by 007 * the Eclipse Foundation 008 * 009 * or (per the licensee's choosing) 010 * 011 * under the terms of the GNU Lesser General Public License version 2.1 012 * as published by the Free Software Foundation. 013 */ 014package ch.qos.logback.core.joran.spi; 015 016import java.util.ArrayList; 017import java.util.List; 018 019public class CaseCombinator { 020 021 List<String> combinations(String in) { 022 int length = in.length(); 023 List<String> permutationsList = new ArrayList<String>(); 024 025 int totalCombinations = computeTotalNumerOfCombinations(in, length); 026 027 for (int j = 0; j < totalCombinations; j++) { 028 StringBuilder newCombination = new StringBuilder(); 029 int pos = 0; 030 for (int i = 0; i < length; i++) { 031 char c = in.charAt(i); 032 if (isEnglishLetter(c)) { 033 c = permute(c, j, pos); 034 pos++; 035 } 036 newCombination.append(c); 037 } 038 permutationsList.add(newCombination.toString()); 039 } 040 return permutationsList; 041 042 } 043 044 private char permute(char c, int permutation, int position) { 045 int mask = 1 << position; 046 boolean shouldBeInUpperCase = (permutation & mask) != 0; 047 boolean isEffectivelyUpperCase = isUpperCase(c); 048 if (shouldBeInUpperCase && !isEffectivelyUpperCase) 049 return toUpperCase(c); 050 if (!shouldBeInUpperCase && isEffectivelyUpperCase) 051 return toLowerCase(c); 052 return c; 053 } 054 055 private int computeTotalNumerOfCombinations(String in, int length) { 056 int count = 0; 057 for (int i = 0; i < length; i++) { 058 char c = in.charAt(i); 059 if (isEnglishLetter(c)) 060 count++; 061 } 062 // return 2^count (2 to the power of count) 063 return (1 << count); 064 } 065 066 private char toUpperCase(char c) { 067 if ('A' <= c && c <= 'Z') { 068 return c; 069 } 070 if ('a' <= c && c <= 'z') { 071 return (char) ((int) c + 'A' - 'a'); 072 } 073 // code should never reach this point 074 return c; 075 } 076 077 private char toLowerCase(char c) { 078 if ('a' <= c && c <= 'z') { 079 return c; 080 } 081 if ('A' <= c && c <= 'Z') { 082 return (char) ((int) c + 'a' - 'A'); 083 } 084 // code should never reach this point 085 return c; 086 } 087 088 private boolean isEnglishLetter(char c) { 089 if ('a' <= c && c <= 'z') 090 return true; 091 092 if ('A' <= c && c <= 'Z') 093 return true; 094 return false; 095 } 096 097 private boolean isUpperCase(char c) { 098 return ('A' <= c && c <= 'Z'); 099 } 100}