From a3a23632990c54a4bf7621092d1695f4c5ec6384 Mon Sep 17 00:00:00 2001 From: houxg Date: Fri, 25 Nov 2016 18:24:41 +0800 Subject: [PATCH] temporary commit about support tag --- .../houxg/leamonax/database/AppDataBase.java | 24 ++++ .../java/org/houxg/leamonax/model/Note.java | 4 + .../leamonax/model/QueryTagRelationship.java | 28 +++++ .../leamonax/model/RelationshipOfNoteTag.java | 34 +++++ .../java/org/houxg/leamonax/model/Tag.java | 119 ++++++++++++++++++ .../houxg/leamonax/service/NoteService.java | 68 +++++++++- .../houxg/leamonax/ui/SettingsActivity.java | 17 ++- .../leamonax/ui/edit/NoteEditActivity.java | 28 ++++- .../leamonax/ui/edit/SettingFragment.java | 29 ++++- .../houxg/leamonax/utils/CollectionUtils.java | 14 +++ 10 files changed, 357 insertions(+), 8 deletions(-) create mode 100644 app/src/main/java/org/houxg/leamonax/model/QueryTagRelationship.java create mode 100644 app/src/main/java/org/houxg/leamonax/model/RelationshipOfNoteTag.java create mode 100644 app/src/main/java/org/houxg/leamonax/model/Tag.java diff --git a/app/src/main/java/org/houxg/leamonax/database/AppDataBase.java b/app/src/main/java/org/houxg/leamonax/database/AppDataBase.java index 55349c1..ea4a260 100644 --- a/app/src/main/java/org/houxg/leamonax/database/AppDataBase.java +++ b/app/src/main/java/org/houxg/leamonax/database/AppDataBase.java @@ -3,6 +3,8 @@ package org.houxg.leamonax.database; import android.util.Log; import com.raizlabs.android.dbflow.annotation.Database; +import com.raizlabs.android.dbflow.sql.language.Join; +import com.raizlabs.android.dbflow.sql.language.NameAlias; import com.raizlabs.android.dbflow.sql.language.SQLite; import org.houxg.leamonax.model.Account; @@ -13,11 +15,16 @@ import org.houxg.leamonax.model.NoteFile_Table; import org.houxg.leamonax.model.Note_Table; import org.houxg.leamonax.model.Notebook; import org.houxg.leamonax.model.Notebook_Table; +import org.houxg.leamonax.model.RelationshipOfNoteTag; +import org.houxg.leamonax.model.RelationshipOfNoteTag_Table; +import org.houxg.leamonax.model.Tag; +import org.houxg.leamonax.model.Tag_Table; import java.util.ArrayList; import java.util.Collection; import java.util.List; +//TODO:upgrade to Ver.2, handle tags @Database(name = "leanote_db", version = 1) public class AppDataBase { @@ -206,4 +213,21 @@ public class AppDataBase { .where(Account_Table.token.notEq("")) .querySingle(); } + + public static List getTagByNoteLocalId(long noteLocalId) { + return SQLite.select() + .from(Tag.class).as("T") + .join(RelationshipOfNoteTag.class, Join.JoinType.INNER).as("R") + .on(Tag_Table.id.withTable(NameAlias.builder("T").build()) + .eq(RelationshipOfNoteTag_Table.tagLocalId.withTable(NameAlias.builder("R").build()))) + .where(RelationshipOfNoteTag_Table.noteLocalId.withTable(NameAlias.builder("R").build()).eq(noteLocalId)) + .queryList(); + } + + public static Tag getTagByText(String text) { + return SQLite.select() + .from(Tag.class) + .where(Tag_Table.text.eq(text)) + .querySingle(); + } } diff --git a/app/src/main/java/org/houxg/leamonax/model/Note.java b/app/src/main/java/org/houxg/leamonax/model/Note.java index 94929a1..ed3dd49 100644 --- a/app/src/main/java/org/houxg/leamonax/model/Note.java +++ b/app/src/main/java/org/houxg/leamonax/model/Note.java @@ -196,6 +196,10 @@ public class Note extends BaseModel implements Serializable { this.noteId = noteId; } + public List getTagData() { + return tagData; + } + public void updateTags() { if (CollectionUtils.isEmpty(tagData)) { tags = ""; diff --git a/app/src/main/java/org/houxg/leamonax/model/QueryTagRelationship.java b/app/src/main/java/org/houxg/leamonax/model/QueryTagRelationship.java new file mode 100644 index 0000000..ee3068a --- /dev/null +++ b/app/src/main/java/org/houxg/leamonax/model/QueryTagRelationship.java @@ -0,0 +1,28 @@ +package org.houxg.leamonax.model; + +import com.raizlabs.android.dbflow.annotation.Column; +import com.raizlabs.android.dbflow.annotation.QueryModel; +import com.raizlabs.android.dbflow.structure.BaseQueryModel; + +import org.houxg.leamonax.database.AppDataBase; + +@QueryModel(database = AppDataBase.class) +public class QueryTagRelationship extends BaseQueryModel{ + + @Column(name = "tagId") + String tagId; + @Column(name = "userId") + String UserId; + @Column(name = "text") + String text; + @Column(name = "isDeleted") + boolean isDeleted; + @Column(name = "usn") + int usn; + @Column(name = "id") + long id; + @Column(name = "createdTime") + long createdTime; + @Column(name = "updatedTime") + long updatedTime; +} diff --git a/app/src/main/java/org/houxg/leamonax/model/RelationshipOfNoteTag.java b/app/src/main/java/org/houxg/leamonax/model/RelationshipOfNoteTag.java new file mode 100644 index 0000000..314b62c --- /dev/null +++ b/app/src/main/java/org/houxg/leamonax/model/RelationshipOfNoteTag.java @@ -0,0 +1,34 @@ +package org.houxg.leamonax.model; + + +import com.raizlabs.android.dbflow.annotation.Column; +import com.raizlabs.android.dbflow.annotation.PrimaryKey; +import com.raizlabs.android.dbflow.annotation.Table; +import com.raizlabs.android.dbflow.structure.BaseModel; + +import org.houxg.leamonax.database.AppDataBase; + +@Table(name = "RelationshipOfNoteTag", database = AppDataBase.class) +public class RelationshipOfNoteTag extends BaseModel { + @Column(name = "id") + @PrimaryKey(autoincrement = true) + long id; + + @Column(name = "noteLocalId") + long noteLocalId; + + @Column(name = "tagLocalId") + long tagLocalId; + + @Column(name = "userId") + String userId; + + RelationshipOfNoteTag() { + } + + public RelationshipOfNoteTag(long noteLocalId, long tagLocalId, String userId) { + this.noteLocalId = noteLocalId; + this.tagLocalId = tagLocalId; + this.userId = userId; + } +} diff --git a/app/src/main/java/org/houxg/leamonax/model/Tag.java b/app/src/main/java/org/houxg/leamonax/model/Tag.java new file mode 100644 index 0000000..3434f1b --- /dev/null +++ b/app/src/main/java/org/houxg/leamonax/model/Tag.java @@ -0,0 +1,119 @@ +package org.houxg.leamonax.model; + + +import com.google.gson.annotations.SerializedName; +import com.raizlabs.android.dbflow.annotation.Column; +import com.raizlabs.android.dbflow.annotation.PrimaryKey; +import com.raizlabs.android.dbflow.annotation.Table; +import com.raizlabs.android.dbflow.structure.BaseModel; + +import org.houxg.leamonax.database.AppDataBase; +import org.houxg.leamonax.utils.TimeUtils; + +@Table(name = "Tag", database = AppDataBase.class) +public class Tag extends BaseModel{ + + @SerializedName("TagId") + @Column(name = "tagId") + String tagId; + @SerializedName("UserId") + @Column(name = "userId") + String UserId; + @SerializedName("Tag") + @Column(name = "text") + String text; + @SerializedName("IsDeleted") + @Column(name = "isDeleted") + boolean isDeleted; + @SerializedName("Usn") + @Column(name = "usn") + int usn; + @SerializedName("CreatedTime") + String createTimeData; + @SerializedName("UpdatedTime") + String updatedTimeData; + + @Column(name = "id") + @PrimaryKey(autoincrement = true) + long id; + @Column(name = "createdTime") + long createdTime; + @Column(name = "updatedTime") + long updatedTime; + + Tag() {} + + public Tag(String userId, String text) { + UserId = userId; + this.text = text; + } + + public String getTagId() { + return tagId; + } + + public String getUserId() { + return UserId; + } + + public String getText() { + return text; + } + + public boolean isDeleted() { + return isDeleted; + } + + public int getUsn() { + return usn; + } + + public long getId() { + return id; + } + + public long getCreatedTime() { + return createdTime; + } + + public long getUpdatedTime() { + return updatedTime; + } + + public void setTagId(String tagId) { + this.tagId = tagId; + } + + public void setUserId(String userId) { + UserId = userId; + } + + public void setText(String text) { + this.text = text; + } + + public void setDeleted(boolean deleted) { + isDeleted = deleted; + } + + public void setUsn(int usn) { + this.usn = usn; + } + + public void setCreatedTime(long createdTime) { + this.createdTime = createdTime; + } + + public void setUpdatedTime(long updatedTime) { + this.updatedTime = updatedTime; + } + + public void setId(long id) { + this.id = id; + } + + public void updateTime() { + createdTime = TimeUtils.toTimestamp(createTimeData); + updatedTime = TimeUtils.toTimestamp(updatedTimeData); + } +} diff --git a/app/src/main/java/org/houxg/leamonax/service/NoteService.java b/app/src/main/java/org/houxg/leamonax/service/NoteService.java index 6f8334e..0b51323 100644 --- a/app/src/main/java/org/houxg/leamonax/service/NoteService.java +++ b/app/src/main/java/org/houxg/leamonax/service/NoteService.java @@ -16,6 +16,10 @@ import org.houxg.leamonax.model.Note; import org.houxg.leamonax.model.NoteFile; import org.houxg.leamonax.model.Note_Table; import org.houxg.leamonax.model.Notebook; +import org.houxg.leamonax.model.RelationshipOfNoteTag; +import org.houxg.leamonax.model.RelationshipOfNoteTag_Table; +import org.houxg.leamonax.model.Tag; +import org.houxg.leamonax.model.Tag_Table; import org.houxg.leamonax.model.UpdateRe; import org.houxg.leamonax.network.ApiProvider; import org.houxg.leamonax.utils.CollectionUtils; @@ -83,6 +87,7 @@ public class NoteService { Log.i(TAG, "content=" + remoteNote.getContent()); remoteNote.update(); handleFile(localId, remoteNote.getNoteFiles()); + handleTag(localId, remoteNote.getTagData()); } } else { return false; @@ -156,6 +161,55 @@ public class NoteService { AppDataBase.deleteFileExcept(noteLocalId, excepts); } + private static void handleTag(long noteLocalId, List tags) { + List tagLocalIds = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(tags)) { + String currentUserId = AccountService.getCurrent().getUserId(); + for (String tag : tags) { + if (TextUtils.isEmpty(tag)) { + continue; + } + long tagLocalId; + Tag tagModel = SQLite.select() + .from(Tag.class) + .where(Tag_Table.text.eq(tag)) + .querySingle(); + if (tagModel == null) { + tagModel = new Tag(currentUserId, tag); + tagLocalId = tagModel.insert(); + } else { + tagLocalId = tagModel.getId(); + } + + RelationshipOfNoteTag relationship = SQLite.select() + .from(RelationshipOfNoteTag.class) + .where(RelationshipOfNoteTag_Table.noteLocalId.eq(noteLocalId)) + .and(RelationshipOfNoteTag_Table.tagLocalId.eq(tagLocalId)) + .querySingle(); + if (relationship == null) { + relationship = new RelationshipOfNoteTag(noteLocalId, tagLocalId, currentUserId); + relationship.insert(); + } + tagLocalIds.add(tagLocalId); + } + } + + if (CollectionUtils.isEmpty(tagLocalIds)) { + SQLite.delete() + .from(RelationshipOfNoteTag.class) + .where(RelationshipOfNoteTag_Table.noteLocalId.eq(noteLocalId)) + .async() + .execute(); + } else { + SQLite.delete() + .from(RelationshipOfNoteTag.class) + .where(RelationshipOfNoteTag_Table.noteLocalId.eq(noteLocalId)) + .and(RelationshipOfNoteTag_Table.tagLocalId.notIn(tagLocalIds.get(0), CollectionUtils.toPrimitive(tagLocalIds.subList(1, tagLocalIds.size())))) + .async() + .execute(); + } + } + private static String convertToLocalImageLinkForRichText(long noteLocalId, String noteContent) { return StringUtils.replace(noteContent, "]+src\\s*=\\s*['\"]([^'\"]+)['\"][^>]*>", @@ -300,6 +354,7 @@ public class NoteService { serverNote.setContent(convertToLocalImageLinkForRichText(localId, serverNote.getContent())); } handleFile(localId, serverNote.getNoteFiles()); + handleTag(localId, serverNote.getTagData()); serverNote.save(); return true; } @@ -309,7 +364,7 @@ public class NoteService { List fileBodies = handleFileBodies(note, requestBodyMap); return ApiProvider.getInstance().getNoteApi().add(requestBodyMap, fileBodies); } - + private static Call updateNote(Note original, Note modified) { Map requestBodyMap = generateCommonBodyMap(modified); requestBodyMap.put("NoteId", createPartFromString(original.getNoteId())); @@ -338,6 +393,17 @@ public class NoteService { requestBodyMap.put("IsBlog", createPartFromString(getBooleanString(note.isPublicBlog()))); requestBodyMap.put("CreatedTime", createPartFromString(TimeUtils.toServerTime(note.getCreatedTimeVal()))); requestBodyMap.put("UpdatedTime", createPartFromString(TimeUtils.toServerTime(note.getUpdatedTimeVal()))); + + List tags = AppDataBase.getTagByNoteLocalId(note.getId()); + + if (CollectionUtils.isNotEmpty(tags)) { + int size = tags.size(); + for (int index = 0; index < size; index++) { + Tag tag = tags.get(index); + requestBodyMap.put(String.format("Tags[%s]", index), createPartFromString(tag.getText())); + } + } + return requestBodyMap; } diff --git a/app/src/main/java/org/houxg/leamonax/ui/SettingsActivity.java b/app/src/main/java/org/houxg/leamonax/ui/SettingsActivity.java index cfda132..e98f0ab 100644 --- a/app/src/main/java/org/houxg/leamonax/ui/SettingsActivity.java +++ b/app/src/main/java/org/houxg/leamonax/ui/SettingsActivity.java @@ -21,9 +21,13 @@ import org.houxg.leamonax.R; import org.houxg.leamonax.model.Account; import org.houxg.leamonax.model.BaseResponse; import org.houxg.leamonax.model.Note; +import org.houxg.leamonax.model.RelationshipOfNoteTag; import org.houxg.leamonax.model.Note_Table; import org.houxg.leamonax.model.Notebook; import org.houxg.leamonax.model.Notebook_Table; +import org.houxg.leamonax.model.RelationshipOfNoteTag_Table; +import org.houxg.leamonax.model.Tag; +import org.houxg.leamonax.model.Tag_Table; import org.houxg.leamonax.service.AccountService; import org.houxg.leamonax.utils.ToastUtils; @@ -182,13 +186,22 @@ public class SettingsActivity extends BaseActivity { @Override public void call(Subscriber subscriber) { if (!subscriber.isUnsubscribed()) { + Account currentUser = AccountService.getCurrent(); SQLite.delete() .from(Note.class) - .where(Note_Table.userId.eq(AccountService.getCurrent().getUserId())) + .where(Note_Table.userId.eq(currentUser.getUserId())) .execute(); SQLite.delete() .from(Notebook.class) - .where(Notebook_Table.userId.eq(AccountService.getCurrent().getUserId())) + .where(Notebook_Table.userId.eq(currentUser.getUserId())) + .execute(); + SQLite.delete() + .from(Tag.class) + .where(Tag_Table.userId.eq(currentUser.getUserId())) + .execute(); + SQLite.delete() + .from(RelationshipOfNoteTag.class) + .where(RelationshipOfNoteTag_Table.userId.eq(currentUser.getUserId())) .execute(); Account account = AccountService.getCurrent(); account.setLastUsn(0); diff --git a/app/src/main/java/org/houxg/leamonax/ui/edit/NoteEditActivity.java b/app/src/main/java/org/houxg/leamonax/ui/edit/NoteEditActivity.java index 87541c9..99e2f0b 100644 --- a/app/src/main/java/org/houxg/leamonax/ui/edit/NoteEditActivity.java +++ b/app/src/main/java/org/houxg/leamonax/ui/edit/NoteEditActivity.java @@ -17,6 +17,8 @@ import android.view.ViewGroup; import org.houxg.leamonax.R; import org.houxg.leamonax.database.AppDataBase; import org.houxg.leamonax.model.Note; +import org.houxg.leamonax.model.Tag; +import org.houxg.leamonax.service.AccountService; import org.houxg.leamonax.service.NoteFileService; import org.houxg.leamonax.service.NoteService; import org.houxg.leamonax.ui.BaseActivity; @@ -24,6 +26,9 @@ import org.houxg.leamonax.utils.NetworkUtils; import org.houxg.leamonax.utils.ToastUtils; import org.houxg.leamonax.widget.LeaViewPager; +import java.util.ArrayList; +import java.util.List; + import rx.Observable; import rx.Subscriber; import rx.android.schedulers.AndroidSchedulers; @@ -44,6 +49,8 @@ public class NoteEditActivity extends BaseActivity implements EditorFragment.Edi private EditorFragment mEditorFragment; private SettingFragment mSettingsFragment; + private List mOriginalTags; + private List mModifiedTags; private Note mOriginal; private Note mModified; private boolean mIsNewNote; @@ -73,6 +80,8 @@ public class NoteEditActivity extends BaseActivity implements EditorFragment.Edi mIsNewNote = getIntent().getBooleanExtra(EXT_IS_NEW_NOTE, false); mOriginal = AppDataBase.getNoteByLocalId(noteLocalId); mModified = AppDataBase.getNoteByLocalId(noteLocalId); + mOriginalTags = AppDataBase.getTagByNoteLocalId(noteLocalId); + mModifiedTags = AppDataBase.getTagByNoteLocalId(noteLocalId); setResult(RESULT_CANCELED); } @@ -86,6 +95,7 @@ public class NoteEditActivity extends BaseActivity implements EditorFragment.Edi @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); + //TODO:save note state outState.putLong(EXT_NOTE_LOCAL_ID, mModified.getId()); outState.putString(TAG_EDITOR, mEditorFragment.getTag()); outState.putString(TAG_SETTING, mSettingsFragment.getTag()); @@ -199,7 +209,17 @@ public class NoteEditActivity extends BaseActivity implements EditorFragment.Edi mModified.setTitle(title); mModified.setContent(content); mModified.setNoteBookId(mSettingsFragment.getNotebookId()); - mModified.setTags(mSettingsFragment.getTags()); + List tagTexts = mSettingsFragment.getTags(); + mModifiedTags = new ArrayList<>(); + for (String tagText : tagTexts) { + Tag tag = AppDataBase.getTagByText(tagText); + if (tag == null) { + tag = new Tag(AccountService.getCurrent().getUserId(), tagText); + long id = tag.insert(); + tag.setId(id); + } + mModifiedTags.add(tag); + } mModified.setIsPublicBlog(mSettingsFragment.shouldPublic()); } @@ -240,7 +260,11 @@ public class NoteEditActivity extends BaseActivity implements EditorFragment.Edi public void onFragmentInitialized() { mSettingsFragment.setNotebookId(mModified.getNoteBookId()); mSettingsFragment.setShouldPublic(mModified.isPublicBlog()); - mSettingsFragment.setTags(mModified.getTags()); + List tagTexts = new ArrayList<>(); + for (Tag tag : mModifiedTags) { + tagTexts.add(tag.getText()); + } + mSettingsFragment.setTags(tagTexts); } private class SectionAdapter extends FragmentPagerAdapter { diff --git a/app/src/main/java/org/houxg/leamonax/ui/edit/SettingFragment.java b/app/src/main/java/org/houxg/leamonax/ui/edit/SettingFragment.java index 855e89a..3cc021f 100644 --- a/app/src/main/java/org/houxg/leamonax/ui/edit/SettingFragment.java +++ b/app/src/main/java/org/houxg/leamonax/ui/edit/SettingFragment.java @@ -19,7 +19,10 @@ import org.houxg.leamonax.R; import org.houxg.leamonax.database.AppDataBase; import org.houxg.leamonax.model.Notebook; import org.houxg.leamonax.service.AccountService; +import org.houxg.leamonax.utils.CollectionUtils; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import butterknife.BindView; @@ -65,7 +68,21 @@ public class SettingFragment extends Fragment { } } - public void setTags(String tags) { + //TODO:input List + public void setTags(List tagData) { + String tags = ""; + if (CollectionUtils.isNotEmpty(tagData)) { + StringBuilder tagBuilder = new StringBuilder(); + int size = tagData.size(); + int lastIndex = size - 1; + for (int i = 0; i < size; i++) { + tagBuilder.append(tagData.get(i)); + if (i < lastIndex) { + tagBuilder.append(","); + } + } + tags = tagBuilder.toString(); + } mTagEt.setText(tags); } @@ -91,8 +108,14 @@ public class SettingFragment extends Fragment { return mPublicSw.isChecked(); } - public String getTags() { - return mTagEt.getText().toString(); + //TODO:output List + public List getTags() { + String text = mTagEt.getText().toString(); + if (TextUtils.isEmpty(text)) { + return new ArrayList<>(); + } else { + return Arrays.asList(text.split(",")); + } } @OnClick(R.id.ll_notebook) diff --git a/app/src/main/java/org/houxg/leamonax/utils/CollectionUtils.java b/app/src/main/java/org/houxg/leamonax/utils/CollectionUtils.java index b915ece..9cf9304 100644 --- a/app/src/main/java/org/houxg/leamonax/utils/CollectionUtils.java +++ b/app/src/main/java/org/houxg/leamonax/utils/CollectionUtils.java @@ -12,4 +12,18 @@ public class CollectionUtils { public static boolean isNotEmpty(Collection collection) { return collection != null && collection.size() > 0; } + + public static long[] toPrimitive(Collection collection) { + if (isEmpty(collection)) { + return new long[0]; + } + + long[] array = new long[collection.size()]; + int i = 0; + for (Long val : collection) { + array[i] = val; + i++; + } + return array; + } }