package de.ugoe.cs.eventbench; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.security.InvalidParameterException; import java.util.LinkedList; import java.util.List; import java.util.SortedMap; import java.util.TreeMap; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.helpers.DefaultHandler; import de.ugoe.cs.eventbench.data.Event; import de.ugoe.cs.eventbench.data.WindowTree; import de.ugoe.cs.eventbench.data.WindowsMessage; import de.ugoe.cs.eventbench.messagehandler.HandlerCreate; import de.ugoe.cs.eventbench.messagehandler.HandlerDestroy; import de.ugoe.cs.eventbench.messagehandler.HandlerSetText; import de.ugoe.cs.eventbench.messagehandler.MessageHandler; import de.ugoe.cs.eventbench.windowsdefs.MessageDefs; import de.ugoe.cs.util.StringTools; import de.ugoe.cs.util.console.Console; public class LogParser extends DefaultHandler { private MessageHandler currentHandler; private WindowsMessage currentMessage; private SequenceSplitter sequenceSplitter; private List>> sequences; private SortedMap typeCounter; private boolean countMessageOccurences; public LogParser() { this(false); } public LogParser(boolean countMessageOccurences) { sequenceSplitter = new SequenceSplitter(); sequences = new LinkedList>>(); currentHandler = null; this.countMessageOccurences = countMessageOccurences; if( countMessageOccurences) { typeCounter = new TreeMap(); } } public List>> getSequences() { return sequences; } @Override public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { if( qName.equals("session") ) { Console.traceln("start of session"); sequenceSplitter = new SequenceSplitter(); } else if( qName.equals("msg") ) { String msgType = atts.getValue("type"); int msgInt = -1; try { msgInt = Integer.parseInt(msgType); if( countMessageOccurences ) { Integer currentCount = typeCounter.get(msgInt); if( currentCount==null ) { typeCounter.put(msgInt, 1); } else { typeCounter.put(msgInt, currentCount+1); } } if( msgInt==MessageDefs.WM_CREATE ) { currentHandler = new HandlerCreate(); currentHandler.onStartElement(); } else if( msgInt==MessageDefs.WM_DESTROY ) { currentHandler = new HandlerDestroy(); currentHandler.onStartElement(); } else if( msgInt==MessageDefs.WM_SETTEXT ) { currentHandler = new HandlerSetText(); currentHandler.onStartElement(); } else { currentMessage = new WindowsMessage(msgInt); } } catch(NumberFormatException e) { Console.printerrln("Invalid message type: type not a number"); e.printStackTrace(); } } else if( qName.equals("param") ) { if( currentHandler!=null ) { currentHandler.onParameter(atts.getValue("name"), atts.getValue("value")); } else { currentMessage.addParameter(atts.getValue("name"), atts.getValue("value")); } } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if( qName.equals("msg") ) { if( currentHandler!=null ) { currentHandler.onEndElement(); currentHandler = null; } else { try { currentMessage.setTarget(WindowTree.getInstance()); sequenceSplitter.addMessage(currentMessage); } catch (InvalidParameterException e) { Console.traceln(e.getMessage() + " WindowsMessage " + currentMessage + " ignored."); } } } else if(qName.equals("session")) { sequenceSplitter.endSession(); sequences.add(sequenceSplitter.getSequence()); Console.traceln("end of session"); } } public void parseFile(String filename) { if( filename==null ) { throw new InvalidParameterException("filename must not be null"); } SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setValidating(true); SAXParser saxParser = null; InputSource inputSource = null; try { saxParser = spf.newSAXParser(); inputSource = new InputSource(new InputStreamReader(new FileInputStream(filename), "UTF-16")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } if( inputSource!=null ) { inputSource.setSystemId("file://" + new File(filename).getAbsolutePath()); try { if( saxParser==null) { throw new RuntimeException("SAXParser creation failed"); } saxParser.parse(inputSource, this); } catch (SAXParseException e) { Console.printerrln("Failure parsing file in line " + e.getLineNumber() + ", column " + e.getColumnNumber() +"."); e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } if( countMessageOccurences ) { Console.println("Message statistics:"); Console.println(typeCounter.toString().replace(" ", StringTools.ENDLINE).replaceAll("[\\{\\}]","")); } } }