diff options
| author | davidovski <david@sendula.com> | 2022-11-30 10:06:56 +0000 | 
|---|---|---|
| committer | davidovski <david@sendula.com> | 2022-11-30 10:06:56 +0000 | 
| commit | 290c68795d8100cc97b8b53d80f331e536fc71b1 (patch) | |
| tree | bf0068c4c9121406df9bc90f5c159fd93de8a61e /src/webserver/src | |
Diffstat (limited to 'src/webserver/src')
4 files changed, 323 insertions, 0 deletions
diff --git a/src/webserver/src/main/java/io/github/davidovski/names/APIRequestHandler.java b/src/webserver/src/main/java/io/github/davidovski/names/APIRequestHandler.java new file mode 100644 index 0000000..5ef2cfe --- /dev/null +++ b/src/webserver/src/main/java/io/github/davidovski/names/APIRequestHandler.java @@ -0,0 +1,112 @@ +package io.github.davidovski.names; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.util.List; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.json.JSONTokener; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; + +@SuppressWarnings("restriction") +public class APIRequestHandler implements HttpHandler { + +    private NameDatabaseManager nameDatabaseManager; + +    public APIRequestHandler() { +        nameDatabaseManager = new NameDatabaseManager(new File("names.db")); +    } + +    @Override +    public void handle(HttpExchange exchange) throws IOException { +        // get the requested path +        String path = exchange.getRequestURI().getPath(); + +        System.out.println(path); + +        if (path.startsWith("/api/name")) { + +            // parse the body as a json object +            JSONTokener jsonParser = new JSONTokener(exchange.getRequestBody()); +            JSONObject json = (JSONObject) jsonParser.nextValue(); + +            System.out.println(json.toString(2)); + +            if (json == null) { +                // Malformed JSON request, 400 +                sendJSON(exchange, (new JSONObject()).put("message", "Malformed JSON body"), 400); +                return; +            } + +            // generate name(s) and send it +            generateName(exchange, json); +        } else { +            sendJSON(exchange, (new JSONObject()).put("message", "Not Found"), 404); +        } +    } + +    public void generateName(HttpExchange exchange, JSONObject options) throws JSONException, IOException { +        String origin = options.optString("origin", "none").toLowerCase(); + +        int count = options.optInt("count", 1); + +        // ensure that the count is between 1-100 +        if (count < 1 || count > 100) { +            sendJSON(exchange, (new JSONObject()).put("message", "Name count is out of range: Ensure that the request is between 1 and 100 names"), 400); +            return; +        } + +        String gender = options.optString("gender", "female"); + +        // ensure that the gender is either male or female +        if (!gender.equals("male") && !gender.equals("female")) { +            sendJSON(exchange, (new JSONObject()).put("message", "Requested gender is invalid"), 400); +            return; +        } + +        // Store the names in an array +        List<String> names = nameDatabaseManager.getRandomNames(origin, gender, count); + +        if (options.optBoolean("surname")) { +            List<String> surnames = nameDatabaseManager.getRandomNames(origin, "surname", count); + +            // Add surnames to the end of each firstname in the names list +            for (int i = 0; i < count; i++) { +                String fullname = names.get(i) + " " + surnames.get(i); +                names.set(i, fullname); +            } +        } + +        // Create the response json object +        JSONObject response = new JSONObject(); +        response.put("message", "Generated " + count + " names"); +        response.put("names", new JSONArray(names)); + +        // send the json back to the client +        sendJSON(exchange, response, 200); +    } + +    public void sendJSON(HttpExchange exchange, JSONObject json, int responseCode) throws IOException { +        // convert the json to a string +        String response = json.toString(2); + +        // calculate the response content size +        int contentSize = response.toString().getBytes().length; + +        // set the response headers +        exchange.getResponseHeaders().add("Content-Type", "text/json"); +        exchange.sendResponseHeaders(responseCode, contentSize); + +        // write the response to the output stream +        OutputStream outputStream = exchange.getResponseBody(); + +        outputStream.write(response.toString().getBytes()); +        outputStream.close(); +    } + +} diff --git a/src/webserver/src/main/java/io/github/davidovski/names/NameDatabaseManager.java b/src/webserver/src/main/java/io/github/davidovski/names/NameDatabaseManager.java new file mode 100644 index 0000000..8822d9c --- /dev/null +++ b/src/webserver/src/main/java/io/github/davidovski/names/NameDatabaseManager.java @@ -0,0 +1,75 @@ +package io.github.davidovski.names; + +import java.io.File; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class NameDatabaseManager { +    private File databaseFile; +    private Connection connection; + +    private static final String TABLE = "names"; + +    public NameDatabaseManager(File databaseFile) { +        this.databaseFile = databaseFile; + +        connect(); +    } + +    /** +     * Creates a connection to the database. If one could not be created, the connection will remain as null +     */ +    private void connect() { +        connection = null; +        try { +            connection = DriverManager.getConnection("jdbc:sqlite:" + databaseFile.getPath()); +        } catch (SQLException e) { +            e.printStackTrace(); +        } +    } + +    public List<String> getRandomNames(String origin, String category, int quantitiy) { +        // create the set to return, even if empty +        List<String> names = new ArrayList<String>(); + +        if (connection != null) { +            // Create an sql statement +            String sql = "SELECT Name FROM " + TABLE + " WHERE Origin=? AND Category=? ORDER BY RANDOM() LIMIT ?;"; +            PreparedStatement statement; +            try { +                statement = connection.prepareStatement(sql); + +                // insert relevant values into the statement +                statement.setString(1, origin); +                statement.setString(2, category); +                statement.setInt(3, quantitiy); + +                // execute the query and get the result +                ResultSet result = statement.executeQuery(); + +                // Add all of the results to the names set +                while (result.next()) { +                    String name = result.getString("Name"); +                    names.add(name); +                } +            } catch (SQLException e) { +                e.printStackTrace(); +            } + +        } +        return names; +    } + +    public static void main(String[] args) { +        NameDatabaseManager dbManager = new NameDatabaseManager(new File("names.db")); +        List<String> names = dbManager.getRandomNames("spain", "female", 10); +        for (String name : names) { +            System.out.println(name); +        } +    } +} diff --git a/src/webserver/src/main/java/io/github/davidovski/names/StaticRequestHandler.java b/src/webserver/src/main/java/io/github/davidovski/names/StaticRequestHandler.java new file mode 100644 index 0000000..d10d0b1 --- /dev/null +++ b/src/webserver/src/main/java/io/github/davidovski/names/StaticRequestHandler.java @@ -0,0 +1,85 @@ +package io.github.davidovski.names; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; + +@SuppressWarnings("restriction") +public class StaticRequestHandler implements HttpHandler { +    private File root; + +    public StaticRequestHandler(File root) { +        this.root = root; +    } + +    @Override +    public void handle(HttpExchange exchange) throws IOException { +        // get the requested path +        String path = exchange.getRequestURI().getPath(); + +        File requested = new File(root, path); + +        // automatically send the index of a directory +        if (requested.isDirectory()) { +            requested = new File(requested, "index.html"); +        } + +        // ensure that the file is in the intended document root +        if (!isInRoot(requested, root)) { +            sendText(exchange, "Access Denied", 403); +        } else if (requested.exists()) { +            sendFile(exchange, requested); +        } else { +            // send 404 if the file isnt found +            sendText(exchange, "File Not Found", 404); +        } +    } + +    private void sendFile(HttpExchange exchange, File file) throws IOException { +        // read the file as into an array of bytes +        byte[] bytes = Files.readAllBytes(file.toPath()); + +        // send the file headers +        exchange.sendResponseHeaders(200, bytes.length); + +        // send the file body +        OutputStream os = exchange.getResponseBody(); +        os.write(bytes); +        os.close(); +    } + +    private void sendText(HttpExchange exchange, String response, int responseCode) throws IOException { +        // calculate the response content size +        int contentSize = response.toString().getBytes().length; + +        // set the response headers +        exchange.getResponseHeaders().add("Content-Type", "text/json"); +        exchange.sendResponseHeaders(responseCode, contentSize); + +        // write the response to the output stream +        OutputStream outputStream = exchange.getResponseBody(); + +        outputStream.write(response.toString().getBytes()); +        outputStream.close(); +    } + +    public static boolean isInRoot(File request, File root) { +        File parentFile = request; + +        // start from the requested file and traverse upwards until reaching the root directory +        while (parentFile != null) { +            if (root.equals(parentFile)) { +                return true; +            } +            parentFile = parentFile.getParentFile(); +        } + +        // If there isn't a parent file, return false +        return false; +    } + +} diff --git a/src/webserver/src/main/java/io/github/davidovski/names/WebServer.java b/src/webserver/src/main/java/io/github/davidovski/names/WebServer.java new file mode 100644 index 0000000..60b311f --- /dev/null +++ b/src/webserver/src/main/java/io/github/davidovski/names/WebServer.java @@ -0,0 +1,51 @@ +package io.github.davidovski.names; + +import java.io.File; +import java.io.IOException; +import java.net.InetSocketAddress; + +import com.sun.net.httpserver.HttpServer; + +@SuppressWarnings("restriction") +public class WebServer { +    private int port; +    private HttpServer server; + +    public WebServer(int port) throws IOException { +        this.port = port; + +        // create an HTTP server instance +        InetSocketAddress socketAddress = new InetSocketAddress(port); +        server = HttpServer.create(socketAddress, 0); + +        // create a context for the static request handler +        server.createContext("/", new StaticRequestHandler(new File("dist"))); +        // create a context for the api request handler +        server.createContext("/api", new APIRequestHandler()); + +    } + +    public void start() { +        server.start(); + +        // tell the user that the webserver has been started, and the port used +        System.out.println("Webserver started on port " + port); +    } + + +    public static void main(String[] args) throws IOException { + +        // set a default port number +        int port = 8080; + +        // parse the arguments for a port number +        if (args.length > 0) +            port = Integer.parseInt(args[0]); + +        // Create the webserver instance +        WebServer webServer = new WebServer(port); + +        // start the webserver +        webServer.start(); +    } +}  | 
