1 package org.unicode.cldr.draft.keyboard; 2 3 import static com.google.common.base.Preconditions.checkNotNull; 4 5 import java.util.Iterator; 6 import java.util.Set; 7 8 import com.google.common.base.Joiner; 9 import com.google.common.base.Objects; 10 import com.google.common.collect.ImmutableSet; 11 import com.google.common.collect.ImmutableSortedSet; 12 13 /** 14 * This class wraps a set of modifier key combinations. This class also includes the necessary 15 * functions to simplify and output these combinations according to the LDML Keyboard Standard. 16 * 17 * <p> 18 * A modifier key combination set is active if any single contained modifier key combination is 19 * active. That is, there is a disjunctive relationship between the combinations. 20 * 21 * <p> 22 * Combination1 OR Combination2 OR Combination3 ... 23 */ 24 public final class ModifierKeyCombinationSet implements Comparable<ModifierKeyCombinationSet> { 25 private final ImmutableSortedSet<ModifierKeyCombination> combinations; 26 27 private ModifierKeyCombinationSet(ImmutableSortedSet<ModifierKeyCombination> combinations) { 28 this.combinations = checkNotNull(combinations); 29 } 30 31 /** 32 * Creates a modifier key combination set from a set of combinations. Simplifies the set to its 33 * simplest form. 34 */ 35 public static ModifierKeyCombinationSet of(Set<ModifierKeyCombination> combinations) { 36 ImmutableSet<ModifierKeyCombination> simplifiedSet = ModifierKeySimplifier 37 .simplifySet(combinations); 38 return new ModifierKeyCombinationSet(ImmutableSortedSet.copyOf(simplifiedSet)); 39 } 40 41 /** 42 * Merge multiple modifier key combinations into a single one. This method is useful when 43 * consolidating identical key maps together. 44 */ 45 public static ModifierKeyCombinationSet combine(Iterable<ModifierKeyCombinationSet> sets) { 46 ImmutableSet.Builder<ModifierKeyCombination> builder = ImmutableSet.builder(); 47 for (ModifierKeyCombinationSet combinationSet : sets) { 48 builder.addAll(combinationSet.combinations); 49 } 50 return ModifierKeyCombinationSet.of(builder.build()); 51 } 52 53 public ImmutableSortedSet<ModifierKeyCombination> combinations() { 54 return combinations; 55 } 56 57 /** 58 * Determines if this modifier key combination set is a base set. That is, is it active when no 59 * modifiers are pressed? 60 */ 61 public boolean isBase() { 62 for (ModifierKeyCombination combination : combinations) { 63 if (combination.isBase()) { 64 return true; 65 } 66 } 67 return false; 68 } 69 70 private static final Joiner SPACE_JOINER = Joiner.on(" "); 71 72 @Override 73 public String toString() { 74 return SPACE_JOINER.join(combinations); 75 } 76 77 @Override 78 public int compareTo(ModifierKeyCombinationSet o) { 79 Iterator<ModifierKeyCombination> iterator1 = combinations.iterator(); 80 Iterator<ModifierKeyCombination> iterator2 = o.combinations.iterator(); 81 // Compare combinations until a difference is found. 82 while (iterator1.hasNext() && iterator2.hasNext()) { 83 ModifierKeyCombination combination1 = iterator1.next(); 84 ModifierKeyCombination combination2 = iterator2.next(); 85 if (combination1.compareTo(combination2) < 0) { 86 return -1; 87 } else if (combination1.compareTo(combination2) > 0) { 88 return 1; 89 } 90 } 91 // Otherwise compare them based on size. 92 return combinations.size() - o.combinations.size(); 93 } 94 95 @Override 96 public boolean equals(Object o) { 97 if (this == o) { 98 return true; 99 } 100 if (o instanceof ModifierKeyCombinationSet) { 101 ModifierKeyCombinationSet other = (ModifierKeyCombinationSet) o; 102 return combinations.equals(other.combinations); 103 } 104 return false; 105 } 106 107 @Override 108 public int hashCode() { 109 return Objects.hashCode(combinations); 110 } 111 } 112