Index: lucene/contrib/icu/src/java/org/apache/lucene/analysis/icu/tokenattributes/ScriptAttributeImpl.java
===================================================================
--- lucene/contrib/icu/src/java/org/apache/lucene/analysis/icu/tokenattributes/ScriptAttributeImpl.java (revision 1060610)
+++ lucene/contrib/icu/src/java/org/apache/lucene/analysis/icu/tokenattributes/ScriptAttributeImpl.java (working copy)
@@ -20,6 +20,7 @@
import java.io.Serializable;
import org.apache.lucene.util.AttributeImpl;
+import org.apache.lucene.util.AttributeReflector;
import com.ibm.icu.lang.UScript;
@@ -77,7 +78,7 @@
}
@Override
- public String toString() {
- return "script=" + getName();
+ public void reflectWith(AttributeReflector reflector) {
+ reflector.reflect(ScriptAttribute.class, "script", getName());
}
}
Index: lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/AllowLeadingWildcardAttributeImpl.java
===================================================================
--- lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/AllowLeadingWildcardAttributeImpl.java (revision 1060610)
+++ lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/AllowLeadingWildcardAttributeImpl.java (working copy)
@@ -20,6 +20,7 @@
import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
import org.apache.lucene.queryParser.standard.processors.AllowLeadingWildcardProcessor;
import org.apache.lucene.util.AttributeImpl;
+import org.apache.lucene.util.AttributeReflector;
/**
* This attribute is used by {@link AllowLeadingWildcardProcessor} processor and
@@ -78,4 +79,9 @@
+ this.allowLeadingWildcard + "/>";
}
+ @Override
+ public void reflectWith(AttributeReflector reflector) {
+ reflector.reflect(AllowLeadingWildcardAttribute.class, "allowLeadingWildcard", this.allowLeadingWildcard);
+ }
+
}
Index: lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/AnalyzerAttributeImpl.java
===================================================================
--- lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/AnalyzerAttributeImpl.java (revision 1060610)
+++ lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/AnalyzerAttributeImpl.java (working copy)
@@ -21,6 +21,7 @@
import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
import org.apache.lucene.queryParser.standard.processors.AnalyzerQueryNodeProcessor;
import org.apache.lucene.util.AttributeImpl;
+import org.apache.lucene.util.AttributeReflector;
/**
* This attribute is used by {@link AnalyzerQueryNodeProcessor} processor and
@@ -89,4 +90,9 @@
return "";
}
+ @Override
+ public void reflectWith(AttributeReflector reflector) {
+ reflector.reflect(AnalyzerAttribute.class, "analyzer", this.analyzer);
+ }
+
}
Index: lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/BoostAttributeImpl.java
===================================================================
--- lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/BoostAttributeImpl.java (revision 1060610)
+++ lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/BoostAttributeImpl.java (working copy)
@@ -20,6 +20,7 @@
import org.apache.lucene.queryParser.core.config.FieldConfig;
import org.apache.lucene.queryParser.standard.processors.MultiFieldQueryNodeProcessor;
import org.apache.lucene.util.AttributeImpl;
+import org.apache.lucene.util.AttributeReflector;
/**
* This attribute is used by {@link MultiFieldQueryNodeProcessor} processor and
@@ -83,4 +84,9 @@
return "";
}
+ @Override
+ public void reflectWith(AttributeReflector reflector) {
+ reflector.reflect(BoostAttribute.class, "boost", this.boost);
+ }
+
}
Index: lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/DateResolutionAttributeImpl.java
===================================================================
--- lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/DateResolutionAttributeImpl.java (revision 1060610)
+++ lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/DateResolutionAttributeImpl.java (working copy)
@@ -22,6 +22,7 @@
import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
import org.apache.lucene.queryParser.standard.processors.ParametricRangeQueryNodeProcessor;
import org.apache.lucene.util.AttributeImpl;
+import org.apache.lucene.util.AttributeReflector;
/**
* This attribute is used by {@link ParametricRangeQueryNodeProcessor} processor
@@ -89,4 +90,9 @@
+ "'/>";
}
+ @Override
+ public void reflectWith(AttributeReflector reflector) {
+ reflector.reflect(DateResolutionAttribute.class, "dateResolution", this.dateResolution);
+ }
+
}
Index: lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/DefaultOperatorAttributeImpl.java
===================================================================
--- lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/DefaultOperatorAttributeImpl.java (revision 1060610)
+++ lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/DefaultOperatorAttributeImpl.java (working copy)
@@ -20,6 +20,7 @@
import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
import org.apache.lucene.queryParser.standard.processors.GroupQueryNodeProcessor;
import org.apache.lucene.util.AttributeImpl;
+import org.apache.lucene.util.AttributeReflector;
/**
* This attribute is used by {@link GroupQueryNodeProcessor} processor and must
@@ -91,4 +92,9 @@
return "";
}
+ @Override
+ public void reflectWith(AttributeReflector reflector) {
+ reflector.reflect(DefaultOperatorAttribute.class, "operator", this.operator);
+ }
+
}
Index: lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/DefaultPhraseSlopAttributeImpl.java
===================================================================
--- lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/DefaultPhraseSlopAttributeImpl.java (revision 1060610)
+++ lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/DefaultPhraseSlopAttributeImpl.java (working copy)
@@ -20,6 +20,7 @@
import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
import org.apache.lucene.queryParser.standard.processors.PhraseSlopQueryNodeProcessor;
import org.apache.lucene.util.AttributeImpl;
+import org.apache.lucene.util.AttributeReflector;
/**
* This attribute is used by {@link PhraseSlopQueryNodeProcessor} processor and
@@ -83,4 +84,9 @@
+ "/>";
}
+ @Override
+ public void reflectWith(AttributeReflector reflector) {
+ reflector.reflect(DefaultPhraseSlopAttribute.class, "defaultPhraseSlop", this.defaultPhraseSlop);
+ }
+
}
Index: lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/FieldBoostMapAttributeImpl.java
===================================================================
--- lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/FieldBoostMapAttributeImpl.java (revision 1060610)
+++ lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/FieldBoostMapAttributeImpl.java (working copy)
@@ -23,6 +23,7 @@
import org.apache.lucene.queryParser.core.config.FieldConfig;
import org.apache.lucene.queryParser.standard.processors.MultiFieldQueryNodeProcessor;
import org.apache.lucene.util.AttributeImpl;
+import org.apache.lucene.util.AttributeReflector;
/**
* This attribute is used by {@link MultiFieldQueryNodeProcessor} processor and
@@ -91,4 +92,9 @@
return "";
}
+ @Override
+ public void reflectWith(AttributeReflector reflector) {
+ reflector.reflect(FieldBoostMapAttribute.class, "boosts", this.boosts);
+ }
+
}
Index: lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/FieldDateResolutionMapAttributeImpl.java
===================================================================
--- lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/FieldDateResolutionMapAttributeImpl.java (revision 1060610)
+++ lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/FieldDateResolutionMapAttributeImpl.java (working copy)
@@ -23,6 +23,7 @@
import org.apache.lucene.document.DateTools;
import org.apache.lucene.document.DateTools.Resolution;
import org.apache.lucene.util.AttributeImpl;
+import org.apache.lucene.util.AttributeReflector;
/**
* This attribute enables the user to define a default DateResolution per field.
@@ -88,4 +89,9 @@
return "";
}
+ @Override
+ public void reflectWith(AttributeReflector reflector) {
+ reflector.reflect(FieldDateResolutionMapAttribute.class, "dateRes", this.dateRes);
+ }
+
}
Index: lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/FuzzyAttributeImpl.java
===================================================================
--- lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/FuzzyAttributeImpl.java (revision 1060610)
+++ lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/FuzzyAttributeImpl.java (working copy)
@@ -21,6 +21,7 @@
import org.apache.lucene.queryParser.standard.processors.PhraseSlopQueryNodeProcessor;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.util.AttributeImpl;
+import org.apache.lucene.util.AttributeReflector;
/**
* This attribute is used by {@link PhraseSlopQueryNodeProcessor} processor and
@@ -93,4 +94,9 @@
return "";
}
+ @Override
+ public void reflectWith(AttributeReflector reflector) {
+ reflector.reflect(FuzzyAttribute.class, "prefixLength", this.prefixLength);
+ }
+
}
Index: lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/LocaleAttributeImpl.java
===================================================================
--- lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/LocaleAttributeImpl.java (revision 1060610)
+++ lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/LocaleAttributeImpl.java (working copy)
@@ -22,6 +22,7 @@
import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
import org.apache.lucene.queryParser.standard.processors.ParametricRangeQueryNodeProcessor;
import org.apache.lucene.util.AttributeImpl;
+import org.apache.lucene.util.AttributeReflector;
/**
* This attribute is used by processor {@link ParametricRangeQueryNodeProcessor}
@@ -89,4 +90,9 @@
return "";
}
+ @Override
+ public void reflectWith(AttributeReflector reflector) {
+ reflector.reflect(LocaleAttribute.class, "locale", this.locale);
+ }
+
}
Index: lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/LowercaseExpandedTermsAttributeImpl.java
===================================================================
--- lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/LowercaseExpandedTermsAttributeImpl.java (revision 1060610)
+++ lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/LowercaseExpandedTermsAttributeImpl.java (working copy)
@@ -22,6 +22,7 @@
import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
import org.apache.lucene.queryParser.standard.processors.ParametricRangeQueryNodeProcessor;
import org.apache.lucene.util.AttributeImpl;
+import org.apache.lucene.util.AttributeReflector;
/**
* This attribute is used by processor {@link ParametricRangeQueryNodeProcessor}
@@ -84,4 +85,9 @@
+ this.lowercaseExpandedTerms + "/>";
}
+ @Override
+ public void reflectWith(AttributeReflector reflector) {
+ reflector.reflect(LowercaseExpandedTermsAttribute.class, "lowercaseExpandedTerms", this.lowercaseExpandedTerms);
+ }
+
}
Index: lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/MultiFieldAttributeImpl.java
===================================================================
--- lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/MultiFieldAttributeImpl.java (revision 1060610)
+++ lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/MultiFieldAttributeImpl.java (working copy)
@@ -22,6 +22,7 @@
import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
import org.apache.lucene.queryParser.standard.processors.MultiFieldQueryNodeProcessor;
import org.apache.lucene.util.AttributeImpl;
+import org.apache.lucene.util.AttributeReflector;
/**
* This attribute is used by {@link MultiFieldQueryNodeProcessor} processor and
@@ -83,4 +84,9 @@
return "";
}
+ @Override
+ public void reflectWith(AttributeReflector reflector) {
+ reflector.reflect(MultiFieldAttribute.class, "fields", this.fields);
+ }
+
}
Index: lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/MultiTermRewriteMethodAttributeImpl.java
===================================================================
--- lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/MultiTermRewriteMethodAttributeImpl.java (revision 1060610)
+++ lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/MultiTermRewriteMethodAttributeImpl.java (working copy)
@@ -22,6 +22,7 @@
import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.MultiTermQuery.RewriteMethod;
import org.apache.lucene.util.AttributeImpl;
+import org.apache.lucene.util.AttributeReflector;
/**
* This attribute is used by {@link ParametricRangeQueryNodeProcessor} processor
@@ -85,4 +86,9 @@
+ this.multiTermRewriteMethod + "/>";
}
+ @Override
+ public void reflectWith(AttributeReflector reflector) {
+ reflector.reflect(MultiTermRewriteMethodAttribute.class, "multiTermRewriteMethod", this.multiTermRewriteMethod);
+ }
+
}
Index: lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/PositionIncrementsAttributeImpl.java
===================================================================
--- lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/PositionIncrementsAttributeImpl.java (revision 1060610)
+++ lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/PositionIncrementsAttributeImpl.java (working copy)
@@ -20,6 +20,7 @@
import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
import org.apache.lucene.queryParser.standard.processors.AnalyzerQueryNodeProcessor;
import org.apache.lucene.util.AttributeImpl;
+import org.apache.lucene.util.AttributeReflector;
/**
* This attribute is used by {@link AnalyzerQueryNodeProcessor} processor and
@@ -82,4 +83,9 @@
+ this.positionIncrementsEnabled + "/>";
}
+ @Override
+ public void reflectWith(AttributeReflector reflector) {
+ reflector.reflect(PositionIncrementsAttribute.class, "positionIncrementsEnabled", this.positionIncrementsEnabled);
+ }
+
}
Index: lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/RangeCollatorAttributeImpl.java
===================================================================
--- lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/RangeCollatorAttributeImpl.java (revision 1060610)
+++ lucene/contrib/queryparser/src/java/org/apache/lucene/queryParser/standard/config/RangeCollatorAttributeImpl.java (working copy)
@@ -23,6 +23,7 @@
import org.apache.lucene.queryParser.standard.processors.ParametricRangeQueryNodeProcessor;
import org.apache.lucene.search.TermRangeQuery;
import org.apache.lucene.util.AttributeImpl;
+import org.apache.lucene.util.AttributeReflector;
/**
* This attribute is used by {@link ParametricRangeQueryNodeProcessor} processor
@@ -91,4 +92,9 @@
+ "'/>";
}
+ @Override
+ public void reflectWith(AttributeReflector reflector) {
+ reflector.reflect(RangeCollatorAttribute.class, "rangeCollator", this.rangeCollator);
+ }
+
}
Index: lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/spans/UniqueFieldAttributeImpl.java
===================================================================
--- lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/spans/UniqueFieldAttributeImpl.java (revision 1060610)
+++ lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/spans/UniqueFieldAttributeImpl.java (working copy)
@@ -19,6 +19,7 @@
import org.apache.lucene.queryParser.core.nodes.FieldableNode;
import org.apache.lucene.util.AttributeImpl;
+import org.apache.lucene.util.AttributeReflector;
/**
* This attribute is used by the {@link UniqueFieldQueryNodeProcessor}
@@ -90,4 +91,9 @@
return "";
}
+ @Override
+ public void reflectWith(AttributeReflector reflector) {
+ reflector.reflect(UniqueFieldAttribute.class, "uniqueField", this.uniqueField);
+ }
+
}
Index: lucene/src/java/org/apache/lucene/analysis/Token.java
===================================================================
--- lucene/src/java/org/apache/lucene/analysis/Token.java (revision 1060610)
+++ lucene/src/java/org/apache/lucene/analysis/Token.java (working copy)
@@ -28,6 +28,7 @@
import org.apache.lucene.util.Attribute;
import org.apache.lucene.util.AttributeSource;
import org.apache.lucene.util.AttributeImpl;
+import org.apache.lucene.util.AttributeReflector;
/**
A Token is an occurrence of a term from the text of a field. It consists of
@@ -589,6 +590,17 @@
}
}
+ @Override
+ public void reflectWith(AttributeReflector reflector) {
+ super.reflectWith(reflector);
+ reflector.reflect(OffsetAttribute.class, "startOffset", startOffset);
+ reflector.reflect(OffsetAttribute.class, "endOffset", endOffset);
+ reflector.reflect(PositionIncrementAttribute.class, "positionIncrement", positionIncrement);
+ reflector.reflect(PayloadAttribute.class, "payload", payload);
+ reflector.reflect(FlagsAttribute.class, "flags", flags);
+ reflector.reflect(TypeAttribute.class, "type", type);
+ }
+
/** Convenience factory that returns Token as implementation for the basic
* attributes and return the default impl (with "Impl" appended) for all other
* attributes.
Index: lucene/src/java/org/apache/lucene/analysis/tokenattributes/CharTermAttributeImpl.java
===================================================================
--- lucene/src/java/org/apache/lucene/analysis/tokenattributes/CharTermAttributeImpl.java (revision 1060610)
+++ lucene/src/java/org/apache/lucene/analysis/tokenattributes/CharTermAttributeImpl.java (working copy)
@@ -22,6 +22,7 @@
import org.apache.lucene.util.ArrayUtil;
import org.apache.lucene.util.AttributeImpl;
+import org.apache.lucene.util.AttributeReflector;
import org.apache.lucene.util.RamUsageEstimator;
/**
@@ -286,6 +287,11 @@
}
@Override
+ public void reflectWith(AttributeReflector reflector) {
+ reflector.reflect(CharTermAttribute.class, "term", toString());
+ }
+
+ @Override
public void copyTo(AttributeImpl target) {
if (target instanceof CharTermAttribute) {
CharTermAttribute t = (CharTermAttribute) target;
Index: lucene/src/java/org/apache/lucene/util/AttributeImpl.java
===================================================================
--- lucene/src/java/org/apache/lucene/util/AttributeImpl.java (revision 1060610)
+++ lucene/src/java/org/apache/lucene/util/AttributeImpl.java (working copy)
@@ -20,7 +20,11 @@
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
+import java.lang.ref.WeakReference;
+import java.util.LinkedList;
+import org.apache.lucene.analysis.tokenattributes.CharTermAttributeImpl; // deprecated
+
/**
* Base class for Attributes that can be added to a
* {@link org.apache.lucene.util.AttributeSource}.
@@ -37,72 +41,134 @@
public abstract void clear();
/**
- * The default implementation of this method accesses all declared
- * fields of this object and prints the values in the following syntax:
+ * Returns a string representation of the object. In general, the {@code toString} method
+ * returns a string that "textually represents" this object.
+ *
+ *
WARNING: For backwards compatibility this method is implemented as
+ * {@code return reflectAsString(false)}. In Lucene 4.0 this default implementation
+ * will be removed. The reason for this is the problem of
+ * {@link CharTermAttributeImpl#toString} that must return a string representation
+ * of the term's char sequence.
+ *
+ *
It is recommeneded to use {@link #reflectAsString} or {@link #reflectWith}
+ * to get a well-defined output of AttributeImpl's internals.
+ */
+ // TODO: @deprecated remove this method in 4.0
+ @Override
+ public String toString() {
+ return reflectAsString(false);
+ }
+
+ /**
+ * This method returns the current attribute values as a string in the following format
+ * by calling the {@link #reflectWith(AttributeReflector)} method:
*
+ *
+ *
+ * @see #reflectWith(AttributeReflector)
+ * @see #toString()
+ */
+ public final String reflectAsString(final boolean prependAttClass) {
+ final StringBuilder buffer = new StringBuilder();
+ reflectWith(new AttributeReflector() {
+ public void reflect(Class extends Attribute> attClass, String key, Object value) {
+ if (buffer.length() > 0) {
+ buffer.append(',');
+ }
+ if (prependAttClass) {
+ buffer.append(attClass.getName()).append('#');
+ }
+ buffer.append(key).append('=').append((value == null) ? "null" : value);
+ }
+ });
+ return buffer.toString();
+ }
+
+ /**
+ * @deprecated this will be removed in Lucene 4.0
+ */
+ @Deprecated
+ private static final VirtualMethod toStringMethod =
+ new VirtualMethod(AttributeImpl.class, "toString");
+
+ /**
+ * @deprecated this will be removed in Lucene 4.0
+ */
+ @Deprecated
+ private boolean assertExternalClass(Class extends AttributeImpl> clazz) {
+ final String name = clazz.getName();
+ return (!name.startsWith("org.apache.lucene.") && !name.startsWith("org.apache.solr."))
+ || name.equals("org.apache.lucene.util.TestAttributeSource$TestAttributeImpl");
+ }
+
+ /**
+ * This method is for introspection of attributes, it should simply
+ * add the key/values this attribute holds to the given {@link AttributeReflector}.
+ *
+ *
The default implementation calls {@link AttributeReflector#reflect} for all
+ * non-static fields from the implementing class, using the field name as key
+ * and the field value as value. The Attribute class is also determined by reflection.
+ * Please note that the default implementation can only handle single-Attribute
+ * implementations.
+ *
+ *
Custom implementations look like this (e.g. for a combined attribute implementation):
*
- *
- * This method may be overridden by subclasses.
+ *
+ *
If you implement this method, make sure that for each invocation, the same set of {@link Attribute}
+ * interfaces and keys are passed to {@link AttributeReflector#reflect} in the same order, but possibly
+ * different values. So don't automatically exclude e.g. {@code null} properties!
+ *
+ * @see #reflectAsString(boolean)
*/
- @Override
- public String toString() {
- StringBuilder buffer = new StringBuilder();
- Class> clazz = this.getClass();
- Field[] fields = clazz.getDeclaredFields();
+ public void reflectWith(AttributeReflector reflector) {
+ final Class extends AttributeImpl> clazz = this.getClass();
+ final LinkedList>> interfaces = AttributeSource.getAttributeInterfaces(clazz);
+ if (interfaces.size() != 1) {
+ throw new UnsupportedOperationException(clazz.getName() +
+ " implements more than one Attribute interface, the default reflectWith() implementation cannot handle this.");
+ }
+ final Class extends Attribute> interf = interfaces.getFirst().get();
+
+ // TODO: @deprecated sophisticated(TM) backwards
+ if (!(this instanceof CharTermAttributeImpl) && toStringMethod.isOverriddenAsOf(clazz)) {
+ assert assertExternalClass(clazz) : "no Lucene/Solr classes should fallback to toString() parsing";
+ // this class overrides toString and for backwards compatibility we try to parse the string returned by this method:
+ for (String part : toString().split(",")) {
+ final int pos = part.indexOf('=');
+ if (pos < 0) {
+ throw new UnsupportedOperationException("The backwards compatibility layer to support reflectWith() " +
+ "on old AtributeImpls expects the toString() implementation to return a correct format as specified for method reflectAsString(false)");
+ }
+ reflector.reflect(interf, part.substring(0, pos).trim(), part.substring(pos + 1));
+ }
+ return;
+ }
+ // end sophisticated(TM) backwards
+
+ final Field[] fields = clazz.getDeclaredFields();
try {
for (int i = 0; i < fields.length; i++) {
- Field f = fields[i];
+ final Field f = fields[i];
if (Modifier.isStatic(f.getModifiers())) continue;
f.setAccessible(true);
- Object value = f.get(this);
- if (buffer.length()>0) {
- buffer.append(',');
- }
- if (value == null) {
- buffer.append(f.getName() + "=null");
- } else {
- buffer.append(f.getName() + "=" + value);
- }
+ reflector.reflect(interf, f.getName(), f.get(this));
}
} catch (IllegalAccessException e) {
// this should never happen, because we're just accessing fields
// from 'this'
throw new RuntimeException(e);
}
-
- return buffer.toString();
}
/**
- * Subclasses must implement this method and should compute
- * a hashCode similar to this:
- *
- * public int hashCode() {
- * int code = startOffset;
- * code = code * 31 + endOffset;
- * return code;
- * }
- *
- *
- * see also {@link #equals(Object)}
- */
- @Override
- public abstract int hashCode();
-
- /**
- * All values used for computation of {@link #hashCode()}
- * should be checked here for equality.
- *
- * see also {@link Object#equals(Object)}
- */
- @Override
- public abstract boolean equals(Object other);
-
- /**
* Copies the values from this Attribute into the passed-in
* target attribute. The target implementation must support all the
* Attributes this implementation supports.
Index: lucene/src/java/org/apache/lucene/util/AttributeReflector.java
===================================================================
--- lucene/src/java/org/apache/lucene/util/AttributeReflector.java (revision 0)
+++ lucene/src/java/org/apache/lucene/util/AttributeReflector.java (revision 0)
@@ -0,0 +1,30 @@
+package org.apache.lucene.util;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * TODO
+ */
+public interface AttributeReflector {
+
+ /**
+ * TODO
+ */
+ public void reflect(Class extends Attribute> attClass, String key, Object value);
+
+}
Property changes on: lucene\src\java\org\apache\lucene\util\AttributeReflector.java
___________________________________________________________________
Added: svn:keywords
+ Date Author Id Revision HeadURL
Added: svn:eol-style
+ native
Index: lucene/src/java/org/apache/lucene/util/AttributeSource.java
===================================================================
--- lucene/src/java/org/apache/lucene/util/AttributeSource.java (revision 1060610)
+++ lucene/src/java/org/apache/lucene/util/AttributeSource.java (working copy)
@@ -188,20 +188,9 @@
private static final WeakHashMap,LinkedList>>> knownImplClasses =
new WeakHashMap,LinkedList>>>();
- /** Expert: Adds a custom AttributeImpl instance with one or more Attribute interfaces.
- *
Please note: It is not guaranteed, that att is added to
- * the AttributeSource, because the provided attributes may already exist.
- * You should always retrieve the wanted attributes using {@link #getAttribute} after adding
- * with this method and cast to your class.
- * The recommended way to use custom implementations is using an {@link AttributeFactory}.
- *
- */
- public void addAttributeImpl(final AttributeImpl att) {
- final Class extends AttributeImpl> clazz = att.getClass();
- if (attributeImpls.containsKey(clazz)) return;
- LinkedList>> foundInterfaces;
+ static LinkedList>> getAttributeInterfaces(final Class extends AttributeImpl> clazz) {
synchronized(knownImplClasses) {
- foundInterfaces = knownImplClasses.get(clazz);
+ LinkedList>> foundInterfaces = knownImplClasses.get(clazz);
if (foundInterfaces == null) {
// we have a strong reference to the class instance holding all interfaces in the list (parameter "att"),
// so all WeakReferences are never evicted by GC
@@ -218,7 +207,23 @@
actClazz = actClazz.getSuperclass();
} while (actClazz != null);
}
+ return foundInterfaces;
}
+ }
+
+ /** Expert: Adds a custom AttributeImpl instance with one or more Attribute interfaces.
+ *
Please note: It is not guaranteed, that att is added to
+ * the AttributeSource, because the provided attributes may already exist.
+ * You should always retrieve the wanted attributes using {@link #getAttribute} after adding
+ * with this method and cast to your class.
+ * The recommended way to use custom implementations is using an {@link AttributeFactory}.
+ *
+ */
+ public void addAttributeImpl(final AttributeImpl att) {
+ final Class extends AttributeImpl> clazz = att.getClass();
+ if (attributeImpls.containsKey(clazz)) return;
+ final LinkedList>> foundInterfaces =
+ getAttributeInterfaces(clazz);
// add all interfaces of this AttributeImpl to the maps
for (WeakReference> curInterfaceRef : foundInterfaces) {
@@ -439,9 +444,21 @@
return false;
}
+ /**
+ * Returns a string representation of the object. In general, the {@code toString} method
+ * returns a string that "textually represents" this object.
+ *
+ *
WARNING: For backwards compatibility this method is implemented as
+ * in Lucene 2.9/3.0. In Lucene 4.0 this default implementation
+ * will be removed.
+ *
+ *
It is recommeneded to use {@link #reflectAsString} or {@link #reflectWith}
+ * to get a well-defined output of AttributeSource's internals.
+ */
+ // TODO: @deprecated remove this method in 4.0
@Override
public String toString() {
- StringBuilder sb = new StringBuilder().append('(');
+ final StringBuilder sb = new StringBuilder().append('(');
if (hasAttributes()) {
if (currentState == null) {
computeCurrentState();
@@ -455,6 +472,53 @@
}
/**
+ * This method returns the current attribute values as a string in the following format
+ * by calling the {@link #reflectWith(AttributeReflector)} method:
+ *
+ *