1461
|
1 package goodjava.lucene.logging;
|
|
2
|
|
3 import java.io.File;
|
|
4 import java.io.RandomAccessFile;
|
|
5 import java.io.IOException;
|
|
6 import java.util.List;
|
|
7 import java.util.ArrayList;
|
|
8 import java.util.Map;
|
|
9 import java.util.LinkedHashMap;
|
|
10 import org.apache.lucene.index.Term;
|
|
11 import org.apache.lucene.search.Query;
|
|
12 import org.apache.lucene.search.MatchAllDocsQuery;
|
|
13 import org.apache.lucene.search.TermQuery;
|
|
14 import org.apache.lucene.search.PrefixQuery;
|
|
15 import org.apache.lucene.search.WildcardQuery;
|
|
16 import org.apache.lucene.search.TermRangeQuery;
|
|
17 import org.apache.lucene.search.PhraseQuery;
|
|
18 import org.apache.lucene.search.NumericRangeQuery;
|
|
19 import org.apache.lucene.search.BooleanQuery;
|
|
20 import org.apache.lucene.search.BooleanClause;
|
|
21 import org.apache.lucene.util.BytesRef;
|
|
22
|
|
23
|
|
24 public final class LogFile extends RandomAccessFile {
|
|
25 private long end;
|
|
26
|
|
27 public LogFile(File file,String mode) throws IOException {
|
|
28 super(file,mode);
|
|
29 init();
|
|
30 }
|
|
31
|
|
32 public LogFile(String file,String mode) throws IOException {
|
|
33 super(file,mode);
|
|
34 init();
|
|
35 }
|
|
36
|
|
37 private void init() throws IOException {
|
|
38 if( length() == 0 ) {
|
|
39 end = 8;
|
|
40 writeLong(end);
|
|
41 } else {
|
|
42 seek(0L);
|
|
43 end = readLong();
|
|
44 gotoEnd();
|
|
45 }
|
|
46 }
|
|
47
|
|
48 public void gotoStart() throws IOException {
|
|
49 seek(8L);
|
|
50 }
|
|
51
|
|
52 public void gotoEnd() throws IOException {
|
|
53 seek(end);
|
|
54 }
|
|
55
|
|
56 public void commit() throws IOException {
|
|
57 end = getFilePointer();
|
|
58 seek(0L);
|
|
59 writeLong(end);
|
|
60 gotoEnd();
|
|
61 }
|
|
62
|
|
63 public boolean hasMore() throws IOException {
|
|
64 return getFilePointer() < end;
|
|
65 }
|
|
66
|
|
67 private static final int TYPE_NULL = 0;
|
|
68 private static final int TYPE_STRING = 1;
|
|
69 private static final int TYPE_INT = 2;
|
|
70 private static final int TYPE_LONG = 3;
|
|
71 private static final int TYPE_FLOAT = 4;
|
|
72 private static final int TYPE_DOUBLE = 5;
|
|
73 private static final int TYPE_BYTES = 6;
|
|
74 private static final int TYPE_LIST = 7;
|
|
75 private static final int TYPE_QUERY_MATCH_ALL_DOCS = 8;
|
|
76 private static final int TYPE_QUERY_TERM = 9;
|
|
77 private static final int TYPE_QUERY_PREFIX = 10;
|
|
78 private static final int TYPE_QUERY_WILDCARD = 11;
|
|
79 private static final int TYPE_QUERY_TERM_RANGE = 12;
|
|
80 private static final int TYPE_QUERY_PHRASE = 13;
|
|
81 private static final int TYPE_QUERY_NUMERIC_RANGE = 14;
|
|
82 private static final int TYPE_QUERY_BOOLEAN = 15;
|
|
83
|
|
84 public void writeObject(Object obj) throws IOException {
|
|
85 if( obj==null ) {
|
|
86 writeByte(TYPE_NULL);
|
|
87 return;
|
|
88 }
|
|
89 if( obj instanceof String ) {
|
|
90 writeByte(TYPE_STRING);
|
|
91 writeUTF((String)obj);
|
|
92 return;
|
|
93 }
|
|
94 if( obj instanceof Integer ) {
|
|
95 writeByte(TYPE_INT);
|
|
96 writeInt((Integer)obj);
|
|
97 return;
|
|
98 }
|
|
99 if( obj instanceof Long ) {
|
|
100 writeByte(TYPE_LONG);
|
|
101 writeLong((Long)obj);
|
|
102 return;
|
|
103 }
|
|
104 if( obj instanceof Float ) {
|
|
105 writeByte(TYPE_FLOAT);
|
|
106 writeFloat((Float)obj);
|
|
107 return;
|
|
108 }
|
|
109 if( obj instanceof Double ) {
|
|
110 writeByte(TYPE_DOUBLE);
|
|
111 writeDouble((Double)obj);
|
|
112 return;
|
|
113 }
|
|
114 if( obj instanceof byte[] ) {
|
|
115 writeByte(TYPE_BYTES);
|
|
116 writeByteArray((byte[])obj);
|
|
117 return;
|
|
118 }
|
|
119 if( obj instanceof List ) {
|
|
120 writeByte(TYPE_LIST);
|
|
121 writeList((List)obj);
|
|
122 return;
|
|
123 }
|
|
124 if( obj instanceof MatchAllDocsQuery ) {
|
|
125 writeByte(TYPE_QUERY_MATCH_ALL_DOCS);
|
|
126 return;
|
|
127 }
|
|
128 if( obj instanceof TermQuery ) {
|
|
129 writeByte(TYPE_QUERY_TERM);
|
|
130 TermQuery query = (TermQuery)obj;
|
|
131 writeTerm( query.getTerm() );
|
|
132 return;
|
|
133 }
|
|
134 if( obj instanceof PrefixQuery ) {
|
|
135 writeByte(TYPE_QUERY_PREFIX);
|
|
136 PrefixQuery query = (PrefixQuery)obj;
|
|
137 writeTerm( query.getPrefix() );
|
|
138 return;
|
|
139 }
|
|
140 if( obj instanceof WildcardQuery ) {
|
|
141 writeByte(TYPE_QUERY_TERM_RANGE);
|
|
142 WildcardQuery query = (WildcardQuery)obj;
|
|
143 writeTerm( query.getTerm() );
|
|
144 return;
|
|
145 }
|
|
146 if( obj instanceof TermRangeQuery ) {
|
|
147 writeByte(TYPE_QUERY_TERM_RANGE);
|
|
148 TermRangeQuery query = (TermRangeQuery)obj;
|
|
149 writeUTF( query.getField() );
|
|
150 writeBytesRef( query.getLowerTerm() );
|
|
151 writeBytesRef( query.getUpperTerm() );
|
|
152 writeBoolean( query.includesLower() );
|
|
153 writeBoolean( query.includesUpper() );
|
|
154 return;
|
|
155 }
|
|
156 if( obj instanceof PhraseQuery ) {
|
|
157 writeByte(TYPE_QUERY_PHRASE);
|
|
158 PhraseQuery query = (PhraseQuery)obj;
|
|
159 Term[] terms = query.getTerms();
|
|
160 int[] positions = query.getPositions();
|
|
161 if( terms.length != positions.length )
|
|
162 throw new RuntimeException();
|
|
163 writeInt( terms.length );
|
|
164 for( int i=0; i<terms.length; i++ ) {
|
|
165 writeTerm( terms[i] );
|
|
166 writeInt( positions[i] );
|
|
167 }
|
|
168 return;
|
|
169 }
|
|
170 if( obj instanceof NumericRangeQuery ) {
|
|
171 writeByte(TYPE_QUERY_NUMERIC_RANGE);
|
|
172 NumericRangeQuery query = (NumericRangeQuery)obj;
|
|
173 writeUTF( query.getField() );
|
|
174 writeObject( query.getMin() );
|
|
175 writeObject( query.getMax() );
|
|
176 writeBoolean( query.includesMin() );
|
|
177 writeBoolean( query.includesMax() );
|
|
178 return;
|
|
179 }
|
|
180 if( obj instanceof BooleanQuery ) {
|
|
181 writeByte(TYPE_QUERY_BOOLEAN);
|
|
182 BooleanQuery query = (BooleanQuery)obj;
|
|
183 BooleanClause[] a = query.getClauses();
|
|
184 writeInt(a.length);
|
|
185 for( BooleanClause bc : a ) {
|
|
186 writeQuery( bc.getQuery() );
|
|
187 writeUTF( bc.getOccur().name() );
|
|
188 }
|
|
189 return;
|
|
190 }
|
|
191 throw new IllegalArgumentException("invalid type for "+obj);
|
|
192 }
|
|
193
|
|
194 public Object readObject() throws IOException {
|
|
195 int type = readByte();
|
|
196 switch(type) {
|
|
197 case TYPE_NULL:
|
|
198 return null;
|
|
199 case TYPE_STRING:
|
|
200 return readUTF();
|
|
201 case TYPE_INT:
|
|
202 return readInt();
|
|
203 case TYPE_LONG:
|
|
204 return readLong();
|
|
205 case TYPE_FLOAT:
|
|
206 return readFloat();
|
|
207 case TYPE_DOUBLE:
|
|
208 return readDouble();
|
|
209 case TYPE_BYTES:
|
|
210 return readByteArray();
|
|
211 case TYPE_LIST:
|
|
212 return readList();
|
|
213 case TYPE_QUERY_MATCH_ALL_DOCS:
|
|
214 return new MatchAllDocsQuery();
|
|
215 case TYPE_QUERY_TERM:
|
|
216 return new TermQuery( readTerm() );
|
|
217 case TYPE_QUERY_PREFIX:
|
|
218 return new PrefixQuery( readTerm() );
|
|
219 case TYPE_QUERY_WILDCARD:
|
|
220 return new WildcardQuery( readTerm() );
|
|
221 case TYPE_QUERY_TERM_RANGE:
|
|
222 {
|
|
223 String field = readUTF();
|
|
224 BytesRef lowerTerm = readBytesRef();
|
|
225 BytesRef upperTerm = readBytesRef();
|
|
226 boolean includeLower = readBoolean();
|
|
227 boolean includeUpper = readBoolean();
|
|
228 return new TermRangeQuery(field,lowerTerm,upperTerm,includeLower,includeUpper);
|
|
229 }
|
|
230 case TYPE_QUERY_PHRASE:
|
|
231 {
|
|
232 PhraseQuery query = new PhraseQuery();
|
|
233 int n = readInt();
|
|
234 for( int i=0; i<n; i++ ) {
|
|
235 Term term = readTerm();
|
|
236 int position = readInt();
|
|
237 query.add(term,position);
|
|
238 }
|
|
239 return query;
|
|
240 }
|
|
241 case TYPE_QUERY_NUMERIC_RANGE:
|
|
242 {
|
|
243 String field = readUTF();
|
|
244 Number min = (Number)readObject();
|
|
245 Number max = (Number)readObject();
|
|
246 boolean minInclusive = readBoolean();
|
|
247 boolean maxInclusive = readBoolean();
|
|
248 Number n = min!=null ? min : max;
|
|
249 if( n instanceof Integer )
|
|
250 return NumericRangeQuery.newIntRange(field,(Integer)min,(Integer)max,minInclusive,maxInclusive);
|
|
251 if( n instanceof Long )
|
|
252 return NumericRangeQuery.newLongRange(field,(Long)min,(Long)max,minInclusive,maxInclusive);
|
|
253 if( n instanceof Float )
|
|
254 return NumericRangeQuery.newFloatRange(field,(Float)min,(Float)max,minInclusive,maxInclusive);
|
|
255 if( n instanceof Double )
|
|
256 return NumericRangeQuery.newDoubleRange(field,(Double)min,(Double)max,minInclusive,maxInclusive);
|
|
257 throw new RuntimeException("bad numeric type for "+n);
|
|
258 }
|
|
259 case TYPE_QUERY_BOOLEAN:
|
|
260 {
|
|
261 BooleanQuery query = new BooleanQuery();
|
|
262 int n = readInt();
|
|
263 for( int i=0; i<n; i++ ) {
|
|
264 Query subquery = readQuery();
|
|
265 BooleanClause.Occur occur = BooleanClause.Occur.valueOf( readUTF() );
|
|
266 query.add(subquery,occur);
|
|
267 }
|
|
268 return query;
|
|
269 }
|
|
270 default:
|
|
271 throw new RuntimeException("invalid type "+type);
|
|
272 }
|
|
273 }
|
|
274
|
|
275 public void writeByteArray(byte[] bytes) throws IOException {
|
|
276 writeInt(bytes.length);
|
|
277 write(bytes);
|
|
278 }
|
|
279
|
|
280 public byte[] readByteArray() throws IOException {
|
|
281 int len = readInt();
|
|
282 byte[] bytes = new byte[len];
|
|
283 readFully(bytes);
|
|
284 return bytes;
|
|
285 }
|
|
286
|
|
287 public void writeList(List list) throws IOException {
|
|
288 writeInt(list.size());
|
|
289 for( Object obj : list ) {
|
|
290 writeObject(obj);
|
|
291 }
|
|
292 }
|
|
293
|
|
294 public List readList() throws IOException {
|
|
295 final int size = readInt();
|
|
296 List list = new ArrayList(size);
|
|
297 for( int i=0; i<size; i++ ) {
|
|
298 list.add( readObject() );
|
|
299 }
|
|
300 return list;
|
|
301 }
|
|
302
|
|
303 public void writeMap(Map map) throws IOException {
|
|
304 writeInt(map.size());
|
|
305 for( Object obj : map.entrySet() ) {
|
|
306 Map.Entry entry = (Map.Entry)obj;
|
|
307 writeObject( entry.getKey() );
|
|
308 writeObject( entry.getValue() );
|
|
309 }
|
|
310 }
|
|
311
|
|
312 public Map readMap() throws IOException {
|
|
313 final int size = readInt();
|
|
314 Map map = new LinkedHashMap();
|
|
315 for( int i=0; i<size; i++ ) {
|
|
316 Object key = readObject();
|
|
317 Object value = readObject();
|
|
318 map.put(key,value);
|
|
319 }
|
|
320 return map;
|
|
321 }
|
|
322
|
|
323 public void writeQuery(Query query) throws IOException {
|
|
324 writeObject(query);
|
|
325 }
|
|
326
|
|
327 public Query readQuery() throws IOException {
|
|
328 return (Query)readObject();
|
|
329 }
|
|
330
|
|
331 public void writeBytesRef(BytesRef br) throws IOException {
|
|
332 writeInt(br.length);
|
|
333 write(br.bytes,0,br.length);
|
|
334 }
|
|
335
|
|
336 public BytesRef readBytesRef() throws IOException {
|
|
337 return new BytesRef( readByteArray() );
|
|
338 }
|
|
339
|
|
340 public void writeTerm(Term term) throws IOException {
|
|
341 writeUTF(term.field());
|
|
342 writeBytesRef( term.bytes() );
|
|
343 }
|
|
344
|
|
345 public Term readTerm() throws IOException {
|
|
346 String key = readUTF();
|
|
347 BytesRef value = readBytesRef();
|
|
348 return new Term(key,value);
|
|
349 }
|
|
350
|
|
351 }
|