diff --git a/README.md b/README.md index 8fca27a3..e5c62abf 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,6 @@ Below you find the currently supported substitution schedule softwares and the c * svPlan ([example](http://bls.infoboard-schleswig.de/dav/schueler1.html)) `"svplan"` * DaVinci ([example](http://hochtaunusschule.de/Vertretungsplan/)) `"davinci"` * ESchool ([example](http://eschool.topackt.com/?wp=d7406384445ce1fc9409bc90f95ccef5&go=vplan&content=x1)) `"eschool"` -* [LegionBoard](https://legionboard.dorfbrunnen.eu/) `"legionboard"` * Indiware * XML export ([example](https://francisceum.de/vertretung/mo.xml)) `"indiware"` * XML export converted to HTML ([example](http://v-plan.gymnasium-nossen.de/v_plan_komplett/vplan_sch_html.html)) `"indiware"` diff --git a/parser/build.gradle b/parser/build.gradle index efa32421..c3356dba 100644 --- a/parser/build.gradle +++ b/parser/build.gradle @@ -13,13 +13,13 @@ compileTestJava.options.encoding = 'UTF-8' dependencies { compile 'joda-time:joda-time:2.8.1' - compile 'org.jsoup:jsoup:1.9.2' + compile 'org.jsoup:jsoup:1.15.3' compile 'org.apache.httpcomponents:fluent-hc:4.5.3' compile 'org.apache.httpcomponents:httpmime:4.5.3' - compile 'org.json:json:20090211' + compile 'org.json:json:20231013' compile 'org.apache.commons:commons-lang3:3.4' compile 'org.jetbrains:annotations:13.0' - compile 'commons-io:commons-io:2.5' + compile 'commons-io:commons-io:2.7' compile 'com.github.mifmif:generex:1.0.2' compile 'net.sf.biweekly:biweekly:0.6.1' compile 'com.googlecode.juniversalchardet:juniversalchardet:1.0.3' diff --git a/parser/src/main/java/me/vertretungsplan/additionalinfo/WinterShParser.java b/parser/src/main/java/me/vertretungsplan/additionalinfo/WinterShParser.java index 4cc59d0d..4ee8b87a 100644 --- a/parser/src/main/java/me/vertretungsplan/additionalinfo/WinterShParser.java +++ b/parser/src/main/java/me/vertretungsplan/additionalinfo/WinterShParser.java @@ -18,7 +18,7 @@ /** * Parser information about cancellation of classes caused by snow or other extreme weather conditions provided as an * RSS feed by the Ministry of Education of Schleswig-Holstein, Germany. - * Same as http://www.schleswig-holstein.de/DE/Landesregierung/III/Service/winterhotline/Winterhotline.html + * Same as ... * Can be used for all public and vocational schools in Schleswig-Holstein. */ public class WinterShParser extends BaseAdditionalInfoParser { diff --git a/parser/src/main/java/me/vertretungsplan/objects/Substitution.java b/parser/src/main/java/me/vertretungsplan/objects/Substitution.java index 8e8bf1dd..3e08586c 100644 --- a/parser/src/main/java/me/vertretungsplan/objects/Substitution.java +++ b/parser/src/main/java/me/vertretungsplan/objects/Substitution.java @@ -105,7 +105,7 @@ public void setClasses(Set classes) { /** * Get the lesson which this substitution is for. - * + *

* Keep it short, the recommended format is e.g. "1" for single lessons and "5-6" for multiple lessons. But some * schools use different ways to name their lessons. * @@ -117,7 +117,7 @@ public String getLesson() { /** * Set the lesson which this substitution is for. - * + *

* Keep it short, the recommended format is e.g. "1" for single lessons and "5-6" for multiple lessons. But some * schools use different ways to name their lessons. Required. * @@ -190,7 +190,7 @@ public void setPreviousSubject(String previousSubject) { * @return the teacher */ public String getTeacher() { - return teachers.size() > 0 ? SubstitutionTextUtils.joinTeachers(teachers) : null; + return !teachers.isEmpty() ? SubstitutionTextUtils.joinTeachers(teachers) : null; } /** @@ -231,7 +231,7 @@ public void setTeachers(Set teachers) { * @return the previous teacher */ public String getPreviousTeacher() { - return previousTeachers.size() > 0 ? SubstitutionTextUtils.joinTeachers(previousTeachers) : null; + return !previousTeachers.isEmpty() ? SubstitutionTextUtils.joinTeachers(previousTeachers) : null; } /** diff --git a/parser/src/main/java/me/vertretungsplan/objects/SubstitutionSchedule.java b/parser/src/main/java/me/vertretungsplan/objects/SubstitutionSchedule.java index eb6d0d1a..15ac2502 100644 --- a/parser/src/main/java/me/vertretungsplan/objects/SubstitutionSchedule.java +++ b/parser/src/main/java/me/vertretungsplan/objects/SubstitutionSchedule.java @@ -454,11 +454,11 @@ public String toString() { builder.append("website: ").append(website).append("\n"); if (classes != null) { - builder.append("classes: ").append(classes.toString()).append("\n"); + builder.append("classes: ").append(classes).append("\n"); } if (teachers != null) { - builder.append("teachers: ").append(teachers.toString()).append("\n"); + builder.append("teachers: ").append(teachers).append("\n"); } builder.append("\n\n"); @@ -467,7 +467,7 @@ public String toString() { for (SubstitutionScheduleDay day : days) builder.append(day.toString(type)).append("\n\n"); - if (additionalInfos.size() > 0) { + if (!additionalInfos.isEmpty()) { builder.append("Additional Infos\n"); builder.append("----------------\n\n"); diff --git a/parser/src/main/java/me/vertretungsplan/objects/SubstitutionScheduleData.java b/parser/src/main/java/me/vertretungsplan/objects/SubstitutionScheduleData.java index 391a25e6..3a320f8c 100644 --- a/parser/src/main/java/me/vertretungsplan/objects/SubstitutionScheduleData.java +++ b/parser/src/main/java/me/vertretungsplan/objects/SubstitutionScheduleData.java @@ -72,7 +72,6 @@ public String getApi() { *

  • {@code "davinci"}
  • *
  • {@code "turbovertretung"}
  • *
  • {@code "csv"}
  • - *
  • {@code "legionboard"}
  • * * * @param api the type of parser to use @@ -86,7 +85,7 @@ public void setApi(String api) { * {@link me.vertretungsplan.additionalinfo.BaseAdditionalInfoParser#getInstance(String)} to create a suitable * parser instance. * - * @return the set of additional info types + * @return the list of additional info types */ public List getAdditionalInfos() { return additionalInfos; diff --git a/parser/src/main/java/me/vertretungsplan/objects/credential/Credential.java b/parser/src/main/java/me/vertretungsplan/objects/credential/Credential.java index 88c3c8fb..610429d3 100644 --- a/parser/src/main/java/me/vertretungsplan/objects/credential/Credential.java +++ b/parser/src/main/java/me/vertretungsplan/objects/credential/Credential.java @@ -16,7 +16,7 @@ public interface Credential { * This can be used to differentiate between two credentials or to allow a user to authenticate to an application * which uses this parser. It should not be used by {@link me.vertretungsplan.parser.SubstitutionScheduleParser} * implementations, especially not if they depend on a specific hashing algorithm. - * + *

    * For two Credential objects a and b, the following relation should apply: * a.getHash().equals(b.getHash()) if and only if a.getLoginData().equals(b.getLoginData()) * diff --git a/parser/src/main/java/me/vertretungsplan/parser/BaseParser.java b/parser/src/main/java/me/vertretungsplan/parser/BaseParser.java index 8025b274..50fa4613 100644 --- a/parser/src/main/java/me/vertretungsplan/parser/BaseParser.java +++ b/parser/src/main/java/me/vertretungsplan/parser/BaseParser.java @@ -184,9 +184,6 @@ public static BaseParser getInstance(SubstitutionScheduleData data, @Nullable Co case "csv": parser = new CSVParser(data, cookieProvider); break; - case "legionboard": - parser = new LegionBoardParser(data, cookieProvider); - break; case "iphis": parser = new IphisParser(data, cookieProvider); break; @@ -248,7 +245,7 @@ private static X509TrustManager trustManagerFromKeystore( for (final TrustManager tm : tms) { if (tm instanceof X509TrustManager) { - return X509TrustManager.class.cast(tm); + return (X509TrustManager) tm; } } throw new IllegalStateException("Could not locate X509TrustManager!"); @@ -577,7 +574,7 @@ public void setLocalSource(Path localSource) { this.localSource = localSource; } - private class CustomHostnameVerifier implements HostnameVerifier { + private static class CustomHostnameVerifier implements HostnameVerifier { private String host; private DefaultHostnameVerifier defaultHostnameVerifier; @@ -596,7 +593,7 @@ public boolean isPersonal() { return false; } - private class NoOpDebuggingDataHandler implements DebuggingDataHandler { + private static class NoOpDebuggingDataHandler implements DebuggingDataHandler { @Override public void columnTitles(List columnTitles) { } diff --git a/parser/src/main/java/me/vertretungsplan/parser/CSVParser.java b/parser/src/main/java/me/vertretungsplan/parser/CSVParser.java index 2ff3f053..eb734635 100644 --- a/parser/src/main/java/me/vertretungsplan/parser/CSVParser.java +++ b/parser/src/main/java/me/vertretungsplan/parser/CSVParser.java @@ -31,10 +31,9 @@ import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; import java.security.GeneralSecurityException; import java.util.*; -import java.util.ArrayList; -import java.util.List; import java.util.regex.Matcher; /** @@ -127,7 +126,7 @@ public SubstitutionSchedule getSubstitutionSchedule() throws IOException, JSONEx schedule.setLastChange(modified); } InputStream stream = client.get(new URI(httpUrl).resolve(file.getHref()).toString()); - parseCSV(IOUtils.toString(stream, "UTF-8"), schedule); + parseCSV(IOUtils.toString(stream, StandardCharsets.UTF_8), schedule); } } } catch (GeneralSecurityException | URISyntaxException e) { @@ -154,7 +153,7 @@ public SubstitutionSchedule getSubstitutionSchedule() throws IOException, JSONEx schedule.setLastChange(modified); } InputStream stream = client.get(new URI(httpUrl).resolve(file.getHref()).toString()); - schedule = parseCSVAdditionalInfos(IOUtils.toString(stream, "UTF-8"), schedule); + schedule = parseCSVAdditionalInfos(IOUtils.toString(stream, StandardCharsets.UTF_8), schedule); } } } catch (GeneralSecurityException | URISyntaxException e) { @@ -208,7 +207,7 @@ SubstitutionSchedule parseCSVAdditionalInfos(String response, SubstitutionSchedu } j++; } - if (info.getText() != null && !info.getText().trim().equals("")) { + if (info.getText() != null && !info.getText().trim().isEmpty()) { Boolean isDayMessage = false; for (SubstitutionScheduleDay day : schedule.getDays()) { if (day.getDate().equals(ParserUtils.parseDate(info.getTitle()))) { diff --git a/parser/src/main/java/me/vertretungsplan/parser/ColumnTypeDetector.java b/parser/src/main/java/me/vertretungsplan/parser/ColumnTypeDetector.java index 25194d2c..8894c369 100644 --- a/parser/src/main/java/me/vertretungsplan/parser/ColumnTypeDetector.java +++ b/parser/src/main/java/me/vertretungsplan/parser/ColumnTypeDetector.java @@ -15,6 +15,7 @@ import java.io.IOException; import java.io.InputStream; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -26,7 +27,7 @@ public class ColumnTypeDetector { public ColumnTypeDetector() throws IOException, JSONException { columns = new HashMap<>(); InputStream is = getClass().getClassLoader().getResourceAsStream("column_headers.json"); - String content = IOUtils.toString(is, "UTF-8"); + String content = IOUtils.toString(is, StandardCharsets.UTF_8); JSONObject json = new JSONObject(content); for (Iterator it = json.keys(); it.hasNext(); ) { String type = (String) it.next(); diff --git a/parser/src/main/java/me/vertretungsplan/parser/DaVinciParser.java b/parser/src/main/java/me/vertretungsplan/parser/DaVinciParser.java index f126012e..43e156d0 100644 --- a/parser/src/main/java/me/vertretungsplan/parser/DaVinciParser.java +++ b/parser/src/main/java/me/vertretungsplan/parser/DaVinciParser.java @@ -100,7 +100,7 @@ static void parseDaVinciTable(Element table, SubstitutionSchedule v, String klas for (Element header : table.select("thead tr th")) { headers.add(header.text()); } - if (headers.size() == 0) { + if (headers.isEmpty()) { skipRow = true; for (Element header : table.select(" tr:first-child td")) { headers.add(header.text()); @@ -321,13 +321,13 @@ public SubstitutionSchedule getSubstitutionSchedule() throws IOException, JSONEx static List getDayUrls(String url, Document doc) throws IOException { List dayUrls = new ArrayList<>(); - if (doc.select("ul.classes").size() > 0) { + if (!doc.select("ul.classes").isEmpty()) { // List of classes Elements classes = doc.select("ul.classes li a"); for (Element klasse : classes) { dayUrls.add(new URL(new URL(url), klasse.attr("href")).toString()); } - } else if (doc.select("ul.month").size() > 0) { + } else if (!doc.select("ul.month").isEmpty()) { // List of days in calendar view Elements days = doc.select("ul.month li input[onclick]"); for (Element day : days) { @@ -335,13 +335,13 @@ static List getDayUrls(String url, Document doc) if (urlFromOnclick == null) continue; dayUrls.add(new URL(new URL(url), urlFromOnclick).toString()); } - } else if (doc.select("ul.day-index").size() > 0) { + } else if (!doc.select("ul.day-index").isEmpty()) { // List of days in list view Elements days = doc.select("ul.day-index li a"); for (Element day : days) { dayUrls.add(new URL(new URL(url), day.attr("href")).toString()); } - } else if (doc.select("table td[align=left] a").size() > 0) { + } else if (!doc.select("table td[align=left] a").isEmpty()) { // Table of classes (DaVinci 5) Elements classes = doc.select("table td[align=left] a"); for (Element klasse : classes) { @@ -369,7 +369,7 @@ static void parsePage(Element doc, SubstitutionSchedule schedule, ColorProvider SubstitutionScheduleDay day = new SubstitutionScheduleDay(); Element titleElem; - if (doc.select("h1.list-table-caption").size() > 0) { + if (!doc.select("h1.list-table-caption").isEmpty()) { titleElem = doc.select("h1.list-table-caption").first(); } else { // DaVinci 5 @@ -454,7 +454,7 @@ static void parsePage(Element doc, SubstitutionSchedule schedule, ColorProvider } } - if (doc.select(".list-table").size() > 0 || !doc.select(".callout").text().contains("Es liegen keine")) { + if (!doc.select(".list-table").isEmpty() || !doc.select(".callout").text().contains("Es liegen keine")) { Element table = doc.select(".list-table, table").first(); parseDaVinciTable(table, schedule, klasse, day, colorProvider); } @@ -471,7 +471,7 @@ public List getAllClasses() throws IOException, JSONException, Credentia Document doc = Jsoup.parse(httpGet(scheduleData.getData().getString("classesSource"), ENCODING)); List classes = new ArrayList<>(); Elements elems = doc.select("li.Class"); - if (elems.size() == 0) { + if (elems.isEmpty()) { // daVinci 5 elems = doc.select("td[align=left] a"); } diff --git a/parser/src/main/java/me/vertretungsplan/parser/ESchoolParser.java b/parser/src/main/java/me/vertretungsplan/parser/ESchoolParser.java index 7f6c871c..a2f78da4 100644 --- a/parser/src/main/java/me/vertretungsplan/parser/ESchoolParser.java +++ b/parser/src/main/java/me/vertretungsplan/parser/ESchoolParser.java @@ -86,7 +86,7 @@ public SubstitutionSchedule getSubstitutionSchedule() String url = BASE_URL + "?" + URLEncodedUtils.format(nvps, "UTF-8"); Document doc = Jsoup.parse(httpGet(url, ENCODING)); - if (doc.select("form[name=loginform]").size() > 0 + if (!doc.select("form[name=loginform]").isEmpty() && scheduleData.getAuthenticationData() instanceof PasswordAuthenticationData) { // Login required List formParams = new ArrayList<>(); @@ -150,7 +150,7 @@ private void parseTable(Element table, SubstitutionScheduleDay day) { // skip over table headers Element row = th.parent().nextElementSibling().nextElementSibling(); - while (row != null && row.select("th").size() == 0) { + while (row != null && row.select("th").isEmpty()) { Substitution subst = new Substitution(); subst.setLesson(lesson); diff --git a/parser/src/main/java/me/vertretungsplan/parser/IndiwareMobileParser.java b/parser/src/main/java/me/vertretungsplan/parser/IndiwareMobileParser.java index f731cd5c..dfd8d856 100644 --- a/parser/src/main/java/me/vertretungsplan/parser/IndiwareMobileParser.java +++ b/parser/src/main/java/me/vertretungsplan/parser/IndiwareMobileParser.java @@ -83,7 +83,7 @@ public IndiwareMobileParser(SubstitutionScheduleData scheduleData, CookieProvide lastException = e; } } - if (docs.size() == 0 && lastException != null) { + if (docs.isEmpty() && lastException != null) { throw lastException; } @@ -121,7 +121,7 @@ static SubstitutionScheduleDay parseDay(Document doc, ColorProvider colorProvide HashSet classes = new HashSet<>(); classes.add(className); for (Element lesson:klasse.select("Pl > Std")) { - if (lesson.select("If:not(:empty), Le[LeAe], Ra[RaAe], Fa[FaAe]").size() == 0) { + if (lesson.select("If:not(:empty), Le[LeAe], Ra[RaAe], Fa[FaAe]").isEmpty()) { continue; } diff --git a/parser/src/main/java/me/vertretungsplan/parser/IndiwareParser.java b/parser/src/main/java/me/vertretungsplan/parser/IndiwareParser.java index 34a58a82..33967778 100644 --- a/parser/src/main/java/me/vertretungsplan/parser/IndiwareParser.java +++ b/parser/src/main/java/me/vertretungsplan/parser/IndiwareParser.java @@ -186,7 +186,7 @@ void parseIndiwarePage(SubstitutionSchedule v, String response) throws JSONExcep if (html && data.has(PARAM_EMBEDDED_CONTENT_SELECTOR)) { String selector = data.getString(PARAM_EMBEDDED_CONTENT_SELECTOR); Elements elems = doc.select(selector); - if (elems.size() == 0) throw new IOException("No elements found using " + selector); + if (elems.isEmpty()) throw new IOException("No elements found using " + selector); for (Element elem : elems) { v.addDay(parseIndiwareDay(elem, true)); } @@ -340,7 +340,7 @@ SubstitutionScheduleDay parseIndiwareDay(Element doc, boolean html) throws IOExc day.setLastChange(DateTimeFormat.forPattern("dd.MM.yyyy, HH:mm") .withLocale(Locale.GERMAN).parseLocalDateTime(lastChange)); - if (ds.kopfinfos().size() > 0) { + if (!ds.kopfinfos().isEmpty()) { for (Element kopfinfo : ds.kopfinfos()) { String title = html ? kopfinfo.select("th").text() : kopfinfoTitle(kopfinfo.tagName()) + ":"; @@ -420,7 +420,7 @@ SubstitutionScheduleDay parseIndiwareDay(Element doc, boolean html) throws IOExc case "fach": String subject = subjectAndCourse(course, value); if (html ? columnTypes.contains("vfach") : - aktion.getElementsByTag("vfach").size() > 0) { + !aktion.getElementsByTag("vfach").isEmpty()) { substitution.setPreviousSubject(subject); } else { substitution.setSubject(subject); @@ -434,7 +434,7 @@ SubstitutionScheduleDay parseIndiwareDay(Element doc, boolean html) throws IOExc value = bracesMatcher.group(1); substitution.setPreviousTeachers(splitTeachers(value, splitTeachers)); } else if (html ? columnTypes.contains("vlehrer") : - aktion.getElementsByTag("vlehrer").size() > 0) { + !aktion.getElementsByTag("vlehrer").isEmpty()) { substitution.setPreviousTeachers(splitTeachers(value, splitTeachers)); } else { substitution.setTeachers(splitTeachers(value, splitTeachers)); diff --git a/parser/src/main/java/me/vertretungsplan/parser/IphisParser.java b/parser/src/main/java/me/vertretungsplan/parser/IphisParser.java index 06ab347b..dbf0d0e3 100644 --- a/parser/src/main/java/me/vertretungsplan/parser/IphisParser.java +++ b/parser/src/main/java/me/vertretungsplan/parser/IphisParser.java @@ -336,7 +336,7 @@ private Substitution getSubstitution(JSONObject change, HashMap } final HashSet classes = new HashSet<>(); for (String classId : classIds) { - if (!classId.toLowerCase().equals("null")) { + if (!classId.equalsIgnoreCase("null")) { if (gradesHashMap.containsKey(classId)) { classes.add(gradesHashMap.get(classId)); } else { @@ -348,7 +348,7 @@ private Substitution getSubstitution(JSONObject change, HashMap } // Set type final String type = change.getString("aenderungsgrund").trim(); - if (!type.isEmpty() && !type.toLowerCase().equals("null")) { + if (!type.isEmpty() && !type.equalsIgnoreCase("null")) { substitution.setType(type); } else { substitution.setType("Vertretung"); @@ -364,7 +364,7 @@ private Substitution getSubstitution(JSONObject change, HashMap throw new IOException("Change references a covering teacher but teachers are empty."); } for (String coveringTeacherId : coveringTeacherIds) { - if (!coveringTeacherId.toLowerCase().equals("null") && teachersHashMap.get(coveringTeacherId) != null) { + if (!coveringTeacherId.equalsIgnoreCase("null") && teachersHashMap.get(coveringTeacherId) != null) { coveringTeachers.add(teachersHashMap.get(coveringTeacherId)); } } @@ -378,7 +378,7 @@ private Substitution getSubstitution(JSONObject change, HashMap throw new IOException("Change references a teacher but teachers are empty."); } for (String teacherId : teacherIds) { - if (!teacherId.toLowerCase().equals("null") && teachersHashMap.get(teacherId) != null) { + if (!teacherId.equalsIgnoreCase("null") && teachersHashMap.get(teacherId) != null) { teachers.add(teachersHashMap.get(teacherId)); } } @@ -386,42 +386,42 @@ private Substitution getSubstitution(JSONObject change, HashMap } //Set room - if (!change.optString("raum").isEmpty() && !change.optString("raum").toLowerCase().equals("null")) { + if (!change.optString("raum").isEmpty() && !change.optString("raum").equalsIgnoreCase("null")) { substitution.setRoom(change.optString("raum")); } else if (!change.optString("raum_orig").isEmpty() && - !change.optString("raum_orig").toLowerCase().equals("null")) { + !change.optString("raum_orig").equalsIgnoreCase("null")) { substitution.setRoom(change.optString("raum_orig")); } - if (!change.optString("raum_orig").isEmpty() && !change.optString("raum_orig").toLowerCase().equals("null")) { + if (!change.optString("raum_orig").isEmpty() && !change.optString("raum_orig").equalsIgnoreCase("null")) { substitution.setPreviousRoom(change.optString("raum_orig")); - } else if (!change.optString("raum").isEmpty() && !change.optString("raum").toLowerCase().equals("null")) { + } else if (!change.optString("raum").isEmpty() && !change.optString("raum").equalsIgnoreCase("null")) { substitution.setPreviousRoom(change.optString("raum")); } //Set subject - if (!change.optString("fach").isEmpty() && !change.optString("fach").toLowerCase().equals("null")) { + if (!change.optString("fach").isEmpty() && !change.optString("fach").equalsIgnoreCase("null")) { substitution.setSubject(change.optString("fach")); } - if (!change.optString("fach_orig").isEmpty() && !change.optString("fach_orig").toLowerCase().equals("null")) { + if (!change.optString("fach_orig").isEmpty() && !change.optString("fach_orig").equalsIgnoreCase("null")) { substitution.setPreviousSubject(change.optString("fach_orig")); } //Set description if (!change.getString("information").isEmpty() && - !change.getString("information").toLowerCase().equals("null")) { + !change.getString("information").equalsIgnoreCase("null")) { substitution.setDesc(change.getString("information").trim()); } final String startingHour = change.getString("zeit_von").replaceFirst("^0+(?!$)", ""); final String endingHour = change.getString("zeit_bis").replaceFirst("^0+(?!$)", ""); - if (!startingHour.equals("") || !endingHour.equals("")) { + if (!startingHour.isEmpty() || !endingHour.isEmpty()) { String lesson = ""; - if (!startingHour.equals("") && endingHour.equals("")) { + if (!startingHour.isEmpty() && endingHour.isEmpty()) { lesson = "Ab " + startingHour; } - if (startingHour.equals("") && !endingHour.equals("")) { + if (startingHour.isEmpty() && !endingHour.isEmpty()) { lesson = "Bis " + endingHour; } - if (!startingHour.equals("") && !endingHour.equals("")) { + if (!startingHour.isEmpty() && !endingHour.isEmpty()) { lesson = startingHour + " - " + endingHour; } if (startingHour.equals(endingHour)) { diff --git a/parser/src/main/java/me/vertretungsplan/parser/LegionBoardParser.java b/parser/src/main/java/me/vertretungsplan/parser/LegionBoardParser.java deleted file mode 100644 index 01e47dd3..00000000 --- a/parser/src/main/java/me/vertretungsplan/parser/LegionBoardParser.java +++ /dev/null @@ -1,322 +0,0 @@ -/* - * substitution-schedule-parser - Java library for parsing schools' substitution schedules - * Copyright (c) 2016 Johan v. Forstner - * Copyright (c) 2016 Nico Alt - * - * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. - * If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.vertretungsplan.parser; - -import me.vertretungsplan.exception.CredentialInvalidException; -import me.vertretungsplan.objects.Substitution; -import me.vertretungsplan.objects.SubstitutionSchedule; -import me.vertretungsplan.objects.SubstitutionScheduleData; -import me.vertretungsplan.objects.SubstitutionScheduleDay; -import me.vertretungsplan.objects.credential.Credential; -import me.vertretungsplan.objects.credential.UserPasswordCredential; -import org.apache.commons.codec.digest.DigestUtils; -import org.apache.http.client.HttpResponseException; -import org.joda.time.LocalDate; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import com.paour.comparator.NaturalOrderComparator; - -import java.io.IOException; -import java.util.*; - -/** - * Parser for LegionBoard, an open source changes management system for schools. - *

    - * More information can be found on the official website and on its - * project page on GitLab. - *

    - * This parser can be accessed using "legionboard" for {@link SubstitutionScheduleData#setApi(String)}. - * - *

    Configuration parameters

    - * These parameters can be supplied in {@link SubstitutionScheduleData#setData(JSONObject)} to configure the parser: - * - *
    - *
    api (String, required)
    - *
    The URL where the LegionBoard Heart API can be found.
    - * - *
    website (String, recommended)
    - *
    The URL of a website where the substitution schedule can be seen online. Normally, this would be the URL of the - * LegionBoard Eye instance.
    - *
    - * - * You have to use a {@link me.vertretungsplan.objects.authentication.UserPasswordAuthenticationData} because all - * schedules on LegionBoard are protected by a login. - */ -public class LegionBoardParser extends BaseParser { - - private static final String PARAM_API = "api"; - private static final String PARAM_WEBSITE = "website"; - - /** - * URL of given LegionBoard Heart instance - */ - private String api; - - /** - * URL of given LegionBoard Eye instance - */ - private String website; - - public LegionBoardParser(SubstitutionScheduleData scheduleData, CookieProvider cookieProvider) { - super(scheduleData, cookieProvider); - JSONObject data = scheduleData.getData(); - try { - api = data.getString(PARAM_API); - website = data.getString(PARAM_WEBSITE); - } catch (JSONException e) { - e.printStackTrace(); - } - } - - public SubstitutionSchedule getSubstitutionSchedule() throws IOException, JSONException, CredentialInvalidException { - final SubstitutionSchedule substitutionSchedule = SubstitutionSchedule.fromData(scheduleData); - substitutionSchedule.setClasses(getAllClasses()); - substitutionSchedule.setTeachers(getAllTeachers()); - substitutionSchedule.setWebsite(website); - final JSONArray changes = getChanges(); - final JSONArray courses = getCourses(); - final JSONArray teachers = getTeachers(); - - parseLegionBoard(substitutionSchedule, changes, courses, teachers); - return substitutionSchedule; - } - - /** - * Returns authentication key as shown - * in the documentation. - */ - private String getAuthenticationKey(Credential credential) { - final UserPasswordCredential userPasswordCredential = (UserPasswordCredential) credential; - final String username = userPasswordCredential.getUsername(); - final String password = userPasswordCredential.getPassword(); - return DigestUtils.sha256Hex(username.toLowerCase() + "//" + password); - } - - /** - * Returns a JSONArray with all changes from now to in one week. - * More information: List changes - */ - private JSONArray getChanges() throws IOException, JSONException, CredentialInvalidException { - // Date (or alias of date) when the changes start - final String startBy = "now"; - // Date (or alias of date) when the changes end - final String endBy = "i1w"; - - final String url = api + "/changes?startBy=" + startBy + "&endBy=" + endBy + "&k=" + getAuthenticationKey(getCredential()); - return getJSONArray(url); - } - - /** - * Returns a JSONArray with all courses. - * More information: List courses - */ - private JSONArray getCourses() throws IOException, JSONException, CredentialInvalidException { - final String url = api + "/courses?k=" + getAuthenticationKey(getCredential()); - return getJSONArray(url); - } - - /** - * Returns a JSONArray with all teachers. - * More information: List teachers - */ - private JSONArray getTeachers() throws IOException, JSONException, CredentialInvalidException { - final String url = api + "/teachers?k=" + getAuthenticationKey(getCredential()); - return getJSONArray(url); - } - - private JSONArray getJSONArray(String url) throws IOException, JSONException, CredentialInvalidException { - try { - return new JSONArray(httpGet(url, "UTF-8")); - } catch (HttpResponseException httpResponseException) { - if (httpResponseException.getStatusCode() == 404) { - return null; - } - throw httpResponseException; - } - } - - void parseLegionBoard(SubstitutionSchedule substitutionSchedule, JSONArray changes, JSONArray courses, - JSONArray teachers) throws IOException, JSONException { - if (changes == null) { - return; - } - // Link course IDs to their names - HashMap coursesHashMap = null; - if (courses != null) { - coursesHashMap = new HashMap<>(); - for (int i = 0; i < courses.length(); i++) { - JSONObject course = courses.getJSONObject(i); - coursesHashMap.put(course.getString("id"), course.getString("name")); - } - } - // Link teacher IDs to their names - HashMap teachersHashMap = null; - if (teachers != null) { - teachersHashMap = new HashMap<>(); - for (int i = 0; i < teachers.length(); i++) { - JSONObject teacher = teachers.getJSONObject(i); - teachersHashMap.put(teacher.getString("id"), teacher.getString("name")); - } - } - // Add changes to SubstitutionSchedule - LocalDate currentDate = LocalDate.now(); - SubstitutionScheduleDay substitutionScheduleDay = new SubstitutionScheduleDay(); - substitutionScheduleDay.setDate(currentDate); - for (int i = 0; i < changes.length(); i++) { - final JSONObject change = changes.getJSONObject(i); - final Substitution substitution = getSubstitution(change, coursesHashMap, teachersHashMap); - final LocalDate startingDate = new LocalDate(change.getString("startingDate")); - final LocalDate endingDate = new LocalDate(change.getString("endingDate")); - // Handle multi-day changes - if (!startingDate.isEqual(endingDate)) { - if (!substitutionScheduleDay.getSubstitutions().isEmpty()) { - substitutionSchedule.addDay(substitutionScheduleDay); - } - for (int k = 0; k < 8; k++) { - final LocalDate date = LocalDate.now().plusDays(k); - if ((date.isAfter(startingDate) || date.isEqual(startingDate)) && - (date.isBefore(endingDate) || date.isEqual(endingDate))) { - substitutionScheduleDay = new SubstitutionScheduleDay(); - substitutionScheduleDay.setDate(date); - substitutionScheduleDay.addSubstitution(substitution); - substitutionSchedule.addDay(substitutionScheduleDay); - currentDate = date; - } - } - continue; - } - // If starting date of change does not equal date of SubstitutionScheduleDay - if (!startingDate.isEqual(currentDate)) { - if (!substitutionScheduleDay.getSubstitutions().isEmpty()) { - substitutionSchedule.addDay(substitutionScheduleDay); - } - substitutionScheduleDay = new SubstitutionScheduleDay(); - substitutionScheduleDay.setDate(startingDate); - currentDate = startingDate; - } - substitutionScheduleDay.addSubstitution(substitution); - } - substitutionSchedule.addDay(substitutionScheduleDay); - } - - private Substitution getSubstitution(JSONObject change, HashMap coursesHashMap, HashMap teachersHashMap) throws IOException, JSONException { - final Substitution substitution = new Substitution(); - // Set class - final String classId = change.getString("course"); - if (!classId.equals("0")) { - if (coursesHashMap == null) { - throw new IOException("Change references a course but courses are empty."); - } - final String singleClass = coursesHashMap.get(classId); - final HashSet classes = new HashSet<>(); - classes.add(singleClass); - substitution.setClasses(classes); - } - // Set type - String type = "Unknown"; - switch (change.getString("type")) { - case "0": - type = "Entfall"; - break; - case "1": - type = "Vertretung"; - break; - case "2": - type = "Information"; - break; - } - substitution.setType(type); - // Set color - substitution.setColor(colorProvider.getColor(type)); - // Set covering teacher - final String coveringTeacherId = change.getString("coveringTeacher"); - if (!coveringTeacherId.equals("0")) { - if (teachersHashMap == null) { - throw new IOException("Change references a covering teacher but teachers are empty."); - } - if (!teachersHashMap.get(coveringTeacherId).equals("-")) { - substitution.setTeacher(teachersHashMap.get(coveringTeacherId)); - } - } - // Set teacher - final String teacherId = change.getString("teacher"); - if (!teacherId.equals("0")) { - if (teachersHashMap == null) { - throw new IOException("Change references a teacher but teachers are empty."); - } - if (!teachersHashMap.get(teacherId).equals("-")) { - if (type.equals("Vertretung") || substitution.getTeacher() != null) { - substitution.setPreviousTeacher(teachersHashMap.get(teacherId)); - } else { - substitution.setTeacher(teachersHashMap.get(teacherId)); - } - } - } - // Set description - substitution.setDesc(change.getString("text")); - // Set lesson - final String startingHour = change.getString("startingHour").replaceFirst("^0+(?!$)", ""); - final String endingHour = change.getString("endingHour").replaceFirst("^0+(?!$)", ""); - if (!startingHour.equals("") || !endingHour.equals("")) { - String lesson = ""; - if (!startingHour.equals("") && endingHour.equals("")) { - lesson = "Ab " + startingHour; - } - if (startingHour.equals("") && !endingHour.equals("")) { - lesson = "Bis " + endingHour; - } - if (!startingHour.equals("") && !endingHour.equals("")) { - if (startingHour.equals(endingHour)) { - lesson = startingHour; - } else { - lesson = startingHour + " - " + endingHour; - } - } - substitution.setLesson(lesson); - } - return substitution; - } - - @Override - public List getAllClasses() throws IOException, JSONException, CredentialInvalidException { - final List classes = new ArrayList<>(); - final JSONArray courses = getCourses(); - if (courses == null) { - return null; - } - for (int i = 0; i < courses.length(); i++) { - final JSONObject course = courses.getJSONObject(i); - if (!course.getBoolean("archived")) { - classes.add(course.getString("name")); - } - } - Collections.sort(classes, new NaturalOrderComparator()); - return classes; - } - - @Override - public List getAllTeachers() throws IOException, JSONException, CredentialInvalidException { - final List teachers = new ArrayList<>(); - final JSONArray jsonTeachers = getTeachers(); - if (jsonTeachers == null) { - return null; - } - for (int i = 0; i < jsonTeachers.length(); i++) { - final JSONObject teacher = jsonTeachers.getJSONObject(i); - if (!teacher.getBoolean("archived")) { - teachers.add(teacher.getString("name")); - } - } - Collections.sort(teachers); - return teachers; - } -} diff --git a/parser/src/main/java/me/vertretungsplan/parser/LoginHandler.java b/parser/src/main/java/me/vertretungsplan/parser/LoginHandler.java index 4c8c3fc4..9a9e7bd9 100644 --- a/parser/src/main/java/me/vertretungsplan/parser/LoginHandler.java +++ b/parser/src/main/java/me/vertretungsplan/parser/LoginHandler.java @@ -325,7 +325,7 @@ private String handleLogin(Executor executor, CookieStore cookieStore, boolean n Element iframe = doc.select("iframe").first(); if (iframe == null) throw new CredentialInvalidException(); String url = iframe.absUrl("src"); - if (url != null && !url.equals("")) { + if (url != null && !url.isEmpty()) { executor.execute(Request.Get(url)).discardContent(); } } diff --git a/parser/src/main/java/me/vertretungsplan/parser/ParserUtils.java b/parser/src/main/java/me/vertretungsplan/parser/ParserUtils.java index fe1b4c1c..dd9b41cd 100644 --- a/parser/src/main/java/me/vertretungsplan/parser/ParserUtils.java +++ b/parser/src/main/java/me/vertretungsplan/parser/ParserUtils.java @@ -121,7 +121,7 @@ static synchronized void init() { } private static synchronized void reinitIfNeeded() { - if (dateFormatters.size() == 0 || dateFormatters.get(0).getDefaultYear() != DateTime.now().getYear()) { + if (dateFormatters.isEmpty() || dateFormatters.get(0).getDefaultYear() != DateTime.now().getYear()) { init(); } } diff --git a/parser/src/main/java/me/vertretungsplan/parser/SVPlanParser.java b/parser/src/main/java/me/vertretungsplan/parser/SVPlanParser.java index c6dbeb11..344e5d84 100644 --- a/parser/src/main/java/me/vertretungsplan/parser/SVPlanParser.java +++ b/parser/src/main/java/me/vertretungsplan/parser/SVPlanParser.java @@ -161,15 +161,15 @@ SubstitutionSchedule parseSVPlanSchedule(List docs) throws IOException SubstitutionSchedule v = SubstitutionSchedule.fromData(scheduleData); for (Document doc : docs) { - if (doc.select(".svp, .scheduler").size() > 0) { + if (!doc.select(".svp, .scheduler").isEmpty()) { for (Element svp : doc.select(".svp, .scheduler")) { parseSvPlanDay(v, svp, doc); } - } else if (doc.select(".Trennlinie").size() > 0) { + } else if (!doc.select(".Trennlinie").isEmpty()) { Element div = new Element(Tag.valueOf("div"), ""); for (Node node : doc.body().childNodesCopy()) { if (node instanceof Element && ((Element) node).hasClass("Trennlinie") - && div.select("table").size() > 0) { + && !div.select("table").isEmpty()) { parseSvPlanDay(v, div, doc); div = new Element(Tag.valueOf("div"), ""); } else { @@ -189,18 +189,18 @@ SubstitutionSchedule parseSVPlanSchedule(List docs) throws IOException private void parseSvPlanDay(SubstitutionSchedule v, Element svp, Document doc) throws IOException, JSONException { SubstitutionScheduleDay day = new SubstitutionScheduleDay(); - if ((svp.select(".svp-plandatum-heute, .svp-plandatum-morgen, .Titel").size() > 0 || doc.title() + if ((!svp.select(".svp-plandatum-heute, .svp-plandatum-morgen, .Titel").isEmpty() || doc.title() .startsWith("Vertretungsplan für "))) { setDate(svp, doc, day); final Elements tables = svp.select(".svp-tabelle, table:has(.Klasse)"); - if (tables.size() > 0) { + if (!tables.isEmpty()) { Iterator iter = tables.iterator(); while (iter.hasNext()) { Element table = iter.next(); Element sibling = table.previousElementSibling(); if (!table.hasClass("svp-tabelle") && - table.select("> tbody > tr > td.Klasse").size() == 0 && - table.select("> tbody > tr > td.KlasseNeu").size() == 0 + table.select("> tbody > tr > td.Klasse").isEmpty() && + table.select("> tbody > tr > td.KlasseNeu").isEmpty() || sibling != null && sibling.hasClass("AufsichtTitel")) { iter.remove(); } @@ -210,8 +210,8 @@ private void parseSvPlanDay(SubstitutionSchedule v, Element svp, Document doc) t String lastLesson = ""; String lastClass = ""; for (Element row : rows) { - if ((doc.select(".svp-header").size() > 0 && row.hasClass("svp-header")) - || row.select("th").size() > 0 || row.text().trim().equals("")) { + if ((!doc.select(".svp-header").isEmpty() && row.hasClass("svp-header")) + || !row.select("th").isEmpty() || row.text().trim().isEmpty()) { continue; } @@ -262,14 +262,14 @@ && hasData(lastClass) && data.optBoolean(PARAM_REPEAT_CLASS, true)) { day.addSubstitution(substitution); } } - if (svp.select(".LehrerVerplant").size() > 0) { + if (!svp.select(".LehrerVerplant").isEmpty()) { day.addMessage("Verplante Lehrer: " + svp.select(".LehrerVerplant").text()); } - if (svp.select(".Abwesenheiten").size() > 0) { + if (!svp.select(".Abwesenheiten").isEmpty()) { day.addMessage("Abwesenheiten: " + svp.select(".Abwesenheiten").text()); } - if (svp.select("h2:contains(Mitteilungen)").size() > 0) { + if (!svp.select("h2:contains(Mitteilungen)").isEmpty()) { Element h2 = svp.select("h2:contains(Mitteilungen)").first(); Element sibling = h2.nextElementSibling(); while (sibling != null && sibling.tagName().equals("p")) { @@ -279,7 +279,7 @@ && hasData(lastClass) && data.optBoolean(PARAM_REPEAT_CLASS, true)) { } sibling = sibling.nextElementSibling(); } - } else if (svp.select(".Mitteilungen").size() > 0) { + } else if (!svp.select(".Mitteilungen").isEmpty()) { for (Element p : svp.select(".Mitteilungen")) { for (String nachricht : TextNode.createFromEncoded(p.html(), null).getWholeText() .split("
    \\s*
    ")) { @@ -289,11 +289,11 @@ && hasData(lastClass) && data.optBoolean(PARAM_REPEAT_CLASS, true)) { } Elements aufsichtTable = svp.select(".svp-pausenaufsicht, .AufsichtTitel + table"); - if (aufsichtTable.size() > 0) { + if (!aufsichtTable.isEmpty()) { Elements rows = aufsichtTable.select("tr"); String lastTime = ""; for (Element row : rows) { - if (row.hasClass("svp-aufs-header") || row.select("td").size() == 0) continue; + if (row.hasClass("svp-aufs-header") || row.select("td").isEmpty()) continue; Substitution substitution = new Substitution(); substitution.setType("Pausenaufsicht"); substitution.setColor(colorProvider.getColor("Pausenaufsicht")); @@ -373,7 +373,7 @@ && hasData(lastClass) && data.optBoolean(PARAM_REPEAT_CLASS, true)) { private void setDate(Element svp, Document doc, SubstitutionScheduleDay day) { String date = "Unbekanntes Datum"; - if (svp.select(".svp-plandatum-heute, .svp-plandatum-morgen, .Titel").size() > 0) { + if (!svp.select(".svp-plandatum-heute, .svp-plandatum-morgen, .Titel").isEmpty()) { date = svp.select(".svp-plandatum-heute, .svp-plandatum-morgen, .Titel").first().text(); } else if (doc.title().startsWith("Vertretungsplan für ")) { date = doc.title().substring("Vertretungsplan für ".length()); @@ -388,7 +388,7 @@ private void setDate(Element svp, Document doc, SubstitutionScheduleDay day) { day.setDateString(date); day.setDate(ParserUtils.parseDate(date)); - if (svp.select(".svp-uploaddatum, .Stand").size() > 0) { + if (!svp.select(".svp-uploaddatum, .Stand").isEmpty()) { String lastChange = svp.select(".svp-uploaddatum, .Stand").text().replace("Aktualisierung: ", "") .replace("Stand: ", ""); day.setLastChangeString(lastChange); @@ -411,6 +411,6 @@ public List getAllTeachers() { } private boolean hasData(String text) { - return !text.trim().equals("") && !text.trim().equals("---"); + return !text.trim().isEmpty() && !text.trim().equals("---"); } } diff --git a/parser/src/main/java/me/vertretungsplan/parser/SchoolJoomlaParser.java b/parser/src/main/java/me/vertretungsplan/parser/SchoolJoomlaParser.java index 68035abf..8aaa7df2 100644 --- a/parser/src/main/java/me/vertretungsplan/parser/SchoolJoomlaParser.java +++ b/parser/src/main/java/me/vertretungsplan/parser/SchoolJoomlaParser.java @@ -156,7 +156,7 @@ public class SchoolJoomlaParser extends BaseParser { } final JSONArray ticker = data.getJSONObject("vertretungsplan").getJSONArray("schuelernewsticker"); - if (ticker.length() > 0) { + if (!ticker.isEmpty()) { final StringBuilder builder = new StringBuilder(); for (int i = 0; i < ticker.length(); i++) { if (i > 0) builder.append("\n\n"); @@ -219,7 +219,7 @@ private JSONObject getConfiguration() throws IOException, CredentialInvalidExcep final JSONObject data = new JSONObject(json); final int error = data.getInt("error"); - if (error != 0 || data.getJSONArray("errors").length() > 0) { + if (error != 0 || !data.getJSONArray("errors").isEmpty()) { switch (error) { case 12: // wrong teacher password case 17: // wrong student password diff --git a/parser/src/main/java/me/vertretungsplan/parser/TurboVertretungParser.java b/parser/src/main/java/me/vertretungsplan/parser/TurboVertretungParser.java index fc1894b7..d08c56a5 100644 --- a/parser/src/main/java/me/vertretungsplan/parser/TurboVertretungParser.java +++ b/parser/src/main/java/me/vertretungsplan/parser/TurboVertretungParser.java @@ -120,24 +120,24 @@ private void parseTurboVertretungDay(SubstitutionSchedule v, Document doc) { return; } - if (doc.select(".LehrerFrueher").size() > 0) { + if (!doc.select(".LehrerFrueher").isEmpty()) { day.addMessage(doc.select(".LehrerFrueherLabel").text() + "\n" + doc.select(".LehrerFrueher").text()); } - if (doc.select(".LehrerVerplant").size() > 0) { + if (!doc.select(".LehrerVerplant").isEmpty()) { day.addMessage(doc.select(".LehrerVerplantLabel").text() + "\n" + doc.select(".LehrerVerplant").text()); } - if (doc.select(".Abwesenheiten-Klassen").size() > 0) { + if (!doc.select(".Abwesenheiten-Klassen").isEmpty()) { day.addMessage(doc.select(".Abwesenheiten-KlassenLabel").text() + "\n" + doc.select(".Abwesenheiten-Klassen").text()); } - if (doc.select(".Abwesenheiten").size() > 0) { + if (!doc.select(".Abwesenheiten").isEmpty()) { day.addMessage(doc.select(".AbwesenheitenLabel").text() + "\n" + doc.select(".Abwesenheiten").text()); } Element table = doc.select("table").first(); for (Element row : table.select("tr:has(td)")) { - if (row.select(".Klasseleer").size() > 0) continue; + if (!row.select(".Klasseleer").isEmpty()) continue; Substitution substitution = new Substitution(); substitution.setLesson(row.select(query("Stunde")).text()); diff --git a/parser/src/main/java/me/vertretungsplan/parser/UntisCommonParser.java b/parser/src/main/java/me/vertretungsplan/parser/UntisCommonParser.java index 0126d7b5..c55f0b82 100644 --- a/parser/src/main/java/me/vertretungsplan/parser/UntisCommonParser.java +++ b/parser/src/main/java/me/vertretungsplan/parser/UntisCommonParser.java @@ -125,11 +125,11 @@ static String findLastChange(Element doc, SubstitutionScheduleData scheduleData) } } - if (doc.select("table.mon_head").size() > 0) { + if (!doc.select("table.mon_head").isEmpty()) { Element monHead = doc.select("table.mon_head").first(); lastChange = findLastChangeFromMonHeadTable(monHead); } else if (lastChangeLeft) { - final String bodyHtml = doc.select("body").size() > 0 ? doc.select("body").html() : doc.html(); + final String bodyHtml = !doc.select("body").isEmpty() ? doc.select("body").html() : doc.html(); lastChange = bodyHtml.substring(0, bodyHtml.indexOf("

    ") - 1); } else { List childNodes; @@ -154,7 +154,7 @@ static String findLastChange(Element doc, SubstitutionScheduleData scheduleData) } private static String findLastChangeFromMonHeadTable(Element monHead) { - if (monHead.select("td[align=right]").size() == 0) return null; + if (monHead.select("td[align=right]").isEmpty()) return null; String lastChange = null; Pattern pattern = Pattern.compile("\\d\\d\\.\\d\\d\\.\\d\\d\\d\\d \\d\\d:\\d\\d"); @@ -206,7 +206,7 @@ private void parseSubstitutionScheduleTable(Element table, JSONObject data, Elements headerRows = table.select("tr:has(th)"); List columnTitles = new ArrayList<>(); - if (headerRows.size() > 0) { + if (!headerRows.isEmpty()) { Elements headers = headerRows.get(0).select("th"); for (int i = 0; i < headers.size(); i++) { StringBuilder builder = new StringBuilder(); @@ -214,7 +214,7 @@ private void parseSubstitutionScheduleTable(Element table, JSONObject data, for (Element headerRow : headerRows) { final String text = headerRow.select("th").get(i).text().replace("\u00a0", " ").trim(); if (first) { - if (!text.equals("")) first = false; + if (!text.isEmpty()) first = false; } else { builder.append(" "); } @@ -228,7 +228,7 @@ private void parseSubstitutionScheduleTable(Element table, JSONObject data, final JSONArray columnsJson = data.optJSONArray(PARAM_COLUMNS); List columns = new ArrayList<>(); - if (columnsJson != null && (columnTitles.size() == 0 || columnTitles.size() == columnsJson.length())) { + if (columnsJson != null && (columnTitles.isEmpty() || columnTitles.size() == columnsJson.length())) { for (int i = 0; i < columnsJson.length(); i++) columns.add(columnsJson.getString(i)); } else { for (String title : columnTitles) { @@ -278,7 +278,7 @@ private void parseSubstitutionScheduleTable(Element table, JSONObject data, } final Element previousLine = zeile.previousElementSibling(); - if (isGroupMessage(zeile) && previousLine != null && previousLine.select(".inline_header").size() > 0) { + if (isGroupMessage(zeile) && previousLine != null && !previousLine.select(".inline_header").isEmpty()) { addGroupMessage(day, getClassName(previousLine.text(), data), zeile); continue; } @@ -414,7 +414,7 @@ private void parseSubstitutionScheduleTable(Element table, JSONObject data, v.setSubject(course); } - if (v.getLesson() == null || v.getLesson().equals("")) { + if (v.getLesson() == null || v.getLesson().isEmpty()) { continue; } @@ -726,7 +726,7 @@ private void parseWithExtraLine(JSONObject data, SubstitutionScheduleDay day, Li v.setTeacher(teacherName); } - if (v.getLesson() != null && !v.getLesson().equals("")) { + if (v.getLesson() != null && !v.getLesson().isEmpty()) { day.addSubstitution(v); } @@ -751,7 +751,7 @@ private boolean isGroupMessage(Element zeile) { private void autoDetectType(JSONObject data, Element zeile, Substitution v) { if (v.getType() == null) { if (data.optBoolean(PARAM_TYPE_AUTO_DETECTION, true)) { - if ((zeile.select("strike").size() > 0 && + if ((!zeile.select("strike").isEmpty() && equalsOrNull(v.getSubject(), v.getPreviousSubject()) && equalsOrNull(v.getTeacher(), v.getPreviousTeacher())) || (v.getSubject() == null && (v.getRoom() == null || v.getRoom().equals(v.getPreviousRoom())) @@ -773,9 +773,9 @@ private void autoDetectType(JSONObject data, Element zeile, Substitution v) { static void handleTeacher(Substitution subst, Element cell, JSONObject data, boolean previousTeacher) { if (data.optBoolean(PARAM_EXCLUDE_TEACHERS)) return; cell = getContentElement(cell); - if (cell.select("s").size() > 0) { + if (!cell.select("s").isEmpty()) { subst.setPreviousTeachers(splitTeachers(cell.select("s").text(), data)); - if (cell.ownText().length() > 0) { + if (!cell.ownText().isEmpty()) { subst.setTeachers(splitTeachers(cell.ownText().replaceFirst("^\\?", "").replaceFirst("→", ""), data)); } } else { @@ -799,9 +799,9 @@ private static Set splitTeachers(String s, JSONObject data) { static void handleRoom(Substitution subst, Element cell, boolean previousRoom) { cell = getContentElement(cell); - if (cell.select("s").size() > 0) { + if (!cell.select("s").isEmpty()) { subst.setPreviousRoom(cell.select("s").text()); - if (cell.ownText().length() > 0) { + if (!cell.ownText().isEmpty()) { subst.setRoom(cell.ownText().replaceFirst("^\\?", "").replaceFirst("→", "")); } } else { @@ -822,9 +822,9 @@ private static Element getContentElement(Element cell) { static void handleSubject(Substitution subst, Element cell, boolean previousSubject) { cell = getContentElement(cell); - if (cell.select("s").size() > 0) { + if (!cell.select("s").isEmpty()) { subst.setPreviousSubject(cell.select("s").text()); - if (cell.ownText().length() > 0) { + if (!cell.ownText().isEmpty()) { subst.setSubject(cell.ownText().replaceFirst("^\\?", "").replaceFirst("→", "")); } } else { @@ -838,7 +838,7 @@ static void handleSubject(Substitution subst, Element cell, boolean previousSubj private boolean isEmpty(String text) { final String trim = text.replaceAll("\u00A0", "").trim(); - return trim.equals("") || trim.equals("---") || trim.equals("+"); + return trim.isEmpty() || trim.equals("---") || trim.equals("+"); } /** @@ -884,12 +884,12 @@ SubstitutionScheduleDay parseMonitorDay(Element doc, JSONObject data) throws } // NACHRICHTEN - if (doc.select("table.info").size() > 0) { + if (!doc.select("table.info").isEmpty()) { parseMessages(doc.select("table.info").first(), day); } // VERTRETUNGSPLAN - if (doc.select("table:has(tr.list)").size() > 0) { + if (!doc.select("table:has(tr.list)").isEmpty()) { parseSubstitutionScheduleTable(doc.select("table:has(tr.list)").first(), data, day, getAllClasses()); } @@ -912,10 +912,10 @@ public List getAllClasses() throws IOException, JSONException, Credentia void parseDay(SubstitutionScheduleDay day, Element next, SubstitutionSchedule v, String klasse, List allClasses) throws JSONException, CredentialInvalidException, IOException { - if (next.children().size() == 0) { + if (next.children().isEmpty()) { next = next.nextElementSibling(); } - if (next.className().equals("subst") || next.select(".list").size() > 0 + if (next.className().equals("subst") || !next.select(".list").isEmpty() || next.text().contains("Vertretungen sind nicht freigegeben") || next.text().contains("Keine Vertretungen")) { //Vertretungstabelle @@ -941,10 +941,10 @@ void parseMultipleMonitorDays(SubstitutionSchedule v, Document doc, JSONObject d Element next = doc.select(".mon_head").get(j).nextElementSibling(); if (next != null && next.tagName().equals("center")) { doc2.body().appendChild(next.select(".mon_title").first().clone()); - if (next.select("table:has(tr.list)").size() > 0) { + if (!next.select("table:has(tr.list)").isEmpty()) { doc2.body().appendChild(next.select("table:has(tr.list)").first()); } - if (next.select("table.info").size() > 0) { + if (!next.select("table.info").isEmpty()) { doc2.body().appendChild(next.select("table.info").first()); } } else if (doc.select(".mon_title").size() - 1 >= j) { @@ -982,11 +982,6 @@ protected void parseSubstitutionTable(SubstitutionSchedule v, String lastChange, /** * Parses an Untis substitution table ({@link UntisSubstitutionParser}). * - * @param v - * @param lastChange - * @param doc - * @throws JSONException - * @throws CredentialInvalidException */ protected void parseSubstitutionTable(SubstitutionSchedule v, String lastChange, Document doc, String className) throws JSONException, CredentialInvalidException, IOException { diff --git a/parser/src/main/java/me/vertretungsplan/parser/UntisInfoHeadlessParser.java b/parser/src/main/java/me/vertretungsplan/parser/UntisInfoHeadlessParser.java index 73273ba8..d9fce628 100644 --- a/parser/src/main/java/me/vertretungsplan/parser/UntisInfoHeadlessParser.java +++ b/parser/src/main/java/me/vertretungsplan/parser/UntisInfoHeadlessParser.java @@ -78,17 +78,17 @@ public SubstitutionSchedule getSubstitutionSchedule() Elements dayElems = doc.select("#vertretung > p > b, #vertretung > b"); Elements frames = doc.select("frame[src*=w00]"); - if (dayElems.size() == 0 && frames.size() > 0) { + if (dayElems.isEmpty() && !frames.isEmpty()) { // doc is embedded in frame doc = Jsoup.parse(httpGet(frames.get(0).absUrl("src"), data.optString(PARAM_ENCODING, null))); dayElems = doc.select("#vertretung > p > b, #vertretung > b"); - } else if (dayElems.size() == 0) { + } else if (dayElems.isEmpty()) { // seen at GHS Berlin, different kinds of center > font > center ... stacked (sometimes within #vertretung) dayElems = doc.select("center > font > p > b"); } final List allClasses = getAllClasses(); - if (dayElems.size() > 0) { + if (!dayElems.isEmpty()) { // untis-info days for (Element dayElem : dayElems) { SubstitutionScheduleDay day = new SubstitutionScheduleDay(); @@ -106,7 +106,7 @@ public SubstitutionSchedule getSubstitutionSchedule() } parseDay(day, next, v, null, allClasses); } - } else if (doc.select("tr:has(td[align=center]):gt(0)").size() > 0) { + } else if (!doc.select("tr:has(td[align=center]):gt(0)").isEmpty()) { // untis-subst table parseSubstitutionTable(v, null, doc); } diff --git a/parser/src/main/java/me/vertretungsplan/parser/UntisInfoParser.java b/parser/src/main/java/me/vertretungsplan/parser/UntisInfoParser.java index 38f4468c..59576159 100644 --- a/parser/src/main/java/me/vertretungsplan/parser/UntisInfoParser.java +++ b/parser/src/main/java/me/vertretungsplan/parser/UntisInfoParser.java @@ -355,7 +355,7 @@ private static List parseTimetableCell(Element cell, String lesson cellFormat, ColorProvider colorProvider) throws JSONException { List substitutions = new ArrayList<>(); - if (cell.text().trim().equals("")) { + if (cell.text().trim().isEmpty()) { return substitutions; } @@ -383,7 +383,7 @@ private static List parseTimetableCell(Element cell, String lesson try { Element td = tr.select("td").get(col + course * cellFormat.getJSONArray(0).length()); - if (td.select("font[color=#FF0000]").size() > 0) { + if (!td.select("font[color=#FF0000]").isEmpty()) { isChange = true; } @@ -449,7 +449,7 @@ void parseSubstitutionDays(SubstitutionSchedule v, String lastChange, Document d allClasses) throws JSONException, CredentialInvalidException, IOException { Elements days = doc.select("#vertretung > p > b, #vertretung > b, p:has(a[href^=#]) > b"); - if (days.size() > 0) { + if (!days.isEmpty()) { for (Element dayElem : days) { SubstitutionScheduleDay day = new SubstitutionScheduleDay(); @@ -468,7 +468,7 @@ void parseSubstitutionDays(SubstitutionSchedule v, String lastChange, Document d } parseDay(day, next, v, klasse, allClasses); } - } else if (doc.select("tr:has(td[align=center]):gt(0)").size() > 0) { + } else if (!doc.select("tr:has(td[align=center]):gt(0)").isEmpty()) { parseSubstitutionTable(v, null, doc); v.setLastChangeString(lastChange); v.setLastChange(ParserUtils.parseDateTime(lastChange)); diff --git a/parser/src/main/java/me/vertretungsplan/parser/UntisMonitorParser.java b/parser/src/main/java/me/vertretungsplan/parser/UntisMonitorParser.java index 62d806f2..52c2ae40 100644 --- a/parser/src/main/java/me/vertretungsplan/parser/UntisMonitorParser.java +++ b/parser/src/main/java/me/vertretungsplan/parser/UntisMonitorParser.java @@ -117,7 +117,7 @@ public SubstitutionSchedule getSubstitutionSchedule() throws IOException, JSONEx } } if (lastException != null && - (docs.size() == 0 || scheduleData.getData().optBoolean(PARAM_FORCE_ALL_PAGES))) { + (docs.isEmpty() || scheduleData.getData().optBoolean(PARAM_FORCE_ALL_PAGES))) { throw lastException; } @@ -130,13 +130,13 @@ public SubstitutionSchedule getSubstitutionSchedule() throws IOException, JSONEx } else if (doc.title().contains("Untis") || doc.html().contains("