AbstractAttribute implements Attribute<O, A> { static <O> Class<O> readGenericObjectType(Class<?> attributeClass, String attributeName) { try { ParameterizedType superclass = (ParameterizedType) attributeClass.getGenericSuperclass(); @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"}) Type actualType = superclass.getActualTypeArguments()[0]; Class<O> cls; if (actualType instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType)actualType; @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"}) Class<O> actualClass = (Class<O>) parameterizedType.getRawType(); cls = actualClass; } else { @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"}) Class<O> actualClass = (Class<O>) actualType; cls = actualClass; } return cls; } catch (Exception e) { String attributeClassStr = attributeName.startsWith("<Unnamed attribute, class ") ? "" : " (" + attributeClass + ")"; throw new IllegalStateException("Attribute '" + attributeName + "'" + attributeClassStr + " is invalid, cannot read generic type information from it. Attributes should typically EITHER be declared in code with generic type information as a (possibly anonymous) subclass of one of the provided attribute types, OR you can use a constructor of the attribute which allows the types to be specified manually."); } } AbstractAttribute();  AbstractAttribute(String attributeName); protected  AbstractAttribute(Class<O> objectType, Class<A> attributeType); protected  AbstractAttribute(Class<O> objectType, Class<A> attributeType, String attributeName); @Override Class<O> getObjectType(); @Override Class<A> getAttributeType(); @Override String getAttributeName(); @Override String toString(); @Override boolean equals(Object o); boolean canEqual(Object other); @Override int hashCode();  }
@Test public void testReadGenericObjectType() throws Exception { Assert.assertEquals(Integer.class, AbstractAttribute.readGenericObjectType(ValidAttribute.class, "foo")); Assert.assertEquals(Set.class, AbstractAttribute.readGenericObjectType(ValidAttributeWithParameterizedTypes.class, "foo")); }
@Test(expected = IllegalStateException.class) public void testReadGenericObjectType_InvalidAttribute() throws Exception { AbstractAttribute.readGenericObjectType(InvalidAttribute.class, "foo"); }