source: other-projects/the-macronizer/trunk/src/java/web/servlets/DirectInput.java@ 35719

Last change on this file since 35719 was 35719, checked in by cstephen, 2 years ago

Add support for JSON response to direct input queries. Cleanup other components.

File size: 9.2 KB
Line 
1package web.servlets;
2
3import java.io.BufferedReader;
4import java.io.BufferedWriter;
5import java.io.File;
6import java.io.FileInputStream;
7import java.io.FileOutputStream;
8import java.io.IOException;
9import java.io.InputStreamReader;
10import java.io.OutputStreamWriter;
11import java.io.UnsupportedEncodingException;
12
13import javax.servlet.RequestDispatcher;
14import javax.servlet.ServletConfig;
15import javax.servlet.ServletException;
16import javax.servlet.http.HttpServlet;
17import javax.servlet.http.HttpServletRequest;
18import javax.servlet.http.HttpServletResponse;
19
20import com.google.gson.Gson;
21import com.google.gson.stream.JsonWriter;
22
23import monogram.plugin.PluginConfiguration;
24import monogram.plugin.PluginManager;
25
26import org.apache.log4j.*;
27
28import util.FileUtil;
29import util.IOUtil;
30
31/**
32 * Represents a servlet for macronising direct text input.
33 * @author OEM
34 * @version 2.0
35 */
36public class DirectInput extends HttpServlet
37{
38 private static final String UTF8_ENCODING = "utf-8";
39
40 //Create an instance of the logger object defined for this class in log4j.properties
41 private static final Logger logger = Logger.getLogger(web.servlets.DirectInput.class.getName());
42
43 private final Gson gsonInstance = new Gson();
44
45 private File tmpdir;
46 private PluginManager pluginManager;
47
48 @Override
49 public void init(ServletConfig config) throws ServletException
50 {
51 super.init(config);
52
53 tmpdir = new File((String) config.getServletContext().getAttribute("tmpdir"));
54 pluginManager = new PluginManager(tmpdir);
55 }
56
57 /**
58 * Handles the HTTP <code>GET</code> method.
59 * @param request The servlet request.
60 * @param response The servlet response.
61 * @throws IllegalStateException if a reponse has already been committed.
62 * @throws IOException if an I/O error occurs.
63 */
64 @Override
65 protected void doGet(HttpServletRequest request, HttpServletResponse response)
66 throws IllegalStateException, IOException
67 {
68 response.sendError(405); // 405 Method Not Allowed
69 }
70
71 /**
72 * Handles the HTTP <code>POST</code> method.
73 * @param request The servlet request.
74 * @param response The servlet response.
75 * @throws IllegalStateException if a response has already been committed.
76 * @throws IOException if an I/O error occurs.
77 * @throws ServletException if a servlet-specific error occurs.
78 * @throws UnsupportedEncodingException if the selected encoding is not supported.
79 */
80 @Override
81 protected void doPost(HttpServletRequest request, HttpServletResponse response)
82 throws IllegalStateException, IOException, ServletException, UnsupportedEncodingException
83 {
84 request.setCharacterEncoding(UTF8_ENCODING);
85
86 final String fragment = request.getParameter("fragment");
87 final Boolean showAdvancedOptions = request.getParameter("options") != null && request.getParameter("options").equals("true");
88 final Boolean shouldPreserveMacrons = request.getParameter("preserveExistingMacrons") != null && request.getParameter("preserveExistingMacrons").equals("true");
89 final OutputType outputType = OutputType.parse(request.getParameter("o"));
90
91 // Note that the lang parameter might be null if the request hasn't been made from an internal JSP page
92 final String lang = request.getParameter("lang");
93 final String forwardPath = lang != null ? "/jsp/" + lang : "/jsp/mi";
94
95 try
96 {
97 final String restoredFragment = restoreMacrons
98 (
99 fragment,
100 shouldPreserveMacrons,
101 true //outputType == OutputType.JspRedirect
102 );
103
104 if (outputType == OutputType.Json)
105 {
106 response.setContentType("application/json; charset=UTF-8");
107 JsonWriter writer = gsonInstance.newJsonWriter(response.getWriter());
108 writer.beginArray();
109
110 for (String element : restoredFragment.split("\\ "))
111 {
112 writer.beginObject();
113
114 if (element.contains("<mark>"))
115 {
116 element = element.replace("<mark>", "").replace("</mark>", "");
117 writer.name("macronised");
118 writer.value(true);
119 }
120
121 writer.name("w");
122 writer.value(element);
123
124 writer.endObject();
125 }
126
127 writer.endArray();
128 writer.flush();
129 }
130 else
131 {
132 request.setAttribute("fragment2", restoredFragment);
133 request.setAttribute("old", fragment);
134 request.setAttribute("options", showAdvancedOptions.toString());
135 request.setAttribute("preserveMacrons", shouldPreserveMacrons.toString());
136
137 forward(forwardPath + "/main.jsp", request, response);
138 }
139
140 logger.info("Macron restoration succeeded. Input: " + fragment + " | Output: " + restoredFragment);
141 }
142 catch (Exception ex)
143 {
144 ex.printStackTrace();
145 logger.error("Failed to restore macrons", ex);
146
147 switch (outputType) {
148 case Json:
149 // 500 Internal Server Error
150 response.sendError(500, "An unexpected error has occurred. Please try again or contact the web administrator if the problem persists.");
151 break;
152 default:
153 request.setAttribute("errorMessage", "UNEXPECTED_ERROR");
154 forward(forwardPath + "/error.jsp", request, response);
155 break;
156 }
157 }
158 }
159
160 /**
161 * Restores macrons on an input fragment.
162 * @param input The input fragment to restore.
163 * @param preserveMacrons Indicates whether existing macrons on the input should be preserved.
164 * @return The macronised fragment.
165 * @throws IOException
166 * @throws UnsupportedOperationException
167 * @throws Exception
168 */
169 private String restoreMacrons(String input, boolean preserveMacrons, boolean markupChangedWords)
170 throws IOException, UnsupportedOperationException, Exception
171 {
172 //Write the input to a temporary file.
173 File inputFile = File.createTempFile(FileUtil.TMP_FILE_PREFIX, ".txt", tmpdir);
174 write(inputFile, UTF8_ENCODING, input);
175
176 //Create a fileview
177 PluginConfiguration configuration = new PluginConfiguration();
178 configuration.setFile(inputFile);
179 configuration.setCharsetEncoding(UTF8_ENCODING);
180 configuration.setFileType(".txt");
181 configuration.setPreserveExistingMacrons(preserveMacrons);
182 configuration.setMarkupChangedWords(markupChangedWords);
183
184 //Restore the file.
185 File restoredFile = null;
186
187 try
188 {
189 restoredFile = pluginManager.run(configuration);
190 return read(restoredFile, UTF8_ENCODING).trim();
191 }
192 finally
193 {
194 inputFile.delete();
195
196 if (restoredFile != null)
197 {
198 restoredFile.delete();
199 }
200 }
201 }
202
203 /**
204 * Forwards a request from a servlet to another resource on the server.
205 * @param path The path to forward to.
206 * @param request The servlet request.
207 * @param response The servlet response.
208 * @throws ServletException
209 * @throws IOException
210 */
211 private void forward(String path, HttpServletRequest request, HttpServletResponse response)
212 throws ServletException, IOException
213 {
214 final RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(path);
215 dispatcher.forward(request, response);
216 }
217
218 /**
219 * Writes the fragment to the file.
220 * @param file The file to write to.
221 * @param fragment The String to write to the file.
222 * @throws IOException
223 */
224 private void write(File file, String charsetEncoding, String fragment)
225 throws IOException
226 {
227 BufferedWriter out = null;
228 try
229 {
230 out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), charsetEncoding));
231 out.write(fragment);
232 }
233 finally
234 {
235 IOUtil.closeWriter(out);
236 }
237 }
238
239 /**
240 * Reads the contents of the file.
241 * @param file The file to read.
242 * @param charsetEncoding The character set encoding of the file.
243 * @return The contents of the file.
244 * @throws IOException
245 */
246 private String read(File file, String charsetEncoding)
247 throws IOException
248 {
249 final StringBuilder buffer = new StringBuilder();
250 BufferedReader reader = null;
251
252 try
253 {
254 reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), charsetEncoding));
255 final char[] chars = new char[1024];
256 int numRead = 0;
257
258 while ((numRead = reader.read(chars)) > -1)
259 {
260 buffer.append(String.valueOf(chars, 0, numRead));
261 }
262 }
263 finally
264 {
265 IOUtil.closeReader(reader);
266 }
267
268 return buffer.toString();
269 }
270}
Note: See TracBrowser for help on using the repository browser.