package de.fau.cs.mad.fablab.android.model; import com.j256.ormlite.dao.RuntimeExceptionDao; import com.j256.ormlite.stmt.DeleteBuilder; import com.j256.ormlite.stmt.QueryBuilder; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; import de.fau.cs.mad.fablab.android.viewmodel.common.ObservableArrayList; import de.fau.cs.mad.fablab.rest.core.ICal; import de.fau.cs.mad.fablab.rest.myapi.ICalApi; import retrofit.Callback; import retrofit.RetrofitError; import retrofit.client.Response; /*** * Handles the connection to the rest server to receive ICals. * Stores the results and fires events on success */ public class ICalModel { private static final int ELEMENT_COUNT = 10; private ObservableArrayList<ICal> mICals; private ICalApi mICalApi; private boolean mICalsRequested; private RuntimeExceptionDao<ICal, Long> mICalDao; private long mTimeStampLastUpdate; private String mDateLastDisplayedICalsString; private boolean mEndReached; private Callback<List<ICal>> mICalApiCallback = new Callback<List<ICal>>() { @Override public void success(List<ICal> iCals, Response response) { mICals.addAll(iCals); mICalsRequested = false; for(ICal i : iCals) { createIfNotExists(mICalDao, i); } mDateLastDisplayedICalsString = mICals.get(mICals.size()-1).getStart(); } @Override public void failure(RetrofitError error) { mICalsRequested = false; if(error.getMessage().equals("404 Not Found")) { mEndReached = true; } } }; private Callback<Long> mICalApiCallbackUpdate = new Callback<Long>() { @Override public void success(Long lastUpdate, Response response) { if(lastUpdate > mTimeStampLastUpdate) { mEndReached = false; mTimeStampLastUpdate = lastUpdate; clearDao(mICalDao); mICals.clear(); fetchNextICals(); } } @Override public void failure(RetrofitError error) { mICalsRequested = false; } }; @Inject public ICalModel(ICalApi api, RuntimeExceptionDao<ICal, Long> iCalDao){ mICalApi = api; mICalDao = iCalDao; mICals = new ObservableArrayList<>(); mICalsRequested = false; mTimeStampLastUpdate = 0; mEndReached = false; mDateLastDisplayedICalsString = ""; fetchNextICals(); } public void fetchNextICals() { //check whether to get news from database or server if (!mICalsRequested && mICals.size() + ELEMENT_COUNT > mICalDao.countOf() && !mEndReached) { mICalsRequested = true; mICalApi.find(mICals.size(), ELEMENT_COUNT, mICalApiCallback); } else if (!mICalsRequested && !mEndReached) { mICalsRequested = true; List<ICal> fetchedICals; //get next Element_count elements from database QueryBuilder<ICal, Long> queryBuilder = mICalDao.queryBuilder(); //sort elements in ascending order according to startdate and only return //ELEMENT_COUNT iCals queryBuilder.orderBy("start", true).limit(ELEMENT_COUNT); try { queryBuilder.where().gt("start", mDateLastDisplayedICalsString); fetchedICals = mICalDao.query(queryBuilder.prepare()); mICals.addAll(fetchedICals); mDateLastDisplayedICalsString = mICals.get(mICals.size()-1).getStart(); } catch (SQLException e) { e.printStackTrace(); } mICalsRequested = false; } } public ObservableArrayList<ICal> getICalsList() { return mICals; } public void checkForUpdates() { mICalApi.lastUpdate(mICalApiCallbackUpdate); deleteOldICals(mICalDao); } private void createIfNotExists(RuntimeExceptionDao<ICal, Long> iCalDao, ICal iCal) { List<ICal> retrievedICals = new ArrayList<>(); QueryBuilder<ICal, Long> queryBuilder = iCalDao.queryBuilder(); try { queryBuilder.where().eq("summery", iCal.getSummery()).and().eq("start", iCal.getStart()) .and().eq("end", iCal.getEnd()); } catch (SQLException e) { e.printStackTrace(); } if(retrievedICals.size() == 0) { iCalDao.create(iCal); } } private void deleteOldICals(RuntimeExceptionDao<ICal, Long> iCalDao) { DeleteBuilder<ICal, Long> deleteBuilder = iCalDao.deleteBuilder(); try { deleteBuilder.where().lt("end", System.currentTimeMillis()); iCalDao.delete(deleteBuilder.prepare()); } catch (SQLException e) { e.printStackTrace(); } } private void clearDao(RuntimeExceptionDao<ICal, Long> iCalDao) { List<ICal> retrievedICals = iCalDao.queryForAll(); for(ICal i : retrievedICals) { iCalDao.delete(i); } } }