add --shared
[pylucene.git] / lucene-java-3.4.0 / lucene / contrib / analyzers / common / src / java / org / apache / lucene / analysis / path / PathHierarchyTokenizer.java
1 package org.apache.lucene.analysis.path;
2 /**
3  * Licensed to the Apache Software Foundation (ASF) under one or more
4  * contributor license agreements.  See the NOTICE file distributed with
5  * this work for additional information regarding copyright ownership.
6  * The ASF licenses this file to You under the Apache License, Version 2.0
7  * (the "License"); you may not use this file except in compliance with
8  * the License.  You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 import java.io.IOException;
20 import java.io.Reader;
21
22 import org.apache.lucene.analysis.Tokenizer;
23 import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
24 import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
25 import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
26
27 /**
28  *
29  * Take something like:
30  *
31  * <pre>
32  *  /something/something/else
33  * </pre>
34  *
35  * and make:
36  *
37  * <pre>
38  *  /something
39  *  /something/something
40  *  /something/something/else
41  * </pre>
42  */
43 public class PathHierarchyTokenizer extends Tokenizer {
44
45   public PathHierarchyTokenizer(Reader input) {
46     this(input, DEFAULT_BUFFER_SIZE, DEFAULT_DELIMITER, DEFAULT_DELIMITER, DEFAULT_SKIP);
47   }
48
49   public PathHierarchyTokenizer(Reader input, int skip) {
50     this(input, DEFAULT_BUFFER_SIZE, DEFAULT_DELIMITER, DEFAULT_DELIMITER, skip);
51   }
52
53   public PathHierarchyTokenizer(Reader input, int bufferSize, char delimiter) {
54     this(input, bufferSize, delimiter, delimiter, DEFAULT_SKIP);
55   }
56
57   public PathHierarchyTokenizer(Reader input, char delimiter, char replacement) {
58     this(input, DEFAULT_BUFFER_SIZE, delimiter, replacement, DEFAULT_SKIP);
59   }
60
61   public PathHierarchyTokenizer(Reader input, char delimiter, char replacement, int skip) {
62     this(input, DEFAULT_BUFFER_SIZE, delimiter, replacement, skip);
63   }
64
65   public PathHierarchyTokenizer(Reader input, int bufferSize, char delimiter, char replacement, int skip) {
66     super(input);
67     termAtt.resizeBuffer(bufferSize);
68
69     this.delimiter = delimiter;
70     this.replacement = replacement;
71     this.skip = skip;
72     resultToken = new StringBuilder(bufferSize);
73   }
74
75   private static final int DEFAULT_BUFFER_SIZE = 1024;
76   public static final char DEFAULT_DELIMITER = '/';
77   public static final int DEFAULT_SKIP = 0;
78
79   private final char delimiter;
80   private final char replacement;
81   private final int skip;
82
83   private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
84   private final OffsetAttribute offsetAtt = addAttribute(OffsetAttribute.class);
85   private final PositionIncrementAttribute posAtt = addAttribute(PositionIncrementAttribute.class);
86   private int startPosition = 0;
87   private int finalOffset = 0;
88   private int skipped = 0;
89   private boolean endDelimiter = false;
90   private StringBuilder resultToken;
91
92
93   @Override
94   public final boolean incrementToken() throws IOException {
95     clearAttributes();
96     termAtt.append( resultToken );
97     if(resultToken.length() == 0){
98       posAtt.setPositionIncrement(1);
99     }
100     else{
101       posAtt.setPositionIncrement(0);
102     }
103     int length = 0;
104     boolean added = false;
105     if( endDelimiter ){
106       termAtt.append(replacement);
107       length++;
108       endDelimiter = false;
109       added = true;
110     }
111
112     while (true) {
113       int c = input.read();
114       if( c < 0 ){
115         if( skipped > skip ) {
116           length += resultToken.length();
117           termAtt.setLength(length);
118           finalOffset = correctOffset(startPosition + length);
119           offsetAtt.setOffset(correctOffset(startPosition), finalOffset);
120           if( added ){
121             resultToken.setLength(0);
122             resultToken.append(termAtt.buffer(), 0, length);
123           }
124           return added;
125         }
126         else{
127           finalOffset = correctOffset(startPosition + length);
128           return false;
129         }
130       }
131       if( !added ){
132         added = true;
133         skipped++;
134         if( skipped > skip ){
135           termAtt.append(c == delimiter ? replacement : (char)c);
136           length++;
137         }
138         else {
139           startPosition++;
140         }
141       }
142       else {
143         if( c == delimiter ){
144           if( skipped > skip ){
145             endDelimiter = true;
146             break;
147           }
148           skipped++;
149           if( skipped > skip ){
150             termAtt.append(replacement);
151             length++;
152           }
153           else {
154             startPosition++;
155           }
156         }
157         else {
158           if( skipped > skip ){
159             termAtt.append((char)c);
160             length++;
161           }
162           else {
163             startPosition++;
164           }
165         }
166       }
167     }
168     length += resultToken.length();
169     termAtt.setLength(length);
170     finalOffset = correctOffset(startPosition + length);
171     offsetAtt.setOffset(correctOffset(startPosition), finalOffset);
172     resultToken.setLength(0);
173     resultToken.append(termAtt.buffer(), 0, length);
174     return true;
175   }
176
177   @Override
178   public final void end() {
179     // set final offset
180     offsetAtt.setOffset(finalOffset, finalOffset);
181   }
182
183   @Override
184   public void reset(Reader input) throws IOException {
185     super.reset(input);
186     resultToken.setLength(0);
187     finalOffset = 0;
188     endDelimiter = false;
189     skipped = 0;
190   }
191 }