1 /* 2 * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 package test.java.text.BreakIterator; 25 26 import java.text.BreakIterator; 27 import java.text.CharacterIterator; 28 import java.util.ArrayList; 29 import java.util.Collections; 30 import java.util.Iterator; 31 import java.util.List; 32 import java.util.NoSuchElementException; 33 34 public class MirroredBreakIterator extends BreakIterator { 35 private final List<Integer> boundaries; 36 private int charIndex; 37 private int boundaryIndex; 38 MirroredBreakIterator(BreakIterator bi)39 MirroredBreakIterator(BreakIterator bi) { 40 List<Integer> b = new ArrayList<Integer>(); 41 int i = bi.first(); 42 charIndex = i; 43 for (; i != DONE; i = bi.next()) { 44 b.add(i); 45 } 46 boundaries = Collections.unmodifiableList(b); 47 } 48 49 @Override clone()50 public Object clone() { 51 try { 52 return super.clone(); 53 } catch (Exception e) { 54 throw new RuntimeException("clone failed", e); 55 } 56 } 57 58 @Override first()59 public int first() { 60 return changeIndices(0); 61 } 62 63 @Override last()64 public int last() { 65 return changeIndices(boundaries.size() - 1); 66 } 67 68 @Override next(int n)69 public int next(int n) { 70 if (n == 0) { 71 return current(); 72 } 73 int newBoundary = boundaryIndex + n; 74 if (newBoundary < 0) { 75 first(); 76 return DONE; 77 } 78 if (newBoundary > lastBoundary()) { 79 last(); 80 return DONE; 81 } 82 return changeIndices(newBoundary); 83 } 84 85 @Override next()86 public int next() { 87 if (boundaryIndex == lastBoundary()) { 88 return DONE; 89 } 90 return changeIndices(boundaryIndex + 1); 91 } 92 93 @Override previous()94 public int previous() { 95 if (boundaryIndex == 0) { 96 return DONE; 97 } 98 return changeIndices(boundaryIndex - 1); 99 } 100 101 @Override following(int offset)102 public int following(int offset) { 103 validateOffset(offset); 104 for (int b = 0; b <= lastBoundary(); b++) { 105 int i = boundaries.get(b); 106 if (i > offset) { 107 return changeIndices(i, b); 108 } 109 } 110 return DONE; 111 } 112 113 @Override preceding(int offset)114 public int preceding(int offset) { 115 validateOffset(offset); 116 for (int b = lastBoundary(); b >= 0; b--) { 117 int i = boundaries.get(b); 118 if (i < offset) { 119 return changeIndices(i, b); 120 } 121 } 122 return DONE; 123 } 124 125 @Override isBoundary(int offset)126 public boolean isBoundary(int offset) { 127 // Call the default impelementation in BreakIterator 128 return super.isBoundary(offset); 129 } 130 131 @Override current()132 public int current() { 133 return charIndex; 134 } 135 136 @Override getText()137 public CharacterIterator getText() { 138 throw new UnsupportedOperationException(); 139 } 140 141 @Override setText(CharacterIterator newText)142 public void setText(CharacterIterator newText) { 143 throw new UnsupportedOperationException(); 144 } 145 lastBoundary()146 private int lastBoundary() { 147 return boundaries.size() - 1; 148 } 149 changeIndices(int newCharIndex, int newBoundary)150 private int changeIndices(int newCharIndex, int newBoundary) { 151 boundaryIndex = newBoundary; 152 return charIndex = newCharIndex; 153 } 154 changeIndices(int newBoundary)155 private int changeIndices(int newBoundary) { 156 try { 157 return changeIndices(boundaries.get(newBoundary), newBoundary); 158 } catch (IndexOutOfBoundsException e) { 159 throw new IllegalArgumentException(e); 160 } 161 } 162 validateOffset(int offset)163 private void validateOffset(int offset) { 164 if (offset < boundaries.get(0) || offset > boundaries.get(lastBoundary())) { 165 throw new IllegalArgumentException(); 166 } 167 } 168 } 169