Commit cf39f67a authored by Mix 1 kouot's avatar Mix 1 kouot
Browse files

Merged with henni master

parents 05d4c2c0 0e67c4d5
......@@ -24,6 +24,9 @@ public class Visuflow extends AbstractUIPlugin {
*/
private ProjectListener projectListener = new ProjectListener();
/* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
*/
@Override
public void start(BundleContext context) {
......@@ -61,6 +64,9 @@ public class Visuflow extends AbstractUIPlugin {
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
*/
@Override
public void stop(BundleContext context) {
ResourcesPlugin.getWorkspace().removeResourceChangeListener(projectListener);
......
......@@ -17,7 +17,7 @@ import de.unipaderborn.visuflow.VisuflowConstants;
/**
* @author PAH-Laptop
*
*
* This class handles adding the Visuflow Project Nature to Projects.
* This enables Eclipse to identify if it has to run our builder on a specific
* Project.
......@@ -25,12 +25,13 @@ import de.unipaderborn.visuflow.VisuflowConstants;
*/
public class AddRemoveVisuFlowNatureHandler extends AbstractHandler implements VisuflowConstants {
/* (non-Javadoc)
* @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent)
* this Method executes the Handler and thus toggles the nature status on a specific project,
* this Method executes the Handler and thus toggles the nature status on a specific project,
* by calling the toggleNature method.
*/
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
ISelection selection = HandlerUtil.getCurrentSelection(event);
//
......@@ -87,9 +88,6 @@ public class AddRemoveVisuFlowNatureHandler extends AbstractHandler implements V
newNatures[natures.length] = VISUFLOW_NATURE;
description.setNatureIds(newNatures);
project.setDescription(description, null);
for(String a : project.getDescription().getNatureIds()){
System.out.println(a);
}
}
}
\ No newline at end of file
......@@ -6,17 +6,40 @@ import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.dialogs.DialogSettings;
import de.unipaderborn.visuflow.Visuflow;
/**
* @author kaarthuk
*
*/
public final class GlobalSettings {
/**
* Filename of the settings xml that stores settings.
*/
final static String fileName = "settings.xml";
/**
* Creates a dialogsettings object.
*/
private static DialogSettings settings = new DialogSettings("ProjectOutputFolder");
/**
* Gets the execution path of the plugin.
*/
IPath path = Visuflow.getDefault().getStateLocation();
/**
* The filename of the settings file appended to the path.
*/
String filename = path.append(fileName).toOSString();
protected GlobalSettings() {
System.out.println("Settings filename is" + filename);
}
/**
* This function writes a key/value pair to the settings file
* @param key The key name.
* @param value The value for the key.
*/
public static void put(String key, String value) {
IPath path = Visuflow.getDefault().getStateLocation();
String filename = path.append(fileName).toOSString();
......@@ -33,6 +56,11 @@ public final class GlobalSettings {
}
}
/**
* Get the value of the key being passed.
* @param key The key whose value is required.
* @return The value as a string.
*/
public static String get(String key) {
IPath path = Visuflow.getDefault().getStateLocation();
String filename = path.append(fileName).toOSString();
......
......@@ -156,7 +156,7 @@ public class JimpleBuilder extends IncrementalProjectBuilder {
@Override
protected IProject[] build(int kind, Map<String, String> args, IProgressMonitor monitor) throws CoreException {
executeBuild = false;
if(getProject() != null && getProject().getName().equals(GlobalSettings.get("TargetProject"))){
if(getProject() != null && getProject().getName().equals(GlobalSettings.get("AnalysisProject"))){
if (kind == FULL_BUILD) {
fullBuild(monitor);
} else {
......
......@@ -5,6 +5,7 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
......@@ -29,7 +30,8 @@ import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.MethodDeclaration;
// TODO analyze only the the current analysis project
import de.unipaderborn.visuflow.builder.GlobalSettings;
/**
* The BreakpointLocator is used to find the locations of the flow functions
* in the user analysis. These locations are needed to set the conditional breakpoints,
......@@ -62,6 +64,13 @@ public class BreakpointLocator {
// @formatter:on
private CoreException exception = null;
/**
* Searches the current analysis project for known flow functions and returns
* a list of BreakpointLocations, which contain all information needed to set
* a Java line breakpoint.
* @return a list of {@link BreakpointLocation}s
* @throws JavaModelException
*/
public List<BreakpointLocation> findFlowFunctions() throws JavaModelException {
List<BreakpointLocation> locations = new ArrayList<>();
......@@ -69,11 +78,12 @@ public class BreakpointLocator {
IWorkspaceRoot workspaceRoot = workspace.getRoot();
IJavaModel model = JavaCore.create(workspaceRoot);
List<IJavaElement> javaProjects = getJavaProjects(model);
List<IJavaElement> sourceFolders = getSourceFolders(javaProjects);
String analysisProjectName = GlobalSettings.get("AnalysisProject");
IJavaElement analysisProject = getJavaProject(model, analysisProjectName);
List<IJavaElement> sourceFolders = getSourceFolders(analysisProject);
List<IJavaElement> flowFunctions = new ArrayList<>();
for (IJavaElement packageFragment : sourceFolders) { // TODO make sure to only use the target code
for (IJavaElement packageFragment : sourceFolders) {
for (String functionName : flowFunctionNames) {
findRecursive(flowFunctions, packageFragment, functionName);
}
......@@ -128,32 +138,64 @@ public class BreakpointLocator {
return locations;
}
private List<IJavaElement> getSourceFolders(List<IJavaElement> javaProjects) throws JavaModelException {
/**
* Returns all folders configured as source folders for the given project.
*
* @param javaProject
* the java project to examine
* @return a List of all source folders as IJavaElements
* @throws JavaModelException
* @see {@link #getJavaProjects(IJavaModel)}
*/
private List<IJavaElement> getSourceFolders(IJavaElement javaProject) throws JavaModelException {
List<IJavaElement> folders = new ArrayList<>();
for (IJavaElement project : javaProjects) {
IJavaElement[] children = ((IParent) project).getChildren();
for (IJavaElement child : children) {
if (child instanceof IPackageFragmentRoot) {
IPackageFragmentRoot packageFragmentRoot = (IPackageFragmentRoot) child;
if (packageFragmentRoot.getKind() == IPackageFragmentRoot.K_SOURCE) {
folders.add(packageFragmentRoot);
}
IJavaElement[] children = ((IParent) javaProject).getChildren();
for (IJavaElement child : children) {
if (child instanceof IPackageFragmentRoot) {
IPackageFragmentRoot packageFragmentRoot = (IPackageFragmentRoot) child;
if (packageFragmentRoot.getKind() == IPackageFragmentRoot.K_SOURCE) {
folders.add(packageFragmentRoot);
}
}
}
return folders;
}
private List<IJavaElement> getJavaProjects(IJavaModel model) throws JavaModelException {
List<IJavaElement> projects = new ArrayList<>();
/**
* Looks up a project in the JDT JavaModel
*
* @param model
* the IJavaModel to extract the projects from
* @param projectName
* the name of the project to retrieve
* @return the project as an IJavaProject
* @throws JavaModelException
* @throws NoSuchElementException
* if the project couldn't be found in the JavaModel
*/
private IJavaProject getJavaProject(IJavaModel model, String projectName) throws JavaModelException {
for (IJavaElement project : model.getChildren()) {
if (project instanceof IJavaProject) {
projects.add(project);
IJavaProject targetProject = (IJavaProject) project;
if (targetProject.getProject().getName().equals(projectName)) {
return targetProject;
}
}
}
return projects;
throw new NoSuchElementException("Project with name " + projectName + " not found in workspace");
}
/**
* Tarverses a hierarchy of IJavaElements and returns all IJavaElements, which names match the given name.
*
* @param result
* A List of IJavaElements, which match the given name
* @param parent
* The root element to start the search at
* @param name
* The element name ({@link IJavaElement#getElementName()}) to search for
* @throws JavaModelException
*/
void findRecursive(List<IJavaElement> result, IJavaElement parent, String name) throws JavaModelException {
if (parent.getElementName().equals(name)) {
result.add(parent);
......@@ -248,6 +290,11 @@ public class BreakpointLocator {
return Signature.createArraySignature(resolvedElementTypeSignature, count);
}
/**
* Contains all information needed to create a Java line breakpoint
* @author henni@upb.de
*
*/
public static class BreakpointLocation {
public IMethod method;
public IResource resource;
......
......@@ -60,11 +60,29 @@ public class JavaBreakpointListener implements IJavaBreakpointListener, Visuflow
if(!"unit".equals(type)) {
// this is a breakpoint for a certain type of units
// at the moment we don't know, which unit this is, so we just remove the
// instruction pointer marker and continue
// remove the old instruction pointer marker
String project = marker.getAttribute("Jimple.project").toString();
removeOldInstructionPointer(project);
// examine the suspended thread and find out, which unit this is, so that
// we can set the instruction pointer marker accordingly
try {
VFUnit unit = StackExaminer.getUnitFromStack(thread);
// save the information at the marker, so that the JimpleBreakpointManager knows
// where to continue, when the step over button is hit
marker.setAttribute("Jimple.unit.fqn", unit.getFullyQualifiedName());
// try to locate this unit in the Jimple file and reveal it in the
// JimpleEditor and in the graph
UnitLocation unitLocation = UnitLocator.locateUnit(unit);
IFile file = unitLocation.project.getFile(unitLocation.jimpleFile);
revealLocationInFile(file, unitLocation.charStart);
revealUnitInGraph(unit.getFullyQualifiedName());
highlightLine(project, file.getProjectRelativePath().toString(), unitLocation.line, unitLocation.charStart, unitLocation.charEnd);
} catch(Exception e) {
logger.error("Couldn't find unit on top stackframe", e);
}
return 0;
} else {
// this is a unit breakpoint
......
......@@ -195,7 +195,6 @@ public class JimpleBreakpointManager implements VisuflowConstants, IResourceChan
IBreakpoint javaBreakpoint = DebugPlugin.getDefault().getBreakpointManager().getBreakpoint(marker);
jimpleBreakpoint.addJavaBreakpoint(javaBreakpoint);
System.out.println("------------------------- JimpleBreakpoint created");
return Status.OK_STATUS;
}
};
......@@ -349,7 +348,7 @@ public class JimpleBreakpointManager implements VisuflowConstants, IResourceChan
if(unitFqn == null) {
// FIXME get the unit from the stack, if possible
// for example for unit-type-breakpoints
// no unit fqn, we don't know, where we are
return;
}
......
package de.unipaderborn.visuflow.debug;
import java.util.List;
import org.apache.commons.lang.ClassUtils;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.core.model.IVariable;
import org.eclipse.jdt.debug.core.IJavaArray;
import org.eclipse.jdt.debug.core.IJavaDebugTarget;
import org.eclipse.jdt.debug.core.IJavaObject;
import org.eclipse.jdt.debug.core.IJavaPrimitiveValue;
import org.eclipse.jdt.debug.core.IJavaThread;
import org.eclipse.jdt.debug.core.IJavaType;
import org.eclipse.jdt.debug.core.IJavaValue;
import de.unipaderborn.visuflow.Logger;
import de.unipaderborn.visuflow.Visuflow;
import de.unipaderborn.visuflow.model.DataModel;
import de.unipaderborn.visuflow.model.VFUnit;
import de.unipaderborn.visuflow.util.ServiceUtil;
import soot.tagkit.Host;
public class StackExaminer {
private static final transient Logger logger = Visuflow.getDefault().getLogger();
public static VFUnit getUnitFromStack(IJavaThread thread) throws CoreException {
String fqn = getUnitFromTopStackFrame(thread);
if(fqn == null) {
throw new RuntimeException("No unit found on top stackframe");
} else {
DataModel model = ServiceUtil.getService(DataModel.class);
VFUnit unit = model.getVFUnit(fqn);
if(unit == null) {
throw new RuntimeException("Unit not found in jimple model ["+fqn+"]");
}
return unit;
}
}
/*
* TODO make sure, this returns the right unit at the moment we look at all
* variables in the top stackframe and just return the first one, which implements the TagHost interface.
* But the stack might contain several units and we might return the wrong one.
*/
private static String getUnitFromTopStackFrame(IJavaThread thread) throws CoreException {
if (!thread.hasStackFrames()) {
return null;
}
IStackFrame top = thread.getTopStackFrame();
if (top.getVariables().length > 0) {
for (IVariable var : top.getVariables()) {
try {
IValue value = var.getValue();
if (value instanceof IJavaValue) {
IJavaObject javaValue = (IJavaObject) value;
IJavaDebugTarget debugTarget = thread.getDebugTarget().getAdapter(IJavaDebugTarget.class);
IJavaValue arg = debugTarget.newValue("Fully Qualified Name");
// the signature (2nd argument) can be retrieved with javap. Unit extends soot.tagkit.Host for the tag support
// -> javap -cp soot-trunk.jar -s soot.tagkit.Host
// the signature is in the output under "descriptor"
IJavaType type = javaValue.getJavaType();
if (isTagHost(type)) { // check, if this is a unit, which contains Tags
IJavaValue fqnTag = javaValue.sendMessage("getTag", "(Ljava/lang/String;)Lsoot/tagkit/Tag;", new IJavaValue[] { arg }, thread,
false);
IJavaValue tagValue = ((IJavaObject) fqnTag).sendMessage("getValue", "()[B", new IJavaValue[0], thread, false);
IJavaArray byteArray = (IJavaArray) tagValue;
byte[] b = new byte[byteArray.getLength()];
for (int i = 0; i < b.length; i++) {
IJavaPrimitiveValue byteValue = (IJavaPrimitiveValue) byteArray.getValue(i);
b[i] = byteValue.getByteValue();
}
String currentUnitFqn = new String(b);
return currentUnitFqn;
}
}
} catch (Exception e) {
logger.error("Couldn't retrieve variable " + var.getName() + " from top stack frame", e);
}
}
}
return null;
}
private static boolean isTagHost(IJavaType type) throws ClassNotFoundException, DebugException {
try {
Class<?> clazz = Class.forName(type.getName());
List<?> interfaces = ClassUtils.getAllInterfaces(clazz);
return interfaces.contains(Host.class);
} catch(ClassNotFoundException e) {
// outside of scope, we can ignore this
return false;
}
}
}
......@@ -31,7 +31,6 @@ public class TerminationListener implements IDebugEventSetListener, VisuflowCons
@Override
public void handleDebugEvents(DebugEvent[] events) {
// System.out.println("Events " + events.length);
for (int i = 0; i < events.length; i++) {
DebugEvent debugEvent = events[i];
if (debugEvent.getKind() == DebugEvent.TERMINATE) {
......
......@@ -44,7 +44,7 @@ public class UnitLocator implements VisuflowConstants {
return location;
}
private static int[] find(List<String> hayStack, String needle, int offset) {
static int[] find(List<String> hayStack, String needle, int offset) {
int[] charStartAndEnd = new int[3];
int lineNumber = 1;
int accumulatedCharacters = 0;
......
......@@ -36,8 +36,14 @@ import soot.tagkit.LineNumberTag;
public class JavaToCFGHandler extends AbstractHandler {
/**
* Get instance of default logger.`
*/
private Logger logger = Visuflow.getDefault().getLogger();
/* (non-Javadoc)
* @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent)
*/
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
IEditorPart part = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
......@@ -76,12 +82,19 @@ public class JavaToCFGHandler extends AbstractHandler {
}
return null;
}
/**
* This function filters the units of a class according to the function name and class name and content.
* We need to filter this based on methods, because different function might contain similar lines of code and
* hence their contents will be similar.
* @param className The name of the class.
* @param document The document which the user is currently interacting with
* @param content The contents of the document.
* @param lineNumber The linenumber on which the user has right-clicked.
* @return Map of filtered unit and the function it belongs to.
*/
private HashMap<VFUnit, VFMethod> getSelectedUnit(String className, IDocument document, int lineNumber) {
DataModel dataModel = ServiceUtil.getService(DataModel.class);
HashMap<VFUnit, VFMethod> map = new HashMap<VFUnit, VFMethod>();
// VFClass
// vfClass=dataModel.listClasses().stream().filter(x->x.getSootClass().getName()==className).collect(Collectors.toList()).get(0);
for (VFClass vfClass : dataModel.listClasses()) {
if (vfClass.getSootClass().getShortJavaStyleName().equals(className)) {
List<VFMethod> vfMethods = vfClass.getMethods();
......@@ -106,7 +119,12 @@ public class JavaToCFGHandler extends AbstractHandler {
}
return map;
}
/**
* This method returns the line numbers of all the methods passed to it.
* @param document The document with which the user is interacting.
* @param vfMethods The list of methods for which the line numbers are required.
* @return Map containing method names and their starting line numbers.
*/
private Map<String, Integer> getMethodLineNumbers(IDocument document, List<VFMethod> vfMethods) {
FindReplaceDocumentAdapter findReplaceDocumentAdapter = new FindReplaceDocumentAdapter(document);
......
......@@ -72,7 +72,7 @@ public class NavigationHandler extends AbstractHandler {
*/
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
//Get the editor part object
IEditorPart part = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
IFileEditorInput input = (IFileEditorInput) part.getEditorInput();
......@@ -100,6 +100,7 @@ public class NavigationHandler extends AbstractHandler {
if (resultantUnit.size() > 0) {
unit.add(new VFNode((VFUnit) resultantUnit.keySet().toArray()[0], 0));
}
//The below conditions check for events.
if (event.getCommand().getId().equals("JimpleEditor.NavigateToCFG")) {
try {
ServiceUtil.getService(DataModel.class).filterGraph(unit, true, true, null);
......@@ -144,7 +145,7 @@ public class NavigationHandler extends AbstractHandler {
}
/**
* This functions highlights units in a jimple file.
* This functions highlights units in a jimple file.
* @param units The units which need to be highlighted
*/
public void highlightJimpleSource(List<VFUnit> units) {
......@@ -258,8 +259,8 @@ public class NavigationHandler extends AbstractHandler {
}
/**
* This function filters the units of a class according to the function name and class name and content.
* We need to filter this based on methods, because different function might contain similar lines of code and
* This function filters the units of a class according to the function name and class name and content.
* We need to filter this based on methods, because different function might contain similar lines of code and
* hence their contents will be similar.
* @param className The name of the class.
* @param document The document which the user is currently interacting with
......@@ -358,7 +359,6 @@ public class NavigationHandler extends AbstractHandler {
valueList.add(db.getValue());
}
}
System.out.println(unit.getUnit());
for (ValueBox ub : u.getUseBoxes()) {
if (valueList.contains(ub.getValue())) {
if (u.getDefBoxes().isEmpty()) {
......
......@@ -8,6 +8,7 @@ import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
......@@ -34,6 +35,7 @@ import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.ContainerSelectionDialog;
import de.unipaderborn.visuflow.ProjectPreferences;
import de.unipaderborn.visuflow.builder.AddRemoveVisuFlowNatureHandler;
import de.unipaderborn.visuflow.builder.GlobalSettings;
import de.unipaderborn.visuflow.model.DataModel;
import de.unipaderborn.visuflow.util.ServiceUtil;
......@@ -247,6 +249,14 @@ import de.unipaderborn.visuflow.util.ServiceUtil;
GlobalSettings.put("TargetProject", targetProject.getProject().getName());
ProjectPreferences projPref = new ProjectPreferences();
projPref.createPreferences();
AddRemoveVisuFlowNatureHandler addNature = new AddRemoveVisuFlowNatureHandler();
try {
if(!analysisProject.getProject().isNatureEnabled("JimpleBuilder.VisuFlowNature"))
addNature.toggleNature(analysisProject.getProject());
} catch (CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
super.okPressed();
ServiceUtil.getService(DataModel.class).triggerProjectRebuild();
......
......@@ -32,7 +32,7 @@ public class ViewJavaSource extends AbstractHandler {
// System.out.println("//////////////////////"+HandlerUtil.getActiveEditor(event).getEditorSite());
// System.out.println(HandlerUtil.getCurrentSelection(event).toString());
// System.out.println(window.getActivePage());
//ISelection selection = HandlerUtil.getCurrentSelectionChecked(event);
//ISelection selection = HandlerUtil.getCurrentSelectionChecked(event);
File fileToOpen = new File("C:/Users/Shashank B S/Documents/Projects/visuflow-plugin/targets2/de/visuflow/analyzeMe/ex2/TargetClass2.java");
if (fileToOpen.exists() && fileToOpen.isFile()) {
......@@ -49,13 +49,10 @@ public class ViewJavaSource extends AbstractHandler {
}
IEditorPart editor = window.getActivePage().getActiveEditor();
ITextEditor txteditor = (ITextEditor) editor.getAdapter(ITextEditor.class);
ITextEditor txteditor = editor.getAdapter(ITextEditor.class);
if (txteditor != null) {
IDocumentProvider provider = txteditor.getDocumentProvider();
IDocument document = provider.getDocument(editor.getEditorInput());
System.out.println(txteditor.getHighlightRange());
System.out.println("==============================="+document);
System.out.println(document);
}
ITextEditor editor1 = (ITextEditor) editor;
......@@ -72,7 +69,6 @@ public class ViewJavaSource extends AbstractHandler {
// we guess this...
}
if (lineInfo != null) {
System.out.println("=================>>>>>>>>>"+lineInfo);
editor1.selectAndReveal(lineInfo.getOffset(), lineInfo.getLength());
// editor1.setHighlightRange(lineInfo.getOffset(), lineInfo.getLength(), true);
......
......@@ -10,6 +10,11 @@ import org.eclipse.ui.IWorkbenchPart;
import de.unipaderborn.visuflow.VisuflowConstants;
/**
* Glue code to enable the double-click behavior in the ruler of the JimpleEditor
* @author henni@upb.de
*