Экзаменационная работа

Работающий пример
Полные исходные коды сервера

Код сервлета для генерации XML-контента для регламентной сводки:

package ru.chermenin.servlet;
 
import ru.chermenin.jdbc.Database;
import ru.chermenin.jdbc.QueryResult;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
 
/**
 * Servlet to generate XML structure by request with parameters.
 */
public class ThirteenServlet extends HttpServlet {
 
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 
        // Get parameters
        String level = request.getParameterMap().containsKey("pLev") ? request.getParameter("pLev") : "1";
        String number = request.getParameterMap().containsKey("pNumber") ? request.getParameter("pNumber") : "0111";
        String h = request.getParameterMap().containsKey("pH") ? request.getParameter("pH") : "h2";
        String start = request.getParameterMap().containsKey("pStart") ? request.getParameter("pStart") : "201012240000";
        String stop = request.getParameterMap().containsKey("pStop") ? request.getParameter("pStop") : "201012242300";
 
        // Set headers
        response.setContentType("application/xml");
        response.setStatus(HttpServletResponse.SC_OK);
        response.setCharacterEncoding("UTF-8");
 
        // Write XML header
        PrintWriter w = response.getWriter();
        w.println("<?xml version='1.0' encoding='UTF-8'?>");
        w.println(String.format("<ROWSET pLev=\"%s\" pNumber=\"%s\" pH=\"%s\" pStart=\"%s\" pStop=\"%s\">", level, number, h, start, stop));
 
        try {
            // Get content
            Database db = new Database("jdbc:mysql://54.208.78.75/airs", "userairs", "userairs");
            QueryResult results = db.query(String.format("SELECT level, number, name, descr, content1 FROM reports1 WHERE lev=%s AND number='%s'  ORDER BY number", level, number));
            ArrayList<String> codes = new ArrayList<>();
 
            if (results.getRows().size() == 1) {
                ArrayList<String> fields = results.getRows().get(0).getFields();
                w.println(String.format("<content1 level=\"%s\" number=\"%s\" name=\"%s\" descr=\"%s\">",
                        fields.get(0), // level
                        fields.get(1), // number
                        fields.get(2), // name
                        fields.get(3)) // description
                );
 
                String content = fields.get(4);
                w.println("<![CDATA[\n" + content + "\n]]>");
 
                // Parse content
                String[] items = (content + ";end;").split(";");
                int count = items.length / 11;
                for (int i = 0; i < count; i++) {
                    codes.add(items[11 * i + 1]);
                    w.println(String.format("" +
                            "<signal%d ord='%s' code='%s' nserv='%s' decp='%s' value='%s' total='%s' type='%s' >\n" +
                            "<name><![CDATA[%s]]></name>\n<unit><![CDATA[%s]]></unit>\n<scale><![CDATA[%s]]></scale>\n</signal%d>",
                            i,                  // row number
                            items[11 * i],      // ord
                            items[11 * i + 1],  // code
                            items[11 * i + 4],  // nserv
                            items[11 * i + 6],  // decp
                            items[11 * i + 8],  // value
                            items[11 * i + 9],  // total
                            items[11 * i + 10], // type
                            items[11 * i + 2],  // name
                            items[11 * i + 3],  // unit
                            items[11 * i + 7],  // scale
                            i                   // end row number
                    ));
                }
                w.println("</content1>");
            }
 
            // Prepare signals map
            TreeMap<String, String[]> signals = new TreeMap<>();
 
            DateFormat format = new SimpleDateFormat("yyyyMMddHHmm");
            Date startDate = format.parse(start);
            Date stopDate = format.parse(stop);
            GregorianCalendar calendar = new GregorianCalendar();
            calendar.setTime(startDate);
 
            while (calendar.getTime().before(stopDate) || calendar.getTime().equals(stopDate)) {
                signals.put(format.format(calendar.getTime()), new String[] {
                        new SimpleDateFormat("dd/HH").format(calendar.getTime()),
                        "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-"
                });
                calendar.add(Calendar.HOUR, 1);
            }
 
            // Fill signals map
            results = db.query(String.format("SELECT tstamp, code, a_val FROM %s WHERE code IN (%s) AND tstamp BETWEEN %s AND %s", 
                    h, String.format("'%s'", String.join("','", codes)), start, stop));
            results.getRows().stream().filter(row -> codes.contains(row.getFields().get(1)))
                    .forEach(row -> signals.get(row.getFields().get(0))[codes.indexOf(row.getFields().get(1)) + 1] = row.getFields().get(2));
 
            // Print signals map
            signals.forEach((s, ss) -> w.println(String.format("<ROW tstamp=\"%s\" %s />", s,
                    IntStream.range(0, ss.length)
                            .mapToObj(
                                    i -> i == 0
                                            ? String.format("time=\"%s\" ", ss[0])
                                            : String.format("val%d=\"%s\" ", i - 1, ss[i]))
                            .collect(Collectors.joining(" ")))));
 
            w.println("</ROWSET>");
 
        } catch (Exception e) {
            w.println("<error>" + e.getMessage() + "</error>");
        }
 
    }
}