pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / src / test / org / apache / lucene / util / TestAttributeSource.java
1 package org.apache.lucene.util;
2
3 /**
4  * Licensed to the Apache Software Foundation (ASF) under one or more
5  * contributor license agreements.  See the NOTICE file distributed with
6  * this work for additional information regarding copyright ownership.
7  * The ASF licenses this file to You under the Apache License, Version 2.0
8  * (the "License"); you may not use this file except in compliance with
9  * the License.  You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 import org.apache.lucene.analysis.Token;
21 import org.apache.lucene.analysis.tokenattributes.*;
22
23 import java.util.Iterator;
24 import java.util.HashMap;
25 import java.util.Map;
26
27 public class TestAttributeSource extends LuceneTestCase {
28
29   public void testCaptureState() {
30     // init a first instance
31     AttributeSource src = new AttributeSource();
32     CharTermAttribute termAtt = src.addAttribute(CharTermAttribute.class);
33     TypeAttribute typeAtt = src.addAttribute(TypeAttribute.class);
34     termAtt.append("TestTerm");
35     typeAtt.setType("TestType");
36     final int hashCode = src.hashCode();
37     
38     AttributeSource.State state = src.captureState();
39     
40     // modify the attributes
41     termAtt.setEmpty().append("AnotherTestTerm");
42     typeAtt.setType("AnotherTestType");
43     assertTrue("Hash code should be different", hashCode != src.hashCode());
44     
45     src.restoreState(state);
46     assertEquals("TestTerm", termAtt.toString());
47     assertEquals("TestType", typeAtt.type());
48     assertEquals("Hash code should be equal after restore", hashCode, src.hashCode());
49
50     // restore into an exact configured copy
51     AttributeSource copy = new AttributeSource();
52     copy.addAttribute(CharTermAttribute.class);
53     copy.addAttribute(TypeAttribute.class);
54     copy.restoreState(state);
55     assertEquals("Both AttributeSources should have same hashCode after restore", src.hashCode(), copy.hashCode());
56     assertEquals("Both AttributeSources should be equal after restore", src, copy);
57     
58     // init a second instance (with attributes in different order and one additional attribute)
59     AttributeSource src2 = new AttributeSource();
60     typeAtt = src2.addAttribute(TypeAttribute.class);
61     FlagsAttribute flagsAtt = src2.addAttribute(FlagsAttribute.class);
62     termAtt = src2.addAttribute(CharTermAttribute.class);
63     flagsAtt.setFlags(12345);
64
65     src2.restoreState(state);
66     assertEquals("TestTerm", termAtt.toString());
67     assertEquals("TestType", typeAtt.type());
68     assertEquals("FlagsAttribute should not be touched", 12345, flagsAtt.getFlags());
69
70     // init a third instance missing one Attribute
71     AttributeSource src3 = new AttributeSource();
72     termAtt = src3.addAttribute(CharTermAttribute.class);
73     try {
74       src3.restoreState(state);
75       fail("The third instance is missing the TypeAttribute, so restoreState() should throw IllegalArgumentException");
76     } catch (IllegalArgumentException iae) {
77       // pass
78     }
79   }
80   
81   public void testCloneAttributes() {
82     final AttributeSource src = new AttributeSource();
83     final FlagsAttribute flagsAtt = src.addAttribute(FlagsAttribute.class);
84     final TypeAttribute typeAtt = src.addAttribute(TypeAttribute.class);
85     flagsAtt.setFlags(1234);
86     typeAtt.setType("TestType");
87     
88     final AttributeSource clone = src.cloneAttributes();
89     final Iterator<Class<? extends Attribute>> it = clone.getAttributeClassesIterator();
90     assertEquals("FlagsAttribute must be the first attribute", FlagsAttribute.class, it.next());
91     assertEquals("TypeAttribute must be the second attribute", TypeAttribute.class, it.next());
92     assertFalse("No more attributes", it.hasNext());
93     
94     final FlagsAttribute flagsAtt2 = clone.getAttribute(FlagsAttribute.class);
95     final TypeAttribute typeAtt2 = clone.getAttribute(TypeAttribute.class);
96     assertNotSame("FlagsAttribute of original and clone must be different instances", flagsAtt2, flagsAtt);
97     assertNotSame("TypeAttribute of original and clone must be different instances", typeAtt2, typeAtt);
98     assertEquals("FlagsAttribute of original and clone must be equal", flagsAtt2, flagsAtt);
99     assertEquals("TypeAttribute of original and clone must be equal", typeAtt2, typeAtt);
100     
101     // test copy back
102     flagsAtt2.setFlags(4711);
103     typeAtt2.setType("OtherType");
104     clone.copyTo(src);
105     assertEquals("FlagsAttribute of original must now contain updated term", 4711, flagsAtt.getFlags());
106     assertEquals("TypeAttribute of original must now contain updated type", "OtherType", typeAtt.type());
107     // verify again:
108     assertNotSame("FlagsAttribute of original and clone must be different instances", flagsAtt2, flagsAtt);
109     assertNotSame("TypeAttribute of original and clone must be different instances", typeAtt2, typeAtt);
110     assertEquals("FlagsAttribute of original and clone must be equal", flagsAtt2, flagsAtt);
111     assertEquals("TypeAttribute of original and clone must be equal", typeAtt2, typeAtt);
112   }
113   
114   public void testToStringAndMultiAttributeImplementations() {
115     AttributeSource src = new AttributeSource();
116     CharTermAttribute termAtt = src.addAttribute(CharTermAttribute.class);
117     TypeAttribute typeAtt = src.addAttribute(TypeAttribute.class);
118     termAtt.append("TestTerm");
119     typeAtt.setType("TestType");    
120     assertEquals("Attributes should appear in original order", "("+termAtt.toString()+","+typeAtt.toString()+")", src.toString());
121     Iterator<AttributeImpl> it = src.getAttributeImplsIterator();
122     assertTrue("Iterator should have 2 attributes left", it.hasNext());
123     assertSame("First AttributeImpl from iterator should be termAtt", termAtt, it.next());
124     assertTrue("Iterator should have 1 attributes left", it.hasNext());
125     assertSame("Second AttributeImpl from iterator should be typeAtt", typeAtt, it.next());
126     assertFalse("Iterator should have 0 attributes left", it.hasNext());
127
128     src = new AttributeSource();
129     src.addAttributeImpl(new Token());
130     // this should not add a new attribute as Token implements CharTermAttribute, too
131     termAtt = src.addAttribute(CharTermAttribute.class);
132     assertTrue("CharTermAttribute should be implemented by Token", termAtt instanceof Token);
133     // get the Token attribute and check, that it is the only one
134     it = src.getAttributeImplsIterator();
135     Token tok = (Token) it.next();
136     assertFalse("There should be only one attribute implementation instance", it.hasNext());
137     
138     termAtt.setEmpty().append("TestTerm");
139     assertEquals("Token should only printed once", "("+tok.toString()+")", src.toString());
140   }
141   
142   public void testDefaultAttributeFactory() throws Exception {
143     AttributeSource src = new AttributeSource();
144     
145     assertTrue("CharTermAttribute is not implemented by CharTermAttributeImpl",
146       src.addAttribute(CharTermAttribute.class) instanceof CharTermAttributeImpl);
147     assertTrue("OffsetAttribute is not implemented by OffsetAttributeImpl",
148       src.addAttribute(OffsetAttribute.class) instanceof OffsetAttributeImpl);
149     assertTrue("FlagsAttribute is not implemented by FlagsAttributeImpl",
150       src.addAttribute(FlagsAttribute.class) instanceof FlagsAttributeImpl);
151     assertTrue("PayloadAttribute is not implemented by PayloadAttributeImpl",
152       src.addAttribute(PayloadAttribute.class) instanceof PayloadAttributeImpl);
153     assertTrue("PositionIncrementAttribute is not implemented by PositionIncrementAttributeImpl", 
154       src.addAttribute(PositionIncrementAttribute.class) instanceof PositionIncrementAttributeImpl);
155     assertTrue("TypeAttribute is not implemented by TypeAttributeImpl",
156       src.addAttribute(TypeAttribute.class) instanceof TypeAttributeImpl);
157   }
158   
159   @SuppressWarnings("unchecked")
160   public void testInvalidArguments() throws Exception {
161     try {
162       AttributeSource src = new AttributeSource();
163       src.addAttribute(Token.class);
164       fail("Should throw IllegalArgumentException");
165     } catch (IllegalArgumentException iae) {}
166     
167     try {
168       AttributeSource src = new AttributeSource(Token.TOKEN_ATTRIBUTE_FACTORY);
169       src.addAttribute(Token.class);
170       fail("Should throw IllegalArgumentException");
171     } catch (IllegalArgumentException iae) {}
172     
173     try {
174       AttributeSource src = new AttributeSource();
175       // break this by unsafe cast
176       src.addAttribute((Class) Iterator.class);
177       fail("Should throw IllegalArgumentException");
178     } catch (IllegalArgumentException iae) {}
179   }
180   
181   public void testLUCENE_3042() throws Exception {
182     final AttributeSource src1 = new AttributeSource();
183     src1.addAttribute(CharTermAttribute.class).append("foo");
184     int hash1 = src1.hashCode(); // this triggers a cached state
185     final AttributeSource src2 = new AttributeSource(src1);
186     src2.addAttribute(TypeAttribute.class).setType("bar");
187     assertTrue("The hashCode is identical, so the captured state was preserved.", hash1 != src1.hashCode());
188     assertEquals(src2.hashCode(), src1.hashCode());
189   }
190   
191   // this class is included in external class check, so no assertion errors occur
192   @Deprecated
193   static class TestAttributeImpl extends AttributeImpl implements FlagsAttribute {
194   
195     private int flags = 0;
196     
197     public int getFlags() { return flags; }
198     public void setFlags(int flags) { this.flags = flags; }
199     
200     @Override
201     public void clear() { flags = 0; }
202     
203     @Override
204     public void copyTo(AttributeImpl target) {
205       FlagsAttribute t = (FlagsAttribute) target;
206       t.setFlags(flags);
207     }
208     
209     @Override
210     public String toString() {
211       return "foo=bar,moo=mae";
212     }
213   
214   }
215   
216   // this class is excluded in external class check, so assertion on calling reflectWith should occur
217   @Deprecated
218   static class TestAttributeImpl2 extends TestAttributeImpl {}
219   
220   @Deprecated
221   public void testReflectionOfToString() throws Exception {
222     final AttributeSource src = new AttributeSource();
223     final AttributeImpl att = new TestAttributeImpl();
224     src.addAttributeImpl(att);
225     
226     assertSame("FlagsAttribute is not implemented by same instance of TestAttributeImpl",
227       att, src.addAttribute(FlagsAttribute.class));
228     
229     final Map<String,Object> map = new HashMap<String,Object>();
230     final AttributeReflector reflector = new AttributeReflector() {
231       public void reflect(Class<? extends Attribute> attClass, String key, Object value) {
232         assertSame(FlagsAttribute.class, attClass);
233         map.put(key, value);
234       }
235     };
236     att.reflectWith(reflector);
237     assertEquals(2, map.size());
238     assertEquals("bar", map.get("foo"));
239     assertEquals("mae", map.get("moo"));
240     
241     map.clear();
242     src.reflectWith(reflector);
243     assertEquals(2, map.size());
244     assertEquals("bar", map.get("foo"));
245     assertEquals("mae", map.get("moo"));
246     
247     map.clear();
248     try {
249       new TestAttributeImpl2().reflectWith(reflector);
250       fail("TestAttributeImpl2 should fail assertion on toString() parsing");
251     } catch (AssertionError e) {
252       // pass
253     }
254   }
255   
256 }