Just a commit while restucturing with API

This commit is contained in:
Caesar2011
2018-05-03 22:41:29 +02:00
parent f2e959df87
commit 58a79fc2c4
13 changed files with 477 additions and 125 deletions

View File

@@ -1,12 +1,24 @@
package de.sebse.fuplanner.fragments.moddetails;
import android.content.Context;
import android.content.res.Resources;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
class ModDetailAdapter extends FragmentPagerAdapter {
public ModDetailAdapter(FragmentManager fm) {
import de.sebse.fuplanner.R;
import de.sebse.fuplanner.tools.logging.Logger;
class ModDetailAdapter extends FragmentStatePagerAdapter {
private final int mItemPos;
private final Context mContext;
private Logger log = new Logger(this);
public ModDetailAdapter(FragmentManager fm, int itemPosition, Context context) {
super(fm);
this.mContext = context;
this.mItemPos = itemPosition;
log.d("constructor");
}
@@ -19,11 +31,12 @@ class ModDetailAdapter extends FragmentPagerAdapter {
// Returns the fragment to display for that page
@Override
public Fragment getItem(int position) {
log.d("getItem");
switch (position) {
case 0: // Fragment # 0 - This will show FirstFragment
return ModDetailOverviewFragment.newInstance("1", "Page # 1");
return ModDetailOverviewFragment.newInstance(mItemPos);
case 1: // Fragment # 0 - This will show FirstFragment different title
return ModDetailAnnounceFragment.newInstance("2", "Page # 2");
return ModDetailAnnounceFragment.newInstance(mItemPos);
default:
return null;
}
@@ -32,7 +45,14 @@ class ModDetailAdapter extends FragmentPagerAdapter {
// Returns the page title for the top indicator
@Override
public CharSequence getPageTitle(int position) {
return "Page " + position;
switch (position) {
case 0:
return this.mContext.getResources().getString(R.string.overview);
case 1:
return this.mContext.getResources().getString(R.string.announcements);
default:
return "";
}
}
}

View File

@@ -8,6 +8,7 @@ import android.view.View;
import android.view.ViewGroup;
import de.sebse.fuplanner.R;
import de.sebse.fuplanner.tools.logging.Logger;
/**
* A simple {@link Fragment} subclass.
@@ -17,12 +18,11 @@ import de.sebse.fuplanner.R;
public class ModDetailAnnounceFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private static final String ARG_POSITION = "itemPosition";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private int mItemPos;
private Logger log = new Logger(this);
public ModDetailAnnounceFragment() {
@@ -33,16 +33,14 @@ public class ModDetailAnnounceFragment extends Fragment {
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @param itemPosition Item position in module list.
* @return A new instance of fragment ModDetailAnnounceFragment.
*/
// TODO: Rename and change types and number of parameters
public static ModDetailAnnounceFragment newInstance(String param1, String param2) {
public static ModDetailAnnounceFragment newInstance(int itemPosition) {
ModDetailAnnounceFragment fragment = new ModDetailAnnounceFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
args.putInt(ARG_POSITION, itemPosition);
fragment.setArguments(args);
return fragment;
}
@@ -51,8 +49,7 @@ public class ModDetailAnnounceFragment extends Fragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
mItemPos = getArguments().getInt(ARG_POSITION);
}
}

View File

@@ -3,13 +3,16 @@ package de.sebse.fuplanner.fragments.moddetails;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import de.sebse.fuplanner.R;
import de.sebse.fuplanner.tools.logging.Logger;
/**
* A simple {@link Fragment} subclass.
@@ -24,11 +27,12 @@ public class ModDetailFragment extends Fragment {
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_POSITION = "itemPosition";
// TODO: Rename and change types of parameters
// Parameters
private int mItemPos;
private OnModuleDetailFragmentInteractionListener mListener;
private ModDetailAdapter adapterViewPager;
private Logger log = new Logger(this);
public ModDetailFragment() {
// Required empty public constructor
@@ -47,6 +51,7 @@ public class ModDetailFragment extends Fragment {
Bundle args = new Bundle();
args.putInt(ARG_POSITION, itemPosition);
fragment.setArguments(args);
Log.d("ModDetailFragment", "newInstance");
return fragment;
}
@@ -56,17 +61,18 @@ public class ModDetailFragment extends Fragment {
if (getArguments() != null) {
mItemPos = getArguments().getInt(ARG_POSITION);
}
log.d("on create");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
log.d("on create view");
View v = inflater.inflate(R.layout.fragment_mod_detail, container, false);
ViewPager vpPager = (ViewPager) v.findViewById(R.id.vpPager);
adapterViewPager = new ModDetailAdapter(getFragmentManager());
adapterViewPager = new ModDetailAdapter(getFragmentManager(), mItemPos, getContext());
vpPager.setAdapter(adapterViewPager);
return v;
}

View File

@@ -2,12 +2,21 @@ package de.sebse.fuplanner.fragments.moddetails;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import de.sebse.fuplanner.MainActivity;
import de.sebse.fuplanner.R;
import de.sebse.fuplanner.services.KVV.KVV;
import de.sebse.fuplanner.services.KVV.Modules;
import de.sebse.fuplanner.tools.logging.Logger;
import de.sebse.fuplanner.tools.network.NetworkCallback;
import de.sebse.fuplanner.tools.network.NetworkError;
import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
/**
* A simple {@link Fragment} subclass.
@@ -17,12 +26,11 @@ import de.sebse.fuplanner.R;
public class ModDetailOverviewFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private static final String ARG_POSITION = "itemPosition";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private int mItemPos;
private Logger log = new Logger(this);
public ModDetailOverviewFragment() {
@@ -33,34 +41,52 @@ public class ModDetailOverviewFragment extends Fragment {
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @param itemPosition Item position in module list.
* @return A new instance of fragment ModDetailOverviewFragment.
*/
// TODO: Rename and change types and number of parameters
public static ModDetailOverviewFragment newInstance(String param1, String param2) {
public static ModDetailOverviewFragment newInstance(int itemPosition) {
ModDetailOverviewFragment fragment = new ModDetailOverviewFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
args.putInt(ARG_POSITION, itemPosition);
fragment.setArguments(args);
String s = "ModDetailOverviewFragment".toString();
Log.d(s, "new Instance");
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
log.d("on create");
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
mItemPos = getArguments().getInt(ARG_POSITION);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_mod_detail_overview, container, false);
log.d("on create");
MainActivity activity = (MainActivity) getActivity();
View view = inflater.inflate(R.layout.fragment_mod_detail_overview, container, false);
if (activity != null) {
KVV kvv = activity.getKVV();
kvv.getModuleDetails(mItemPos, new NetworkCallback<Modules.UpgradeModule>() {
@Override
public void onResponse(@NonNull Modules.UpgradeModule success) {
log.d(success);
success.description = "Neue Beschreibung";
}
}, new NetworkErrorCallback() {
@Override
public void onError(NetworkError error) {
log.e(error);
}
});
}
return view;
}
}

View File

@@ -56,6 +56,20 @@ public class KVV {
});
}
public void getModuleDetails(final int index, final NetworkCallback<Modules.UpgradeModule> callback, final NetworkErrorCallback error) {
this.getLastToken(new LastTokenCallback() {
@Override
public void onReceived(LoginToken token) {
KVVModuleList modules = (KVVModuleList) addons.get("modules");
if (modules == null) {
modules = new KVVModuleList(KVV.this.context, token);
addons.put("modules", modules);
}
modules.getModuleDetails(index, callback, error);
}
});
}
private void getLastToken(LastTokenCallback lastTokenCallback) {
if (this.isUpdating) {
this.updatingList.add(lastTokenCallback);

View File

@@ -6,6 +6,10 @@ import android.support.annotation.NonNull;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -14,6 +18,7 @@ import java.util.regex.MatchResult;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import de.sebse.fuplanner.tools.AsyncQueue;
import de.sebse.fuplanner.tools.network.HTTPService;
import de.sebse.fuplanner.tools.network.NetworkCallback;
import de.sebse.fuplanner.tools.network.NetworkError;
@@ -27,128 +32,199 @@ import de.sebse.fuplanner.tools.network.Result;
public class KVVModuleList extends HTTPService {
private final LoginToken token;
private Modules moduleList;
//private AsyncQueue<NetworkCallback<String>, NetworkErrorCallback> queueUpgradeModule = new AsyncQueue<>();
private AsyncQueue queueModuleDetails = new AsyncQueue();
public KVVModuleList(Context context, LoginToken token) {
super(context);
this.token = token;
}
public void getModuleList(final NetworkCallback<Modules> callback, final NetworkErrorCallback errorCallback) {
/*public void getModuleList(final NetworkCallback<Modules> callback, final NetworkErrorCallback errorCallback) {
if (moduleList != null) {
callback.onResponse(moduleList);
return;
}
get("https://kvv.imp.fu-berlin.de/portal/site/~" + token.getUsername() + "/tool/9df8c796-7d6b-4416-8ba1-f505ea6b8224/", token.getCookies(), new Response.Listener<Result>() {
get("https://kvv.imp.fu-berlin.de/portal/site/~" + token.getUsername(), token.getCookies(), new Response.Listener<Result>() {
@Override
public void onResponse(Result response) {
String location = response.getHeaders().get("Location");
get("https://kvv.imp.fu-berlin.de/portal/site/~"+token.getUsername()+"/tool/9df8c796-7d6b-4416-8ba1-f505ea6b8224/"+location, token.getCookies(), new Response.Listener<Result>() {
// tool/([0-9a-f-]*)"(.|\n|\r){0,200}icon-sakai--fu-berlin-joinablecoursebrowser
String body = response.getParsed();
log.d("FIRST STEP", body);
log.d("FIRST STEP", response.getHeaders().get("Location"));
final String id;
try {
//language=RegExp
id = regex("tool/([0-9a-f-]*)\"(.|\\n|\\r){0,200}icon-sakai--fu-berlin-joinablecoursebrowser", body);
} catch (NoSuchFieldException e) {
errorCallback.onError(new NetworkError(101105, -1, "Cannot parse module list!"));
return;
}
get("https://kvv.imp.fu-berlin.de/portal/site/~" + token.getUsername() + "/tool/9df8c796-7d6b-4416-8ba1-f505ea6b8224/", token.getCookies(), new Response.Listener<Result>() {
@Override
public void onResponse(Result response) {
String body = response.getParsed();
//largeLog("KVVModules", body);
Pattern pattern = Pattern.compile("<tbody>(.*)</tbody>", Pattern.DOTALL);
Matcher matcher = pattern.matcher(body);
if (!matcher.find()) {
errorCallback.onError(new NetworkError(101101, -1, "Cannot parse module list!"));
return;
}
//largeLog("KVVGroup", matcher.group(1));
Modules modules = new Modules();
//<tr.*?>(.|\n)+?</tr>
for (MatchResult match: allMatches(Pattern.compile("<tr.*?>.+?</tr>", Pattern.DOTALL), matcher.group(1))) {
try {
// Instructors
HashSet<String> instructs = new HashSet<>();
String instructors = regex("<td class=\"instructors\">.+?<div>(.+?)</div>.+?</td>", match.group());
for (MatchResult match2: allMatches(Pattern.compile(".*(?=,)"), instructors)) {
if (match2.group()!=null && match2.group().length()>0)
instructs.add(match2.group());
String location = response.getHeaders().get("Location");
get("https://kvv.imp.fu-berlin.de/portal/site/~"+token.getUsername()+"/tool/9df8c796-7d6b-4416-8ba1-f505ea6b8224/"+location, token.getCookies(), new Response.Listener<Result>() {
@Override
public void onResponse(Result response) {
String body = response.getParsed();
//largeLog("KVVModules", body);
Pattern pattern = Pattern.compile("<tbody>(.*)</tbody>", Pattern.DOTALL);
Matcher matcher = pattern.matcher(body);
if (!matcher.find()) {
errorCallback.onError(new NetworkError(101104, -1, "Cannot parse module list!"));
return;
}
for (MatchResult match2: allMatches(Pattern.compile(".*(?=\\s+$|$)"), instructors)) {
if (match2.group()!=null && match2.group().length()>0)
instructs.add(match2.group());
//largeLog("KVVGroup", matcher.group(1));
Modules modules = new Modules();
//<tr.*?>(.|\n)+?</tr>
for (MatchResult match: allMatches(Pattern.compile("<tr.*?>.+?</tr>", Pattern.DOTALL), matcher.group(1))) {
try {
// Instructors
HashSet<String> instructs = new HashSet<>();
String instructors = regex("<td class=\"instructors\">.+?<div>(.+?)</div>.+?</td>", match.group());
for (MatchResult match2: allMatches(Pattern.compile(".*(?=,)"), instructors)) {
if (match2.group()!=null && match2.group().length()>0)
instructs.add(match2.group());
}
for (MatchResult match2: allMatches(Pattern.compile(".*(?=\\s+$|$)"), instructors)) {
if (match2.group()!=null && match2.group().length()>0)
instructs.add(match2.group());
}
// Semester
String semester = regex("<div>((Winter|Sommer)semester.*?)</div>", match.group());
// lvNumber
HashSet<String> lvNumbers = new HashSet<>();
String numbers = regex("<td class=\"vvid\">.*?<div>(.*?)</div", match.group());
for (MatchResult match2: allMatches(Pattern.compile("\\d+"), numbers)) {
if (match2.group()!=null && match2.group().length()>0)
lvNumbers.add(match2.group());
}
// Title
//language=RegExp
String title = regex("<span class=\"fs\"></span>(.+?)</a><span>", match.group());
// Type
//language=RegExp
String type = regex("<td class=\"typelong\">.*?<div>(.*?)</div>", match.group());
// Upgrade URI
//language=RegExp
String upgradeURI = regex("<a href=\"\\./\\?([0-9]*-[0-9]*\\.ILinkListener-tableform-coursetable-body-rows-[0-9]*-cells-[0-9]*-cell-thelink)\"><span class=\"fs\"></span>.+?</a><span>", match.group());
modules.addModule(semester, lvNumbers, title, instructs, type, upgradeURI);
} catch (NoSuchFieldException e) {
errorCallback.onError(new NetworkError(101102, -1, "Cannot parse module list!"));
return;
}
}
// Semester
String semester = regex("<div>((Winter|Sommer)semester.*?)</div>", match.group());
// lvNumber
HashSet<String> lvNumbers = new HashSet<>();
String numbers = regex("<td class=\"vvid\">.*?<div>(.*?)</div", match.group());
for (MatchResult match2: allMatches(Pattern.compile("\\d+"), numbers)) {
if (match2.group()!=null && match2.group().length()>0)
lvNumbers.add(match2.group());
}
// Title
//language=RegExp
String title = regex("<span class=\"fs\"></span>(.+?)</a><span>", match.group());
// Type
//language=RegExp
String type = regex("<td class=\"typelong\">.*?<div>(.*?)</div>", match.group());
// Upgrade URI
//language=RegExp
String upgradeURI = regex("<a href=\"\\./\\?([0-9]*-[0-9]*\\.ILinkListener-tableform-coursetable-body-rows-[0-9]*-cells-[0-9]*-cell-thelink)\"><span class=\"fs\"></span>.+?</a><span>", match.group());
modules.addModule(semester, lvNumbers, title, instructs, type, upgradeURI);
} catch (NoSuchFieldException e) {
errorCallback.onError(new NetworkError(101102, -1, "Cannot parse module list!"));
return;
KVVModuleList.this.moduleList = modules;
callback.onResponse(modules);
}
}
KVVModuleList.this.moduleList = modules;
callback.onResponse(modules);
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
errorCallback.onError(new NetworkError(101101, error.networkResponse.statusCode, "Cannot get module list!"));
}
});
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
errorCallback.onError(new NetworkError(101102, error.networkResponse.statusCode, "Cannot get module list!"));
errorCallback.onError(new NetworkError(101100, error.networkResponse.statusCode, "Cannot get module list!"));
}
});
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
errorCallback.onError(new NetworkError(101100, error.networkResponse.statusCode, "Cannot get module list!"));
errorCallback.onError(new NetworkError(101103, error.networkResponse.statusCode, "Cannot get module list!"));
}
});
}
*/
public void getModuleList(NetworkCallback<Modules> callback, final NetworkErrorCallback errorCallback) {
get("https://kvv.imp.fu-berlin.de/direct/site.json", token.getCookies(), new Response.Listener<Result>() {
@Override
public void onResponse(Result response) {
String body = response.getParsed();
if (body == null) {
errorCallback.onError(new NetworkError(101101, 403, "No module list retreived!"));
return;
}
try {
JSONObject json = new JSONObject(body);
JSONArray sites = json.getJSONArray("site_collection");
for (int i = 0; i < sites.length(); i++) {
JSONObject site = sites.getJSONObject(i);
moduleList = new Modules();
String semester = site.getJSONObject("props").getString("term_eid");
HashSet<String> lvNumbers = new HashSet<>();
for (MatchResult matchResult: allMatches("[0-9]*", site.getJSONObject("props").getString("kvv_lvnumbers"))) {
lvNumbers.add(matchResult.group());
}
String title = site.getJSONObject("props").getString("entityTitle");
HashSet<Lecturer> lecturers = new HashSet<>();
for (String lecturer : site.getJSONObject("props").getString("kvv_lecturers").split("#")) {
lecturers.add(new Lecturer(lecturer));
}
moduleList.addModule(semester, lvNumbers, title, lecturers, "", "");
}
} catch (JSONException e) {
errorCallback.onError(new NetworkError(101102, 403, "Cannot parse module list!"));
return;
} catch (NoSuchFieldException e) {
errorCallback.onError(new NetworkError(101103, 403, "Cannot parse module list!"));
return;
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
errorCallback.onError(new NetworkError(101103, error.networkResponse.statusCode, "Cannot get module list!"));
}
});
}
public void getModuleDetails(final int index, final NetworkCallback<Modules.UpgradeModule> callback, final NetworkErrorCallback errorCallback) {
if (moduleList == null) {
this.getModuleList(new NetworkCallback<Modules>() {
@Override
public void onResponse(@NonNull Modules success) {
getModuleDetails(index, callback, errorCallback);
queueModuleDetails.add(new AsyncQueue.AsyncQueueCallback() {
@Override
public void run() {
if (moduleList == null) {
KVVModuleList.this.getModuleList(new NetworkCallback<Modules>() {
@Override
public void onResponse(@NonNull Modules success) {
getModuleDetails(index, callback, errorCallback);
queueModuleDetails.next();
}
}, queueModuleDetails.check(errorCallback));
return;
}
}, errorCallback);
} else {
Modules.Module m = moduleList.get(index);
if (m instanceof Modules.SimpleModule) {
upgradeModule((Modules.SimpleModule) m, new NetworkCallback<HashMap<String, String>>() {
final Modules.Module m = moduleList.get(index);
if (m instanceof Modules.UpgradeModule) {
callback.onResponse((Modules.UpgradeModule) m);
queueModuleDetails.next();
return;
}
upgradeModule((Modules.SimpleModule) m, new NetworkCallback<String>() {
@Override
public void onResponse(@NonNull HashMap<String, String> success) {
moduleList.upgradeItem(index, success.get("moduleID"), success.get("description"));
callback.onResponse((Modules.UpgradeModule) moduleList.get(index));
public void onResponse(@NonNull String success) {
callback.onResponse(moduleList.upgradeItem(index, success));
queueModuleDetails.next();
}
}, errorCallback);
} else {
callback.onResponse((Modules.UpgradeModule) moduleList.get(index));
}, queueModuleDetails.check(errorCallback));
}
}
});
}
private void upgradeModule(Modules.SimpleModule module, final NetworkCallback<HashMap<String, String>> callback, final NetworkErrorCallback errorCallback) {
HashMap<String, String> success = new HashMap<>();
success.put("moduleID", "cool ID");
success.put("desctiption", "cool desctiption");
callback.onResponse(success);
private void upgradeModule(Modules.SimpleModule module, final NetworkCallback<String> callback, final NetworkErrorCallback errorCallback) {
callback.onResponse("cool ID");
}

View File

@@ -0,0 +1,33 @@
package de.sebse.fuplanner.services.KVV;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Lecturer {
private final String firstname;
private final String surname;
private final String mail;
public Lecturer(String parsableString) throws NoSuchFieldException {
Pattern pattern = Pattern.compile("([^|]*)\\|([^|]*)\\|([^|]*)\\|\\|", Pattern.DOTALL);
Matcher matcher = pattern.matcher(parsableString);
if (!matcher.find()) {
throw new NoSuchFieldException();
}
this.firstname = matcher.group(1);
this.surname = matcher.group(2);
this.mail = matcher.group(3);
}
public String getFirstname() {
return firstname;
}
public String getSurname() {
return surname;
}
public String getMail() {
return mail;
}
}

View File

@@ -1,16 +1,20 @@
package de.sebse.fuplanner.services.KVV;
import android.support.annotation.NonNull;
import android.util.Pair;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import de.sebse.fuplanner.tools.EventEmitter;
import de.sebse.fuplanner.tools.Triplet;
/**
* Created by sebastian on 29.10.17.
*/
public class Modules implements Iterable<Modules.Module> {
public class Modules extends EventEmitter<Triplet<Integer, Modules.UpgradeModule, ArrayList<String>>> implements Iterable<Modules.Module> {
private final ArrayList<Module> list;
Modules() {
@@ -23,10 +27,10 @@ public class Modules implements Iterable<Modules.Module> {
return m;
}
UpgradeModule upgradeItem(int index, String moduleID, String description) {
UpgradeModule upgradeItem(int index, String moduleID) {
Module sm = list.get(index);
if (sm instanceof SimpleModule) {
UpgradeModule um = new UpgradeModule((SimpleModule) sm, moduleID, description);
UpgradeModule um = new UpgradeModule((SimpleModule) sm, moduleID);
list.set(index, um);
return um;
} else {
@@ -34,6 +38,15 @@ public class Modules implements Iterable<Modules.Module> {
}
}
public void setDescription(int index, String description) {
Module entry = this.list.get(index);
if (!(entry instanceof UpgradeModule)) {
return;
}
((UpgradeModule) entry).description = description;
emit(new Triplet<>(index, ((UpgradeModule) entry), new ArrayList<String>()));
}
@NonNull
@Override
public Iterator<Module> iterator() {
@@ -98,7 +111,7 @@ public class Modules implements Iterable<Modules.Module> {
}
public class SimpleModule extends Module {
public final String upgradeURI;
final String upgradeURI;
private SimpleModule(String semester, HashSet<String> lvNumber, String title, HashSet<String> lecturer, String type, String upgradeURI) {
super(semester, lvNumber, title, lecturer, type);
@@ -113,13 +126,12 @@ public class Modules implements Iterable<Modules.Module> {
}
public class UpgradeModule extends Module {
public final String moduleID;
public final String description;
final String moduleID;
public String description = null;
private UpgradeModule(SimpleModule module, String moduleID, String description) {
private UpgradeModule(SimpleModule module, String moduleID) {
super(module.semester, module.lvNumber, module.title, module.lecturer, module.type);
this.moduleID = moduleID;
this.description = description;
}
@Override

View File

@@ -0,0 +1,107 @@
package de.sebse.fuplanner.tools;
import android.support.annotation.NonNull;
import java.util.LinkedList;
import de.sebse.fuplanner.tools.network.NetworkCallback;
import de.sebse.fuplanner.tools.network.NetworkError;
import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
public class AsyncQueue {
private LinkedList<AsyncQueueCallback> mQueue = new LinkedList<>();
private boolean mRunning = false;
public void add(AsyncQueueCallback callback) {
if (mRunning)
mQueue.addLast(callback);
else {
mRunning = true;
callback.run();
}
}
public void next() {
AsyncQueueCallback callback = mQueue.pollFirst();
if (callback == null)
mRunning = false;
else
callback.run();
}
public interface AsyncQueueCallback {
void run();
}
public NetworkErrorCallback check(final NetworkErrorCallback value) {
return new NetworkErrorCallback() {
@Override
public void onError(NetworkError error) {
value.onError(error);
next();
}
};
}
public <T> NetworkCallback<T> check(final NetworkCallback<T> value) {
return new NetworkCallback<T>() {
@Override
public void onResponse(@NonNull T success) {
value.onResponse(success);
next();
}
};
}
}
/*public class AsyncQueue<T, U> {
private ArrayList<T> successes = new ArrayList<>();
private ArrayList<U> errors = new ArrayList<>();
private boolean isRequesting = false;
public void add(T successFunc, U errorFunc) {
this.successes.add(successFunc);
this.errors.add(errorFunc);
}
public void add(T successFunc, U errorFunc, AsyncQueueCallback request) {
this.add(successFunc, errorFunc);
request(request);
}
public void forEachSuccess(AsyncQueueCallbackValue<T> forEach) {
isRequesting = false;
for (T success: this.successes) {
forEach.run(success);
}
this.clear();
}
public void forEachError(AsyncQueueCallbackValue<U> forEach) {
isRequesting = false;
for (U error: this.errors) {
forEach.run(error);
}
this.clear();
}
public void clear() {
this.successes.clear();
this.errors.clear();
}
public void request(AsyncQueueCallback request) {
if (!this.isRequesting) {
this.isRequesting = true;
request.run();
}
}
public interface AsyncQueueCallbackValue<T> {
public void run(T value);
}
public interface AsyncQueueCallback {
public void run();
}
}*/

View File

@@ -0,0 +1,41 @@
package de.sebse.fuplanner.tools;
import java.util.HashSet;
public class EventEmitter<T> {
private T lastValue = null;
private HashSet<EventListener<T>> list = new HashSet<>();
public EventEmitter() {
this(null);
}
protected EventEmitter(T value) {
this.lastValue = value;
}
public boolean emitterAdd(EventListener<T> listener) {
return list.add(listener);
}
public boolean emitterAddEmit(EventListener<T> listener) {
listener.onResponse(this.lastValue);
return list.add(listener);
}
public boolean emitterRemove(EventListener<T> listener) {
return list.remove(listener);
}
protected void emit(T value) {
this.lastValue = value;
for (EventListener<T> emitter: list) {
emitter.onResponse(value);
}
}
public interface EventListener<T> {
void onResponse(T value);
}
}

View File

@@ -0,0 +1,18 @@
package de.sebse.fuplanner.tools;
public class Triplet<T, U, V> {
private final T first;
private final U second;
private final V third;
public Triplet(T first, U second, V third) {
this.first = first;
this.second = second;
this.third = third;
}
public T getFirst() { return first; }
public U getSecond() { return second; }
public V getThird() { return third; }
}

View File

@@ -8,4 +8,6 @@
<!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment">Hello blank fragment</string>
<string name="overview">Overview</string>
<string name="announcements">Announcements</string>
</resources>