From 328c72ec2206df25c643bc5dbd6854086faadab5 Mon Sep 17 00:00:00 2001 From: Jo Grimstad Date: Fri, 2 Jun 2017 21:31:25 +0200 Subject: [PATCH 1/5] #409 Add StoryBook greenDAO entity --- contentprovider/build.gradle | 2 +- .../contentprovider/dao/DaoMaster.java | 3 + .../contentprovider/dao/DaoSession.java | 14 + .../contentprovider/dao/StoryBookDao.java | 284 ++++++++++++++++++ .../dao/converter/GradeLevelConverter.java | 13 +- .../model/content/StoryBook.java | 167 ++++++++-- 6 files changed, 445 insertions(+), 38 deletions(-) create mode 100644 contentprovider/src/main/java/org/literacyapp/contentprovider/dao/StoryBookDao.java diff --git a/contentprovider/build.gradle b/contentprovider/build.gradle index 69e28df..93bc30d 100644 --- a/contentprovider/build.gradle +++ b/contentprovider/build.gradle @@ -49,7 +49,7 @@ dependencies { }) testCompile 'junit:junit:4.12' - compile 'org.literacyapp:literacyapp-model:1.1.41' + compile 'org.literacyapp:literacyapp-model:1.1.47' compile 'org.greenrobot:greendao:3.2.0' compile 'com.android.support:appcompat-v7:23.4.0' } diff --git a/contentprovider/src/main/java/org/literacyapp/contentprovider/dao/DaoMaster.java b/contentprovider/src/main/java/org/literacyapp/contentprovider/dao/DaoMaster.java index 9ea6f9b..c23d1cd 100644 --- a/contentprovider/src/main/java/org/literacyapp/contentprovider/dao/DaoMaster.java +++ b/contentprovider/src/main/java/org/literacyapp/contentprovider/dao/DaoMaster.java @@ -45,6 +45,7 @@ public static void createAllTables(Database db, boolean ifNotExists) { StudentDao.createTable(db, ifNotExists); StudentImageDao.createTable(db, ifNotExists); StudentImageFeatureDao.createTable(db, ifNotExists); + StoryBookDao.createTable(db, ifNotExists); } /** Drops underlying database table using DAOs. */ @@ -73,6 +74,7 @@ public static void dropAllTables(Database db, boolean ifExists) { StudentDao.dropTable(db, ifExists); StudentImageDao.dropTable(db, ifExists); StudentImageFeatureDao.dropTable(db, ifExists); + StoryBookDao.dropTable(db, ifExists); } /** @@ -115,6 +117,7 @@ public DaoMaster(Database db) { registerDaoClass(StudentDao.class); registerDaoClass(StudentImageDao.class); registerDaoClass(StudentImageFeatureDao.class); + registerDaoClass(StoryBookDao.class); } public DaoSession newSession() { diff --git a/contentprovider/src/main/java/org/literacyapp/contentprovider/dao/DaoSession.java b/contentprovider/src/main/java/org/literacyapp/contentprovider/dao/DaoSession.java index c04cfff..7bd0bb4 100644 --- a/contentprovider/src/main/java/org/literacyapp/contentprovider/dao/DaoSession.java +++ b/contentprovider/src/main/java/org/literacyapp/contentprovider/dao/DaoSession.java @@ -32,6 +32,7 @@ import org.literacyapp.contentprovider.model.Student; import org.literacyapp.contentprovider.model.StudentImage; import org.literacyapp.contentprovider.model.StudentImageFeature; +import org.literacyapp.contentprovider.model.content.StoryBook; import org.literacyapp.contentprovider.dao.AuthenticationEventDao; import org.literacyapp.contentprovider.dao.StudentImageCollectionEventDao; @@ -57,6 +58,7 @@ import org.literacyapp.contentprovider.dao.StudentDao; import org.literacyapp.contentprovider.dao.StudentImageDao; import org.literacyapp.contentprovider.dao.StudentImageFeatureDao; +import org.literacyapp.contentprovider.dao.StoryBookDao; // THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. @@ -91,6 +93,7 @@ public class DaoSession extends AbstractDaoSession { private final DaoConfig studentDaoConfig; private final DaoConfig studentImageDaoConfig; private final DaoConfig studentImageFeatureDaoConfig; + private final DaoConfig storyBookDaoConfig; private final AuthenticationEventDao authenticationEventDao; private final StudentImageCollectionEventDao studentImageCollectionEventDao; @@ -116,6 +119,7 @@ public class DaoSession extends AbstractDaoSession { private final StudentDao studentDao; private final StudentImageDao studentImageDao; private final StudentImageFeatureDao studentImageFeatureDao; + private final StoryBookDao storyBookDao; public DaoSession(Database db, IdentityScopeType type, Map>, DaoConfig> daoConfigMap) { @@ -193,6 +197,9 @@ public DaoSession(Database db, IdentityScopeType type, Map { + + public static final String TABLENAME = "STORY_BOOK"; + + /** + * Properties of entity StoryBook.
+ * Can be used for QueryBuilder and for referencing column names. + */ + public static class Properties { + public final static Property Id = new Property(0, Long.class, "id", true, "_id"); + public final static Property Locale = new Property(1, String.class, "locale", false, "LOCALE"); + public final static Property TimeLastUpdate = new Property(2, Long.class, "timeLastUpdate", false, "TIME_LAST_UPDATE"); + public final static Property RevisionNumber = new Property(3, Integer.class, "revisionNumber", false, "REVISION_NUMBER"); + public final static Property ContentStatus = new Property(4, String.class, "contentStatus", false, "CONTENT_STATUS"); + public final static Property Title = new Property(5, String.class, "title", false, "TITLE"); + public final static Property CoverImageId = new Property(6, long.class, "coverImageId", false, "COVER_IMAGE_ID"); + public final static Property GradeLevel = new Property(7, String.class, "gradeLevel", false, "GRADE_LEVEL"); + } + + private DaoSession daoSession; + + private final LocaleConverter localeConverter = new LocaleConverter(); + private final CalendarConverter timeLastUpdateConverter = new CalendarConverter(); + private final ContentStatusConverter contentStatusConverter = new ContentStatusConverter(); + private final GradeLevelConverter gradeLevelConverter = new GradeLevelConverter(); + + public StoryBookDao(DaoConfig config) { + super(config); + } + + public StoryBookDao(DaoConfig config, DaoSession daoSession) { + super(config, daoSession); + this.daoSession = daoSession; + } + + /** Creates the underlying database table. */ + public static void createTable(Database db, boolean ifNotExists) { + String constraint = ifNotExists? "IF NOT EXISTS ": ""; + db.execSQL("CREATE TABLE " + constraint + "\"STORY_BOOK\" (" + // + "\"_id\" INTEGER PRIMARY KEY ," + // 0: id + "\"LOCALE\" TEXT NOT NULL ," + // 1: locale + "\"TIME_LAST_UPDATE\" INTEGER," + // 2: timeLastUpdate + "\"REVISION_NUMBER\" INTEGER NOT NULL ," + // 3: revisionNumber + "\"CONTENT_STATUS\" TEXT NOT NULL ," + // 4: contentStatus + "\"TITLE\" TEXT NOT NULL ," + // 5: title + "\"COVER_IMAGE_ID\" INTEGER NOT NULL ," + // 6: coverImageId + "\"GRADE_LEVEL\" TEXT NOT NULL );"); // 7: gradeLevel + } + + /** Drops the underlying database table. */ + public static void dropTable(Database db, boolean ifExists) { + String sql = "DROP TABLE " + (ifExists ? "IF EXISTS " : "") + "\"STORY_BOOK\""; + db.execSQL(sql); + } + + @Override + protected final void bindValues(DatabaseStatement stmt, StoryBook entity) { + stmt.clearBindings(); + + Long id = entity.getId(); + if (id != null) { + stmt.bindLong(1, id); + } + stmt.bindString(2, localeConverter.convertToDatabaseValue(entity.getLocale())); + + Calendar timeLastUpdate = entity.getTimeLastUpdate(); + if (timeLastUpdate != null) { + stmt.bindLong(3, timeLastUpdateConverter.convertToDatabaseValue(timeLastUpdate)); + } + stmt.bindLong(4, entity.getRevisionNumber()); + stmt.bindString(5, contentStatusConverter.convertToDatabaseValue(entity.getContentStatus())); + stmt.bindString(6, entity.getTitle()); + stmt.bindLong(7, entity.getCoverImageId()); + stmt.bindString(8, gradeLevelConverter.convertToDatabaseValue(entity.getGradeLevel())); + } + + @Override + protected final void bindValues(SQLiteStatement stmt, StoryBook entity) { + stmt.clearBindings(); + + Long id = entity.getId(); + if (id != null) { + stmt.bindLong(1, id); + } + stmt.bindString(2, localeConverter.convertToDatabaseValue(entity.getLocale())); + + Calendar timeLastUpdate = entity.getTimeLastUpdate(); + if (timeLastUpdate != null) { + stmt.bindLong(3, timeLastUpdateConverter.convertToDatabaseValue(timeLastUpdate)); + } + stmt.bindLong(4, entity.getRevisionNumber()); + stmt.bindString(5, contentStatusConverter.convertToDatabaseValue(entity.getContentStatus())); + stmt.bindString(6, entity.getTitle()); + stmt.bindLong(7, entity.getCoverImageId()); + stmt.bindString(8, gradeLevelConverter.convertToDatabaseValue(entity.getGradeLevel())); + } + + @Override + protected final void attachEntity(StoryBook entity) { + super.attachEntity(entity); + entity.__setDaoSession(daoSession); + } + + @Override + public Long readKey(Cursor cursor, int offset) { + return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0); + } + + @Override + public StoryBook readEntity(Cursor cursor, int offset) { + StoryBook entity = new StoryBook( // + cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id + localeConverter.convertToEntityProperty(cursor.getString(offset + 1)), // locale + cursor.isNull(offset + 2) ? null : timeLastUpdateConverter.convertToEntityProperty(cursor.getLong(offset + 2)), // timeLastUpdate + cursor.getInt(offset + 3), // revisionNumber + contentStatusConverter.convertToEntityProperty(cursor.getString(offset + 4)), // contentStatus + cursor.getString(offset + 5), // title + cursor.getLong(offset + 6), // coverImageId + gradeLevelConverter.convertToEntityProperty(cursor.getString(offset + 7)) // gradeLevel + ); + return entity; + } + + @Override + public void readEntity(Cursor cursor, StoryBook entity, int offset) { + entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0)); + entity.setLocale(localeConverter.convertToEntityProperty(cursor.getString(offset + 1))); + entity.setTimeLastUpdate(cursor.isNull(offset + 2) ? null : timeLastUpdateConverter.convertToEntityProperty(cursor.getLong(offset + 2))); + entity.setRevisionNumber(cursor.getInt(offset + 3)); + entity.setContentStatus(contentStatusConverter.convertToEntityProperty(cursor.getString(offset + 4))); + entity.setTitle(cursor.getString(offset + 5)); + entity.setCoverImageId(cursor.getLong(offset + 6)); + entity.setGradeLevel(gradeLevelConverter.convertToEntityProperty(cursor.getString(offset + 7))); + } + + @Override + protected final Long updateKeyAfterInsert(StoryBook entity, long rowId) { + entity.setId(rowId); + return rowId; + } + + @Override + public Long getKey(StoryBook entity) { + if(entity != null) { + return entity.getId(); + } else { + return null; + } + } + + @Override + public boolean hasKey(StoryBook entity) { + return entity.getId() != null; + } + + @Override + protected final boolean isEntityUpdateable() { + return true; + } + + private String selectDeep; + + protected String getSelectDeep() { + if (selectDeep == null) { + StringBuilder builder = new StringBuilder("SELECT "); + SqlUtils.appendColumns(builder, "T", getAllColumns()); + builder.append(','); + SqlUtils.appendColumns(builder, "T0", daoSession.getImageDao().getAllColumns()); + builder.append(" FROM STORY_BOOK T"); + builder.append(" LEFT JOIN IMAGE T0 ON T.\"COVER_IMAGE_ID\"=T0.\"_id\""); + builder.append(' '); + selectDeep = builder.toString(); + } + return selectDeep; + } + + protected StoryBook loadCurrentDeep(Cursor cursor, boolean lock) { + StoryBook entity = loadCurrent(cursor, 0, lock); + int offset = getAllColumns().length; + + Image coverImage = loadCurrentOther(daoSession.getImageDao(), cursor, offset); + if(coverImage != null) { + entity.setCoverImage(coverImage); + } + + return entity; + } + + public StoryBook loadDeep(Long key) { + assertSinglePk(); + if (key == null) { + return null; + } + + StringBuilder builder = new StringBuilder(getSelectDeep()); + builder.append("WHERE "); + SqlUtils.appendColumnsEqValue(builder, "T", getPkColumns()); + String sql = builder.toString(); + + String[] keyArray = new String[] { key.toString() }; + Cursor cursor = db.rawQuery(sql, keyArray); + + try { + boolean available = cursor.moveToFirst(); + if (!available) { + return null; + } else if (!cursor.isLast()) { + throw new IllegalStateException("Expected unique result, but count was " + cursor.getCount()); + } + return loadCurrentDeep(cursor, true); + } finally { + cursor.close(); + } + } + + /** Reads all available rows from the given cursor and returns a list of new ImageTO objects. */ + public List loadAllDeepFromCursor(Cursor cursor) { + int count = cursor.getCount(); + List list = new ArrayList(count); + + if (cursor.moveToFirst()) { + if (identityScope != null) { + identityScope.lock(); + identityScope.reserveRoom(count); + } + try { + do { + list.add(loadCurrentDeep(cursor, false)); + } while (cursor.moveToNext()); + } finally { + if (identityScope != null) { + identityScope.unlock(); + } + } + } + return list; + } + + protected List loadDeepAllAndCloseCursor(Cursor cursor) { + try { + return loadAllDeepFromCursor(cursor); + } finally { + cursor.close(); + } + } + + + /** A raw-style query where you can pass any WHERE clause and arguments. */ + public List queryDeep(String where, String... selectionArg) { + Cursor cursor = db.rawQuery(getSelectDeep() + where, selectionArg); + return loadDeepAllAndCloseCursor(cursor); + } + +} diff --git a/contentprovider/src/main/java/org/literacyapp/contentprovider/dao/converter/GradeLevelConverter.java b/contentprovider/src/main/java/org/literacyapp/contentprovider/dao/converter/GradeLevelConverter.java index 035add5..7ba35d4 100644 --- a/contentprovider/src/main/java/org/literacyapp/contentprovider/dao/converter/GradeLevelConverter.java +++ b/contentprovider/src/main/java/org/literacyapp/contentprovider/dao/converter/GradeLevelConverter.java @@ -3,21 +3,22 @@ import android.util.Log; import org.greenrobot.greendao.converter.PropertyConverter; +import org.literacyapp.model.enums.GradeLevel; import org.literacyapp.model.enums.Locale; -public class LocaleConverter implements PropertyConverter { +public class GradeLevelConverter implements PropertyConverter { @Override - public Locale convertToEntityProperty(String databaseValue) { + public GradeLevel convertToEntityProperty(String databaseValue) { Log.d(getClass().getName(), "convertToEntityProperty"); - Locale locale = Locale.valueOf(databaseValue); - Log.d(getClass().getName(), "locale: " + locale); - return locale; + GradeLevel gradeLevel = GradeLevel.valueOf(databaseValue); + Log.d(getClass().getName(), "gradeLevel: " + gradeLevel); + return gradeLevel; } @Override - public String convertToDatabaseValue(Locale entityProperty) { + public String convertToDatabaseValue(GradeLevel entityProperty) { Log.d(getClass().getName(), "convertToDatabaseValue"); String databaseValue = entityProperty.toString(); diff --git a/contentprovider/src/main/java/org/literacyapp/contentprovider/model/content/StoryBook.java b/contentprovider/src/main/java/org/literacyapp/contentprovider/model/content/StoryBook.java index 82580bd..0563d04 100644 --- a/contentprovider/src/main/java/org/literacyapp/contentprovider/model/content/StoryBook.java +++ b/contentprovider/src/main/java/org/literacyapp/contentprovider/model/content/StoryBook.java @@ -2,22 +2,30 @@ import org.greenrobot.greendao.annotation.Convert; import org.greenrobot.greendao.annotation.Entity; -import org.greenrobot.greendao.annotation.Generated; import org.greenrobot.greendao.annotation.Id; import org.greenrobot.greendao.annotation.NotNull; +import org.greenrobot.greendao.annotation.ToOne; import org.literacyapp.contentprovider.dao.converter.CalendarConverter; import org.literacyapp.contentprovider.dao.converter.ContentStatusConverter; +import org.literacyapp.contentprovider.dao.converter.GradeLevelConverter; import org.literacyapp.contentprovider.dao.converter.LocaleConverter; +import org.literacyapp.contentprovider.model.content.multimedia.Image; +import org.literacyapp.model.enums.GradeLevel; import org.literacyapp.model.enums.Locale; import org.literacyapp.model.enums.content.ContentStatus; import java.util.Calendar; +import org.greenrobot.greendao.annotation.Generated; +import org.greenrobot.greendao.DaoException; +import org.literacyapp.contentprovider.dao.DaoSession; +import org.literacyapp.contentprovider.dao.ImageDao; +import org.literacyapp.contentprovider.dao.StoryBookDao; /** - * Based on {@link org.literacyapp.model.gson.content.WordGson} + * Based on {@link org.literacyapp.model.gson.content.StoryBookGson} */ @Entity -public class Word { +public class StoryBook { @Id private Long id; @@ -37,33 +45,51 @@ public class Word { private ContentStatus contentStatus; @NotNull - private String text; + private String title; + + private long coverImageId; + + @ToOne(joinProperty = "coverImageId") + private Image coverImage; @NotNull - private String phonetics; + @Convert(converter = GradeLevelConverter.class, columnType = String.class) + private GradeLevel gradeLevel; + + /** Used to resolve relations */ + @Generated(hash = 2040040024) + private transient DaoSession daoSession; - private int usageCount; + /** Used for active entity operations. */ + @Generated(hash = 256360698) + private transient StoryBookDao myDao; - @Generated(hash = 1041052912) - public Word(Long id, @NotNull Locale locale, Calendar timeLastUpdate, + @Generated(hash = 1731918440) + private transient Long coverImage__resolvedKey; + + // TODO: pages + + @Generated(hash = 185999927) + public StoryBook(Long id, @NotNull Locale locale, Calendar timeLastUpdate, @NotNull Integer revisionNumber, @NotNull ContentStatus contentStatus, - @NotNull String text, @NotNull String phonetics, int usageCount) { + @NotNull String title, long coverImageId, + @NotNull GradeLevel gradeLevel) { this.id = id; this.locale = locale; this.timeLastUpdate = timeLastUpdate; this.revisionNumber = revisionNumber; this.contentStatus = contentStatus; - this.text = text; - this.phonetics = phonetics; - this.usageCount = usageCount; + this.title = title; + this.coverImageId = coverImageId; + this.gradeLevel = gradeLevel; } - @Generated(hash = 3342184) - public Word() { + @Generated(hash = 232147559) + public StoryBook() { } public Long getId() { - return id; + return this.id; } public void setId(Long id) { @@ -71,7 +97,7 @@ public void setId(Long id) { } public Locale getLocale() { - return locale; + return this.locale; } public void setLocale(Locale locale) { @@ -79,7 +105,7 @@ public void setLocale(Locale locale) { } public Calendar getTimeLastUpdate() { - return timeLastUpdate; + return this.timeLastUpdate; } public void setTimeLastUpdate(Calendar timeLastUpdate) { @@ -87,7 +113,7 @@ public void setTimeLastUpdate(Calendar timeLastUpdate) { } public Integer getRevisionNumber() { - return revisionNumber; + return this.revisionNumber; } public void setRevisionNumber(Integer revisionNumber) { @@ -95,34 +121,113 @@ public void setRevisionNumber(Integer revisionNumber) { } public ContentStatus getContentStatus() { - return contentStatus; + return this.contentStatus; } public void setContentStatus(ContentStatus contentStatus) { this.contentStatus = contentStatus; } - public String getText() { - return text; + public String getTitle() { + return this.title; + } + + public void setTitle(String title) { + this.title = title; + } + + public GradeLevel getGradeLevel() { + return this.gradeLevel; + } + + public void setGradeLevel(GradeLevel gradeLevel) { + this.gradeLevel = gradeLevel; + } + + public long getCoverImageId() { + return this.coverImageId; + } + + public void setCoverImageId(long coverImageId) { + this.coverImageId = coverImageId; + } + + /** To-one relationship, resolved on first access. */ + @Generated(hash = 1989913581) + public Image getCoverImage() { + long __key = this.coverImageId; + if (coverImage__resolvedKey == null + || !coverImage__resolvedKey.equals(__key)) { + final DaoSession daoSession = this.daoSession; + if (daoSession == null) { + throw new DaoException("Entity is detached from DAO context"); + } + ImageDao targetDao = daoSession.getImageDao(); + Image coverImageNew = targetDao.load(__key); + synchronized (this) { + coverImage = coverImageNew; + coverImage__resolvedKey = __key; + } + } + return coverImage; } - public void setText(String text) { - this.text = text; + /** called by internal mechanisms, do not call yourself. */ + @Generated(hash = 508023874) + public void setCoverImage(@NotNull Image coverImage) { + if (coverImage == null) { + throw new DaoException( + "To-one property 'coverImageId' has not-null constraint; cannot set to-one to null"); + } + synchronized (this) { + this.coverImage = coverImage; + coverImageId = coverImage.getId(); + coverImage__resolvedKey = coverImageId; + } } - public String getPhonetics() { - return phonetics; + /** + * Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}. + * Entity must attached to an entity context. + */ + @Generated(hash = 128553479) + public void delete() { + if (myDao == null) { + throw new DaoException("Entity is detached from DAO context"); + } + myDao.delete(this); } - public void setPhonetics(String phonetics) { - this.phonetics = phonetics; + /** + * Convenient call for {@link org.greenrobot.greendao.AbstractDao#refresh(Object)}. + * Entity must attached to an entity context. + */ + @Generated(hash = 1942392019) + public void refresh() { + if (myDao == null) { + throw new DaoException("Entity is detached from DAO context"); + } + myDao.refresh(this); } - public int getUsageCount() { - return this.usageCount; + /** + * Convenient call for {@link org.greenrobot.greendao.AbstractDao#update(Object)}. + * Entity must attached to an entity context. + */ + @Generated(hash = 713229351) + public void update() { + if (myDao == null) { + throw new DaoException("Entity is detached from DAO context"); + } + myDao.update(this); } - public void setUsageCount(int usageCount) { - this.usageCount = usageCount; + /** called by internal mechanisms, do not call yourself. */ + @Generated(hash = 1536503294) + public void __setDaoSession(DaoSession daoSession) { + this.daoSession = daoSession; + myDao = daoSession != null ? daoSession.getStoryBookDao() : null; } + + // TODO: pages } From d71e5b2fb01a61bf50ce6e339e6311b44acbeecd Mon Sep 17 00:00:00 2001 From: Jo Grimstad Date: Fri, 2 Jun 2017 22:04:09 +0200 Subject: [PATCH 2/5] #409 Download StoryBooks from REST API --- .../DownloadContentAsyncTask.java | 40 +++++++++++++++++++ .../dao/GsonToGreenDaoConverter.java | 25 ++++++++++++ 2 files changed, 65 insertions(+) diff --git a/app/src/main/java/org/literacyapp/service/synchronization/DownloadContentAsyncTask.java b/app/src/main/java/org/literacyapp/service/synchronization/DownloadContentAsyncTask.java index eada9d2..f65cb36 100644 --- a/app/src/main/java/org/literacyapp/service/synchronization/DownloadContentAsyncTask.java +++ b/app/src/main/java/org/literacyapp/service/synchronization/DownloadContentAsyncTask.java @@ -27,11 +27,13 @@ import org.literacyapp.contentprovider.dao.JoinVideosWithWordsDao; import org.literacyapp.contentprovider.dao.LetterDao; import org.literacyapp.contentprovider.dao.NumberDao; +import org.literacyapp.contentprovider.dao.StoryBookDao; import org.literacyapp.contentprovider.dao.VideoDao; import org.literacyapp.contentprovider.dao.WordDao; import org.literacyapp.contentprovider.model.content.Allophone; import org.literacyapp.contentprovider.model.content.Letter; import org.literacyapp.contentprovider.model.content.Number; +import org.literacyapp.contentprovider.model.content.StoryBook; import org.literacyapp.contentprovider.model.content.Word; import org.literacyapp.contentprovider.model.content.multimedia.Audio; import org.literacyapp.contentprovider.model.content.multimedia.Image; @@ -48,6 +50,7 @@ import org.literacyapp.model.gson.content.AllophoneGson; import org.literacyapp.model.gson.content.LetterGson; import org.literacyapp.model.gson.content.NumberGson; +import org.literacyapp.model.gson.content.StoryBookGson; import org.literacyapp.model.gson.content.WordGson; import org.literacyapp.model.gson.content.multimedia.AudioGson; import org.literacyapp.model.gson.content.multimedia.ImageGson; @@ -72,6 +75,7 @@ public class DownloadContentAsyncTask extends AsyncTask { private NumberDao numberDao; private LetterDao letterDao; private WordDao wordDao; + private StoryBookDao storyBookDao; private AudioDao audioDao; private ImageDao imageDao; private VideoDao videoDao; @@ -96,6 +100,7 @@ public DownloadContentAsyncTask(Context context) { numberDao = literacyApplication.getDaoSession().getNumberDao(); letterDao = literacyApplication.getDaoSession().getLetterDao(); wordDao = literacyApplication.getDaoSession().getWordDao(); + storyBookDao = literacyApplication.getDaoSession().getStoryBookDao(); audioDao = literacyApplication.getDaoSession().getAudioDao(); imageDao = literacyApplication.getDaoSession().getImageDao(); videoDao = literacyApplication.getDaoSession().getVideoDao(); @@ -258,6 +263,41 @@ protected String doInBackground(Void... voids) { } + publishProgress("Downloading StoryBooks"); + url = EnvironmentSettings.getRestUrl() + "/content/storybook/list" + + "?deviceId=" + DeviceInfoHelper.getDeviceId(context) + + "&locale=" + DeviceInfoHelper.getLocale(context); + jsonResponse = JsonLoader.loadJson(url); + Log.i(getClass().getName(), "jsonResponse: " + jsonResponse); + try { + JSONObject jsonObject = new JSONObject(jsonResponse); + if (!"success".equals(jsonObject.getString("result"))) { + Log.w(getClass().getName(), "Download failed"); + } else { + JSONArray jsonArray = jsonObject.getJSONArray("storyBooks"); + for (int i = 0; i < jsonArray.length(); i++) { + Type type = new TypeToken(){}.getType(); + StoryBookGson storyBookGson = new Gson().fromJson(jsonArray.getString(i), type); + StoryBook storyBook = GsonToGreenDaoConverter.getStoryBook(storyBookGson); + StoryBook existingStoryBook = storyBookDao.queryBuilder() + .where(StoryBookDao.Properties.Id.eq(storyBook.getId())) + .unique(); + if (existingStoryBook == null) { + Log.i(getClass().getName(), "Storing StoryBook, id: " + storyBook.getId() + ", title: \"" + storyBook.getTitle() + "\", revisionNumber: " + storyBook.getRevisionNumber()); + storyBookDao.insert(storyBook); + } else if (existingStoryBook.getRevisionNumber() < storyBook.getRevisionNumber()) { + Log.i(getClass().getName(), "Updating StoryBook with id " + existingStoryBook.getId() + " from revisionNumber " + existingStoryBook.getRevisionNumber() + " to revisionNumber " + storyBook.getRevisionNumber()); + storyBookDao.update(storyBook); + } else { + Log.i(getClass().getName(), "StoryBook \"" + storyBook.getTitle() + "\" already exists in database with id " + storyBook.getId() + " (revision " + storyBook.getRevisionNumber() + ")"); + } + } + } + } catch (JSONException e) { + Log.e(getClass().getName(), null, e); + } + + publishProgress("Downloading Audios"); url = EnvironmentSettings.getRestUrl() + "/content/multimedia/audio/list" + diff --git a/contentprovider/src/main/java/org/literacyapp/contentprovider/dao/GsonToGreenDaoConverter.java b/contentprovider/src/main/java/org/literacyapp/contentprovider/dao/GsonToGreenDaoConverter.java index b26d72d..3ef2c5d 100644 --- a/contentprovider/src/main/java/org/literacyapp/contentprovider/dao/GsonToGreenDaoConverter.java +++ b/contentprovider/src/main/java/org/literacyapp/contentprovider/dao/GsonToGreenDaoConverter.java @@ -5,6 +5,7 @@ import org.literacyapp.contentprovider.model.content.Allophone; import org.literacyapp.contentprovider.model.content.Letter; import org.literacyapp.contentprovider.model.content.Number; +import org.literacyapp.contentprovider.model.content.StoryBook; import org.literacyapp.contentprovider.model.content.Word; import org.literacyapp.contentprovider.model.content.multimedia.Audio; import org.literacyapp.contentprovider.model.content.multimedia.Image; @@ -14,6 +15,7 @@ import org.literacyapp.model.gson.content.AllophoneGson; import org.literacyapp.model.gson.content.LetterGson; import org.literacyapp.model.gson.content.NumberGson; +import org.literacyapp.model.gson.content.StoryBookGson; import org.literacyapp.model.gson.content.WordGson; import org.literacyapp.model.gson.content.multimedia.AudioGson; import org.literacyapp.model.gson.content.multimedia.ImageGson; @@ -111,6 +113,29 @@ public static Word getWord(WordGson wordGson) { } } + public static StoryBook getStoryBook(StoryBookGson storyBookGson) { + if (storyBookGson == null) { + return null; + } else { + StoryBook storyBook = new StoryBook(); + + storyBook.setId(storyBookGson.getId()); + + storyBook.setLocale(storyBookGson.getLocale()); + storyBook.setTimeLastUpdate(storyBookGson.getTimeLastUpdate()); + storyBook.setRevisionNumber(storyBookGson.getRevisionNumber()); + storyBook.setContentStatus(storyBookGson.getContentStatus()); + + storyBook.setTitle(storyBookGson.getTitle()); + storyBook.setCoverImage(getImage(storyBookGson.getCoverImage())); + storyBook.setGradeLevel(storyBookGson.getGradeLevel()); + + // TODO: pages + + return storyBook; + } + } + public static Audio getAudio(AudioGson audioGson) { if (audioGson == null) { return null; From 01a32f36163e7277a73eaabcad792fa45d090084 Mon Sep 17 00:00:00 2001 From: Jo Grimstad Date: Fri, 2 Jun 2017 22:19:51 +0200 Subject: [PATCH 3/5] #409 Added method to ContentProvider --- app/build.gradle | 2 +- .../org/literacyapp/dao/CustomDaoMaster.java | 8 ++++++ contentprovider/build.gradle | 2 +- .../contentprovider/ContentProvider.java | 28 ++++++++++++++++++- .../contentprovider/dao/DaoMaster.java | 4 +-- 5 files changed, 39 insertions(+), 5 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 112add5..edd7c90 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -56,7 +56,7 @@ android { } greendao { - schemaVersion 2000003 // Must match greendao.schemaVersion in contentprovider/build.gradle + schemaVersion 2000004 // Must match greendao.schemaVersion in contentprovider/build.gradle daoPackage 'org.literacyapp.contentprovider.dao' targetGenDir '../contentprovider/src/main/java' } diff --git a/app/src/main/java/org/literacyapp/dao/CustomDaoMaster.java b/app/src/main/java/org/literacyapp/dao/CustomDaoMaster.java index 8969a9e..f5586ea 100644 --- a/app/src/main/java/org/literacyapp/dao/CustomDaoMaster.java +++ b/app/src/main/java/org/literacyapp/dao/CustomDaoMaster.java @@ -8,6 +8,7 @@ import org.literacyapp.contentprovider.dao.AllophoneDao; import org.literacyapp.contentprovider.dao.DaoMaster; import org.literacyapp.contentprovider.dao.JoinNumbersWithWordsDao; +import org.literacyapp.contentprovider.dao.StoryBookDao; import org.literacyapp.contentprovider.model.JoinNumbersWithWords; public class CustomDaoMaster extends DaoMaster { @@ -53,6 +54,13 @@ public void onUpgrade(Database db, int oldVersion, int newVersion) { ); } + if (oldVersion < 2000004) { + // Add new tables and/or columns automatically (include only the DAO classes that have been modified) + DbMigrationHelper.migrate(db, + StoryBookDao.class + ); + } + // if (oldVersion < ???) { // // Add new tables and/or columns automatically (include only the DAO classes that have been modified) // DbMigrationHelper.migrate(db, diff --git a/contentprovider/build.gradle b/contentprovider/build.gradle index 93bc30d..7fad9cb 100644 --- a/contentprovider/build.gradle +++ b/contentprovider/build.gradle @@ -26,7 +26,7 @@ android { } greendao { - schemaVersion 2000003 // Must match greendao.schemaVersion in app/build.gradle + schemaVersion 2000004 // Must match greendao.schemaVersion in app/build.gradle daoPackage 'org.literacyapp.contentprovider.dao' targetGenDir '../contentprovider/src/main/java' } diff --git a/contentprovider/src/main/java/org/literacyapp/contentprovider/ContentProvider.java b/contentprovider/src/main/java/org/literacyapp/contentprovider/ContentProvider.java index 36e4bbc..89af920 100644 --- a/contentprovider/src/main/java/org/literacyapp/contentprovider/ContentProvider.java +++ b/contentprovider/src/main/java/org/literacyapp/contentprovider/ContentProvider.java @@ -12,16 +12,19 @@ import org.literacyapp.contentprovider.dao.ImageDao; import org.literacyapp.contentprovider.dao.LetterDao; import org.literacyapp.contentprovider.dao.NumberDao; +import org.literacyapp.contentprovider.dao.StoryBookDao; import org.literacyapp.contentprovider.dao.VideoDao; import org.literacyapp.contentprovider.dao.WordDao; import org.literacyapp.contentprovider.model.Student; import org.literacyapp.contentprovider.model.content.Allophone; import org.literacyapp.contentprovider.model.content.Letter; import org.literacyapp.contentprovider.model.content.Number; +import org.literacyapp.contentprovider.model.content.StoryBook; import org.literacyapp.contentprovider.model.content.Word; import org.literacyapp.contentprovider.model.content.multimedia.Audio; import org.literacyapp.contentprovider.model.content.multimedia.Image; import org.literacyapp.contentprovider.model.content.multimedia.Video; +import org.literacyapp.model.enums.GradeLevel; import java.util.ArrayList; import java.util.List; @@ -231,7 +234,30 @@ public static List getAllWordsOrderedByFrequency() { // TODO: getUnlockedStoryBooks() - // TODO: getAllStoryBooks() + public static List getStoryBooks(GradeLevel... gradeLevels) { + Log.i(ContentProvider.class.getName(), "getAllStoryBooks"); + + StoryBookDao storyBookDao = daoSession.getStoryBookDao(); + + List storyBooks = storyBookDao.queryBuilder() + .where(StoryBookDao.Properties.GradeLevel.in(gradeLevels)) + .orderAsc(StoryBookDao.Properties.Title) + .list(); + + return storyBooks; + } + + public static List getAllStoryBooks() { + Log.i(ContentProvider.class.getName(), "getAllStoryBooks"); + + StoryBookDao wordDao = daoSession.getStoryBookDao(); + + List words = wordDao.queryBuilder() + .orderAsc(StoryBookDao.Properties.Title) + .list(); + + return words; + } public static List