2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 package org.apache.lucene.analysis;
20 import java.io.IOException;
21 import java.io.Reader;
22 import java.util.LinkedList;
25 * Simplistic {@link CharFilter} that applies the mappings
26 * contained in a {@link NormalizeCharMap} to the character
27 * stream, and correcting the resulting changes to the
30 public class MappingCharFilter extends BaseCharFilter {
32 private final NormalizeCharMap normMap;
33 private LinkedList<Character> buffer;
34 private String replacement;
35 private int charPointer;
36 private int nextCharCounter;
38 /** Default constructor that takes a {@link CharStream}. */
39 public MappingCharFilter(NormalizeCharMap normMap, CharStream in) {
41 this.normMap = normMap;
44 /** Easy-use constructor that takes a {@link Reader}. */
45 public MappingCharFilter(NormalizeCharMap normMap, Reader in) {
46 super(CharReader.get(in));
47 this.normMap = normMap;
51 public int read() throws IOException {
53 if (replacement != null && charPointer < replacement.length()) {
54 return replacement.charAt(charPointer++);
57 int firstChar = nextChar();
58 if (firstChar == -1) return -1;
59 NormalizeCharMap nm = normMap.submap != null ?
60 normMap.submap.get(Character.valueOf((char) firstChar)) : null;
61 if (nm == null) return firstChar;
62 NormalizeCharMap result = match(nm);
63 if (result == null) return firstChar;
64 replacement = result.normStr;
66 if (result.diff != 0) {
67 int prevCumulativeDiff = getLastCumulativeDiff();
68 if (result.diff < 0) {
69 for(int i = 0; i < -result.diff ; i++)
70 addOffCorrectMap(nextCharCounter + i - prevCumulativeDiff, prevCumulativeDiff - 1 - i);
72 addOffCorrectMap(nextCharCounter - result.diff - prevCumulativeDiff, prevCumulativeDiff + result.diff);
78 private int nextChar() throws IOException {
80 if (buffer != null && !buffer.isEmpty()) {
81 return buffer.removeFirst().charValue();
86 private void pushChar(int c) {
89 buffer = new LinkedList<Character>();
90 buffer.addFirst(Character.valueOf((char) c));
93 private void pushLastChar(int c) {
95 buffer = new LinkedList<Character>();
97 buffer.addLast(Character.valueOf((char) c));
100 private NormalizeCharMap match(NormalizeCharMap map) throws IOException {
101 NormalizeCharMap result = null;
102 if (map.submap != null) {
103 int chr = nextChar();
105 NormalizeCharMap subMap = map.submap.get(Character.valueOf((char) chr));
106 if (subMap != null) {
107 result = match(subMap);
109 if (result == null) {
114 if (result == null && map.normStr != null) {
121 public int read(char[] cbuf, int off, int len) throws IOException {
122 char[] tmp = new char[len];
123 int l = input.read(tmp, 0, len);
125 for(int i = 0; i < l; i++)
126 pushLastChar(tmp[i]);
129 for(int i = off; i < off + len; i++) {
135 return l == 0 ? -1 : l;