diff --git a/build.gradle.kts b/build.gradle.kts index 300b4f8..cfdecc4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,7 +7,7 @@ plugins { group = "igs-landstuhl" -version = "v1.1.0-SNAPSHOT-0" +version = "v2.0.0-SNAPSHOT-0" application { mainClass.set("de.igslandstuhl.database.Application") diff --git a/src/main/java/de/igslandstuhl/database/Application.java b/src/main/java/de/igslandstuhl/database/Application.java index d84ca56..19cd206 100644 --- a/src/main/java/de/igslandstuhl/database/Application.java +++ b/src/main/java/de/igslandstuhl/database/Application.java @@ -17,6 +17,7 @@ import de.igslandstuhl.database.server.webserver.WebPath; import de.igslandstuhl.database.server.webserver.handlers.GetRequestHandler; import de.igslandstuhl.database.server.webserver.handlers.PostRequestHandler; +import de.igslandstuhl.database.server.webserver.handlers.get.SQLRequestHandler; import de.igslandstuhl.database.utils.CommandLineUtils; /** @@ -110,6 +111,7 @@ public static void main(String[] args) throws Exception { Holiday.setupCurrentSchoolYear(); PostRequestHandler.registerHandlers(); + SQLRequestHandler.register(); PluginLoader.getInstance().registerPlugins(); WebPath.registerPaths(); diff --git a/src/main/java/de/igslandstuhl/database/Registry.java b/src/main/java/de/igslandstuhl/database/Registry.java index 6e756e2..e0604f0 100644 --- a/src/main/java/de/igslandstuhl/database/Registry.java +++ b/src/main/java/de/igslandstuhl/database/Registry.java @@ -8,6 +8,7 @@ import java.util.stream.Stream; import de.igslandstuhl.database.client.HTMLTemplate; +import de.igslandstuhl.database.client.dynamic.DynamicFieldType; import de.igslandstuhl.database.client.navigation.NavigationElement; import de.igslandstuhl.database.client.navigation.NavigationType; import de.igslandstuhl.database.plugins.Plugin; @@ -15,6 +16,7 @@ import de.igslandstuhl.database.server.commands.CommandDescription; import de.igslandstuhl.database.server.webserver.WebPath; import de.igslandstuhl.database.server.webserver.handlers.HttpHandler; +import de.igslandstuhl.database.server.webserver.handlers.get.SQLRequestHandler; import de.igslandstuhl.database.server.webserver.requests.APIPostRequest; import de.igslandstuhl.database.server.webserver.requests.GetRequest; import de.igslandstuhl.database.utils.RegistryEnum; @@ -24,10 +26,12 @@ public class Registry implements Closeable { private static final Registry COMMAND_DESCRIPTION_REGISTRY = new Registry<>(); private static final Registry> POST_HANDLER_REGISTRY = new Registry<>(); private static final Registry> GET_HANDLER_REGISTRY = new Registry<>(); + private static final Registry SQL_REQUEST_HANDLER_REGISTRY = new Registry<>(); private static final Registry PLUGIN_REGISTRY = new Registry<>(); private static final Registry WEB_PATH_REGISTRY = new Registry<>(); private static final EnumRegistry NAVIGATION_REGISTRY = new EnumRegistry<>(NavigationType.class); + private static final EnumRegistry DYNAMIC_TEMPLATES_REGISTRY = new EnumRegistry<>(DynamicFieldType.class); private static final Registry TEMPLATE_REGISTRY = new Registry<>(); public static Registry commandRegistry() { @@ -39,6 +43,9 @@ public static Registry> postRequestHandlerRe public static Registry> getRequestHandlerRegistry() { return GET_HANDLER_REGISTRY; } + public static Registry sqlRequestHandlerRegistry() { + return SQL_REQUEST_HANDLER_REGISTRY; + } public static Registry pluginRegistry() { return PLUGIN_REGISTRY; } @@ -51,6 +58,9 @@ public static Registry webPathRegistry() { public static EnumRegistry navigationRegistry() { return NAVIGATION_REGISTRY; } + public static EnumRegistry dynamicTemplatesRegistry() { + return DYNAMIC_TEMPLATES_REGISTRY; + } public static Registry templateRegistry() { return TEMPLATE_REGISTRY; } diff --git a/src/main/java/de/igslandstuhl/database/api/Room.java b/src/main/java/de/igslandstuhl/database/api/Room.java deleted file mode 100644 index 9919a6c..0000000 --- a/src/main/java/de/igslandstuhl/database/api/Room.java +++ /dev/null @@ -1,240 +0,0 @@ -package de.igslandstuhl.database.api; - -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import de.igslandstuhl.database.server.Server; -import de.igslandstuhl.database.server.sql.SQLHelper; - -/** - * Represents a room in the system. - * Each room has a label and a minimum level required for students to access it. - */ -public class Room implements APIObject { - private static final String[] SQL_FIELDS = {"label", "minimum_level"}; - /** - * A map to store all rooms, keyed by their label. - * This allows for quick access to room information without repeated database queries. - */ - private static final Map rooms = new HashMap<>(); - /** - * The label of the room, which is a unique identifier. - */ - private final String label; - /** - * The minimum level required for students to access this room. - * This is used to determine if a student is eligible to enter the room. - */ - private final int minimumLevel; - - /** - * Constructs a new Room. - * @param label the label of the room - * @param minimumLevel the minimum level required to access the room - */ - private Room(String label, int minimumLevel) { - this.label = label; - this.minimumLevel = minimumLevel; - } - /** - * Creates a Room instance from SQL result fields. - * This method is used to convert the result of a database query into a Room object. - * @param sqlResult the result fields from the SQL query - * @return a Room object constructed from the SQL fields - * @see Room#SQL_FIELDS - */ - private static Room fromSQLFields(String[] sqlResult) { - String label = sqlResult[0]; - int minimumLevel = Integer.parseInt(sqlResult[1]); - return new Room(label, minimumLevel); - } - /** - * Fetches all rooms from the database and populates the static map. - * This method retrieves all room records and stores them in the `rooms` map for quick access. - * @throws SQLException if there is an error accessing the database - */ - public static void fetchAll() throws SQLException { - rooms.clear(); - Server.getInstance().processRequest((fields) -> { - Room room = fromSQLFields(fields); - rooms.put(room.getLabel(), room); - }, "get_all_rooms", SQL_FIELDS); - } - /** - * Checks if the rooms map is empty and fetches all rooms if it is. - * This method ensures that the rooms are loaded into memory only once, - * preventing unnecessary database queries in subsequent calls. - * @throws SQLException if there is an error accessing the database - */ - public static void fetchAllIfNotExists() throws SQLException { - if (rooms.size() == 0) { - fetchAll(); - } - } - - /** - * Returns a map of all rooms. - * This method ensures that all rooms are fetched from the database if they haven't been loaded yet. - * @return a map of room labels to Room objects - * @throws IllegalStateException if there is an error fetching rooms from the database - */ - public static Map getRooms() { - try { - fetchAllIfNotExists(); - } catch (SQLException e) { - throw new IllegalStateException("Could not fetch rooms", e); - } - return rooms; - } - /** - * Retrieves a room by its label. - * This method checks if the room is already in the static map; if not, it fetches it from the database. - * @param label the label of the room to retrieve - * @return the Room object corresponding to the label, or null if not found - */ - public static Room getRoom(String label) { - if (rooms.keySet().contains(label)) { - return rooms.get(label); - } else { - try { - Room room = Server.getInstance().processSingleRequest(Room::fromSQLFields, "get_room_by_label", SQL_FIELDS, label); - if (room == null) { - return null; - } - rooms.put(label, room); - return room; - } catch (SQLException e) { - e.printStackTrace(); - return null; - } - } - } - /** - * Adds a new room to the database and the static map. - * This method creates a new Room object, inserts it into the database, - * and adds it to the `rooms` map for future access. - * @param label the label of the new room - * @param minimumLevel the minimum level required to access the new room - * @return the newly created Room object - * @throws SQLException if there is an error inserting the room into the database - */ - public static Room addRoom(String label, int minimumLevel) throws SQLException { - Room room = new Room(label, minimumLevel); - Server.getInstance().getConnection().executeVoidProcessSecure(SQLHelper.getAddObjectProcess("room", label, String.valueOf(minimumLevel))); - rooms.put(label, room); - return room; - } - public void delete() throws SQLException { - Server.getInstance().getConnection().executeVoidProcessSecure(SQLHelper.getDeleteObjectProcess("room", getLabel())); - rooms.remove(getLabel()); - } - /** - * Returns the label of the room. - * This is used to identify the room in various operations. - * @return the label of the room - */ - public String getLabel() { - return label; - } - /** - * Returns the minimum level required to access the room. - * This is used to determine if a student meets the requirements to enter the room. - * @return the minimum level required for access - */ - public int getMinimumLevel() { - return minimumLevel; - } - - public Room setMinimumLevel(int level) throws SQLException { - if (level < 0 || level > 3) throw new IllegalArgumentException("Level " + level + " out of range"); - Server.getInstance().getConnection().executeVoidProcessSecure(SQLHelper.getUpdateObjectProcess("level_of_room", getLabel(), String.valueOf(level))); - rooms.remove(getLabel()); - return getRoom(getLabel()); - } - - @Override - public String toString() { - return "{\"label\": \""+label+ "\", \"minimumLevel\": \"" + minimumLevel + "\"}"; - } - /** - * Adds multiple rooms to the database and the static map. - * This method allows for batch creation of rooms, ensuring that all rooms are added in a single operation. - * @param labels a list of room labels - * @param minimumLevels a list of minimum levels corresponding to each room - * @return a list of Room objects created - * @throws SQLException if there is an error inserting any of the rooms into the database - */ - public static List addAllRooms(List labels, List minimumLevels) throws SQLException { - if (labels.size() != minimumLevels.size()) { - throw new IllegalArgumentException("Labels and minimum levels must have the same size"); - } - List rooms = new ArrayList<>(); - for (int i = 0; i < labels.size(); i++) { - rooms.add(addRoom(labels.get(i), minimumLevels.get(i))); - } - return rooms; - } - /** - * Generates a list of Room objects from a CSV string. - * This method parses the CSV data and creates Room objects for each entry. - * @param csv the CSV string containing room data - * @return an array of Room objects created from the CSV data - */ - public static Room[] generateRoomsFromCSV(String csv) throws SQLException, IllegalArgumentException { - String[] lines = csv.split("\n"); - List labels = new ArrayList<>(); - List minimumLevels = new ArrayList<>(); - for (int i = 0; i < lines.length; i++) { - String[] parts = lines[i].split(","); - if (parts.length != 2) { - throw new IllegalArgumentException("Invalid CSV format for room: " + lines[i]); - } - String label = parts[0].trim(); - int minimumLevel; - try { - minimumLevel = Integer.parseInt(parts[1].trim()); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("Invalid minimum level for room: " + lines[i], e); - } - labels.add(label); - minimumLevels.add(minimumLevel); - } - List rooms = Room.addAllRooms(labels, minimumLevels); - return rooms.toArray(new Room[rooms.size()]); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((label == null) ? 0 : label.hashCode()); - result = prime * result + minimumLevel; - return result; - } - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Room other = (Room) obj; - if (label == null) { - if (other.label != null) - return false; - } else if (!label.equals(other.label)) - return false; - if (minimumLevel != other.minimumLevel) - return false; - return true; - } - @Override - public String toJSON() { - return "{\"label\": \""+label+ "\", \"minimumLevel\": \"" + minimumLevel + "\"}"; - } - -} diff --git a/src/main/java/de/igslandstuhl/database/api/Student.java b/src/main/java/de/igslandstuhl/database/api/Student.java index 79eb120..933b89b 100644 --- a/src/main/java/de/igslandstuhl/database/api/Student.java +++ b/src/main/java/de/igslandstuhl/database/api/Student.java @@ -87,11 +87,6 @@ public class Student extends User { */ private final Map currentTopics = new ConcurrentHashMap<>(); - /** - * The current room of the student. - */ - private Room currentRoom = null; - /** * Constructs a new Student. * @@ -223,10 +218,6 @@ public static List getAll() { .collect(Collectors.toList()); } - public static List getByRoom(Room room) { - return students.values().stream().filter((s) -> room.equals(s.getCurrentRoom())).toList(); - } - /** * Registers a new student with a password. * This method creates a new student in the database and returns the created Student object. @@ -352,18 +343,6 @@ public String getUsername() { */ public GraduationLevel getGraduationLevel() { return graduationLevel; } - /** - * Returns the student's current room. - * @return the current room - */ - public Room getCurrentRoom() { return currentRoom; } - - /** - * Sets the student's current room. - * @param currentRoom the new room - */ - public void setCurrentRoom(Room currentRoom) { this.currentRoom = currentRoom; } - /** * Returns the set of selected tasks. * @return selected tasks @@ -553,7 +532,6 @@ public String toJSON() { .append("\"selectedTasks\": ").append(selectedTasks).append(",\n") .append("\"completedTasks\": ").append(completedTasks).append(",\n") .append("\"lockedTasks\": ").append(lockedTasks).append(",\n") - .append("\"currentRoom\": ").append(String.valueOf(currentRoom)).append(",\n") .append("\"currentRequests\": {").append(currentRequests.entrySet().stream() .map(entry -> "\"" + entry.getKey() + "\": " + entry.getValue().stream().map((r) -> '"' + r.getGermanTranslation() + '"').toList()) .reduce((a, b) -> a + ", " + b).orElse("")).append("},\n") diff --git a/src/main/java/de/igslandstuhl/database/client/HTMLTemplate.java b/src/main/java/de/igslandstuhl/database/client/HTMLTemplate.java index 79a3d20..8b20614 100644 --- a/src/main/java/de/igslandstuhl/database/client/HTMLTemplate.java +++ b/src/main/java/de/igslandstuhl/database/client/HTMLTemplate.java @@ -4,6 +4,8 @@ import java.util.Map; import de.igslandstuhl.database.Registry; +import de.igslandstuhl.database.client.dynamic.DynamicFieldType; +import de.igslandstuhl.database.client.dynamic.DynamicHTMLTemplate; import de.igslandstuhl.database.client.navigation.HTMLNavigationTemplate; import de.igslandstuhl.database.client.navigation.NavigationAppearance; import de.igslandstuhl.database.client.navigation.NavigationElement; @@ -19,6 +21,7 @@ private static void register(HTMLTemplate template, String key) { } public static void registerAll() { NavigationElement.registerAll(); + DynamicHTMLTemplate.registerDynamicElements(); Map json = Server.getInstance().getResourceManager().readJsonResourceMerged(meta); json.keySet().forEach((key) -> { @SuppressWarnings("unchecked") @@ -36,6 +39,9 @@ public static void registerAll() { break; case "HTMLNavigationTemplate": register(new HTMLNavigationTemplate(NavigationAppearance.valueOf((String) template.get("appearance")), NavigationType.valueOf((String) template.get("navigation_type"))), key); + break; + case "DynamicHTMLTemplate": + register(new DynamicHTMLTemplate(DynamicFieldType.valueOf((String) template.get("dynamic_field_type"))), key); default: break; } diff --git a/src/main/java/de/igslandstuhl/database/client/dynamic/DynamicFieldType.java b/src/main/java/de/igslandstuhl/database/client/dynamic/DynamicFieldType.java new file mode 100644 index 0000000..7220797 --- /dev/null +++ b/src/main/java/de/igslandstuhl/database/client/dynamic/DynamicFieldType.java @@ -0,0 +1,44 @@ +package de.igslandstuhl.database.client.dynamic; + +import java.lang.reflect.InvocationTargetException; +import java.util.List; + +import de.igslandstuhl.database.Registry; +import de.igslandstuhl.database.server.resources.ResourceLocation; +import de.igslandstuhl.database.utils.RegistryEnum; + +public class DynamicFieldType extends RegistryEnum { + protected DynamicFieldType(Registry registry, String key) { + super(registry, key); + } + + private static final ResourceLocation meta = new ResourceLocation("meta", "dynamic", "dynamic_field_types.json"); + @Override + protected DynamicFieldType[] values(Registry registry) { + List DynamicFieldTypes = registry.stream().toList(); + DynamicFieldType[] arr = new DynamicFieldType[DynamicFieldTypes.size()]; + return DynamicFieldTypes.toArray(arr); + } + + @Override + protected void initValues() { + initUsingJSONMeta(meta); + } + + @Override + protected DynamicFieldType initValue(Registry registry,String key) { + return new DynamicFieldType(registry, key); + } + + public static DynamicFieldType valueOf(String string) { + return RegistryEnum.valueOf(string, DynamicFieldType.class); + } + public static void init() { + try { + RegistryEnum.init(DynamicFieldType.class); + } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException + | NoSuchMethodException | SecurityException e) { + throw new ExceptionInInitializerError(e); + } + } +} diff --git a/src/main/java/de/igslandstuhl/database/client/dynamic/DynamicHTMLTemplate.java b/src/main/java/de/igslandstuhl/database/client/dynamic/DynamicHTMLTemplate.java new file mode 100644 index 0000000..e425e1a --- /dev/null +++ b/src/main/java/de/igslandstuhl/database/client/dynamic/DynamicHTMLTemplate.java @@ -0,0 +1,41 @@ +package de.igslandstuhl.database.client.dynamic; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import com.google.gson.reflect.TypeToken; + +import de.igslandstuhl.database.Registry; +import de.igslandstuhl.database.client.HTMLTemplate; +import de.igslandstuhl.database.client.TemplatingPreprocessor; +import de.igslandstuhl.database.server.Server; +import de.igslandstuhl.database.server.resources.ResourceLocation; + +public record DynamicHTMLTemplate(DynamicFieldType type) implements HTMLTemplate { + @Override + public String fill(Map args) { + return Registry.dynamicTemplatesRegistry().stream(type) + .map(Registry.templateRegistry()::get) + .map((t) -> t.fill(args)) + .map(arg0 -> { + try { + return TemplatingPreprocessor.getInstance().executeTemplating(arg0); + } catch (IOException e) { + System.err.println("Failed filling template " + arg0); + e.printStackTrace(); + return ""; + } + }) + .reduce("", (s1, s2) -> s1 + "\n" + s2); + } + public static final ResourceLocation meta = new ResourceLocation("meta", "dynamic", "dynamic_elements.json"); + public static void registerDynamicElements() { + List> elements = Server.getInstance().getResourceManager().readJsonListMerged(meta, new TypeToken>>() {}); + elements.forEach((m) -> { + DynamicFieldType type = DynamicFieldType.valueOf(m.get("type")); + String template = m.get("template"); + Registry.dynamicTemplatesRegistry().register(type, template); + }); + } +} \ No newline at end of file diff --git a/src/main/java/de/igslandstuhl/database/server/Server.java b/src/main/java/de/igslandstuhl/database/server/Server.java index a4b2f98..df4aafc 100644 --- a/src/main/java/de/igslandstuhl/database/server/Server.java +++ b/src/main/java/de/igslandstuhl/database/server/Server.java @@ -3,25 +3,19 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; -import java.util.HashSet; import java.util.LinkedList; import java.util.List; -import java.util.Set; import java.util.function.Consumer; import java.util.function.Function; import org.apache.commons.codec.digest.DigestUtils; import de.igslandstuhl.database.Application; -import de.igslandstuhl.database.api.Room; -import de.igslandstuhl.database.api.SchoolClass; -import de.igslandstuhl.database.api.Student; -import de.igslandstuhl.database.api.Subject; -import de.igslandstuhl.database.api.Teacher; import de.igslandstuhl.database.api.User; import de.igslandstuhl.database.server.resources.ResourceManager; import de.igslandstuhl.database.server.sql.SQLHelper; import de.igslandstuhl.database.server.sql.SQLiteConnection; +import de.igslandstuhl.database.server.webserver.handlers.get.SQLRequestHandler; /** * Represents the main server class that handles all incoming requests and manages the database connection. @@ -206,45 +200,7 @@ public boolean isValidUser(String username, String password) { */ public String getSQLResource(String username, String resource) { resource = resource.intern(); - if (resource.equals("mydata")) { - User user = User.getUser(username); - return user.toJSON(); - } else if (resource.equals("rooms")) { - return new HashSet<>(Room.getRooms().values()).toString(); - } else if (resource.equals("mysubjects")) { - User user = User.getUser(username); - if (user instanceof Student student) { - return student.getSchoolClass().getSubjects().toString(); - } else if (user instanceof Teacher teacher) { - return teacher.getSubjects().toString(); - } else { - return null; - } - } else if (resource.equals("myclasses")) { - User user = User.getUser(username); - if (user instanceof Teacher teacher) { - Set classIDs = teacher.getClassIds(); - Set classes = new HashSet<>(); - for (Integer classID : classIDs) { - classes.add("{\"classId\": " + classID + ", \"name\": \"" + SchoolClass.get(classID).getLabel() + "\"}"); - } - return classes.toString(); - } else { - return null; - } - } else if (resource.equals("teachers")) { - return new HashSet<>(Teacher.getAll()).toString(); - } else if (resource.equals("students")) { - return new HashSet<>(Student.getAll()).toString(); - } else if (resource.equals("subjects")) { - return new HashSet<>(Subject.getAll()).toString(); - } else if (resource.equals("classes")) { - return new HashSet<>(SchoolClass.getAll()).toString(); - } else if (resource.equals("all-student-results")) { - return Student.getAllResultsCSV(); - } else { - return null; - } + return SQLRequestHandler.getResource(resource, User.getUser(username)); } @Override diff --git a/src/main/java/de/igslandstuhl/database/server/commands/Command.java b/src/main/java/de/igslandstuhl/database/server/commands/Command.java index 795833d..38469b1 100644 --- a/src/main/java/de/igslandstuhl/database/server/commands/Command.java +++ b/src/main/java/de/igslandstuhl/database/server/commands/Command.java @@ -78,71 +78,6 @@ public static void registerCommands() { return String.valueOf(level.getRatio() * 100) + "%"; }, new CommandDescription("get-level-ratio", "Gets the ratio of a task level", "get-level-ratio [level]")); - // Room commands - registerCommand("list-rooms", (args) -> { - try { - Room.fetchAll(); - } catch (SQLException e) { - return "Error while trying to access database:\n" + CommonUtils.getStacktrace(e); - } - return Room.getRooms().keySet().stream().reduce("Rooms:", (s1, s2) -> s1 + "\n" + s2); - }, new CommandDescription("list-rooms", "Lists all available rooms", "list-rooms")); - registerCommand("get-room-level", (args) -> { - if (args.length < 1) return "Usage: get-room-level [room]"; - Room room = Room.getRoom(argsPart(args, 0, args.length)); - if (room == null) return "Room not found. Try list-rooms for a list of available rooms"; - return "Room " + room.getLabel() + " has access level " + room.getMinimumLevel(); - }, new CommandDescription("get-room-level", "Gets the minimum level required to access a room", "get-room-level [room]")); - registerCommand("set-room-level", (args) -> { - if (args.length < 2) return "Usage: set-room-level [room] [level]"; - Room room = Room.getRoom(argsPart(args, 0, args.length-1)); - if (room == null) return "Room not found. Try list-rooms for a list of available rooms"; - int level; - try { - level = Integer.parseInt(args[args.length - 1]); - } catch (NumberFormatException e) { - return args[1] + " is not a valid number."; - } - try { - room.setMinimumLevel(level); - } catch (SQLException e) { - return "Error while trying to access database: \n" + CommonUtils.getStacktrace(e); - } catch (IllegalArgumentException e) { - return e.getMessage(); - } - return "Successfully changed room level"; - }, new CommandDescription("set-room-level", "Sets the minimum level required to access a room", "set-room-level [room] [level]")); - registerCommand("add-room", (args) -> { - if (args.length < 2) return "Usage: add-room [room] [level]"; - if (Room.getRoom(args[0]) != null) return "Room already present"; - - try { - String label = argsPart(args, 0, args.length-1); - int level = Integer.parseInt(args[args.length-1]); - - Room.addRoom(label, level); - } catch (NumberFormatException e) { - return args[args.length - 1] + " is not a valid number."; - } catch (IllegalArgumentException e) { - return e.getMessage(); - } catch (SQLException e) { - throw new IllegalStateException(e); - } - return "Room successfully added"; - }, new CommandDescription("add-room", "Adds a new room", "add-room [room] [level]")); - registerCommand("remove-room", (args) -> { - if (args.length < 1) return "Usage: remove-room [room]"; - - Room room = Room.getRoom(argsPart(args, 0, args.length)); - try { - room.delete(); - } catch (SQLException e) { - return "Error while trying to access database: \n" + CommonUtils.getStacktrace(e); - } - return "Room successfully deleted"; - }, new CommandDescription("remove-room", "Removes a room", "remove-room [room]")); - - // class commands registerCommand("list-classes", (args) -> { return SchoolClass.getAll().stream().map(SchoolClass::getLabel).reduce("Classes:", (s1,s2) -> s1 + "\n" + s2); diff --git a/src/main/java/de/igslandstuhl/database/server/webserver/handlers/PostRequestHandler.java b/src/main/java/de/igslandstuhl/database/server/webserver/handlers/PostRequestHandler.java index 6b8d4e3..5bbb557 100644 --- a/src/main/java/de/igslandstuhl/database/server/webserver/handlers/PostRequestHandler.java +++ b/src/main/java/de/igslandstuhl/database/server/webserver/handlers/PostRequestHandler.java @@ -20,7 +20,6 @@ import de.igslandstuhl.database.Application; import de.igslandstuhl.database.Registry; import de.igslandstuhl.database.api.APIObject; -import de.igslandstuhl.database.api.Room; import de.igslandstuhl.database.api.SchoolClass; import de.igslandstuhl.database.api.Student; import de.igslandstuhl.database.api.Subject; @@ -205,15 +204,6 @@ public static void registerHandlers() { } }, PostRequestHandler::csvResult) ); - HttpHandler.registerPostRequestHandler("/add-rooms", AccessLevel.ADMIN, (rq) -> - handleBatchInsertCSV(rq, "rooms", ContentType.JSON, t -> { - try { - return Room.generateRoomsFromCSV(t); - } catch (SQLException e) { - throw new IllegalStateException(e); - } - }, Arrays::toString) - ); HttpHandler.registerPostRequestHandler("/add-teacher", AccessLevel.ADMIN, (rq) -> { String firstName = prepare(rq.getString("firstName")); String lastName = prepare(rq.getString("lastName")); @@ -271,14 +261,6 @@ public static void registerHandlers() { HttpHandler.registerPostRequestHandler("/tasks", AccessLevel.USER, (rq) -> { return PostResponse.ok(JSONUtils.toJSON(rq.getTaskList()), ContentType.JSON, rq); }); - HttpHandler.registerPostRequestHandler("/update-room", AccessLevel.USER, (rq) -> { - Student student = rq.getCurrentStudent(); - if (student == null) return PostResponse.unauthorized(rq); - Room room = rq.getRoom(); - if (room == null) return PostResponse.badRequest("Room not found", rq); - student.setCurrentRoom(room); - return PostResponse.ok("Changed current room", ContentType.TEXT_PLAIN, rq); - }); HttpHandler.registerPostRequestHandler("/begin-task", AccessLevel.USER, (rq) -> handleTaskChange(rq, Task.STATUS_IN_PROGRESS)); HttpHandler.registerPostRequestHandler("/complete-task", AccessLevel.USER, (rq) -> handleTaskChange(rq, Task.STATUS_COMPLETED)); HttpHandler.registerPostRequestHandler("/cancel-task", AccessLevel.USER, (rq) -> handleTaskChange(rq, Task.STATUS_NOT_STARTED)); @@ -301,30 +283,7 @@ public static void registerHandlers() { .addProperty("id", student.getId()) .addProperty("name", student.getFirstName() + " " + student.getLastName()) .addProperty("actionRequired", student.isActionRequired()) - .addProperty("graduationLevel", student.getGraduationLevel()) - .addProperty("room", student.getCurrentRoom() != null ? student.getCurrentRoom().getLabel() : "None"); - if (rq.getJson().containsKey("subjectId") && rq.getSubject() != null) { - Set subjectRequests = student.getCurrentRequests(rq.getSubject()); - builder.addProperty("experiment",subjectRequests.stream().anyMatch(r -> r == SubjectRequest.EXPERIMENT)) - .addProperty("help", subjectRequests.stream().anyMatch(r -> r == SubjectRequest.HELP)) - .addProperty("test", subjectRequests.stream().anyMatch(r -> r == SubjectRequest.EXAM)) - .addProperty("partner", subjectRequests.stream().anyMatch(r -> r == SubjectRequest.PARTNER)); - } - }), - ContentType.JSON, rq - ); - }); - HttpHandler.registerPostRequestHandler("/get-students-by-room", AccessLevel.TEACHER, (rq) -> { - Room room = rq.getRoom(); - List students = Student.getByRoom(room); - return PostResponse.ok( - JSONUtils.toJSON(students, (student, builder) -> { - builder - .addProperty("id", student.getId()) - .addProperty("name", student.getFirstName() + " " + student.getLastName()) - .addProperty("actionRequired", student.isActionRequired()) - .addProperty("graduationLevel", student.getGraduationLevel()) - .addProperty("room", student.getCurrentRoom() != null ? student.getCurrentRoom().getLabel() : "None"); + .addProperty("graduationLevel", student.getGraduationLevel()); if (rq.getJson().containsKey("subjectId") && rq.getSubject() != null) { Set subjectRequests = student.getCurrentRequests(rq.getSubject()); builder.addProperty("experiment",subjectRequests.stream().anyMatch(r -> r == SubjectRequest.EXPERIMENT)) @@ -364,8 +323,7 @@ public static void registerHandlers() { .toList(); return PostResponse.ok(JSONUtils.toJSON(students, (partner, builder) -> { builder.addProperty("id", partner.getId()) - .addProperty("name", partner.getFirstName() + " " + partner.getLastName()) - .addProperty("room", partner.getCurrentRoom() != null ? partner.getCurrentRoom().getLabel() : "None"); + .addProperty("name", partner.getFirstName() + " " + partner.getLastName()); }), ContentType.JSON, rq); }); HttpHandler.registerPostRequestHandler("/delete-subject", AccessLevel.ADMIN, (rq) -> diff --git a/src/main/java/de/igslandstuhl/database/server/webserver/handlers/get/SQLRequestHandler.java b/src/main/java/de/igslandstuhl/database/server/webserver/handlers/get/SQLRequestHandler.java new file mode 100644 index 0000000..391c9f4 --- /dev/null +++ b/src/main/java/de/igslandstuhl/database/server/webserver/handlers/get/SQLRequestHandler.java @@ -0,0 +1,51 @@ +package de.igslandstuhl.database.server.webserver.handlers.get; + +import java.util.HashSet; +import java.util.Set; + +import de.igslandstuhl.database.Registry; +import de.igslandstuhl.database.api.SchoolClass; +import de.igslandstuhl.database.api.Student; +import de.igslandstuhl.database.api.Subject; +import de.igslandstuhl.database.api.Teacher; +import de.igslandstuhl.database.api.User; + +@FunctionalInterface +public interface SQLRequestHandler { + public String get(User user); + + public static String getResource(String resource, User user) { + return Registry.sqlRequestHandlerRegistry().get(resource).get(user); + } + public static void register() { + Registry.sqlRequestHandlerRegistry().register("mydata", (user) -> user.toJSON()); + + Registry.sqlRequestHandlerRegistry().register("mysubjects", (user) -> { + if (user instanceof Student student) { + return student.getSchoolClass().getSubjects().toString(); + } else if (user instanceof Teacher teacher) { + return teacher.getSubjects().toString(); + } else { + return null; + } + }); + Registry.sqlRequestHandlerRegistry().register("myclasses", (user) -> { + if (user instanceof Teacher teacher) { + Set classIDs = teacher.getClassIds(); + Set classes = new HashSet<>(); + for (Integer classID : classIDs) { + classes.add("{\"classId\": " + classID + ", \"name\": \"" + SchoolClass.get(classID).getLabel() + "\"}"); + } + return classes.toString(); + } else { + return null; + } + }); + + Registry.sqlRequestHandlerRegistry().register("teachers", (user) -> new HashSet<>(Teacher.getAll()).toString()); + Registry.sqlRequestHandlerRegistry().register("students", (user) -> new HashSet<>(Student.getAll()).toString()); + Registry.sqlRequestHandlerRegistry().register("subjects", (user) -> new HashSet<>(Subject.getAll()).toString()); + Registry.sqlRequestHandlerRegistry().register("classes", (user) -> new HashSet<>(SchoolClass.getAll()).toString()); + Registry.sqlRequestHandlerRegistry().register("all-student-resukts", (user) -> Student.getAllResultsCSV()); + } +} diff --git a/src/main/java/de/igslandstuhl/database/server/webserver/requests/APIPostRequest.java b/src/main/java/de/igslandstuhl/database/server/webserver/requests/APIPostRequest.java index 72edc41..2c070a4 100644 --- a/src/main/java/de/igslandstuhl/database/server/webserver/requests/APIPostRequest.java +++ b/src/main/java/de/igslandstuhl/database/server/webserver/requests/APIPostRequest.java @@ -7,7 +7,6 @@ import com.google.gson.reflect.TypeToken; import de.igslandstuhl.database.api.APIObject; -import de.igslandstuhl.database.api.Room; import de.igslandstuhl.database.api.SchoolClass; import de.igslandstuhl.database.api.Student; import de.igslandstuhl.database.api.Subject; @@ -58,9 +57,6 @@ public Topic getTopic() { public SubjectRequest getSubjectRequest() { return SubjectRequest.fromGermanTranslation(getString("subjectRequest")); } - public Room getRoom() { - return Room.getRoom(getString("room")); - } public Task getTask() { return Task.get(getInt("taskId")); } @@ -86,8 +82,6 @@ public T getAPIObject(TypeToken type) { return (T) getSubjectRequest(); } else if (rawType.getTypeName().contains("Task")) { return (T) getTask(); - } else if (rawType.getTypeName().contains("Room")) { - return (T) getRoom(); } else if (rawType.getTypeName().contains("SchoolClass")) { return (T) getSchoolClass(); } else { diff --git a/src/main/resources/html/admin/class.html b/src/main/resources/html/admin/class.html index cec7d6a..513c556 100644 --- a/src/main/resources/html/admin/class.html +++ b/src/main/resources/html/admin/class.html @@ -40,7 +40,6 @@

Schüler in der Klasse

Name - Raum Graduierung diff --git a/src/main/resources/html/admin/manage_rooms.html b/src/main/resources/html/admin/manage_rooms.html deleted file mode 100644 index bda0d6d..0000000 --- a/src/main/resources/html/admin/manage_rooms.html +++ /dev/null @@ -1,46 +0,0 @@ -%[site;title=Raumverwaltung;content=!FOLLOWS] -
-
-

Raumverwaltung

-
-
-
-

Räume hinzufügen

-
- - - -
-
-
-

Raumliste

- - - - - - - - - - -
RaumnameMindestlevel
-
-
- -
- \ No newline at end of file diff --git a/src/main/resources/html/admin/teacher.html b/src/main/resources/html/admin/teacher.html index e6c43f5..96eb3ee 100644 --- a/src/main/resources/html/admin/teacher.html +++ b/src/main/resources/html/admin/teacher.html @@ -19,9 +19,7 @@

Lehrer bearbeiten

- %[class_info] - %[subject_info] - %[room_info] + %[teacher_infos]