cc6f97a295ed7fd7742f33541ae1fea788813b59
[idea/community.git] / platform / structuralsearch / source / com / intellij / structuralsearch / impl / matcher / predicates / ScriptSupport.java
1 package com.intellij.structuralsearch.impl.matcher.predicates;
2
3 import com.intellij.openapi.diagnostic.Logger;
4 import com.intellij.psi.PsiElement;
5 import com.intellij.structuralsearch.MatchResult;
6 import com.intellij.structuralsearch.SSRBundle;
7 import com.intellij.structuralsearch.StructuralSearchException;
8 import com.intellij.structuralsearch.StructuralSearchUtil;
9 import groovy.lang.Binding;
10 import groovy.lang.GroovyRuntimeException;
11 import groovy.lang.GroovyShell;
12 import groovy.lang.Script;
13 import org.codehaus.groovy.control.CompilationFailedException;
14 import org.codehaus.groovy.control.ErrorCollector;
15 import org.codehaus.groovy.control.MultipleCompilationErrorsException;
16 import org.codehaus.groovy.control.messages.Message;
17 import org.codehaus.groovy.control.messages.SyntaxErrorMessage;
18 import org.codehaus.groovy.syntax.SyntaxException;
19 import org.jetbrains.annotations.NotNull;
20
21 import java.io.File;
22 import java.io.IOException;
23 import java.util.ArrayList;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
27
28 /**
29  * @author Maxim.Mossienko
30  * Date: 11.06.2009
31  * Time: 16:25:12
32  */
33 public class ScriptSupport {
34   private final Script script;
35
36   public ScriptSupport(String text, String name) {
37     File scriptFile = new File(text);
38     GroovyShell shell = new GroovyShell();
39     try {
40       script = scriptFile.exists() ? shell.parse(scriptFile):shell.parse(text, name);
41     } catch (Exception ex) {
42       Logger.getInstance(getClass().getName()).error(ex);
43       throw new RuntimeException(ex);
44     }
45   }
46
47   private static Map<String, Object> buildVariableMap(@NotNull MatchResult result, @NotNull Map<String, Object> out) {
48     final String name = result.getName();
49     if (name != null && !result.isMultipleMatch()) {
50       final Object value = out.get(name);
51       final PsiElement match = StructuralSearchUtil.getPresentableElement(result.getMatch());
52       if (value == null) {
53         out.put(name, match);
54       }
55       else if (value instanceof List) {
56         @SuppressWarnings("unchecked")
57         final List<PsiElement> list = (List<PsiElement>)value;
58         list.add(match);
59       }
60       else if (value instanceof PsiElement){
61         final List<PsiElement> list = new ArrayList<PsiElement>();
62         list.add((PsiElement)value);
63         list.add(match);
64         out.put(name, list);
65       }
66       else {
67         throw new AssertionError();
68       }
69     }
70     if (result.hasSons()) {
71       for (MatchResult son : result.getAllSons()) {
72         buildVariableMap(son, out);
73       }
74     }
75     return out;
76   }
77
78   public String evaluate(MatchResult result, PsiElement context) {
79     try {
80       final HashMap<String, Object> variableMap = new HashMap<String, Object>();
81       if (result != null) {
82         buildVariableMap(result, variableMap);
83         if (context == null) {
84           context = result.getMatch();
85         }
86       }
87       final Binding binding = new Binding(variableMap);
88
89       context = StructuralSearchUtil.getPresentableElement(context);
90       binding.setVariable("__context__", context);
91       script.setBinding(binding);
92
93       final Object o = script.run();
94       return String.valueOf(o);
95     } catch (GroovyRuntimeException ex) {
96       throw new StructuralSearchException(SSRBundle.message("groovy.script.error", ex.getMessage()));
97     } finally {
98       script.setBinding(null);
99     }
100   }
101
102   public static String checkValidScript(String scriptText) {
103     try {
104       final File scriptFile = new File(scriptText);
105       final GroovyShell shell = new GroovyShell();
106       final Script script = scriptFile.exists() ? shell.parse(scriptFile) : shell.parse(scriptText);
107       return null;
108     } catch (IOException e) {
109       return e.getMessage();
110     } catch (MultipleCompilationErrorsException e) {
111       final ErrorCollector errorCollector = e.getErrorCollector();
112       final List<Message> errors = errorCollector.getErrors();
113       for (Message error : errors) {
114         if (error instanceof SyntaxErrorMessage) {
115           final SyntaxErrorMessage errorMessage = (SyntaxErrorMessage)error;
116           final SyntaxException cause = errorMessage.getCause();
117           return cause.getMessage();
118         }
119       }
120       return e.getMessage();
121     } catch (CompilationFailedException ex) {
122       return ex.getLocalizedMessage();
123     }
124   }
125 }