1 package org.apache.lucene.util;
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 import org.apache.lucene.analysis.Token;
21 import org.apache.lucene.analysis.tokenattributes.*;
23 import java.util.Iterator;
24 import java.util.HashMap;
27 public class TestAttributeSource extends LuceneTestCase {
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();
38 AttributeSource.State state = src.captureState();
40 // modify the attributes
41 termAtt.setEmpty().append("AnotherTestTerm");
42 typeAtt.setType("AnotherTestType");
43 assertTrue("Hash code should be different", hashCode != src.hashCode());
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());
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);
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);
65 src2.restoreState(state);
66 assertEquals("TestTerm", termAtt.toString());
67 assertEquals("TestType", typeAtt.type());
68 assertEquals("FlagsAttribute should not be touched", 12345, flagsAtt.getFlags());
70 // init a third instance missing one Attribute
71 AttributeSource src3 = new AttributeSource();
72 termAtt = src3.addAttribute(CharTermAttribute.class);
74 src3.restoreState(state);
75 fail("The third instance is missing the TypeAttribute, so restoreState() should throw IllegalArgumentException");
76 } catch (IllegalArgumentException iae) {
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");
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());
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);
102 flagsAtt2.setFlags(4711);
103 typeAtt2.setType("OtherType");
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());
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);
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());
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());
138 termAtt.setEmpty().append("TestTerm");
139 assertEquals("Token should only printed once", "("+tok.toString()+")", src.toString());
142 public void testDefaultAttributeFactory() throws Exception {
143 AttributeSource src = new AttributeSource();
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);
159 @SuppressWarnings("unchecked")
160 public void testInvalidArguments() throws Exception {
162 AttributeSource src = new AttributeSource();
163 src.addAttribute(Token.class);
164 fail("Should throw IllegalArgumentException");
165 } catch (IllegalArgumentException iae) {}
168 AttributeSource src = new AttributeSource(Token.TOKEN_ATTRIBUTE_FACTORY);
169 src.addAttribute(Token.class);
170 fail("Should throw IllegalArgumentException");
171 } catch (IllegalArgumentException iae) {}
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) {}
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());
191 // this class is included in external class check, so no assertion errors occur
193 static class TestAttributeImpl extends AttributeImpl implements FlagsAttribute {
195 private int flags = 0;
197 public int getFlags() { return flags; }
198 public void setFlags(int flags) { this.flags = flags; }
201 public void clear() { flags = 0; }
204 public void copyTo(AttributeImpl target) {
205 FlagsAttribute t = (FlagsAttribute) target;
210 public String toString() {
211 return "foo=bar,moo=mae";
216 // this class is excluded in external class check, so assertion on calling reflectWith should occur
218 static class TestAttributeImpl2 extends TestAttributeImpl {}
221 public void testReflectionOfToString() throws Exception {
222 final AttributeSource src = new AttributeSource();
223 final AttributeImpl att = new TestAttributeImpl();
224 src.addAttributeImpl(att);
226 assertSame("FlagsAttribute is not implemented by same instance of TestAttributeImpl",
227 att, src.addAttribute(FlagsAttribute.class));
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);
236 att.reflectWith(reflector);
237 assertEquals(2, map.size());
238 assertEquals("bar", map.get("foo"));
239 assertEquals("mae", map.get("moo"));
242 src.reflectWith(reflector);
243 assertEquals(2, map.size());
244 assertEquals("bar", map.get("foo"));
245 assertEquals("mae", map.get("moo"));
249 new TestAttributeImpl2().reflectWith(reflector);
250 fail("TestAttributeImpl2 should fail assertion on toString() parsing");
251 } catch (AssertionError e) {