LUCENE-8638: remove deprecated code (#243)

This commit is contained in:
Michael Sokolov 2021-08-17 13:51:04 -04:00 committed by GitHub
parent 29ed3908ea
commit 2d21a600ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 79 additions and 181 deletions

View File

@ -22,6 +22,9 @@ System Requirements
API Changes
* LUCENE-8638: haversin() expressions function now returns its result in meters rather than
kilometers.
* LUCENE-8982: Separate out native code to another module to allow cpp
build with gradle. This also changes the name of the native "posix-support"
library to LuceneNativeIO. (Zachary Chen, Dawid Weiss)

View File

@ -40,21 +40,6 @@ public final class FilesystemResourceLoader implements ResourceLoader {
private final Path baseDirectory;
private final ResourceLoader delegate;
/**
* Creates a resource loader that resolves resources against the given base directory (may be
* {@code null} to refer to CWD). Files not found in file system and class lookups are delegated
* to context classloader.
*
* @deprecated You should not use this ctor, because it uses the thread's context class loader as
* fallback for resource lookups, which is bad programming style. Please specify a {@link
* ClassLoader} instead.
* @see #FilesystemResourceLoader(Path, ClassLoader)
*/
@Deprecated
public FilesystemResourceLoader(Path baseDirectory) {
this(baseDirectory, new ClasspathResourceLoader());
}
/**
* Creates a resource loader that resolves resources against the given base directory (may be
* {@code null} to refer to CWD). Files not found in file system and class lookups are delegated

View File

@ -74,8 +74,8 @@ public class TestFilesystemResourceLoader extends LuceneTestCase {
IOUtils.closeWhileHandlingException(os);
}
@SuppressWarnings("deprecation")
ResourceLoader rl = new FilesystemResourceLoader(base);
ResourceLoader rl =
new FilesystemResourceLoader(base, TestFilesystemResourceLoader.class.getClassLoader());
assertEquals(
"foobar",
WordlistLoader.getLines(rl.openResource("template.txt"), StandardCharsets.UTF_8).get(0));

View File

@ -22,6 +22,7 @@ import org.apache.lucene.codecs.Codec;
import org.apache.lucene.index.BaseSegmentInfoFormatTestCase;
import org.apache.lucene.util.Version;
@SuppressWarnings("deprecation")
public class TestLucene70SegmentInfoFormat extends BaseSegmentInfoFormatTestCase {
@Override

View File

@ -22,6 +22,7 @@ import org.apache.lucene.codecs.Codec;
import org.apache.lucene.index.BaseSegmentInfoFormatTestCase;
import org.apache.lucene.util.Version;
@SuppressWarnings("deprecation")
public class TestLucene86SegmentInfoFormat extends BaseSegmentInfoFormatTestCase {
@Override

View File

@ -124,6 +124,7 @@ import org.junit.BeforeClass;
*/
// See: https://issues.apache.org/jira/browse/SOLR-12028 Tests cannot remove files on Windows
// machines occasionally
@SuppressWarnings("deprecation")
public class TestBackwardsCompatibility extends LuceneTestCase {
// Backcompat index generation, described below, is mostly automated in:

View File

@ -161,6 +161,7 @@ public class SpatialDocMaker extends DocMaker {
}
/** Optionally converts points to circles, and optionally bbox'es result. */
@SuppressWarnings("deprecation")
public static ShapeConverter makeShapeConverter(
final SpatialStrategy spatialStrategy, Config config, String configKeyPrefix) {
// by default does no conversion
@ -220,6 +221,7 @@ public class SpatialDocMaker extends DocMaker {
return doc;
}
@SuppressWarnings("deprecation")
public static Shape makeShapeFromString(SpatialStrategy strategy, String name, String shapeStr) {
if (shapeStr != null && shapeStr.length() > 0) {
try {

View File

@ -439,7 +439,9 @@ public class AnalyzerFactoryTask extends PerfTask {
if (!Files.isDirectory(baseDir)) {
baseDir = Paths.get(".");
}
((ResourceLoaderAware) instance).inform(new FilesystemResourceLoader(baseDir));
((ResourceLoaderAware) instance)
.inform(
new FilesystemResourceLoader(baseDir, AnalyzerFactoryTask.class.getClassLoader()));
}
if (CharFilterFactory.class.isAssignableFrom(clazz)) {
charFilterFactories.add((CharFilterFactory) instance);

View File

@ -318,7 +318,6 @@ public abstract class IndexReader implements Closeable {
}
return null;
}
;
/** Get TermVectors from this index, or null if term vectors were not indexed. */
public abstract TermVectors getTermVectorsReader();

View File

@ -27,24 +27,6 @@ public final class ClasspathResourceLoader implements ResourceLoader {
private final Class<?> clazz;
private final ClassLoader loader;
/**
* Creates an instance using the context classloader to load resources and classes. Resource paths
* must be absolute.
*
* @deprecated You should not use this ctor, because it uses the thread's context class loader,
* which is bad programming style. Please specify a reference class or a {@link ClassLoader}
* instead.
* @see #ClasspathResourceLoader(ClassLoader)
* @see #ClasspathResourceLoader(Class)
*/
@Deprecated
@SuppressForbidden(
reason =
"Deprecated method uses thread's context classloader, but there for backwards compatibility")
public ClasspathResourceLoader() {
this(Thread.currentThread().getContextClassLoader());
}
/**
* Creates an instance using the given classloader to load Resources and classes. Resource paths
* must be absolute.

View File

@ -90,18 +90,4 @@ public final class Constants {
JVM_MAJOR_VERSION > 1 || (JVM_MAJOR_VERSION == 1 && JVM_MINOR_VERSION >= 9);
public static final boolean JRE_IS_MINIMUM_JAVA11 =
JVM_MAJOR_VERSION > 1 || (JVM_MAJOR_VERSION == 1 && JVM_MINOR_VERSION >= 11);
/**
* This is the internal Lucene version, including bugfix versions, recorded into each segment.
*
* @deprecated Use {@link Version#LATEST}
*/
@Deprecated public static final String LUCENE_MAIN_VERSION = Version.LATEST.toString();
/**
* Don't use this constant because the name is not self-describing!
*
* @deprecated Use {@link Version#LATEST}
*/
@Deprecated public static final String LUCENE_VERSION = Version.LATEST.toString();
}

View File

@ -416,38 +416,6 @@ public final class IOUtils {
throw new RuntimeException(th);
}
/**
* Rethrows the argument as {@code IOException} or {@code RuntimeException} if it's not null.
*
* @deprecated This method is deprecated in favor of {@link #rethrowAlways}. Code should be
* updated to {@link #rethrowAlways} and guarded with an additional null-argument check
* (because {@link #rethrowAlways} is not accepting null arguments).
*/
@Deprecated
public static void reThrow(Throwable th) throws IOException {
if (th != null) {
throw rethrowAlways(th);
}
}
/**
* @deprecated This method is deprecated in favor of {@link #rethrowAlways}. Code should be
* updated to {@link #rethrowAlways} and guarded with an additional null-argument check
* (because {@link #rethrowAlways} is not accepting null arguments).
*/
@Deprecated
public static void reThrowUnchecked(Throwable th) {
if (th != null) {
if (th instanceof Error) {
throw (Error) th;
}
if (th instanceof RuntimeException) {
throw (RuntimeException) th;
}
throw new RuntimeException(th);
}
}
/**
* Ensure that any writes to the given file is written to the storage device that contains it.
*

View File

@ -58,23 +58,6 @@ public class SloppyMath {
return TO_METERS * 2 * asin(Math.min(1, Math.sqrt(sortKey * 0.5)));
}
/**
* Returns the Haversine distance in kilometers between two points specified in decimal degrees
* (latitude/longitude). This works correctly even if the dateline is between the two points.
*
* @param lat1 Latitude of the first point.
* @param lon1 Longitude of the first point.
* @param lat2 Latitude of the second point.
* @param lon2 Longitude of the second point.
* @return distance in kilometers.
* @deprecated Use {@link #haversinMeters(double, double, double, double) instead}
*/
@Deprecated
public static double haversinKilometers(double lat1, double lon1, double lat2, double lon2) {
double h = haversinSortKey(lat1, lon1, lat2, lon2);
return TO_KILOMETERS * 2 * asin(Math.min(1, Math.sqrt(h * 0.5)));
}
/**
* Returns a sort key for distance. This is less expensive to compute than {@link
* #haversinMeters(double, double, double, double)}, but it always compares the same. This can be
@ -198,7 +181,6 @@ public class SloppyMath {
// Earth's mean radius, in meters and kilometers; see
// http://earth-info.nga.mil/GandG/publications/tr8350.2/wgs84fin.pdf
private static final double TO_METERS = 6_371_008.7714D; // equatorial radius
private static final double TO_KILOMETERS = 6_371.0087714D; // equatorial radius
// cos/asin
private static final double ONE_DIV_F2 = 1 / 2.0;

View File

@ -54,10 +54,10 @@ import org.apache.lucene.store.Directory;
*/
public class DistanceFacetsExample implements Closeable {
final DoubleRange ONE_KM = new DoubleRange("< 1 km", 0.0, true, 1.0, false);
final DoubleRange TWO_KM = new DoubleRange("< 2 km", 0.0, true, 2.0, false);
final DoubleRange FIVE_KM = new DoubleRange("< 5 km", 0.0, true, 5.0, false);
final DoubleRange TEN_KM = new DoubleRange("< 10 km", 0.0, true, 10.0, false);
final DoubleRange ONE_KM = new DoubleRange("< 1 km", 0.0, true, 1000.0, false);
final DoubleRange TWO_KM = new DoubleRange("< 2 km", 0.0, true, 2000.0, false);
final DoubleRange FIVE_KM = new DoubleRange("< 5 km", 0.0, true, 5000.0, false);
final DoubleRange TEN_KM = new DoubleRange("< 10 km", 0.0, true, 10000.0, false);
private final Directory indexDir = new ByteBuffersDirectory();
private IndexSearcher searcher;

View File

@ -31,7 +31,7 @@ cos = java.lang.Math, cos, 1
cosh = java.lang.Math, cosh, 1
exp = java.lang.Math, exp, 1
floor = java.lang.Math, floor, 1
haversin = org.apache.lucene.util.SloppyMath, haversinKilometers, 4
haversin = org.apache.lucene.util.SloppyMath, haversinMeters, 4
ln = java.lang.Math, log, 1
log10 = java.lang.Math, log10, 1
logn = org.apache.lucene.util.MathUtil, log, 2

View File

@ -221,13 +221,13 @@ public class TestDemoExpressions extends LuceneTestCase {
TopFieldDocs td = searcher.search(new MatchAllDocsQuery(), 3, sort);
FieldDoc d = (FieldDoc) td.scoreDocs[0];
assertEquals(0.4621D, (Double) d.fields[0], 1E-4);
assertEquals(462.1D, (Double) d.fields[0], 1E-1);
d = (FieldDoc) td.scoreDocs[1];
assertEquals(1.055D, (Double) d.fields[0], 1E-4);
assertEquals(1055D, (Double) d.fields[0], 1E-1);
d = (FieldDoc) td.scoreDocs[2];
assertEquals(5.2859D, (Double) d.fields[0], 1E-4);
assertEquals(5285.9D, (Double) d.fields[0], 1E-1);
}
public void testStaticExtendedVariableExample() throws Exception {

View File

@ -158,7 +158,7 @@ public class TestJavascriptFunction extends LuceneTestCase {
}
public void testHaversinMethod() throws Exception {
assertEvaluatesTo("haversin(40.7143528,-74.0059731,40.759011,-73.9844722)", 5.285885589128259);
assertEvaluatesTo("haversin(40.7143528,-74.0059731,40.759011,-73.9844722)", 5285.885589128259);
}
public void testLnMethod() throws Exception {

View File

@ -259,6 +259,7 @@ public class TestDrillDownQuery extends FacetTestCase {
assertEquals(base, rewrite);
}
@SuppressWarnings("deprecation")
public void testRequireDimensionDrillDown() throws Exception {
Directory dir = newDirectory();
RandomIndexWriter writer =

View File

@ -22,8 +22,7 @@ import org.apache.lucene.index.Term;
import org.apache.lucene.search.Query;
/** Base class for queries that expand to sets of simple terms. */
public abstract class SimpleTerm extends SrndQuery
implements DistanceSubQuery, Comparable<SimpleTerm> {
public abstract class SimpleTerm extends SrndQuery implements DistanceSubQuery {
public SimpleTerm(boolean q) {
quoted = q;
}
@ -44,17 +43,6 @@ public abstract class SimpleTerm extends SrndQuery
public abstract String toStringUnquoted();
/**
* @deprecated (March 2011) Not normally used, to be removed from Lucene 4.0. This class
* implementing Comparable is to be removed at the same time.
*/
@Override
@Deprecated
public int compareTo(SimpleTerm ost) {
/* for ordering terms and prefixes before using an index, not used */
return this.toStringUnquoted().compareTo(ost.toStringUnquoted());
}
protected void suffixToString(StringBuilder r) {} /* override for prefix query */
@Override

View File

@ -105,14 +105,6 @@ public class DateRangePrefixTree extends NumberRangePrefixTree {
// how many million years are there?
private static final int NUM_MYEARS = 586; // we assert how this was computed in the constructor
/**
* An instanced based on {@link Calendar#getInstance(TimeZone, Locale)} with UTC and Locale.Root.
* This will (always?) be a {@link GregorianCalendar} with a so-called "Gregorian Change Date" of
* 1582.
*/
@Deprecated
public static final DateRangePrefixTree INSTANCE = new DateRangePrefixTree(DEFAULT_CAL);
// Instance fields: (all are final)
private final Calendar CAL_TMP; // template

View File

@ -116,6 +116,7 @@ public class SpatialArgsParser {
args.setDistErr(readDouble(nameValPairs.remove(DIST_ERR)));
}
@SuppressWarnings("deprecation")
protected Shape parseShape(String str, SpatialContext ctx) throws ParseException {
// return ctx.readShape(str);//still in Spatial4j 0.4 but will be deleted
return ctx.readShapeFromWkt(str);

View File

@ -22,7 +22,6 @@ import java.util.List;
import java.util.Set;
import org.apache.lucene.search.suggest.InputIterator;
import org.apache.lucene.search.suggest.Lookup;
import org.apache.lucene.search.suggest.jaspell.JaspellTernarySearchTrie.TSTNode;
import org.apache.lucene.store.DataInput;
import org.apache.lucene.store.DataOutput;
import org.apache.lucene.util.BytesRef;
@ -134,52 +133,54 @@ public class JaspellLookup extends Lookup {
private static final byte HI_KID = 0x04;
private static final byte HAS_VALUE = 0x08;
private void readRecursively(DataInput in, TSTNode node) throws IOException {
private void readRecursively(DataInput in, JaspellTernarySearchTrie.TSTNode node)
throws IOException {
node.splitchar = in.readString().charAt(0);
byte mask = in.readByte();
if ((mask & HAS_VALUE) != 0) {
node.data = in.readLong();
}
if ((mask & LO_KID) != 0) {
TSTNode kid = new TSTNode('\0', node);
node.relatives[TSTNode.LOKID] = kid;
JaspellTernarySearchTrie.TSTNode kid = new JaspellTernarySearchTrie.TSTNode('\0', node);
node.relatives[JaspellTernarySearchTrie.TSTNode.LOKID] = kid;
readRecursively(in, kid);
}
if ((mask & EQ_KID) != 0) {
TSTNode kid = new TSTNode('\0', node);
node.relatives[TSTNode.EQKID] = kid;
JaspellTernarySearchTrie.TSTNode kid = new JaspellTernarySearchTrie.TSTNode('\0', node);
node.relatives[JaspellTernarySearchTrie.TSTNode.EQKID] = kid;
readRecursively(in, kid);
}
if ((mask & HI_KID) != 0) {
TSTNode kid = new TSTNode('\0', node);
node.relatives[TSTNode.HIKID] = kid;
JaspellTernarySearchTrie.TSTNode kid = new JaspellTernarySearchTrie.TSTNode('\0', node);
node.relatives[JaspellTernarySearchTrie.TSTNode.HIKID] = kid;
readRecursively(in, kid);
}
}
private void writeRecursively(DataOutput out, TSTNode node) throws IOException {
private void writeRecursively(DataOutput out, JaspellTernarySearchTrie.TSTNode node)
throws IOException {
if (node == null) {
return;
}
out.writeString(new String(new char[] {node.splitchar}, 0, 1));
byte mask = 0;
if (node.relatives[TSTNode.LOKID] != null) mask |= LO_KID;
if (node.relatives[TSTNode.EQKID] != null) mask |= EQ_KID;
if (node.relatives[TSTNode.HIKID] != null) mask |= HI_KID;
if (node.relatives[JaspellTernarySearchTrie.TSTNode.LOKID] != null) mask |= LO_KID;
if (node.relatives[JaspellTernarySearchTrie.TSTNode.EQKID] != null) mask |= EQ_KID;
if (node.relatives[JaspellTernarySearchTrie.TSTNode.HIKID] != null) mask |= HI_KID;
if (node.data != null) mask |= HAS_VALUE;
out.writeByte(mask);
if (node.data != null) {
out.writeLong(((Number) node.data).longValue());
}
writeRecursively(out, node.relatives[TSTNode.LOKID]);
writeRecursively(out, node.relatives[TSTNode.EQKID]);
writeRecursively(out, node.relatives[TSTNode.HIKID]);
writeRecursively(out, node.relatives[JaspellTernarySearchTrie.TSTNode.LOKID]);
writeRecursively(out, node.relatives[JaspellTernarySearchTrie.TSTNode.EQKID]);
writeRecursively(out, node.relatives[JaspellTernarySearchTrie.TSTNode.HIKID]);
}
@Override
public boolean store(DataOutput output) throws IOException {
output.writeVLong(count);
TSTNode root = trie.getRoot();
JaspellTernarySearchTrie.TSTNode root = trie.getRoot();
if (root == null) { // empty tree
return false;
}
@ -190,7 +191,7 @@ public class JaspellLookup extends Lookup {
@Override
public boolean load(DataInput input) throws IOException {
count = input.readVLong();
TSTNode root = new TSTNode('\0', null);
JaspellTernarySearchTrie.TSTNode root = new JaspellTernarySearchTrie.TSTNode('\0', null);
readRecursively(input, root);
trie.setRoot(root);
return true;

View File

@ -328,7 +328,7 @@ public abstract class BaseFieldInfoFormatTestCase extends BaseIndexFileFormatTes
}
if (r.nextBoolean()) {
DocValuesType[] values = DocValuesType.values();
DocValuesType values[] = DocValuesType.values();
type.setDocValuesType(values[r.nextInt(values.length)]);
}

View File

@ -209,7 +209,7 @@ public abstract class BaseSegmentInfoFormatTestCase extends BaseIndexFileFormatT
info.setFiles(Collections.<String>emptySet());
codec.segmentInfoFormat().write(dir, info, IOContext.DEFAULT);
SegmentInfo info2 = codec.segmentInfoFormat().read(dir, "_123", id, IOContext.DEFAULT);
assertIDEquals(id, info2.getId());
assertArrayEquals(id, info2.getId());
dir.close();
}
@ -633,7 +633,7 @@ public abstract class BaseSegmentInfoFormatTestCase extends BaseIndexFileFormatT
// assertSame(expected.getCodec(), actual.getCodec());
assertEquals(expected.getDiagnostics(), actual.getDiagnostics());
assertEquals(expected.maxDoc(), actual.maxDoc());
assertIDEquals(expected.getId(), actual.getId());
assertArrayEquals(expected.getId(), actual.getId());
assertEquals(expected.getUseCompoundFile(), actual.getUseCompoundFile());
assertEquals(expected.getVersion(), actual.getVersion());
assertEquals(expected.getAttributes(), actual.getAttributes());
@ -642,16 +642,6 @@ public abstract class BaseSegmentInfoFormatTestCase extends BaseIndexFileFormatT
/** Returns the versions this SI should test */
protected abstract Version[] getVersions();
/**
* assert that unique id is equal.
*
* @deprecated only exists to be overridden by old codecs that didnt support this
*/
@Deprecated
protected void assertIDEquals(byte expected[], byte actual[]) {
assertArrayEquals(expected, actual);
}
@Override
protected void addRandomFields(Document doc) {
doc.add(new StoredField("foobar", TestUtil.randomSimpleString(random())));

View File

@ -3057,15 +3057,6 @@ public abstract class LuceneTestCase extends Assert {
}
}
/**
* This method is deprecated for a reason. Do not use it. Call {@link #createTempDir()} or {@link
* #createTempDir(String)} or {@link #createTempFile(String, String)}.
*/
@Deprecated
public static Path getBaseTempDirForTestClass() {
return tempFilesCleanupRule.getPerTestClassTempDir();
}
/**
* Creates an empty, temporary folder (when the name of the folder is of no importance).
*
@ -3076,8 +3067,7 @@ public abstract class LuceneTestCase extends Assert {
}
/**
* Creates an empty, temporary folder with the given name prefix under the test class's {@link
* #getBaseTempDirForTestClass()}.
* Creates an empty, temporary folder with the given name prefix.
*
* <p>The folder will be automatically removed after the test class completes successfully. The
* test should close any file handles that would prevent the folder from being removed.
@ -3087,8 +3077,7 @@ public abstract class LuceneTestCase extends Assert {
}
/**
* Creates an empty file with the given prefix and suffix under the test class's {@link
* #getBaseTempDirForTestClass()}.
* Creates an empty file with the given prefix and suffix.
*
* <p>The file will be automatically removed after the test class completes successfully. The test
* should close any file handles that would prevent the folder from being removed.

View File

@ -18,7 +18,15 @@ package org.apache.lucene.analysis;
import java.io.StringReader;
import java.util.HashMap;
import org.apache.lucene.analysis.tokenattributes.*;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.FlagsAttribute;
import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
import org.apache.lucene.analysis.tokenattributes.PayloadAttribute;
import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
import org.apache.lucene.analysis.tokenattributes.PositionLengthAttribute;
import org.apache.lucene.analysis.tokenattributes.TermFrequencyAttribute;
import org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute;
import org.apache.lucene.analysis.tokenattributes.TypeAttribute;
import org.apache.lucene.util.Attribute;
import org.apache.lucene.util.AttributeImpl;
import org.apache.lucene.util.AttributeReflector;
@ -26,7 +34,6 @@ import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.TestUtil;
@Deprecated
public class TestToken extends LuceneTestCase {
public void testCtor() throws Exception {
@ -49,20 +56,20 @@ public class TestToken extends LuceneTestCase {
char[] content = "hello".toCharArray();
t.copyBuffer(content, 0, 5);
char[] buf = t.buffer();
Token copy = TestCharTermAttributeImpl.assertCloneIsEqual(t);
Token copy = assertCloneIsEqual(t);
assertEquals(t.toString(), copy.toString());
assertNotSame(buf, copy.buffer());
BytesRef pl = new BytesRef(new byte[] {1, 2, 3, 4});
t.setPayload(pl);
copy = TestCharTermAttributeImpl.assertCloneIsEqual(t);
copy = assertCloneIsEqual(t);
assertEquals(pl, copy.getPayload());
assertNotSame(pl, copy.getPayload());
}
public void testCopyTo() throws Exception {
Token t = new Token();
Token copy = TestCharTermAttributeImpl.assertCopyIsEqual(t);
Token copy = assertCopyIsEqual(t);
assertEquals("", t.toString());
assertEquals("", copy.toString());
@ -71,13 +78,13 @@ public class TestToken extends LuceneTestCase {
char[] content = "hello".toCharArray();
t.copyBuffer(content, 0, 5);
char[] buf = t.buffer();
copy = TestCharTermAttributeImpl.assertCopyIsEqual(t);
copy = assertCopyIsEqual(t);
assertEquals(t.toString(), copy.toString());
assertNotSame(buf, copy.buffer());
BytesRef pl = new BytesRef(new byte[] {1, 2, 3, 4});
t.setPayload(pl);
copy = TestCharTermAttributeImpl.assertCopyIsEqual(t);
copy = assertCopyIsEqual(t);
assertEquals(pl, copy.getPayload());
assertNotSame(pl, copy.getPayload());
}
@ -162,4 +169,21 @@ public class TestToken extends LuceneTestCase {
}
});
}
public static <T extends AttributeImpl> T assertCloneIsEqual(T att) {
@SuppressWarnings("unchecked")
T clone = (T) att.clone();
assertEquals("Clone must be equal", att, clone);
assertEquals("Clone's hashcode must be equal", att.hashCode(), clone.hashCode());
return clone;
}
public static <T extends AttributeImpl> T assertCopyIsEqual(T att) throws Exception {
@SuppressWarnings("unchecked")
T copy = (T) att.getClass().getConstructor().newInstance();
att.copyTo(copy);
assertEquals("Copied instance must be equal", att, copy);
assertEquals("Copied instance's hashcode must be equal", att.hashCode(), copy.hashCode());
return copy;
}
}