diff --git a/LockdownTravellerServer/README.md b/LockdownTravellerServer/README.md new file mode 100644 index 0000000..f24ffb4 --- /dev/null +++ b/LockdownTravellerServer/README.md @@ -0,0 +1,145 @@ +# Index +* [Build and Run Commands](#build-and-run-commands) +* [List of tables](#list-of-tables); +* [Description of tables](#description-of-tables); + * [Admin](#admin); + * [Basic_Train_Info](#basic_train_info) + * [Booking_Info](#booking_info) + * [Notification](#notification) + * [Route_Info](#route_info) + * [User](#user) + * [Vacancy_Info](#vacancy_info) + +# Build and Run Commands. + + ~/checker-framework-3.7.0/checker/bin/javac -processor nullness *.java -d ./bin + + java -classpath ~/Lockdown_Traveller/LockdownTravellerServer/src/bin/:/usr/share/java/mysql-connector-java-8.0.21.jar Server + +# List of tables. + +| Tables | Needed in minimal version?| +|:---------------:|:-------------------------:| +|Admin | Yes | +|Basic_Train_Info | Yes | +|Booking_Info | Yes | +|Notification | Yes | +|Platform_No | No | +|Route_Info | Yes | +|User | Yes | +|Vacancy_Info | Yes | + + +# Description of tables. + +#### Admin + Stores information related to admin login. + +| Field | Type | Null | Key | Default | Extra | +|----------|-------------|------|-----|---------|-------| +| Username | varchar(20) | NO | | NULL | | +| Password | varchar(64) | NO | | NULL | | +| Admin_ID | int | NO | | NULL | | + + +#### Basic_Train_Info + + Stores basic information about the train, like its name, number of different + types of coaches and number of seats in them, fare for each type of coach, + days on which the trains run. + +| Field | Type | Null | Key | Default | Needed in minimal version? | +|------------------|-------------|------|-----|---------|:-----:| +| Train_ID | varchar(5) | NO | PRI | NULL | | +| Train_Name | varchar(30) | NO | | NULL | | +| Days_Running | varchar(7) | NO | | NULL | | +| Cancelled_Till | date | YES | | NULL | No| +| FirstAC_Coaches | int | YES | | NULL | | +| SecondAC_Coaches | int | YES | | NULL | | +| ThirdAC_Coaches | int | YES | | NULL | | +| Sleeper_Coaches | int | YES | | NULL | | +| FirstAC_Seats | int | YES | | NULL | | +| SecondAC_Seats | int | YES | | NULL | | +| ThirdAC_Seats | int | YES | | NULL | | +| Sleeper_Seats | int | YES | | NULL | | +| FirstAC_Fare | int | YES | | NULL | | +| SecondAC_Fare | int | YES | | NULL | | +| ThirdAC_Fare | int | YES | | NULL | | +| Sleeper_Fare | int | YES | | NULL | | +| Rerouted_Till | date | YES | | NULL | No| +| Added_Till | date | YES | | NULL | No| + +#### Booking_Info + + Stores relevant information about each booking. Things liked which user booked + a seat, who will travel on the seat, is the booking confirmed or in waiting. + +| Field | Type | Null | Key | Default | Extra | +|------------------|-------------|------|-----|---------|-------| +| Booking_ID | varchar(10) | NO | PRI | NULL | | +| PNR | varchar(5) | NO | | NULL | | +| User_ID | varchar(20) | NO | MUL | NULL | | +| Passenger_Name | varchar(40) | NO | | NULL | | +| Passenger_Age | int | NO | | NULL | | +| Passenger_Gender | varchar(10) | NO | | NULL | | +| Booking_Status | varchar(10) | NO | | NULL | | + +#### Notification + + Stores notification details. The notification itself, the user to give the + notification to and whether or not the notification has already been seen once. + +| Field | Type | Null | Key | Default | Extra | +|----------------|--------------|------|-----|---------|-------| +| User_ID | varchar(20) | NO | | NULL | | +| Message | varchar(500) | NO | | NULL | | +| Pending_Status | int | NO | | NULL | | + +#### Route_Info + + Stores the stations each train will visit and various information like arrival + departure times etc. + +| Field | Type | Null | Key | Default | Extra | +|------------------|-------------|------|-----|---------|-------| +| Train_ID | varchar(5) | NO | MUL | NULL | | +| Train_Name | varchar(30) | NO | | NULL | | +| Station | varchar(20) | NO | | NULL | | +| Station_No | int | NO | | NULL | | +| City_Code | varchar(3) | NO | | NULL | | +| Arrival | varchar(4) | YES | | NULL | | +| Departure | varchar(4) | YES | | NULL | | +| Day_No | int | NO | | NULL | | +| Distance_Covered | int | NO | | NULL | | +| Rerouted | int | YES | | NULL | | +| inCurrentRoute | int | NO | | NULL | | + +#### User + + Stores detail of the users of the application. + +| Field | Type | Null | Key | Default | Extra | +|-------------|-------------|------|-----|---------|-------| +| User_ID | varchar(20) | NO | PRI | NULL | | +| First_Name | varchar(20) | NO | | NULL | | +| Last_Name | varchar(20) | NO | | NULL | | +| Gender | varchar(10) | NO | | NULL | | +| Age | int | NO | | NULL | | +| Email_ID | varchar(50) | NO | | NULL | | +| Phone_No | varchar(15) | NO | | NULL | | +| Username | varchar(20) | NO | | NULL | | +| Password | varchar(64) | NO | | NULL | | +| Total_Spend | int | NO | | 0 | | + +#### Vacancy_Info + + Stores seats which have been booked from a particular station to another. + +| Field | Type | Null | Key | Default | Extra | +|------------|-------------|------|-----|---------|-------| +| Train_ID | varchar(5) | NO | | NULL | | +| Booking_ID | varchar(15) | NO | MUL | NULL | | +| Date | date | NO | | NULL | | +| Station | varchar(20) | NO | | NULL | | +| Station_No | int | NO | | NULL | | +| Seat_No | varchar(10) | NO | | NULL | | diff --git a/LockdownTravellerServer/src/AdminLoginRequestHandler.java b/LockdownTravellerServer/src/AdminLoginRequestHandler.java index 2d65018..cd301db 100644 --- a/LockdownTravellerServer/src/AdminLoginRequestHandler.java +++ b/LockdownTravellerServer/src/AdminLoginRequestHandler.java @@ -1,3 +1,7 @@ +import org.checkerframework.checker.initialization.qual.Initialized; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.io.ObjectOutputStream; import java.sql.Connection; import java.sql.PreparedStatement; @@ -42,14 +46,17 @@ public void sendQuery() { * @params Queries. * @return Response to the admin login query. */ - public AdminLoginResponse adminLoginRequest(String query) { + public @Nullable AdminLoginResponse adminLoginRequest(String query) { try { System.out.println("Prepared statement"); PreparedStatement validateLogin = connection.prepareStatement(query); validateLogin.setString(1, adminLoginRequest.getUsername()); validateLogin.setString(2, adminLoginRequest.getPassword()); System.out.println("going to execute"); - ResultSet adminCredentials = validateLogin.executeQuery(); + @Initialized @NonNull ResultSet adminCredentials = validateLogin.executeQuery(); // This @NonNull here is + // not redundant because without it, there is a dereference.of.nullable warning in the while clause in the + // else block below. Same with the @Initialized annotation. + // Check if the result set is empty. If empty send failure as object response. if (!adminCredentials.next()) { System.out.println("fail"); @@ -57,7 +64,9 @@ public AdminLoginResponse adminLoginRequest(String query) { } else { do { System.out.println("success"); - return new AdminLoginResponse("success", adminCredentials.getString("Admin_ID")); + @SuppressWarnings("assignment.type.incompatible") // Admin_ID cannot be null. Refer the README. + @NonNull String s = adminCredentials.getString("Admin_ID"); + return new AdminLoginResponse("success", s); } while (adminCredentials.next()); } } catch (SQLException e) { diff --git a/LockdownTravellerServer/src/BookingHistoryRequestHandler.java b/LockdownTravellerServer/src/BookingHistoryRequestHandler.java index fbed946..2060631 100644 --- a/LockdownTravellerServer/src/BookingHistoryRequestHandler.java +++ b/LockdownTravellerServer/src/BookingHistoryRequestHandler.java @@ -1,3 +1,7 @@ +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.io.ObjectOutputStream; import java.sql.Connection; import java.sql.PreparedStatement; @@ -53,7 +57,7 @@ public void sendQuery() { * @params Queries. * @return Response to the Booking history request. */ - public BookingHistoryResponse bookinghistory(BookingHistoryRequest historyRequest, String query1, String query2, String query3) { + public @Nullable BookingHistoryResponse bookinghistory(BookingHistoryRequest historyRequest, String query1, String query2, String query3) { // All fields that will be a part of the response object. ArrayList> bookingID = new ArrayList<>(); @@ -71,13 +75,16 @@ public BookingHistoryResponse bookinghistory(BookingHistoryRequest historyReques getPnr.setString(1, historyRequest.getUserid()); resultSet = getPnr.executeQuery(); while(resultSet.next()) { - pnr.add(resultSet.getString("PNR")); + + @SuppressWarnings("assignment.type.incompatible") // PNR cannot be null. Refer the README. + @NonNull String s = resultSet.getString("PNR"); + pnr.add(s); } final int n = pnr.size(); for(int i = 0; i < n; i++) { System.out.println(pnr.get(i)); PreparedStatement perPnrQuery = connection.prepareStatement(query2); - String confirmedBookingID = ""; + @MonotonicNonNull String confirmedBookingID = null; perPnrQuery.setString(1, pnr.get(i)); ResultSet bookingForPnr = perPnrQuery.executeQuery(); bookingID.add(new ArrayList<>()); @@ -85,25 +92,50 @@ public BookingHistoryResponse bookinghistory(BookingHistoryRequest historyReques age.add(new ArrayList<>()); gender.add(new ArrayList<>()); while(bookingForPnr.next()) { - bookingID.get(i).add(bookingForPnr.getString("Booking_ID")); - if(bookingForPnr.getString("Booking_Status").equals("Confirmed")) - confirmedBookingID = bookingForPnr.getString("Booking_ID"); - name.get(i).add(bookingForPnr.getString("Passenger_Name")); + @SuppressWarnings("assignment.type.incompatible") // Booking_ID cannot be null. Refer the README. + @NonNull String s = bookingForPnr.getString("Booking_ID"); + bookingID.get(i).add(s); + + @SuppressWarnings("assignment.type.incompatible") // Booking_Status cannot be null. Refer the README. + @NonNull String bookingStatus = bookingForPnr.getString("Booking_Status"); + if(bookingStatus.equals("Confirmed")) { + @SuppressWarnings("assignment.type.incompatible") // Booking ID cannot be null. Refer the README. + @NonNull String confirmedId = bookingForPnr.getString("Booking_ID"); + confirmedBookingID = confirmedId; + } + + @SuppressWarnings("assignment.type.incompatible") // Passenger_Name cannot be null. Refer the README. + @NonNull String pName = bookingForPnr.getString("Passenger_Name"); + name.get(i).add(pName); + age.get(i).add(bookingForPnr.getInt("Passenger_Age")); - gender.get(i).add(bookingForPnr.getString("Passenger_Gender")); + + @SuppressWarnings("assignment.type.incompatible") // Gender cannot be null. Refer the README. + @NonNull String pGender = bookingForPnr.getString("Passenger_Gender"); + gender.get(i).add(pGender); } PreparedStatement otherDetails = connection.prepareStatement(query3); - if(!confirmedBookingID.equals("")) { + if(confirmedBookingID != null) { otherDetails.setString(1, confirmedBookingID); otherDetails.setString(2, confirmedBookingID); otherDetails.setString(3, confirmedBookingID); System.out.println(otherDetails.toString()); ResultSet others = otherDetails.executeQuery(); others.next(); - source.add(others.getString("Station")); - date.add(others.getString("Date")); + System.out.println(query3); + @SuppressWarnings("assignment.type.incompatible") // Station cannot be null. Refer the README. + @NonNull String s = others.getString("Station"); + source.add(s); + + @SuppressWarnings("assignment.type.incompatible") // Date cannot be null. Refer the README. + @NonNull String pDate = others.getString("Date"); + date.add(pDate); + others.next(); - destination.add("Station"); + + @SuppressWarnings("assignment.type.incompatible") // Station cannot be null. Refer the README. + @NonNull String pDestination = others.getString("Station"); + destination.add(pDestination); } else { source.add("N/A"); destination.add("N/A"); diff --git a/LockdownTravellerServer/src/BookingRequestHandler.java b/LockdownTravellerServer/src/BookingRequestHandler.java index 71bfaba..e978ea2 100644 --- a/LockdownTravellerServer/src/BookingRequestHandler.java +++ b/LockdownTravellerServer/src/BookingRequestHandler.java @@ -1,3 +1,6 @@ +import org.checkerframework.checker.nullness.qual.*; +import org.checkerframework.common.util.report.qual.ReportWrite; + import java.io.ObjectOutputStream; import java.sql.Connection; import java.sql.PreparedStatement; @@ -12,8 +15,8 @@ public class BookingRequestHandler extends Handler { private final BookingRequest bookingRequest; private final ObjectOutputStream oos; private final String coach, trainID, userID; - private String coachCode; - private boolean[] notVacant; + private @NonNull String coachCode; + private boolean @MonotonicNonNull [] notVacant; private int numCoaches, seatsPerCoach, numSeats, availableSeats, sourceStationNumber=-1, totalCost; private ArrayList stationsOnRoute = new ArrayList<>(); private int currentWaiting = 0; @@ -36,17 +39,6 @@ public BookingRequestHandler(Connection connection, BookingRequest bookingReques userID = this.bookingRequest.getUserId(); totalCost = this.bookingRequest.getTotalCost(); currentWaiting = Math.max(0, -bookingRequest.getAvailableSeat()); - System.out.println(currentWaiting); - } - - /** - * This is the first function that is called inside the request identifier. In this function, we form the relevant - * sql queries and pass it to another function to execute. - */ - @Override - public void sendQuery() { - numSeats = bookingRequest.getNumSeat(); - availableSeats = bookingRequest.getAvailableSeat(); // Station which are in the route. switch (coach) { case "Sleeper": @@ -62,6 +54,17 @@ public void sendQuery() { coachCode = "A3"; break; } + System.out.println(currentWaiting); + } + + /** + * This is the first function that is called inside the request identifier. In this function, we form the relevant + * sql queries and pass it to another function to execute. + */ + @Override + public void sendQuery() { + numSeats = bookingRequest.getNumSeat(); + availableSeats = bookingRequest.getAvailableSeat(); // Select stations on that the journey takes from the specified Source and Destination. // TODO Can be made more efficient. @@ -93,8 +96,8 @@ public void sendQuery() { * This is where the statements are executed. * @return Response to the booking request. */ - private BookingResponse bookSeats(String query1, String query2, String query3, String query4, String query5, - String query6, String query7) { + private @Nullable BookingResponse bookSeats(String query1, String query2, String query3, String query4, String query5, + String query6, String query7) { try { PreparedStatement stations = connection.prepareStatement(query1); stations.setString(1, trainID); @@ -106,7 +109,9 @@ private BookingResponse bookSeats(String query1, String query2, String query3, S while(route.next()) { if(sourceStationNumber == -1) sourceStationNumber = route.getInt("Station_No"); - stationsOnRoute.add(route.getString("Station")); + @SuppressWarnings("assignment.type.incompatible") // Station cannot be null. Refer the README. + @NonNull String s = route.getString("Station"); + stationsOnRoute.add(s); query2 = query2 + "?, "; } query2 = query2.substring(0, query2.length()-2) + ");"; @@ -125,12 +130,14 @@ private BookingResponse bookSeats(String query1, String query2, String query3, S coachArrangement.next(); numCoaches = coachArrangement.getInt(coach + "_Coaches"); seatsPerCoach = coachArrangement.getInt(coach + "_Seats"); - notVacant = new boolean[numCoaches*seatsPerCoach + 5]; + initVacantArray(); while(occupiedSeats.next()) { int coachNumber = 0, seat = 0; try { - coachNumber = Integer.parseInt(String.valueOf(occupiedSeats.getString("Seat_No").charAt(2))); - seat = Integer.parseInt(occupiedSeats.getString("Seat_No").substring(3)); + @SuppressWarnings("assignment.type.incompatible") // Seat_No cannot be null. Refer the README. + @NonNull String s = occupiedSeats.getString("Seat_No"); + coachNumber = Integer.parseInt(String.valueOf(s.charAt(2))); + seat = Integer.parseInt(s.substring(3)); System.out.println(coachNumber + " " + seat); } catch (NumberFormatException e) { notVacant[0] = true; @@ -203,12 +210,18 @@ private BookingResponse bookSeats(String query1, String query2, String query3, S return null; } + @EnsuresNonNull("notVacant") + private void initVacantArray() { + notVacant = new boolean[numCoaches*seatsPerCoach + 5]; + } + int p = 0; /** * Seat distribution logic. Seats are alloted on the basis of age and preference. * @return Response to the booking request. */ + @RequiresNonNull("notVacant") private BookingResponse allot() { int[] age = bookingRequest.getAge(); @@ -349,6 +362,7 @@ private BookingResponse allot() { * @param b 1 or 2, implies which type of seat is checked first. * @return Seat number which was alloted. The number is of the format coach + coachNo + seatNo for eg, SL101. */ + @RequiresNonNull("notVacant") private String allot2(int a, int b) { // 4 seats // 1 2 3 4. odd is lower. even is upper. @@ -375,6 +389,7 @@ private String allot2(int a, int b) { * @params Order of checking the seat vacancy. * @return Alloted seat number. */ + @RequiresNonNull("notVacant") private String allot6(int a, int b, int c, int d, int e, int f) { // 6 seats. // 1 and 5 are lower. 2 and 6 are upper. 3 is side lower. 4 is side upper. @@ -404,6 +419,7 @@ private String allot6(int a, int b, int c, int d, int e, int f) { * @params Order of checking the seat vacancy. * @return Alloted seat number. */ + @RequiresNonNull("notVacant") private String allot8(int a, int b, int c, int d, int e, int f, int g, int h) { // 8 seats in a compartment. // 1 and 6 are lower. 2 and 8 are upper.5 and 7 are middle. 3 is side lower. 4 is side upper. @@ -435,6 +451,7 @@ private String allot8(int a, int b, int c, int d, int e, int f, int g, int h) { * Allot nearby seats to female passengers if they are travelling alone. * @return Response to the booking request. */ + @RequiresNonNull("notVacant") private BookingResponse allotSingleFemale() { // We will give them what they want, starting from the back of the coach. String[] bookingID = new String[1], seat = new String[1]; diff --git a/LockdownTravellerServer/src/CancelBookingRequestHandler.java b/LockdownTravellerServer/src/CancelBookingRequestHandler.java index 51d178f..6a5cf4b 100644 --- a/LockdownTravellerServer/src/CancelBookingRequestHandler.java +++ b/LockdownTravellerServer/src/CancelBookingRequestHandler.java @@ -1,3 +1,7 @@ +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.io.ObjectOutputStream; import java.sql.Connection; import java.sql.PreparedStatement; @@ -57,9 +61,9 @@ void sendQuery() { * @params Queries. * @return Reponse object. */ - private CancelBookingResponse CancelBooking(String query1, String query2, String query3, String query4, String query5, String query6) { + private @Nullable CancelBookingResponse CancelBooking(String query1, String query2, String query3, String query4, String query5, String query6) { - String seatType, trainID, date, query7; + @MonotonicNonNull String seatType, trainID, date, query7; int numCoaches, seatsPerCoach; boolean[] notVacant; @@ -70,9 +74,17 @@ private CancelBookingResponse CancelBooking(String query1, String query2, String ResultSet pnrDetail = getCancelledBooking.executeQuery(); if(pnrDetail.next()) { - seatType = pnrDetail.getString("Seat_No").substring(0, 2); - trainID = pnrDetail.getString("Train_ID"); - date = pnrDetail.getString("Date"); + @SuppressWarnings("assignment.type.incompatible") // Seat_No cannot be null. Refer the README. + @NonNull String s = pnrDetail.getString("Seat_No"); + seatType = s.substring(0, 2); + + @SuppressWarnings("assignment.type.incompatible") // Train_ID cannot be null. Refer the README. + @NonNull String pTrainID = pnrDetail.getString("Train_ID"); + trainID = pTrainID; + + @SuppressWarnings("assignment.type.incompatible") // Date cannot be null. Refer the README. + @NonNull String pDate = pnrDetail.getString("Date"); + date = pDate; query7 = "select " + coach(seatType) + "_Coaches, " + coach(seatType) + "_Seats from " + "Basic_Train_Info where Train_ID = ?"; PreparedStatement changeStatus = connection.prepareStatement(query2); @@ -118,8 +130,10 @@ private CancelBookingResponse CancelBooking(String query1, String query2, String while(occupied.next()) { int coachNumber = 0, seat = 0; try { - coachNumber = Integer.parseInt(String.valueOf(occupied.getString("Seat_No").charAt(2))); - seat = Integer.parseInt(occupied.getString("Seat_No").substring(3)); + @SuppressWarnings("assignment.type.incompatible") // Seat_No cannot be null. Refer the README. + @NonNull String s = occupied.getString("Seat_No"); + coachNumber = Integer.parseInt(String.valueOf(s.charAt(2))); + seat = Integer.parseInt(s.substring(3)); System.out.println(coachNumber + " " + seat); } catch (NumberFormatException e) { notVacant[0] = true; diff --git a/LockdownTravellerServer/src/DisplayTrainsRequestHandler.java b/LockdownTravellerServer/src/DisplayTrainsRequestHandler.java index c2031cd..019c319 100644 --- a/LockdownTravellerServer/src/DisplayTrainsRequestHandler.java +++ b/LockdownTravellerServer/src/DisplayTrainsRequestHandler.java @@ -1,3 +1,7 @@ +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.io.ObjectOutputStream; import java.sql.Connection; import java.sql.PreparedStatement; @@ -9,6 +13,7 @@ import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.ArrayList; +import java.util.Objects; public class DisplayTrainsRequestHandler extends Handler { @@ -95,43 +100,28 @@ private static int DayToDate(String sDate) { * @param dest Destination. * @return The response to the request. */ - private DisplayTrainsResponse DisplayTrains(String query1, String query2, String query3, String query4, String query5, String query6, String query7,String query8, String sDate, String source, String dest) { + private @Nullable DisplayTrainsResponse DisplayTrains(String query1, String query2, String query3, String query4, String query5, String query6, String query7,String query8, String sDate, String source, String dest) { char[] Days_Running = null; - ResultSet result = null; + @MonotonicNonNull ResultSet result = null; int required_day = DisplayTrainsRequestHandler.DayToDate(sDate); PreparedStatement preparedStatement; try { - assert null != connection; preparedStatement = connection.prepareStatement(query1, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); preparedStatement.setString(1,source); preparedStatement.setString(2,dest); System.out.println(preparedStatement.toString()); result = preparedStatement.executeQuery(); - } catch (SQLException e) { - e.printStackTrace(); - } - ArrayList Train_ID = new ArrayList<>(), Train_Name = new ArrayList<>(), Departure = new ArrayList<>(), Arrival = new ArrayList<>(), First_AC = new ArrayList<>(), Second_AC = new ArrayList<>(), Third_AC = new ArrayList<>(), Sleeper = new ArrayList<>(); int i = 0; ArrayListAC3Fare=new ArrayList<>(),AC2Fare=new ArrayList<>(),AC1Fare=new ArrayList<>(),SLFare=new ArrayList<>(); while (true) { - try { - assert result != null; - if (!result.next()) break; - } catch (SQLException e) { - e.printStackTrace(); - } - - String Day_No = null; - try { - Day_No = result.getString("Day_No"); - Days_Running = result.getString("Days_Running").toCharArray(); - } catch (SQLException e) { - e.printStackTrace(); - } - assert Days_Running != null; - assert Day_No != null; + if (!result.next()) + break; + @SuppressWarnings("assignment.type.incompatible") // Day_No cannot be null. Refer the README. + @NonNull String Day_No = result.getString("Day_No"), + s = result.getString("Days_Running"); + Days_Running = s.toCharArray(); char value = Days_Running[required_day - Integer.parseInt(Day_No)]; if (value == '1') { try { @@ -144,20 +134,22 @@ private DisplayTrainsResponse DisplayTrains(String query1, String query2, String SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); try { java.util.Date date = sdf.parse(sDate); - if (resultSet1.getString("Added_Till") != null) { - java.util.Date date1 = sdf.parse(resultSet1.getString("Added_Till")); + @Nullable String addedTill = resultSet1.getString("Added_Till"), + cancelledTill = resultSet1.getString("Cancelled_Till"); + if (addedTill != null) { + java.util.Date date1 = sdf.parse(addedTill); compare1 = date.compareTo(date1); if (compare1 < 0) { - if (resultSet1.getString("Cancelled_Till") != null) { - java.util.Date date2 = sdf.parse(resultSet1.getString("Cancelled_Till")); + if (cancelledTill != null) { + java.util.Date date2 = sdf.parse(cancelledTill); compare2 = date.compareTo(date2); if (compare2 > 0) { counter = 1; } } else counter = 1; } - } else if (resultSet1.getString("Cancelled_Till") != null) { - java.util.Date date2 = sdf.parse(resultSet1.getString("Cancelled_Till")); + } else if (cancelledTill != null) { + java.util.Date date2 = sdf.parse(cancelledTill); compare2 = date.compareTo(date2); if (compare2 > 0) { counter = 1; @@ -167,12 +159,23 @@ private DisplayTrainsResponse DisplayTrains(String query1, String query2, String e.printStackTrace(); } if (counter == 1) { + @SuppressWarnings("assignment.type.incompatible") // Train_ID cannot be null. Refer the README. + @NonNull String trainID = result.getString("Train_ID"), + trainName = result.getString("Train_Name"); + Train_ID.add(trainID); + Train_Name.add(trainName); + @Nullable String time = result.getString("Departure"); + if(time != null) + Departure.add(time); + else + Departure.add("End"); - Train_ID.add(result.getString("Train_ID")); - Train_Name.add(result.getString("Train_Name")); - Departure.add(result.getString("Departure")); - Arrival.add(result.getString("Arrival")); + time = result.getString("Arrival"); + if(time != null) + Arrival.add(time); + else + Arrival.add("Start"); preparedStatement = connection.prepareStatement(query2); preparedStatement.setString(1, Train_ID.get(i)); @@ -201,16 +204,29 @@ private DisplayTrainsResponse DisplayTrains(String query1, String query2, String ResultSet SL_Seats = preparedStatement.executeQuery(); resultSet.next(); SL_Seats.next(); - int available_seats ; - if (resultSet.getString("Sleeper_Seats") != null) { - available_seats = Integer.parseInt(resultSet.getString("Sleeper_Seats")) - Integer.parseInt(SL_Seats.getString(1)); - Sleeper.add(String.valueOf(available_seats * Integer.parseInt(resultSet.getString("Sleeper_Coaches")))); + int available_seats = 0; + @Nullable String number = resultSet.getString("Sleeper_Seats"); + if (number != null) { + @SuppressWarnings("assignment.type.incompatible") // If number of seats is not null, + // number of coaches will not be null either. + @NonNull String coaches = resultSet.getString("Sleeper_Coaches"); + + @Nullable String occupiedCount = SL_Seats.getString(1); + available_seats = Integer.parseInt(number) - Integer.parseInt( + (occupiedCount == null)? "0" : occupiedCount); + Sleeper.add(String.valueOf(available_seats * Integer.parseInt(coaches))); } else Sleeper.add("N/A"); if(resultSet.getString(9)!=null) { - if(result.getString("Train_ID").equals("22209")&&resultSet.getString("FirstAC_Seats") != null)//dynamic pricing for garib rath train + if(Objects.equals(result.getString("Train_ID"), "22209") && + resultSet.getString("FirstAC_Seats") != null)//dynamic pricing for garib rath train { - float percentageBooked=Float.parseFloat(SL_Seats.getString(1))/(Float.parseFloat(resultSet.getString("Sleeper_Seats"))*Float.parseFloat(resultSet.getString("Sleeper_Coaches"))); + @Nullable String coaches = resultSet.getString("Sleeper_Coaches"); + + @Nullable String occupiedCount = SL_Seats.getString(1); + float percentageBooked=Float.parseFloat((occupiedCount != null)? occupiedCount : + "0")/(Float.parseFloat(number != null ? number : "9999999") * + Float.parseFloat(coaches != null ? coaches : "9999999")); SLFare.add((int) (resultSet.getInt(9)*distance*(1+percentageBooked))); } SLFare.add(resultSet.getInt(9)*distance); @@ -227,15 +243,23 @@ private DisplayTrainsResponse DisplayTrains(String query1, String query2, String preparedStatement.setString(7, sDate); ResultSet AC1_Seats = preparedStatement.executeQuery(); AC1_Seats.next(); - if (resultSet.getString("FirstAC_Seats") != null) { - available_seats = Integer.parseInt(resultSet.getString("FirstAC_Seats")) - Integer.parseInt(AC1_Seats.getString(1)); - First_AC.add(String.valueOf(available_seats * Integer.parseInt(resultSet.getString("FirstAC_Coaches")))); + number = resultSet.getString("FirstAC_Seats"); + if (number != null) { + @SuppressWarnings("assignment.type.incompatible") // If number of seats is not null, + // number of coaches will be non null too. + @NonNull String coach = resultSet.getString("FirstAC_Coaches"); + @Nullable String occupiedCount = AC1_Seats.getString(1); + available_seats = Integer.parseInt(number) - Integer.parseInt(occupiedCount != null ? occupiedCount : "0"); + First_AC.add(String.valueOf(available_seats * Integer.parseInt(coach))); } else First_AC.add("N/A"); if(resultSet.getString(10)!=null) { - if(result.getString("Train_ID").equals("22209")&&resultSet.getString("FirstAC_Seats") != null)//dynamic pricing for garib rath train + if(Objects.equals(result.getString("Train_ID"), "22209") &&resultSet.getString("FirstAC_Seats") != null)//dynamic pricing for garib rath train { - float percentageBooked=Float.parseFloat(AC1_Seats.getString(1))/(Float.parseFloat(resultSet.getString("FirstAC_Seats"))*Float.parseFloat(resultSet.getString("FirstAC_Coaches"))); + @Nullable String occupiedCount = AC1_Seats.getString(1); + @Nullable String coaches = resultSet.getString("FirstAC_Coaches"); + float percentageBooked=Float.parseFloat(occupiedCount != null ? occupiedCount : "0")/ + (Float.parseFloat(number != null ? number : "99999")*Float.parseFloat(coaches != null ? coaches : "99999")); AC1Fare.add((int) (resultSet.getInt(10)*distance*(1+percentageBooked))); } else AC1Fare.add(resultSet.getInt(10)*distance); @@ -252,15 +276,23 @@ private DisplayTrainsResponse DisplayTrains(String query1, String query2, String preparedStatement.setString(7, sDate); ResultSet AC2_Seats = preparedStatement.executeQuery(); AC2_Seats.next(); - if (resultSet.getString("SecondAC_Seats") != null) { - available_seats = Integer.parseInt(resultSet.getString("SecondAC_Seats")) - Integer.parseInt(AC2_Seats.getString(1)); - Second_AC.add(String.valueOf(available_seats * Integer.parseInt(resultSet.getString("SecondAC_Coaches")))); + number = resultSet.getString("SecondAC_Seats"); + if (number != null) { + @SuppressWarnings("assignment.type.incompatible") // If number of seats is not null, number + // of coaches will not be null either. + @NonNull String coach = resultSet.getString("SecondAC_Coaches"); + @Nullable String occupiedCount = AC2_Seats.getString(1); + available_seats = Integer.parseInt(number) - Integer.parseInt(occupiedCount != null ? occupiedCount : "0"); + Second_AC.add(String.valueOf(available_seats * Integer.parseInt(coach))); } else Second_AC.add("N/A"); if(resultSet.getString(11)!=null) { - if(result.getString("Train_ID").equals("22209")&&resultSet.getString("SecondAC_Seats") != null)//dynamic pricing for garib rath train + if(Objects.equals(result.getString("Train_ID"), "22209") &&resultSet.getString("SecondAC_Seats") != null)//dynamic pricing for garib rath train { - float percentageBooked=Float.parseFloat(AC2_Seats.getString(1))/(Float.parseFloat(resultSet.getString("SecondAC_Seats"))*Float.parseFloat(resultSet.getString("SecondAC_Coaches"))); + @Nullable String coach = resultSet.getString("SecondAC_Coaches"); + @Nullable String occupiedCount = AC2_Seats.getString(1); + float percentageBooked=Float.parseFloat(occupiedCount != null ? occupiedCount : "0") + /(Float.parseFloat(number != null ? number : "99999")*Float.parseFloat(coach != null ? coach : "99999")); AC2Fare.add((int) (resultSet.getInt(11)*distance*(1+percentageBooked))); } else AC2Fare.add(resultSet.getInt(11)*distance); @@ -277,15 +309,24 @@ private DisplayTrainsResponse DisplayTrains(String query1, String query2, String preparedStatement.setString(7, sDate); ResultSet AC3_Seats = preparedStatement.executeQuery(); AC3_Seats.next(); - if (resultSet.getString("ThirdAC_Seats") != null) { - available_seats = Integer.parseInt(resultSet.getString("ThirdAC_Seats")) - Integer.parseInt(AC3_Seats.getString(1)); - Third_AC.add(String.valueOf(available_seats * Integer.parseInt(resultSet.getString("ThirdAC_Coaches")))); + number = resultSet.getString("ThirdAC_Seats"); + if (number != null) { + @SuppressWarnings("assignment.type.incompatible") // If number of seats is not null, number + // of coaches will not be null either. + @NonNull String coach = resultSet.getString("ThirdAC_Coaches"); + @Nullable String occupiedCount = AC3_Seats.getString(1); + available_seats = Integer.parseInt(number) - Integer.parseInt(occupiedCount != null ? occupiedCount : "0"); + Third_AC.add(String.valueOf(available_seats * Integer.parseInt(coach))); } else Third_AC.add("N/A"); if(resultSet.getString(12)!=null) { - if(result.getString("Train_ID").equals("22209")&&resultSet.getString("ThirdAC_Seats") != null)//dynamic pricing for garib rath train + if(Objects.equals(result.getString("Train_ID"), "22209") &&resultSet.getString("ThirdAC_Seats") != null)//dynamic pricing for garib rath train { - float percentageBooked=Float.parseFloat(AC3_Seats.getString(1))/(Float.parseFloat(resultSet.getString("ThirdAC_Seats"))*Float.parseFloat(resultSet.getString("ThirdAC_Coaches"))); + @Nullable String coach = resultSet.getString("ThirdAC_Coaches"); + @Nullable String occupiedCount = AC3_Seats.getString(1); + float percentageBooked=Float.parseFloat(occupiedCount != null ? occupiedCount : + "0")/(Float.parseFloat(number != null ? number : "99999")* + Float.parseFloat(coach != null ? coach : "99999")); AC3Fare.add((int) (resultSet.getInt(12)*distance*(1+percentageBooked))); } else AC3Fare.add(resultSet.getInt(12)*distance); @@ -300,5 +341,9 @@ private DisplayTrainsResponse DisplayTrains(String query1, String query2, String } } return new DisplayTrainsResponse(Train_ID,Train_Name,Departure,Arrival,First_AC,Second_AC,Third_AC,Sleeper,sDate,source,dest,AC1Fare,AC2Fare,AC3Fare,SLFare); + } catch (SQLException e) { + e.printStackTrace(); + } + return null; } } \ No newline at end of file diff --git a/LockdownTravellerServer/src/LoginRequestHandler.java b/LockdownTravellerServer/src/LoginRequestHandler.java index 4266d0e..2dc0ea5 100644 --- a/LockdownTravellerServer/src/LoginRequestHandler.java +++ b/LockdownTravellerServer/src/LoginRequestHandler.java @@ -1,3 +1,6 @@ +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.io.ObjectOutputStream; import java.sql.Connection; import java.sql.PreparedStatement; @@ -33,7 +36,7 @@ public void sendQuery() { * @param query Query to get the details for the credentials. * @return The response to the request. */ - private LoginResponse loginRequest(String query) { + private @Nullable LoginResponse loginRequest(String query) { try { PreparedStatement loginQuery = connection.prepareStatement(query); loginQuery.setString(1, loginRequest.getUsername()); @@ -41,12 +44,17 @@ private LoginResponse loginRequest(String query) { ResultSet loginResult = loginQuery.executeQuery(); // If the result set is empty, this implies the credentials are wrong. if (!loginResult.next()) { - return new LoginResponse(null, null, null, null, null); + return null; // This change causes the clients program to crash on an unsuccessful login attempt due to + // a null pointer exception but seems like a reasonable change. The client side crash can be fixed + // trivially. } else { - return new LoginResponse(loginResult.getString("User_ID"), - loginResult.getString("First_Name") + " " + loginResult.getString("Last_Name"), - loginResult.getString("Username"), loginResult.getString("Email_ID"), - loginResult.getString("Phone_No")); + @SuppressWarnings("assignment.type.incompatible") // No column in User table can have null values. + @NonNull String userId = loginResult.getString("User_ID"), + name = loginResult.getString("First_Name") + " " + loginResult.getString("Last_Name"), + username = loginResult.getString("Username"), + email = loginResult.getString("Email_ID"), + phone = loginResult.getString("Phone_No"); + return new LoginResponse(userId, name, username, email, phone); } } catch (SQLException throwables) { throwables.printStackTrace(); diff --git a/LockdownTravellerServer/src/MaintainCustomerRequestHandler.java b/LockdownTravellerServer/src/MaintainCustomerRequestHandler.java index eba40d7..f5224b0 100644 --- a/LockdownTravellerServer/src/MaintainCustomerRequestHandler.java +++ b/LockdownTravellerServer/src/MaintainCustomerRequestHandler.java @@ -1,3 +1,6 @@ +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.io.ObjectOutputStream; import java.sql.Connection; import java.sql.PreparedStatement; @@ -42,21 +45,23 @@ public void sendQuery() { * @param query Query to get all user info. * @return Response to maintain customer request. */ - private MaintainCustomerResponse maintainCustomerRequest(String query) { + private @Nullable MaintainCustomerResponse maintainCustomerRequest(String query) { ArrayList customers = new ArrayList<>(); try { PreparedStatement customerQuery = connection.prepareStatement(query); ResultSet customerInfo = customerQuery.executeQuery(); while(customerInfo.next()) { + @SuppressWarnings("assignment.type.incompatible") // these columns cannot be null in the table. + @NonNull String name = customerInfo.getString("First_Name") + " " + + customerInfo.getString("Last_Name"), + gender = customerInfo.getString("Gender"), + email = customerInfo.getString("Email_ID"), + phone = customerInfo.getString("Phone_No"), + username = customerInfo.getString("Username"), + userId = customerInfo.getString("User_ID"); + customers.add(new Customer( - customerInfo.getString("First_Name") + " " + customerInfo.getString("Last_Name"), - customerInfo.getString("Gender"), - customerInfo.getString("Email_ID"), - customerInfo.getString("Phone_No"), - customerInfo.getString("Username"), - customerInfo.getString("User_ID"), - customerInfo.getInt("Age") - )); + name, gender, email, phone, username, userId, customerInfo.getInt("Age"))); } } catch (SQLException throwables) { throwables.printStackTrace(); diff --git a/LockdownTravellerServer/src/MaintainSeatsRequestHandler.java b/LockdownTravellerServer/src/MaintainSeatsRequestHandler.java index 5ddc5a0..0403f3f 100644 --- a/LockdownTravellerServer/src/MaintainSeatsRequestHandler.java +++ b/LockdownTravellerServer/src/MaintainSeatsRequestHandler.java @@ -1,3 +1,6 @@ +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.io.ObjectOutputStream; import java.sql.Connection; import java.sql.PreparedStatement; @@ -40,7 +43,7 @@ public void sendQuery() { * @param query Query to get all the information. * @return Response to the maitatin seats request. */ - private MaintainSeatsResponse maintainSeatsRequest(String query) { + private @Nullable MaintainSeatsResponse maintainSeatsRequest(String query) { try { PreparedStatement seatInquiry = connection.prepareStatement(query); ResultSet seatInformation = seatInquiry.executeQuery(); @@ -51,8 +54,10 @@ private MaintainSeatsResponse maintainSeatsRequest(String query) { coaches.add(new Coach("First AC", seatInformation.getInt("FirstAC_Coaches"), seatInformation.getInt("FirstAC_Seats"))); coaches.add(new Coach("Second AC", seatInformation.getInt("SecondAC_Coaches"), seatInformation.getInt("SecondAC_Seats"))); coaches.add(new Coach("Third AC", seatInformation.getInt("ThirdAC_Coaches"), seatInformation.getInt("ThirdAC_Seats"))); - - trains.add(new Train2(seatInformation.getString("Train_ID"), seatInformation.getString("Train_Name"), coaches)); + @SuppressWarnings("assignment.type.incompatible") // Train_ID cannot be null. Refer the README. + @NonNull String trainId = seatInformation.getString("Train_ID"), + trainName = seatInformation.getString("Train_Name"); + trains.add(new Train2(trainId, trainName, coaches)); } return new MaintainSeatsResponse(trains); } catch (SQLException throwables) { diff --git a/LockdownTravellerServer/src/MaintainTrainsRequestHandler.java b/LockdownTravellerServer/src/MaintainTrainsRequestHandler.java index e863178..9a0b1cc 100644 --- a/LockdownTravellerServer/src/MaintainTrainsRequestHandler.java +++ b/LockdownTravellerServer/src/MaintainTrainsRequestHandler.java @@ -1,3 +1,6 @@ +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.io.ObjectOutputStream; import java.sql.Connection; import java.sql.PreparedStatement; @@ -22,14 +25,11 @@ public void sendQuery() { MaintainTrainsResponse maintainTrainsResponse = maintainTrainsRequest(query1, query2); Server.SendResponse(oos, maintainTrainsResponse); } - private MaintainTrainsResponse maintainTrainsRequest(String query1, String query2) { + private @Nullable MaintainTrainsResponse maintainTrainsRequest(String query1, String query2) { try { PreparedStatement basicInfoQuery = connection.prepareStatement(query1); ResultSet basicTrainInfo = basicInfoQuery.executeQuery(); ArrayList trains = new ArrayList<>(); - String trainId; - String trainName; - String days; ArrayList route; ArrayList arrival; ArrayList departure; @@ -41,9 +41,10 @@ private MaintainTrainsResponse maintainTrainsRequest(String query1, String query PreparedStatement routeQuery = connection.prepareStatement(query2); routeQuery.setString(1, basicTrainInfo.getString("Train_ID")); - trainId=(basicTrainInfo.getString("Train_ID")); - trainName=(basicTrainInfo.getString("Train_Name")); - days=(basicTrainInfo.getString("Days_Running")); + @SuppressWarnings("assignment.type.incompatible") // Train_ID, Train_Name, Days_Running cannot be null. Refer the README. + @NonNull String trainId = basicTrainInfo.getString("Train_ID"), + trainName = basicTrainInfo.getString("Train_Name"), + days = basicTrainInfo.getString("Days_Running"); ResultSet routeInfo = routeQuery.executeQuery(); route = (new ArrayList<>()); @@ -52,9 +53,13 @@ private MaintainTrainsResponse maintainTrainsRequest(String query1, String query day = new ArrayList<>(); stationNumber = new ArrayList<>(); while(routeInfo.next()) { - route.add(routeInfo.getString("Station")); - arrival.add(routeInfo.getString("Arrival")); - departure.add(routeInfo.getString("Departure")); + @SuppressWarnings("assignment.type.incompatible") // Station cannot be null. Refer the README. + @NonNull String pRoute = routeInfo.getString("Station"); + @Nullable String pArrival = routeInfo.getString("Arrival"), + pDeparture = routeInfo.getString("Departure"); + route.add(pRoute); + arrival.add(pArrival != null ? pArrival : "Start"); + departure.add(pDeparture != null ? pDeparture : "End"); day.add(routeInfo.getInt("Day_No")); stationNumber.add(routeInfo.getInt("Station_No")); } diff --git a/LockdownTravellerServer/src/NotificationRequestHandler.java b/LockdownTravellerServer/src/NotificationRequestHandler.java index 7d474c4..c4c2ad3 100644 --- a/LockdownTravellerServer/src/NotificationRequestHandler.java +++ b/LockdownTravellerServer/src/NotificationRequestHandler.java @@ -1,3 +1,6 @@ +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; +import org.checkerframework.checker.nullness.qual.NonNull; + import java.io.IOException; import java.io.ObjectOutputStream; import java.sql.Connection; @@ -26,8 +29,8 @@ void sendQuery() { } public NotificationResponse notification(String query1,String query2,NotificationRequest notificationRequest) { - PreparedStatement preparedStatement= null; - ResultSet resultSet=null; + @MonotonicNonNull PreparedStatement preparedStatement ; + @MonotonicNonNull ResultSet resultSet; ArrayListmessage = new ArrayList<>(); ArrayList pendingStatus = new ArrayList<>(); @@ -40,8 +43,9 @@ public NotificationResponse notification(String query1,String query2,Notificatio preparedStatement.executeUpdate(); while (resultSet.next()) { - assert message != null; - message.add(resultSet.getString(1)); + @SuppressWarnings("assignment.type.incompatible") // Message cannot be null. Refer the README. + @NonNull String s = resultSet.getString(1); + message.add(s); pendingStatus.add(resultSet.getInt("Pending_Status")); } } catch (SQLException e) { diff --git a/LockdownTravellerServer/src/RequestIdentifier.java b/LockdownTravellerServer/src/RequestIdentifier.java index e74581d..38a2ef2 100644 --- a/LockdownTravellerServer/src/RequestIdentifier.java +++ b/LockdownTravellerServer/src/RequestIdentifier.java @@ -1,4 +1,6 @@ +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; + import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; @@ -27,16 +29,16 @@ public RequestIdentifier(Socket socket) { @Override public void run() { - ObjectInputStream ois = null; - ObjectOutputStream oos = null; + @MonotonicNonNull ObjectInputStream ois = null; + @MonotonicNonNull ObjectOutputStream oos = null; try { oos = new ObjectOutputStream(socket.getOutputStream()); ois = new ObjectInputStream(socket.getInputStream()); } catch (IOException e) { e.printStackTrace(); + return; } while (socket.isConnected()) { - assert ois != null; Object request = Server.ReceiveRequest(ois); if (request == null) break; diff --git a/LockdownTravellerServer/src/Server.java b/LockdownTravellerServer/src/Server.java index 679a959..2f53ad4 100644 --- a/LockdownTravellerServer/src/Server.java +++ b/LockdownTravellerServer/src/Server.java @@ -1,3 +1,5 @@ +import org.checkerframework.checker.nullness.qual.*; + import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; @@ -13,18 +15,21 @@ */ public class Server { - private static Connection connection; + // static with monotonic non null! TODO Make Connection non static somehow. + private static @MonotonicNonNull Connection connection; public static void main(String[] args) { - ServerSocket serverSocket = null; - Socket socket; + @MonotonicNonNull ServerSocket serverSocket = null; + @MonotonicNonNull Socket socket; try { serverSocket = new ServerSocket(12000); } catch (IOException e) { e.printStackTrace(); + return; } + getConnection(); // Infinite loop. After a client connects to the server, the server client interaction is assigned a thread and // the server loops back to the serverSocket.accept() line to listen for other connection attempts. while (true) { @@ -48,18 +53,21 @@ public static void main(String[] args) { * Connects the server side to the database to make queries. * @return Connection to the database. */ - public static Connection getConnection() { - if (connection != null) { + @SuppressWarnings("return.type.incompatible") // Null can only be returned when the lines in the try block + // throw some exception. Since these are hard coded, there is no need to worry about the connection object being + // null. + public static @NonNull Connection getConnection() { + if(connection != null) return connection; - } try { Class.forName("com.mysql.cj.jdbc.Driver"); String url = "jdbc:mysql://127.0.0.1:3306/lockdown_traveller"; connection = DriverManager.getConnection(url, "utkarsh", "Hello@123"); + return connection; } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); + return null; } - return connection; } /** @@ -67,7 +75,7 @@ public static Connection getConnection() { * @param oos Reference to the output stream of the thread that called the function. * @param response The object to be sent via tha output stream. */ - public static void SendResponse(ObjectOutputStream oos, Response response) { + public static void SendResponse(ObjectOutputStream oos, @Nullable Response response) { try { System.out.println("Sending the object now " + response); if (response == null) @@ -86,7 +94,7 @@ public static void SendResponse(ObjectOutputStream oos, Response response) { * @param objectInputStream The input stream in the thread. * @return The object read from the input stream. */ - public static Object ReceiveRequest(ObjectInputStream objectInputStream) + public static @Nullable Object ReceiveRequest(ObjectInputStream objectInputStream) { try { return objectInputStream.readObject();