import java.io.File;           import java.io.FileInputStream;
import java.io.OutputStream;
import java.text.DateFormat;   import java.text.SimpleDateFormat;
import java.util.HashMap;      import java.util.Map;
import java.util.Iterator;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.events.XMLEvent;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.Characters;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;

// continue next page

public class ExamStreamParser {
  public static void main(String[] args) {
  try{
    FileInputStream in = new FileInputStream("exams.xml");
    OutputStream out = System.out;
    XMLInputFactory inputFactory = XMLInputFactory.newInstance();
    XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
    XMLEventReader parser = inputFactory.createXMLEventReader(in);
    XMLEventWriter writer = outputFactory.createXMLEventWriter(out);
    XMLEventFactory eventFactory = XMLEventFactory.newInstance();
    Map<String,Exam> exams = new HashMap<String,Exam>();
    boolean goOn = true;

    while (goOn) {
      XMLEvent event = parser.nextEvent();
      int eventtype = event.getEventType();
      switch(eventtype) {




      // continue next page

        case XMLStreamConstants.START_ELEMENT:
          StartElement ev = (StartElement)(event.asStartElement());
          if("start-registration".equals(ev.getName().getLocalPart())) {
            Exam exam = new Exam(ev);
            exams.put(exam.getId(), exam);
            Iterator<Attribute> attrs = ev.getAttributes();
            StartElement se = eventFactory.createStartElement("", null, "registration-opened", attrs, null);
            writer.add(se);
            writer.add(eventFactory.createEndElement("", null, "registration-opened"));
            writer.add(eventFactory.createCharacters("\n"));
          }
          else if("end-registration".equals(ev.getName().getLocalPart())) {
              String examId = ev.getAttributeByName(new QName("id")).getValue();
            Exam exam = exams.get(examId);
            if(exam == null) {
              System.err.println("no such exam with id '"+examId+"' open for registration!");
              break;
              }
            exam.setEndOfReg(Exam.getTodayDate());
            exam.setRegisteringClosed(true);
            }
          // continue next page

          else if("register".equals(ev.getName().getLocalPart())) {
            String studentId = ev.getAttributeByName(new QName("student")).getValue();
            String examId = ev.getAttributeByName(new QName("exam")).getValue();
            if(exams.containsKey(examId)) {
              Exam exam = exams.get(examId);
              if(! exam.isRegisteringClosed()) {
               StartElement se = eventFactory.createStartElement(
                    "", null, "valid-register", ev.getAttributes(), null);
                writer.add(se);
                writer.add(eventFactory.createEndElement("", null, "valid-register"));
                writer.add(eventFactory.createCharacters("\n"));
              }
              else {  //  exam.isRegisteringClosed()
                StartElement se = eventFactory.createStartElement(
                    "", null, "invalid-register", ev.getAttributes(), null);
                writer.add(se);
                writer.add(eventFactory.createCharacters("(reg. ended on " + exam.getEndOfReg() + ")"));
                writer.add(eventFactory.createEndElement(
                   "", null, "invalid-register"));
                writer.add(eventFactory.createCharacters("\n"));
              }
            }
            // continue next page

            else {  // not (exams.containsKey(examId))
              StartElement se = eventFactory.createStartElement(
                   "", null, "invalid-register", ev.getAttributes(), null);
              writer.add(se);
              writer.add(eventFactory.createCharacters("reg. for exam '"+examId+"' not open"));
              writer.add(eventFactory.createEndElement("", null, "invalid-register"));
              writer.add(eventFactory.createCharacters("\n"));
            }
          }
          break;
        case XMLStreamConstants.END_DOCUMENT:
           parser.close();
           writer.flush();
           writer.close();
           goOn = false;
           break;
     }
  }} catch (Exception e) { e.printStackTrace(); }
 }
}
