diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/ModulesList.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/ModulesList.java index b21635a..afd948a 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/kvv/ModulesList.java +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/ModulesList.java @@ -115,10 +115,10 @@ public class ModulesList extends HTTPService { this.upgrade(success -> { if (this.mModules == null) this.mModules = success; - else - this.mModules.updateList(success); - mListener.onModuleListChange(); - store(); + else if (this.mModules.updateList(success)) { + mListener.onModuleListChange(); + store(); + } callback.onResponse(this.mModules); mQueue.next(); }, error -> { diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Announcement.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Announcement.java index c4b96be..6214621 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Announcement.java +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Announcement.java @@ -2,12 +2,15 @@ package de.sebse.fuplanner.services.kvv.types; import com.google.android.gms.common.internal.Objects; -import java.io.Serializable; +import org.json.JSONException; +import org.json.JSONObject; + import java.util.ArrayList; import androidx.annotation.NonNull; +import de.sebse.fuplanner.tools.UtilsJson; -public class Announcement implements Serializable { +public class Announcement implements UtilsJson.JsonConvertable { private final String id; private final String title; private final String body; @@ -63,4 +66,16 @@ public class Announcement implements Serializable { public int hashCode() { return Objects.hashCode(getId(), getBody(), getCreatedBy(), getCreatedOn(), getTitle(), getUrls()); } + + @Override + public JSONObject toJSONObject() throws JSONException { + JSONObject json = new JSONObject(); + json.put("id", id); + json.put("title", title); + json.put("body", body); + json.put("createdBy", createdBy); + json.put("createdOn", createdOn); + json.put("urls", UtilsJson.collectionToJson(urls)); + return json; + } } diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Assignment.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Assignment.java index b5e3ac3..63d670e 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Assignment.java +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Assignment.java @@ -2,12 +2,16 @@ package de.sebse.fuplanner.services.kvv.types; import com.google.android.gms.common.internal.Objects; +import org.json.JSONException; +import org.json.JSONObject; + import java.io.Serializable; import java.util.ArrayList; import androidx.annotation.NonNull; +import de.sebse.fuplanner.tools.UtilsJson; -public class Assignment implements Serializable { +public class Assignment implements UtilsJson.JsonConvertable { private final String id; private final String title; private final long dueTime; @@ -59,4 +63,15 @@ public class Assignment implements Serializable { public int hashCode() { return Objects.hashCode(getId(), getDueDate(), getInstructions(), getTitle(), getUrls()); } + + @Override + public JSONObject toJSONObject() throws JSONException { + JSONObject json = new JSONObject(); + json.put("id", id); + json.put("title", title); + json.put("dueTime", dueTime); + json.put("createdBy", UtilsJson.collectionToJson(urls)); + json.put("instructions", instructions); + return json; + } } diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Event.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Event.java index 8a6005c..6103ab8 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Event.java +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Event.java @@ -2,6 +2,9 @@ package de.sebse.fuplanner.services.kvv.types; import com.google.android.gms.common.internal.Objects; +import org.json.JSONException; +import org.json.JSONObject; + import java.io.Serializable; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; @@ -9,8 +12,9 @@ import java.security.NoSuchAlgorithmException; import androidx.annotation.NonNull; import de.sebse.fuplanner.tools.ColorRGB; +import de.sebse.fuplanner.tools.UtilsJson; -public class Event implements Serializable { +public class Event implements UtilsJson.JsonConvertable { private final String siteId; private final String id; private final String type; @@ -120,4 +124,17 @@ public class Event implements Serializable { public int hashCode() { return Objects.hashCode(getId(), getType(), getStartDate(), getEndDate(), getTitle(), getLocation()); } + + @Override + public JSONObject toJSONObject() throws JSONException { + JSONObject json = new JSONObject(); + json.put("siteId", siteId); + json.put("id", id); + json.put("type", type); + json.put("title", title); + json.put("duration", duration); + json.put("firstTime", firstTime); + json.put("location", location); + return json; + } } diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Grade.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Grade.java index fefba7f..d35d233 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Grade.java +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Grade.java @@ -2,11 +2,15 @@ package de.sebse.fuplanner.services.kvv.types; import com.google.android.gms.common.internal.Objects; +import org.json.JSONException; +import org.json.JSONObject; + import java.io.Serializable; import androidx.annotation.NonNull; +import de.sebse.fuplanner.tools.UtilsJson; -public class Grade implements Serializable { +public class Grade implements UtilsJson.JsonConvertable { private final String itemName; private final double grade; private final double maxPoints; @@ -41,4 +45,13 @@ public class Grade implements Serializable { public int hashCode() { return Objects.hashCode(getItemName(), getPoints(), getMaxPoints()); } + + @Override + public JSONObject toJSONObject() throws JSONException { + JSONObject json = new JSONObject(); + json.put("itemName", itemName); + json.put("grade", grade); + json.put("maxPoints", maxPoints); + return json; + } } diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Lecturer.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Lecturer.java index 48842c5..9940ec4 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Lecturer.java +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Lecturer.java @@ -1,12 +1,17 @@ package de.sebse.fuplanner.services.kvv.types; -import java.io.Serializable; +import com.google.android.gms.common.internal.Objects; + +import org.json.JSONException; +import org.json.JSONObject; + import java.util.regex.Matcher; import java.util.regex.Pattern; import androidx.annotation.NonNull; +import de.sebse.fuplanner.tools.UtilsJson; -public class Lecturer implements Serializable { +public class Lecturer implements UtilsJson.JsonConvertable { private final String firstName; private final String surname; private final String mail; @@ -55,4 +60,19 @@ public class Lecturer implements Serializable { "\nSurname: "+getSurname()+ "\nMail: "+getMail(); } + + @Override + public int hashCode() { + return Objects.hashCode(getFirstName(), getSurname(), getMail(), isResponsible()); + } + + @Override + public JSONObject toJSONObject() throws JSONException { + JSONObject json = new JSONObject(); + json.put("firstName", firstName); + json.put("surname", surname); + json.put("mail", mail); + json.put("isResponsible", isResponsible); + return json; + } } diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/LoginToken.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/LoginToken.java index b08905f..84aefc8 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/LoginToken.java +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/LoginToken.java @@ -19,10 +19,7 @@ import de.sebse.fuplanner.tools.logging.Logger; * Created by sebastian on 29.10.17. */ -public class LoginToken implements Serializable { - static Logger log = new Logger("LoginToken"); - private static final String FILE_NAME = "LoginTokenSaving"; - +public class LoginToken { private final String username; private final String shibsessionKey; private final String shibsessionName; diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Modules.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Modules.java index 8ca426b..e66547d 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Modules.java +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Modules.java @@ -2,14 +2,20 @@ package de.sebse.fuplanner.services.kvv.types; import android.content.Context; -import org.jetbrains.annotations.NotNull; +import com.google.android.gms.common.internal.Objects; +import org.jetbrains.annotations.NotNull; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.BufferedReader; import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; +import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; @@ -17,16 +23,21 @@ import java.util.LinkedHashSet; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import de.sebse.fuplanner.tools.UtilsJson; + +import static de.sebse.fuplanner.tools.UtilsJson.collectionToJson; /** * Created by sebastian on 29.10.17. */ -public class Modules implements Iterable, Serializable { +public class Modules implements Iterable { private SortedListModule list; private final String mUsername; + private long mLoadTime; //private transient Logger log = new Logger(this); private static final String FILE_NAME = "ModuleListSaving"; + private static final String FILE_NAME_TIMESTAMP = "ModuleListSavingTimestamp"; public Modules(String username) { this.mUsername = username; @@ -66,24 +77,51 @@ public class Modules implements Iterable, Serializable { return this.list.get(index); } - public static Modules load(Context context) throws IOException, ClassNotFoundException { - FileInputStream fis = context.openFileInput(FILE_NAME); - ObjectInputStream is = new ObjectInputStream(fis); - Object readObject = is.readObject(); - if (!(readObject instanceof Modules)) - return null; - Modules modules = (Modules) readObject; - is.close(); - fis.close(); - return modules; + public static Modules load(Context context) throws IOException { + String ret = ""; + InputStream inputStream = context.openFileInput(FILE_NAME_TIMESTAMP); + + if (inputStream != null) { + InputStreamReader inputStreamReader = new InputStreamReader(inputStream); + BufferedReader bufferedReader = new BufferedReader(inputStreamReader); + String receiveString; + StringBuilder stringBuilder = new StringBuilder(); + while ((receiveString = bufferedReader.readLine()) != null) { + stringBuilder.append(receiveString); + } + inputStream.close(); + ret = stringBuilder.toString(); + } + + try { + JSONObject json = new JSONObject(ret); + Modules mod = new Modules(json.getString("username")); + JSONArray arr = json.getJSONArray("modules"); + + for (int i = 0; i < arr.length(); i++) { + mod.list.add(Module.); + } + return mod + } catch (JSONException e) { + e.printStackTrace(); + } + return null; } public void save(Context context) throws IOException { - FileOutputStream fos = context.openFileOutput(FILE_NAME, Context.MODE_PRIVATE); - ObjectOutputStream os = new ObjectOutputStream(fos); - os.writeObject(this); - os.close(); - fos.close(); + JSONObject json = new JSONObject(); + JSONArray jModules = new JSONArray(); + try { + json.put("username", mUsername); + json.put("modules", UtilsJson.collectionToJson(list)); + } catch (JSONException e) { + e.printStackTrace(); + } + + mLoadTime = System.currentTimeMillis(); + OutputStreamWriter osw = new OutputStreamWriter(context.openFileOutput(FILE_NAME, Context.MODE_PRIVATE)); + osw.write(json.toString()); + osw.close(); } public void delete(Context context) { @@ -94,27 +132,41 @@ public class Modules implements Iterable, Serializable { return mUsername; } - public void updateList(Modules modules) { + public boolean updateList(Modules modules) { SortedListModule old = this.list; this.list = modules.list; + boolean isChanged = false; for (Module oldModule : old) { Module newModule = this.list.getById(oldModule.getID()); if (newModule != null) { + if (!isChanged && !hashEquals(oldModule, newModule)) + isChanged = true; newModule.announcements = oldModule.announcements; newModule.assignments = oldModule.assignments; newModule.events = oldModule.events; newModule.gradebook = oldModule.gradebook; newModule.resources = oldModule.resources; + } else { + isChanged = true; } } + return isChanged; } - public class Module implements Serializable { + private boolean hashEquals(Module o1, Module o2) { + if (o1 == null && o2 == null) + return true; + else if (o1 == null || o2 == null) + return false; + else + return o1.hashCode() == o2.hashCode(); + } + + public class Module implements UtilsJson.JsonConvertable { @Nullable public final Semester semester; @NotNull final HashSet lvNumber; @NotNull public final String title; - @NotNull - public final ArrayList lecturer; + @NotNull public final ArrayList lecturer; @Nullable public final String type; @Nullable public final String description; @NotNull private final String ID; @@ -124,6 +176,29 @@ public class Modules implements Iterable, Serializable { @Nullable public ArrayList gradebook; @Nullable public ArrayList resources; + @Override + public int hashCode() { + return Objects.hashCode(semester, lvNumber, title, lecturer, type, description, ID); + } + + @Override + public JSONObject toJSONObject() throws JSONException { + JSONObject json = new JSONObject(); + json.put("semester", semester != null ? semester.toJSONObject() : null); + json.put("lvNumber", collectionToJson(lvNumber)); + json.put("title", title); + json.put("lecturer", collectionToJson(lecturer)); + json.put("type", type); + json.put("description", description); + json.put("ID", ID); + json.put("announcements", collectionToJson(announcements)); + json.put("assignments", collectionToJson(assignments)); + json.put("events", collectionToJson(events)); + json.put("gradebook", collectionToJson(gradebook)); + json.put("resources", collectionToJson(resources)); + return json; + } + public float getGradebookPercent(){ float maxPoint = 0; float userPoint = 0; @@ -151,6 +226,27 @@ public class Modules implements Iterable, Serializable { this.ID = ID; } + private Module(JSONObject json) throws JSONException { + HashSet hs = new HashSet<>(); + Iterator it = UtilsJson.jsonArrayToIterator(json.getJSONArray("lvNumber")); + while (it.hasNext()) { + hs. + } + Module(new Semester(json.getJSONObject("semester")), + json.getString("lvNumber"), + json.getString("title"), + json.getJSONObject("lvNumber"), + + json.getString("type"), + json.getString("description"), + json.getString("ID")); + json.put("announcements", collectionToJson(announcements)); + json.put("assignments", collectionToJson(assignments)); + json.put("events", collectionToJson(events)); + json.put("gradebook", collectionToJson(gradebook)); + json.put("resources", collectionToJson(resources)); + } + @NonNull public String getID() { return ID; diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Resource.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Resource.java index 829e53f..6c7820f 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Resource.java +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Resource.java @@ -2,17 +2,21 @@ package de.sebse.fuplanner.services.kvv.types; import com.google.android.gms.common.internal.Objects; +import org.json.JSONException; +import org.json.JSONObject; + import java.io.Serializable; import java.util.ArrayList; import androidx.annotation.LayoutRes; import androidx.annotation.NonNull; import de.sebse.fuplanner.R; +import de.sebse.fuplanner.tools.UtilsJson; import de.sebse.fuplanner.tools.ui.treeview.LayoutItemType; import de.sebse.fuplanner.tools.ui.treeview.TreeNode; -public abstract class Resource implements Serializable { +public abstract class Resource implements UtilsJson.JsonConvertable { final String author; final long modifiedDate; @@ -62,6 +66,19 @@ public abstract class Resource implements Serializable { return Objects.hashCode(getAuthor(), getContainer(), getModifiedDate(), getTitle(), getUrl()); } + @Override + public JSONObject toJSONObject() throws JSONException { + JSONObject json = new JSONObject(); + json.put("author", author); + json.put("modifiedDate", modifiedDate); + json.put("title", title); + json.put("url", url); + json.put("visible", visible); + json.put("container", container); + json.put("restype", ""); + return json; + } + public static class File extends Resource implements LayoutItemType { private final String type; @@ -91,6 +108,14 @@ public abstract class Resource implements Serializable { public @LayoutRes int getLayoutId() { return R.layout.item_file; } + + @Override + public JSONObject toJSONObject() throws JSONException { + JSONObject json = super.toJSONObject(); + json.put("type", type); + json.put("restype", "file"); + return json; + } } public static class Folder extends Resource implements LayoutItemType { @@ -138,6 +163,14 @@ public abstract class Resource implements Serializable { public @LayoutRes int getLayoutId() { return R.layout.item_dir; } + + @Override + public JSONObject toJSONObject() throws JSONException { + JSONObject json = super.toJSONObject(); + json.put("children", UtilsJson.collectionToJson(children)); + json.put("restype", "dir"); + return json; + } } } diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Semester.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Semester.java index 80823cb..95a432d 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Semester.java +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/Semester.java @@ -1,11 +1,15 @@ package de.sebse.fuplanner.services.kvv.types; +import org.json.JSONException; +import org.json.JSONObject; + import java.io.Serializable; import androidx.annotation.Nullable; import de.sebse.fuplanner.tools.Regex; +import de.sebse.fuplanner.tools.UtilsJson; -public class Semester implements Serializable { +public class Semester implements UtilsJson.JsonConvertable { public static final int SEM_WS = 1; public static final int SEM_SS = 2; private int type; @@ -52,4 +56,12 @@ public class Semester implements Serializable { } return false; } + + @Override + public JSONObject toJSONObject() throws JSONException { + JSONObject json = new JSONObject(); + json.put("type", type); + json.put("year", year); + return json; + } } diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/SortedListModule.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/SortedListModule.java index b85f862..7ad170b 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/SortedListModule.java +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/SortedListModule.java @@ -1,5 +1,8 @@ package de.sebse.fuplanner.services.kvv.types; +import org.json.JSONException; +import org.json.JSONObject; + import androidx.annotation.Nullable; import de.sebse.fuplanner.tools.SortedList; diff --git a/app/src/main/java/de/sebse/fuplanner/tools/SortedList.java b/app/src/main/java/de/sebse/fuplanner/tools/SortedList.java index 4d8ff10..b39d036 100644 --- a/app/src/main/java/de/sebse/fuplanner/tools/SortedList.java +++ b/app/src/main/java/de/sebse/fuplanner/tools/SortedList.java @@ -3,12 +3,11 @@ package de.sebse.fuplanner.tools; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; -public abstract class SortedList implements Iterable, Serializable { +public abstract class SortedList implements Iterable { private final ArrayList internalList = new ArrayList<>(); diff --git a/app/src/main/java/de/sebse/fuplanner/tools/UtilsJson.java b/app/src/main/java/de/sebse/fuplanner/tools/UtilsJson.java new file mode 100644 index 0000000..35f9cbc --- /dev/null +++ b/app/src/main/java/de/sebse/fuplanner/tools/UtilsJson.java @@ -0,0 +1,81 @@ +package de.sebse.fuplanner.tools; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; + +import androidx.annotation.Nullable; +import de.sebse.fuplanner.services.kvv.types.Modules; +import de.sebse.fuplanner.services.kvv.types.SortedListModule; + +public class UtilsJson { + public static JSONArray collectionToJson(@Nullable HashSet coll) { + if (coll == null) + return null; + JSONArray arr = new JSONArray(); + for (String e: coll) { + arr.put(e); + } + return arr; + } + + public static JSONArray collectionToJson(@Nullable Collection coll) throws JSONException { + if (coll == null) + return null; + JSONArray arr = new JSONArray(); + for (E e: coll) { + arr.put(e.toJSONObject()); + } + return arr; + } + + public static JSONArray collectionToJson(@Nullable ArrayList coll) throws JSONException { + if (coll == null) + return null; + JSONArray arr = new JSONArray(); + for (String e: coll) { + arr.put(e); + } + return arr; + } + + public static JSONArray collectionToJson(@Nullable SortedList coll) throws JSONException { + if (coll == null) + return null; + JSONArray arr = new JSONArray(); + for (A e: coll) { + arr.put(e.toJSONObject()); + } + return arr; + } + + public static Iterator jsonArrayToIterator(JSONArray array) { + return new Iterator() { + int size = array == null ? 0 : array.length(); + int pos = 0; + @Override + public boolean hasNext() { + return pos < size; + } + + @Override + public Object next() { + try { + return array.get(pos++); + } catch (JSONException e) { + e.printStackTrace(); + return null; + } + } + } + } + + public interface JsonConvertable { + JSONObject toJSONObject() throws JSONException; + } +}