/* * Copyright 2008 Wishnu Prasetya. * * This file is part of T2. * T2 is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License (GPL) as published by the * Free Software Foundation; either version 3 of the License, or any * later version. * * T2 is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * A copy of the GNU General Public License can be found in T2 distribution. * If it is missing, see http://www.gnu.org/licenses. */ package t2ext.trace; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Hashtable; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import t2ext.trace.utils.TraceAnalysis; import t2ext.util.Util; import t2ext.xml.XMLBuilder; import Sequenic.T2.Pool; import Sequenic.T2.TrFile; import Sequenic.T2.Engines.BaseEngine; import Sequenic.T2.Engines.Replay; import Sequenic.T2.Seq.CALL_METHOD; import Sequenic.T2.Seq.ExecResult; import Sequenic.T2.Seq.Trace; import Sequenic.T2.Seq.TraceSetExecInfo; import Sequenic.T2.Seq.TraceStep; /** * @author Maaike Gerritsen */ public class TraceAnalyser { private Pool _pool; private TrFile _trFile; private LinkedList _list; private XMLBuilder _xmlBuilder; private List _originalMethodNames; private List _specNames; private Hashtable> _methodToTraces; private List _analysedTraces; private BaseEngine _baseEngine; public TraceAnalyser(TrFile trFile, BaseEngine baseEngine) { _trFile = trFile; setupPool(); _list = _trFile.traces; _xmlBuilder = new XMLBuilder(); _analysedTraces = new ArrayList(); setMethodsToTraces(); setOriginalMethodNames(); _baseEngine = baseEngine; } @SuppressWarnings("unchecked") private void setOriginalMethodNames() { _originalMethodNames = new ArrayList(); _specNames = new ArrayList(); Document doc = _xmlBuilder.readXMLFile("classInfo.xml"); NodeList list = doc.getChildNodes(); Element root = (Element) list.item(0); String total = ""; String className = root.getAttribute("name").toString(); total += className + "."; NodeList methods = root.getChildNodes(); for (int a = 0; a < methods.getLength(); a++) { Element method = (Element) methods.item(a); String name = method.getAttribute("name").toString(); total += name + "("; NodeList arguments = method.getChildNodes(); for (int i = 0; i < arguments.getLength(); i++) { Element arg = (Element) arguments.item(i); total += arg.getAttribute("name").toString(); if (i != arguments.getLength() - 1) total += ", "; } total += ")"; _originalMethodNames.add(total); if (total.contains("_spec")) { total = total.replace("_spec", ""); _specNames.add(total); } total = className + "."; } } @SuppressWarnings("unchecked") private void setMethodsToTraces() { _methodToTraces = new Hashtable>(); Document doc = _xmlBuilder.readXMLFile("paths.xml"); NodeList nodeList = doc.getChildNodes(); Element root = (Element) nodeList.item(0); NodeList methods = root.getChildNodes(); for (int i = 0; i < methods.getLength(); i++) { Element method = (Element) methods.item(i); if (method.getChildNodes().getLength() > 0) { List list = new ArrayList(); String name = method.getAttribute("official").toString(); _methodToTraces.put(name, list); } } } public Hashtable> analyseTraces() throws InvocationTargetException { int counter = 0; for (ListIterator iterator = _list.listIterator(); iterator .hasNext();) { Trace trace = iterator.next(); LinkedList steps = trace.trace; TraceSetExecInfo info = new TraceSetExecInfo(); info.time = System.currentTimeMillis(); _pool.reset(); ExecResult stepResult = trace.creation.MkTargetObject( _baseEngine.CUT, _pool, _baseEngine.allClassINVs); Object targetObj = _pool.get(trace.indexOfTargetObj); TraceAnalysis trAnalysis = new TraceAnalysis(trace); trAnalysis.setPool(_pool); trAnalysis.setTargetObj(targetObj); trAnalysis.setFields(_baseEngine.fieldsIPs); if (stepResult.isAsmOrReqViolating()) System.out.println("PROBLEM creating target object"); for (int i = 0; i < steps.size(); i++) { TraceStep traceStep = steps.get(i); // if(traceStep.getName().contains("remove")) // System.out.println("step name: " + traceStep.getName()); String methodName = getMethodName(traceStep); trAnalysis.addToSteps(traceStep, methodName, _pool); stepResult = traceStep.exec(_baseEngine.CUT, _pool, targetObj, i, _baseEngine.allClassINVs); Hashtable> table = getPaths(methodName); List pathIds = table.get(0); List specPathIds = table.get(1); // System.out.println("list: "+pathIds); trAnalysis .setPathsForLastStep(pathIds, methodName, specPathIds); addToMethodToTraces(methodName, trAnalysis); if (stepResult.isAsmOrReqViolating()) System.out.println("Violating trace found..."); } _analysedTraces.add(trAnalysis); counter++; } // System.out.println("traces: " + counter); // Enumeration keys = _methodToTraces.keys(); // while (keys.hasMoreElements()) { // String key = keys.nextElement(); // System.out.println("+++++++++++++++"); // System.out.println(key); // System.out.println(_methodToTraces.get(key).size()); // } return _methodToTraces; } public List getSpecNames() { return _specNames; } private void addToMethodToTraces(String methodName, TraceAnalysis trAnalysis) { if (!"".equals(methodName) && _originalMethodNames.contains(methodName)) { List list = _methodToTraces.get(methodName); if (list != null && list.indexOf(trAnalysis) == -1) { list.add(trAnalysis); _methodToTraces.put(methodName, list); } } } private Hashtable> getPaths(String methodName) { Hashtable> table = new Hashtable>(); List list = new ArrayList(); List specList = new ArrayList(); String newSpecName = ""; if (methodName.contains("_spec")) newSpecName = methodName.replace("_spec", ""); if (!"".equals(methodName) && _originalMethodNames.contains(methodName)) { Document doc = _xmlBuilder.readXMLFile("paths.xml"); String condition = "//method[@official='" + methodName + "']"; NodeList methods = _xmlBuilder.getNodesFromXML(doc, condition); if (methods.getLength() == 1) { Element method = (Element) methods.item(0); String lastFound = method.getAttribute("lastfound"); if (lastFound != null && !"".equals(lastFound)) { String[] split = lastFound.split(","); for (int j = 0; j < split.length; j++) list.add(new Integer(split[j])); } } condition = "//method[@official='" + newSpecName + "']"; methods = _xmlBuilder.getNodesFromXML(doc, condition); if (methods.getLength() == 1) { Element method = (Element) methods.item(0); String lastFound = method.getAttribute("lastfound").toString(); if (lastFound != null && !"".equals(lastFound)) { String[] split = lastFound.split(","); for (int j = 0; j < split.length; j++) { specList.add(new Integer(split[j])); } } } } table.put(0, list); table.put(1, specList); return table; } private String getMethodName(TraceStep traceStep) { String result = ""; if (traceStep instanceof CALL_METHOD) { CALL_METHOD callMethod = (CALL_METHOD) traceStep; Method method = callMethod.method; String className = method.getDeclaringClass().getName(); result = Util.officialMethodName(className, method.getName(), method.getGenericParameterTypes()); } return result; } private void setupPool() { _pool = (Pool) Replay.mkAnInstance(_trFile.poolClassName); if (_pool == null) System.err.println("NO POOL FOUND"); } public List getAnalysisForMethod(String name) { return _methodToTraces.get(name); } }