Skip to content

Commit 155cf1b

Browse files
committed
Update run/rerun SWAN action to use new program arguments implementation
1 parent 3a1e9fb commit 155cf1b

File tree

9 files changed

+158
-124
lines changed

9 files changed

+158
-124
lines changed

swan_assist/build.gradle

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ repositories {
1414

1515
dependencies {
1616
compile group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1'
17-
compile group:'de.upb.cs.swt', name: 'swan_core', version: '1.0.0'
17+
compile group:'de.upb.cs.swt', name: 'swan_core', version: '1.3.0'
1818
compile group: 'ca.mcgill.sable', name: 'soot', version: '3.3.0'
19+
compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.5'
20+
compile group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.5'
1921
testCompile group: 'junit', name: 'junit', version: '4.12'
2022
}
2123

swan_assist/src/main/java/de/fraunhofer/iem/swan/assist/actions/LaunchSwanAction.java

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,20 @@
2020
import de.fraunhofer.iem.swan.assist.data.MethodWrapper;
2121
import de.fraunhofer.iem.swan.assist.ui.dialog.SwanLauncherDialog;
2222
import de.fraunhofer.iem.swan.assist.util.Constants;
23+
import de.fraunhofer.iem.swan.data.Method;
2324

2425
import java.io.File;
2526
import java.io.IOException;
2627
import java.io.InputStream;
27-
import java.util.ArrayList;
28-
import java.util.HashMap;
29-
import java.util.Objects;
30-
import java.util.Properties;
28+
import java.io.InputStreamReader;
29+
import java.util.*;
3130

3231
/**
3332
* Action opens dialog for user to set parameters for running SWAN. After which thread is created to run SWAN.
3433
*/
3534
public class LaunchSwanAction extends AnAction {
3635

36+
protected Set<Method> methods = new HashSet<Method>();
3737
/**
3838
* Obtains application parameters from user, exports updated JSON file and starts thread to run SWAN.
3939
* @param anActionEvent source event
@@ -70,27 +70,35 @@ public void actionPerformed(AnActionEvent anActionEvent) {
7070

7171
HashMap<String, String> swanParameters = dialog.getParameters();
7272

73-
//Merge current list with training methods
74-
HashMap<String, MethodWrapper> methods = JSONFileLoader.getAllMethods();
73+
if(JSONFileLoader.isFileSelected()) {
74+
//Merge current list with training methods
75+
HashMap<String, MethodWrapper> methods = JSONFileLoader.getAllMethods();
7576

76-
//Load training methods
77-
String trainingFile = Objects.requireNonNull(getClass().getClassLoader().getResource(config.getProperty("train_config_file"))).getPath() ;
78-
JSONFileParser fileParser = new JSONFileParser(trainingFile);
79-
HashMap<String, MethodWrapper> trainingMethods = fileParser.parseJSONFileMap();
77+
InputStream stream = getClass().getClassLoader().getResourceAsStream(config.getProperty("train_config_file"));
78+
HashMap<String, MethodWrapper> trainingMethods = new HashMap<>();
8079

81-
HashMap<String, MethodWrapper> mergedMethods = new HashMap<>(methods);
82-
mergedMethods.putAll(trainingMethods);
80+
if (stream != null) {
8381

84-
//Export changes to configuration files
85-
JSONWriter exportFile = new JSONWriter();
86-
String newConfigFile = swanParameters.get(Constants.SWAN_OUTPUT_DIR) + File.separator + config.getProperty("input_json_suffix");
87-
try {
88-
exportFile.writeToJsonFile(new ArrayList<>(mergedMethods.values()), newConfigFile);
89-
} catch (IOException e) {
90-
e.printStackTrace();
91-
}
82+
JSONFileParser fileParser = new JSONFileParser();
83+
trainingMethods = fileParser.parseJSONFileStream(new InputStreamReader(stream));
84+
}
85+
86+
HashMap<String, MethodWrapper> mergedMethods = new HashMap<>(methods);
87+
mergedMethods.putAll(trainingMethods);
9288

93-
swanParameters.put(Constants.SWAN_CONFIG_FILE, newConfigFile);
89+
//Export changes to configuration files
90+
JSONWriter exportFile = new JSONWriter();
91+
String newConfigFile = swanParameters.get(Constants.SWAN_OUTPUT_DIR) + File.separator + config.getProperty("input_json_suffix");
92+
try {
93+
exportFile.writeToJsonFile(new ArrayList<>(mergedMethods.values()), newConfigFile);
94+
} catch (IOException e) {
95+
e.printStackTrace();
96+
}
97+
swanParameters.put(Constants.SWAN_CONFIG_FILE, newConfigFile);
98+
}
99+
else{
100+
swanParameters.put(Constants.SWAN_CONFIG_FILE, config.getProperty("swan_default_param_value"));
101+
}
94102

95103
SwanProcessBuilder processBuilder = new SwanProcessBuilder(project, dialog.getParameters());
96104
processBuilder.start();
@@ -108,7 +116,7 @@ public void actionPerformed(AnActionEvent anActionEvent) {
108116
public void update(AnActionEvent event) {
109117

110118
//Disable/Enable action button
111-
if (JSONFileLoader.isReloading() || !JSONFileLoader.isFileSelected())
119+
if (JSONFileLoader.isReloading())
112120
event.getPresentation().setEnabled(false);
113121
else
114122
event.getPresentation().setEnabled(true);

swan_assist/src/main/java/de/fraunhofer/iem/swan/assist/actions/SwanProcessBuilder.java

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99

1010
import com.intellij.openapi.project.Project;
1111
import com.intellij.util.messages.MessageBus;
12+
import de.fraunhofer.iem.swan.Main;
1213
import de.fraunhofer.iem.swan.assist.comm.SwanNotifier;
1314
import de.fraunhofer.iem.swan.assist.util.Constants;
1415

15-
import java.io.File;
16-
import java.io.IOException;
16+
import java.io.*;
1717
import java.time.LocalDateTime;
1818
import java.time.format.DateTimeFormatter;
1919
import java.util.HashMap;
@@ -46,51 +46,36 @@ public void run() {
4646

4747
ResourceBundle resource = ResourceBundle.getBundle("dialog_messages");
4848

49-
String currentTimestamp = getCurrentTimestamp("yyyy-MM-dd-HHmmss");
49+
String currentTimestamp = getCurrentTimestamp();
5050

5151
File outputFolder = new File(parameters.get(Constants.SWAN_OUTPUT_DIR));
52-
outputFolder.mkdirs();
52+
53+
if(!outputFolder.exists())
54+
outputFolder.mkdir();
5355

5456
File logFile = new File(outputFolder, currentTimestamp + parameters.get(Constants.SWAN_OUTPUT_LOG));
5557
try {
5658
logFile.createNewFile();
5759
parameters.replace(Constants.SWAN_OUTPUT_LOG, logFile.getPath());
5860

61+
FileOutputStream fileOutputStream = new FileOutputStream(logFile.getAbsolutePath());
62+
63+
System.setOut(new PrintStream(fileOutputStream));
64+
5965
} catch (IOException e) {
6066
e.printStackTrace();
6167
}
6268

63-
ProcessBuilder processBuilder = new ProcessBuilder("java", "-jar",
64-
parameters.get(Constants.SWAN_JAR_DIR),
65-
parameters.get(Constants.SWAN_SOURCE_DIR),
69+
Main.main(new String[]{parameters.get(Constants.SWAN_SOURCE_DIR),
6670
parameters.get(Constants.SWAN_TRAIN_DIR),
6771
parameters.get(Constants.SWAN_CONFIG_FILE),
68-
parameters.get(Constants.SWAN_OUTPUT_DIR));
72+
parameters.get(Constants.SWAN_OUTPUT_DIR)});
6973

70-
processBuilder.redirectErrorStream(true);
71-
processBuilder.redirectOutput(ProcessBuilder.Redirect.appendTo(logFile));
72-
73-
String message;
74-
75-
try {
76-
Process swanProcess = processBuilder.start();
77-
int result = swanProcess.waitFor();
78-
79-
if (result == 0)
80-
message = resource.getString("Messages.Notification.Success");
81-
else
82-
message = resource.getString("Messages.Notification.Failure");
83-
84-
} catch (IOException | InterruptedException e) {
85-
86-
e.printStackTrace();
87-
message = resource.getString("Messages.Notification.Failure");
88-
}
74+
System.setOut(System.out);
8975

9076
HashMap<String, String> results = new HashMap<String, String>();
9177
results.put(Constants.SWAN_OUTPUT_FILE, parameters.get(Constants.SWAN_OUTPUT_FILE));
9278
results.put(Constants.SWAN_OUTPUT_LOG, parameters.get(Constants.SWAN_OUTPUT_LOG));
93-
results.put(Constants.SWAN_OUTPUT_MESSAGE, message);
9479

9580
MessageBus messageBus = project.getMessageBus();
9681
SwanNotifier publisher = messageBus.syncPublisher(SwanNotifier.END_SWAN_PROCESS_TOPIC);
@@ -99,12 +84,11 @@ public void run() {
9984

10085
/**
10186
* Get the timestamp in a specified format.
102-
* @param dateFormat Date format that should be used.
10387
* @return Formatted date
10488
*/
105-
private String getCurrentTimestamp(String dateFormat) {
89+
private String getCurrentTimestamp() {
10690

107-
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormat);
91+
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd-HHmmss");
10892
return LocalDateTime.now().format(formatter);
10993
}
11094
}

swan_assist/src/main/java/de/fraunhofer/iem/swan/assist/ui/MethodListTree.java

Lines changed: 88 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,13 @@
4040
import de.fraunhofer.iem.swan.assist.comm.*;
4141
import de.fraunhofer.iem.swan.assist.data.JSONFileLoader;
4242
import de.fraunhofer.iem.swan.assist.data.MethodWrapper;
43+
import de.fraunhofer.iem.swan.assist.ui.dialog.MethodDialog;
4344
import de.fraunhofer.iem.swan.assist.ui.dialog.SwanResultsDialog;
4445
import de.fraunhofer.iem.swan.assist.util.Constants;
4546
import de.fraunhofer.iem.swan.assist.util.Formatter;
4647
import de.fraunhofer.iem.swan.assist.util.PsiTraversal;
4748
import de.fraunhofer.iem.swan.data.Category;
49+
import de.fraunhofer.iem.swan.data.Method;
4850
import javafx.util.Pair;
4951
import org.jetbrains.annotations.NotNull;
5052

@@ -70,6 +72,7 @@ public class MethodListTree extends Tree {
7072

7173
/**
7274
* Initialises method list tree
75+
*
7376
* @param project Active project in IDE
7477
*/
7578
public MethodListTree(Project project) {
@@ -98,55 +101,62 @@ public void mouseClicked(MouseEvent e) {
98101
if ((SwingUtilities.isRightMouseButton(e) || (e.isControlDown()) && !isEmpty())) {
99102

100103
DefaultMutableTreeNode node = (DefaultMutableTreeNode) getLastSelectedPathComponent();
101-
Object object = node.getUserObject();
102104

103-
if (object instanceof MethodWrapper) {
105+
if (node != null) {
106+
107+
Object object = node.getUserObject();
108+
109+
if (object instanceof MethodWrapper) {
104110

105-
MethodWrapper method = (MethodWrapper) object;
111+
MethodWrapper method = (MethodWrapper) object;
106112

107-
RESTORE_METHOD = method.getUpdateOperation().equals(Constants.METHOD_DELETED);
113+
RESTORE_METHOD = method.getUpdateOperation().equals(Constants.METHOD_DELETED);
108114

109-
ActionPopupMenu actionPopupMenu = ActionManager.getInstance().createActionPopupMenu("Method", new MethodActionGroup(method));
110-
actionPopupMenu.getComponent().show(e.getComponent(), e.getX(), e.getY());
115+
ActionPopupMenu actionPopupMenu = ActionManager.getInstance().createActionPopupMenu("Method", new MethodActionGroup(method));
116+
actionPopupMenu.getComponent().show(e.getComponent(), e.getX(), e.getY());
117+
}
111118
}
112119

113120
} else if (e.getClickCount() == 2) {
114121

115122
DefaultMutableTreeNode node = (DefaultMutableTreeNode) getLastSelectedPathComponent();
116-
Object object = node.getUserObject();
123+
if (node != null) {
124+
Object object = node.getUserObject();
117125

118-
if (object instanceof MethodWrapper) {
126+
if (object instanceof MethodWrapper) {
119127

120-
MethodWrapper method = (MethodWrapper) object;
128+
MethodWrapper method = (MethodWrapper) object;
121129

122-
//Get PSI element location
123-
PsiFile[] files = FilenameIndex.getFilesByName(project, method.getFileName(), GlobalSearchScope.allScope(project));
130+
//Get PSI element location
131+
PsiFile[] files = FilenameIndex.getFilesByName(project, method.getFileName(), GlobalSearchScope.allScope(project));
124132

125-
boolean methodFound = false;
133+
boolean methodFound = false;
126134

127-
for (PsiFile file : files) {
135+
for (PsiFile file : files) {
128136

129-
PsiJavaFile psiJavaFile = (PsiJavaFile) file;
137+
PsiJavaFile psiJavaFile = (PsiJavaFile) file;
130138

131-
for (PsiClass psiClass : psiJavaFile.getClasses()) {
132-
for (PsiMethod psiMethod : psiClass.getMethods()) {
139+
for (PsiClass psiClass : psiJavaFile.getClasses()) {
140+
for (PsiMethod psiMethod : psiClass.getMethods()) {
133141

134-
if (Objects.equals(PsiTraversal.getMethodSignature(psiMethod), method.getSignature(true))) {
142+
if (Objects.equals(PsiTraversal.getMethodSignature(psiMethod), method.getSignature(true))) {
135143

136-
methodFound = true;
137-
FileEditorManager.getInstance(project).openFile(psiJavaFile.getVirtualFile(), true, true);
138-
FileEditorManager.getInstance(project).getSelectedTextEditor().getCaretModel().moveToOffset(psiMethod.getTextOffset());
144+
methodFound = true;
145+
FileEditorManager.getInstance(project).openFile(psiJavaFile.getVirtualFile(), true, true);
146+
FileEditorManager.getInstance(project).getSelectedTextEditor().getCaretModel().moveToOffset(psiMethod.getTextOffset());
147+
}
139148
}
140149
}
141150
}
142-
}
143151

144-
if (!methodFound) {
145-
JBPopupFactory.getInstance().createHtmlTextBalloonBuilder(resource.getString("Messages.Error.MethodNotFound"), MessageType.ERROR, null)
146-
.createBalloon()
147-
.show(JBPopupFactory.getInstance().guessBestPopupLocation((JComponent) e.getComponent()), Balloon.Position.below);
152+
if (!methodFound) {
153+
JBPopupFactory.getInstance().createHtmlTextBalloonBuilder(resource.getString("Messages.Error.MethodNotFound"), MessageType.ERROR, null)
154+
.createBalloon()
155+
.show(JBPopupFactory.getInstance().guessBestPopupLocation((JComponent) e.getComponent()), Balloon.Position.below);
156+
}
148157
}
149158
}
159+
150160
}
151161
}
152162
});
@@ -279,12 +289,11 @@ public void launchSwan(HashMap<String, String> values) {
279289
JSONFileLoader.setReloading(false);
280290
NotificationType notificationType = NotificationType.INFORMATION;
281291

282-
if (!values.get(Constants.SWAN_OUTPUT_MESSAGE).equals(resource.getString("Messages.Notification.Success"))) {
283-
notificationType = NotificationType.ERROR;
284-
}
292+
String message = "<html>"
293+
+ resource.getString("Messages.Notification.Completed")
294+
+ "<br><a href='logs'>View Logs</a> or <a href='load'>Load Changes</a></html>";
285295

286-
String message = "<html>" + values.get(Constants.SWAN_OUTPUT_MESSAGE) + "<br><a href='logs'>View Logs</a> or <a href='load'>Load Changes</a></html>";
287-
Notifications.Bus.notify(new Notification(Constants.PLUGIN_GROUP_DISPLAY_ID, "Completed", message, notificationType, new NotificationListener() {
296+
Notifications.Bus.notify(new Notification(Constants.PLUGIN_GROUP_DISPLAY_ID, resource.getString("Messages.Notification.Title.Completed"), message, notificationType, new NotificationListener() {
288297
@Override
289298
public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent hyperlinkEvent) {
290299

@@ -305,6 +314,52 @@ public void hyperlinkUpdate(@NotNull Notification notification, @NotNull Hyperli
305314
}
306315
});
307316

317+
318+
//Update Tool Window to notify user that SWAN is running
319+
bus.connect().subscribe(SuggestNotifier.START_SUGGEST_TOPIC, new SuggestNotifier() {
320+
@Override
321+
public void setStartSuggestTopic() {
322+
JSONFileLoader.setReloading(true);
323+
Notifications.Bus.notify(new Notification(Constants.PLUGIN_GROUP_DISPLAY_ID, resource.getString("Messages.Title.SuggestStarted"), resource.getString("Messages.Notification.SuggestStarted"), NotificationType.INFORMATION));
324+
325+
}
326+
327+
@Override
328+
public void setEndSuggestTopic(Set<Method> values) {
329+
JSONFileLoader.setReloading(false);
330+
331+
NotificationType notificationType = NotificationType.INFORMATION;
332+
333+
String message = "<html>" + resource.getString("Messages.Notification.Suggest.Successful") + "<br><a href='methods'>View methods</a></html>";
334+
Notifications.Bus.notify(new Notification(Constants.PLUGIN_GROUP_DISPLAY_ID, "Completed", message, notificationType, new NotificationListener() {
335+
@Override
336+
public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent hyperlinkEvent) {
337+
338+
if (hyperlinkEvent.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
339+
340+
if (hyperlinkEvent.getDescription().equals("methods")) {
341+
342+
HashMap<String,MethodWrapper> suggestedMethods = new HashMap<>();
343+
344+
for(Method m: values){
345+
346+
MethodWrapper methodWrapper = new MethodWrapper(m);
347+
methodWrapper.setStatus(MethodWrapper.MethodStatus.SUGGESTED);
348+
349+
suggestedMethods.put(methodWrapper.getSignature(true), methodWrapper);
350+
}
351+
352+
MethodDialog dialog = new MethodDialog(suggestedMethods, (String)suggestedMethods.keySet().toArray()[0], project, JSONFileLoader.getCategories());
353+
dialog.show();
354+
355+
356+
}
357+
}
358+
}
359+
}));
360+
}
361+
});
362+
308363
//Connect to project bus and obtain filter for Method Tree
309364
bus.connect().subscribe(FilterNotifier.FILTER_SELECTED_TOPIC, new FilterNotifier() {
310365
@Override
@@ -379,6 +434,7 @@ private DefaultMutableTreeNode searchNode(DefaultMutableTreeNode root, String me
379434

380435
/**
381436
* Add new node to tree
437+
*
382438
* @param method New method to be added
383439
*/
384440
private void addNode(MethodWrapper method) {
@@ -390,6 +446,7 @@ private void addNode(MethodWrapper method) {
390446

391447
/**
392448
* Extracts categories from method and adds them to the DefaultMutableTreeNode node.
449+
*
393450
* @param method the method that is being added to the tree
394451
* @return the node object with the categories as children
395452
*/
@@ -399,6 +456,7 @@ private DefaultMutableTreeNode addCategoriesToNode(MethodWrapper method) {
399456

400457
/**
401458
* Extracts categories from method and adds them to the DefaultMutableTreeNode node.
459+
*
402460
* @param node method to be added to tree
403461
* @param method the method that is being added to the tree
404462
* @return the node object with the categories as children

0 commit comments

Comments
 (0)