// Path: framework/src/main/java/com/kifile/android/cornerstone/core/AbstractFetcherConverter.java
// public abstract class AbstractFetcherConverter<FROM, TO> implements DataFetcher<TO> {
// 
//     private DataFetcher<FROM> mProxy;
// 
//     /**
//      * Wrap the DataFetcher will be transformed.
//      *
//      * @param proxy
//      */
//     public AbstractFetcherConverter(DataFetcher<FROM> proxy) {
//         mProxy = proxy;
//     }
// 
//     @Override
//     public TO fetch() throws FetchException, ConvertException {
//         FROM data = mProxy.fetch();
//         if (data == null) {
//             throw new FetchException("Proxy return null.");
//         }
//         return convert(data);
//     }
// 
//     protected abstract TO convert(@NonNull FROM from) throws ConvertException;
// 
// }
// 
// Path: framework/src/main/java/com/kifile/android/cornerstone/core/ConvertException.java
// public class ConvertException extends Exception {
// 
//     private Object o;
// 
//     public ConvertException() {
//     }
// 
//     public ConvertException(String detailMessage) {
//         super(detailMessage);
//     }
// 
//     public ConvertException(String detailMessage, Throwable throwable) {
//         super(detailMessage, throwable);
//     }
// 
//     public ConvertException(Throwable throwable) {
//         super(throwable);
//     }
// 
//     public void setError(Object error) {
//         o = error;
//     }
// 
//     public Object getError() {
//         return o;
//     }
// }
// 
// Path: framework/src/main/java/com/kifile/android/cornerstone/core/DataFetcher.java
// public interface DataFetcher<DATA> {
// 
//     /**
//      * Fetch data.
//      *
//      * @return If fetch successful, return the data.
//      * @throws FetchException   Throw FetchException when you cannot fetch a data.
//      * @throws ConvertException Throw ConvertException when you cannot convert the data to another type.
//      */
//     DATA fetch() throws FetchException, ConvertException;
// }


import android.database.Cursor;
import android.support.annotation.NonNull;
import com.kifile.android.cornerstone.core.AbstractFetcherConverter;
import com.kifile.android.cornerstone.core.ConvertException;
import com.kifile.android.cornerstone.core.DataFetcher;
import com.kifile.android.cornerstone.impl.annotations.Property;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
package com.kifile.android.cornerstone.impl.fetchers;




/**
 * Use annotation build result.
 * <p/>
 * Created by kifile on 15/9/10.
 */
public class AnnotationCursorConverter<DATA> extends AbstractFetcherConverter<Cursor, List<DATA>> {

    private final Class<DATA> mDataClazz;

    private Map<String, Field> mAnnotationMap = new HashMap<>();

    /**
     * Wrap the DataFetcher will be transformed.
     *
     * @param proxy
     */
    public AnnotationCursorConverter(DataFetcher<Cursor> proxy, Class<DATA> clazz) {
        super(proxy);
        mDataClazz = clazz;
        processAnnotation();
    }

    private void processAnnotation() {
        Field[] fields = mDataClazz.getFields();
        if (fields != null) {
            for (Field field : fields) {
                Property property = field.getAnnotation(Property.class);
                if (property != null) {
                    String name = property.name();
                    mAnnotationMap.put(name, field);
                }

            }
        }
    }

    @Override
// Path: framework/src/main/java/com/kifile/android/cornerstone/core/AbstractFetcherConverter.java
// public abstract class AbstractFetcherConverter<FROM, TO> implements DataFetcher<TO> {
// 
//     private DataFetcher<FROM> mProxy;
// 
//     /**
//      * Wrap the DataFetcher will be transformed.
//      *
//      * @param proxy
//      */
//     public AbstractFetcherConverter(DataFetcher<FROM> proxy) {
//         mProxy = proxy;
//     }
// 
//     @Override
//     public TO fetch() throws FetchException, ConvertException {
//         FROM data = mProxy.fetch();
//         if (data == null) {
//             throw new FetchException("Proxy return null.");
//         }
//         return convert(data);
//     }
// 
//     protected abstract TO convert(@NonNull FROM from) throws ConvertException;
// 
// }
// 
// Path: framework/src/main/java/com/kifile/android/cornerstone/core/ConvertException.java
// public class ConvertException extends Exception {
// 
//     private Object o;
// 
//     public ConvertException() {
//     }
// 
//     public ConvertException(String detailMessage) {
//         super(detailMessage);
//     }
// 
//     public ConvertException(String detailMessage, Throwable throwable) {
//         super(detailMessage, throwable);
//     }
// 
//     public ConvertException(Throwable throwable) {
//         super(throwable);
//     }
// 
//     public void setError(Object error) {
//         o = error;
//     }
// 
//     public Object getError() {
//         return o;
//     }
// }
// 
// Path: framework/src/main/java/com/kifile/android/cornerstone/core/DataFetcher.java
// public interface DataFetcher<DATA> {
// 
//     /**
//      * Fetch data.
//      *
//      * @return If fetch successful, return the data.
//      * @throws FetchException   Throw FetchException when you cannot fetch a data.
//      * @throws ConvertException Throw ConvertException when you cannot convert the data to another type.
//      */
//     DATA fetch() throws FetchException, ConvertException;
// }


// Path: framework/src/main/java/com/kifile/android/cornerstone/impl/fetchers/AnnotationCursorConverter.java
import android.database.Cursor;
import android.support.annotation.NonNull;
import com.kifile.android.cornerstone.core.AbstractFetcherConverter;
import com.kifile.android.cornerstone.core.ConvertException;
import com.kifile.android.cornerstone.core.DataFetcher;
import com.kifile.android.cornerstone.impl.annotations.Property;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

package com.kifile.android.cornerstone.impl.fetchers;




/**
 * Use annotation build result.
 * <p/>
 * Created by kifile on 15/9/10.
 */
public class AnnotationCursorConverter<DATA> extends AbstractFetcherConverter<Cursor, List<DATA>> {

    private final Class<DATA> mDataClazz;

    private Map<String, Field> mAnnotationMap = new HashMap<>();

    /**
     * Wrap the DataFetcher will be transformed.
     *
     * @param proxy
     */
    public AnnotationCursorConverter(DataFetcher<Cursor> proxy, Class<DATA> clazz) {
        super(proxy);
        mDataClazz = clazz;
        processAnnotation();
    }

    private void processAnnotation() {
        Field[] fields = mDataClazz.getFields();
        if (fields != null) {
            for (Field field : fields) {
                Property property = field.getAnnotation(Property.class);
                if (property != null) {
                    String name = property.name();
                    mAnnotationMap.put(name, field);
                }

            }
        }
    }

    @Override
    protected List<DATA> convert(@NonNull Cursor cursor) throws ConvertException {