Version featureVersion;
if(feature instanceof VersionEnum) // Explicit version.
{featureVersion = ((VersionEnum)feature).getVersion();}
else // Implicit version (element annotation).
{
PDF annotation;
{
if(feature instanceof String) // Property name.
{
BeanInfo classInfo;
try
{classInfo = Introspector.getBeanInfo(getClass());}
catch(IntrospectionException e)
{throw new RuntimeException(e);}
for(PropertyDescriptor property : classInfo.getPropertyDescriptors())
{
if(feature.equals(property.getName()))
{
feature = property.getReadMethod();
break;
}
}
}
else if(feature instanceof Enum<?>) // Enum constant.
{
try
{feature = feature.getClass().getField(((Enum<?>)feature).name());}
catch(Exception e)
{throw new RuntimeException(e);}
}
//TODO:remove?
// else if(feature == null) // Implicit feature.
// {
// try
// {
// /*
// NOTE: I know this is a somewhat weird (considering both OO design and performance) technique,
// but at the moment I couldn't figure out a better solution for dynamically retrieving
// the caller context's annotations in case of no arguments.
// */
// StackTraceElement callerStackElement = (StackTraceElement)Thread.currentThread().getStackTrace()[2];
// Class<?> callerClass = Class.forName(callerStackElement.getClassName());
// String callerMethodName = callerStackElement.getMethodName();
// for(Method method : callerClass.getMethods())
// {
// if(method.getName().equals(callerMethodName))
// {
// feature = method; // NOTE: I assume that any overload of the same method conforms to the same version.
// break;
// }
// }
// }
// catch(Exception e)
// {throw new RuntimeException(e);}
// }
if(!(feature instanceof AnnotatedElement))
throw new IllegalArgumentException("Feature type '" + feature.getClass().getName() + "' not supported.");
while(true)
{
annotation = ((AnnotatedElement)feature).getAnnotation(PDF.class);
if(annotation != null)
break;
if(feature instanceof Member)
{feature = ((Member)feature).getDeclaringClass();}
else if(feature instanceof Class<?>)
{
Class<?> containerClass = ((Class<?>)feature).getDeclaringClass();
feature = (containerClass != null ? containerClass : ((Class<?>)feature).getPackage());
}
else // Element hierarchy walk complete.
return; // NOTE: As no annotation is available, we assume the feature has no specific compatibility requirements.
}
}
featureVersion = annotation.value().getVersion();
}
// Is the feature version compatible?
if(getDocument().getVersion().compareTo(featureVersion) >= 0)
return;