package examples.multipart;

import com.vtence.molecule.BodyPart;
import com.vtence.molecule.WebServer;
import com.vtence.molecule.lib.TextBody;
import com.vtence.molecule.routing.DynamicRoutes;

import java.io.IOException;

public class MultipartExample {

    public void run(WebServer server) throws IOException {
        server.start(new DynamicRoutes() {{
            get("/profile").to((request, response) -> {
                response.contentType("text/html");
                response.done("<html>" +
                        "<body>" +
                        "<form enctype='multipart/form-data' action='/profile' method='post'>\n" +
                        "<p>" +
                        "  <label>Email: <input type=\"email\" name=\"email\"></label>\n" +
                        "</p>" +
                        "<p>" +
                        "  <label>Biography: <input type=\"file\" name=\"biography\"></label>\n" +
                        "</p>" +
                        "<p>" +
                        "  <label>Avatar: <input type=\"file\" name=\"avatar\"></label>\n" +
                        "</p>" +
                        "<p>" +
                        "  <input type=\"submit\" value=\"Go\">\n" +
                        "</p>" +
                        "</form>" +
                        "</body>" +
                        "</html>");
            });

            post("/profile").to((request, response) -> {
                BodyPart email = request.part("email");
                BodyPart biography = request.part("biography");
                BodyPart avatar = request.part("avatar");

                response.contentType("text/plain");
                TextBody echo = new TextBody();
                if (email != null)
                    echo.append("email: ").append(email.value()).append("\n");
                if (biography != null)
                    echo.append("biography: ").append(biography.value()).append("\n");
                if (avatar != null)
                    echo.append("avatar: ")
                        .append(avatar.filename()).append(" (").append(avatar.contentType()).append(")")
                        .append(" - ").append(String.valueOf(avatar.content().length)).append(" bytes");
                response.done(echo);
            });
        }});
    }

    public static void main(String[] args) throws IOException {
        MultipartExample example = new MultipartExample();
        WebServer webServer = WebServer.create();
        example.run(webServer);
        System.out.println("Access at " + webServer.uri() + "/profile");
    }
}

@@ -222,199 +222,981 @@
 n;%0A%0A
-public class MultipartExample %7B%0A%0A    public void run(WebServer server) throws IOException %7B%0A        server.start(new DynamicRoutes() %7B%7B%0A            get(%22/profile%22).to((request, response) -%3E %7B
+/**%0A * %3Cp%3E%0A *     This example shows how to handle multi-part file uploads.%0A * %3C/p%3E%0A * %3Cp%3E%0A *     We have a first endpoint to serve a very simple profile HTML form in which our user can%0A *     enter an email address, upload a text biography and a profile image.%0A *     %3Cbr%3E%0A *     This form is submitted encoded as %3Ccode%3Emultipart/form-data%3C/code%3E.%0A *     We process the form submission in a second endpoint.%0A * %3C/p%3E%0A */%0Apublic class MultipartExample %7B%0A%0A    public void run(WebServer server) throws IOException %7B%0A        // Start the server with a set of routes%0A        server.start(new DynamicRoutes() %7B%7B%0A%0A            // A GET request to /profile renders an HTML profile form, that will be submitted as%0A            // multipart/form-data. In this form the user can enter an email address, upload a text biography%0A            // and a profile image%0A            get(%22/profile%22).to((request, response) -%3E %7B%0A                // Set the content type of the response to text/html
 %0A   
@@ -1238,24 +1238,68 @@
 text/html%22);
+%0A%0A                // Render the profile form
 %0A           
@@ -2216,231 +2216,626 @@
     
-post(%22/profile%22).to((request, response) -%3E %7B%0A                BodyPart email = request.part(%22email%22);%0A                BodyPart biography = request.part(%22biography%22);%0A                BodyPart avatar = request.part(%22avatar%22);%0A
+// A POST to /profile submits the form, then returns a plain text page with a summary of the%0A            // profile.%0A            post(%22/profile%22).to((request, response) -%3E %7B%0A                // Get the email address as a body part%0A                BodyPart email = request.part(%22email%22);%0A                // Get the biography as a second body part%0A                BodyPart biography = request.part(%22biography%22);%0A                // Get the avatar image as the last body part%0A                BodyPart avatar = request.part(%22avatar%22);%0A%0A                // We respond with plain text content containing the profile information
 %0A   
@@ -2958,32 +2958,99 @@
 (email != null)%0A
+                    // We read the value of the email part as text%0A
                 
@@ -3143,32 +3143,118 @@
 graphy != null)%0A
+                    // We read the value of the file containing the biography as text%0A
                 
@@ -3432,88 +3432,285 @@
     
-.append(avatar.filename()).append(%22 (%22).append(avatar.contentType()).append(%22)%22)
+// We read the filename of the avatar and its content-type%0A                        .append(avatar.filename()).append(%22 (%22).append(avatar.contentType()).append(%22)%22)%0A                        // We also read the content of the image as a raw stream of bytes to calculate its length
 %0A   

Add inline documentation to the multi-part example