2015-11-17 5 views
7

Я пытаюсь создать свою структуру классов.
Я покажу свою реальную структуру, чтобы быть более конкретным.Как создать класс с помощью T и List <T>

Я пишу приложения с поддержкой автономного режима, так что я решил реализовать свой ETag механизм кэширования при помощи Robospice и GreenDao ОРМ.

Мне нужно только кэш GET запросов.

Во-первых, мои запросы должны расширить базовый запрос (не мое), в моем случае RetrofitSpiceRequest<T, V>

T is type of return data 
V is service type, in my case I am using Retrofit. 

Проблема состоит в том, что тип возвращаемого значения не List of T типов по умолчанию, и мне нужно создать подкласс, который расширяет массив T объекты, которые используют его как возвращаемый тип.

Что-то вроде этого

public class City { 
.... 
.... 
.... 
    public static class List extends ArrayList<City> { 
    ..... 
    ..... 
    } 

} 

И использовать City.List в качестве возвращаемого типа.

Но у меня есть мой DAO объявлен следующий

public class CityDao extends AbstractDao<City, Long> { 

} 

В каждом запросе (GET) Мне нужно иметь определенный DAO в качестве члена для того, чтобы данные кэшей, если он отличается от данных сервера. Или загрузите данные из локальной базы данных, если соединение отсутствует.

Проблема заключается в том, что запрос генерируется типом T, который в основном является списком, City.List в моем случае, некоторых объектов, но мой dao генерируется, например, E-типом, который является City в моем случае.

Я хочу создать метод, как это

public AbastractDao<T,Long> getRequestDao() { 

} 

Но насколько мой запрос возвращает City.List, я не знаю, как generify этого класса, я чувствую, что это не возможно, но сейчас нет идей ,
В случае неиспользования общего метода дао, я должен дублировать код, как этот

@Override 
    public void insertReceivedData(City.List received) { 
     mCityDao.insertOrReplaceInTx(received); 
    } 

@Override 
    public City.List getCachedData() { 
     if (mFilterMap != null && mFilterMap.size() > 0) { 
      return (City.List) mCityDao.loadAll(); 
     } else { 
      WhereCondition[] whereConditions = QueryUtils.convertPropertyMapToConditionalArray(mFilterMap); 
      return (City.List) mCityDao.queryBuilder().where(whereConditions[0], Arrays.copyOfRange(whereConditions, 1, whereConditions.length)).list(); 
     } 
    } 

В каждом запросе

Пожалуйста, поделитесь своими идеями.

Спасибо.

+0

ли я понимаю, это правильно, вы хотите, чтобы ваши услуги, чтобы автоматически вводить и вызывать надлежащую Dao? –

+0

Да, но проблема в том, что Dao является расширенным AbstractDao и в основном используется как AbstractDao где T - тип, который сопоставляется с таблицей в моем городе, но мне нужно получить список городов, поскольку запрос возвращает объект класс TI должен создать пользовательский класс MyCityList расширяет ArrayList и вот в чем проблема. – CROSP

ответ

2

Я в конечном итоге со следующим решением. Это не так хорошо, как я хотел, но он работает и лучше, чем дублирование кода.

Мой базовый запрос класс.

public abstract class BaseGetRequest<L extends List<T>, T, V> extends RetrofitSpiceRequest<L, V> implements FilterableRequest { 
    // Context 
    protected Context mContext; 
    // Filter used in request and in queries 
    protected Map<Property, String> mFilterMap; 
    // Session provided Singletone 
    protected DaoSessionProvider mSessionProvider; 

    public BaseGetRequest(Class<L> clazz, Class<V> retrofitedInterfaceClass, Context context, Map<Property, String> filterMap) { 
     super(clazz, retrofitedInterfaceClass); 
     mContext = context; 
     mFilterMap = filterMap; 
     mSessionProvider = ((DaoSessionProvider) mContext.getApplicationContext()); 
     // TODO determine required retry count 
     setRetryPolicy(new RetryPolicy() { 
      @Override 
      public int getRetryCount() { 
       return 0; 
      } 

      @Override 
      public void retry(SpiceException e) { 

      } 

      @Override 
      public long getDelayBeforeRetry() { 
       return 0; 
      } 
     }); 
    } 

    protected WhereCondition[] getWhereConditions() { 
     return QueryUtils.convertPropertyMapToConditionalArray(mFilterMap); 
    } 

    public BaseGetRequestV2(Class<L> clazz, Class<V> retrofitedInterfaceClass, Context context) { 
     this(clazz, retrofitedInterfaceClass, context, null); 
    } 

    public abstract AbstractDao<T, Long> getDao(); 

    public abstract L createDataList(List<T> list); 

    public L getCachedData() { 
     if (mFilterMap != null && mFilterMap.size() > 0) { 
      WhereCondition[] whereConditions = getWhereConditions(); 
      return createDataList(getDao().queryBuilder().where(whereConditions[0], Arrays.copyOfRange(whereConditions, 1, whereConditions.length)).list()); 
     } else { 
      return createDataList(getDao().loadAll()); 
     } 
    } 

    public abstract L getData(); 

    @Override 
    public Map<Property, String> getFilterMap() { 
     return mFilterMap; 
    } 

    public Map<String, String> getStringMap() { 
     return QueryUtils.convertPropertyMapToString(mFilterMap); 
    } 

    @Override 
    public L loadDataFromNetwork() throws Exception { 
     L receivedData = null; 
     try { 
      receivedData = getData(); 
      WhereCondition[] conditions = getWhereConditions(); 
      getDao().queryBuilder().where(conditions[0],Arrays.copyOfRange(conditions, 1, conditions.length)).buildDelete().executeDeleteWithoutDetachingEntities(); 
      getDao().insertOrReplaceInTx(receivedData); 
     } catch (Exception ex) { 
      receivedData = getCachedData(); 
     } 
     return receivedData; 
    } 
} 

И я могу расширить этот класс

общественного класса NewsRequest расширяет BaseGetRequest { общественности статической конечной строки TARGET_URL = "/ Новости"; NewsArticleDao mNewsArticleDao;

public NewsRequest(Context context) { 
    this(context, null); 
} 

public NewsRequest(Context context, Map<Property, String> filterMap) { 
    super(NewsArticle.List.class, API.class, context, filterMap); 
    mNewsArticleDao = mSessionProvider.getDaoSession().getNewsArticleDao(); 
} 

@Override 
public AbstractDao<NewsArticle, Long> getDao() { 
    return mNewsArticleDao; 
} 

@Override 
public NewsArticle.List createDataList(List<NewsArticle> list) { 
    return new NewsArticle.List(list); 
} 

@Override 
public NewsArticle.List getData() { 
    return getService().getNews(getStringMap()); 
} 

}

+0

Отличный человек – ketazafor