diff --git a/buisnesslogic/src/main/java/com/plannaplan/api/package-info.java b/buisnesslogic/src/main/java/com/plannaplan/api/package-info.java new file mode 100755 index 0000000..9f88873 --- /dev/null +++ b/buisnesslogic/src/main/java/com/plannaplan/api/package-info.java @@ -0,0 +1,6 @@ +/** + * Provides the classes necessary to obtain usos authentication with Oauth1 + * + * @since 1.0 + */ +package com.plannaplan.api; diff --git a/buisnesslogic/src/main/java/com/plannaplan/configutils/FileReader.java b/buisnesslogic/src/main/java/com/plannaplan/configutils/FileReader.java index 824c350..fe9eaaf 100755 --- a/buisnesslogic/src/main/java/com/plannaplan/configutils/FileReader.java +++ b/buisnesslogic/src/main/java/com/plannaplan/configutils/FileReader.java @@ -12,16 +12,29 @@ import org.apache.poi.ss.usermodel.Row; import com.plannaplan.models.FileData; /** - * FileReader is used for reading xls file from input stream. + * FileReader is used for reading xls file from input stream. */ public class FileReader { private InputStream fileInputStream; + /** + * @param fileInputStream stream of stadarized file contains courses and gropups + * to import. File needs to be .xlsx file that has + * fields: zaj_cyk_id, typ, sym, nazwa, gr_nr, Mc, dzien, + * godz_od, sala, tytul, nazwisko, imie. Order doesn't + * have impact on import. Any change name of given field + * can be performed in FileToDatabaseMigrator class + */ public FileReader(InputStream fileInputStream) { this.fileInputStream = fileInputStream; } + /** + * read data rom file + * + * @return instance of class FileData + */ public FileData read() { FileData result = null; diff --git a/buisnesslogic/src/main/java/com/plannaplan/configutils/FileToDatabaseMigrator.java b/buisnesslogic/src/main/java/com/plannaplan/configutils/FileToDatabaseMigrator.java index ad955f9..0413622 100755 --- a/buisnesslogic/src/main/java/com/plannaplan/configutils/FileToDatabaseMigrator.java +++ b/buisnesslogic/src/main/java/com/plannaplan/configutils/FileToDatabaseMigrator.java @@ -16,99 +16,119 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** - * FileToDatabaseMigrator is used for migrate data from file (it reads line by line) and push it into database + * FileToDatabaseMigrator is used for migrate data from file (it reads line by + * line) and push it into database */ @Component public class FileToDatabaseMigrator { - private static final String LECTURER_NAME_STRING = "imie"; - private static final String LECTURER_SURNAME_STRING = "nazwisko"; - private static final String LECTURER_TITLE_STRING = "tytul"; + private static final String LECTURER_NAME_STRING = "imie"; + private static final String LECTURER_SURNAME_STRING = "nazwisko"; + private static final String LECTURER_TITLE_STRING = "tytul"; - private static final String COURSE_SYMBOL_STRING = "sym"; - private static final String COURSE_NAME_STRING = "nazwa"; + private static final String COURSE_SYMBOL_STRING = "sym"; + private static final String COURSE_NAME_STRING = "nazwa"; - private static final String groupDay_STRING = "dzien"; - private static final String GROUP_TIME_STRING = "godz_od"; - private static final String ROOM_STRING = "sala"; - private static final String CAPACITY_STRING = "Mc"; - private static final String TYPE_GROUP= "typ"; + private static final String groupDay_STRING = "dzien"; + private static final String GROUP_TIME_STRING = "godz_od"; + private static final String ROOM_STRING = "sala"; + private static final String CAPACITY_STRING = "Mc"; + private static final String TYPE_GROUP = "typ"; - private static final String ZAJ_CYK_ID = "zaj_cyk_id"; - private static final String GR_NR = "gr_nr"; + private static final String ZAJ_CYK_ID = "zaj_cyk_id"; + private static final String GR_NR = "gr_nr"; - @Autowired - private LecturerService lecturerService; - @Autowired - private CourseService courseService; - @Autowired - private GroupService groupService; + @Autowired + private LecturerService lecturerService; + @Autowired + private CourseService courseService; + @Autowired + private GroupService groupService; - public FileToDatabaseMigrator() { - } + public FileToDatabaseMigrator() { + } - public void migrate(FileData data) { - Iterator rows = data.getRows(); - int courseNameIndex = data.getIndexOf(FileToDatabaseMigrator.COURSE_NAME_STRING); - int symbolIndex = data.getIndexOf(FileToDatabaseMigrator.COURSE_SYMBOL_STRING); + /** + * insert data to database + * + * @param data FileData imported from file + */ + public void migrate(FileData data) { + Iterator rows = data.getRows(); + int courseNameIndex = data.getIndexOf(FileToDatabaseMigrator.COURSE_NAME_STRING); + int symbolIndex = data.getIndexOf(FileToDatabaseMigrator.COURSE_SYMBOL_STRING); - int titleIndex = data.getIndexOf(FileToDatabaseMigrator.LECTURER_TITLE_STRING); - int surnameIndex = data.getIndexOf(FileToDatabaseMigrator.LECTURER_SURNAME_STRING); - int nameIndex = data.getIndexOf(FileToDatabaseMigrator.LECTURER_NAME_STRING); + int titleIndex = data.getIndexOf(FileToDatabaseMigrator.LECTURER_TITLE_STRING); + int surnameIndex = data.getIndexOf(FileToDatabaseMigrator.LECTURER_SURNAME_STRING); + int nameIndex = data.getIndexOf(FileToDatabaseMigrator.LECTURER_NAME_STRING); - int dayIndex = data.getIndexOf(FileToDatabaseMigrator.groupDay_STRING); - int timeIndex = data.getIndexOf(FileToDatabaseMigrator.GROUP_TIME_STRING); - int roomIndex = data.getIndexOf(FileToDatabaseMigrator.ROOM_STRING); - int capacityIndex = data.getIndexOf(FileToDatabaseMigrator.CAPACITY_STRING); - int typeGroupIndex = data.getIndexOf(FileToDatabaseMigrator.TYPE_GROUP); + int dayIndex = data.getIndexOf(FileToDatabaseMigrator.groupDay_STRING); + int timeIndex = data.getIndexOf(FileToDatabaseMigrator.GROUP_TIME_STRING); + int roomIndex = data.getIndexOf(FileToDatabaseMigrator.ROOM_STRING); + int capacityIndex = data.getIndexOf(FileToDatabaseMigrator.CAPACITY_STRING); + int typeGroupIndex = data.getIndexOf(FileToDatabaseMigrator.TYPE_GROUP); - int zajCykIdIndex = data.getIndexOf(FileToDatabaseMigrator.ZAJ_CYK_ID); - int grNrIndex = data.getIndexOf(FileToDatabaseMigrator.GR_NR); + int zajCykIdIndex = data.getIndexOf(FileToDatabaseMigrator.ZAJ_CYK_ID); + int grNrIndex = data.getIndexOf(FileToDatabaseMigrator.GR_NR); - while (rows.hasNext()) { - Row row = rows.next(); + while (rows.hasNext()) { + Row row = rows.next(); - String courseName = row.getCell(courseNameIndex).toString().trim(); - String symbol = row.getCell(symbolIndex).toString().trim(); + String courseName = row.getCell(courseNameIndex).toString().trim(); + String symbol = row.getCell(symbolIndex).toString().trim(); - String lecturerTitle = row.getCell(titleIndex) != null ? row.getCell(titleIndex).toString().trim() : ""; - String lecturerName = row.getCell(nameIndex) != null ? row.getCell(nameIndex).toString().trim() : ""; - String lecturerSurname = row.getCell(surnameIndex) != null ? row.getCell(surnameIndex).toString().trim() - : ""; + String lecturerTitle = row.getCell(titleIndex) != null + ? row.getCell(titleIndex).toString().trim() + : ""; + String lecturerName = row.getCell(nameIndex) != null ? row.getCell(nameIndex).toString().trim() + : ""; + String lecturerSurname = row.getCell(surnameIndex) != null + ? row.getCell(surnameIndex).toString().trim() + : ""; - Integer zajCykId = row.getCell(zajCykIdIndex) != null ? (int) Double.parseDouble(row.getCell(zajCykIdIndex).toString().trim()) - : null; - - Integer grNr = row.getCell(grNrIndex) != null ? (int) Double.parseDouble(row.getCell(grNrIndex).toString().trim()) - : null; + Integer zajCykId = row.getCell(zajCykIdIndex) != null + ? (int) Double.parseDouble(row.getCell(zajCykIdIndex).toString().trim()) + : null; - int day = row.getCell(dayIndex) != null ? (int) Double.parseDouble(row.getCell(dayIndex).toString()) : 0; - WeekDay groupDay = WeekDay.getDay(day - 1); - int time = parseTimeToInt(row.getCell(timeIndex).toString()); - String room = row.getCell(roomIndex).toString().trim(); - int capacity = (int) Double.parseDouble(row.getCell(capacityIndex).toString()); - GroupType typeGroup = GroupType.getType(row.getCell(typeGroupIndex).toString()); + Integer grNr = row.getCell(grNrIndex) != null + ? (int) Double.parseDouble(row.getCell(grNrIndex).toString().trim()) + : null; - Course course = this.courseService.getCourseByName(courseName) - .orElseGet(() -> this.courseService.save(new Course(courseName, symbol))); + int day = row.getCell(dayIndex) != null + ? (int) Double.parseDouble(row.getCell(dayIndex).toString()) + : 0; + WeekDay groupDay = WeekDay.getDay(day - 1); + int time = parseTimeToInt(row.getCell(timeIndex).toString()); + String room = row.getCell(roomIndex).toString().trim(); + int capacity = (int) Double.parseDouble(row.getCell(capacityIndex).toString()); + GroupType typeGroup = GroupType.getType(row.getCell(typeGroupIndex).toString()); - Lecturer lecturer = this.lecturerService.getLecturer(lecturerTitle, lecturerName, lecturerSurname) - .orElseGet(() -> this.lecturerService - .save(new Lecturer(lecturerTitle, lecturerName, lecturerSurname))); + Course course = this.courseService.getCourseByName(courseName) + .orElseGet(() -> this.courseService.save(new Course(courseName, symbol))); - Groups group = this.groupService.find(zajCykId, grNr).orElseGet( - () -> new Groups(capacity, room, course, time, groupDay, lecturer, zajCykId, grNr, typeGroup)); - group.update(capacity, room, course, time, null, groupDay, lecturer, typeGroup); - - this.groupService.save(group); + Lecturer lecturer = this.lecturerService + .getLecturer(lecturerTitle, lecturerName, lecturerSurname) + .orElseGet(() -> this.lecturerService.save( + new Lecturer(lecturerTitle, lecturerName, lecturerSurname))); + + Groups group = this.groupService.find(zajCykId, grNr).orElseGet(() -> new Groups(capacity, room, + course, time, groupDay, lecturer, zajCykId, grNr, typeGroup)); + group.update(capacity, room, course, time, null, groupDay, lecturer, typeGroup); + + this.groupService.save(group); + + } } - } + /** + * + * @param time time string in formaT hh:mm or hh.mm + * @return int time witch is minutes from 00:00 + */ + private static int parseTimeToInt(String time) { + String times[] = time.split("\\.|\\:"); + return times.length == 2 ? Integer.parseInt(times[0]) * 60 + Integer.parseInt(times[1]) : 0; - private static int parseTimeToInt(String time) { - String times[] = time.split("\\.|\\:"); - return times.length == 2 ? Integer.parseInt(times[0]) * 60 + Integer.parseInt(times[1]) : 0; - - } + } } \ No newline at end of file diff --git a/buisnesslogic/src/main/java/com/plannaplan/configutils/package-info.java b/buisnesslogic/src/main/java/com/plannaplan/configutils/package-info.java new file mode 100755 index 0000000..15bfb00 --- /dev/null +++ b/buisnesslogic/src/main/java/com/plannaplan/configutils/package-info.java @@ -0,0 +1,7 @@ +/** + * Provides the classes necessary to to config and import related operations in + * the app + * + * @since 1.0 + */ +package com.plannaplan.configutils; diff --git a/buisnesslogic/src/main/java/com/plannaplan/entities/Assignment.java b/buisnesslogic/src/main/java/com/plannaplan/entities/Assignment.java index 5d5550d..289b117 100755 --- a/buisnesslogic/src/main/java/com/plannaplan/entities/Assignment.java +++ b/buisnesslogic/src/main/java/com/plannaplan/entities/Assignment.java @@ -38,6 +38,15 @@ public class Assignment { this.group = group; } + /** + * + * @param oldAssignment old assignment that we want to move to new commision + * @param newCommision commsion to move assiongment + */ + public static Assignment getNewFromAssignment(Assignment oldAssignment, Commision newCommision) { + return new Assignment(oldAssignment.getGroup(), newCommision); + } + /** * If it returns trues it mesans u are assigned to group accepted by algorythm * @@ -49,9 +58,10 @@ public class Assignment { /** * Getter of commision + * * @return Commision Commision of given assignments */ - public Commision getCommision(){ + public Commision getCommision() { return this.commision; } @@ -68,9 +78,13 @@ public class Assignment { public Assignment() { } + /** + * @param commision commision to set + */ public void setCommision(Commision commision) { - this.commision = commision; + this.commision = commision; } + /** * Id getter * diff --git a/buisnesslogic/src/main/java/com/plannaplan/entities/package-info.java b/buisnesslogic/src/main/java/com/plannaplan/entities/package-info.java new file mode 100755 index 0000000..eb30373 --- /dev/null +++ b/buisnesslogic/src/main/java/com/plannaplan/entities/package-info.java @@ -0,0 +1,6 @@ +/** + * Provides all entieites that are created in database by Hibernate + * + * @since 1.0 + */ +package com.plannaplan.entities; diff --git a/buisnesslogic/src/main/java/com/plannaplan/exceptions/TokenExpiredException.java b/buisnesslogic/src/main/java/com/plannaplan/exceptions/TokenExpiredException.java index 2507ad6..deee58e 100755 --- a/buisnesslogic/src/main/java/com/plannaplan/exceptions/TokenExpiredException.java +++ b/buisnesslogic/src/main/java/com/plannaplan/exceptions/TokenExpiredException.java @@ -1,9 +1,9 @@ package com.plannaplan.exceptions; +/** + * Excepction to be thrown when provided token is expired + */ public class TokenExpiredException extends RuntimeException { - /** - * - */ private static final long serialVersionUID = 1L; public TokenExpiredException(String message) { diff --git a/buisnesslogic/src/main/java/com/plannaplan/exceptions/UserNotFoundException.java b/buisnesslogic/src/main/java/com/plannaplan/exceptions/UserNotFoundException.java index d56283f..7a9ba09 100755 --- a/buisnesslogic/src/main/java/com/plannaplan/exceptions/UserNotFoundException.java +++ b/buisnesslogic/src/main/java/com/plannaplan/exceptions/UserNotFoundException.java @@ -1,9 +1,9 @@ package com.plannaplan.exceptions; +/** + * Exception to be thrown when provided user does not exist in database + */ public class UserNotFoundException extends Exception { - /** - * - */ private static final long serialVersionUID = 1L; public UserNotFoundException(String message) { diff --git a/buisnesslogic/src/main/java/com/plannaplan/exceptions/package-info.java b/buisnesslogic/src/main/java/com/plannaplan/exceptions/package-info.java new file mode 100755 index 0000000..3676222 --- /dev/null +++ b/buisnesslogic/src/main/java/com/plannaplan/exceptions/package-info.java @@ -0,0 +1,6 @@ +/** + * Provides custom for our app exceptions to get more accutrate errors info + * + * @since 1.0 + */ +package com.plannaplan.exceptions; diff --git a/buisnesslogic/src/main/java/com/plannaplan/models/ConfigData.java b/buisnesslogic/src/main/java/com/plannaplan/models/ConfigData.java index f5c966d..dfde864 100755 --- a/buisnesslogic/src/main/java/com/plannaplan/models/ConfigData.java +++ b/buisnesslogic/src/main/java/com/plannaplan/models/ConfigData.java @@ -2,6 +2,9 @@ package com.plannaplan.models; import java.io.InputStream; +/** + * Config data copntainer to keep tours dates and stream of dasta to import + */ public class ConfigData { private TourData firstTour; private TourData secondTour; diff --git a/buisnesslogic/src/main/java/com/plannaplan/models/FileData.java b/buisnesslogic/src/main/java/com/plannaplan/models/FileData.java index 8828d21..dc753be 100755 --- a/buisnesslogic/src/main/java/com/plannaplan/models/FileData.java +++ b/buisnesslogic/src/main/java/com/plannaplan/models/FileData.java @@ -4,6 +4,9 @@ import java.util.HashMap; import java.util.Iterator; import org.apache.poi.ss.usermodel.Row; +/** + * Wrapper for data readed from file + */ public class FileData { private HashMap keys; @@ -13,6 +16,7 @@ public class FileData { * FileData * * @param keys this is a hashmap of String and Integer + * * @param rows this is a iterator of rows. */ public FileData(HashMap keys, Iterator rows) { @@ -31,6 +35,7 @@ public class FileData { /* * setRows + * * @param rows set the rows to given function */ public void setRows(Iterator rows) { @@ -39,6 +44,7 @@ public class FileData { /* * getKeys + * * @return keys */ public HashMap getKeys() { @@ -47,6 +53,7 @@ public class FileData { /* * setKeys + * * @param keys set the key is being a struck of hashmap (String, Integer) */ public void setKeys(HashMap keys) { @@ -55,6 +62,7 @@ public class FileData { /* * getIndexOf + * * @return index */ public int getIndexOf(String key) { diff --git a/buisnesslogic/src/main/java/com/plannaplan/models/MatchData.java b/buisnesslogic/src/main/java/com/plannaplan/models/MatchData.java index 1ee5db5..f0b7adf 100755 --- a/buisnesslogic/src/main/java/com/plannaplan/models/MatchData.java +++ b/buisnesslogic/src/main/java/com/plannaplan/models/MatchData.java @@ -3,64 +3,93 @@ package com.plannaplan.models; import com.plannaplan.entities.Assignment; import com.plannaplan.entities.Exchange; +/** + * Match of users Exchange's to be performed + */ public class MatchData { - private Exchange exchangeOne; - private Exchange exchangeTwo; + private Exchange exchangeOne; + private Exchange exchangeTwo; - public MatchData(Exchange exchangeOne, Exchange exchangeTwo) { - this.exchangeOne = exchangeOne; - this.exchangeTwo = exchangeTwo; - } - - public Exchange getExchangeOne() { - return this.exchangeOne; - } - - public Exchange getExchangeTwo() { - return this.exchangeTwo; - } - - public Assignment getAssignmentTwo() { - return this.exchangeTwo.getOwnedAssignment(); - } - - public Assignment getAssignmentOne() { - return this.exchangeOne.getOwnedAssignment(); - } - - @Override - public int hashCode() { - return this.getAssignmentOne().hashCode() + this.getAssignmentTwo().hashCode(); - } - - @Override - public boolean equals(Object o) { - - // If the object is compared with itself then return true - if (o == this) { - return true; - } - - /* - * Check if o is an instance of Complex or not "null instanceof [type]" also - * returns false + /** + * create MatchData + * + * @param exchangeOne first Exchange of found match + * @param exchangeTwo second Exchange of found match */ - if (!(o instanceof MatchData)) { - return false; + public MatchData(Exchange exchangeOne, Exchange exchangeTwo) { + this.exchangeOne = exchangeOne; + this.exchangeTwo = exchangeTwo; } - // typecast o to Complex so that we can compare data members - MatchData c = (MatchData) o; + /** + * @return first Exchange + */ + public Exchange getExchangeOne() { + return this.exchangeOne; + } - // Compare the data members and return accordingly - return (this.getAssignmentOne().equals(c.getAssignmentOne()) && this.getAssignmentTwo().equals(c.getAssignmentTwo())) || (this.getAssignmentOne().equals(c.getAssignmentTwo()) && this.getAssignmentTwo().equals(c.getAssignmentOne())); - } + /** + * @return second Exchange + */ + public Exchange getExchangeTwo() { + return this.exchangeTwo; + } - public int compare(MatchData m1) { - return Long.compare(m1.getExchangesMsValue(), this.getExchangesMsValue()); - } + /** + * @return second Exchange's owned assignmetn + */ + public Assignment getAssignmentTwo() { + return this.exchangeTwo.getOwnedAssignment(); + } - public long getExchangesMsValue(){ - return this.exchangeOne.getDataExchange().getTime() + this.exchangeTwo.getDataExchange().getTime(); - } + /** + * @return first Exchange's owned assignmetn + */ + public Assignment getAssignmentOne() { + return this.exchangeOne.getOwnedAssignment(); + } + + @Override + public int hashCode() { + return this.getAssignmentOne().hashCode() + this.getAssignmentTwo().hashCode(); + } + + @Override + public boolean equals(Object o) { + + if (o == this) { + return true; + } + + if (!(o instanceof MatchData)) { + return false; + } + + MatchData c = (MatchData) o; + + return (this.getAssignmentOne().equals(c.getAssignmentOne()) + && this.getAssignmentTwo().equals(c.getAssignmentTwo())) + || (this.getAssignmentOne().equals(c.getAssignmentTwo()) + && this.getAssignmentTwo().equals(c.getAssignmentOne())); + } + + /** + * comparator for MatchData. It compare it by sum of both exchange's times. For + * example MatchData with Exchanges 11:00 and 12:00 will be less than with + * Exchanges 12:00 and 12:00 + * + * @param m1 MatchData instance to compare to + * @return int less than 0 if m1 is "less than", 0 if it's equal and more than 0 + * otherwise + */ + public int compare(MatchData m1) { + return Long.compare(m1.getExchangesMsValue(), this.getExchangesMsValue()); + } + + /** + * @return sum of both exchanges java.sql.Timestanp::getTime" + */ + public long getExchangesMsValue() { + return this.exchangeOne.getDataExchange().getTime() + this.exchangeTwo.getDataExchange().getTime(); + } } diff --git a/buisnesslogic/src/main/java/com/plannaplan/models/TourData.java b/buisnesslogic/src/main/java/com/plannaplan/models/TourData.java index 7858f08..2e30813 100755 --- a/buisnesslogic/src/main/java/com/plannaplan/models/TourData.java +++ b/buisnesslogic/src/main/java/com/plannaplan/models/TourData.java @@ -2,6 +2,9 @@ package com.plannaplan.models; import java.sql.Date; +/** + * Container for Tours dates + */ public class TourData { private Date start; diff --git a/buisnesslogic/src/main/java/com/plannaplan/models/UserApiResponse.java b/buisnesslogic/src/main/java/com/plannaplan/models/UserApiResponse.java index 7fb8274..a7b2ecd 100755 --- a/buisnesslogic/src/main/java/com/plannaplan/models/UserApiResponse.java +++ b/buisnesslogic/src/main/java/com/plannaplan/models/UserApiResponse.java @@ -11,18 +11,36 @@ public class UserApiResponse { public UserApiResponse() { } + /** + * @return user's Surname + */ public String getSurname() { return surname; } + /** + * setter for name. Reson to have setters for this class is for case if there + * would be name and no surname or otherwise + * + * @param surname name to set that was obtained by api request + */ public void setSurname(String surname) { this.surname = surname; } + /** + * @return user's Name + */ public String getName() { return name; } + /** + * setter for surname. Reson to have setters for this class is for case if there + * would be name and no surname or otherwise + * + * @param name name to set that was obtained by api request + */ public void setName(String name) { this.name = name; } diff --git a/buisnesslogic/src/main/java/com/plannaplan/models/package-info.java b/buisnesslogic/src/main/java/com/plannaplan/models/package-info.java new file mode 100755 index 0000000..9055071 --- /dev/null +++ b/buisnesslogic/src/main/java/com/plannaplan/models/package-info.java @@ -0,0 +1,6 @@ +/** + * Provides readonly (mostly) classes to keep data for diffrent pourposes + * + * @since 1.0 + */ +package com.plannaplan.models; diff --git a/buisnesslogic/src/main/java/com/plannaplan/repositories/AppConfigRepository.java b/buisnesslogic/src/main/java/com/plannaplan/repositories/AppConfigRepository.java index 08e3fbb..d0be800 100755 --- a/buisnesslogic/src/main/java/com/plannaplan/repositories/AppConfigRepository.java +++ b/buisnesslogic/src/main/java/com/plannaplan/repositories/AppConfigRepository.java @@ -4,5 +4,8 @@ import com.plannaplan.entities.AppConfig; import org.springframework.data.jpa.repository.JpaRepository; +/** + * Repository for app config + */ public interface AppConfigRepository extends JpaRepository { } diff --git a/buisnesslogic/src/main/java/com/plannaplan/repositories/package-info.java b/buisnesslogic/src/main/java/com/plannaplan/repositories/package-info.java new file mode 100755 index 0000000..4d5edc4 --- /dev/null +++ b/buisnesslogic/src/main/java/com/plannaplan/repositories/package-info.java @@ -0,0 +1,7 @@ +/** + * Provides jpa repositories interfaces to comunicate with database. These are + * used exclusively in services + * + * @since 1.0 + */ +package com.plannaplan.repositories; diff --git a/buisnesslogic/src/main/java/com/plannaplan/services/AssignmentService.java b/buisnesslogic/src/main/java/com/plannaplan/services/AssignmentService.java index e5a8ccf..a99d0ea 100755 --- a/buisnesslogic/src/main/java/com/plannaplan/services/AssignmentService.java +++ b/buisnesslogic/src/main/java/com/plannaplan/services/AssignmentService.java @@ -91,12 +91,14 @@ public class AssignmentService { if (com.isPresent()) { final List assignments = this.getCommisionAssignments(com.get()); assignments.forEach(a -> { - final Groups group = a.getGroup(); - if (group.getCapacity() > group.getRegisteredStudents().size()) { - e.claimGroup(group); - accepted.add(group); - } else { - removed.add(group); + if (a.isAccepted() == false) { + final Groups group = a.getGroup(); + if (group.getCapacity() > group.getRegisteredStudents().size()) { + e.claimGroup(group); + accepted.add(group); + } else { + removed.add(group); + } } }); } diff --git a/buisnesslogic/src/main/java/com/plannaplan/services/CommisionService.java b/buisnesslogic/src/main/java/com/plannaplan/services/CommisionService.java index 109dfd4..2f01a46 100755 --- a/buisnesslogic/src/main/java/com/plannaplan/services/CommisionService.java +++ b/buisnesslogic/src/main/java/com/plannaplan/services/CommisionService.java @@ -26,6 +26,13 @@ public class CommisionService { public CommisionService() { } + /** + * save to database commision. It also checks for missing assignments from + * previous commision (you can not get rid of accepted assignment) + * + * @param commision to save to db + * @return Commision instance with id from database + */ public Commision save(Commision commision) { Optional lastCommision = this.getNewestCommision(commision.getCommisionOwner()); if (lastCommision.isPresent()) { @@ -34,6 +41,7 @@ public class CommisionService { assignment.setPastAssignment(true); this.aRepository.save(assignment); }); + } this.repo.save(commision); return commision; diff --git a/buisnesslogic/src/main/java/com/plannaplan/services/CourseService.java b/buisnesslogic/src/main/java/com/plannaplan/services/CourseService.java index 4a60421..efc8425 100755 --- a/buisnesslogic/src/main/java/com/plannaplan/services/CourseService.java +++ b/buisnesslogic/src/main/java/com/plannaplan/services/CourseService.java @@ -10,7 +10,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** - * Service of CourseService which can get(Course By Name, All Courses, Courses Ammount ), save, delete course. + * Service of CourseService which can get(Course By Name, All Courses, Courses + * Ammount ), save, delete course. */ @Service @@ -18,42 +19,46 @@ public class CourseService { @Autowired private CourseRepository repo; - /* + /** * getCourseByName - * Return Course By Name + * + * @param name name of course to be found + * @return Course By Name */ public Optional getCourseByName(String name) { return this.repo.findByName(name); } - /* - * getAllCourses - * Return List of get courses + /** + * + * @return all courses from db */ public List getAllCourses() { return this.repo.findAll(); } - /* - * save + /** + * save to db + * * @param course which course you would like to save + * @return Course instance with id from db */ public Course save(Course course) { this.repo.save(course); return course; } - /* - * delete + /** + * delete course from db + * * @param course which course you would like to delete */ public void delete(Course course) { this.repo.delete(course); } - /* - * getCoursesAmmount - * Return a ammount of courses + /** + * @return ammount of courses in db */ public int getCoursesAmmount() { return (int) this.repo.count(); diff --git a/buisnesslogic/src/main/java/com/plannaplan/services/EventService.java b/buisnesslogic/src/main/java/com/plannaplan/services/EventService.java index 589348b..daab648 100755 --- a/buisnesslogic/src/main/java/com/plannaplan/services/EventService.java +++ b/buisnesslogic/src/main/java/com/plannaplan/services/EventService.java @@ -12,6 +12,9 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.scheduling.support.CronTrigger; import org.springframework.stereotype.Service; +/** + * Service to manage app events + */ @Service public class EventService { @@ -29,6 +32,9 @@ public class EventService { System.out.println("Checking for groups"); } + /** + * perfroms checks for matching exchanges daily + */ @Scheduled(cron = "0 0 0 * * *") public void performExchangeService() { System.out.println("Performing Exchange"); @@ -53,6 +59,10 @@ public class EventService { jobsMap.put(taskId, scheduledTask); } + /** + * init resources needed for dynamicly creating new tasks (needed to set tours + * end events) + */ @PostConstruct public void initialize() { this.scheduler = new ThreadPoolTaskScheduler(); diff --git a/buisnesslogic/src/main/java/com/plannaplan/services/ExchangeService.java b/buisnesslogic/src/main/java/com/plannaplan/services/ExchangeService.java index dc8fb31..b57a196 100755 --- a/buisnesslogic/src/main/java/com/plannaplan/services/ExchangeService.java +++ b/buisnesslogic/src/main/java/com/plannaplan/services/ExchangeService.java @@ -19,6 +19,9 @@ import com.plannaplan.repositories.ExchangeRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +/** + * Service to manage Exchanges + */ @Service public class ExchangeService { @@ -50,6 +53,9 @@ public class ExchangeService { return this.repo.findById(id); } + /** + * @return list of all exchanges in database + */ public List getAllExchanges() { return this.repo.findAll(); } @@ -78,6 +84,12 @@ public class ExchangeService { return this.repo.checkForExchange(assignment, group); } + /** + * method to perform Exchange algorythm. It search for matches and swap + * assignments between latests user commisions if it can be performed. After + * swap we block users matches that contains switched groups. After algorythm + * email is being sent to all users with information about performed exchanges + */ public void performExchange() { final List matchData = this.getMatches(); final List performedAssignmentExchanges = new ArrayList<>(); @@ -127,6 +139,9 @@ public class ExchangeService { this.repo.deleteAll(exchangesToDelete); } + /** + * @return list of matches found in database + */ public List getMatches() { final List matches = this.repo.getMatches().stream().map(m -> { final Exchange exchangeOne = (Exchange) m[0]; diff --git a/buisnesslogic/src/main/java/com/plannaplan/services/GroupService.java b/buisnesslogic/src/main/java/com/plannaplan/services/GroupService.java index e9a6bab..d3d9656 100755 --- a/buisnesslogic/src/main/java/com/plannaplan/services/GroupService.java +++ b/buisnesslogic/src/main/java/com/plannaplan/services/GroupService.java @@ -18,7 +18,6 @@ import org.springframework.stereotype.Service; * Service of GroupService which can find(optional), get(By Course, Groups * Ammount, Group By Id, find Not Existing Group), save, delete group. */ - @Service public class GroupService { @Autowired @@ -27,34 +26,84 @@ public class GroupService { public GroupService() { } + /** + * find group with given properties + * + * @param time scheduled time for group as int of minutes passed from 00:00 + * @param capacity capacity of group + * @param room class room + * @return optional with Groups instance if found + */ public Optional find(int time, int capacity, String room) { return this.repo.find(time, room, capacity); } + /** + * find group with given properties + * + * @param zajCykId proteprty from usos + * @param nrGr group number + * @return optional with Groups instance if found + */ public Optional find(Integer zajCykId, Integer nrGr) { return this.repo.find(zajCykId, nrGr); } + /** + * find group with given properties + * + * @param id course id of groups belogns to + * @return list of found groups + */ public List getGroupsByCourse(Long id) { return this.repo.getByCourse(id); } + /** + * save group to database + * + * @param group insatnce to be saved + * @return new instance that has id form database + */ public Groups save(Groups group) { return this.repo.save(group); } + /** + * delete from database + * + * @param groups isntance to delete + */ public void delete(Groups groups) { this.repo.delete(groups); } + /** + * get hom manyh groups are in database in general + * + * @return int - groups ammount + */ public int getGroupsAmmount() { return (int) this.repo.count(); } + /** + * find group with given properties + * + * @param id group id + * @return optional with group if found + */ public Optional getGroupById(Long id) { return this.repo.findById(id); } + /** + * get wich of provided id is not existind groups + * + * @param ids list of ids to check + * @return optional with id that is not group if found. If there is multiple + * will be returned first found + */ public Optional findNotExistingGroup(List ids) { for (Long oneId : ids) { if (this.repo.existsById(oneId) == false) { diff --git a/buisnesslogic/src/main/java/com/plannaplan/services/package-info.java b/buisnesslogic/src/main/java/com/plannaplan/services/package-info.java new file mode 100755 index 0000000..2870f10 --- /dev/null +++ b/buisnesslogic/src/main/java/com/plannaplan/services/package-info.java @@ -0,0 +1,7 @@ +/** + * Provides service classes to make operations with entities or comunicate with + * external systems. + * + * @since 1.0 + */ +package com.plannaplan.services; diff --git a/buisnesslogic/src/main/java/com/plannaplan/types/package-info.java b/buisnesslogic/src/main/java/com/plannaplan/types/package-info.java new file mode 100755 index 0000000..a68c251 --- /dev/null +++ b/buisnesslogic/src/main/java/com/plannaplan/types/package-info.java @@ -0,0 +1,6 @@ +/** + * Provides enums for different goals. + * + * @since 1.0 + */ +package com.plannaplan.types; diff --git a/buisnesslogic/src/test/java/com/plannaplan/services/AssignmentServiceTest.java b/buisnesslogic/src/test/java/com/plannaplan/services/AssignmentServiceTest.java index efe00fa..c3a8e4e 100755 --- a/buisnesslogic/src/test/java/com/plannaplan/services/AssignmentServiceTest.java +++ b/buisnesslogic/src/test/java/com/plannaplan/services/AssignmentServiceTest.java @@ -131,6 +131,34 @@ public class AssignmentServiceTest { } + @Test + @DirtiesContext(methodMode = MethodMode.BEFORE_METHOD) + public void shouldAcceptTwoTours() throws InterruptedException { + final Groups group = this.groupService.save(new Groups(5, null, null, 840, WeekDay.MONDAY, null)); + final Groups group2 = this.groupService.save(new Groups(5, null, null, 840, WeekDay.MONDAY, null)); + + User user = this.userService.save(new User(null, null, + "shouldNotAcceptForOnePerson-" + UUID.randomUUID().toString() + "@AssignmentService.test", null, + UserRoles.STUDENT, 234)); + + final Commision com = this.comServie.save(new Commision(user)); + + this.service.save(new Assignment(group, com)); + + this.service.callAcceptAlgorythm(); + + user = this.userService.getById(user.getId()).get(); + assertTrue(user.getStudentRegisteredGrups().size() == 1); + + this.service.save(new Assignment(group2, com)); + + this.service.callAcceptAlgorythm(); + + user = this.userService.getById(user.getId()).get(); + assertTrue(user.getStudentRegisteredGrups().size() == 2); + + } + private void addAssignmentToCommision(Commision com) { Assignment a = new Assignment(null, com); this.service.save(a); diff --git a/restservice/src/main/java/com/plannaplan/App.java b/restservice/src/main/java/com/plannaplan/App.java index 5369a49..b5afea8 100755 --- a/restservice/src/main/java/com/plannaplan/App.java +++ b/restservice/src/main/java/com/plannaplan/App.java @@ -21,6 +21,9 @@ import org.springframework.scheduling.annotation.EnableScheduling; import com.plannaplan.services.ConfiguratorService; +/** + * Root class of Application. + */ @SpringBootApplication @EnableScheduling public class App { @@ -46,7 +49,9 @@ public class App { /** * method to import mocked data to testing app after startz. It is called only - * in dev profile + * in dev profile. Note that tests are written to this app state so if you + * change ConfigData it can have an impact to other tests like + * CommisionControllerTest */ @EventListener(ApplicationReadyEvent.class) public void importData() { diff --git a/restservice/src/main/java/com/plannaplan/Logo.java b/restservice/src/main/java/com/plannaplan/Logo.java index 3573082..229ab78 100755 --- a/restservice/src/main/java/com/plannaplan/Logo.java +++ b/restservice/src/main/java/com/plannaplan/Logo.java @@ -3,6 +3,9 @@ package com.plannaplan; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +/** + * Class to generate logo string on start application and make logs info + */ public class Logo { public static final String ANSI_RESET = "\u001B[0m"; @@ -35,6 +38,11 @@ ANSI_RESET; } + /** + * return init string to log + * @param isDev is spring profile dev + * @return string to print in log + */ public static String getInitInfo(boolean isDev){ DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); LocalDateTime now = LocalDateTime.now(); @@ -45,6 +53,11 @@ ANSI_RESET; return ANSI_BLACK + dtf.format(now) + ANSI_YELLOW + " plannaplan" + ANSI_RESET + " initializing [" +ANSI_BLUE + "prod" + ANSI_RESET +"]"; } + /** + * return start string to log + * @param isDev is spring profile dev + * @return string to print in log + */ public static String getStartedInfo(boolean isDev){ DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); LocalDateTime now = LocalDateTime.now(); diff --git a/restservice/src/main/java/com/plannaplan/Swagger2Config.java b/restservice/src/main/java/com/plannaplan/Swagger2Config.java index 19ad14d..f3796e0 100755 --- a/restservice/src/main/java/com/plannaplan/Swagger2Config.java +++ b/restservice/src/main/java/com/plannaplan/Swagger2Config.java @@ -18,6 +18,9 @@ import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; +/** + * Config class of Swagger to generate rest api documentation + */ @Configuration @EnableSwagger2 public class Swagger2Config extends WebMvcConfigurationSupport { diff --git a/restservice/src/main/java/com/plannaplan/controllers/CommisionController.java b/restservice/src/main/java/com/plannaplan/controllers/CommisionController.java index d052c69..583acd4 100755 --- a/restservice/src/main/java/com/plannaplan/controllers/CommisionController.java +++ b/restservice/src/main/java/com/plannaplan/controllers/CommisionController.java @@ -22,7 +22,9 @@ import com.plannaplan.responses.mappers.CommisionResponseMappers; import com.plannaplan.responses.models.CommisionResponse; import com.plannaplan.services.AssignmentService; import com.plannaplan.services.CommisionService; +import com.plannaplan.services.ConfiguratorService; import com.plannaplan.services.GroupService; +import com.plannaplan.types.AppState; import com.plannaplan.types.UserRoles; import org.springframework.beans.factory.annotation.Autowired; @@ -37,10 +39,15 @@ import org.springframework.web.bind.annotation.RequestParam; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import com.plannaplan.responses.mappers.AssignmentResponseMappers; import com.plannaplan.responses.models.AssignmentResponse; +/** + * Rest controller to Commision and Assignment related endpoints. More detailed + * api docs is available via swagger + */ @RestController @CrossOrigin @RequestMapping("/api/" + App.API_VERSION + "/commisions") @@ -56,9 +63,17 @@ public class CommisionController extends TokenBasedController { @Autowired private AssignmentService assignmentService; + @Autowired + private ConfiguratorService configuratorService; + public CommisionController() { } + /** + * @param groups to make assignmetns + * @param userId user to assign to groups + * @return was operations success + */ @PostMapping(value = { "/user", "/user/{id}" }) @ApiOperation(value = "Create commision with assignents to given groups. If group doesn't exist error will be thrown") public ResponseEntity addCommision( @@ -66,7 +81,7 @@ public class CommisionController extends TokenBasedController { @PathVariable(name = "id", required = false) Long userId) { try { - + final AppState appState = this.configuratorService.getCurrentConfig().getCurrentState(); final User asker = this.getCurrentUser() .orElseThrow(() -> new UserNotFoundException("Invalid token")); @@ -76,23 +91,46 @@ public class CommisionController extends TokenBasedController { : asker; Assert.isTrue((asker.getRole() == UserRoles.DEANERY && user.getRole() == UserRoles.STUDENT - || (asker.getId().equals(user.getId()) && user.getRole() == UserRoles.STUDENT)), + && appState == AppState.NO_TOUR + || (asker.getId().equals(user.getId()) && user.getRole() == UserRoles.STUDENT + && appState != AppState.NO_TOUR)), "Incorrect attempt to change plan"); Optional notExistingGroup = this.groupServcicxe.findNotExistingGroup(groups); Assert.isTrue(!notExistingGroup.isPresent(), "Group " + notExistingGroup.orElse(Long.MIN_VALUE).toString() + "doesn't exist"); + final Optional comPrev = this.commisionService.getNewestCommision(user); final Commision com = new Commision(user, asker); this.commisionService.save(com); + final List addedGroups = new ArrayList<>(); groups.stream().forEach((groupId) -> { Groups group = this.groupServcicxe.getGroupById(groupId) .orElseThrow(() -> new NullPointerException()); Assignment a = new Assignment(group, com); this.assignmentService.save(a); + addedGroups.add(groupId); }); + boolean isBad = false; + if (comPrev.isPresent()) { + final Iterator it = comPrev.get().getAssignments().iterator(); + + while (it.hasNext() && !isBad) { + final Assignment a = it.next(); + if (a.isAccepted() && !addedGroups.contains(a.getId())) { + isBad = true; + } + } + + } + + if (isBad) { + return new ResponseEntity<>("Error. You can't delete accepted assignmet", + HttpStatus.BAD_REQUEST); + } + return new ResponseEntity<>("Succes", HttpStatus.OK); } catch (UserNotFoundException exception) { return new ResponseEntity<>(exception.getMessage(), HttpStatus.NOT_FOUND); @@ -101,6 +139,11 @@ public class CommisionController extends TokenBasedController { } } + /** + * @param groups should include groups list in response + * @return list of user all commisions (history of schedules) + * @throws UserNotFoundException if user was found + */ @GetMapping("/user") @ApiOperation("Return list of user all commisions (history of schedules)") public ResponseEntity> getAlCommisions( @@ -120,6 +163,11 @@ public class CommisionController extends TokenBasedController { return new ResponseEntity<>(result, HttpStatus.OK); } + /** + * @return current schedule of user indenified via token + * @throws Exception if incorrect role was trying to see self schedule (for + * example DEANERY don't have a schedule) + */ @GetMapping("/user/schedule") @ApiOperation(value = "Return user current assignemts (from newest commision). STUDENT Token needs to be provided.") public ResponseEntity> getCurrentAssignments() throws Exception { @@ -137,6 +185,12 @@ public class CommisionController extends TokenBasedController { return new ResponseEntity<>(new ArrayList<>(), HttpStatus.OK); } + /** + * @param userId user id in db + * @param groups should commision include assigned groups list + * @return list of commisions for given user + * @throws UserNotFoundException + */ @PreAuthorize("hasRole('ROLE_DEANERY')") @GetMapping("/user/{id}") @ApiOperation("Return list of commisions for given user. To be able to access this data u need to provide DEANERY token") @@ -156,6 +210,11 @@ public class CommisionController extends TokenBasedController { return new ResponseEntity<>(result, HttpStatus.OK); } + /** + * @param userId schedule to display owner + * @return user's schedule + * @throws Exception if incorrect access atempt occured + */ @PreAuthorize("hasRole('ROLE_DEANERY')") @GetMapping("/user/{id}/schedule") @ApiOperation(value = "Return given user current assignemts (from newest commision). DEANERY Token needs to be provided.") diff --git a/restservice/src/main/java/com/plannaplan/controllers/ConfigController.java b/restservice/src/main/java/com/plannaplan/controllers/ConfigController.java index 9b59955..b4769df 100755 --- a/restservice/src/main/java/com/plannaplan/controllers/ConfigController.java +++ b/restservice/src/main/java/com/plannaplan/controllers/ConfigController.java @@ -35,6 +35,10 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; +/** + * Rest controller to Config related endpoints. More detailed api docs is + * available via swagger + */ @RestController @CrossOrigin @RequestMapping("/api/" + App.API_VERSION + "/configurator") @@ -47,14 +51,22 @@ public class ConfigController { @Value("${plannaplan.dev}") private boolean isDev; - + @Autowired private ConfiguratorService contrl; @Autowired - private UserService userService; - + private UserService userService; + /** + * @param file file .xlsx that contains courses and groups with + * apoinnted rules + * @param firstTourBegin formated string dd.MM.yyyy + * @param firstTourEnd formated string dd.MM.yyyy + * @param secondTourBegin formated string dd.MM.yyyy + * @param secondTourEnd formated string dd.MM.yyyy + * @return was config success + */ @PostMapping(path = "/config", consumes = { "multipart/form-data" }) @PreAuthorize("hasRole('ROLE_ADMIN')") @ApiOperation("Imports data to system. To call you need to provide ADMIN token") @@ -82,7 +94,13 @@ public class ConfigController { } } - + /** + * @param firstTourBegin formated string dd.MM.yyyy + * @param firstTourEnd formated string dd.MM.yyyy + * @param secondTourBegin formated string dd.MM.yyyy + * @param secondTourEnd formated string dd.MM.yyyy + * @return was operation successful + */ @PostMapping(path = "/config/tours") @PreAuthorize("hasRole('ROLE_ADMIN')") @ApiOperation("Set tours dates. To call you need to provide ADMIN token") @@ -104,12 +122,15 @@ public class ConfigController { return new ResponseEntity<>("Sucess", HttpStatus.OK); } + /** + * @param file file .xlsx that contains courses and groups with + * @return was operation successfull + */ @PostMapping(path = "/config/courses", consumes = { "multipart/form-data" }) @PreAuthorize("hasRole('ROLE_ADMIN')") @ApiOperation("Imports data to system. To call you need to provide ADMIN token") public ResponseEntity configAppChangeCources( - @RequestParam("file") @ApiParam(value = "file .xlsx that contains courses and groups with apoinnted rules") MultipartFile file) - { + @RequestParam("file") @ApiParam(value = "file .xlsx that contains courses and groups with apoinnted rules") MultipartFile file) { try { this.contrl.importCoursesStream(file.getInputStream()); return new ResponseEntity<>("Sucess", HttpStatus.OK); @@ -118,15 +139,20 @@ public class ConfigController { } } + /** + * @param ticket CAS ticket to get user wuthority + * @return was admin created + */ @PostMapping(path = "/admin/init") @ApiOperation("It can be run only in the initialization of the application. It will create admin user to manage the application.") - public ResponseEntity initAdmin(@RequestParam("ticket") @ApiParam(value = "Ticket for validation.") String ticket){ - if (this.userService.adminExists()){ + public ResponseEntity initAdmin( + @RequestParam("ticket") @ApiParam(value = "Ticket for validation.") String ticket) { + if (this.userService.adminExists()) { return new ResponseEntity<>("Admin had been already created.", HttpStatus.FORBIDDEN); } - + final CasValidator validator = isDev ? new DefaultUAMCasValidator(serviceUrl, ticket) - : new CustomUAMCasValidator(serviceUrl, ticket); + : new CustomUAMCasValidator(serviceUrl, ticket); try { final CasUserIdentity casUserIdentity = validator.validate(); @@ -140,5 +166,5 @@ public class ConfigController { } catch (Exception e) { return new ResponseEntity<>("Internal Server Error", HttpStatus.INTERNAL_SERVER_ERROR); } - } + } } \ No newline at end of file diff --git a/restservice/src/main/java/com/plannaplan/controllers/CoursesController.java b/restservice/src/main/java/com/plannaplan/controllers/CoursesController.java index 011c707..e20a9cc 100755 --- a/restservice/src/main/java/com/plannaplan/controllers/CoursesController.java +++ b/restservice/src/main/java/com/plannaplan/controllers/CoursesController.java @@ -29,6 +29,10 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import com.plannaplan.responses.models.abstracts.CoursesResponse; +/** + * Rest controller to Courses related endpoints. More detailed api docs is + * available via swagger + */ @RestController @CrossOrigin @RequestMapping("/api/" + App.API_VERSION + "/courses") @@ -41,6 +45,11 @@ public class CoursesController { @Autowired private GroupService groupService; + /** + * @param groups should include groups in response + * @param takenPlaces should include groups in response + * @return list of all courses in system + */ @GetMapping("/all") @ApiOperation(value = "Return all courses") public ResponseEntity> getMethodName( diff --git a/restservice/src/main/java/com/plannaplan/controllers/ExchangeController.java b/restservice/src/main/java/com/plannaplan/controllers/ExchangeController.java index 24c0d89..30a703f 100755 --- a/restservice/src/main/java/com/plannaplan/controllers/ExchangeController.java +++ b/restservice/src/main/java/com/plannaplan/controllers/ExchangeController.java @@ -33,11 +33,15 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; +/** + * Rest controller to Exchange related endpoints. More detailed api docs is + * available via swagger + */ @RestController @CrossOrigin @RequestMapping("/api/" + App.API_VERSION + "/exchanges") @Api(tags = { "Exchange" }, value = "Exchange", description = "Endpoint to exchange with accepted assignments.") -public class ExchangeController extends TokenBasedController{ +public class ExchangeController extends TokenBasedController { @Autowired private GroupService groupService; @@ -48,40 +52,47 @@ public class ExchangeController extends TokenBasedController{ @Autowired private ExchangeService exchangeService; + /** + * @param exchangeRequest mapped json body with requierd paramas (groupid and + * assignment) + * @return was job successfull + * @throws UserNotFoundException if user was not found + */ @PostMapping("/exchange") @ApiOperation(value = "Creates exchange offer.") public ResponseEntity createExchange( - @ApiParam( value = "Json object that contains assignment to trade and desired group") - @RequestBody - Map exchangeRequest) + @ApiParam(value = "Json object that contains assignment to trade and desired group. For example: { \"assignment\": 3, \"group\":32 }") @RequestBody Map exchangeRequest) throws UserNotFoundException { - final User asker = this.getCurrentUser() - .orElseThrow(() -> new UserNotFoundException("Invalid token")); + final User asker = this.getCurrentUser().orElseThrow(() -> new UserNotFoundException("Invalid token")); final Long assignmentId = exchangeRequest.get("assignment"); final Long groupId = exchangeRequest.get("group"); - final List ownedGroups = asker.getStudentRegisteredGrups().stream().map(Groups::getId).collect(Collectors.toList()); + final List ownedGroups = asker.getStudentRegisteredGrups().stream().map(Groups::getId) + .collect(Collectors.toList()); - if(ownedGroups.contains(groupId)){ + if (ownedGroups.contains(groupId)) { return new ResponseEntity<>("User has already got this group.", HttpStatus.BAD_REQUEST); } - if(assignmentId == null || groupId == null ){ + if (assignmentId == null || groupId == null) { return new ResponseEntity<>("Some of values are missing", HttpStatus.BAD_REQUEST); } final Optional assignment = this.assignmentService.getById(assignmentId); final Optional group = this.groupService.getGroupById(groupId); - if(assignment.isEmpty() || group.isEmpty()){ + if (assignment.isEmpty() || group.isEmpty()) { return new ResponseEntity<>("Some of provided value does not exist.", HttpStatus.BAD_REQUEST); } final Assignment assignmentInstance = assignment.get(); final Groups groupInstance = group.get(); - if(!(assignmentInstance.getCommision().getCommisionOwner().getId().equals(asker.getId()) && assignmentInstance.isAccepted())){ - return new ResponseEntity<>("Some of problems appeared. Check if you have access to given assignment and if it is accepted or the exchange has not been already added.", HttpStatus.BAD_REQUEST); + if (!(assignmentInstance.getCommision().getCommisionOwner().getId().equals(asker.getId()) + && assignmentInstance.isAccepted())) { + return new ResponseEntity<>( + "Some of problems appeared. Check if you have access to given assignment and if it is accepted or the exchange has not been already added.", + HttpStatus.BAD_REQUEST); } this.exchangeService.save(new Exchange(assignmentInstance, groupInstance)); @@ -89,37 +100,43 @@ public class ExchangeController extends TokenBasedController{ return new ResponseEntity<>("Success", HttpStatus.OK); } + /** + * @param offerId id to delwete from db + * @return was jub successful + * @throws UserNotFoundException if user was not found + */ @DeleteMapping("/exchange/{id}") @ApiOperation(value = "Delete exchange offer") public ResponseEntity deleteExchange(@PathVariable(name = "id", required = false) Long offerId) throws UserNotFoundException { - final User asker = this.getCurrentUser() - .orElseThrow(() -> new UserNotFoundException("Invalid token")); + final User asker = this.getCurrentUser().orElseThrow(() -> new UserNotFoundException("Invalid token")); final Optional exchange = this.exchangeService.getById(offerId); - if(exchange.isEmpty()){ - return new ResponseEntity<>("Given offer does not exist.", HttpStatus.BAD_REQUEST); + if (exchange.isEmpty()) { + return new ResponseEntity<>("Given offer does not exist.", HttpStatus.BAD_REQUEST); } final Exchange exchangeToDelete = exchange.get(); - if(!(exchangeToDelete.getOwnedAssignment().getCommision().getCommisionOwner().getId().equals(asker.getId()))){ - return new ResponseEntity<>("You have not permission for that action.", HttpStatus.BAD_REQUEST); + if (!(exchangeToDelete.getOwnedAssignment().getCommision().getCommisionOwner().getId().equals(asker.getId()))) { + return new ResponseEntity<>("You have not permission for that action.", HttpStatus.BAD_REQUEST); } this.exchangeService.deleteExchange(exchangeToDelete); return new ResponseEntity<>("Success", HttpStatus.OK); } + /** + * @return return all user's exchange offers + * @throws UserNotFoundException iF user was not found + */ @GetMapping("/exchange/all") @ApiOperation(value = "Get exchange offers") - public ResponseEntity> getExchange() - throws UserNotFoundException { + public ResponseEntity> getExchange() throws UserNotFoundException { - final User asker = this.getCurrentUser() - .orElseThrow(() -> new UserNotFoundException("Invalid token")); + final User asker = this.getCurrentUser().orElseThrow(() -> new UserNotFoundException("Invalid token")); final List response = exchangeService.getByUserId(asker.getId()); final List listOfResponses = ExchangeResponseMappers.mapToDefaultResponse(response); @@ -127,23 +144,27 @@ public class ExchangeController extends TokenBasedController{ return new ResponseEntity<>(listOfResponses, HttpStatus.OK); } + /** + * @param offerId id of exchange in db + * @return Exchage response + * @throws UserNotFoundException if user was not found + */ @GetMapping("/exchange/{id}") - @ApiOperation(value = "Get exchange offers") + @ApiOperation(value = "Get exchange offer") public ResponseEntity getExchangeById(@PathVariable(name = "id", required = false) Long offerId) throws UserNotFoundException { - final User asker = this.getCurrentUser() - .orElseThrow(() -> new UserNotFoundException("Invalid token")); + final User asker = this.getCurrentUser().orElseThrow(() -> new UserNotFoundException("Invalid token")); final Optional exchange = this.exchangeService.getById(offerId); - if(exchange.isEmpty()){ - return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST); + if (exchange.isEmpty()) { + return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST); } final Exchange exchangeInstance = exchange.get(); - if(!exchangeInstance.getOwnerId().equals(asker.getId())){ - return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST); + if (!exchangeInstance.getOwnerId().equals(asker.getId())) { + return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST); } return new ResponseEntity<>(new ExchangeResponse(exchangeInstance), HttpStatus.OK); diff --git a/restservice/src/main/java/com/plannaplan/controllers/GroupController.java b/restservice/src/main/java/com/plannaplan/controllers/GroupController.java index 0af2431..a11f5e2 100755 --- a/restservice/src/main/java/com/plannaplan/controllers/GroupController.java +++ b/restservice/src/main/java/com/plannaplan/controllers/GroupController.java @@ -27,9 +27,12 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; +/** + * Rest controller to Groups related endpoints. More detailed api docs is + * available via swagger + */ @RestController @CrossOrigin - @RequestMapping("/api/" + App.API_VERSION + "/groups") @Api(tags = { "Group" }, value = "Group", description = "Enpoints to deal with gorups. Group is related directly to course and can be either class and lecture") @@ -37,6 +40,12 @@ public class GroupController { @Autowired private GroupService groupService; + /** + * @param id course to display with groups + * @param capacity should include capaticty in response + * @param takenPlaces should include takenPlaces in response + * @return CourseWithGroupsResponse + */ @GetMapping("/course/{id}") @ApiOperation(value = "Return list of lectures and classes (if present) given course") public ResponseEntity> getCourses( @@ -61,6 +70,11 @@ public class GroupController { return new ResponseEntity<>(GroupsMappers.mapToGetCourseGroupsDefaultResponse(groups), HttpStatus.OK); } + /** + * @param id group id to change capacity + * @param newcapacity new capacity to insert + * @return ResponseEntity was action success + */ @PutMapping("/{id}/capacity") @PreAuthorize("hasRole('ROLE_DEANERY')") @ApiOperation(value = "Change capacity of given group. You need to provide DEANERY token to be ale to change capacity") diff --git a/restservice/src/main/java/com/plannaplan/controllers/TokenBasedController.java b/restservice/src/main/java/com/plannaplan/controllers/TokenBasedController.java index 504ce33..b815f52 100755 --- a/restservice/src/main/java/com/plannaplan/controllers/TokenBasedController.java +++ b/restservice/src/main/java/com/plannaplan/controllers/TokenBasedController.java @@ -11,6 +11,10 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.authentication.AnonymousAuthenticationToken; +/** + * Abstract class for controllers that requires token to extra authorize action + * beyond spring security + */ public abstract class TokenBasedController { @Autowired protected UserService userService; @@ -18,6 +22,10 @@ public abstract class TokenBasedController { public TokenBasedController() { } + /** + * @return get currect user based no current spring context + * @throws UserNotFoundException if user was not fount + */ protected Optional getCurrentUser() throws UserNotFoundException { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); diff --git a/restservice/src/main/java/com/plannaplan/controllers/TokenController.java b/restservice/src/main/java/com/plannaplan/controllers/TokenController.java index 18b66c8..0b5e219 100755 --- a/restservice/src/main/java/com/plannaplan/controllers/TokenController.java +++ b/restservice/src/main/java/com/plannaplan/controllers/TokenController.java @@ -26,6 +26,10 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; +/** + * Rest controller to Token related endpoints. More detailed api docs is + * available via swagger + */ @RestController @CrossOrigin @Api(tags = { "Token" }, value = "Token", description = "Enpoints to get authorization.") @@ -40,6 +44,10 @@ public class TokenController { @Autowired private UserService userService; + /** + * @param ticket via CAS obtained ticket - it's base to auth user + * @return TokenResponse if operation was success + */ @GetMapping("/token") @ApiOperation(value = "Endpoint to access token required to call secured endpoints. In order to access token we need to provide access token comming from unviersity CAS system") public ResponseEntity getToken( @@ -64,6 +72,11 @@ public class TokenController { } } + /** + * @param refreshToken refresh token obtained via /token endpoint + * @return TokenResponse if operation was success + * @throws NullPointerException is thrown if user was not found by refrshtoken + */ @GetMapping("/token/refresh") @ApiOperation(value = "Endpoint to access new token based on refresh token. It's needed when request with provided token fail with code 403") public ResponseEntity getRefreshToken( diff --git a/restservice/src/main/java/com/plannaplan/controllers/UsersController.java b/restservice/src/main/java/com/plannaplan/controllers/UsersController.java index 7d3614a..ddc8bfd 100755 --- a/restservice/src/main/java/com/plannaplan/controllers/UsersController.java +++ b/restservice/src/main/java/com/plannaplan/controllers/UsersController.java @@ -27,6 +27,10 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; +/** + * Rest controller to assignments related endpoints. More detailed api docs is + * available via swagger + */ @RestController @CrossOrigin @RequestMapping("/api/" + App.API_VERSION + "/users") @@ -36,6 +40,10 @@ public class UsersController { @Autowired private UserService userService; + /** + * @param query to filrer userst with STUDENT role + * @return list found + */ @GetMapping("/student/search") @PreAuthorize("hasRole('ROLE_DEANERY')") @ApiOperation(value = "Serch for user by providing query. If query is empty it will return all students. You need token with DEANERY role to call this") @@ -46,6 +54,9 @@ public class UsersController { return new ResponseEntity<>(response, HttpStatus.OK); } + /** + * @return list of all studnents + */ @GetMapping("/students") @PreAuthorize("hasRole('ROLE_DEANERY')") @ApiOperation(value = "Gets all students. You need token with DEANERY role to call this") @@ -55,10 +66,16 @@ public class UsersController { return new ResponseEntity<>(response, HttpStatus.OK); } + /** + * @param authority USOS ID or E-mail. If user does not exist it should be USOS + * ID + * @return response entity was operation with succcesss + */ @PostMapping(path = "/admin") @PreAuthorize("hasRole('ROLE_ADMIN')") @ApiOperation(value = "Adds new admin user.") - public ResponseEntity addAdmin(@RequestParam("authority") @ApiParam(value = "USOS ID or E-mail. If user does not exist it should be USOS ID") String authority) { + public ResponseEntity addAdmin( + @RequestParam("authority") @ApiParam(value = "USOS ID or E-mail. If user does not exist it should be USOS ID") String authority) { final Optional userResponse = this.userService.getByAuthority(authority); final User user = userResponse.orElseGet(() -> new User(null, null, null, authority, UserRoles.ADMIN)); user.setRole(UserRoles.ADMIN); @@ -66,10 +83,16 @@ public class UsersController { return new ResponseEntity<>("Success", HttpStatus.OK); } + /** + * @param authority USOS ID or E-mail. If user does not exist it should be USOS + * ID + * @return response entity was operation with succcesss + */ @PostMapping(path = "/deanery") @PreAuthorize("hasRole('ROLE_ADMIN')") @ApiOperation(value = "Adds new deanery user.") - public ResponseEntity addDeanery(@RequestParam("authority") @ApiParam(value = "USOS ID or E-mail. If user does not exist it should be USOS ID") String authority) { + public ResponseEntity addDeanery( + @RequestParam("authority") @ApiParam(value = "USOS ID or E-mail. If user does not exist it should be USOS ID") String authority) { final Optional userResponse = this.userService.getByAuthority(authority); final User user = userResponse.orElseGet(() -> new User(null, null, null, authority, UserRoles.DEANERY)); user.setRole(UserRoles.DEANERY); diff --git a/restservice/src/main/java/com/plannaplan/controllers/package-info.java b/restservice/src/main/java/com/plannaplan/controllers/package-info.java new file mode 100755 index 0000000..e5b6b96 --- /dev/null +++ b/restservice/src/main/java/com/plannaplan/controllers/package-info.java @@ -0,0 +1,6 @@ +/** + * Provides rest controllers that defines endpoints and their accessibility + * + * @since 1.0 + */ +package com.plannaplan.controllers; diff --git a/restservice/src/main/java/com/plannaplan/package-info.java b/restservice/src/main/java/com/plannaplan/package-info.java new file mode 100755 index 0000000..1e3ecca --- /dev/null +++ b/restservice/src/main/java/com/plannaplan/package-info.java @@ -0,0 +1,6 @@ +/** + * Root package of project + * + * @since 1.0 + */ +package com.plannaplan; diff --git a/restservice/src/main/java/com/plannaplan/responses/mappers/AssignmentResponseMappers.java b/restservice/src/main/java/com/plannaplan/responses/mappers/AssignmentResponseMappers.java index b5e4920..eb54a19 100755 --- a/restservice/src/main/java/com/plannaplan/responses/mappers/AssignmentResponseMappers.java +++ b/restservice/src/main/java/com/plannaplan/responses/mappers/AssignmentResponseMappers.java @@ -11,12 +11,25 @@ import com.plannaplan.entities.Groups; import com.plannaplan.responses.models.AssignmentResponse; import com.plannaplan.types.GroupType; +/** + * Mappers for Assingnmetns to api responses + */ public class AssignmentResponseMappers { + /** + * @param assignments lsit of assignments to be maped + * @return list of api responses + */ public static final List mapToResponse(List assignments) { return mapToResponse(assignments, null); } + /** + * + * @param assignments lsit of assignments to be maped + * @param ammounts ammounts to be take into account + * @return list of api responses + */ public static final List mapToResponse(List assignments, HashMap ammounts) { List response = new ArrayList<>(); diff --git a/restservice/src/main/java/com/plannaplan/responses/mappers/CommisionResponseMappers.java b/restservice/src/main/java/com/plannaplan/responses/mappers/CommisionResponseMappers.java index 7ce70d2..1962a4f 100755 --- a/restservice/src/main/java/com/plannaplan/responses/mappers/CommisionResponseMappers.java +++ b/restservice/src/main/java/com/plannaplan/responses/mappers/CommisionResponseMappers.java @@ -8,11 +8,22 @@ import com.plannaplan.entities.Commision; import com.plannaplan.responses.models.CommisionResponse; import com.plannaplan.responses.models.CommisionWithGroupsResponse; +/** + * Mappers for Commisions to api responses + */ public class CommisionResponseMappers { + /** + * @param commisions list of commisions to be mapped + * @return list of api responses + */ public static final List mapToResponse(List commisions) { return commisions.stream().filter(Objects::nonNull).map(CommisionResponse::new).collect(Collectors.toList()); } + /** + * @param commisions list of commisions to be mapped + * @return list of api responses + */ public static final List mapToResponseWithGroups(List commisions) { return commisions.stream().filter(Objects::nonNull).map(CommisionWithGroupsResponse::new) .collect(Collectors.toList()); diff --git a/restservice/src/main/java/com/plannaplan/responses/mappers/CoursesResponseMappers.java b/restservice/src/main/java/com/plannaplan/responses/mappers/CoursesResponseMappers.java index 5d9c1df..944a055 100755 --- a/restservice/src/main/java/com/plannaplan/responses/mappers/CoursesResponseMappers.java +++ b/restservice/src/main/java/com/plannaplan/responses/mappers/CoursesResponseMappers.java @@ -8,11 +8,22 @@ import com.plannaplan.entities.Course; import com.plannaplan.responses.models.CoursesDefaultResponse; import com.plannaplan.responses.models.CoursesWithGroupsResponse; +/** + * Mappers for Courses to api responses + */ public class CoursesResponseMappers { + /** + * @param courses list of courses to be mapped + * @return list of api responses + */ public static final List mapToGetCoursesResponse(List courses) { return courses.stream().filter(Objects::nonNull).map(CoursesDefaultResponse::new).collect(Collectors.toList()); } + /** + * @param courses list of courses to be mapped + * @return list of api responses + */ public static final List mapToGetCoursesWithGroupsResponse(List courses) { return courses.stream().filter(Objects::nonNull).map(CoursesWithGroupsResponse::new) .collect(Collectors.toList()); diff --git a/restservice/src/main/java/com/plannaplan/responses/mappers/ExchangeResponseMappers.java b/restservice/src/main/java/com/plannaplan/responses/mappers/ExchangeResponseMappers.java index 5adc9d6..bad9fef 100755 --- a/restservice/src/main/java/com/plannaplan/responses/mappers/ExchangeResponseMappers.java +++ b/restservice/src/main/java/com/plannaplan/responses/mappers/ExchangeResponseMappers.java @@ -7,7 +7,14 @@ import java.util.stream.Collectors; import com.plannaplan.entities.Exchange; import com.plannaplan.responses.models.ExchangeResponse; +/** + * Mappers for Exchange to api responses + */ public class ExchangeResponseMappers { + /** + * @param exchanges lsit of exchanges to be mapped + * @return list of api responses + */ public static final List mapToDefaultResponse(List exchanges) { return exchanges.stream().filter(Objects::nonNull).map(ExchangeResponse::new).collect(Collectors.toList()); } diff --git a/restservice/src/main/java/com/plannaplan/responses/mappers/GroupsMappers.java b/restservice/src/main/java/com/plannaplan/responses/mappers/GroupsMappers.java index 43779d3..ddabacd 100755 --- a/restservice/src/main/java/com/plannaplan/responses/mappers/GroupsMappers.java +++ b/restservice/src/main/java/com/plannaplan/responses/mappers/GroupsMappers.java @@ -13,7 +13,15 @@ import com.plannaplan.responses.models.CourseWithGroupsResponse; import com.plannaplan.responses.models.GroupWithCapacityResponse; import com.plannaplan.types.GroupType; +/** + * Mappers for Groups to api responses + */ public class GroupsMappers { + /** + * @param groups list of groups to be mapped + * @param taken ammoints to be take into account + * @return list of api responses + */ public static List mapToDefaultResponse(List groups, HashMap taken) { return groups.stream().filter(Objects::nonNull).map(new Function() { @Override @@ -27,10 +35,20 @@ public class GroupsMappers { }).collect(Collectors.toList()); } + /** + * + * @param groups list of groups to be mapped + * @return ammoints to be take into account + */ public static List mapToDefaultResponse(List groups) { return GroupsMappers.mapToDefaultResponse(groups, null); } + /** + * @param groups list of groups to be mapped + * @param taken ammoints to be take into account + * @return list of api responses + */ public static List mapToCapacityResponse(List groups, HashMap taken) { return groups.stream().filter(Objects::nonNull).map(new Function() { @@ -45,10 +63,19 @@ public class GroupsMappers { }).collect(Collectors.toList()); } + /** + * @param groups list of groups to be mapped + * @return ammoints to be take into account + */ public static List mapToCapacityResponse(List groups) { return GroupsMappers.mapToCapacityResponse(groups, null); } + /** + * @param groups list of groups to be mapped + * @param taken ammoints to be take into account + * @return list of api responses + */ public static CourseWithGroupsResponse mapToGetCourseGroupsDefaultResponse( List groups, HashMap taken) { @@ -74,11 +101,20 @@ public class GroupsMappers { return new CourseWithGroupsResponse<>(classes, lectures); } + /** + * @param groups list of groups to be mapped + * @return ammoints to be take into account + */ public static CourseWithGroupsResponse mapToGetCourseGroupsDefaultResponse( List groups) { return GroupsMappers.mapToGetCourseGroupsDefaultResponse(groups, null); } + /** + * @param groups list of groups to be mapped + * @param taken ammoints to be take into account + * @return list of api responses + */ public static CourseWithGroupsResponse mapToGetCourseGroupsWithCapacityResponse( List groups, HashMap taken) { @@ -105,6 +141,10 @@ public class GroupsMappers { return new CourseWithGroupsResponse<>(classes, lectures); } + /** + * @param groups list of groups to be mapped + * @return ammoints to be take into account + */ public static CourseWithGroupsResponse mapToGetCourseGroupsWithCapacityResponse( List groups) { return GroupsMappers.mapToGetCourseGroupsWithCapacityResponse(groups, null); diff --git a/restservice/src/main/java/com/plannaplan/responses/mappers/UserResponseMappers.java b/restservice/src/main/java/com/plannaplan/responses/mappers/UserResponseMappers.java index 096b20e..bef8dd3 100755 --- a/restservice/src/main/java/com/plannaplan/responses/mappers/UserResponseMappers.java +++ b/restservice/src/main/java/com/plannaplan/responses/mappers/UserResponseMappers.java @@ -7,9 +7,15 @@ import java.util.stream.Collectors; import com.plannaplan.entities.User; import com.plannaplan.responses.models.UserResponse; +/** + * Mappers for Users to api responses + */ public class UserResponseMappers { + /** + * @param groups list of groups to be mapped + * @return list of api responses + */ public static List mapToDefaultResponse(List groups) { - return groups.stream().filter(Objects::nonNull).map(UserResponse::new) - .collect(Collectors.toList()); + return groups.stream().filter(Objects::nonNull).map(UserResponse::new).collect(Collectors.toList()); } } diff --git a/restservice/src/main/java/com/plannaplan/responses/mappers/package-info.java b/restservice/src/main/java/com/plannaplan/responses/mappers/package-info.java new file mode 100755 index 0000000..afdd746 --- /dev/null +++ b/restservice/src/main/java/com/plannaplan/responses/mappers/package-info.java @@ -0,0 +1,6 @@ +/** + * Provides mappers to map mutiple entites from db to single api response + * + * @since 1.0 + */ +package com.plannaplan.responses.mappers; diff --git a/restservice/src/main/java/com/plannaplan/responses/models/AssignmentResponse.java b/restservice/src/main/java/com/plannaplan/responses/models/AssignmentResponse.java index 313d6d7..75a4269 100755 --- a/restservice/src/main/java/com/plannaplan/responses/models/AssignmentResponse.java +++ b/restservice/src/main/java/com/plannaplan/responses/models/AssignmentResponse.java @@ -8,6 +8,9 @@ import com.plannaplan.types.GroupType; import io.swagger.annotations.ApiModel; +/** + * Assignment entity api response + */ @ApiModel(description = "Response shows information about given assigment to course.", value = "AssignmentResponse") public class AssignmentResponse { private Long id; @@ -15,6 +18,11 @@ public class AssignmentResponse { private GroupWithCapacityResponse classes; private GroupWithCapacityResponse lecture; + /** + * @param course course entity + * @param lecture lecture Groups entity + * @param classes class Groups entity + */ public AssignmentResponse(Course course, Groups lecture, Groups classes) { this.id = course.getId(); this.name = course.getName(); @@ -22,6 +30,13 @@ public class AssignmentResponse { this.classes = classes == null ? null : new GroupWithCapacityResponse(classes); } + /** + * @param course course entity + * @param lecture lecture Groups entity + * @param classes class Groups entity + * @param ammounts map with ammounts key - group id, value - ammounts of taken + * places + */ public AssignmentResponse(Course course, Groups lecture, Groups classes, HashMap ammounts) { this.id = course.getId(); this.name = course.getName(); @@ -29,28 +44,51 @@ public class AssignmentResponse { this.classes = classes == null ? null : new GroupWithCapacityResponse(classes, ammounts.get(classes.getId())); } + /** + * + * @param course course entity + * @param group class/lecture entity + */ public AssignmentResponse(Course course, Groups group) { this(course, group.getType() == GroupType.LECTURE ? group : null, group.getType() == GroupType.CLASS ? group : null); } + /** + * @param course course entity + * @param group class/lecture entity + * @param ammounts map with ammounts key - group id, value - ammounts of taken + * places + */ public AssignmentResponse(Course course, Groups group, HashMap ammounts) { this(course, group.getType() == GroupType.LECTURE ? group : null, group.getType() == GroupType.CLASS ? group : null, ammounts); } + /** + * @return Lecture in api response forms + */ public GroupWithCapacityResponse getLecture() { return this.lecture; } + /** + * @return Class in api response forms + */ public GroupWithCapacityResponse getClasses() { return this.classes; } + /** + * @return String course name + */ public String getName() { return this.name; } + /** + * @return db assignment id + */ public Long getId() { return this.id; } diff --git a/restservice/src/main/java/com/plannaplan/responses/models/CommisionResponse.java b/restservice/src/main/java/com/plannaplan/responses/models/CommisionResponse.java index 9c91e1e..bd18a4b 100755 --- a/restservice/src/main/java/com/plannaplan/responses/models/CommisionResponse.java +++ b/restservice/src/main/java/com/plannaplan/responses/models/CommisionResponse.java @@ -5,6 +5,9 @@ import com.plannaplan.entities.Commision; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; +/** + * Commision api response + */ @ApiModel(description = "Response shows information about commision.", value = "CommisionResponse") public class CommisionResponse { @ApiModelProperty(value = "ID created by database") @@ -19,6 +22,9 @@ public class CommisionResponse { @ApiModelProperty(value = "Timestamp where the user commit the commision") private String commisionDate; + /** + * @param commision commision to map to api response + */ public CommisionResponse(Commision commision) { this.id = commision.getId(); this.commisionDate = commision.getCommisionDate().toString(); @@ -27,18 +33,30 @@ public class CommisionResponse { : null; } + /** + * @return get Commiter user as api response + */ public UserResponse getCommiter() { return commiter; } + /** + * @return get Owner user as api response + */ public UserResponse getOwner() { return owner; } + /** + * @return when commision was created string formated + */ public String getCommisionDate() { return commisionDate; } + /** + * @return db id + */ public Long getId() { return id; } diff --git a/restservice/src/main/java/com/plannaplan/responses/models/CommisionWithGroupsResponse.java b/restservice/src/main/java/com/plannaplan/responses/models/CommisionWithGroupsResponse.java index 435f754..0e7c109 100755 --- a/restservice/src/main/java/com/plannaplan/responses/models/CommisionWithGroupsResponse.java +++ b/restservice/src/main/java/com/plannaplan/responses/models/CommisionWithGroupsResponse.java @@ -11,12 +11,18 @@ import com.plannaplan.entities.Commision; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; +/** + * Commision With Groups api Response. It extends CommisionResponse repsone + */ @ApiModel(description = "Response shows information about commision and its groups.", value = "CommisionWithGroupsResponse") public class CommisionWithGroupsResponse extends CommisionResponse { @ApiModelProperty(value = "List of groups ids in databse that belongs to commision") private List groups; + /** + * @param commision commision to map to api response + */ public CommisionWithGroupsResponse(Commision commision) { super(commision); this.groups = commision.getAssignments().stream().filter(Objects::nonNull) @@ -29,6 +35,9 @@ public class CommisionWithGroupsResponse extends CommisionResponse { }).collect(Collectors.toList()); } + /** + * @return lsit of fetured groups ids + */ public List getGroups() { return groups; } diff --git a/restservice/src/main/java/com/plannaplan/responses/models/CourseWithGroupsResponse.java b/restservice/src/main/java/com/plannaplan/responses/models/CourseWithGroupsResponse.java index 6b8107f..a4bb3f7 100755 --- a/restservice/src/main/java/com/plannaplan/responses/models/CourseWithGroupsResponse.java +++ b/restservice/src/main/java/com/plannaplan/responses/models/CourseWithGroupsResponse.java @@ -5,21 +5,36 @@ import java.util.List; import io.swagger.annotations.ApiModel; +/** + * Course respose with all realted groups as api response. Alse needs to specify + * what type of Groups api response will be kept here. For excmaple it can be + * GroupDefaultRespnse + */ @ApiModel(description = "Response shows information about groups to given course.", value = "CourseWithGroupsResponse") -public class CourseWithGroupsResponse { +public class CourseWithGroupsResponse { private List lectures = new ArrayList<>(); private List classes = new ArrayList<>(); - public CourseWithGroupsResponse(List classes, List lectures ){ + /** + * @param classes realted classes Groups instance + * @param lectures realted lectures Groups instance + */ + public CourseWithGroupsResponse(List classes, List lectures) { this.lectures = lectures; this.classes = classes; } + /** + * @return realted classes Groups instance + */ public List getClasses() { return this.classes; } + /** + * @return realted lectures Groups instance + */ public List getLectures() { return this.lectures; } diff --git a/restservice/src/main/java/com/plannaplan/responses/models/CoursesDefaultResponse.java b/restservice/src/main/java/com/plannaplan/responses/models/CoursesDefaultResponse.java index 12f5671..83277a9 100755 --- a/restservice/src/main/java/com/plannaplan/responses/models/CoursesDefaultResponse.java +++ b/restservice/src/main/java/com/plannaplan/responses/models/CoursesDefaultResponse.java @@ -5,9 +5,21 @@ import com.plannaplan.responses.models.abstracts.CoursesResponse; import io.swagger.annotations.ApiModel; +/** + * Courses Default Api Response. It extends abstract response - CoursesResponse. + * It was one of first repsones created in system. Later we resigned from + * asbstract and used settig + * spring.jackson.default-property-inclusion = NON_NULL in + * properties instead. + */ @ApiModel(description = "Response shows information about course.", value = "CoursesDefaultResponse") public class CoursesDefaultResponse extends CoursesResponse { + /** + * create new instance + * + * @param course course to map to api response + */ public CoursesDefaultResponse(Course course) { super(course); } diff --git a/restservice/src/main/java/com/plannaplan/responses/models/CoursesWithGroupsResponse.java b/restservice/src/main/java/com/plannaplan/responses/models/CoursesWithGroupsResponse.java index 62820fa..cf5eb17 100755 --- a/restservice/src/main/java/com/plannaplan/responses/models/CoursesWithGroupsResponse.java +++ b/restservice/src/main/java/com/plannaplan/responses/models/CoursesWithGroupsResponse.java @@ -9,12 +9,24 @@ import com.plannaplan.types.GroupType; import io.swagger.annotations.ApiModel; +/** + * Courses With Groups Api Response . It extends abstract response - + * CoursesResponse. It was one of first repsones created in system. Later we + * resigned from asbstract and used settig + * spring.jackson.default-property-inclusion = NON_NULL in + * properties instead. + */ @ApiModel(description = "Response shows information about groups to given course.", value = "CoursesWithGroupsResponse") public class CoursesWithGroupsResponse extends CoursesResponse { private List lectures = new ArrayList<>(); private List classes = new ArrayList<>(); + /** + * create new instance + * + * @param course course to map to api response + */ public CoursesWithGroupsResponse(Course course) { super(course); course.getGroups().stream().forEach(group -> { @@ -26,6 +38,12 @@ public class CoursesWithGroupsResponse extends CoursesResponse { }); } + /** + * + * @param course course to map to api response + * @param lectures list of api resposnes of lectures + * @param classes list of api resposnes of classes + */ public CoursesWithGroupsResponse(Course course, List lectures, List classes) { super(course); @@ -33,10 +51,16 @@ public class CoursesWithGroupsResponse extends CoursesResponse { this.classes = classes; } + /** + * @return list of api resposnes of classes + */ public List getClasses() { return this.classes; } + /** + * @return list of api resposnes of lectures + */ public List getLectures() { return this.lectures; } diff --git a/restservice/src/main/java/com/plannaplan/responses/models/ExchangeResponse.java b/restservice/src/main/java/com/plannaplan/responses/models/ExchangeResponse.java index 7e6057c..4a02a83 100755 --- a/restservice/src/main/java/com/plannaplan/responses/models/ExchangeResponse.java +++ b/restservice/src/main/java/com/plannaplan/responses/models/ExchangeResponse.java @@ -2,35 +2,72 @@ package com.plannaplan.responses.models; import com.plannaplan.entities.Exchange; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +/** + * Exchange proposal api repsonse + */ +@ApiModel(description = "Response shows information about user exchanges", value = "CourseWithGroupsResponse") public class ExchangeResponse { - private Long id; - private GroupDefaultResponse ownedAssignment; - private GroupDefaultResponse desiredGroup; + @ApiModelProperty(value = "Database id") + private Long id; + @ApiModelProperty(value = "Assignmetn that user want to trade") + private GroupDefaultResponse ownedAssignment; + @ApiModelProperty(value = "Group that user want to get") + private GroupDefaultResponse desiredGroup; - public ExchangeResponse(Exchange exchange){ - this.id = exchange.getId(); - this.ownedAssignment = new GroupDefaultResponse(exchange.getOwnedAssignment().getGroup()); - this.desiredGroup = new GroupDefaultResponse(exchange.getDesiredAssignment()); - } + /** + * creat new instance + * + * @param exchange entity to map to api repsone + */ + public ExchangeResponse(Exchange exchange) { + this.id = exchange.getId(); + this.ownedAssignment = new GroupDefaultResponse(exchange.getOwnedAssignment().getGroup()); + this.desiredGroup = new GroupDefaultResponse(exchange.getDesiredAssignment()); + } + /** + * @return get api respondse of wanted byt user group + */ public GroupDefaultResponse getDesiredGroup() { return desiredGroup; } + + /** + * @param desiredGroup set api respondse of wanted byt user group + */ public void setDesiredGroup(GroupDefaultResponse desiredGroup) { this.desiredGroup = desiredGroup; } + + /** + * @return get api respondse of owned user group + */ public GroupDefaultResponse getOwnedAssignment() { return ownedAssignment; } + + /** + * @param ownedAssignment set api respondse of owned user group + */ public void setOwnedAssignment(GroupDefaultResponse ownedAssignment) { this.ownedAssignment = ownedAssignment; } + + /** + * @return database id + */ public Long getId() { return id; } + + /** + * @param id set database id + */ public void setId(Long id) { this.id = id; } - } diff --git a/restservice/src/main/java/com/plannaplan/responses/models/GroupDefaultResponse.java b/restservice/src/main/java/com/plannaplan/responses/models/GroupDefaultResponse.java index 2a16b91..3e16109 100755 --- a/restservice/src/main/java/com/plannaplan/responses/models/GroupDefaultResponse.java +++ b/restservice/src/main/java/com/plannaplan/responses/models/GroupDefaultResponse.java @@ -8,6 +8,9 @@ import com.plannaplan.types.GroupType; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; +/** + * Default api response for Groups entity + */ @JsonInclude(JsonInclude.Include.NON_NULL) @ApiModel(description = "Response shows information about given group.", value = "GroupDefaultResponse") public class GroupDefaultResponse { @@ -36,6 +39,11 @@ public class GroupDefaultResponse { @ApiModelProperty(value = "Value shows how many places is already taken by other students.") private Integer takenPlaces; + /** + * creat new entity + * + * @param group entity to map to api response + */ public GroupDefaultResponse(Groups group) { this.id = group.getId() != null ? group.getId() : null; this.day = group.getDay() != null ? group.getDay().label : -1; @@ -46,43 +54,77 @@ public class GroupDefaultResponse { this.type = group.getType() != null ? group.getType() : null; } + /** + * + * @param group entity to map to api response + * @param takenPlaces ammount of taken places for group by other users + */ public GroupDefaultResponse(Groups group, int takenPlaces) { this(group); this.takenPlaces = takenPlaces; } + /** + * creat new entity + * + * @param assignment entity to map to api response + */ public GroupDefaultResponse(Assignment assignment) { this(assignment.getGroup()); } + /** + * @return what typew of group is this (lecture or class) + */ public GroupType getType() { return type; } + /** + * @return room where classes will take place + */ public String getRoom() { return room; } + /** + * @return name of group lecturer + */ public String getLecturer() { return lecturer; } + /** + * @return time when group is scheduled on + */ public String getTime() { return time; } + /** + * @return time when class ends + */ public String getEndTime() { return endTime; } + /** + * @return int what day is it. 0-6 (Monday - Sunday) + */ public int getDay() { return day; } + /** + * @return db id + */ public Long getId() { return id; } + /** + * @return ammount of taken places for group by other users + */ public Integer getTakenPlaces() { return this.takenPlaces; } diff --git a/restservice/src/main/java/com/plannaplan/responses/models/GroupWithCapacityResponse.java b/restservice/src/main/java/com/plannaplan/responses/models/GroupWithCapacityResponse.java index 1ca9fc2..881dcfe 100755 --- a/restservice/src/main/java/com/plannaplan/responses/models/GroupWithCapacityResponse.java +++ b/restservice/src/main/java/com/plannaplan/responses/models/GroupWithCapacityResponse.java @@ -4,29 +4,57 @@ import com.plannaplan.entities.Assignment; import com.plannaplan.entities.Groups; import io.swagger.annotations.ApiModel; +/** + * Group api response featuring group capacity + */ @ApiModel(description = "Response shows information about group with included capacity.", value = "GroupWithCapacityResponse") public class GroupWithCapacityResponse extends GroupDefaultResponse { private int capacity; + /** + * create new instance + * + * @param group entity to map to api response + */ public GroupWithCapacityResponse(Groups group) { super(group); this.capacity = group.getCapacity(); } + /** + * create new instance + * + * @param group entity to map to api response + * @param takenPlaces group taken places + */ public GroupWithCapacityResponse(Groups group, int takenPlaces) { super(group, takenPlaces); this.capacity = group.getCapacity(); } + /** + * create new instance + * + * @param assignment entity to map to api response + */ public GroupWithCapacityResponse(Assignment assignment) { this(assignment.getGroup()); } + /** + * create new instance + * + * @param assignment entity to map to api response + * @param takenPlaces group taken places + */ public GroupWithCapacityResponse(Assignment assignment, int takenPlaces) { this(assignment.getGroup(), takenPlaces); } + /** + * @return group taken places + */ public int getCapacity() { return capacity; } diff --git a/restservice/src/main/java/com/plannaplan/responses/models/TokenResponse.java b/restservice/src/main/java/com/plannaplan/responses/models/TokenResponse.java index 583619f..3bcec30 100755 --- a/restservice/src/main/java/com/plannaplan/responses/models/TokenResponse.java +++ b/restservice/src/main/java/com/plannaplan/responses/models/TokenResponse.java @@ -5,6 +5,9 @@ import com.plannaplan.entities.User; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; +/** + * Response to show after successfully login cation + */ @ApiModel(description = "Response shows information about logged user.", value = "TokenResponse") public class TokenResponse { @ApiModelProperty(value = "user token used to verify requests") @@ -18,6 +21,9 @@ public class TokenResponse { @ApiModelProperty(value = "user unviersity email") private String email; + /** + * @param user user to be mapped to api response + */ public TokenResponse(User user) { this.id = user.getId(); this.authorityRole = user.getRole().toString(); @@ -26,22 +32,37 @@ public class TokenResponse { this.refreshToken = user.getRefreshToken(); } + /** + * @return user email + */ public String getEmail() { return email; } + /** + * @return user role in system + */ public String getAuthorityRole() { return authorityRole; } + /** + * @return db id + */ public Long getId() { return id; } + /** + * @return user token to authorize other requests + */ public String getToken() { return token; } + /** + * @return user refresh token + */ public String getRefreshToken() { return this.refreshToken; } diff --git a/restservice/src/main/java/com/plannaplan/responses/models/UserResponse.java b/restservice/src/main/java/com/plannaplan/responses/models/UserResponse.java index ac606ac..6aa695a 100755 --- a/restservice/src/main/java/com/plannaplan/responses/models/UserResponse.java +++ b/restservice/src/main/java/com/plannaplan/responses/models/UserResponse.java @@ -4,6 +4,9 @@ import com.plannaplan.entities.User; import io.swagger.annotations.ApiModel; +/** + * Model for api response for user serach results. + */ @ApiModel(description = "Response shows information about user.", value = "UserResponse") public class UserResponse { @@ -12,6 +15,9 @@ public class UserResponse { private String surname; private String email; + /** + * @param user entity to be mapped to api response + */ public UserResponse(User user) { this.id = user.getId(); this.name = user.getName() != null ? user.getName() : ""; @@ -19,18 +25,30 @@ public class UserResponse { this.email = user.getEmail(); } + /** + * @return user email + */ public String getEmail() { return email; } + /** + * @return user surname + */ public String getSurname() { return surname; } + /** + * @return user name + */ public String getName() { return name; } + /** + * @return db id + */ public Long getId() { return id; } diff --git a/restservice/src/main/java/com/plannaplan/responses/models/abstracts/CoursesResponse.java b/restservice/src/main/java/com/plannaplan/responses/models/abstracts/CoursesResponse.java index 6f1f916..903a451 100755 --- a/restservice/src/main/java/com/plannaplan/responses/models/abstracts/CoursesResponse.java +++ b/restservice/src/main/java/com/plannaplan/responses/models/abstracts/CoursesResponse.java @@ -2,20 +2,34 @@ package com.plannaplan.responses.models.abstracts; import com.plannaplan.entities.Course; +/** + * Course entity api response + */ public abstract class CoursesResponse { private Long id; private String name; + /** + * create instance + * + * @param course entity to map to api response + */ public CoursesResponse(Course course) { this.id = course.getId() != null ? course.getId() : null; this.name = course.getName() != null ? course.getName() : ""; } + /** + * @return course name + */ public String getName() { return name; } + /** + * @return db id + */ public Long getId() { return id; } diff --git a/restservice/src/main/java/com/plannaplan/responses/models/abstracts/package-info.java b/restservice/src/main/java/com/plannaplan/responses/models/abstracts/package-info.java new file mode 100755 index 0000000..0c26925 --- /dev/null +++ b/restservice/src/main/java/com/plannaplan/responses/models/abstracts/package-info.java @@ -0,0 +1,6 @@ +/** + * Abstract api responses + * + * @since 1.0 + */ +package com.plannaplan.responses.models.abstracts; diff --git a/restservice/src/main/java/com/plannaplan/responses/models/package-info.java b/restservice/src/main/java/com/plannaplan/responses/models/package-info.java new file mode 100755 index 0000000..4c64d0a --- /dev/null +++ b/restservice/src/main/java/com/plannaplan/responses/models/package-info.java @@ -0,0 +1,7 @@ +/** + * Provides models of all possible api responses. Convention for naming this + * class is EntityModifierRepsone. For Example CourseDefaultResponse + * + * @since 1.0 + */ +package com.plannaplan.responses.models; diff --git a/restservice/src/main/java/com/plannaplan/responses/package-info.java b/restservice/src/main/java/com/plannaplan/responses/package-info.java new file mode 100755 index 0000000..27f155a --- /dev/null +++ b/restservice/src/main/java/com/plannaplan/responses/package-info.java @@ -0,0 +1,6 @@ +/** + * Contains packeges realted to creating api responses + * + * @since 1.0 + */ +package com.plannaplan.responses; diff --git a/restservice/src/main/java/com/plannaplan/security/AuthenticationFilter.java b/restservice/src/main/java/com/plannaplan/security/AuthenticationFilter.java index 3ebfe13..f9bcb26 100755 --- a/restservice/src/main/java/com/plannaplan/security/AuthenticationFilter.java +++ b/restservice/src/main/java/com/plannaplan/security/AuthenticationFilter.java @@ -17,6 +17,9 @@ import org.springframework.security.web.util.matcher.RequestMatcher; import static org.springframework.http.HttpHeaders.AUTHORIZATION; +/** + * Spring authentication filter class + */ public class AuthenticationFilter extends AbstractAuthenticationProcessingFilter { AuthenticationFilter(final RequestMatcher requiresAuth) { diff --git a/restservice/src/main/java/com/plannaplan/security/AuthenticationProvider.java b/restservice/src/main/java/com/plannaplan/security/AuthenticationProvider.java index e094488..a2bd294 100755 --- a/restservice/src/main/java/com/plannaplan/security/AuthenticationProvider.java +++ b/restservice/src/main/java/com/plannaplan/security/AuthenticationProvider.java @@ -16,6 +16,9 @@ import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Component; +/** + * Spring authentication provider + */ @Component public class AuthenticationProvider extends AbstractUserDetailsAuthenticationProvider { @@ -25,8 +28,6 @@ public class AuthenticationProvider extends AbstractUserDetailsAuthenticationPro @Override protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { - // is being done in other task - } @Override diff --git a/restservice/src/main/java/com/plannaplan/security/AuthorityRoles.java b/restservice/src/main/java/com/plannaplan/security/AuthorityRoles.java index 7005438..ead5811 100755 --- a/restservice/src/main/java/com/plannaplan/security/AuthorityRoles.java +++ b/restservice/src/main/java/com/plannaplan/security/AuthorityRoles.java @@ -6,6 +6,9 @@ import com.plannaplan.types.UserRoles; import org.springframework.security.core.GrantedAuthority; +/** + * Users Roles for spring app + */ public enum AuthorityRoles implements GrantedAuthority { STUDENT("ROLE_STUDENT"), DEANERY("ROLE_DEANERY"), ADMIN("ROLE_ADMIN"), TEST_USER("ROLE_TESTUSER"); @@ -20,6 +23,12 @@ public enum AuthorityRoles implements GrantedAuthority { return this.role; } + /** + * map buisness logic UserRoles enum to spring enum + * + * @param role buisness logic enum + * @return restservice AuthorityRoles enum + */ public static final Optional getAuthorityRole(UserRoles role) { switch (role) { case ADMIN: diff --git a/restservice/src/main/java/com/plannaplan/security/WebSecurityConfig.java b/restservice/src/main/java/com/plannaplan/security/WebSecurityConfig.java index cbeff0d..a5bbce8 100755 --- a/restservice/src/main/java/com/plannaplan/security/WebSecurityConfig.java +++ b/restservice/src/main/java/com/plannaplan/security/WebSecurityConfig.java @@ -16,9 +16,11 @@ import org.springframework.http.HttpStatus; import org.springframework.security.web.authentication.AnonymousAuthenticationFilter; import org.springframework.security.web.authentication.HttpStatusEntryPoint; +/** + * Spring config class for security + */ @Configuration @EnableWebSecurity - public class WebSecurityConfig extends WebSecurityConfigurerAdapter { private static final RequestMatcher PROTECTED_URLS = new OrRequestMatcher(new AntPathRequestMatcher("/api/**")); diff --git a/restservice/src/main/java/com/plannaplan/security/cas/CasUserIdentity.java b/restservice/src/main/java/com/plannaplan/security/cas/CasUserIdentity.java index 90b1f5e..01a72be 100755 --- a/restservice/src/main/java/com/plannaplan/security/cas/CasUserIdentity.java +++ b/restservice/src/main/java/com/plannaplan/security/cas/CasUserIdentity.java @@ -1,19 +1,36 @@ package com.plannaplan.security.cas; +/** + * Model to keep data from Cas response. It's important to remember that wee + * need to register our domain name in CAS in order to get this data. Otherwise + * CAS will retuned what user typed as login. + */ public class CasUserIdentity { private String usosId; private String email; - - public CasUserIdentity(String usosId, String email){ + + /** + * creates new instance + * + * @param usosId usosId retured from CAS + * @param email emial returned from CAS + */ + public CasUserIdentity(String usosId, String email) { this.usosId = usosId; this.email = email; } + /** + * @return string with usosid + */ public String getUsosId() { return usosId; - } + } + /** + * @return string with email + */ public String getEmail() { return email; - } + } } \ No newline at end of file diff --git a/restservice/src/main/java/com/plannaplan/security/cas/CasValidationExcepiton.java b/restservice/src/main/java/com/plannaplan/security/cas/CasValidationExcepiton.java index 3e6fec3..e53b99a 100755 --- a/restservice/src/main/java/com/plannaplan/security/cas/CasValidationExcepiton.java +++ b/restservice/src/main/java/com/plannaplan/security/cas/CasValidationExcepiton.java @@ -1,9 +1,9 @@ package com.plannaplan.security.cas; +/** + * Exception to throw when cas didn't validate provided ticket + */ public class CasValidationExcepiton extends RuntimeException { - /** - * - */ private static final long serialVersionUID = 1L; public CasValidationExcepiton(String s) { diff --git a/restservice/src/main/java/com/plannaplan/security/cas/CasValidator.java b/restservice/src/main/java/com/plannaplan/security/cas/CasValidator.java index b091e42..3ef3562 100755 --- a/restservice/src/main/java/com/plannaplan/security/cas/CasValidator.java +++ b/restservice/src/main/java/com/plannaplan/security/cas/CasValidator.java @@ -1,6 +1,17 @@ package com.plannaplan.security.cas; +/** + * We can authorize in different contexts. For example if we rgister our domain + * we will get more info than on localhost. This abstraction let's us handle + * both cases based on spring profile + */ public interface CasValidator { - + + /** + * validate ticket (should be provided in costructor or by setter) + * + * @return CasUserIdentity instance with values from response or null if + * validation failed + */ CasUserIdentity validate(); } diff --git a/restservice/src/main/java/com/plannaplan/security/cas/CustomUAMCasValidator.java b/restservice/src/main/java/com/plannaplan/security/cas/CustomUAMCasValidator.java index 9a845df..be32736 100755 --- a/restservice/src/main/java/com/plannaplan/security/cas/CustomUAMCasValidator.java +++ b/restservice/src/main/java/com/plannaplan/security/cas/CustomUAMCasValidator.java @@ -4,6 +4,10 @@ import org.jasig.cas.client.validation.Assertion; import org.jasig.cas.client.validation.Cas20ServiceTicketValidator; import org.jasig.cas.client.validation.TicketValidationException; +/** + * Cas Validator for UAM with domain registered for email and usosid as a + * repsonse + */ public class CustomUAMCasValidator implements CasValidator { private static String CAS_URL = "https://cas.amu.edu.pl/cas"; private static String EMAIL_FIELD = "mail"; @@ -11,31 +15,36 @@ public class CustomUAMCasValidator implements CasValidator { private String service; private String ticket; - public CustomUAMCasValidator(String service, String ticket){ + /** + * craste new instance + * + * @param service string with url of our service from where request began + * @param ticket ticket returned after user provided creeds on cas page + */ + public CustomUAMCasValidator(String service, String ticket) { this.service = service; this.ticket = ticket; } @Override public CasUserIdentity validate() { - /* - * TO DO - * Dodać case z CAS10/CAS20/CAS30 - */ final Cas20ServiceTicketValidator validator = new Cas20ServiceTicketValidator(CustomUAMCasValidator.CAS_URL); try { final Assertion assertion = validator.validate(this.ticket, this.service); - + if (assertion == null) { - throw new CasValidationExcepiton("Validation failed. Assertion could not be retrieved for ticket " + ""); + throw new CasValidationExcepiton( + "Validation failed. Assertion could not be retrieved for ticket " + ""); } - final String usosid = assertion.getPrincipal().getAttributes().get(CustomUAMCasValidator.USOS_ID).toString(); - - final String mail = assertion.getPrincipal().getAttributes().get(CustomUAMCasValidator.EMAIL_FIELD).toString(); + final String usosid = assertion.getPrincipal().getAttributes().get(CustomUAMCasValidator.USOS_ID) + .toString(); - return new CasUserIdentity(usosid,mail); + final String mail = assertion.getPrincipal().getAttributes().get(CustomUAMCasValidator.EMAIL_FIELD) + .toString(); + + return new CasUserIdentity(usosid, mail); } catch (TicketValidationException e) { e.printStackTrace(); diff --git a/restservice/src/main/java/com/plannaplan/security/cas/DefaultUAMCasValidator.java b/restservice/src/main/java/com/plannaplan/security/cas/DefaultUAMCasValidator.java index e79a410..989c67f 100755 --- a/restservice/src/main/java/com/plannaplan/security/cas/DefaultUAMCasValidator.java +++ b/restservice/src/main/java/com/plannaplan/security/cas/DefaultUAMCasValidator.java @@ -9,12 +9,21 @@ import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; +/** + * Cas Validator for localhost and not registered dopmains + */ public class DefaultUAMCasValidator implements CasValidator { private static String CAS_URL = "https://cas.amu.edu.pl/cas"; private final CloseableHttpClient httpClient = HttpClients.createDefault(); private String service; private String ticket; + /** + * craste new instance + * + * @param service string with url of our service from where request began + * @param ticket ticket returned after user provided creeds on cas page + */ public DefaultUAMCasValidator(String service, String ticket) { this.service = service; this.ticket = ticket; @@ -39,13 +48,13 @@ public class DefaultUAMCasValidator implements CasValidator { } String res = result.substring(result.indexOf('\n') + 1); - return new CasUserIdentity(null,res); + return new CasUserIdentity(null, res); } } catch (Exception e) { - throw new CasValidationExcepiton("Cas Validation has failed."); + throw new CasValidationExcepiton("Cas Validation has failed."); } } } diff --git a/restservice/src/main/java/com/plannaplan/security/cas/package-info.java b/restservice/src/main/java/com/plannaplan/security/cas/package-info.java new file mode 100755 index 0000000..4634cc0 --- /dev/null +++ b/restservice/src/main/java/com/plannaplan/security/cas/package-info.java @@ -0,0 +1,6 @@ +/** + * All calsses realted to authorizing user with CAS system. + * + * @since 1.0 + */ +package com.plannaplan.security.cas; diff --git a/restservice/src/main/java/com/plannaplan/security/package-info.java b/restservice/src/main/java/com/plannaplan/security/package-info.java new file mode 100755 index 0000000..25da29a --- /dev/null +++ b/restservice/src/main/java/com/plannaplan/security/package-info.java @@ -0,0 +1,7 @@ +/** + * All classes realted to seciuirty includin spring secuirty and cas + * authentication + * + * @since 1.0 + */ +package com.plannaplan.security; diff --git a/restservice/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/restservice/src/main/resources/META-INF/additional-spring-configuration-metadata.json index ddf61f2..a106409 100755 --- a/restservice/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/restservice/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -14,6 +14,21 @@ "name": "plannaplan.email", "type": "java.lang.String", "description": "Email from which app sends message" + }, + { + "name": "plannaplan.apiurl", + "type": "java.lang.String", + "description": "Url to usos api endpoints" + }, + { + "name": "plannaplan.apikey", + "type": "java.lang.String", + "description": "Api consumer key" + }, + { + "name": "plannaplan.apisecret", + "type": "java.lang.String", + "description": "Api consumer secret" } ] } diff --git a/restservice/src/test/java/com/plannaplan/controllers/CommisionControllerTest.java b/restservice/src/test/java/com/plannaplan/controllers/CommisionControllerTest.java index 5ff2377..25990f5 100755 --- a/restservice/src/test/java/com/plannaplan/controllers/CommisionControllerTest.java +++ b/restservice/src/test/java/com/plannaplan/controllers/CommisionControllerTest.java @@ -67,14 +67,14 @@ public class CommisionControllerTest extends AbstractControllerTest { } @Test - public void shouldReturnOkAddingCommision() throws Exception { + public void shouldFailAddingCommisionDueToWrongTour() throws Exception { this.checkUsers(); final User user = this.service.checkForUser(TEST_COMMISIONS_STUDENT_EMAIL, null); final String token = this.service.login(user).getToken(); MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build(); mockMvc.perform(post(ADD_COMMISION_ENDPOINT).header("Authorization", "Bearer " + token) - .contentType(APPLICATION_JSON_UTF8).content("[]")).andExpect(status().isOk()); + .contentType(APPLICATION_JSON_UTF8).content("[]")).andExpect(status().is4xxClientError()); } @Test @@ -95,15 +95,16 @@ public class CommisionControllerTest extends AbstractControllerTest { } @Test - public void shouldAddCommisionWithSelfIdPrivided() throws Exception { + public void shouldFailAddingCommisionWithSelfIdPrividedDueToWrongTour() throws Exception { this.checkUsers(); + final User user = this.service.checkForUser(TEST_COMMISIONS_STUDENT_EMAIL, null); final String token = this.service.login(user).getToken(); MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build(); mockMvc.perform(post(ADD_COMMISION_ENDPOINT + "/" + CommisionControllerTest.user.getId().toString()) .header("Authorization", "Bearer " + token).contentType(APPLICATION_JSON_UTF8).content("[]")) - .andExpect(status().isOk()); + .andExpect(status().is4xxClientError()); } @Test