Migrate to greenDAO (#23)

* Migration of database operation to greenDAO
* Disable crashlitics for debug builds
* Remove unused drawable
* Fix crash when user have one grade
This commit is contained in:
Rafał Borcz 2017-09-17 18:04:28 +02:00 committed by Mikołaj Pich
parent 9b4c406934
commit 690b730494
44 changed files with 1222 additions and 934 deletions

View File

@ -1,12 +1,14 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
apply plugin: 'jacoco-android' apply plugin: 'jacoco-android'
apply plugin: "io.github.ddimtirov.codacy" apply plugin: "io.github.ddimtirov.codacy"
apply plugin: 'org.greenrobot.greendao'
android { android {
compileSdkVersion 26 compileSdkVersion 26
buildToolsVersion "26.0.1" buildToolsVersion "26.0.1"
defaultConfig { defaultConfig {
applicationId "io.github.wulkanowy" applicationId "io.github.wulkanowy"
testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 14 minSdkVersion 14
targetSdkVersion 26 targetSdkVersion 26
versionCode 1 versionCode 1
@ -21,10 +23,16 @@ android {
} }
debug { debug {
testCoverageEnabled = true testCoverageEnabled = true
ext.enableCrashlytics = false
} }
} }
} }
greendao {
schemaVersion 10
generateTests = true
}
dependencies { dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs') compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
@ -43,7 +51,11 @@ dependencies {
compile 'org.apache.commons:commons-lang3:3.6' compile 'org.apache.commons:commons-lang3:3.6'
compile 'org.apache.commons:commons-collections4:4.1' compile 'org.apache.commons:commons-collections4:4.1'
compile 'org.jsoup:jsoup:1.10.3' compile 'org.jsoup:jsoup:1.10.3'
compile 'org.greenrobot:greendao:3.2.2'
debugCompile 'com.amitshekhar.android:debug-db:1.0.1'
debugCompile 'net.zetetic:android-database-sqlcipher:3.5.7@aar'
testCompile 'junit:junit:4.12' testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:2.9.0' testCompile 'org.mockito:mockito-core:2.10.0'
} }

View File

@ -0,0 +1,18 @@
package io.github.wulkanowy.dao.entities;
import org.greenrobot.greendao.test.AbstractDaoTestLongPk;
public class AccountTest extends AbstractDaoTestLongPk<AccountDao, Account> {
public AccountTest() {
super(AccountDao.class);
}
@Override
protected Account createEntity(Long key) {
Account entity = new Account();
entity.setId(key);
return entity;
}
}

View File

@ -0,0 +1,19 @@
package io.github.wulkanowy.dao.entities;
import org.greenrobot.greendao.test.AbstractDaoTestLongPk;
public class GradeTest extends AbstractDaoTestLongPk<GradeDao, Grade> {
public GradeTest() {
super(GradeDao.class);
}
@Override
protected Grade createEntity(Long key) {
Grade entity = new Grade();
entity.setId(key);
entity.setIsNew(false);
return entity;
}
}

View File

@ -0,0 +1,18 @@
package io.github.wulkanowy.dao.entities;
import org.greenrobot.greendao.test.AbstractDaoTestLongPk;
public class SubjectTest extends AbstractDaoTestLongPk<SubjectDao, Subject> {
public SubjectTest() {
super(SubjectDao.class);
}
@Override
protected Subject createEntity(Long key) {
Subject entity = new Subject();
entity.setId(key);
return entity;
}
}

View File

@ -11,6 +11,7 @@
<uses-sdk tools:overrideLibrary="com.thoughtbot.expandablerecyclerview" /> <uses-sdk tools:overrideLibrary="com.thoughtbot.expandablerecyclerview" />
<application <application
android:name=".activity.WulkanowyApp"
android:allowBackup="false" android:allowBackup="false"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"

View File

@ -0,0 +1,43 @@
package io.github.wulkanowy.activity;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import org.greenrobot.greendao.database.Database;
import org.greenrobot.greendao.query.QueryBuilder;
import io.github.wulkanowy.dao.entities.DaoMaster;
import io.github.wulkanowy.dao.entities.DaoSession;
public class WulkanowyApp extends Application {
private DaoSession daoSession;
@Override
public void onCreate() {
super.onCreate();
DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(this, "wulkanowy-database");
Database database = devOpenHelper.getWritableDb();
daoSession = new DaoMaster(database).newSession();
int schemaVersion = getSharedPreferences("LoginData", Context.MODE_PRIVATE).getInt("schemaVersion", 0);
if (DaoMaster.SCHEMA_VERSION != schemaVersion) {
SharedPreferences sharedPreferences = getSharedPreferences("LoginData", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putLong("userId", 0);
editor.putInt("schemaVersion", DaoMaster.SCHEMA_VERSION);
editor.apply();
}
QueryBuilder.LOG_VALUES = true;
}
public DaoSession getDaoSession() {
return daoSession;
}
}

View File

@ -67,7 +67,7 @@ public class DashboardActivity extends AppCompatActivity {
setTitle(R.string.dashboard_text); setTitle(R.string.dashboard_text);
BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation); BottomNavigationView navigation = findViewById(R.id.navigation);
navigation.setSelectedItemId(R.id.navigation_dashboard); navigation.setSelectedItemId(R.id.navigation_dashboard);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener); navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
@ -77,7 +77,7 @@ public class DashboardActivity extends AppCompatActivity {
public void onBackPressed() { public void onBackPressed() {
BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation); BottomNavigationView navigation = findViewById(R.id.navigation);
if (navigation.getSelectedItemId() != R.id.navigation_dashboard) { if (navigation.getSelectedItemId() != R.id.navigation_dashboard) {
navigation.setSelectedItemId(R.id.navigation_dashboard); navigation.setSelectedItemId(R.id.navigation_dashboard);

View File

@ -1,59 +0,0 @@
package io.github.wulkanowy.activity.dashboard.grades;
import android.os.Parcel;
import android.os.Parcelable;
import io.github.wulkanowy.R;
import io.github.wulkanowy.api.grades.Grade;
public class GradeItem extends Grade implements Parcelable {
protected GradeItem(Parcel source) {
value = source.readString();
}
public GradeItem() {
// empty constructor
}
public int getValueColor() {
if ("6".equals(value) || "6-".equals(value) || "6+".equals(value)) {
return R.color.six_grade;
} else if ("5".equals(value) || "5-".equals(value) || "5+".equals(value)) {
return R.color.five_grade;
} else if ("4".equals(value) || "4-".equals(value) || "4+".equals(value)) {
return R.color.four_grade;
} else if ("3".equals(value) || "3-".equals(value) || "3+".equals(value)) {
return R.color.three_grade;
} else if ("2".equals(value) || "2-".equals(value) || "2+".equals(value)) {
return R.color.two_grade;
} else if ("1".equals(value) || "1-".equals(value) || "1+".equals(value)) {
return R.color.one_grade;
} else {
return R.color.default_grade;
}
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(value);
}
public static final Creator<GradeItem> CREATOR = new Creator<GradeItem>() {
@Override
public GradeItem createFromParcel(Parcel source) {
return new GradeItem(source);
}
@Override
public GradeItem[] newArray(int size) {
return new GradeItem[size];
}
};
}

View File

@ -20,6 +20,7 @@ import com.thoughtbot.expandablerecyclerview.viewholders.GroupViewHolder;
import java.util.List; import java.util.List;
import io.github.wulkanowy.R; import io.github.wulkanowy.R;
import io.github.wulkanowy.dao.entities.Grade;
import static android.view.animation.Animation.RELATIVE_TO_SELF; import static android.view.animation.Animation.RELATIVE_TO_SELF;
@ -51,7 +52,7 @@ public class GradesAdapter extends ExpandableRecyclerViewAdapter<GradesAdapter.S
@Override @Override
public void onBindChildViewHolder(GradeViewHolder holder, int flatPosition, ExpandableGroup group, int childIndex) { public void onBindChildViewHolder(GradeViewHolder holder, int flatPosition, ExpandableGroup group, int childIndex) {
holder.bind((GradeItem) group.getItems().get(childIndex)); holder.bind((Grade) group.getItems().get(childIndex));
} }
public class SubjectViewHolder extends GroupViewHolder { public class SubjectViewHolder extends GroupViewHolder {
@ -64,9 +65,9 @@ public class GradesAdapter extends ExpandableRecyclerViewAdapter<GradesAdapter.S
public SubjectViewHolder(View itemView) { public SubjectViewHolder(View itemView) {
super(itemView); super(itemView);
subjectName = (TextView) itemView.findViewById(R.id.subject_text); subjectName = itemView.findViewById(R.id.subject_text);
indicatorDown = (ImageView) itemView.findViewById(R.id.group_indicator_down); indicatorDown = itemView.findViewById(R.id.group_indicator_down);
indicatorUp = (ImageView) itemView.findViewById(R.id.group_indicator_up); indicatorUp = itemView.findViewById(R.id.group_indicator_up);
} }
@ -143,13 +144,13 @@ public class GradesAdapter extends ExpandableRecyclerViewAdapter<GradesAdapter.S
private TextView dateGrade; private TextView dateGrade;
private GradeItem grade; private Grade grade;
public GradeViewHolder(final View itemView) { public GradeViewHolder(final View itemView) {
super(itemView); super(itemView);
gradeValue = (TextView) itemView.findViewById(R.id.grade_text); gradeValue = itemView.findViewById(R.id.grade_text);
descriptionGrade = (TextView) itemView.findViewById(R.id.description_grade_text); descriptionGrade = itemView.findViewById(R.id.description_grade_text);
dateGrade = (TextView) itemView.findViewById(R.id.grade_date_text); dateGrade = itemView.findViewById(R.id.grade_date_text);
itemView.setOnClickListener(new View.OnClickListener() { itemView.setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -161,7 +162,7 @@ public class GradesAdapter extends ExpandableRecyclerViewAdapter<GradesAdapter.S
}); });
} }
public void bind(GradeItem grade) { public void bind(Grade grade) {
this.grade = grade; this.grade = grade;
gradeValue.setText(grade.getValue()); gradeValue.setText(grade.getValue());
gradeValue.setBackgroundResource(grade.getValueColor()); gradeValue.setBackgroundResource(grade.getValueColor());

View File

@ -9,16 +9,17 @@ import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import io.github.wulkanowy.R; import io.github.wulkanowy.R;
import io.github.wulkanowy.dao.entities.Grade;
public class GradesDialogFragment extends DialogFragment { public class GradesDialogFragment extends DialogFragment {
private GradeItem grade; private Grade grade;
public static final GradesDialogFragment newInstance(GradeItem grade) { public static final GradesDialogFragment newInstance(Grade grade) {
return new GradesDialogFragment().setGrade(grade); return new GradesDialogFragment().setGrade(grade);
} }
public GradesDialogFragment setGrade(GradeItem grade) { public GradesDialogFragment setGrade(Grade grade) {
this.grade = grade; this.grade = grade;
return this; return this;
} }
@ -27,14 +28,14 @@ public class GradesDialogFragment extends DialogFragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.grades_dialog, container, false); View view = inflater.inflate(R.layout.grades_dialog, container, false);
TextView gradeText = (TextView) view.findViewById(R.id.dialog_grade_text); TextView gradeText = view.findViewById(R.id.dialog_grade_text);
TextView subjectText = (TextView) view.findViewById(R.id.subject_dialog_text_value); TextView subjectText = view.findViewById(R.id.subject_dialog_text_value);
TextView descriptionText = (TextView) view.findViewById(R.id.description_dialog_text_value); TextView descriptionText = view.findViewById(R.id.description_dialog_text_value);
TextView weightText = (TextView) view.findViewById(R.id.weight_dialog_text_value); TextView weightText = view.findViewById(R.id.weight_dialog_text_value);
TextView teacherText = (TextView) view.findViewById(R.id.teacher_dialog_text_value); TextView teacherText = view.findViewById(R.id.teacher_dialog_text_value);
TextView dateText = (TextView) view.findViewById(R.id.date_dialog_text_value); TextView dateText = view.findViewById(R.id.date_dialog_text_value);
TextView colorText = (TextView) view.findViewById(R.id.color_dialog_text_value); TextView colorText = view.findViewById(R.id.color_dialog_text_value);
TextView okTextClick = (TextView) view.findViewById(R.id.OK_dialog); TextView okTextClick = view.findViewById(R.id.OK_dialog);
subjectText.setText(grade.getSubject()); subjectText.setText(grade.getSubject());
gradeText.setText(grade.getValue()); gradeText.setText(grade.getValue());

View File

@ -14,9 +14,12 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import io.github.wulkanowy.R; import io.github.wulkanowy.R;
import io.github.wulkanowy.api.grades.Subject; import io.github.wulkanowy.activity.WulkanowyApp;
import io.github.wulkanowy.database.grades.GradesDatabase; import io.github.wulkanowy.dao.entities.Account;
import io.github.wulkanowy.database.subjects.SubjectsDatabase; import io.github.wulkanowy.dao.entities.AccountDao;
import io.github.wulkanowy.dao.entities.DaoSession;
import io.github.wulkanowy.dao.entities.Grade;
import io.github.wulkanowy.dao.entities.Subject;
public class GradesFragment extends Fragment { public class GradesFragment extends Fragment {
@ -30,9 +33,11 @@ public class GradesFragment extends Fragment {
view = inflater.inflate(R.layout.fragment_grades, container, false); view = inflater.inflate(R.layout.fragment_grades, container, false);
if (subjectWithGradesList.size() == 0) { DaoSession daoSession = ((WulkanowyApp) getActivity().getApplication()).getDaoSession();
new MarksTask(container.getContext()).execute();
} else if (subjectWithGradesList.size() > 1) { if (subjectWithGradesList.equals(new ArrayList<>())) {
new GradesTask(daoSession).execute();
} else if (subjectWithGradesList.size() > 0) {
createExpListView(); createExpListView();
view.findViewById(R.id.loadingPanel).setVisibility(View.GONE); view.findViewById(R.id.loadingPanel).setVisibility(View.GONE);
} }
@ -42,48 +47,46 @@ public class GradesFragment extends Fragment {
public void createExpListView() { public void createExpListView() {
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.subject_grade_recycler); RecyclerView recyclerView = view.findViewById(R.id.subject_grade_recycler);
recyclerView.setLayoutManager(new LinearLayoutManager(view.getContext())); recyclerView.setLayoutManager(new LinearLayoutManager(view.getContext()));
GradesAdapter gradesAdapter = new GradesAdapter(subjectWithGradesList, view.getContext()); GradesAdapter gradesAdapter = new GradesAdapter(subjectWithGradesList, view.getContext());
recyclerView.setAdapter(gradesAdapter); recyclerView.setAdapter(gradesAdapter);
} }
public class MarksTask extends AsyncTask<Void, Void, Void> { private class GradesTask extends AsyncTask<Void, Void, Void> {
private Context context; private DaoSession daoSession;
MarksTask(Context context) { GradesTask(DaoSession daoSession) {
this.context = context; this.daoSession = daoSession;
} }
@Override @Override
protected Void doInBackground(Void... params) { protected Void doInBackground(Void... params) {
SubjectsDatabase subjectsDatabase = new SubjectsDatabase(context); long userId = getActivity().getSharedPreferences("LoginData", Context.MODE_PRIVATE)
GradesDatabase gradesDatabase = new GradesDatabase(context); .getLong("userId", 0);
gradesDatabase.open(); AccountDao accountDao = daoSession.getAccountDao();
Account account = accountDao.load(userId);
for (Subject subject : subjectsDatabase.getAllSubjectsNames()) { for (Subject subject : account.getSubjectList()) {
List<GradeItem> gradeItems = gradesDatabase.getSubjectGrades(context.getSharedPreferences("LoginData", Context.MODE_PRIVATE).getLong("isLogin", 0), List<Grade> gradeList = subject.getGradeList();
SubjectsDatabase.getSubjectId(subject.getName())); if (gradeList.size() != 0) {
if (gradeItems.size() > 0) { SubjectWithGrades subjectWithGrades = new SubjectWithGrades(subject.getName(), gradeList);
subjectWithGradesList.add(new SubjectWithGrades(subject.getName(), gradeItems)); subjectWithGradesList.add(subjectWithGrades);
} }
} }
gradesDatabase.close();
return null; return null;
} }
protected void onPostExecute(Void result) { protected void onPostExecute(Void result) {
super.onPostExecute(result);
createExpListView(); createExpListView();
view.findViewById(R.id.loadingPanel).setVisibility(View.GONE); view.findViewById(R.id.loadingPanel).setVisibility(View.GONE);
super.onPostExecute(result);
} }
} }
} }

View File

@ -5,9 +5,11 @@ import com.thoughtbot.expandablerecyclerview.models.ExpandableGroup;
import java.util.List; import java.util.List;
public class SubjectWithGrades extends ExpandableGroup<GradeItem> { import io.github.wulkanowy.dao.entities.Grade;
public SubjectWithGrades(String title, List<GradeItem> items) { public class SubjectWithGrades extends ExpandableGroup<Grade> {
public SubjectWithGrades(String title, List<Grade> items) {
super(title, items); super(title, items);
} }
} }

View File

@ -1,7 +1,7 @@
package io.github.wulkanowy.activity.main; package io.github.wulkanowy.activity.main;
import android.app.Activity;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.widget.Toast; import android.widget.Toast;
@ -21,21 +21,21 @@ import io.github.wulkanowy.utilities.ConnectionUtilities;
public class LoginTask extends AsyncTask<String, Integer, Integer> { public class LoginTask extends AsyncTask<String, Integer, Integer> {
private Context context; private Activity activity;
private ProgressDialog progress; private ProgressDialog progress;
public LoginTask(Context context) { public LoginTask(Activity activity) {
this.context = context; this.activity = activity;
this.progress = new ProgressDialog(context); this.progress = new ProgressDialog(activity);
} }
@Override @Override
protected void onPreExecute() { protected void onPreExecute() {
super.onPreExecute(); super.onPreExecute();
progress.setTitle(context.getText(R.string.login_text)); progress.setTitle(activity.getText(R.string.login_text));
progress.setMessage(context.getText(R.string.please_wait_text)); progress.setMessage(activity.getText(R.string.please_wait_text));
progress.setCancelable(false); progress.setCancelable(false);
progress.show(); progress.show();
} }
@ -43,10 +43,10 @@ public class LoginTask extends AsyncTask<String, Integer, Integer> {
@Override @Override
protected Integer doInBackground(String... credentials) { protected Integer doInBackground(String... credentials) {
if (ConnectionUtilities.isOnline(context)) { if (ConnectionUtilities.isOnline(activity)) {
VulcanSynchronisation vulcanSynchronisation = new VulcanSynchronisation(); VulcanSynchronisation vulcanSynchronisation = new VulcanSynchronisation();
try { try {
vulcanSynchronisation.loginNewUser(credentials[0], credentials[1], credentials[2], context); vulcanSynchronisation.loginNewUser(credentials[0], credentials[1], credentials[2], activity);
} catch (BadCredentialsException e) { } catch (BadCredentialsException e) {
return R.string.login_bad_credentials_text; return R.string.login_bad_credentials_text;
} catch (AccountPermissionException e) { } catch (AccountPermissionException e) {
@ -57,8 +57,8 @@ public class LoginTask extends AsyncTask<String, Integer, Integer> {
return R.string.login_denied_text; return R.string.login_denied_text;
} }
DataSynchronisation dataSynchronisation = new DataSynchronisation(context); DataSynchronisation dataSynchronisation = new DataSynchronisation(activity);
dataSynchronisation.syncGradesAndSubjects(vulcanSynchronisation); dataSynchronisation.syncSubjectsAndGrades(vulcanSynchronisation);
return R.string.login_accepted_text; return R.string.login_accepted_text;
@ -71,16 +71,16 @@ public class LoginTask extends AsyncTask<String, Integer, Integer> {
super.onPostExecute(messageID); super.onPostExecute(messageID);
GradesSync gradesSync = new GradesSync(); GradesSync gradesSync = new GradesSync();
gradesSync.scheduledJob(context); gradesSync.scheduledJob(activity);
progress.dismiss(); progress.dismiss();
Toast.makeText(context, context.getString(messageID), Toast.LENGTH_LONG).show(); Toast.makeText(activity, activity.getString(messageID), Toast.LENGTH_LONG).show();
if (messageID == R.string.login_accepted_text || messageID == R.string.root_failed_text if (messageID == R.string.login_accepted_text || messageID == R.string.root_failed_text
|| messageID == R.string.encrypt_failed_text) { || messageID == R.string.encrypt_failed_text) {
Intent intent = new Intent(context, DashboardActivity.class); Intent intent = new Intent(activity, DashboardActivity.class);
context.startActivity(intent); activity.startActivity(intent);
} }
} }
} }

View File

@ -45,7 +45,7 @@ public class MainActivity extends AppCompatActivity {
private void autoComplete() { private void autoComplete() {
// Get a reference to the AutoCompleteTextView in the layout // Get a reference to the AutoCompleteTextView in the layout
AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.symbolText); AutoCompleteTextView textView = findViewById(R.id.symbolText);
// Get the string array // Get the string array
String[] countries = getResources().getStringArray(R.array.symbols); String[] countries = getResources().getStringArray(R.array.symbols);
// Create the adapter and set it to the AutoCompleteTextView // Create the adapter and set it to the AutoCompleteTextView

View File

@ -38,7 +38,7 @@ public class LoadingTask extends AsyncTask<Void, Void, Boolean> {
Toast.makeText(context, R.string.noInternet_text, Toast.LENGTH_LONG).show(); Toast.makeText(context, R.string.noInternet_text, Toast.LENGTH_LONG).show();
} }
if (context.getSharedPreferences("LoginData", Context.MODE_PRIVATE).getLong("isLogin", 0) == 0) { if (context.getSharedPreferences("LoginData", Context.MODE_PRIVATE).getLong("userId", 0) == 0) {
Intent intent = new Intent(context, MainActivity.class); Intent intent = new Intent(context, MainActivity.class);
context.startActivity(intent); context.startActivity(intent);
} else { } else {

View File

@ -14,7 +14,7 @@ public class StartedActivity extends AppCompatActivity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_started); setContentView(R.layout.activity_started);
TextView versionName = (TextView) findViewById(R.id.rawText); TextView versionName = findViewById(R.id.rawText);
versionName.setText(getText(R.string.version_text) + BuildConfig.VERSION_NAME); versionName.setText(getText(R.string.version_text) + BuildConfig.VERSION_NAME);
new LoadingTask(this).execute(); new LoadingTask(this).execute();

View File

@ -1,14 +1,6 @@
package io.github.wulkanowy.api.grades; package io.github.wulkanowy.api.grades;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
public class Grade { public class Grade {
protected int id;
private int userID;
private int subjectID;
private String subject = ""; private String subject = "";
@ -28,38 +20,6 @@ public class Grade {
private String semester = ""; private String semester = "";
private boolean isNew;
public int getId() {
return id;
}
public Grade setId(int id) {
this.id = id;
return this;
}
public int getUserID() {
return userID;
}
public Grade setUserID(int userID) {
this.userID = userID;
return this;
}
public int getSubjectID() {
return subjectID;
}
public Grade setSubjectID(int subjectID) {
this.subjectID = subjectID;
return this;
}
public String getSubject() { public String getSubject() {
return subject; return subject;
} }
@ -149,50 +109,4 @@ public class Grade {
return this; return this;
} }
public boolean isNew() {
return isNew;
}
public Grade setIsNew(boolean isNew) {
this.isNew = isNew;
return this;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Grade grade = (Grade) o;
return new EqualsBuilder()
.append(subject, grade.subject)
.append(value, grade.value)
.append(color, grade.color)
.append(symbol, grade.symbol)
.append(description, grade.description)
.append(weight, grade.weight)
.append(date, grade.date)
.append(teacher, grade.teacher)
.append(semester, grade.semester)
.isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder(17, 37)
.append(subject)
.append(value)
.append(color)
.append(symbol)
.append(description)
.append(weight)
.append(date)
.append(teacher)
.append(semester)
.toHashCode();
}
} }

View File

@ -0,0 +1,26 @@
package io.github.wulkanowy.dao;
import org.apache.commons.collections4.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
import io.github.wulkanowy.dao.entities.Grade;
public class EntitiesCompare {
public static List<Grade> compareGradeList(List<Grade> newList, List<Grade> oldList) {
List<Grade> addedOrUpdatedGradeList = new ArrayList<>(CollectionUtils
.removeAll(newList, oldList));
List<Grade> updatedList = new ArrayList<>(CollectionUtils
.removeAll(newList, addedOrUpdatedGradeList));
for (Grade grade : addedOrUpdatedGradeList) {
grade.setNew(true);
updatedList.add(grade);
}
return updatedList;
}
}

View File

@ -0,0 +1,211 @@
package io.github.wulkanowy.dao.entities;
import org.greenrobot.greendao.DaoException;
import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Generated;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.Property;
import org.greenrobot.greendao.annotation.ToMany;
import java.util.List;
@Entity(nameInDb = "Accounts")
public class Account {
@Id(autoincrement = true)
private Long id;
@Property(nameInDb = "NAME")
private String name;
@Property(nameInDb = "E-MAIL")
private String email;
@Property(nameInDb = "PASSWORD")
private String password;
@Property(nameInDb = "SYMBOL")
private String symbol;
@ToMany(referencedJoinProperty = "userId")
private List<Subject> subjectList;
@ToMany(referencedJoinProperty = "userId")
private List<Grade> gradeList;
/**
* Used to resolve relations
*/
@Generated(hash = 2040040024)
private transient DaoSession daoSession;
/**
* Used for active entity operations.
*/
@Generated(hash = 335469827)
private transient AccountDao myDao;
@Generated(hash = 1514643300)
public Account(Long id, String name, String email, String password,
String symbol) {
this.id = id;
this.name = name;
this.email = email;
this.password = password;
this.symbol = symbol;
}
@Generated(hash = 882125521)
public Account() {
}
public Long getId() {
return id;
}
public Account setId(Long id) {
this.id = id;
return this;
}
public String getName() {
return name;
}
public Account setName(String name) {
this.name = name;
return this;
}
public String getEmail() {
return email;
}
public Account setEmail(String email) {
this.email = email;
return this;
}
public String getPassword() {
return password;
}
public Account setPassword(String password) {
this.password = password;
return this;
}
public String getSymbol() {
return symbol;
}
public Account setSymbol(String symbol) {
this.symbol = symbol;
return this;
}
/**
* To-many relationship, resolved on first access (and after reset).
* Changes to to-many relations are not persisted, make changes to the target entity.
*/
@Generated(hash = 1800750450)
public List<Subject> getSubjectList() {
if (subjectList == null) {
final DaoSession daoSession = this.daoSession;
if (daoSession == null) {
throw new DaoException("Entity is detached from DAO context");
}
SubjectDao targetDao = daoSession.getSubjectDao();
List<Subject> subjectListNew = targetDao._queryAccount_SubjectList(id);
synchronized (this) {
if (subjectList == null) {
subjectList = subjectListNew;
}
}
}
return subjectList;
}
/**
* Resets a to-many relationship, making the next get call to query for a fresh result.
*/
@Generated(hash = 594294258)
public synchronized void resetSubjectList() {
subjectList = null;
}
/**
* To-many relationship, resolved on first access (and after reset).
* Changes to to-many relations are not persisted, make changes to the target entity.
*/
@Generated(hash = 1040074549)
public List<Grade> getGradeList() {
if (gradeList == null) {
final DaoSession daoSession = this.daoSession;
if (daoSession == null) {
throw new DaoException("Entity is detached from DAO context");
}
GradeDao targetDao = daoSession.getGradeDao();
List<Grade> gradeListNew = targetDao._queryAccount_GradeList(id);
synchronized (this) {
if (gradeList == null) {
gradeList = gradeListNew;
}
}
}
return gradeList;
}
/**
* Resets a to-many relationship, making the next get call to query for a fresh result.
*/
@Generated(hash = 1939990047)
public synchronized void resetGradeList() {
gradeList = null;
}
/**
* 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);
}
/**
* 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);
}
/**
* 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);
}
/**
* called by internal mechanisms, do not call yourself.
*/
@Generated(hash = 1812283172)
public void __setDaoSession(DaoSession daoSession) {
this.daoSession = daoSession;
myDao = daoSession != null ? daoSession.getAccountDao() : null;
}
}

View File

@ -0,0 +1,299 @@
package io.github.wulkanowy.dao.entities;
import android.os.Parcel;
import android.os.Parcelable;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Generated;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.Property;
import io.github.wulkanowy.R;
@Entity(nameInDb = "Grades")
public class Grade implements Parcelable {
@Id(autoincrement = true)
protected Long id;
@Property(nameInDb = "SUBJECT_ID")
private Long subjectId;
@Property(nameInDb = "USER_ID")
private Long userId;
@Property(nameInDb = "SUBJECT")
private String subject = "";
@Property(nameInDb = "VALUE")
protected String value = "";
@Property(nameInDb = "COLOR")
private String color = "";
@Property(nameInDb = "SYMBOL")
private String symbol = "";
@Property(nameInDb = "DESCRIPTION")
private String description = "";
@Property(nameInDb = "WEIGHT")
private String weight = "";
@Property(nameInDb = "DATE")
private String date = "";
@Property(nameInDb = "TEACHER")
private String teacher = "";
@Property(nameInDb = "SEMESTER")
private String semester = "";
@Property(nameInDb = "IS_NEW")
private boolean isNew = false;
protected Grade(Parcel source) {
value = source.readString();
}
@Generated(hash = 1154096520)
public Grade(Long id, Long subjectId, Long userId, String subject, String value,
String color, String symbol, String description, String weight,
String date, String teacher, String semester, boolean isNew) {
this.id = id;
this.subjectId = subjectId;
this.userId = userId;
this.subject = subject;
this.value = value;
this.color = color;
this.symbol = symbol;
this.description = description;
this.weight = weight;
this.date = date;
this.teacher = teacher;
this.semester = semester;
this.isNew = isNew;
}
@Generated(hash = 2042976393)
public Grade() {
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(subject);
parcel.writeString(value);
parcel.writeString(color);
parcel.writeString(symbol);
parcel.writeString(description);
parcel.writeString(weight);
parcel.writeString(date);
parcel.writeString(value);
parcel.writeString(value);
}
public static final Creator<Grade> CREATOR = new Creator<Grade>() {
@Override
public Grade createFromParcel(Parcel source) {
return new Grade(source);
}
@Override
public Grade[] newArray(int size) {
return new Grade[size];
}
};
public int getValueColor() {
String replacedString = value.replaceAll("[^0-9]", "");
if (!"".equals(replacedString)) {
switch (Integer.parseInt(replacedString)) {
case 6:
return R.color.six_grade;
case 5:
return R.color.five_grade;
case 4:
return R.color.four_grade;
case 3:
return R.color.three_grade;
case 2:
return R.color.two_grade;
case 1:
return R.color.one_grade;
default:
return R.color.default_grade;
}
}
return R.color.default_grade;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Grade grade = (Grade) o;
return new EqualsBuilder()
.append(subject, grade.subject)
.append(value, grade.value)
.append(color, grade.color)
.append(symbol, grade.symbol)
.append(description, grade.description)
.append(weight, grade.weight)
.append(date, grade.date)
.append(teacher, grade.teacher)
.append(semester, grade.semester)
.isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder(17, 37)
.append(subject)
.append(value)
.append(color)
.append(symbol)
.append(description)
.append(weight)
.append(date)
.append(teacher)
.append(semester)
.toHashCode();
}
public Long getId() {
return id;
}
public Grade setId(Long id) {
this.id = id;
return this;
}
public Long getSubjectId() {
return subjectId;
}
public Grade setSubjectId(Long subjectId) {
this.subjectId = subjectId;
return this;
}
public Long getUserId() {
return userId;
}
public Grade setUserId(Long userId) {
this.userId = userId;
return this;
}
public String getSubject() {
return subject;
}
public Grade setSubject(String subject) {
this.subject = subject;
return this;
}
public String getValue() {
return value;
}
public Grade setValue(String value) {
this.value = value;
return this;
}
public String getColor() {
return color;
}
public Grade setColor(String color) {
this.color = color;
return this;
}
public String getSymbol() {
return symbol;
}
public Grade setSymbol(String symbol) {
this.symbol = symbol;
return this;
}
public String getDescription() {
return description;
}
public Grade setDescription(String description) {
this.description = description;
return this;
}
public String getWeight() {
return weight;
}
public Grade setWeight(String weight) {
this.weight = weight;
return this;
}
public String getDate() {
return date;
}
public Grade setDate(String date) {
this.date = date;
return this;
}
public String getTeacher() {
return teacher;
}
public Grade setTeacher(String teacher) {
this.teacher = teacher;
return this;
}
public String getSemester() {
return semester;
}
public Grade setSemester(String semester) {
this.semester = semester;
return this;
}
public boolean isNew() {
return isNew;
}
public Grade setNew(boolean aNew) {
isNew = aNew;
return this;
}
public boolean getIsNew() {
return this.isNew;
}
public void setIsNew(boolean isNew) {
this.isNew = isNew;
}
}

View File

@ -0,0 +1,191 @@
package io.github.wulkanowy.dao.entities;
import org.greenrobot.greendao.DaoException;
import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Generated;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.Property;
import org.greenrobot.greendao.annotation.ToMany;
import java.util.List;
@Entity(nameInDb = "Subjects")
public class Subject {
@Id(autoincrement = true)
private Long id;
@Property(nameInDb = "USER_ID")
private Long userId;
@Property(nameInDb = "NAME")
private String name;
@Property(nameInDb = "PREDICTED_RATING")
private String predictedRating;
@Property(nameInDb = "FINAL_RATING")
private String finalRating;
@Property(nameInDb = "SEMESTER")
private String semester;
@ToMany(referencedJoinProperty = "subjectId")
private List<Grade> gradeList;
/**
* Used to resolve relations
*/
@Generated(hash = 2040040024)
private transient DaoSession daoSession;
/**
* Used for active entity operations.
*/
@Generated(hash = 1644932788)
private transient SubjectDao myDao;
@Generated(hash = 396325764)
public Subject(Long id, Long userId, String name, String predictedRating,
String finalRating, String semester) {
this.id = id;
this.userId = userId;
this.name = name;
this.predictedRating = predictedRating;
this.finalRating = finalRating;
this.semester = semester;
}
@Generated(hash = 1617906264)
public Subject() {
}
public Long getId() {
return id;
}
public Subject setId(Long id) {
this.id = id;
return this;
}
public Long getUserId() {
return userId;
}
public Subject setUserId(Long userId) {
this.userId = userId;
return this;
}
public String getName() {
return name;
}
public Subject setName(String name) {
this.name = name;
return this;
}
public String getPredictedRating() {
return predictedRating;
}
public Subject setPredictedRating(String predictedRating) {
this.predictedRating = predictedRating;
return this;
}
public String getFinalRating() {
return finalRating;
}
public Subject setFinalRating(String finalRating) {
this.finalRating = finalRating;
return this;
}
public String getSemester() {
return semester;
}
public Subject setSemester(String semester) {
this.semester = semester;
return this;
}
/**
* To-many relationship, resolved on first access (and after reset).
* Changes to to-many relations are not persisted, make changes to the target entity.
*/
@Generated(hash = 1358847893)
public List<Grade> getGradeList() {
if (gradeList == null) {
final DaoSession daoSession = this.daoSession;
if (daoSession == null) {
throw new DaoException("Entity is detached from DAO context");
}
GradeDao targetDao = daoSession.getGradeDao();
List<Grade> gradeListNew = targetDao._querySubject_GradeList(id);
synchronized (this) {
if (gradeList == null) {
gradeList = gradeListNew;
}
}
}
return gradeList;
}
/**
* Resets a to-many relationship, making the next get call to query for a fresh result.
*/
@Generated(hash = 1939990047)
public synchronized void resetGradeList() {
gradeList = null;
}
/**
* 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);
}
/**
* 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);
}
/**
* 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);
}
/**
* called by internal mechanisms, do not call yourself.
*/
@Generated(hash = 937984622)
public void __setDaoSession(DaoSession daoSession) {
this.daoSession = daoSession;
myDao = daoSession != null ? daoSession.getSubjectDao() : null;
}
}

View File

@ -1,90 +0,0 @@
package io.github.wulkanowy.database;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
public class DatabaseAdapter {
private final String DATABASE_NAME = "accountdatabase.db";
private final int DATABASE_VERSION = 6;
public static SQLiteDatabase database;
private DatabaseHelper databaseHelper;
public Context context;
public DatabaseAdapter(Context context) {
this.context = context;
}
public DatabaseAdapter open() {
databaseHelper = new DatabaseHelper(context, DATABASE_NAME, null, DATABASE_VERSION);
try {
database = databaseHelper.getWritableDatabase();
} catch (SQLException e) {
database = databaseHelper.getReadableDatabase();
Log.w(DatabaseHelper.DEBUG_TAG, "Database in read-only");
}
Log.d(DatabaseHelper.DEBUG_TAG, "Open database");
return this;
}
public void close() {
databaseHelper.close();
Log.d(DatabaseHelper.DEBUG_TAG, "Close database");
}
protected boolean checkExist(String tableName, String dbfield, String fieldValue) {
Cursor cursor;
if (dbfield == null && fieldValue == null && tableName != null) {
cursor = database.rawQuery("SELECT COUNT(*) FROM " + tableName, null);
Log.d(DatabaseHelper.DEBUG_TAG, "Check exist " + tableName + " table");
} else if (dbfield != null && fieldValue != null && tableName != null) {
cursor = database.rawQuery("SELECT COUNT(*) FROM " + tableName + " WHERE " + dbfield + "=?", new String[]{fieldValue});
Log.d(DatabaseHelper.DEBUG_TAG, "Check exist " + fieldValue + " row");
} else {
cursor = null;
}
if (cursor != null) {
cursor.moveToFirst();
int count = cursor.getInt(0);
if (count > 0) {
return true;
}
cursor.close();
}
return false;
}
protected boolean checkExist(String tableName) {
return checkExist(tableName, null, null);
}
protected void deleteAndCreate(String tableName) {
database.execSQL(databaseHelper.DROP_TABLE + tableName);
database.execSQL(databaseHelper.SUBJECT_TABLE);
database.execSQL(databaseHelper.ACCOUNT_TABLE);
database.execSQL(databaseHelper.GRADE_TABLE);
Log.d(DatabaseHelper.DEBUG_TAG, "Recreate table " + tableName);
}
}

View File

@ -1,25 +0,0 @@
package io.github.wulkanowy.database;
import org.apache.commons.collections4.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
import io.github.wulkanowy.api.grades.Grade;
public class DatabaseComparer {
public static List<Grade> compareGradesLists(List<Grade> newList, List<Grade> oldList) {
List<Grade> addedOrUpdatedGradesList = new ArrayList<>(CollectionUtils.removeAll(newList, oldList));
List<Grade> updatedList = new ArrayList<>(CollectionUtils.removeAll(newList, addedOrUpdatedGradesList));
for (Grade grade : addedOrUpdatedGradesList) {
grade.setIsNew(true);
updatedList.add(grade);
}
return updatedList;
}
}

View File

@ -1,65 +0,0 @@
package io.github.wulkanowy.database;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DatabaseHelper extends SQLiteOpenHelper {
public final static String DEBUG_TAG = "SQLiteWulkanowyDatabase";
public final String ACCOUNT_TABLE = "CREATE TABLE IF NOT EXISTS accounts( " +
"id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"name TEXT, " +
"email TEXT," +
"password TEXT, " +
"symbol TEXT );";
public final String SUBJECT_TABLE = "CREATE TABLE IF NOT EXISTS subjects( " +
"id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"name TEXT, " +
"predictedRating1 TEXT, " +
"finalRating1 TEXT, " +
"predictedRating2 TEXT, " +
"finalRating2 TEXT );";
public final String GRADE_TABLE = "CREATE TABLE IF NOT EXISTS grades( " +
"id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"userID INTEGER, " +
"subjectID INTEGER, " +
"subject TEXT, " +
"value TEXT, " +
"color TEXT, " +
"symbol TEXT, " +
"description TEXT, " +
"weight TEXT, " +
"date DATE, " +
"teacher TEXT, " +
"semester INTEGER, " +
"isNew INTEGER );";
public final String DROP_TABLE = "DROP TABLE IF EXISTS ";
public DatabaseHelper(Context context, String name, CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(ACCOUNT_TABLE);
db.execSQL(SUBJECT_TABLE);
db.execSQL(GRADE_TABLE);
Log.d(DEBUG_TAG, "Create database");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL(DROP_TABLE + "accounts");
db.execSQL(DROP_TABLE + "subjects");
db.execSQL(DROP_TABLE + "grades");
onCreate(db);
Log.d(DEBUG_TAG, "Database upgrade from ver." + oldVersion + " to ver." + newVersion);
}
}

View File

@ -1,60 +0,0 @@
package io.github.wulkanowy.database.accounts;
public class Account {
private int id;
private String name;
private String email;
private String password;
private String symbol;
public int getId() {
return id;
}
public Account setId(int id) {
this.id = id;
return this;
}
public String getName() {
return name;
}
public Account setName(String name) {
this.name = name;
return this;
}
public String getEmail() {
return email;
}
public Account setEmail(String email) {
this.email = email;
return this;
}
public String getPassword() {
return password;
}
public Account setPassword(String password) {
this.password = password;
return this;
}
public String getSymbol() {
return symbol;
}
public Account setSymbol(String symbol) {
this.symbol = symbol;
return this;
}
}

View File

@ -1,81 +0,0 @@
package io.github.wulkanowy.database.accounts;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.CursorIndexOutOfBoundsException;
import android.database.SQLException;
import android.util.Log;
import io.github.wulkanowy.database.DatabaseAdapter;
import io.github.wulkanowy.database.DatabaseHelper;
public class AccountsDatabase extends DatabaseAdapter {
private String name = "name";
private String email = "email";
private String password = "password";
private String symbol = "symbol";
private String idText = "id";
private String accounts = "accounts";
public AccountsDatabase(Context context) {
super(context);
}
public long put(Account account) throws SQLException {
ContentValues newAccount = new ContentValues();
newAccount.put(name, account.getName());
newAccount.put(email, account.getEmail());
newAccount.put(password, account.getPassword());
newAccount.put(symbol, account.getSymbol());
if (!database.isReadOnly()) {
long newId = database.insertOrThrow(accounts, null, newAccount);
Log.d(DatabaseHelper.DEBUG_TAG, "Put account " + newId + " into database");
return newId;
}
Log.e(DatabaseHelper.DEBUG_TAG, "Attempt to write on read-only database");
throw new SQLException("Attempt to write on read-only database");
}
public Account getAccount(long id) throws SQLException {
Account account = new Account();
String[] columns = {idText, name, email, password, symbol};
String args[] = {id + ""};
try {
Cursor cursor = database.query(accounts, columns, "id=?", args, null, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
account.setId(cursor.getInt(0));
account.setName(cursor.getString(1));
account.setEmail(cursor.getString(2));
account.setPassword(cursor.getString(3));
account.setSymbol(cursor.getString(4));
cursor.close();
}
} catch (SQLException e) {
Log.e(DatabaseHelper.DEBUG_TAG, e.getMessage());
throw e;
} catch (CursorIndexOutOfBoundsException e) {
Log.e(DatabaseHelper.DEBUG_TAG, e.getMessage());
throw new SQLException(e.getMessage());
}
Log.d(DatabaseHelper.DEBUG_TAG, "Extract account " + id + " from database");
return account;
}
}

View File

@ -1,155 +0,0 @@
package io.github.wulkanowy.database.grades;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
import io.github.wulkanowy.activity.dashboard.grades.GradeItem;
import io.github.wulkanowy.api.grades.Grade;
import io.github.wulkanowy.database.DatabaseAdapter;
import io.github.wulkanowy.database.DatabaseComparer;
import io.github.wulkanowy.database.DatabaseHelper;
import io.github.wulkanowy.database.subjects.SubjectsDatabase;
public class GradesDatabase extends DatabaseAdapter {
private String userIdText = "userID";
private String subjectIdText = "subjectID";
private String subject = "subject";
private String value = "value";
private String color = "color";
private String symbol = "symbol";
private String description = "description";
private String weight = "weight";
private String date = "date";
private String teacher = "teacher";
private String isNew = "isNew";
private String semester = "semester";
private String grades = "grades";
public GradesDatabase(Context context) {
super(context);
}
public long put(Grade grade) throws SQLException {
ContentValues newGrade = new ContentValues();
newGrade.put(userIdText, context.getSharedPreferences("LoginData", context.MODE_PRIVATE).getLong("isLogin", 0));
newGrade.put(subjectIdText, SubjectsDatabase.getSubjectId(grade.getSubject()));
newGrade.put(subject, grade.getSubject());
newGrade.put(value, grade.getValue());
newGrade.put(color, grade.getColor());
newGrade.put(symbol, grade.getSymbol());
newGrade.put(description, grade.getDescription());
newGrade.put(weight, grade.getWeight());
newGrade.put(date, grade.getDate());
newGrade.put(teacher, grade.getTeacher());
newGrade.put(semester, grade.getSemester());
newGrade.put(isNew, grade.isNew() ? 1 : 0);
if (!database.isReadOnly()) {
long newId = database.insertOrThrow(grades, null, newGrade);
Log.d(DatabaseHelper.DEBUG_TAG, "Put grade " + newId + " into database");
return newId;
}
Log.e(DatabaseHelper.DEBUG_TAG, "Attempt to write on read-only database");
throw new SQLException("Attempt to write on read-only database");
}
public List<Long> put(List<Grade> gradeList) throws SQLException {
List<Long> newIdList = new ArrayList<>();
List<Grade> preparedList;
if (checkExist(grades)) {
preparedList = DatabaseComparer.compareGradesLists(gradeList, getAllUserGrades());
deleteAndCreate(grades);
} else {
preparedList = gradeList;
}
for (Grade grade : preparedList) {
newIdList.add(put(grade));
}
return newIdList;
}
public List<GradeItem> getSubjectGrades(long userId, long subjectId) throws SQLException {
String exec = "SELECT " + grades + ".*, strftime('%d.%m.%Y', " + date + ") " +
"FROM " + grades + " WHERE " + userIdText + "=? AND "
+ subjectIdText + "=? ORDER BY " + date + " DESC";
List<GradeItem> gradesList = new ArrayList<>();
Cursor cursor = database.rawQuery(exec, new String[]{String.valueOf(userId), String.valueOf(subjectId)});
while (cursor.moveToNext()) {
GradeItem grade = new GradeItem();
grade.setId(cursor.getInt(0));
grade.setUserID(cursor.getInt(1));
grade.setSubjectID(cursor.getInt(2));
grade.setSubject(cursor.getString(3));
grade.setValue(cursor.getString(4));
grade.setColor(cursor.getString(5));
grade.setSymbol(cursor.getString(6));
grade.setDescription(cursor.getString(7));
grade.setWeight(cursor.getString(8));
grade.setDate(cursor.getString(13)); // last, because reformatted date is last
grade.setTeacher(cursor.getString(10));
grade.setSemester(cursor.getString(11));
grade.setIsNew(cursor.getInt(12) != 0);
gradesList.add(grade);
}
cursor.close();
return gradesList;
}
public List<Grade> getAllUserGrades() {
List<Grade> gradesList = new ArrayList<>();
String exec = "SELECT " + grades + ".*, strftime('%d.%m.%Y', " + date + ") " +
" FROM " + grades + " WHERE " + userIdText + "=? ORDER BY " + date + " DESC";
Cursor cursor = database.rawQuery(exec, new String[]{String.valueOf(context.getSharedPreferences("LoginData", context.MODE_PRIVATE).getLong("isLogin", 0))});
while (cursor.moveToNext()) {
Grade grade = new Grade();
grade.setSubject(cursor.getString(3));
grade.setValue(cursor.getString(4));
grade.setColor(cursor.getString(5));
grade.setSymbol(cursor.getString(6));
grade.setDescription(cursor.getString(7));
grade.setWeight(cursor.getString(8));
grade.setDate(cursor.getString(9));
grade.setTeacher(cursor.getString(10));
grade.setSemester(cursor.getString(11));
grade.setIsNew(cursor.getInt(12) != 0);
gradesList.add(grade);
}
cursor.close();
return gradesList;
}
}

View File

@ -1,144 +0,0 @@
package io.github.wulkanowy.database.subjects;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.CursorIndexOutOfBoundsException;
import android.database.SQLException;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
import io.github.wulkanowy.api.grades.Subject;
import io.github.wulkanowy.database.DatabaseAdapter;
import io.github.wulkanowy.database.DatabaseHelper;
public class SubjectsDatabase extends DatabaseAdapter {
private static String idText = "id";
private static String name = "name";
private static String predictedRating1 = "predictedRating1";
private static String finalRating1 = "finalRating1";
private static String predictedRating2 = "predictedRating2";
private static String finalRating2 = "finalRating2";
private static String subjects = "subjects";
public SubjectsDatabase(Context context) {
super(context);
}
public long put(Subject subject) throws SQLException {
ContentValues newSubject = new ContentValues();
newSubject.put(name, subject.getName());
newSubject.put(predictedRating1, subject.getPredictedRating());
newSubject.put(finalRating1, subject.getFinalRating());
if (!database.isReadOnly()) {
long newId = database.insertOrThrow(subjects, null, newSubject);
Log.d(DatabaseHelper.DEBUG_TAG, "Put subject " + newId + " into database");
return newId;
}
Log.e(DatabaseHelper.DEBUG_TAG, "Attempt to write on read-only database");
throw new SQLException("Attempt to write on read-only database");
}
public List<Long> put(List<Subject> subjectList) throws SQLException {
List<Long> newIdList = new ArrayList<>();
for (Subject subject : subjectList) {
if (!checkExist(subjects, name, subject.getName())) {
newIdList.add(put(subject));
}
}
return newIdList;
}
public long update(Subject subject) throws SQLException {
ContentValues updateSubject = new ContentValues();
updateSubject.put(name, subject.getName());
updateSubject.put(predictedRating1, subject.getPredictedRating());
updateSubject.put(finalRating1, subject.getFinalRating());
String args[] = {subject.getId() + ""};
if (!database.isReadOnly()) {
long updateId = database.update(subjects, updateSubject, "id=?", args);
Log.d(DatabaseHelper.DEBUG_TAG, "Update subject " + updateId + " into database");
return updateId;
}
Log.e(DatabaseHelper.DEBUG_TAG, "Attempt to write on read-only database");
throw new SQLException("Attempt to write on read-only database");
}
public Subject getSubject(long id) throws SQLException {
Subject subject = new Subject();
String[] columns = {idText, name, predictedRating1, finalRating1, predictedRating2, finalRating2};
String args[] = {id + ""};
try {
Cursor cursor = database.query(subjects, columns, "id=?", args, null, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
subject.setId(cursor.getInt(0));
subject.setName(cursor.getString(1));
subject.setPredictedRating(cursor.getString(2));
subject.setFinalRating(cursor.getString(3));
cursor.close();
}
} catch (SQLException e) {
Log.e(DatabaseHelper.DEBUG_TAG, e.getMessage());
throw e;
} catch (CursorIndexOutOfBoundsException e) {
Log.e(DatabaseHelper.DEBUG_TAG, e.getMessage());
throw new SQLException(e.getMessage());
}
Log.d(DatabaseHelper.DEBUG_TAG, "Extract subject " + id + " from database");
return subject;
}
public List<Subject> getAllSubjectsNames() {
List<Subject> subjectsList = new ArrayList<>();
String exec = "SELECT " + name + " FROM " + subjects;
Cursor cursor = database.rawQuery(exec, null);
while (cursor.moveToNext()) {
Subject subject = new Subject();
subject.setName(cursor.getString(0));
subjectsList.add(subject);
}
cursor.close();
return subjectsList;
}
public static long getSubjectId(String nameSubject) throws SQLException {
String whereExec = "SELECT " + idText + " FROM " + subjects + " WHERE " + name + " =?";
Cursor cursor = database.rawQuery(whereExec, new String[]{nameSubject});
cursor.moveToFirst();
int idSubject = cursor.getInt(0);
cursor.close();
return idSubject;
}
}

View File

@ -3,9 +3,6 @@ package io.github.wulkanowy.security;
public class CryptoException extends Exception { public class CryptoException extends Exception {
public CryptoException() {
}
public CryptoException(String message) { public CryptoException(String message) {
super(message); super(message);
} }

View File

@ -21,7 +21,6 @@ import java.security.interfaces.RSAPublicKey;
import java.security.spec.AlgorithmParameterSpec; import java.security.spec.AlgorithmParameterSpec;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Enumeration;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.crypto.CipherInputStream; import javax.crypto.CipherInputStream;
@ -34,7 +33,7 @@ public class Scrambler {
private static final String ANDROID_KEYSTORE = "AndroidKeyStore"; private static final String ANDROID_KEYSTORE = "AndroidKeyStore";
public final static String DEBUG_TAG = "KeyStoreSecurity"; public final static String DEBUG_TAG = "WulkanowySecurity";
public Context context; public Context context;
@ -54,22 +53,6 @@ public class Scrambler {
} }
public ArrayList<String> getAllAliases() throws CryptoException {
ArrayList<String> keyAliases = new ArrayList<>();
try {
Enumeration<String> aliases = keyStore.aliases();
while (aliases.hasMoreElements()) {
keyAliases.add(aliases.nextElement());
}
} catch (Exception e) {
Log.e(DEBUG_TAG, e.getMessage());
throw new CryptoException(e.getMessage());
}
return keyAliases;
}
@TargetApi(18) @TargetApi(18)
public void generateNewKey(String alias) throws CryptoException { public void generateNewKey(String alias) throws CryptoException {
@ -122,21 +105,6 @@ public class Scrambler {
} }
public void deleteKey(String alias) throws CryptoException {
if (!alias.isEmpty()) {
try {
keyStore.deleteEntry(alias);
Log.d(DEBUG_TAG, "Key" + alias + "is delete");
} catch (Exception e) {
Log.e(DEBUG_TAG, e.getMessage());
}
} else {
Log.e(DEBUG_TAG, "DeleteKey - String is empty");
throw new CryptoException("DeleteKey - String is empty");
}
}
public String encryptString(String alias, String text) throws CryptoException { public String encryptString(String alias, String text) throws CryptoException {
if (!alias.isEmpty() && !text.isEmpty()) { if (!alias.isEmpty() && !text.isEmpty()) {
@ -153,13 +121,9 @@ public class Scrambler {
cipherOutputStream.write(text.getBytes("UTF-8")); cipherOutputStream.write(text.getBytes("UTF-8"));
cipherOutputStream.close(); cipherOutputStream.close();
Log.d(DEBUG_TAG, "String is encrypt");
byte[] vals = outputStream.toByteArray(); byte[] vals = outputStream.toByteArray();
String encryptedText = Base64.encodeToString(vals, Base64.DEFAULT); return Base64.encodeToString(vals, Base64.DEFAULT);
Log.d(DEBUG_TAG, encryptedText);
return encryptedText;
} catch (Exception e) { } catch (Exception e) {
Log.e(DEBUG_TAG, e.getMessage()); Log.e(DEBUG_TAG, e.getMessage());
@ -193,8 +157,6 @@ public class Scrambler {
Byte[] bytes = values.toArray(new Byte[values.size()]); Byte[] bytes = values.toArray(new Byte[values.size()]);
Log.d(DEBUG_TAG, "String is decrypt");
return new String(ArrayUtils.toPrimitive(bytes), 0, bytes.length, "UTF-8"); return new String(ArrayUtils.toPrimitive(bytes), 0, bytes.length, "UTF-8");
} catch (Exception e) { } catch (Exception e) {

View File

@ -9,9 +9,11 @@ import com.firebase.jobdispatcher.Trigger;
import java.io.IOException; import java.io.IOException;
import io.github.wulkanowy.activity.WulkanowyApp;
import io.github.wulkanowy.api.login.AccountPermissionException; import io.github.wulkanowy.api.login.AccountPermissionException;
import io.github.wulkanowy.api.login.BadCredentialsException; import io.github.wulkanowy.api.login.BadCredentialsException;
import io.github.wulkanowy.api.login.LoginErrorException; import io.github.wulkanowy.api.login.LoginErrorException;
import io.github.wulkanowy.dao.entities.DaoSession;
import io.github.wulkanowy.security.CryptoException; import io.github.wulkanowy.security.CryptoException;
import io.github.wulkanowy.services.synchronisation.DataSynchronisation; import io.github.wulkanowy.services.synchronisation.DataSynchronisation;
import io.github.wulkanowy.services.synchronisation.VulcanSynchronisation; import io.github.wulkanowy.services.synchronisation.VulcanSynchronisation;
@ -44,9 +46,11 @@ public class GradesSync extends VulcanSync {
public void workToBePerformed() throws CryptoException, BadCredentialsException, public void workToBePerformed() throws CryptoException, BadCredentialsException,
LoginErrorException, AccountPermissionException, IOException { LoginErrorException, AccountPermissionException, IOException {
DaoSession daoSession = ((WulkanowyApp) getApplication()).getDaoSession();
VulcanSynchronisation vulcanSynchronisation = new VulcanSynchronisation(); VulcanSynchronisation vulcanSynchronisation = new VulcanSynchronisation();
DataSynchronisation dataSynchronisation = new DataSynchronisation(getApplicationContext()); DataSynchronisation dataSynchronisation = new DataSynchronisation(daoSession);
vulcanSynchronisation.loginCurrentUser(getApplicationContext()); vulcanSynchronisation.loginCurrentUser(getApplicationContext(), daoSession);
dataSynchronisation.syncGrades(vulcanSynchronisation); dataSynchronisation.syncGrades(vulcanSynchronisation);
} }
} }

View File

@ -9,9 +9,11 @@ import com.firebase.jobdispatcher.Trigger;
import java.io.IOException; import java.io.IOException;
import io.github.wulkanowy.activity.WulkanowyApp;
import io.github.wulkanowy.api.login.AccountPermissionException; import io.github.wulkanowy.api.login.AccountPermissionException;
import io.github.wulkanowy.api.login.BadCredentialsException; import io.github.wulkanowy.api.login.BadCredentialsException;
import io.github.wulkanowy.api.login.LoginErrorException; import io.github.wulkanowy.api.login.LoginErrorException;
import io.github.wulkanowy.dao.entities.DaoSession;
import io.github.wulkanowy.security.CryptoException; import io.github.wulkanowy.security.CryptoException;
import io.github.wulkanowy.services.synchronisation.DataSynchronisation; import io.github.wulkanowy.services.synchronisation.DataSynchronisation;
import io.github.wulkanowy.services.synchronisation.VulcanSynchronisation; import io.github.wulkanowy.services.synchronisation.VulcanSynchronisation;
@ -44,10 +46,12 @@ public class SubjectsSync extends VulcanSync {
public void workToBePerformed() throws CryptoException, BadCredentialsException, public void workToBePerformed() throws CryptoException, BadCredentialsException,
LoginErrorException, AccountPermissionException, IOException { LoginErrorException, AccountPermissionException, IOException {
DaoSession daoSession = ((WulkanowyApp) getApplication()).getDaoSession();
VulcanSynchronisation vulcanSynchronisation = new VulcanSynchronisation(); VulcanSynchronisation vulcanSynchronisation = new VulcanSynchronisation();
DataSynchronisation dataSynchronisation = new DataSynchronisation(getApplicationContext()); DataSynchronisation dataSynchronisation = new DataSynchronisation(daoSession);
vulcanSynchronisation.loginCurrentUser(getApplicationContext()); vulcanSynchronisation.loginCurrentUser(getApplicationContext(), daoSession);
dataSynchronisation.syncSubjects(vulcanSynchronisation); dataSynchronisation.syncSubjectsAndGrades(vulcanSynchronisation);
} }
} }

View File

@ -19,14 +19,14 @@ public abstract class VulcanJob extends JobService {
@Override @Override
public boolean onStartJob(JobParameters params) { public boolean onStartJob(JobParameters params) {
Log.d(VulcanSync.DEBUG_TAG, "Start job"); Log.d(VulcanSync.DEBUG_TAG, "Wulkanowy services start");
syncTask.execute(params); syncTask.execute(params);
return true; return true;
} }
@Override @Override
public boolean onStopJob(JobParameters params) { public boolean onStopJob(JobParameters params) {
Log.d(VulcanSync.DEBUG_TAG, "Stop job"); Log.e(VulcanSync.DEBUG_TAG, "Wulkanowy serives stop");
syncTask.cancel(true); syncTask.cancel(true);
return true; return true;
} }

View File

@ -1,40 +1,42 @@
package io.github.wulkanowy.services.synchronisation; package io.github.wulkanowy.services.synchronisation;
import android.content.Context; import android.app.Activity;
import android.util.Log; import android.util.Log;
import io.github.wulkanowy.activity.WulkanowyApp;
import io.github.wulkanowy.dao.entities.DaoSession;
import io.github.wulkanowy.services.jobs.VulcanSync; import io.github.wulkanowy.services.jobs.VulcanSync;
public class DataSynchronisation { public class DataSynchronisation {
private Context context; private DaoSession daoSession;
public DataSynchronisation(Context context) { public DataSynchronisation(DaoSession daoSession) {
this.context = context; this.daoSession = daoSession;
}
public DataSynchronisation(Activity activity) {
daoSession = ((WulkanowyApp) activity.getApplication()).getDaoSession();
} }
public void syncGrades(VulcanSynchronisation vulcanSynchronisation) { public void syncGrades(VulcanSynchronisation vulcanSynchronisation) {
GradesSynchronisation gradesSynchronisation = new GradesSynchronisation(); GradesSynchronisation gradesSynchronisation = new GradesSynchronisation();
try { try {
gradesSynchronisation.sync(vulcanSynchronisation, context); gradesSynchronisation.sync(vulcanSynchronisation, daoSession);
} catch (Exception e) { } catch (Exception e) {
Log.e(VulcanSync.DEBUG_TAG, "Synchronisation of grades failed", e); Log.e(VulcanSync.DEBUG_TAG, "Synchronisation of grades failed", e);
} }
} }
public void syncSubjects(VulcanSynchronisation vulcanSynchronisation) { public void syncSubjectsAndGrades(VulcanSynchronisation vulcanSynchronisation) {
SubjectsSynchronisation subjectsSynchronisation = new SubjectsSynchronisation(); SubjectsSynchronisation subjectsSynchronisation = new SubjectsSynchronisation();
try { try {
subjectsSynchronisation.sync(vulcanSynchronisation, context); subjectsSynchronisation.sync(vulcanSynchronisation, daoSession);
syncGrades(vulcanSynchronisation);
} catch (Exception e) { } catch (Exception e) {
Log.e(VulcanSync.DEBUG_TAG, "Synchronisation of subjects failed", e); Log.e(VulcanSync.DEBUG_TAG, "Synchronisation of subjects failed", e);
} }
} }
public void syncGradesAndSubjects(VulcanSynchronisation vulcanSynchronisation) {
syncSubjects(vulcanSynchronisation);
syncGrades(vulcanSynchronisation);
}
} }

View File

@ -1,23 +1,62 @@
package io.github.wulkanowy.services.synchronisation; package io.github.wulkanowy.services.synchronisation;
import android.content.Context; import android.util.Log;
import org.greenrobot.greendao.query.Query;
import java.io.IOException; import java.io.IOException;
import java.text.ParseException; import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import io.github.wulkanowy.api.grades.GradesList; import io.github.wulkanowy.api.grades.GradesList;
import io.github.wulkanowy.api.login.LoginErrorException; import io.github.wulkanowy.api.login.LoginErrorException;
import io.github.wulkanowy.database.grades.GradesDatabase; import io.github.wulkanowy.dao.EntitiesCompare;
import io.github.wulkanowy.dao.entities.Account;
import io.github.wulkanowy.dao.entities.AccountDao;
import io.github.wulkanowy.dao.entities.DaoSession;
import io.github.wulkanowy.dao.entities.Grade;
import io.github.wulkanowy.dao.entities.GradeDao;
import io.github.wulkanowy.dao.entities.Subject;
import io.github.wulkanowy.dao.entities.SubjectDao;
import io.github.wulkanowy.services.jobs.VulcanSync;
import io.github.wulkanowy.utilities.ConversionVulcanObject;
public class GradesSynchronisation { public class GradesSynchronisation {
public void sync(VulcanSynchronisation vulcanSynchronisation, Context context) throws IOException, ParseException, LoginErrorException { public void sync(VulcanSynchronisation vulcanSynchronisation, DaoSession daoSession) throws IOException,
ParseException, LoginErrorException {
GradesList gradesList = new GradesList(vulcanSynchronisation.getStudentAndParent()); GradesList gradesList = new GradesList(vulcanSynchronisation.getStudentAndParent());
GradesDatabase gradesDatabase = new GradesDatabase(context); GradeDao gradeDao = daoSession.getGradeDao();
gradesDatabase.open(); AccountDao accountDao = daoSession.getAccountDao();
gradesDatabase.put(gradesList.getAll()); SubjectDao subjectDao = daoSession.getSubjectDao();
gradesDatabase.close();
Account account = accountDao.load(vulcanSynchronisation.getUserId());
List<Grade> gradesFromDb = account.getGradeList();
List<Grade> gradeEntitiesList = ConversionVulcanObject.gradesToGradeEntities(gradesList.getAll());
List<Grade> updatedList = EntitiesCompare.compareGradeList(gradeEntitiesList, gradesFromDb);
List<Grade> lastList = new ArrayList<>();
GradeDao.dropTable(gradeDao.getDatabase(), true);
GradeDao.createTable(gradeDao.getDatabase(), false);
for (Grade grade : updatedList) {
Query<Subject> subjectQuery = subjectDao.queryBuilder()
.where(SubjectDao.Properties.Name.eq(grade.getSubject()))
.build();
grade.setUserId(vulcanSynchronisation.getUserId());
grade.setSubjectId((subjectQuery.uniqueOrThrow()).getId());
lastList.add(grade);
}
gradeDao.insertInTx(lastList);
Log.d(VulcanSync.DEBUG_TAG, "Synchronization grades (amount = " + String.valueOf(lastList.size() + ")"));
} }
} }

View File

@ -1,23 +1,41 @@
package io.github.wulkanowy.services.synchronisation; package io.github.wulkanowy.services.synchronisation;
import android.content.Context; import android.util.Log;
import java.io.IOException; import java.io.IOException;
import java.text.ParseException; import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import io.github.wulkanowy.api.grades.SubjectsList; import io.github.wulkanowy.api.grades.SubjectsList;
import io.github.wulkanowy.api.login.LoginErrorException; import io.github.wulkanowy.api.login.LoginErrorException;
import io.github.wulkanowy.database.subjects.SubjectsDatabase; import io.github.wulkanowy.dao.entities.DaoSession;
import io.github.wulkanowy.dao.entities.Subject;
import io.github.wulkanowy.dao.entities.SubjectDao;
import io.github.wulkanowy.services.jobs.VulcanSync;
import io.github.wulkanowy.utilities.ConversionVulcanObject;
public class SubjectsSynchronisation { public class SubjectsSynchronisation {
public void sync(VulcanSynchronisation vulcanSynchronisation, Context context) throws IOException, ParseException, LoginErrorException { public void sync(VulcanSynchronisation vulcanSynchronisation, DaoSession daoSession) throws IOException,
ParseException, LoginErrorException {
SubjectsList subjectsList = new SubjectsList(vulcanSynchronisation.getStudentAndParent()); SubjectsList subjectsList = new SubjectsList(vulcanSynchronisation.getStudentAndParent());
SubjectDao subjectDao = daoSession.getSubjectDao();
SubjectsDatabase subjectsDatabase = new SubjectsDatabase(context); List<Subject> subjectEntitiesList = ConversionVulcanObject.subjectsToSubjectEntities(subjectsList.getAll());
subjectsDatabase.open(); List<Subject> preparedList = new ArrayList<>();
subjectsDatabase.put(subjectsList.getAll());
subjectsDatabase.close(); for (Subject subject : subjectEntitiesList) {
subject.setUserId(vulcanSynchronisation.getUserId());
preparedList.add(subject);
}
SubjectDao.dropTable(subjectDao.getDatabase(), true);
SubjectDao.createTable(subjectDao.getDatabase(), false);
subjectDao.insertInTx(preparedList);
Log.d(VulcanSync.DEBUG_TAG, "Synchronization subjects (amount = " + String.valueOf(subjectEntitiesList.size() + ")"));
} }
} }

View File

@ -1,5 +1,6 @@
package io.github.wulkanowy.services.synchronisation; package io.github.wulkanowy.services.synchronisation;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.util.Log; import android.util.Log;
@ -7,6 +8,7 @@ import android.util.Log;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;
import io.github.wulkanowy.activity.WulkanowyApp;
import io.github.wulkanowy.api.Cookies; import io.github.wulkanowy.api.Cookies;
import io.github.wulkanowy.api.StudentAndParent; import io.github.wulkanowy.api.StudentAndParent;
import io.github.wulkanowy.api.login.AccountPermissionException; import io.github.wulkanowy.api.login.AccountPermissionException;
@ -15,8 +17,9 @@ import io.github.wulkanowy.api.login.Login;
import io.github.wulkanowy.api.login.LoginErrorException; import io.github.wulkanowy.api.login.LoginErrorException;
import io.github.wulkanowy.api.user.BasicInformation; import io.github.wulkanowy.api.user.BasicInformation;
import io.github.wulkanowy.api.user.PersonalData; import io.github.wulkanowy.api.user.PersonalData;
import io.github.wulkanowy.database.accounts.Account; import io.github.wulkanowy.dao.entities.Account;
import io.github.wulkanowy.database.accounts.AccountsDatabase; import io.github.wulkanowy.dao.entities.AccountDao;
import io.github.wulkanowy.dao.entities.DaoSession;
import io.github.wulkanowy.security.CryptoException; import io.github.wulkanowy.security.CryptoException;
import io.github.wulkanowy.security.Safety; import io.github.wulkanowy.security.Safety;
import io.github.wulkanowy.services.jobs.VulcanSync; import io.github.wulkanowy.services.jobs.VulcanSync;
@ -25,17 +28,21 @@ public class VulcanSynchronisation {
private StudentAndParent studentAndParent; private StudentAndParent studentAndParent;
public void loginCurrentUser(Context context) throws CryptoException, BadCredentialsException, LoginErrorException, AccountPermissionException, IOException { private Long userId = 0L;
long userId = context.getSharedPreferences("LoginData", Context.MODE_PRIVATE).getLong("isLogin", 0); public void loginCurrentUser(Context context, DaoSession daoSession) throws CryptoException,
BadCredentialsException, LoginErrorException, AccountPermissionException, IOException {
AccountDao accountDao = daoSession.getAccountDao();
userId = context.getSharedPreferences("LoginData", Context.MODE_PRIVATE).getLong("userId", 0);
if (userId != 0) { if (userId != 0) {
AccountsDatabase accountsDatabase = new AccountsDatabase(context);
accountsDatabase.open();
Account account = accountsDatabase.getAccount(userId);
accountsDatabase.close();
Safety safety = new Safety(context);
Log.d(VulcanSync.DEBUG_TAG, "Login current user id=" + String.valueOf(userId));
Safety safety = new Safety(context);
Account account = accountDao.load(userId);
Login login = loginUser( Login login = loginUser(
account.getEmail(), account.getEmail(),
safety.decrypt(account.getEmail(), account.getPassword()), safety.decrypt(account.getEmail(), account.getPassword()),
@ -47,12 +54,14 @@ public class VulcanSynchronisation {
} }
} }
public void loginNewUser(String email, String password, String symbol, Context context) throws BadCredentialsException, LoginErrorException, AccountPermissionException, IOException, CryptoException { public void loginNewUser(String email, String password, String symbol, Context context, DaoSession daoSession)
throws BadCredentialsException, LoginErrorException, AccountPermissionException, IOException, CryptoException {
AccountDao accountDao = daoSession.getAccountDao();
Login login = loginUser(email, password, symbol); Login login = loginUser(email, password, symbol);
Safety safety = new Safety(context); Safety safety = new Safety(context);
AccountsDatabase accountsDatabase = new AccountsDatabase(context);
BasicInformation basicInformation = new BasicInformation(getAndSetStudentAndParentFromApi(symbol, login.getCookies())); BasicInformation basicInformation = new BasicInformation(getAndSetStudentAndParentFromApi(symbol, login.getCookies()));
PersonalData personalData = basicInformation.getPersonalData(); PersonalData personalData = basicInformation.getPersonalData();
@ -62,25 +71,23 @@ public class VulcanSynchronisation {
.setPassword(safety.encrypt(email, password)) .setPassword(safety.encrypt(email, password))
.setSymbol(symbol); .setSymbol(symbol);
accountsDatabase.open(); userId = accountDao.insert(account);
long idNewUser = accountsDatabase.put(account);
accountsDatabase.close(); Log.d(VulcanSync.DEBUG_TAG, "Login and save new user id=" + String.valueOf(userId));
SharedPreferences sharedPreferences = context.getSharedPreferences("LoginData", Context.MODE_PRIVATE); SharedPreferences sharedPreferences = context.getSharedPreferences("LoginData", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit(); SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putLong("isLogin", idNewUser); editor.putLong("userId", userId);
editor.apply(); editor.apply();
} }
public StudentAndParent getStudentAndParent() { public void loginNewUser(String email, String password, String symbol, Activity activity)
return studentAndParent; throws BadCredentialsException, LoginErrorException, AccountPermissionException, IOException, CryptoException {
loginNewUser(email, password, symbol, activity, ((WulkanowyApp) activity.getApplication()).getDaoSession());
} }
private void setStudentAndParent(StudentAndParent studentAndParent) { private Login loginUser(String email, String password, String symbol) throws BadCredentialsException,
this.studentAndParent = studentAndParent; LoginErrorException, AccountPermissionException {
}
private Login loginUser(String email, String password, String symbol) throws BadCredentialsException, LoginErrorException, AccountPermissionException {
Cookies cookies = new Cookies(); Cookies cookies = new Cookies();
Login login = new Login(cookies); Login login = new Login(cookies);
@ -89,7 +96,16 @@ public class VulcanSynchronisation {
} }
private StudentAndParent getAndSetStudentAndParentFromApi(String symbol, Map<String, String> cookiesMap) throws IOException, LoginErrorException { public Long getUserId() {
return userId;
}
public StudentAndParent getStudentAndParent() {
return studentAndParent;
}
private StudentAndParent getAndSetStudentAndParentFromApi(String symbol, Map<String, String> cookiesMap)
throws IOException, LoginErrorException {
if (studentAndParent == null) { if (studentAndParent == null) {
Cookies cookies = new Cookies(); Cookies cookies = new Cookies();
@ -97,7 +113,7 @@ public class VulcanSynchronisation {
StudentAndParent snp = new StudentAndParent(cookies, symbol); StudentAndParent snp = new StudentAndParent(cookies, symbol);
setStudentAndParent(snp); studentAndParent = snp;
return snp; return snp;
} else { } else {
return studentAndParent; return studentAndParent;

View File

@ -0,0 +1,48 @@
package io.github.wulkanowy.utilities;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import io.github.wulkanowy.dao.entities.Grade;
import io.github.wulkanowy.dao.entities.Subject;
public abstract class ConversionVulcanObject {
public static List<Subject> subjectsToSubjectEntities(List<io.github.wulkanowy.api.grades.Subject> subjectList) {
List<Subject> subjectEntityList = new ArrayList<>();
for (io.github.wulkanowy.api.grades.Subject subject : subjectList) {
Subject subjectEntity = new Subject()
.setName(subject.getName())
.setPredictedRating(subject.getPredictedRating())
.setFinalRating(subject.getFinalRating());
subjectEntityList.add(subjectEntity);
}
return subjectEntityList;
}
public static List<Grade> gradesToGradeEntities(List<io.github.wulkanowy.api.grades.Grade> gradeList) throws ParseException {
List<Grade> gradeEntityList = new ArrayList<>();
for (io.github.wulkanowy.api.grades.Grade grade : gradeList) {
Grade gradeEntity = new Grade()
.setSubject(grade.getSubject())
.setValue(grade.getValue())
.setColor(grade.getColor())
.setSymbol(grade.getSymbol())
.setDescription(grade.getDescription())
.setWeight(grade.getWeight())
.setDate(grade.getDate())
.setTeacher(grade.getTeacher())
.setSemester(grade.getSemester());
gradeEntityList.add(gradeEntity);
}
return gradeEntityList;
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

View File

@ -7,9 +7,11 @@
<TextView <TextView
android:id="@+id/subject_text" android:id="@+id/subject_text"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="15dp" android:padding="15dp"
android:layout_marginRight="50dp"
android:layout_marginEnd="50dp"
android:text="@string/app_name" android:text="@string/app_name"
android:textSize="19sp" /> android:textSize="19sp" />

View File

@ -1,6 +1,6 @@
<resources> <resources>
<style name="WulkanowyTheme" parent="Theme.AppCompat.Light"> <style name="WulkanowyTheme" parent="Base.Theme.AppCompat.Light">
<item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorPrimary</item> <item name="colorAccent">@color/colorPrimary</item>

View File

@ -0,0 +1,80 @@
package io.github.wulkanowy.dao;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import io.github.wulkanowy.dao.entities.Grade;
public class EntitiesCompareTest {
private List<Grade> newList = new ArrayList<>();
private List<Grade> oldList = new ArrayList<>();
private Grade grade1;
private Grade grade2;
@Before
public void prepareObjects() {
grade1 = new Grade()
.setSubject("Matematyka")
.setValue("6")
.setColor("FFFFFF")
.setSymbol("S")
.setDescription("Lorem ipsum")
.setWeight("10")
.setDate("01.01.2017")
.setTeacher("Andrzej")
.setSemester("777");
grade2 = new Grade()
.setSubject("Religia")
.setValue("6")
.setColor("FFFFFF")
.setSymbol("S")
.setDescription("Wolna wola")
.setWeight("10")
.setDate("01.01.2017")
.setTeacher("Andrzej")
.setSemester("777");
}
@Test
public void testCompareNewGradePositive() {
newList.add(grade1);
List<Grade> updatedList = EntitiesCompare.compareGradeList(newList, oldList);
Assert.assertEquals(true, (updatedList.get(0)).getIsNew());
}
@Test
public void testCompareNewGradeNegative() {
newList.add(grade1);
newList.add(grade1);
oldList.add(grade1);
oldList.add(grade2);
List<Grade> updatedList = EntitiesCompare.compareGradeList(newList, oldList);
Assert.assertEquals(false, (updatedList.get(0)).getIsNew());
Assert.assertEquals(false, (updatedList.get(1)).getIsNew());
}
@Test
public void testCompareEmptyGradeList() {
List<Grade> updatedList = EntitiesCompare.compareGradeList(newList, oldList);
Assert.assertEquals(new ArrayList<>(), updatedList);
}
}

View File

@ -0,0 +1,35 @@
package io.github.wulkanowy.dao.entities;
import org.junit.Assert;
import org.junit.Test;
import io.github.wulkanowy.R;
public class GradeTest {
@Test
public void getValueColorTest() {
Assert.assertEquals(R.color.six_grade, new Grade().setValue("-6").getValueColor());
Assert.assertEquals(R.color.five_grade, new Grade().setValue("--5").getValueColor());
Assert.assertEquals(R.color.four_grade, new Grade().setValue("=4").getValueColor());
Assert.assertEquals(R.color.three_grade, new Grade().setValue("3-").getValueColor());
Assert.assertEquals(R.color.two_grade, new Grade().setValue("2--").getValueColor());
Assert.assertEquals(R.color.two_grade, new Grade().setValue("2=").getValueColor());
Assert.assertEquals(R.color.one_grade, new Grade().setValue("1+").getValueColor());
Assert.assertEquals(R.color.one_grade, new Grade().setValue("+1").getValueColor());
Assert.assertEquals(R.color.default_grade, new Grade().setValue("Np").getValueColor());
Assert.assertEquals(R.color.default_grade, new Grade().setValue("").getValueColor());
}
@Test
public void equalsTest() {
Assert.assertTrue(new Grade().setSubject("Religia").setValue("5")
.equals(new Grade().setSubject("Religia").setValue("5")));
Assert.assertFalse(new Grade().setSubject("Religia").setValue("4")
.equals(new Grade().setSubject("Religia").setValue("5")));
Assert.assertEquals(new Grade().setSubject("Religia").setValue("5").hashCode(),
new Grade().setSubject("Religia").setValue("5").hashCode());
}
}

View File

@ -13,6 +13,7 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:2.3.3' classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files