001/* 002 * SPDX-FileCopyrightText: none 003 * SPDX-License-Identifier: CC0-1.0 004 */ 005 006package gov.nist.secauto.metaschema.databind.model; 007 008import java.lang.reflect.Field; 009import java.lang.reflect.Type; 010 011import edu.umd.cs.findbugs.annotations.NonNull; 012 013@FunctionalInterface 014public interface IFeatureJavaField extends IValuedMutable { 015 016 /** 017 * Gets the bound Java field associated with this instance. 018 * 019 * @return the Java field 020 */ 021 @NonNull 022 Field getField(); 023 024 /** 025 * Get the actual Java type of the underlying bound object. 026 * <p> 027 * This may be the same as the what is returned by {@link #getItemType()}, or 028 * may be a Java collection class. 029 * 030 * @return the raw type of the bound object 031 */ 032 @SuppressWarnings("null") 033 @NonNull 034 default Type getType() { 035 return getField().getGenericType(); 036 } 037 038 /** 039 * Get the item type of the bound object. An item type is the primitive or 040 * specialized type that represents that data associated with this binding. 041 * 042 * @return the item type of the bound object 043 */ 044 @NonNull 045 default Class<?> getItemType() { 046 return (Class<?>) getType(); 047 } 048 049 @Override 050 default Object getValue(@NonNull Object parent) { 051 Field field = getField(); 052 // boolean accessable = field.canAccess(parent); 053 // field.setAccessible(true); // NOPMD - intentional 054 Object retval; 055 try { 056 Object result = field.get(parent); 057 retval = result; 058 } catch (IllegalArgumentException | IllegalAccessException ex) { 059 throw new IllegalArgumentException( 060 String.format("Unable to get the value of field '%s' in class '%s'.", field.getName(), 061 field.getDeclaringClass().getName()), 062 ex); 063 // } finally { 064 // field.setAccessible(accessable); // NOPMD - intentional 065 } 066 return retval; 067 } 068 069 @Override 070 default void setValue(@NonNull Object parentObject, Object value) { 071 Field field = getField(); 072 // boolean accessable = field.canAccess(parentObject); 073 // field.setAccessible(true); // NOPMD - intentional 074 try { 075 field.set(parentObject, value); 076 } catch (IllegalArgumentException | IllegalAccessException ex) { 077 throw new IllegalArgumentException( 078 String.format( 079 "Unable to set the value of field '%s' in class '%s'." + 080 " Perhaps this is a data type adapter problem on the declared class?", 081 field.getName(), 082 field.getDeclaringClass().getName()), 083 ex); 084 // } finally { 085 // field.setAccessible(accessable); // NOPMD - intentional 086 } 087 } 088 089}