All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.formos.tapestry.testify.internal.ForComponentsInjectionProvider Maven / Gradle / Ivy

package com.formos.tapestry.testify.internal;

import java.lang.annotation.Annotation;

import org.apache.tapestry5.annotations.Service;
import org.apache.tapestry5.internal.services.ComponentClassCache;
import org.apache.tapestry5.ioc.AnnotationProvider;
import org.apache.tapestry5.ioc.ObjectLocator;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.ioc.annotations.Symbol;
import org.apache.tapestry5.ioc.annotations.Value;
import org.apache.tapestry5.ioc.services.MasterObjectProvider;
import org.apache.tapestry5.model.MutableComponentModel;
import org.apache.tapestry5.plastic.FieldConduit;
import org.apache.tapestry5.plastic.InstanceContext;
import org.apache.tapestry5.plastic.PlasticField;
import org.apache.tapestry5.services.transform.InjectionProvider2;

public class ForComponentsInjectionProvider implements InjectionProvider2 {
    private final ObjectsForComponentsStore objectStore;
    private final MasterObjectProvider masterObjectProvider;
    private final ObjectLocator locator;
    private final ComponentClassCache classCache;


    public ForComponentsInjectionProvider(
            MasterObjectProvider masterObjectProvider, ObjectLocator locator,
            ObjectsForComponentsStore objectStore,
            ComponentClassCache classCache) {
		assert objectStore != null;
        assert masterObjectProvider != null;
        assert locator != null;

        this.objectStore = objectStore;
        this.masterObjectProvider = masterObjectProvider;
        this.locator = locator;
        this.classCache = classCache;
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public boolean provideInjection(PlasticField field, ObjectLocator locator, MutableComponentModel componentModel) {
        if (canHandle(field)) {
            Service service = field.getAnnotation(Service.class);
            final String serviceId = service == null ? ObjectsForComponentsStore.NO_ID : service.value();
            final Class fieldType = classCache.forName(field.getTypeName());
            final Object valueInjectedByTapestry = findTapestrysInjectedValue(field, fieldType);

            field.setConduit(new FieldConduit() {
				public Object get(Object instance, InstanceContext context) {
                    Object testDouble = objectStore.get(fieldType, serviceId);
                    return testDouble == null ? valueInjectedByTapestry : testDouble;
				}
				public void set(Object instance, InstanceContext context, Object newValue) {
                    throw new RuntimeException("Field is read-only");
				}
			});
            return true;
        }
        return false;
    }


    public static boolean canHandle(PlasticField field) {
        return field.getAnnotation(Inject.class) != null &&
               field.getAnnotation(Symbol.class) == null &&
               field.getAnnotation(Value.class) == null;
    }


    private Object findTapestrysInjectedValue(final PlasticField field, Class fieldType) {
        try {
            AnnotationProvider annotationProvider = new AnnotationProvider() {
                public  T getAnnotation(Class annotationClass) {
                    return field.getAnnotation(annotationClass);
                }
            };


            Object result = masterObjectProvider.provide(fieldType, annotationProvider, this.locator, false);
            if (result == null) {
                result = this.locator.getService(fieldType);
            }
            return result;
        } catch (RuntimeException e) {
            // We get this exception if we try to find a service that does not exist
            return null;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy