Helper.java 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package hello;
  2. import static io.undertow.util.Headers.CONTENT_TYPE;
  3. import com.fasterxml.jackson.databind.ObjectMapper;
  4. import com.github.mustachejava.DefaultMustacheFactory;
  5. import com.github.mustachejava.Mustache;
  6. import com.github.mustachejava.MustacheFactory;
  7. import io.undertow.server.HttpServerExchange;
  8. import java.io.IOException;
  9. import java.io.StringWriter;
  10. import java.nio.ByteBuffer;
  11. import java.util.Deque;
  12. import java.util.concurrent.ThreadLocalRandom;
  13. import org.bson.Document;
  14. /**
  15. * Provides utility methods for the application.
  16. */
  17. final class Helper {
  18. private Helper() {
  19. throw new AssertionError();
  20. }
  21. /**
  22. * Returns the value of the "queries" request parameter, which is an integer
  23. * bound between 1 and 500 with a default value of 1.
  24. *
  25. * @param exchange the current HTTP exchange
  26. * @return the value of the "queries" request parameter
  27. */
  28. static int getQueries(HttpServerExchange exchange) {
  29. Deque<String> values = exchange.getQueryParameters().get("queries");
  30. if (values == null) {
  31. return 1;
  32. }
  33. String textValue = values.peekFirst();
  34. if (textValue == null) {
  35. return 1;
  36. }
  37. int parsedValue;
  38. try {
  39. parsedValue = Integer.parseInt(textValue);
  40. } catch (NumberFormatException e) {
  41. return 1;
  42. }
  43. return Math.min(500, Math.max(1, parsedValue));
  44. }
  45. /**
  46. * Returns a random integer that is a suitable value for both the {@code id}
  47. * and {@code randomNumber} properties of a world object.
  48. *
  49. * @return a random world number
  50. */
  51. static int randomWorldNumber() {
  52. return 1 + ThreadLocalRandom.current().nextInt(10000);
  53. }
  54. /**
  55. * Ends the HTTP exchange by encoding the given value as JSON and writing
  56. * that JSON to the response.
  57. *
  58. * @param exchange the current HTTP exchange
  59. * @param value the value to be encoded as JSON
  60. * @throws IllegalArgumentException if the value cannot be encoded as JSON
  61. */
  62. static void sendJson(HttpServerExchange exchange, Object value) {
  63. byte[] jsonBytes;
  64. try {
  65. jsonBytes = objectMapper.writeValueAsBytes(value);
  66. } catch (IOException e) {
  67. throw new IllegalArgumentException(e);
  68. }
  69. ByteBuffer jsonBuffer = ByteBuffer.wrap(jsonBytes);
  70. exchange.getResponseHeaders().put(CONTENT_TYPE, "application/json");
  71. exchange.getResponseSender().send(jsonBuffer);
  72. }
  73. private static final ObjectMapper objectMapper = new ObjectMapper();
  74. /**
  75. * Ends the HTTP exchange by supplying the given value to a Mustache template
  76. * and writing the HTML output of the template to the response.
  77. *
  78. * @param exchange the current HTTP exchange
  79. * @param value the value to be supplied to the Mustache template
  80. * @param templatePath the path to the Mustache template
  81. */
  82. static void sendHtml(HttpServerExchange exchange,
  83. Object value,
  84. String templatePath) {
  85. Mustache mustache = mustacheFactory.compile(templatePath);
  86. StringWriter writer = new StringWriter();
  87. mustache.execute(writer, value);
  88. String html = writer.toString();
  89. exchange.getResponseHeaders().put(CONTENT_TYPE, "text/html;charset=utf-8");
  90. exchange.getResponseSender().send(html);
  91. }
  92. private static final MustacheFactory mustacheFactory =
  93. new DefaultMustacheFactory();
  94. /**
  95. * Ends the HTTP exchange with an exception.
  96. *
  97. * @param exchange the current HTTP exchange
  98. * @param exception the exception that was thrown
  99. */
  100. static void sendException(HttpServerExchange exchange, Throwable exception) {
  101. exchange.setStatusCode(500);
  102. exchange.endExchange();
  103. exception.printStackTrace();
  104. }
  105. /**
  106. * Reads a {@link World} from its persisted {@link Document} representation.
  107. */
  108. static World mongoDocumentToWorld(Document document) {
  109. int id = mongoGetInt(document, "_id");
  110. int randomNumber = mongoGetInt(document, "randomNumber");
  111. return new World(id, randomNumber);
  112. }
  113. /**
  114. * Reads a {@link Fortune} from its persisted {@link Document} representation.
  115. */
  116. static Fortune mongoDocumentToFortune(Document document) {
  117. int id = mongoGetInt(document, "_id");
  118. String message = document.getString("message");
  119. return new Fortune(id, message);
  120. }
  121. // We don't know ahead of time whether these values are instances of Integer
  122. // or Double. This code is compatible with both.
  123. private static int mongoGetInt(Document document, String key) {
  124. return ((Number) document.get(key)).intValue();
  125. }
  126. }