Skip to content

Commit 01a11b0

Browse files
authored
Merge pull request #391 from rakshitkr/content-assist
Content proposal for includeClass call
2 parents 9f5c3a8 + 74cae11 commit 01a11b0

5 files changed

Lines changed: 177 additions & 5 deletions

File tree

plugins/de.cognicrypt.codegenerator/plugin.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,19 @@
4040
</toolbar>
4141
</menuContribution>
4242
</extension>
43+
<extension
44+
id="crysltemplate_category"
45+
name="CrySL Template Proposals"
46+
point="org.eclipse.jdt.ui.javaCompletionProposalComputer">
47+
<proposalCategory/>
48+
</extension>
49+
<extension
50+
id="crysltemplate_proposal"
51+
point="org.eclipse.jdt.ui.javaCompletionProposalComputer">
52+
<javaCompletionProposalComputer
53+
class="de.cognicrypt.codegenerator.ui.contentassist.CustomCompletionProposalComputer"
54+
categoryId="de.cognicrypt.codegenerator.ui.contentassist.crysltemplate_category"
55+
activate="true">
56+
</javaCompletionProposalComputer>
57+
</extension>
4358
</plugin>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package de.cognicrypt.codegenerator.ui.contentassist;
2+
3+
import java.io.BufferedReader;
4+
import java.io.File;
5+
import java.io.FileReader;
6+
import java.io.IOException;
7+
import java.util.ArrayList;
8+
import java.util.List;
9+
10+
import org.eclipse.core.runtime.IProgressMonitor;
11+
import org.eclipse.jdt.core.ICompilationUnit;
12+
import org.eclipse.jdt.internal.ui.text.java.JavaCompletionProposalComputer;
13+
import org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext;
14+
import org.eclipse.jdt.ui.text.java.JavaContentAssistInvocationContext;
15+
import org.eclipse.jface.text.contentassist.CompletionProposal;
16+
import org.eclipse.jface.text.contentassist.ICompletionProposal;
17+
18+
import de.cognicrypt.codegenerator.Activator;
19+
import de.cognicrypt.core.Constants;
20+
21+
22+
@SuppressWarnings("restriction")
23+
public class CustomCompletionProposalComputer extends JavaCompletionProposalComputer {
24+
25+
26+
static private List<String> ruleNames = readClassnames(Constants.JCA_LATEST_ECLIPSE_RULES_DIR);
27+
28+
@Override
29+
public List<ICompletionProposal> computeCompletionProposals(ContentAssistInvocationContext context, IProgressMonitor monitor) {
30+
List<ICompletionProposal> defaultProposals = super.computeCompletionProposals(context, monitor);
31+
32+
JavaContentAssistInvocationContext javaContext = (JavaContentAssistInvocationContext) context;
33+
ICompilationUnit cu = javaContext.getCompilationUnit();
34+
int offset = context.getInvocationOffset();
35+
SelectionFinder finder = new SelectionFinder(cu, offset);
36+
37+
if (finder.getMemberName() == null) {
38+
return defaultProposals;
39+
}
40+
41+
List<ICompletionProposal> customProposals = new ArrayList<ICompletionProposal>();
42+
for (String name : ruleNames) {
43+
String s = '"' + name + '"';
44+
CompletionProposal proposal = new CompletionProposal(s, offset, 0, s.length());
45+
customProposals.add(proposal);
46+
}
47+
48+
customProposals.addAll(defaultProposals);
49+
return customProposals;
50+
}
51+
52+
private static List<String> readClassnames(String rulesFolder) {
53+
List<String> classnames = new ArrayList<String>();
54+
for (File rule : (new File(rulesFolder)).listFiles()) {
55+
if (rule.isDirectory()) {
56+
classnames.addAll(readClassnames(rule.getAbsolutePath()));
57+
continue;
58+
}
59+
60+
String classname = null;
61+
try {
62+
classname = readClassnameFromRule(rule);
63+
} catch (IOException e) {
64+
Activator.getDefault().logError(e);
65+
}
66+
67+
if (classname != null) {
68+
classnames.add(classname);
69+
}
70+
}
71+
72+
return classnames;
73+
}
74+
75+
private static String readClassnameFromRule(File ruleFile) throws IOException {
76+
final String fileName = ruleFile.getName();
77+
if (!fileName.endsWith(Constants.cryslFileEnding)) {
78+
return null;
79+
}
80+
81+
BufferedReader reader = null;
82+
String classname = null;
83+
try {
84+
reader = new BufferedReader(new FileReader(ruleFile));
85+
String spec = reader.readLine();
86+
classname = spec.split(" ")[1];
87+
} finally {
88+
reader.close();
89+
}
90+
91+
return classname;
92+
}
93+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package de.cognicrypt.codegenerator.ui.contentassist;
2+
3+
import org.eclipse.core.runtime.NullProgressMonitor;
4+
import org.eclipse.jdt.core.ICompilationUnit;
5+
import org.eclipse.jdt.core.dom.AST;
6+
import org.eclipse.jdt.core.dom.ASTNode;
7+
import org.eclipse.jdt.core.dom.ASTParser;
8+
import org.eclipse.jdt.core.dom.ASTVisitor;
9+
import org.eclipse.jdt.core.dom.MethodInvocation;
10+
11+
public class SelectionFinder extends ASTVisitor {
12+
private ICompilationUnit unit;
13+
private int offset;
14+
private String memberName;
15+
16+
public SelectionFinder(ICompilationUnit unit, int offset) {
17+
this.unit = unit;
18+
this.offset = offset;
19+
}
20+
21+
public String getMemberName() {
22+
visit();
23+
return memberName;
24+
}
25+
26+
private boolean visited = false;
27+
28+
private void visit() {
29+
if (visited) {
30+
return;
31+
}
32+
visited = true;
33+
34+
ASTParser parser = ASTParser.newParser(AST.JLS12);
35+
parser.setSource(unit);
36+
parser.setSourceRange(offset, -1);
37+
ASTNode node = parser.createAST(new NullProgressMonitor());
38+
node.accept(this);
39+
}
40+
41+
@Override
42+
public boolean visit(MethodInvocation node) {
43+
return treatMethodName(node);
44+
}
45+
46+
private boolean treatMethodName(MethodInvocation node) {
47+
String methodName = node.getName().getFullyQualifiedName();
48+
int currentOffset = node.getLength() + node.getStartPosition() - 1;
49+
if(("includeClass").equals(methodName) && currentOffset == offset) {
50+
this.memberName = methodName;
51+
return true;
52+
} else if ((node.getExpression() instanceof MethodInvocation)) {
53+
return treatMethodName((MethodInvocation) node.getExpression());
54+
} else {
55+
return false;
56+
}
57+
}
58+
59+
60+
}

plugins/de.cognicrypt.core/src/de/cognicrypt/core/Constants.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
import org.eclipse.swt.graphics.Point;
1111
import org.eclipse.swt.graphics.Rectangle;
1212

13+
import de.cognicrypt.utils.CrySLUtils;
14+
1315
/**
1416
* This class comprises all constants that are used by the plugin.
1517
*/
@@ -581,6 +583,10 @@ public String toString() {
581583
public static final int JDT_PROBLEM_ID = 10000000;
582584
public final static String RELATIVE_RULES_DIR = "resources/CrySLRules";
583585
public final static String ECLIPSE_RULES_DIR = System.getProperty("user.dir");
586+
public final static String JCA_LATEST_ECLIPSE_RULES_DIR = Constants.ECLIPSE_RULES_DIR + Constants.innerFileSeparator + Constants.Rules.JavaCryptographicArchitecture.toString() + Constants.innerFileSeparator +
587+
CrySLUtils.getRuleVersions(Constants.Rules.JavaCryptographicArchitecture.toString())[CrySLUtils.getRuleVersions(Constants.Rules.JavaCryptographicArchitecture.toString()).length - 1] +
588+
Constants.innerFileSeparator + Constants.Rules.JavaCryptographicArchitecture.toString();
589+
584590
public static final String cryslFileEnding = ".crysl";
585591
public static final String cryslEditorID = "de.darmstadt.tu.crossing.CrySL";
586592
public static final String HEALTHY = "Secure";

plugins/de.cognicrypt.core/src/de/cognicrypt/utils/CrySLUtils.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@
99
import java.util.regex.Matcher;
1010
import java.util.stream.Collectors;
1111
import java.util.stream.Stream;
12+
1213
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
14+
1315
import crypto.analysis.CrySLRulesetSelector.RuleFormat;
1416
import crypto.cryslhandler.CrySLModelReader;
1517
import crypto.rules.CrySLRule;
1618
import crypto.rules.CrySLRuleReader;
1719
import crypto.rules.StateNode;
1820
import crypto.rules.TransitionEdge;
19-
import de.cognicrypt.core.Activator;
2021
import de.cognicrypt.core.Constants;
21-
import de.cognicrypt.core.Constants.Rules;
2222

2323
public class CrySLUtils {
2424

@@ -72,9 +72,7 @@ public static List<CrySLRule> readCrySLRules() {
7272
*/
7373

7474
public static CrySLRule getCrySLRule(String cryslRule) throws MalformedURLException {
75-
File ruleRes = new File(Constants.ECLIPSE_RULES_DIR + Constants.innerFileSeparator + Constants.Rules.JavaCryptographicArchitecture.toString() + Constants.innerFileSeparator +
76-
CrySLUtils.getRuleVersions(Constants.Rules.JavaCryptographicArchitecture.toString())[CrySLUtils.getRuleVersions(Constants.Rules.JavaCryptographicArchitecture.toString()).length - 1] +
77-
Constants.innerFileSeparator + Constants.Rules.JavaCryptographicArchitecture.toString() + Constants.innerFileSeparator + cryslRule + RuleFormat.SOURCE.toString());
75+
File ruleRes = new File(Constants.JCA_LATEST_ECLIPSE_RULES_DIR + Constants.innerFileSeparator + cryslRule + RuleFormat.SOURCE.toString());
7876
if (ruleRes == null || !ruleRes.exists() || !ruleRes.canRead()) {
7977
ruleRes = Utils.getResourceFromWithin(Constants.RELATIVE_CUSTOM_RULES_DIR + Constants.innerFileSeparator + cryslRule + RuleFormat.SOURCE.toString(), de.cognicrypt.core.Activator.PLUGIN_ID);
8078
}

0 commit comments

Comments
 (0)