/* * 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.weaver.utils; import java.util.ArrayList; import java.util.Hashtable; import java.util.LinkedList; import java.util.List; import java.util.Queue; import java.util.Stack; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import t2ext.xml.XMLBuilder; /** * The CUT does a new WeaverMethods() call at initialisation (inserted by the weaver) * * @author Maaike Gerritsen */ public class WeaverMethods { private Hashtable>> _collected = new Hashtable>>(); private Hashtable _endMethods = new Hashtable(); private Hashtable _pathsToFind = new Hashtable(); private static final int NotFound = 0; private static final int Found = 1; private static final int FoundWithSideTrip = 2; public void startPathList(String name) { if (_collected == null) _collected = new Hashtable>>(); Stack> stack = _collected.get(name); if (stack == null) stack = new Stack>(); stack.add(new ArrayList()); _collected.put(name, stack); } public void getPathToFindFromXML(String longName) { String name = getOfficialMethodName(longName); if (_pathsToFind == null) _pathsToFind = new Hashtable(); String path = getPathToFind(name); if (path != null) _pathsToFind.put(name, path); } @SuppressWarnings("unchecked") private String getPathToFind(String name) { XMLBuilder builder = new XMLBuilder(); Document doc = builder.readXMLFile("paths.xml"); String condition = "//method[@official='" + name + "']"; NodeList methods = builder.getNodesFromXML(doc, condition); Element method = (Element) methods.item(0); String pathToFind = method.getAttribute("pathtofind"); return pathToFind; } public boolean findPath(String longName) { String name = getOfficialMethodName(longName); Boolean allowContinue = _endMethods.get(name); if (allowContinue != null) { return allowContinue.booleanValue(); } return true; } public void addToList(String name, Integer id) { Stack> stack = _collected.get(name); stack.peek().add(id); } public void checkList(String name, String parentName) { if (_endMethods == null) _endMethods = new Hashtable(); Stack> stack = _collected.get(name); boolean allowContinue = true; if (stack != null) { List list = stack.peek(); if (list != null) { String stringList = list.toString(); String pathToFind = _pathsToFind.get(parentName); if (pathToFind != null && !stringList.contains(pathToFind)) allowContinue = false; } } _endMethods.put(parentName, allowContinue); } public List getCompletePathList(String name) { Stack> stack = _collected.get(name); return stack.pop(); } public static String getOfficialMethodName(String longName) { String[] split = longName.split(" "); String name = ""; if (split.length > 2) { for (int i = 2; i < split.length; i++) name = name + split[i] + " "; name = name.trim(); name = name.substring(0, name.length() - 1); } else name = split[0]; return name; } @SuppressWarnings("unchecked") public static void findPath(String longName, List list) { longName = getOfficialMethodName(longName); XMLBuilder builder = new XMLBuilder(); Document doc = builder.readXMLFile("paths.xml"); String condition = "//method[@official='" + longName + "']"; Element method = builder.getNodeFromXML(doc, condition); if (method!=null && method.getChildNodes().getLength()>0) { NodeList paths = method.getChildNodes(); String pathsIDs = ""; for (int i = 0; i < paths.getLength(); i++) { Element path = (Element) paths.item(i); String id = path.getAttribute("id"); if (paths.getLength() == 1) path.setAttribute("found", "true"); else { int found = checkPath(list, path); if (found == Found) { path.setAttribute("found", "true"); if (pathsIDs.equals("")) pathsIDs = id; else pathsIDs = pathsIDs + "," + id; } else if (found == FoundWithSideTrip) path.setAttribute("foundws", "true"); } } method.setAttribute("lastfound", pathsIDs); builder.writeToFile(doc, "paths.xml"); } } // @SuppressWarnings("unchecked") // private static List getOwnLoopIds(XMLElement method) { // List list = new ArrayList(); // Enumeration paths = method.enumerateChildren(); // while (paths.hasMoreElements()) { // XMLElement path = paths.nextElement(); // Vector nodes = path.getChildren(); // if (nodes.size() == 2) { // int firstValue = Integer.parseInt(nodes.get(0).getAttribute( // "value").toString()); // int lastValue = Integer.parseInt(nodes.get(1).getAttribute( // "value").toString()); // if (firstValue == lastValue) // list.add(firstValue); // } // } // return list; // } /** * * @param list * The list of branches found while executing * @param path * The path to be checked against * @return */ @SuppressWarnings("unchecked") private static int checkPath(List list, Element path) { Element nodes = (Element) path.getChildNodes().item(0); String pathToFind = nodes.getAttribute("value").toString(); String[] split = pathToFind.split(", "); String pathList = list.toString(); if (pathList.contains(pathToFind)) return Found; // check if it will be found with sidetrips return checkForSideTrips(createQueueFromArray(split), list); } private static int checkForSideTrips(Queue fQueue, List list) { Queue queue = createQueueFromList(list); while (!queue.isEmpty()) { String edge = queue.poll(); String fEdge = fQueue.peek(); if (edge.equals(fEdge)) fQueue.poll(); if (fQueue.isEmpty()) return FoundWithSideTrip; } return NotFound; } private static Queue createQueueFromList(List list) { Queue queue = new LinkedList(); for (int i = 0; i < list.size() - 1; i++) { String id = list.get(i).toString(); String nextId = list.get(i + 1).toString(); id += "," + nextId; queue.add(id); } return queue; } private static Queue createQueueFromArray(String[] split) { Queue queue = new LinkedList(); for (int i = 0; i < split.length - 1; i++) { String id = split[i]; String nextId = split[i + 1]; id += "," + nextId; queue.add(id); } return queue; } // private static Hashtable> extractDuplicates( // List list, List ownLoops) { // List newList = new ArrayList(); // Set foundLoops = new TreeSet(); // int lastId = -1; // for (Iterator iterator = list.iterator(); iterator.hasNext();) { // Integer id = iterator.next(); // if (!ownLoops.contains(id) && id.intValue() != lastId) { // newList.add(id); // } else if (ownLoops.contains(id) && id.intValue() != lastId) // newList.add(id); // else // foundLoops.add(id); // lastId = id; // } // Hashtable> table = new Hashtable>(); // table.put(0, newList); // table.put(1, new ArrayList(foundLoops)); // return table; // } public static int getIdFromMethodName(String methodName) { int id1 = methodName.indexOf("_id"); int id2 = methodName.lastIndexOf("_id"); if (id2 > id1) { String id = methodName.substring(id1 + 3, id2); try { int convertedId = Integer.parseInt(id); return convertedId; } catch (Exception e) { } } return -1; } }