Statistics
| Revision:

gvsig-scripting / trunk / org.gvsig.scripting / org.gvsig.scripting.lib / org.gvsig.scripting.lib.impl / src / main / java / org / gvsig / scripting / impl / DefaultScriptingScript.java @ 171

History | View | Annotate | Download (8.3 KB)

1
package org.gvsig.scripting.impl;
2

    
3
import groovy.lang.MissingMethodException;
4

    
5
import java.io.BufferedWriter;
6
import java.io.File;
7
import java.io.FileWriter;
8
import java.io.IOException;
9
import java.util.Map;
10

    
11
import javax.script.Invocable;
12
import javax.script.ScriptEngine;
13
import javax.script.ScriptException;
14

    
15
import org.codehaus.groovy.control.MultipleCompilationErrorsException;
16
import org.gvsig.scripting.ScriptingFolder;
17
import org.gvsig.scripting.ScriptingManager;
18
import org.gvsig.scripting.ScriptingScript;
19
import org.gvsig.tools.observer.Observer;
20
import org.gvsig.tools.observer.WeakReferencingObservable;
21
import org.gvsig.tools.observer.impl.DelegateWeakReferencingObservable;
22
import org.ini4j.Ini;
23
import org.ini4j.InvalidFileFormatException;
24
import org.python.core.PySyntaxError;
25

    
26

    
27
public class DefaultScriptingScript extends AbstractScript implements ScriptingScript{
28

    
29
        protected String langName;
30
        protected String extension = null;
31
        protected Invocable engine = null;
32
        private String code = null;
33
        private String mainName = "main";
34
        private boolean saved;
35
        private DelegateWeakReferencingObservable delegatedObservable;
36
        
37
        public DefaultScriptingScript(ScriptingManager manager) {
38
                super(manager);
39
                this.setLangName("python");
40
                this.setSaved(true);
41
                this.delegatedObservable = new DelegateWeakReferencingObservable((WeakReferencingObservable) this);
42
        }
43

    
44
        private void launchSyntaxException(Exception exception, int excId, String command) {
45
                System.out.println("[DefaultScriptingScript-launchSyntaxException] "+exception.getMessage()+" "+excId+" "+command);
46
                this.delegatedObservable.notifyObservers(new BaseScriptingNotifycation(this, excId, command, exception));
47
        }
48
        
49
        private void launchCompilingException(Exception exception, int excId, String command) {
50
                this.delegatedObservable.notifyObservers(new BaseScriptingNotifycation(this, excId, command, exception));
51
        }
52

    
53
        public void setSaved(boolean saved) {
54
                this.saved = saved;
55
        }
56
                
57
        public String getCode(){
58
                if (this.code != null){
59
                        return this.code;
60
                }
61
                return DefaultScriptingManager.getStringFromFile(this.getFileResource(this.extension).getAbsolutePath());
62
        }
63
        
64
        public void setCode(String code){
65
                this.code = code;
66
                this.engine = null;
67
                this.setSaved(false);
68
        }
69
        
70
        
71
        public Object run(Object args[]) {
72
                try {
73
                        return this.invokeFunction(this.getMainName(), args);        
74
                } catch (NoSuchMethodException e) {
75
                        this.engine = null;
76
                        launchCompilingException(e,2,this.getId());
77
                        return null;
78
                } catch (Exception e) {
79
                        this.engine = null;
80
                        ScriptException e1;
81
                        if (e.getCause() instanceof PySyntaxError){
82
                                e1 = getScriptExceptionFromPyException((ScriptException) e);
83
                        } else if(e.getCause() instanceof MissingMethodException){
84
                                MissingMethodException mme = (MissingMethodException)e.getCause().getCause();                                        
85
                                e1 = new ScriptException(mme.getMessage(),this.getId(),-1, -1);
86
                        }
87
                        else if(e.getCause() instanceof MultipleCompilationErrorsException){
88
                                MultipleCompilationErrorsException mcee= (MultipleCompilationErrorsException)e.getCause();
89
                                e1 = new ScriptException(mcee.getMessage(),this.getId(),-1, -1);        
90
                        }
91
                        else {
92
                                if(e instanceof ScriptException){
93
                                        e1 = (ScriptException) e;
94
                                }else{
95
                                        e1 = new ScriptException("Runtime exception");
96
                                }
97
                        }
98
                        launchSyntaxException(e1,1,"invoke");
99
                        e.printStackTrace();
100
                        return null;
101
                }
102
        }
103
        
104
        private ScriptException getScriptExceptionFromPyException(ScriptException e){
105
                PySyntaxError syntaxError = (PySyntaxError)e.getCause();
106
                
107
                String message = syntaxError.value.__getitem__(0)+" ";
108
                //String filename = syntaxError.value.__getitem__(1).__getitem__(3).toString();
109
                String line = syntaxError.value.__getitem__(1).__getitem__(1).toString();
110
                String column = syntaxError.value.__getitem__(1).__getitem__(2).toString();
111
                
112
                int l = Integer.parseInt(line);
113
                int c = Integer.parseInt(column);
114
                
115
                return new ScriptException(message,this.getId(),l, c);
116
        }
117

    
118
        protected Invocable getEngine(){
119
                if(this.engine == null){
120
                        this.engine = (Invocable) this.manager.getEngine(this.langName);
121
                        String code = this.getCode();
122
                        ScriptEngine scriptEngine = (ScriptEngine)this.engine;
123
                        scriptEngine.put("script", this);
124
                        try {
125
                                scriptEngine.eval(code);
126
                        } catch (ScriptException e) {
127
                                ScriptException e1;
128
                                if (e.getCause() instanceof PySyntaxError){
129
                                        e1 = getScriptExceptionFromPyException(e);
130
                                } else if(e.getCause() instanceof MultipleCompilationErrorsException){
131
                                        MultipleCompilationErrorsException mcee= (MultipleCompilationErrorsException)e.getCause();
132
                                        e1 = new ScriptException(mcee.getMessage(),this.getId(),-1, -1);        
133
                                }
134
                                else if(e.getCause().getCause() instanceof MissingMethodException){
135
                                        MissingMethodException mme = (MissingMethodException)e.getCause().getCause();
136
                                        e1 = new ScriptException(mme.getMessage(),this.getId(),-1, -1);
137
                                }
138
                                else{
139
                                        e1 = e;
140
                                }
141
                                launchSyntaxException(e1,1,"eval");
142
                        }
143
                }
144
                return this.engine;
145
        }
146
        
147

    
148
        protected void loadInf(Ini prefs){
149
                super.loadInf(prefs);
150
                
151
                this.setMainName((String) getInfValue(prefs,"Script","main", "main"));
152
                this.setLangName((String) getInfValue(prefs,"Script","Lang", this.getLangName()));
153
        }
154
        
155
        public void load(ScriptingFolder folder, String id) {
156
                this.setId(id);
157
                this.setParent(folder);                
158
                
159
                Map languages = this.manager.getSupportedLanguagesByExtension();
160
                String s[] = id.split("\\.");
161
                if(s.length>=2){
162
                        String extension ="." +  s[s.length-1];
163
                        String langName = (String) languages.get(extension);
164
                        this.setLangName(langName);
165
                        this.setExtension(extension);
166
                }
167
                
168
                File f = getFileResource(".inf");
169
                if (f.isFile()){
170
                        Ini prefs = null;
171
                        
172
                        try {
173
                                prefs = new Ini(f);
174
                        } catch (InvalidFileFormatException e) {
175
                                e.printStackTrace();
176
                        } catch (IOException e) {
177
                                e.printStackTrace();
178
                        }
179
                        
180
                        loadInf(prefs);
181
                }
182
                this.setSaved(true);
183
        }
184

    
185
        public void save(){
186
                File f = getFileResource(".inf");
187
                if(!f.isFile()){
188
                        try {
189
                                f.createNewFile();
190
                        } catch (IOException e) {
191
                                e.printStackTrace();
192
                        }
193
                }
194

    
195
                Ini prefs = null;
196

    
197
                try {
198
                        prefs = new Ini(f);
199
                } catch (InvalidFileFormatException e) {
200
                        e.printStackTrace();
201
                } catch (IOException e) {
202
                        e.printStackTrace();
203
                }
204

    
205
                save(prefs);
206

    
207
                // Guardo el código en el fichero
208
                try{
209
                        FileWriter fstream = new FileWriter(((DefaultScriptingFolder)this.getParent()).getPath()+File.separator+this.getId()+this.getExtension());
210
                        BufferedWriter out = new BufferedWriter(fstream);
211
                        out.write(this.getCode());
212
                        out.close();
213
                }catch (Exception e){
214
                        System.err.println("Error: " + e.getMessage());
215
                }
216
                this.setSaved(true);
217
        }
218

    
219
        
220
        protected void save(Ini prefs){
221
                super.save(prefs);
222
                prefs.put("Script","main", this.getMainName());
223
                prefs.put("Script","Lang", this.getLangName());
224
                try {
225
                        prefs.store();
226
                } catch (IOException e) {
227
                        // TODO Auto-generated catch block
228
                        e.printStackTrace();
229
                }
230

    
231
        }
232
                
233
        public Object invokeFunction(String name, Object args[]) throws NoSuchMethodException{
234
                Invocable engine = getEngine();
235
                try {
236
                        return engine.invokeFunction(name, args);
237
                } catch (ScriptException e) {
238
                        throw new RuntimeException(e);
239
                } catch (NoSuchMethodException e) {
240
                        throw e;
241
                }
242
        }
243
        
244
        public Object invokeMethod(Object obj, String name, Object[] args) throws NoSuchMethodException {
245
                Invocable engine = getEngine();
246
        
247
                try {
248
                        return engine.invokeMethod(obj, name, args);
249
                } catch (ScriptException e) {
250
                        throw new RuntimeException(e);
251
                } catch (NoSuchMethodException e) {
252
                        throw e;
253
                }
254
        }
255

    
256
        public String getLangName() {
257
                return this.langName;
258
        }
259
        
260
        protected void setLangName(String langName) {
261
                this.langName = langName;
262
                this.extension = this.manager.getExtensionByLanguage(this.langName);
263
        }
264

    
265
        public String[] getIconNames() {
266
                return new String[]{"scripting_"+this.getLangName(), null};
267
        }
268

    
269
        public String getMainName() {
270
                return this.mainName;
271
        }
272

    
273
        public void setMainName(String mainName) {
274
                this.mainName = mainName;
275
        }
276
        
277
        public String getExtension() {
278
                return this.extension;
279
        }
280

    
281
        public void setExtension(String extension) {
282
                this.extension = extension;
283
        }
284

    
285
        public Object run() {
286
                return this.run(null);
287
                
288
        }
289
        public boolean isSaved() {
290
                return this.saved;
291
        }
292
        
293
        public void addObserver(Observer o) {
294
                this.delegatedObservable.addObserver(o);
295
        }
296
        
297
        public void deleteObserver(Observer o) {
298
                this.delegatedObservable.deleteObserver(o);
299
        }
300

    
301
        public void deleteObservers() {
302
                this.delegatedObservable.deleteObservers();
303
        }
304

    
305

    
306
}