/******************************************************************************* * Copyright (c) 2014 Imperial College London * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Raul Castro Fernandez - initial API and implementation ******************************************************************************/ package uk.ac.imperial.lsds.java2sdg; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.logging.Logger; import soot.Body; import soot.Scene; import soot.SootClass; import soot.SootField; import soot.SootMethod; import soot.Type; import soot.Unit; import soot.Value; import soot.ValueBox; import soot.jimple.InvokeExpr; import soot.tagkit.Tag; import soot.toolkits.graph.ExceptionalUnitGraph; import soot.toolkits.graph.UnitGraph; import uk.ac.imperial.lsds.java2sdg.bricks.InternalStateRepr; public class Util { private final static Logger log = Logger.getLogger(Main.class.getCanonicalName()); private Util(){ } public static Map<String, InternalStateRepr> extractStateInformation(Iterator<SootField> fieldsIterator){ int seId = 0; Map<String, InternalStateRepr> stateElements = new HashMap<String, InternalStateRepr>(); while(fieldsIterator.hasNext()){ SootField field = fieldsIterator.next(); Type fieldType = field.getType(); SootClass sc = null; try{ sc = Scene.v().loadClassAndSupport(fieldType.toString()); } catch(RuntimeException re){ log.warning("Field: "+fieldType.toString()+" is not a valid class"); continue; } Tag annotationTag = field.getTag("VisibilityAnnotationTag"); if(annotationTag != null){ String rawAnnotationData = annotationTag.toString(); InternalStateRepr stateRepr = null; if(rawAnnotationData.contains("Partitioned")){ stateRepr = new InternalStateRepr(sc, InternalStateRepr.StateLabel.PARTITIONED, seId); seId++; } else if(rawAnnotationData.contains("Partial")){ stateRepr = new InternalStateRepr(sc, InternalStateRepr.StateLabel.PARTIAL, seId); seId++; } if(stateRepr != null){ stateElements.put(field.getName(), stateRepr); } } } return stateElements; } private static List<String> extractWorkflowsFromMainMethod(SootMethod sm, SootClass c){ List<String> workflowsNames = new ArrayList<String>(); UnitGraph cfg = Util.getCFGForMethod(sm.getName(), c); Iterator<Unit> units = cfg.iterator(); while(units.hasNext()){ Unit u = units.next(); Iterator<ValueBox> iValueBox = u.getUseBoxes().iterator(); while(iValueBox.hasNext()){ ValueBox valueBox = iValueBox.next(); Value v = valueBox.getValue(); if(v instanceof InvokeExpr){ InvokeExpr m = (InvokeExpr)v; SootMethod method = m.getMethod(); String methodName = method.getName(); workflowsNames.add(methodName); } } } return workflowsNames; } public static List<String> extractWorkflows(Iterator<SootMethod> methods, SootClass c){ List<String> workflows = null; // First we detect the main program to analyze it while(methods.hasNext()){ SootMethod sm = methods.next(); if(sm.getName().equals("main")){ System.out.println("detected main"); workflows = Util.extractWorkflowsFromMainMethod(sm, c); } } return workflows; } public static UnitGraph getCFGForMethod(String methodName, SootClass c){ SootMethod m = c.getMethodByName(methodName); Body b = m.retrieveActiveBody(); // Build CFG UnitGraph cfg = new ExceptionalUnitGraph(b); return cfg; } public static boolean isFieldState(String rawData){ if(rawData == null) return false; String[] tokens = rawData.split(" "); int accessIdx = -1; for(int i = 0; i<tokens.length; i++){ if(tokens[i].equals("type:")){ accessIdx = i+1; break; } } if(accessIdx != -1){ String annotation = tokens[accessIdx]; if(annotation.contains("OperatorState")){ return true; } } return false; } }