Package so.tio.inlearn.server.session

Source Code of so.tio.inlearn.server.session.Session$SessionCallback

package so.tio.inlearn.server.session;

import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import so.tio.inlearn.common.testing.TaskItem;
import so.tio.inlearn.common.testing.TestItem;
import so.tio.inlearn.common.testing.TestVariant;
import so.tio.inlearn.common.utils.XmlTools;
import so.tio.inlearn.server.testing.TestsFacility;

public class Session {
    private User user = new User();
    private long[] availableTests;
    private long[] testsTimeOut;
    private TestAnswersHandler answers = null;
    private long inTest = 0; // TODO: When testing done set to 0 again
    private SessionCallback cb = new SessionCallback();

    public Session(long[] availableTests, long[] testsTimeOut) {
        this.availableTests = availableTests;
        this.testsTimeOut = testsTimeOut;
    }

    public void setSessionCallback(SessionCallback cb) {
        this.cb = cb;
    }

    public long isInTest() {
        return inTest;
    }

    private String buildResponsePacket(Map<String, String> params) {
        Document doc = XmlTools.getDocBuilder().newDocument();
        Element root = doc.createElement("response");
        for (Entry<String, String> param : params.entrySet()) {
            root.setAttribute(param.getKey(), param.getValue());
        }
        doc.appendChild(root);
        return XmlTools.docToString(doc);
    }

    private String buildErrorPacket(String msg) {
        Map<String, String> params = new HashMap<String, String>();
        params.put("type", "error");
        params.put("message", msg);
        return buildResponsePacket(params);
    }

    private String parseAuth(Node xmlNode) {
        NamedNodeMap attrs = xmlNode.getAttributes();
        try {
            Map<String, String> got = new HashMap<String, String>();
            try {
                // Pass all params into map
                for (String key : new String[] { "firstName", "lastName", "imei", "phoneNumber" }) {
                    got.put(key, attrs.getNamedItem(key).getNodeValue());
                }
            } catch (NullPointerException e) {
                throw new IOException("Not enough params");
            }
            // Check mandatory params in map
            if (got.get("firstName").isEmpty() || got.get("lastName").isEmpty() || got.get("imei").isEmpty()) {
                throw new IOException("Not enough information in params");
            }
            // Creating user
            user.setFirstName(got.get("firstName"));
            user.setLastName(got.get("lastName"));
            user.setImei(got.get("imei"));
            user.setPhoneNumber(got.get("phoneNumber"));
            user.setAuthed(true);
            System.out.println("Authed: " + user);
            // Responding: auth ok
            Map<String, String> params = new HashMap<String, String>();
            params.put("type", "auth");
            params.put("message", "ok");
            return buildResponsePacket(params);
        } catch (DOMException | NullPointerException | IOException e) {
            System.out.println("Auth rejected. " + e.getMessage());
            return buildErrorPacket("Auth rejected. " + e.getMessage());
        }
    }

    private String parseTestsList(Node xmlNode) {
        if (!user.isAuthed()) {
            return buildErrorPacket("Not authorized");
        }
        // Show only selected tests
        List<TestItem> tests = new ArrayList<TestItem>();
        int availTestId = 0;
        for (TestItem test : TestsFacility.getTests()) {
            if (isTestAvailable(test.getTestId())) {
                test.setTimeOut(testsTimeOut[availTestId++]);
                tests.add(test);
            }
        }
        Document answerDoc = XmlTools.getDocBuilder().newDocument();
        Element answerRoot = answerDoc.createElement("response");
        answerRoot.setAttribute("type", "testsList");
        for (TestItem test : tests) {
            Element answerItem = answerDoc.createElement("test");
            answerItem.setAttribute("name", test.getName());
            answerItem.setAttribute("maximumMark", String.valueOf(test.getMaximumMark()));
            answerItem.setAttribute("id", String.valueOf(test.getTestId()));
            answerItem.setAttribute("timeOut", String.valueOf(test.getTimeOut()));

            answerRoot.appendChild(answerItem);
        }
        answerDoc.appendChild(answerRoot);
        return XmlTools.docToString(answerDoc);
    }

    private String parseTest(Node xmlNode) {
        if (!user.isAuthed()) {
            return buildErrorPacket("Not authorized");
        }
        if (inTest != 0) {
            return buildErrorPacket("You can't do more than 1 test at once");
        }
        NamedNodeMap requestAttrs = xmlNode.getAttributes();
        try {
            long testId = Long.parseLong(requestAttrs.getNamedItem("id").getNodeValue());
            if (!isTestAvailable(testId)) {
                return buildErrorPacket("Test is not available now");
            }
            TestVariant variant = TestsFacility.getTestVariant(testId, user.toString());
            if (variant == null) {
                return buildErrorPacket("Test doesn't exist");
            }
            Document answerDoc = XmlTools.getDocBuilder().newDocument();
            Element answerRoot = answerDoc.createElement("response");
            answerRoot.setAttribute("type", "test");
            answerRoot.setAttribute("testId", String.valueOf(variant.getTestId()));
            answerRoot.setAttribute("testName", variant.getName());
            answerRoot.setAttribute("maximumMark", String.valueOf(variant.getMaximumMark()));
            answerRoot.setAttribute("variantId", String.valueOf(variant.getVariantId()));
            answerRoot.setAttribute("timeOut", String.valueOf(variant.getTimeOut()));
            for (TaskItem item : variant.getTasks()) {
                Element taskItem = answerDoc.createElement("task");
                taskItem.setAttribute("cost", String.valueOf(item.getCost()));

                taskItem.setAttribute("taskId", String.valueOf(item.getTaskId()));

                Element taskItemQuestion = answerDoc.createElement("question");
                taskItemQuestion.appendChild(answerDoc.createCDATASection(item.getQuestion()));
                taskItem.appendChild(taskItemQuestion);

                Element taskItemAnswerForm = answerDoc.createElement("answerForm");
                taskItemAnswerForm.appendChild(answerDoc.createCDATASection(item.getAnswerForm()));
                taskItem.appendChild(taskItemAnswerForm);

                answerRoot.appendChild(taskItem);
            }
            answerDoc.appendChild(answerRoot);
            inTest = variant.getTestId();
            if(answers == null){
                answers = new TestAnswersHandler(TestsFacility.getTestVariant(testId, user.toString()));
            }
            cb.onClientStartTesting(variant.getTestId());
            return XmlTools.docToString(answerDoc);

        } catch (DOMException | NullPointerException | NumberFormatException e) {
            System.out.println("Wrong test request " + e.getMessage());
            return buildErrorPacket("Wrong test request.");
        }
    }

    public String parseTestAnswer(Node xmlNode) {
        if (!user.isAuthed()) {
            return buildErrorPacket("Not authorized");
        }
        if (inTest == 0) {
            return buildErrorPacket("You should start testing before posting answers.");
        }
        NamedNodeMap requestAttrs = xmlNode.getAttributes();

        long testId = Long.parseLong(requestAttrs.getNamedItem("testId").getNodeValue());
        if (!isTestAvailable(testId)) {
            return buildErrorPacket("Test is not available now");
        }
        if (!TestsFacility.variantExist(testId, user.toString())) {
            return buildErrorPacket("Variant is not generated yet. Maybe you not requested test?");
        }
        long taskId = Long.parseLong(requestAttrs.getNamedItem("taskId").getNodeValue());
        String rawAnswers = requestAttrs.getNamedItem("answers").getNodeValue();
        answers.putAnswers(taskId, getQueryParams(rawAnswers));
        System.out.print("task " + taskId + " is: " + answers.isTaskValid(taskId) + "\n");
        return buildErrorPacket("Not implemented yet.");
    }

    public String parseEndTest(Node xmlNode) {
        Map<String, String> params = new HashMap<String, String>();
        params.put("type", "endtest");
        params.put("message", "ok");
        System.out.println("testing done");
        cb.onClientDoneTesting(user, answers);
        return buildResponsePacket(params);
    }
    public String parseRequest(String request) {
        try {
            Document doc = XmlTools.getDocBuilder().parse(new InputSource(new StringReader(request)));
            Node root = doc.getDocumentElement();
            if (root.getNodeName().toLowerCase().equals("request")) {
                NamedNodeMap attrs = root.getAttributes();
                String requestType;
                try {
                    requestType = attrs.getNamedItem("type").getNodeValue();
                } catch (DOMException | NullPointerException e) {
                    return buildErrorPacket("Can't recognize request");
                }
                switch (requestType.toLowerCase()) {
                case "auth":
                    return parseAuth(root);
                case "testslist":
                    return parseTestsList(root);
                case "test":
                    return parseTest(root);
                case "postanswer":
                    return parseTestAnswer(root);
                case "endtest":
                    return parseEndTest(root);
                default:
                    return buildErrorPacket("Unknown request type");
                }
            } else {
                return buildErrorPacket("Can't recognize packet");
            }
        } catch (IOException e) {
            e.printStackTrace();
            return buildErrorPacket("Unknown error");
        } catch (SAXException e) {
            return buildErrorPacket("Can't parse XML");
        }
    }

    private boolean isTestAvailable(long testId) {
        for (long id : availableTests) {
            if (testId == id)
                return true;
        }
        return false;
    }

    public static class SessionCallback {
        public void onClientConnected() {
            System.out.println("Session.SessionCallback.onClientConnected()");
        }

        public void onClientDisconnected() {
            System.out.println("Session.SessionCallback.onClientDisconnected()");
        }

        public void onClientStartTesting(long testId) {
            System.out.println("Session.SessionCallback.onClientStartTesting()");
        }

        public void onClientDoneTesting(User user, TestAnswersHandler handler) {
            System.out.println("Session.SessionCallback.onClientDoneTesting()");
        }
    }
    public static Map<String, List<String>> getQueryParams(String url) {
        try {
            Map<String, List<String>> params = new HashMap<String, List<String>>();
                String query = url;
                for (String param : query.split("&")) {
                    String[] pair = param.split("=");
                    String key = URLDecoder.decode(pair[0], "UTF-8");
                    String value = "";
                    if (pair.length > 1) {
                        value = URLDecoder.decode(pair[1], "UTF-8");
                    }

                    List<String> values = params.get(key);
                    if (values == null) {
                        values = new ArrayList<String>();
                        params.put(key, values);
                    }
                    values.add(value);
                }

            return params;
        } catch (UnsupportedEncodingException ex) {
            throw new AssertionError(ex);
        }
    }
}
TOP

Related Classes of so.tio.inlearn.server.session.Session$SessionCallback

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.