// Path: src/main/java/com/timgroup/karg/reference/Getter.java
// public interface Getter<O, T> {
//     T get(O object);
// }
// 
// Path: src/main/java/com/timgroup/karg/reference/Lens.java
// public interface Lens<O, T> extends Getter<O, T>, Setter<O, T> { }
// 
// Path: src/main/java/com/timgroup/karg/reference/Setter.java
// public interface Setter<O, T> {
//     T set(O object, T newValue);
// }


import com.google.common.base.Preconditions;
import com.timgroup.karg.reference.Getter;
import com.timgroup.karg.reference.Lens;
import com.timgroup.karg.reference.Setter;
package com.timgroup.karg.reflection;


public class ReflectiveAccessorFactory<O> {
    
    private final AccessorCatalogue<O> catalogue;
    
    public static <O> ReflectiveAccessorFactory<O> forClass(Class<O> targetClass) {
        return new ReflectiveAccessorFactory<O>(targetClass);
    }
    
    private ReflectiveAccessorFactory(Class<O> targetClass) {
        catalogue = AccessorCatalogue.forClass(targetClass);
    }
    
    public <T> Lens<O, T> getLens(final String propertyName) {
        Lens<O, T> lens = catalogue.getAttribute(propertyName);
        Preconditions.checkNotNull(lens, "No writable property or field \"%s\"", propertyName);
        return lens;
    }
    
// Path: src/main/java/com/timgroup/karg/reference/Getter.java
// public interface Getter<O, T> {
//     T get(O object);
// }
// 
// Path: src/main/java/com/timgroup/karg/reference/Lens.java
// public interface Lens<O, T> extends Getter<O, T>, Setter<O, T> { }
// 
// Path: src/main/java/com/timgroup/karg/reference/Setter.java
// public interface Setter<O, T> {
//     T set(O object, T newValue);
// }


// Path: src/main/java/com/timgroup/karg/reflection/ReflectiveAccessorFactory.java
import com.google.common.base.Preconditions;
import com.timgroup.karg.reference.Getter;
import com.timgroup.karg.reference.Lens;
import com.timgroup.karg.reference.Setter;

package com.timgroup.karg.reflection;


public class ReflectiveAccessorFactory<O> {
    
    private final AccessorCatalogue<O> catalogue;
    
    public static <O> ReflectiveAccessorFactory<O> forClass(Class<O> targetClass) {
        return new ReflectiveAccessorFactory<O>(targetClass);
    }
    
    private ReflectiveAccessorFactory(Class<O> targetClass) {
        catalogue = AccessorCatalogue.forClass(targetClass);
    }
    
    public <T> Lens<O, T> getLens(final String propertyName) {
        Lens<O, T> lens = catalogue.getAttribute(propertyName);
        Preconditions.checkNotNull(lens, "No writable property or field \"%s\"", propertyName);
        return lens;
    }
    
    public <T> Getter<O, T> getGetter(String propertyName) {