package fr.imag.adele.apam.declarations.instrumentation; import fr.imag.adele.apam.declarations.AtomicImplementationDeclaration; import fr.imag.adele.apam.declarations.references.resources.ResourceReference; import fr.imag.adele.apam.declarations.references.resources.UnknownReference; /** * An injected field declaration * */ public abstract class InjectedField extends Instrumentation { protected final String field; private final Lazy<String> fieldType = new Lazy<String>() { @Override protected String evaluate(InstrumentedClass instrumentedClass) { try { return instrumentedClass.getFieldType(field); } catch (NoSuchFieldException e) { return null; } }; }; private final Lazy<Boolean> fieldMultiplicity = new Lazy<Boolean>() { @Override protected Boolean evaluate(InstrumentedClass instrumentedClass) { try { return instrumentedClass.isCollectionField(field); } catch (NoSuchFieldException e) { return false; } }; }; protected InjectedField(AtomicImplementationDeclaration implementation, String field) { super(implementation.getReference(), implementation.getImplementationClass()); this.field = field; } @Override public String getName() { return field; } public ResourceReference getType() { String target = fieldType.get(); return target != null && !target.equals(InstrumentedClass.UNKNOWN_TYPE)? generateReference(target) : new UnknownReference(generateReference(this.toString())); } public boolean isCollection() { return fieldMultiplicity.get(); } /** * Generates a new reference of the appropriate class for the specified, required resource */ protected abstract ResourceReference generateReference(String type); @Override public boolean isValidInstrumentation() { return fieldType.get() != null; } @Override public String toString() { return "field " + getName(); } @Override public int hashCode() { return field.hashCode(); } @Override public boolean equals(Object object) { if (this == object) return true; if (object == null) return false; if (!(object instanceof InjectedField)) return false; InjectedField that = (InjectedField) object; return this.field.equals(that.field); } }