Revision 1023 org.gvsig.scripting/trunk/org.gvsig.scripting/org.gvsig.scripting.lib/org.gvsig.scripting.lib.impl/src/main/java/org/gvsig/scripting/impl/DefaultScriptingScript.java

View differences:

DefaultScriptingScript.java
1 1
package org.gvsig.scripting.impl;
2 2

  
3
import groovy.lang.GroovyClassLoader;
4
import groovy.util.GroovyScriptEngine;
3 5
import java.io.File;
4 6
import java.io.IOException;
5 7
import java.io.InputStream;
6 8
import java.io.PrintStream;
7 9
import java.io.Writer;
10
import java.net.URL;
8 11
import java.nio.charset.Charset;
9 12
import java.util.ArrayList;
13
import java.util.Arrays;
10 14
import java.util.HashSet;
15
import java.util.LinkedHashSet;
11 16
import java.util.List;
12 17
import java.util.Set;
18
import java.util.concurrent.locks.ReentrantLock;
13 19

  
14 20
import javax.script.Compilable;
15 21
import javax.script.CompiledScript;
......
35 41
import org.gvsig.tools.observer.impl.DelegateWeakReferencingObservable;
36 42
import org.gvsig.tools.task.AbstractMonitorableTask;
37 43
import org.ini4j.Ini;
44
import org.python.core.Py;
38 45
import org.python.core.PyException;
39 46
import org.python.core.PyString;
47
import org.python.core.PySystemState;
40 48
import org.python.core.PyTraceback;
49
import org.python.core.imp;
50
import org.python.jsr223.MyPyScriptEngine;
41 51
import org.slf4j.Logger;
42 52
import org.slf4j.LoggerFactory;
43 53

  
44 54
public class DefaultScriptingScript extends AbstractScript implements
45 55
        ScriptingScript {
46 56

  
57
    @SuppressWarnings("FieldNameHidesFieldInSuperclass")
47 58
    private static final Logger logger = LoggerFactory.getLogger(DefaultScriptingScript.class);
48 59
    protected String langName;
49 60
    protected String extension = null;
50 61
    protected String librarySuffix = null;
51 62
    protected ScriptEngine engine = null;
52 63
    protected CompiledScript compiledCode;
64
    protected boolean useSysPath;
53 65

  
54 66
    private String code = null;
55 67
    private String mainName = "main";
......
113 125

  
114 126
    }
115 127

  
128
    @SuppressWarnings("OverridableMethodCallInConstructor")
116 129
    protected DefaultScriptingScript(ScriptingFolder parent, String typename, ScriptingManager manager, String id) {
117 130
        super(parent, typename, manager, id);
131
        this.useSysPath = false;
118 132
        this.setLangName("python");
119 133
        this.setSaved(true);
120 134
        this.delegatedObservable = new DelegateWeakReferencingObservable(this);
......
148 162
    
149 163
    public Object __getattr__(String name) {
150 164
        try {
151
            ScriptEngine engine = this.getEngine();
165
            ScriptEngine theEngine = this.getEngine();
152 166
            this.compile();
153
            return engine.get(name);
167
            return theEngine.get(name);
154 168
        } catch(Exception ex) {
155 169
            return null;
156 170
        }
157 171
    }
158 172

  
159 173
    public void __setattr__(String name, Object value) {
160
        ScriptEngine engine = this.getEngine();
174
        ScriptEngine theEngine = this.getEngine();
161 175
        this.compile();
162
        engine.put(name, value);
176
        theEngine.put(name, value);
163 177
    }
164 178

  
165 179
    public Object __call__() {
......
235 249
    }
236 250
    
237 251
    protected String getCodeToInitializeEngine() {
238
        String name = "org/gvsig/scripting/langs/"+this.getLangName().toLowerCase()+"/init.txt";
252
        String initName = "org/gvsig/scripting/langs/"+this.getLangName().toLowerCase()+"/init.txt";
239 253
        try {
240
            InputStream template = this.getClass().getClassLoader().getResourceAsStream(name);
254
            InputStream template = this.getClass().getClassLoader().getResourceAsStream(initName);
241 255
            if( template == null ) {
242 256
                return null;
243 257
            }
244 258
            List<String> lines = IOUtils.readLines(template);
245 259
            return StringUtils.join(lines, "\n");
246 260
        } catch (Exception ex) {
247
            logger.warn("Can't load code to initialize the script from '"+name+".",ex);
261
            logger.warn("Can't load code to initialize the script from '"+initName+".",ex);
248 262
            return null;
249 263
        }
250 264
    }
251 265

  
266
    private List<URL> getClassPath() {
267
        Set<URL> classPath = new HashSet<>();
268
        
269
        try {
270
//            ClassLoader myloader = this.getClass().getClassLoader();
271
//            if( myloader instanceof URLClassLoader) {
272
//                classPath.addAll(Arrays.asList(((URLClassLoader) myloader).getURLs()));
273
//            }
274
            URL url;
275
            if( StringUtils.isEmpty(this.getIsolationGroup()) ) {
276
                url = this.getFile().getParentFile().getCanonicalFile().toURI().toURL();
277
                classPath.add(url);
278
            }
279
            
280
            url = this.getManager().getUserFolder().getFile().getCanonicalFile().toURI().toURL();
281
            classPath.add(url);
282

  
283
            List<File> folders = getLibFolders();
284
            if( folders!=null ) {
285
                for (File folder : folders) {
286
                    url = folder.getAbsoluteFile().toURI().toURL();
287
                    classPath.add(url);
288
                }
289
            }
290
            
291
            ScriptingFolder folders2 = getManager().getSystemFolder();
292
            if( folders2!=null ) {
293
                for (ScriptingUnit folder : folders2.getUnits()) {
294
                    url = folder.getFile().getCanonicalFile().toURI().toURL();
295
                    classPath.add(url);
296
                }
297
            }
298
        } catch(Exception ex) {
299
            
300
        }
301
        return new ArrayList<>(classPath);
302
    }
303
    
304
    private void addClassPathToEngine(ScriptEngine engine, List<URL> classPath) {
305
        if( engine instanceof MyPyScriptEngine ) {
306
            PySystemState sys = Py.getSystemState();
307
            if( this.useSysPath ) {
308
//                logger.info("Running without sys.classLoader, "+ this.getFile().getAbsolutePath()+".");
309
//                ReentrantLock importLock =sys.getImportLock();
310
//                importLock.lock();
311
//                try {
312
                    Set<String> paths = new LinkedHashSet<>();
313
                    for( int i=0; i<sys.path.size(); i++) {
314
                        String path = (String) sys.path.get(i);
315
                        paths.add(path);
316
                    }
317
                    for (URL url : classPath) {
318
                        String path = FileUtils.toFile(url).getAbsolutePath();
319
                        if( !paths.contains(path) ) {
320
                            sys.path.add( Py.newString(path));
321
                        }
322
                    }
323
//                } finally {
324
//                    importLock.unlock();
325
//                }
326
            } else {
327
                ClassLoader loader = sys.getClassLoader();
328
                if( loader == null ) {
329
                    ClassLoader parentClassLoader = imp.getParentClassLoader();
330
                    loader = new MutableURLClassLoader(classPath, parentClassLoader);
331
                    sys.setClassLoader(loader);
332
                } else if( loader instanceof MutableURLClassLoader ) {
333
                    ((MutableURLClassLoader) loader).addUrls(classPath);
334
                }
335
            }
336

  
337
        } else if( engine instanceof GroovyScriptEngine ) {
338
            GroovyClassLoader loader = ((GroovyScriptEngine)engine).getGroovyClassLoader();
339
            Set<URL> urls = new HashSet(); 
340
            urls.addAll(Arrays.asList(loader.getURLs()));
341
            for (URL url : classPath) {
342
                if( ! urls.contains(url) ) {
343
                    loader.addURL(url);
344
                }
345
            }
346
        }
347
    }
348

  
252 349
    public ScriptEngine getEngine() {
253 350
        if (this.engine == null) {
254 351
            synchronized(this.getManager()) {
255 352
                ScriptEngine scriptEngine = this.manager.getEngineByLanguage(langName, this.getIsolationGroup());
256

  
353
                addClassPathToEngine(scriptEngine,getClassPath());
354
                
257 355
                scriptEngine.put("script", this);
258 356
                scriptEngine.put("Main", Main.class);
259 357
                scriptEngine.getContext().setWriter(stdout);
260 358
                scriptEngine.getContext().setErrorWriter(stderr);
261 359

  
262 360
                this.engine = scriptEngine;
263
                String code = this.getCodeToInitializeEngine();
264
                if (code != null) {
361
                String theCode = this.getCodeToInitializeEngine();
362
                if (theCode != null) {
265 363
                    try {
266
                        this.engine.eval(code);
364
                        this.engine.eval(theCode);
267 365
                    } catch (Exception ex) {
268
                        logger.warn("Can't initialize engine with the code:\n" + code, ex);
366
                        logger.warn("Can't initialize engine with the code:\n" + theCode, ex);
269 367
                    }
270 368
                }
271 369
            }
......
280 378
        this.setMainName((String) getInfValue(prefs, "Script", "main", "main"));
281 379
        this.setLangName((String) getInfValue(prefs, "Script", "Lang",this.getLangName()));
282 380
        this.setLibrarySuffix((String) getInfValue(prefs, "Script", "LibraryVersion",null));
381
        this.useSysPath = getInfBoolean(prefs, "Script", "useSysPath", false);
283 382
    }
284 383

  
285 384
    @Override
......
287 386
        this.setId(id);
288 387
        this.setParent(folder);
289 388

  
290
        String extension = FilenameUtils.getExtension(id);
291
        if( extension != null ) {
292
            String language = this.manager.getLanguageOfExtension(extension);
389
        String theExtension = FilenameUtils.getExtension(id);
390
        if( theExtension != null ) {
391
            String language = this.manager.getLanguageOfExtension(theExtension);
293 392
            if( language != null ) {
294 393
                this.setLangName(language);
295 394
            }
296
            this.setExtension(extension);
395
            this.setExtension(theExtension);
297 396
        }
298 397
        File f = getFileResource(".inf");
299 398
        if (f.isFile()) {
......
345 444
        super.save(prefs);
346 445
        prefs.put("Script", "main", this.getMainName());
347 446
        prefs.put("Script", "Lang", this.getLangName());
447
        if( this.useSysPath ) {
448
            prefs.put("Script", "useSysPath", this.useSysPath);
449
        }
348 450
        try {
349 451
            prefs.store();
350 452
        } catch (IOException e) {
......
427 529
    @Override
428 530
    public void compile() {
429 531
        if (this.compiledCode == null) {
430
            ScriptEngine engine = this.getEngine();
431
            if (engine instanceof Compilable) {
532
            ScriptEngine theEngine = this.getEngine();
533
            if (theEngine instanceof Compilable) {
432 534
                try {
433
                    Compilable compilable = (Compilable) engine;
434
                    String code = this.getCode();
535
                    Compilable compilable = (Compilable) theEngine;
536
                    String theCode = this.getCode();
435 537
                    if( "python".equalsIgnoreCase(this.getLangName()) ) {
436 538
                        // If a Unicode string with a coding declaration is passed to compile(),
437 539
                        // a SyntaxError will be raised, but this is necessary to import from 
438 540
                        // another module, so we remove it.
439 541
                        // http://bugs.jython.org/issue1696
440
                        code = code.replaceFirst("^\\s*#([^:\\n]*)coding:","#$1 c-o-d-i-n-g:");
542
                        theCode = theCode.replaceFirst("^\\s*#([^:\\n]*)coding:","#$1 c-o-d-i-n-g:");
441 543
                    }
442
                    this.compiledCode = compilable.compile(code);
443
                    if( engine instanceof Invocable) {
544
                    this.compiledCode = compilable.compile(theCode);
545
                    if( theEngine instanceof Invocable) {
444 546
                        this.compiledCode.eval();
445 547
                    }
446 548
                } catch (ScriptException e) {
......
460 562
                    throw ce;
461 563
                }
462 564
            } else {
463
                String code = this.getCode();
565
                String theCode = this.getCode();
464 566
                try {
465
                    engine.eval(code);
567
                    theEngine.eval(theCode);
466 568
                } catch (ScriptException e) {
467 569
                    Object[] location = this.getLocation(e);
468 570
                    CompileErrorException ce = new CompileErrorException(
......
743 845
    }
744 846

  
745 847
    public String getNewTemplate() {
746
        String name = "org/gvsig/scripting/langs/"+this.getLangName().toLowerCase()+"/new_template.txt";
848
        String theTemplateName = "org/gvsig/scripting/langs/"+this.getLangName().toLowerCase()+"/new_template.txt";
747 849
        try {
748
            InputStream template = this.getClass().getClassLoader().getResourceAsStream(name);
850
            InputStream template = this.getClass().getClassLoader().getResourceAsStream(theTemplateName);
749 851
            if( template == null ) {
750 852
                return null;
751 853
            }
752 854
            List<String> lines = IOUtils.readLines(template);
753 855
            return StringUtils.join(lines, "\n");
754 856
        } catch (Exception ex) {
755
            logger.warn("Can't load new-template from '"+name+"'.",ex);
857
            logger.warn("Can't load new-template from '"+theTemplateName+"'.",ex);
756 858
            return null;
757 859
        }
758 860
    }

Also available in: Unified diff