Index: common-build.xml =================================================================== --- common-build.xml (revision 809286) +++ common-build.xml (working copy) @@ -58,10 +58,10 @@ - - + + - + @@ -549,6 +549,7 @@ + Index: src/java/org/apache/lucene/util/AttributeImpl.java =================================================================== --- src/java/org/apache/lucene/util/AttributeImpl.java (revision 809286) +++ src/java/org/apache/lucene/util/AttributeImpl.java (working copy) @@ -49,7 +49,7 @@ * This method may be overridden by subclasses. */ public String toString() { - StringBuffer buffer = new StringBuffer(); + StringBuilder buffer = new StringBuilder(); Class clazz = this.getClass(); Field[] fields = clazz.getDeclaredFields(); try { Index: src/java/org/apache/lucene/util/AttributeSource.java =================================================================== --- src/java/org/apache/lucene/util/AttributeSource.java (revision 809286) +++ src/java/org/apache/lucene/util/AttributeSource.java (working copy) @@ -44,9 +44,8 @@ public static abstract class AttributeFactory { /** * returns an {@link AttributeImpl} for the supplied {@link Attribute} interface class. - *

Signature for Java 1.5: public AttributeImpl createAttributeInstance(Class%lt;? extends Attribute> attClass) */ - public abstract AttributeImpl createAttributeInstance(Class attClass); + public abstract AttributeImpl createAttributeInstance(Class attClass); /** * This is the default factory that creates {@link AttributeImpl}s using the @@ -55,13 +54,14 @@ public static final AttributeFactory DEFAULT_ATTRIBUTE_FACTORY = new DefaultAttributeFactory(); private static final class DefaultAttributeFactory extends AttributeFactory { - private static final IdentityHashMap/*,Class>*/ attClassImplMap = new IdentityHashMap(); + private static final IdentityHashMap, Class> attClassImplMap = + new IdentityHashMap, Class>(); private DefaultAttributeFactory() {} - public AttributeImpl createAttributeInstance(Class attClass) { + public AttributeImpl createAttributeInstance(Class attClass) { try { - return (AttributeImpl) getClassForInterface(attClass).newInstance(); + return getClassForInterface(attClass).newInstance(); } catch (InstantiationException e) { throw new IllegalArgumentException("Could not instantiate class " + attClass); } catch (IllegalAccessException e) { @@ -69,12 +69,12 @@ } } - private static Class getClassForInterface(Class attClass) { + private static Class getClassForInterface(Class attClass) { synchronized(attClassImplMap) { - Class clazz = (Class) attClassImplMap.get(attClass); + Class clazz = attClassImplMap.get(attClass); if (clazz == null) { try { - attClassImplMap.put(attClass, clazz = Class.forName(attClass.getName() + "Impl")); + attClassImplMap.put(attClass, clazz = Class.forName(attClass.getName() + "Impl").asSubclass(AttributeImpl.class)); } catch (ClassNotFoundException e) { throw new IllegalArgumentException("Could not find implementing class for " + attClass.getName()); } @@ -87,8 +87,8 @@ // These two maps must always be in sync!!! // So they are private, final and read-only from the outside (read-only iterators) - private final Map/*,AttributeImpl>*/ attributes; - private final Map/*,AttributeImpl>*/ attributeImpls; + private final Map, AttributeImpl> attributes; + private final Map, AttributeImpl> attributeImpls; private AttributeFactory factory; @@ -115,8 +115,8 @@ * An AttributeSource using the supplied {@link AttributeFactory} for creating new {@link Attribute} instances. */ public AttributeSource(AttributeFactory factory) { - this.attributes = new LinkedHashMap(); - this.attributeImpls = new LinkedHashMap(); + this.attributes = new LinkedHashMap, AttributeImpl>(); + this.attributeImpls = new LinkedHashMap, AttributeImpl>(); this.factory = factory; } @@ -129,31 +129,29 @@ /** Returns a new iterator that iterates the attribute classes * in the same order they were added in. - *

Signature for Java 1.5: public Iterator<Class<? extends Attribute>> getAttributeClassesIterator() */ - public Iterator getAttributeClassesIterator() { + public Iterator> getAttributeClassesIterator() { return Collections.unmodifiableSet(attributes.keySet()).iterator(); } /** Returns a new iterator that iterates all unique Attribute implementations. * This iterator may contain less entries that {@link #getAttributeClassesIterator}, * if one instance implements more than one Attribute interface. - *

Signature for Java 1.5: public Iterator<AttributeImpl> getAttributeImplsIterator() */ - public Iterator getAttributeImplsIterator() { + public Iterator getAttributeImplsIterator() { if (hasAttributes()) { if (currentState == null) { computeCurrentState(); } final State initState = currentState; - return new Iterator() { + return new Iterator() { private State state = initState; public void remove() { throw new UnsupportedOperationException(); } - public Object next() { + public AttributeImpl next() { if (state == null) throw new NoSuchElementException(); final AttributeImpl att = state.attribute; @@ -166,31 +164,30 @@ } }; } else { - return Collections.EMPTY_SET.iterator(); + return Collections.emptySet().iterator(); } } /** a cache that stores all interfaces for known implementation classes for performance (slow reflection) */ - private static final IdentityHashMap/*,LinkedList>>*/ knownImplClasses = new IdentityHashMap(); + private static final IdentityHashMap,LinkedList>> knownImplClasses = + new IdentityHashMap,LinkedList>>(); /** Adds a custom AttributeImpl instance with one or more Attribute interfaces. */ public void addAttributeImpl(final AttributeImpl att) { - final Class clazz = att.getClass(); + final Class clazz = att.getClass(); if (attributeImpls.containsKey(clazz)) return; - LinkedList foundInterfaces; + LinkedList> foundInterfaces; synchronized(knownImplClasses) { - foundInterfaces = (LinkedList) knownImplClasses.get(clazz); + foundInterfaces = knownImplClasses.get(clazz); if (foundInterfaces == null) { - knownImplClasses.put(clazz, foundInterfaces=new LinkedList()); + knownImplClasses.put(clazz, foundInterfaces = new LinkedList>()); // find all interfaces that this attribute instance implements // and that extend the Attribute interface - Class actClazz = clazz; + Class actClazz = clazz; do { - Class[] interfaces = actClazz.getInterfaces(); - for (int i = 0; i < interfaces.length; i++) { - final Class curInterface = interfaces[i]; + for (Class curInterface : actClazz.getInterfaces()) { if (curInterface != Attribute.class && Attribute.class.isAssignableFrom(curInterface)) { - foundInterfaces.add(curInterface); + foundInterfaces.add(curInterface.asSubclass(Attribute.class)); } } actClazz = actClazz.getSuperclass(); @@ -199,8 +196,7 @@ } // add all interfaces of this AttributeImpl to the maps - for (Iterator it = foundInterfaces.iterator(); it.hasNext(); ) { - final Class curInterface = (Class) it.next(); + for (Class curInterface : foundInterfaces) { // Attribute is a superclass of this interface if (!attributes.containsKey(curInterface)) { // invalidate state to force recomputation in captureState() @@ -216,17 +212,15 @@ * This method first checks if an instance of that class is * already in this AttributeSource and returns it. Otherwise a * new instance is created, added to this AttributeSource and returned. - *

Signature for Java 1.5: public <T extends Attribute> T addAttribute(Class<T>) */ - public Attribute addAttribute(Class attClass) { - final Attribute att = (Attribute) attributes.get(attClass); - if (att == null) { - final AttributeImpl attImpl = this.factory.createAttributeInstance(attClass); - addAttributeImpl(attImpl); - return attImpl; - } else { - return att; + public A addAttribute(Class attClass) { + AttributeImpl attImpl = attributes.get(attClass); + if (attImpl == null) { + addAttributeImpl(attImpl = this.factory.createAttributeInstance(attClass)); } + // the following cast is unchecked, because compiler does not know if attImpl really implements A + @SuppressWarnings("unchecked") final A att = (A) attImpl; + return att; } /** Returns true, iff this AttributeSource has any attributes */ @@ -237,16 +231,14 @@ /** * The caller must pass in a Class<? extends Attribute> value. * Returns true, iff this AttributeSource contains the passed-in Attribute. - *

Signature for Java 1.5: public boolean hasAttribute(Class<? extends Attribute>) */ - public boolean hasAttribute(Class attClass) { + public boolean hasAttribute(Class attClass) { return this.attributes.containsKey(attClass); } /** * The caller must pass in a Class<? extends Attribute> value. * Returns the instance of the passed in Attribute contained in this AttributeSource - *

Signature for Java 1.5: public <T extends Attribute> T getAttribute(Class<T>) * * @throws IllegalArgumentException if this AttributeSource does not contain the * Attribute. It is recommended to always use {@link #addAttribute} even in consumers @@ -255,8 +247,9 @@ * available. If you want to only use the attribute, if it is available (to optimize * consuming), use {@link #hasAttribute}. */ - public Attribute getAttribute(Class attClass) { - final Attribute att = (Attribute) this.attributes.get(attClass); + public A getAttribute(Class attClass) { + // the following cast is unchecked, because compiler does not know if implementation really implements A + @SuppressWarnings("unchecked") final A att = (A) this.attributes.get(attClass); if (att == null) { throw new IllegalArgumentException("This AttributeSource does not have the attribute '" + attClass.getName() + "'."); } @@ -290,12 +283,12 @@ private void computeCurrentState() { currentState = new State(); State c = currentState; - Iterator it = attributeImpls.values().iterator(); - c.attribute = (AttributeImpl) it.next(); + final Iterator it = attributeImpls.values().iterator(); + c.attribute = it.next(); while (it.hasNext()) { c.next = new State(); c = c.next; - c.attribute = (AttributeImpl) it.next(); + c.attribute = it.next(); } } @@ -348,7 +341,7 @@ if (state == null) return; do { - AttributeImpl targetImpl = (AttributeImpl) attributeImpls.get(state.attribute.getClass()); + AttributeImpl targetImpl = attributeImpls.get(state.attribute.getClass()); if (targetImpl == null) throw new IllegalArgumentException("State contains an AttributeImpl that is not in this AttributeSource"); state.attribute.copyTo(targetImpl); @@ -412,9 +405,7 @@ } public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append('('); - + StringBuilder sb = new StringBuilder().append('('); if (hasAttributes()) { if (currentState == null) { computeCurrentState(); @@ -424,8 +415,7 @@ sb.append(state.attribute.toString()); } } - sb.append(')'); - return sb.toString(); + return sb.append(')').toString(); } /** @@ -442,14 +432,12 @@ computeCurrentState(); } for (State state = currentState; state != null; state = state.next) { - clone.attributeImpls.put(state.attribute.getClass(), state.attribute.clone()); + clone.attributeImpls.put(state.attribute.getClass(), (AttributeImpl) state.attribute.clone()); } } // now the interfaces - Iterator/*, AttributeImpl>>*/ attIt = this.attributes.entrySet().iterator(); - while (attIt.hasNext()) { - Entry/*, AttributeImpl>*/ entry = (Entry/*, AttributeImpl>*/) attIt.next(); + for (Entry, AttributeImpl> entry : this.attributes.entrySet()) { clone.attributes.put(entry.getKey(), clone.attributeImpls.get(entry.getValue().getClass())); } Index: src/test/org/apache/lucene/util/TestAttributeSource.java =================================================================== --- src/test/org/apache/lucene/util/TestAttributeSource.java (revision 809286) +++ src/test/org/apache/lucene/util/TestAttributeSource.java (working copy) @@ -27,8 +27,8 @@ public void testCaptureState() { // init a first instance AttributeSource src = new AttributeSource(); - TermAttribute termAtt = (TermAttribute) src.addAttribute(TermAttribute.class); - TypeAttribute typeAtt = (TypeAttribute) src.addAttribute(TypeAttribute.class); + TermAttribute termAtt = src.addAttribute(TermAttribute.class); + TypeAttribute typeAtt = src.addAttribute(TypeAttribute.class); termAtt.setTermBuffer("TestTerm"); typeAtt.setType("TestType"); final int hashCode = src.hashCode(); @@ -55,9 +55,9 @@ // init a second instance (with attributes in different order and one additional attribute) AttributeSource src2 = new AttributeSource(); - typeAtt = (TypeAttribute) src2.addAttribute(TypeAttribute.class); - FlagsAttribute flagsAtt = (FlagsAttribute) src2.addAttribute(FlagsAttribute.class); - termAtt = (TermAttribute) src2.addAttribute(TermAttribute.class); + typeAtt = src2.addAttribute(TypeAttribute.class); + FlagsAttribute flagsAtt = src2.addAttribute(FlagsAttribute.class); + termAtt = src2.addAttribute(TermAttribute.class); flagsAtt.setFlags(12345); src2.restoreState(state); @@ -67,7 +67,7 @@ // init a third instance missing one Attribute AttributeSource src3 = new AttributeSource(); - termAtt = (TermAttribute) src3.addAttribute(TermAttribute.class); + termAtt = src3.addAttribute(TermAttribute.class); try { src3.restoreState(state); fail("The third instance is missing the TypeAttribute, so restoreState() should throw IllegalArgumentException"); @@ -78,19 +78,19 @@ public void testCloneAttributes() { final AttributeSource src = new AttributeSource(); - final TermAttribute termAtt = (TermAttribute) src.addAttribute(TermAttribute.class); - final TypeAttribute typeAtt = (TypeAttribute) src.addAttribute(TypeAttribute.class); + final TermAttribute termAtt = src.addAttribute(TermAttribute.class); + final TypeAttribute typeAtt = src.addAttribute(TypeAttribute.class); termAtt.setTermBuffer("TestTerm"); typeAtt.setType("TestType"); final AttributeSource clone = src.cloneAttributes(); - final Iterator it = clone.getAttributeClassesIterator(); + final Iterator> it = clone.getAttributeClassesIterator(); assertEquals("TermAttribute must be the first attribute", TermAttribute.class, it.next()); assertEquals("TypeAttribute must be the second attribute", TypeAttribute.class, it.next()); assertFalse("No more attributes", it.hasNext()); - final TermAttribute termAtt2 = (TermAttribute) clone.getAttribute(TermAttribute.class); - final TypeAttribute typeAtt2 = (TypeAttribute) clone.getAttribute(TypeAttribute.class); + final TermAttribute termAtt2 = clone.getAttribute(TermAttribute.class); + final TypeAttribute typeAtt2 = clone.getAttribute(TypeAttribute.class); assertNotSame("TermAttribute of original and clone must be different instances", termAtt2, termAtt); assertNotSame("TypeAttribute of original and clone must be different instances", typeAtt2, typeAtt); assertEquals("TermAttribute of original and clone must be equal", termAtt2, termAtt); @@ -99,12 +99,12 @@ public void testToStringAndMultiAttributeImplementations() { AttributeSource src = new AttributeSource(); - TermAttribute termAtt = (TermAttribute) src.addAttribute(TermAttribute.class); - TypeAttribute typeAtt = (TypeAttribute) src.addAttribute(TypeAttribute.class); + TermAttribute termAtt = src.addAttribute(TermAttribute.class); + TypeAttribute typeAtt = src.addAttribute(TypeAttribute.class); termAtt.setTermBuffer("TestTerm"); typeAtt.setType("TestType"); assertEquals("Attributes should appear in original order", "("+termAtt.toString()+","+typeAtt.toString()+")", src.toString()); - Iterator it = src.getAttributeImplsIterator(); + Iterator it = src.getAttributeImplsIterator(); assertTrue("Iterator should have 2 attributes left", it.hasNext()); assertSame("First AttributeImpl from iterator should be termAtt", termAtt, it.next()); assertTrue("Iterator should have 1 attributes left", it.hasNext()); @@ -114,7 +114,7 @@ src = new AttributeSource(); src.addAttributeImpl(new Token()); // this should not add a new attribute as Token implements TermAttribute, too - termAtt = (TermAttribute) src.addAttribute(TermAttribute.class); + termAtt = src.addAttribute(TermAttribute.class); assertTrue("TermAttribute should be implemented by Token", termAtt instanceof Token); // get the Token attribute and check, that it is the only one it = src.getAttributeImplsIterator();