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 @ 212

History | View | Annotate | Download (8.29 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.ini4j.Ini;
17
import org.ini4j.InvalidFileFormatException;
18
import org.python.core.PySyntaxError;
19

    
20
import org.gvsig.scripting.ScriptingFolder;
21
import org.gvsig.scripting.ScriptingManager;
22
import org.gvsig.scripting.ScriptingScript;
23
import org.gvsig.tools.observer.Observer;
24
import org.gvsig.tools.observer.impl.DelegateWeakReferencingObservable;
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 final DelegateWeakReferencingObservable delegatedObservable;
36
        
37
        public DefaultScriptingScript(ScriptingManager manager) {
38
                super(manager);
39
                this.setLangName("python");
40
                this.setSaved(true);
41
                this.delegatedObservable = new DelegateWeakReferencingObservable(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
        @Override
149
    protected void loadInf(Ini prefs){
150
                super.loadInf(prefs);
151
                
152
                this.setMainName((String) getInfValue(prefs,"Script","main", "main"));
153
                this.setLangName((String) getInfValue(prefs,"Script","Lang", this.getLangName()));
154
        }
155
        
156
        @Override
157
    public void load(ScriptingFolder folder, String id) {
158
                this.setId(id);
159
                this.setParent(folder);                
160
                
161
        Map<String, String> languages =
162
            this.manager.getSupportedLanguagesByExtension();
163
                String s[] = id.split("\\.");
164
                if(s.length>=2){
165
                        String extension ="." +  s[s.length-1];
166
                        String langName = languages.get(extension);
167
                        this.setLangName(langName);
168
                        this.setExtension(extension);
169
                }
170
                
171
                File f = getFileResource(".inf");
172
                if (f.isFile()){
173
                        Ini prefs = null;
174
                        
175
                        try {
176
                                prefs = new Ini(f);
177
                        } catch (InvalidFileFormatException e) {
178
                                e.printStackTrace();
179
                        } catch (IOException e) {
180
                                e.printStackTrace();
181
                        }
182
                        
183
                        loadInf(prefs);
184
                }
185
                this.setSaved(true);
186
        }
187

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

    
198
                Ini prefs = null;
199

    
200
                try {
201
                        prefs = new Ini(f);
202
                } catch (InvalidFileFormatException e) {
203
                        e.printStackTrace();
204
                } catch (IOException e) {
205
                        e.printStackTrace();
206
                }
207

    
208
                save(prefs);
209

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

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

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

    
260
        public String getLangName() {
261
                return this.langName;
262
        }
263
        
264
        protected void setLangName(String langName) {
265
                this.langName = langName;
266
                this.extension = this.manager.getExtensionByLanguage(this.langName);
267
        }
268

    
269
        public String[] getIconNames() {
270
                return new String[]{"scripting_"+this.getLangName(), null};
271
        }
272

    
273
        public String getMainName() {
274
                return this.mainName;
275
        }
276

    
277
        public void setMainName(String mainName) {
278
                this.mainName = mainName;
279
        }
280
        
281
        public String getExtension() {
282
                return this.extension;
283
        }
284

    
285
        public void setExtension(String extension) {
286
                this.extension = extension;
287
        }
288

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

    
305
        public void deleteObservers() {
306
                this.delegatedObservable.deleteObservers();
307
        }
308

    
309

    
310
}