ADD: Assignment 1 source code. (4ec7f52e) · Commits · YUE SONG / assignment-1 · GitLab Skip to content Projects Groups Snippets Help Loading... Help Submit feedback Sign in / Register Toggle navigation A assignment-1 Project Project Details Activity Releases Cycle Analytics Repository Repository Files Commits Branches Tags Contributors Graph Compare Charts Issues 0 Issues 0 List Board Labels Milestones Merge Requests 0 Merge Requests 0 CI / CD CI / CD Pipelines Jobs Schedules Charts Wiki Wiki Snippets Snippets Members Members Collapse sidebar Close sidebar Activity Graph Charts Create a new issue Jobs Commits Issue Boards Open sidebar YUE SONG assignment-1 Commits 4ec7f52e Commit 4ec7f52e authored Aug 11, 2021 by Tim Miller Browse files Options Browse Files Download Email Patches Plain Diff ADD: Assignment 1 source code. parents Changes 48 Expand all Hide whitespace changes Inline Side-by-side Showing 48 changed files with 2882 additions and 0 deletions +2882 -0 README.md README.md +0 -0 build.xml build.xml +87 -0 hamcrest-core-1.3.jar lib/hamcrest-core-1.3.jar +0 -0 junit-4.11.jar lib/junit-4.11.jar +0 -0 Date.java programs/mutant-1/swen90006/fotbot/Date.java +125 -0 DuplicateUserException.java ...ams/mutant-1/swen90006/fotbot/DuplicateUserException.java +9 -0 FotBot.java programs/mutant-1/swen90006/fotbot/FotBot.java +272 -0 IncorrectPasswordException.java ...mutant-1/swen90006/fotbot/IncorrectPasswordException.java +9 -0 InvalidPasswordException.java ...s/mutant-1/swen90006/fotbot/InvalidPasswordException.java +12 -0 InvalidUsernameException.java ...s/mutant-1/swen90006/fotbot/InvalidUsernameException.java +11 -0 NoSuchUserException.java programs/mutant-1/swen90006/fotbot/NoSuchUserException.java +9 -0 Date.java programs/mutant-2/swen90006/fotbot/Date.java +125 -0 DuplicateUserException.java ...ams/mutant-2/swen90006/fotbot/DuplicateUserException.java +9 -0 FotBot.java programs/mutant-2/swen90006/fotbot/FotBot.java +272 -0 IncorrectPasswordException.java ...mutant-2/swen90006/fotbot/IncorrectPasswordException.java +9 -0 InvalidPasswordException.java ...s/mutant-2/swen90006/fotbot/InvalidPasswordException.java +12 -0 InvalidUsernameException.java ...s/mutant-2/swen90006/fotbot/InvalidUsernameException.java +11 -0 NoSuchUserException.java programs/mutant-2/swen90006/fotbot/NoSuchUserException.java +9 -0 Date.java programs/mutant-3/swen90006/fotbot/Date.java +125 -0 DuplicateUserException.java ...ams/mutant-3/swen90006/fotbot/DuplicateUserException.java +9 -0 FotBot.java programs/mutant-3/swen90006/fotbot/FotBot.java +272 -0 IncorrectPasswordException.java ...mutant-3/swen90006/fotbot/IncorrectPasswordException.java +9 -0 InvalidPasswordException.java ...s/mutant-3/swen90006/fotbot/InvalidPasswordException.java +12 -0 InvalidUsernameException.java ...s/mutant-3/swen90006/fotbot/InvalidUsernameException.java +11 -0 NoSuchUserException.java programs/mutant-3/swen90006/fotbot/NoSuchUserException.java +9 -0 Date.java programs/mutant-4/swen90006/fotbot/Date.java +125 -0 DuplicateUserException.java ...ams/mutant-4/swen90006/fotbot/DuplicateUserException.java +9 -0 FotBot.java programs/mutant-4/swen90006/fotbot/FotBot.java +272 -0 IncorrectPasswordException.java ...mutant-4/swen90006/fotbot/IncorrectPasswordException.java +9 -0 InvalidPasswordException.java ...s/mutant-4/swen90006/fotbot/InvalidPasswordException.java +12 -0 InvalidUsernameException.java ...s/mutant-4/swen90006/fotbot/InvalidUsernameException.java +11 -0 NoSuchUserException.java programs/mutant-4/swen90006/fotbot/NoSuchUserException.java +9 -0 Date.java programs/mutant-5/swen90006/fotbot/Date.java +125 -0 DuplicateUserException.java ...ams/mutant-5/swen90006/fotbot/DuplicateUserException.java +9 -0 FotBot.java programs/mutant-5/swen90006/fotbot/FotBot.java +272 -0 IncorrectPasswordException.java ...mutant-5/swen90006/fotbot/IncorrectPasswordException.java +9 -0 InvalidPasswordException.java ...s/mutant-5/swen90006/fotbot/InvalidPasswordException.java +12 -0 InvalidUsernameException.java ...s/mutant-5/swen90006/fotbot/InvalidUsernameException.java +11 -0 NoSuchUserException.java programs/mutant-5/swen90006/fotbot/NoSuchUserException.java +9 -0 Date.java programs/original/swen90006/fotbot/Date.java +125 -0 DuplicateUserException.java ...ams/original/swen90006/fotbot/DuplicateUserException.java +9 -0 FotBot.java programs/original/swen90006/fotbot/FotBot.java +272 -0 IncorrectPasswordException.java ...original/swen90006/fotbot/IncorrectPasswordException.java +9 -0 InvalidPasswordException.java ...s/original/swen90006/fotbot/InvalidPasswordException.java +12 -0 InvalidUsernameException.java ...s/original/swen90006/fotbot/InvalidUsernameException.java +11 -0 NoSuchUserException.java programs/original/swen90006/fotbot/NoSuchUserException.java +9 -0 BoundaryTests.java tests/swen90006/fotbot/BoundaryTests.java +25 -0 PartitioningTests.java tests/swen90006/fotbot/PartitioningTests.java +88 -0 No files found. README.md 0 → 100644 View file @ 4ec7f52e This diff is collapsed. Click to expand it. build.xml 0 → 100644 View file @ 4ec7f52e
lib/hamcrest-core-1.3.jar 0 → 100644 View file @ 4ec7f52e File added lib/junit-4.11.jar 0 → 100644 View file @ 4ec7f52e File added programs/mutant-1/swen90006/fotbot/Date.java 0 → 100644 View file @ 4ec7f52e package swen90006.fotbot; public class Date { //a mapping from month numbers to month names final private static String [] MONTHS = new String [] {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; //the day, month, and year of this date private int day; private int month; private int year; public Date(int day, int month, int year) { this.day = day; this.month = month; this.year = year; } public int getDay() { return day; } public int getMonth() { return month; } public int getYear() { return year; } /** * Increment the date */ public void increment() { if (day < monthDuration(month, year)) { day++; } else if (month < 12) { day = 1; month++; } else { day = 1; month = 1; year++; } } /** * Decrement the date */ public void decrement() { if (day > 1) { day--; } else if (month > 1) { month--; day = monthDuration(month, year); } else { month = 12; year--; day = monthDuration(month, year); } } /** * Calculates the month duration. */ private static int monthDuration(int month, int year) { //Adjust February for leap years if (month == 2 && (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))) { return 29; } else if (month == 2) { return 28; } else if (month == 4 || month == 6 || month == 9 || month == 11) { return 30; } return 31; } public Date copy() { return new Date(day, month, year); } public boolean equals(Object o) { if (o instanceof Date) { Date date = (Date) o; return day == date.day && month == date.month && year == date.year; } return false; } public String toString() { String result = day + " " + MONTHS[month - 1] + " " + year; return result; } } programs/mutant-1/swen90006/fotbot/DuplicateUserException.java 0 → 100644 View file @ 4ec7f52e package swen90006.fotbot; public class DuplicateUserException extends Exception { public DuplicateUserException(String username) { super("Username already exists: " + username); } } programs/mutant-1/swen90006/fotbot/FotBot.java 0 → 100644 View file @ 4ec7f52e package swen90006.fotbot; import java.util.Map; import java.util.HashMap; import java.util.Set; import java.util.HashSet; import java.util.List; import java.util.ArrayList; /** * * A FotBot looks like a wristwatch and includes functions for * counting the steps of the wearer. This data is uploaded into a * cloud-based system. The FotBot and its cloud application has three * main intended features: * - To record the number of steps a person takes each day. * - To share information with other FotBot wearers for social reasons; e.g.competitions to see who can take the most steps. * - To share information with the FotBot company. * * Each FotBot's data is stored in the cloud. Each user can set access * permissions to their own data, described below. * * The server code is below. For simplicity for the assignment, the * database is implemented as a Java data structure. */ public class FotBot { /** The minimum length of a username */ public final static int MINIMUM_USERNAME_LENGTH = 4; /** The minimum length of a password */ public final static int MINIMUM_PASSWORD_LENGTH = 8; //The admin username and password protected final static String ADMIN_USERNAME = "admin"; protected final static String ADMIN_PASSWORD = "admin_password1"; //Unbreakable! //The passwords for all users (non encrypted!!!) //I'm not claiming this code maintains privacy! :) private Map
passwords; //The number of steps a user has taken in the past private Map> stepData; //The last update for a user private Map latestUpdate; //The friends of users private Map> friends; //The current day private Date currentDay; /** * Constructs a new FotBot server with no users */ public FotBot() { passwords = new HashMap(); stepData = new HashMap>(); latestUpdate = new HashMap(); friends = new HashMap>(); currentDay = new Date(1, 1, 2021); passwords.put(ADMIN_USERNAME, ADMIN_PASSWORD); } /** * Registers a new user. * * The username must be at least four characters long and has no other contraints. * * The password must conform to the following requirements: * - Must be at least eight characters long * - Must contain at least one special ASCII character other than a letter or digit (that is, * other than a-z, A-Z, or 0-9) * * @param username the username for the user to be added * @param password the password for the user * @throws DuplicateUserException if the username is already registered * @throws InvalidUsernameException if the username does not fit * the requirements * @throws InvalidPasswordException if the password does not fit * the requirements * * Assumption: username and password are non-null */ public void register(String username, String password) throws DuplicateUserException, InvalidUsernameException, InvalidPasswordException { //Check if this user exists if (passwords.containsKey(username)) { throw new DuplicateUserException(username); } //Check that the username and password are long enough else if (username.length() < MINIMUM_USERNAME_LENGTH) { throw new InvalidUsernameException(username); } else if (password.length() < MINIMUM_PASSWORD_LENGTH) { throw new InvalidPasswordException(password); } else { //check the password contains at least one special character boolean special = false; for(char c : password.toCharArray()) { if (!('a' <= c && c <= 'z') && !('A' <= c && c <= 'Z') && !('0' <= c && c <= '9')) { special = true; break; } } if (!special) { throw new InvalidPasswordException(password); } } passwords.put(username, password); stepData.put(username, new ArrayList()); latestUpdate.put(username, currentDay.copy()); friends.put(username, new HashSet()); } /** * Checks if a user exists * @param username the username * @return true if and only if this user is registered * * Assumption: username is non-null */ public boolean isUser(String username) { return passwords.containsKey(username); } /** * Updates the steps for a sequence of previous days by adding the * new steps to the user's steps. The update is made from the * current day back to the date of the last update. If the length * of 'steps' is less than the number of days since the last * update, it updates those remaining days with 0. That is, it * updates as many days as possible and then backfills the rest * with 0. * * For example, if the last update is three days ago, and * steps is [3000, 5000], then update [0, 3000, 5000]. * * @throws NoSuchUserException if the user does not have an account * @throws IncorrectPasswordException if the password is incorrect for this user * * Assumption: the length of 'steps' is always less than or equal * to numbers of days since the last update * * Assumption: username and password are non-null * * Assumption: 'steps' records the order of the days from oldest * (at index 0) to most recent (at index steps.length - 1) */ public void update(String username, String password, List steps) throws NoSuchUserException, IncorrectPasswordException { if (checkUsernamePassword(username, password)) { Date userLastUpdate = latestUpdate.get(username); Date day = currentDay.copy(); int i = steps.size() - 1; //Add zeros to the start of the list if required List newUpdates = new ArrayList(); while (!day.equals(userLastUpdate)) { if (i >= 0) { newUpdates.add(0, steps.get(i)); } else { newUpdates.add(0, 0); } i--; day.decrement(); } //Add the new data and update the latest update for this user stepData.get(username).addAll(newUpdates); latestUpdate.put(username, currentDay.copy()); } } /** * Add a friend to a user's set of friends. * * @param username the username * @param password the password * @param friendUsername the friend's username * * @throws NoSuchUserException if the user does not have an account * @throws IncorrectPasswordException if the password is incorrect for this user */ public void addFriend(String username, String password, String friendUsername) throws NoSuchUserException, IncorrectPasswordException { if (checkUsernamePassword(username, password)) { friends.get(username).add(friendUsername); } } /** * Check if someone is a friend of another person. Anyone can read this information * * Assumption: username and friendUsername are both non-null */ public boolean isFriend(String username, String friendUsername) { return friends.get(username).contains(friendUsername); } /** * Read the step data from a user. A user should be able to read step data if and only if: * - the data they are reading is their own; * - the data they are reading is their friends; or * - 'username' is FotBot.ADMIN_USERNAME * * If the reading user is not a friend or admin, return an empty list of data * * @throws NoSuchUserException if either user ('username' or 'user') does not have an account * @throws IncorrectPasswordException if the password is incorrect for username */ public List getStepData(String username, String password, String targetUser) throws NoSuchUserException, IncorrectPasswordException { if (checkUsernamePassword(username, password)) { if (!passwords.containsKey(targetUser)) { throw new NoSuchUserException(targetUser); } if (isFriend(targetUser, username) || username.equals(ADMIN_USERNAME) || username.equals(targetUser)) { return stepData.get(targetUser); } } List result = new ArrayList(); return result; } /** * Increment the current day by a number of days */ public void incrementCurrentDay(int days) { for (int i = 0; i < days; i++) { currentDay.increment(); } } /** * Check a username and password combination, returning true if the * username and password are correct and throwing an exception otherwise. * * @throws NoSuchUserException if the user does not have an account * @throws IncorrectPasswordException if the password is incorrect for this user */ private boolean checkUsernamePassword(String username, String password) throws NoSuchUserException, IncorrectPasswordException { //Check that the user exists if (!passwords.containsKey(username)) { throw new NoSuchUserException(username); } //Check the password else if (!passwords.get(username).equals(password)) { throw new IncorrectPasswordException(username, password); } return true; } } programs/mutant-1/swen90006/fotbot/IncorrectPasswordException.java 0 → 100644 View file @ 4ec7f52e package swen90006.fotbot; public class IncorrectPasswordException extends Exception { public IncorrectPasswordException(String username, String password) { super("Incorrect password: " + password + " for user " + username); } } programs/mutant-1/swen90006/fotbot/InvalidPasswordException.java 0 → 100644 View file @ 4ec7f52e package swen90006.fotbot; public class InvalidPasswordException extends Exception { public InvalidPasswordException(String password) { super("Password " + password + " does not comply with the requirements\n" + "\t- must contains at least " + FotBot.MINIMUM_PASSWORD_LENGTH + " characters\n" + " and one special character that is not a letter or digit"); } } programs/mutant-1/swen90006/fotbot/InvalidUsernameException.java 0 → 100644 View file @ 4ec7f52e package swen90006.fotbot; public class InvalidUsernameException extends Exception { public InvalidUsernameException(String username) { super("Username " + username + " does not comply with the requirements\n" + "\t- must contains at least " + FotBot.MINIMUM_USERNAME_LENGTH + " characters"); } } programs/mutant-1/swen90006/fotbot/NoSuchUserException.java 0 → 100644 View file @ 4ec7f52e package swen90006.fotbot; public class NoSuchUserException extends Exception { public NoSuchUserException (String username) { super("Username does not exist: " + username); } } programs/mutant-2/swen90006/fotbot/Date.java 0 → 100644 View file @ 4ec7f52e package swen90006.fotbot; public class Date { //a mapping from month numbers to month names final private static String [] MONTHS = new String [] {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; //the day, month, and year of this date private int day; private int month; private int year; public Date(int day, int month, int year) { this.day = day; this.month = month; this.year = year; } public int getDay() { return day; } public int getMonth() { return month; } public int getYear() { return year; } /** * Increment the date */ public void increment() { if (day < monthDuration(month, year)) { day++; } else if (month < 12) { day = 1; month++; } else { day = 1; month = 1; year++; } } /** * Decrement the date */ public void decrement() { if (day > 1) { day--; } else if (month > 1) { month--; day = monthDuration(month, year); } else { month = 12; year--; day = monthDuration(month, year); } } /** * Calculates the month duration. */ private static int monthDuration(int month, int year) { //Adjust February for leap years if (month == 2 && (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))) { return 29; } else if (month == 2) { return 28; } else if (month == 4 || month == 6 || month == 9 || month == 11) { return 30; } return 31; } public Date copy() { return new Date(day, month, year); } public boolean equals(Object o) { if (o instanceof Date) { Date date = (Date) o; return day == date.day && month == date.month && year == date.year; } return false; } public String toString() { String result = day + " " + MONTHS[month - 1] + " " + year; return result; } } programs/mutant-2/swen90006/fotbot/DuplicateUserException.java 0 → 100644 View file @ 4ec7f52e package swen90006.fotbot; public class DuplicateUserException extends Exception { public DuplicateUserException(String username) { super("Username already exists: " + username); } } programs/mutant-2/swen90006/fotbot/FotBot.java 0 → 100644 View file @ 4ec7f52e package swen90006.fotbot; import java.util.Map; import java.util.HashMap; import java.util.Set; import java.util.HashSet; import java.util.List; import java.util.ArrayList; /** * * A FotBot looks like a wristwatch and includes functions for * counting the steps of the wearer. This data is uploaded into a * cloud-based system. The FotBot and its cloud application has three * main intended features: * - To record the number of steps a person takes each day. * - To share information with other FotBot wearers for social reasons; e.g.competitions to see who can take the most steps. * - To share information with the FotBot company. * * Each FotBot's data is stored in the cloud. Each user can set access * permissions to their own data, described below. * * The server code is below. For simplicity for the assignment, the * database is implemented as a Java data structure.