Statistics
| Revision:

gvsig-scripting / org.gvsig.scripting / trunk / org.gvsig.scripting / org.gvsig.scripting.lib / org.gvsig.scripting.lib.impl / src / main / java / org / gvsig / scripting / impl / DefaultScriptingManager.java @ 1120

History | View | Annotate | Download (27.9 KB)

1 164 jobacas
package org.gvsig.scripting.impl;
2
3
import java.io.File;
4 669 jjdelcerro
import java.io.IOException;
5 1068 jjdelcerro
import java.net.URI;
6 164 jobacas
import java.util.ArrayList;
7 468 jjdelcerro
import java.util.Collections;
8 164 jobacas
import java.util.HashMap;
9
import java.util.Iterator;
10
import java.util.List;
11
import java.util.Map;
12 799 jjdelcerro
import java.util.Set;
13 1120 jjdelcerro
import java.util.regex.Matcher;
14
import java.util.regex.Pattern;
15 164 jobacas
16
import javax.script.ScriptContext;
17
import javax.script.ScriptEngine;
18 220 cordinyana
import javax.script.ScriptEngineFactory;
19 164 jobacas
import javax.script.ScriptEngineManager;
20
import javax.script.SimpleBindings;
21
import javax.swing.ImageIcon;
22 1120 jjdelcerro
import org.apache.commons.io.IOUtils;
23 164 jobacas
24 799 jjdelcerro
import org.apache.commons.lang3.StringUtils;
25 1084 jjdelcerro
import org.gvsig.scripting.DataFolderFound;
26 164 jobacas
import org.gvsig.scripting.ScriptingBaseScript;
27
import org.gvsig.scripting.ScriptingDialog;
28 702 jjdelcerro
import org.gvsig.scripting.ScriptingExternalFile;
29 164 jobacas
import org.gvsig.scripting.ScriptingFolder;
30
import org.gvsig.scripting.ScriptingManager;
31
import org.gvsig.scripting.ScriptingScript;
32
import org.gvsig.scripting.ScriptingUnit;
33 1084 jjdelcerro
import org.gvsig.tools.packageutils.Version;
34 1120 jjdelcerro
import org.gvsig.tools.resourcesstorage.ResourcesStorage;
35 630 jjdelcerro
import org.gvsig.tools.script.Script;
36 468 jjdelcerro
import org.gvsig.tools.service.spi.ProviderFactory;
37 1084 jjdelcerro
import org.gvsig.tools.util.FolderSet;
38 679 jjdelcerro
import org.python.jsr223.MyPyScriptEngine;
39 301 jjdelcerro
import org.slf4j.Logger;
40
import org.slf4j.LoggerFactory;
41 164 jobacas
42 630 jjdelcerro
43 1084 jjdelcerro
@SuppressWarnings("UseSpecificCatch")
44 464 jjdelcerro
public class DefaultScriptingManager implements ScriptingManager {
45 164 jobacas
46 468 jjdelcerro
    public static class RegisterSystemFolder {
47
48
        public String name;
49
        public File folder;
50
51
        public RegisterSystemFolder(String name, File folder) {
52
            this.name = name;
53
            this.folder = folder;
54
        }
55
    }
56
57 814 jjdelcerro
    static final Logger LOG = LoggerFactory
58 464 jjdelcerro
            .getLogger(DefaultScriptingManager.class);
59 799 jjdelcerro
60 212 cordinyana
    protected Map<String, ImageIcon> icons;
61 468 jjdelcerro
    protected List<RegisterSystemFolder> systemFolders = new ArrayList<>();
62 464 jjdelcerro
    protected ScriptEngineManager engineManager = null;
63
    private final SimpleBindings bindings = new SimpleBindings();
64
    private List<String> unitTypes = null;
65 220 cordinyana
    private ClassLoader classLoader = null;
66 799 jjdelcerro
    private final List<File> libFolders = new ArrayList<>();
67 301 jjdelcerro
    private File home = null;
68 799 jjdelcerro
    private final List<ScriptingFolder> alternativeUserFolders = new ArrayList<>();
69 468 jjdelcerro
    private Map<String, String> extensionOfLanguage = null;
70
    private Map<String, String> languageOfExtension = null;
71
    private File packagesFolder;
72 724 jjdelcerro
    private final Map properties = new HashMap();
73 799 jjdelcerro
    private final Map<String,ScriptEngine> engineGroups = new HashMap<>();
74 1084 jjdelcerro
    private DataFolderManager dataFolderManager = null;
75
    private ScriptingFolder userFolder = null;
76
    private ScriptingFolder systemFolder = null;
77 799 jjdelcerro
78 1020 jjdelcerro
    @SuppressWarnings({"OverridableMethodCallInConstructor", "LeakingThisInConstructor"})
79 220 cordinyana
    public DefaultScriptingManager() {
80 301 jjdelcerro
        this.classLoader = getClass().getClassLoader();
81
        this.setHomeFolder(null);
82
        this.bindings.put("ScriptingManager", this);
83 220 cordinyana
    }
84 164 jobacas
85 220 cordinyana
    public DefaultScriptingManager(ClassLoader classLoader) {
86
        this();
87
        this.classLoader = classLoader;
88
    }
89
90 724 jjdelcerro
    @Override
91
    public Object getProperty(Object key) {
92
        return properties.get(key);
93
    }
94
95
    @Override
96
    public void setProperty(Object key, Object val) {
97
        properties.put(key, val);
98
    }
99
100
    @Override
101
    public Map getExtendedProperties() {
102
        return properties;
103
    }
104
105 464 jjdelcerro
    private void createFolder(File f) {
106
        if (!f.exists()) {
107
            try {
108
                FileUtils.forceMkdir(f);
109
                LOG.info("Created scripting folder '" + f.getAbsolutePath() + "'");
110
            } catch (Throwable e) {
111
                LOG.warn("Can't Create scripting folder '" + f.getAbsolutePath() + "'");
112
            }
113
        }
114 301 jjdelcerro
    }
115 220 cordinyana
116 301 jjdelcerro
    private void createDefaultFolders(File home) {
117 464 jjdelcerro
        createFolder(new File(home, "scripts"));
118
        createFolder(new File(home, "lib"));
119 975 jjdelcerro
        createFolder(new File(home, "data"));
120 220 cordinyana
    }
121 464 jjdelcerro
122 468 jjdelcerro
    @Override
123 301 jjdelcerro
    public File getHomeFolder() {
124 464 jjdelcerro
        if (!this.home.exists()) {
125
            createFolder(home);
126
            createDefaultFolders(home);
127
        }
128
        return this.home;
129 301 jjdelcerro
    }
130 464 jjdelcerro
131 468 jjdelcerro
    @Override
132 301 jjdelcerro
    public void setHomeFolder(File home) {
133 464 jjdelcerro
        if (home == null) {
134
            this.home = new File(System.getProperty("user.home"), ".gvsig-scripting");
135
        } else {
136
            this.home = home;
137
        }
138
        createDefaultFolders(this.home);
139
        LOG.info("Set scripting home to '" + this.home.getAbsolutePath() + "'");
140
        this.addLibFolder(new File(this.home, "lib"));
141 301 jjdelcerro
    }
142 975 jjdelcerro
143 1084 jjdelcerro
    private DataFolderManager getDataFolderManager() {
144
        if( this.dataFolderManager==null ) {
145
            this.dataFolderManager = new DataFolderManager(this);
146
        }
147
        return this.dataFolderManager;
148
    }
149
150 986 jjdelcerro
    @Override
151 975 jjdelcerro
    public File getDataFolder(String id) {
152 1084 jjdelcerro
        return this.getDataFolderManager().getDataFolder(id);
153 975 jjdelcerro
    }
154 464 jjdelcerro
155 1084 jjdelcerro
    public void registerDataFolder(ScriptingFolder folderScript, String id ) {
156
        this.getDataFolderManager().registerDataFolder(folderScript, id);
157
    }
158
159
    @Override
160
    public List<DataFolderFound> searchOldVersions(Version currentVersion, FolderSet folder) {
161
        return this.getDataFolderManager().searchOldVersions(currentVersion, folder);
162
    }
163
164 799 jjdelcerro
    protected synchronized ScriptEngineManager getEngineManager() {
165 464 jjdelcerro
        if (this.engineManager == null) {
166
            this.engineManager
167
                    = classLoader == null ? new ScriptEngineManager()
168
                            : new ScriptEngineManager(classLoader);
169 220 cordinyana
            showEnginesInfo(engineManager);
170 464 jjdelcerro
        }
171
        return this.engineManager;
172
    }
173
174 220 cordinyana
    private void showEnginesInfo(ScriptEngineManager mgr) {
175
        if (LOG.isInfoEnabled()) {
176
            List<ScriptEngineFactory> factories = mgr.getEngineFactories();
177 468 jjdelcerro
            StringBuilder buffer = new StringBuilder();
178
            List<Object> values = new ArrayList<>();
179 220 cordinyana
            buffer.append("Scripting engines available:");
180
            for (ScriptEngineFactory factory : factories) {
181
182
                // Main engine info
183
                buffer
184 464 jjdelcerro
                        .append("\n- {}: version = {}, language = {}, langVersion = {}");
185 220 cordinyana
                values.add(factory.getEngineName());
186
                values.add(factory.getEngineVersion());
187
                values.add(factory.getLanguageName());
188
                values.add(factory.getLanguageVersion());
189
190
                // Aliases
191
                buffer.append("\n\t- Aliases: ");
192
                List<String> engNames = factory.getNames();
193
                int size = engNames.size();
194
                for (String name : engNames) {
195
                    size--;
196
                    buffer.append("{}");
197
                    if (size > 0) {
198
                        buffer.append(", ");
199
                    }
200
                    values.add(name);
201
                }
202
                buffer.append("\n\t- File extensions: ");
203
                List<String> extNames = factory.getExtensions();
204
                size = extNames.size();
205
                for (String name : extNames) {
206
                    size--;
207
                    buffer.append("{}");
208
                    if (size > 0) {
209
                        buffer.append(", ");
210
                    }
211
                    values.add(name);
212
                }
213
                buffer.append("\n\t- Mime types: ");
214
                List<String> mimeNames = factory.getMimeTypes();
215
                size = mimeNames.size();
216
                for (String name : mimeNames) {
217
                    size--;
218
                    buffer.append("{}");
219
                    if (size > 0) {
220
                        buffer.append(", ");
221
                    }
222
                    values.add(name);
223
                }
224
225
            }
226
            LOG.info(buffer.toString(), values.toArray());
227
        }
228
    }
229
230 799 jjdelcerro
    @Override
231
    public synchronized void loadEngines() {
232 583 jjdelcerro
        this.getEngineManager();
233
    }
234
235 799 jjdelcerro
    private ScriptEngine createJythonEngine() {
236
        ScriptEngineFactory factory = this.getEngineFactoryByLanguage(PYTHON_LANGUAGE_NAME);
237 679 jjdelcerro
        ScriptEngine engine = new MyPyScriptEngine(factory);
238 464 jjdelcerro
        return engine;
239
    }
240 679 jjdelcerro
241 464 jjdelcerro
    public ImageIcon getIcon(String name) {
242
        return this.icons.get(name);
243
    }
244
245 468 jjdelcerro
    @Override
246
    public String getEngineNameByLanguage(String langName) {
247 679 jjdelcerro
        ScriptEngineFactory factory = this.getEngineFactoryByLanguage(langName);
248
        if( factory == null ) {
249
            return null;
250
        }
251
        return factory.getEngineName();
252
    }
253 799 jjdelcerro
254
    public ScriptEngine getEngineByLanguage(String langName) {
255
        return this.getEngineByLanguage(langName, null);
256 724 jjdelcerro
    }
257 799 jjdelcerro
258
    public synchronized ScriptEngine getEngineByLanguage(String langName, String isolationGroup) {
259
        ScriptEngine engine = null;
260
        if( !StringUtils.isEmpty(isolationGroup) ) {
261
            isolationGroup += "-" + langName;
262
            engine = this.engineGroups.get(isolationGroup.toLowerCase());
263
        }
264
        if( engine == null ) {
265
            if( PYTHON_LANGUAGE_NAME.equalsIgnoreCase(langName) ) {
266
                engine = createJythonEngine();
267
            } else {
268
                ScriptEngineFactory factory = this.getEngineFactoryByLanguage(langName);
269
                if( factory == null ) {
270
                    return null;
271
                }
272
                engine = factory.getScriptEngine();
273 226 cordinyana
            }
274 1020 jjdelcerro
//            if( SCALA_LANGUAGE_NAME.equalsIgnoreCase(langName) ) {
275
//                try {
276
//                    // https://gist.github.com/takawitter/5479445
277
//                    Object settings = engine.getClass().getMethod("settings", new Class[0]).invoke(engine, new Object[0]);
278
//                    settings.getClass().getMethod("processArgumentString", new Class[] { String.class }).invoke(settings, new String[] { "-usejavacp"});
279
//                } catch(Throwable th) {
280
//                    LOG.warn("Can't initialice scala setting -usejavacp",th);
281
//                }
282
//            }
283 799 jjdelcerro
            if( !StringUtils.isEmpty(isolationGroup) ) {
284
                this.engineGroups.put(isolationGroup.toLowerCase(), engine);
285
            }
286 226 cordinyana
        }
287 679 jjdelcerro
        engine.getBindings(ScriptContext.ENGINE_SCOPE).putAll(bindings);
288
        return engine;
289 464 jjdelcerro
    }
290
291 799 jjdelcerro
    @Override
292
    public synchronized Set<String> getEnginesIsolationGroups() {
293
        return this.engineGroups.keySet();
294
    }
295
296 679 jjdelcerro
    public ScriptEngineFactory getEngineFactoryByLanguage(String langName) {
297 468 jjdelcerro
        List<ScriptEngineFactory> factories
298
                = getEngineManager().getEngineFactories();
299
300
        for (ScriptEngineFactory factory : factories) {
301
            if (factory.getLanguageName().equalsIgnoreCase(langName)) {
302 679 jjdelcerro
                return factory;
303 468 jjdelcerro
            }
304 464 jjdelcerro
        }
305 468 jjdelcerro
        return null;
306 464 jjdelcerro
    }
307
308 468 jjdelcerro
    @Override
309 464 jjdelcerro
    public boolean validateUnitId(ScriptingFolder folder, String id) {
310 724 jjdelcerro
        File f = new File(folder.getFile(),id+".inf");
311 1020 jjdelcerro
        return !f.exists();
312 464 jjdelcerro
    }
313 164 jobacas
314 464 jjdelcerro
    public ScriptingScript createScript(ScriptingFolder folder, String id) {
315
        return this.createScript(folder, id, null);
316
    }
317 630 jjdelcerro
318 799 jjdelcerro
    @Override
319 630 jjdelcerro
    public Script createScript(String name, String code, String languaje) {
320 1120 jjdelcerro
        ScriptingScript script = new DefaultScriptingScript(this.getUserFolder(), this, name, languaje);
321 630 jjdelcerro
        script.setCode(code);
322
        script.setSaved(true);
323
        return script;
324
    }
325 164 jobacas
326 464 jjdelcerro
    private ScriptingScript createScript(ScriptingFolder folder, String id, String language) {
327
        DefaultScriptingScript script = new DefaultScriptingScript(folder, this, id);
328
        if (!script.getFile().exists()) {
329
            script.create(folder, id, language);
330
        } else {
331
            script.load(folder, id);
332
        }
333
        return script;
334
    }
335 164 jobacas
336 464 jjdelcerro
    public ScriptingDialog createDialog(ScriptingFolder folder, String id) {
337
        return this.createDialog(folder, id, null);
338
    }
339 164 jobacas
340 464 jjdelcerro
    private ScriptingDialog createDialog(ScriptingFolder folder, String id, String language) {
341
        DefaultScriptingDialog dialog = new DefaultScriptingDialog(folder, this, id);
342
        if (!dialog.getFile().exists()) {
343
            dialog.create(folder, id, language);
344
        } else {
345
            dialog.load(folder, id);
346
        }
347
        return dialog;
348
    }
349 164 jobacas
350 464 jjdelcerro
    public ScriptingFolder createFolder(ScriptingFolder folder, String id) {
351
        DefaultScriptingFolder unit = new DefaultScriptingFolder(folder, this, new File(folder.getFile(), id));
352 471 jjdelcerro
        unit.load(folder, id);
353 585 jjdelcerro
        if (!unit.getFile().exists()) {
354
            unit.create(folder, id);
355
        }
356 464 jjdelcerro
        return unit;
357
    }
358 164 jobacas
359 702 jjdelcerro
    public ScriptingExternalFile createExternalFile(ScriptingFolder folder, String id) {
360
        DefaultScriptingExternalFile unit = new DefaultScriptingExternalFile(folder, this, id);
361 952 jjdelcerro
        if( unit.getExternalFile()!=null && !unit.getExternalFile().exists() ) {
362
            unit.create(folder, id);
363
        }
364 702 jjdelcerro
        return unit;
365
    }
366
367 468 jjdelcerro
    @Override
368 464 jjdelcerro
    public ScriptingBaseScript getScript(File file) {
369
        ScriptingBaseScript script = (ScriptingBaseScript) this.getUnit(file);
370
        if (script == null) {
371
            throw new ScriptNotFoundException(file);
372
        }
373
        return script;
374
    }
375 1068 jjdelcerro
376
    @Override
377
    public Script loadScript(URI uri) {
378
        File f = new File(uri);
379
        try {
380
            return (Script) this.getScript(f);
381
        } catch(ScriptNotFoundException ex) {
382
            throw ex;
383
        } catch(Throwable th) {
384
            throw new ScriptNotFoundException(f);
385
        }
386
    }
387 164 jobacas
388 1120 jjdelcerro
    private static final Pattern RE_LANG = Pattern.compile(".*lang[:]\\s*([a-zA-Z_][a-zA-Z_0-9]*)");
389
    private static final Pattern RE_ENCODING = Pattern.compile(".*encoding[:]\\s*([a-zA-Z_][a-zA-Z_0-9]*)");
390
391
    public Script loadScript(ResourcesStorage storage, String name) {
392
        ResourcesStorage.Resource res = null;
393
        try {
394
            if( storage==null ) {
395
                return null;
396
            }
397
            res = storage.getResource(name);
398
            if( res == null || !res.exists() ) {
399
                return null;
400
            }
401
            byte[] head_bytes = new byte[500];
402
            IOUtils.read(res.asInputStream(), head_bytes);
403
            IOUtils.closeQuietly(res);
404
            String head = new String(head_bytes);
405
            if( StringUtils.isEmpty(head) ) {
406
                return null;
407
            }
408
            head = StringUtils.split("\n")[0];
409
410
            String lang = "python";
411
            String encoding = null;
412
            Matcher m = RE_LANG.matcher(head);
413
            if( m.groupCount()==1 ) {
414
                String s = m.group(1);
415
                if( !StringUtils.isBlank(s) ) {
416
                    lang = s;
417
                }
418
            }
419
            m = RE_ENCODING.matcher(head);
420
            if( m.groupCount()==1 ) {
421
                String s = m.group(1);
422
                if( !StringUtils.isBlank(s) ) {
423
                    encoding = s;
424
                }
425
            }
426 1068 jjdelcerro
427 1120 jjdelcerro
            String source;
428
            if( StringUtils.isBlank(encoding) ) {
429
                source = IOUtils.toString(res.asInputStream());
430
            } else {
431
                source = IOUtils.toString(res.asInputStream(), encoding);
432
            }
433
            Script script = this.createScript(name, source, lang);
434
            return script;
435
        } catch (Exception ex) {
436
            LOG.warn("Can't load script from resources storage.", ex);
437
            return null;
438
        } finally {
439
            IOUtils.closeQuietly(res);
440
        }
441
    }
442 989 jjdelcerro
443 468 jjdelcerro
    @Override
444 464 jjdelcerro
    public ScriptingFolder getFolder(File file) {
445 989 jjdelcerro
        if( file == null ) {
446
            throw new IllegalArgumentException("file argument can't be null");
447
        }
448
        file = this.getLinkSource(file);
449
        if( FileUtils.isSameFile(this.getRootUserFolder(),file) ) {
450
            return this.getUserFolder();
451
        }
452
453 464 jjdelcerro
        ScriptingFolder folder = (ScriptingFolder) this.getUnit(file);
454
        if (folder == null) {
455 989 jjdelcerro
            throw new IllegalArgumentException("Can't get ScriptFolder from '"+file.getAbsolutePath()+"'.");
456 464 jjdelcerro
        }
457
        return folder;
458
    }
459 301 jjdelcerro
460 1084 jjdelcerro
    public ScriptingUnit getUnit(String pathName) {
461
        ScriptingUnit unit = null;
462
        String[] parts = StringUtils.split(pathName, '/');
463 1085 jjdelcerro
        if( parts[0].equals(this.getUserFolder().getName()) ) {
464 1084 jjdelcerro
            unit = this.getUserFolder().getUnit(
465
                    StringUtils.join(parts, "/", 1, parts.length)
466
            );
467 1085 jjdelcerro
        } else if( parts[0].equals(this.getSystemFolder().getName()) ) {
468 1084 jjdelcerro
            unit = this.getSystemFolder().getUnit(
469
                    StringUtils.join(parts, "/", 1, parts.length)
470
            );
471
        }
472
        return unit;
473
    }
474
475 464 jjdelcerro
    public ScriptingUnit getUnit(File file) {
476 468 jjdelcerro
        ScriptingFolder folder;
477
        ScriptingUnit unit;
478 164 jobacas
479 464 jjdelcerro
        if (file.isAbsolute()) {
480 1084 jjdelcerro
            if( FileUtils.isSameFile(this.getRootUserFolder(), file.getParentFile()) ) {
481
                folder = this.getUserFolder();
482
                // FIXME: que pasa si esta en SystemFolder ???
483
            } else {
484
                folder = new DefaultScriptingFolder(null, this, file.getParentFile());
485
            }
486 464 jjdelcerro
            unit = folder.getUnit(file);
487
            return unit;
488
        } else {
489
            folder = this.getUserFolder();
490
            unit = folder.getUnit(file);
491
            if (unit != null) {
492
                return unit;
493
            }
494 164 jobacas
495 464 jjdelcerro
            folder = this.getSystemFolder();
496
            unit = folder.getUnit(file);
497
            if (unit != null) {
498
                return unit;
499
            }
500
        }
501
        return null;
502
    }
503
504 468 jjdelcerro
    @Override
505 464 jjdelcerro
    public ScriptingFolder getSystemFolder() {
506 1084 jjdelcerro
        if( this.systemFolder == null ) {
507
            this.systemFolder = new SystemFolder(this);
508
        }
509
        return  this.systemFolder;
510 464 jjdelcerro
    }
511
512 468 jjdelcerro
    @Override
513 464 jjdelcerro
    public ScriptingFolder getUserFolder() {
514 1084 jjdelcerro
        if( this.userFolder == null ) {
515
            this.userFolder = new UserFolder(this, this.getRootUserFolder());
516
        }
517
        return  this.userFolder;
518 464 jjdelcerro
    }
519
520 468 jjdelcerro
    @Override
521 464 jjdelcerro
    public ScriptingBaseScript getScript(String name) {
522
        return (ScriptingBaseScript) findScript(null, name);
523
    }
524
525 986 jjdelcerro
    @Override
526 814 jjdelcerro
    public Script locateScript(String name) {
527
        ScriptingUnit script = findScript(null, name);
528
        if( script instanceof Script ) {
529
            return (Script) script;
530
        }
531
        return null;
532
    }
533
534 464 jjdelcerro
    private ScriptingUnit findScript(ScriptingFolder folder, String name) {
535
        if (name == null) {
536
            return null;
537
        }
538
        if (name.trim().length() == 0) {
539
            return null;
540
        }
541 468 jjdelcerro
        ScriptingUnit unit;
542 464 jjdelcerro
        if (folder == null) {
543
            unit = findScript(this.getUserFolder(), name);
544
            if (unit != null) {
545
                return unit;
546
            }
547
            unit = findScript(this.getSystemFolder(), name);
548
            return unit;
549
        }
550
        List<ScriptingUnit> units = folder.getUnits();
551
        Iterator<ScriptingUnit> it = units.iterator();
552
        while (it.hasNext()) {
553
            unit = it.next();
554
            if (unit instanceof ScriptingFolder) {
555
                unit = findScript((ScriptingFolder) unit, name);
556
                if (unit != null) {
557
                    return unit;
558
                }
559
            } else if (unit instanceof ScriptingBaseScript) {
560
                if (name.equalsIgnoreCase(unit.getId())) {
561
                    return unit;
562
                }
563
            }
564
        }
565
        return null;
566
    }
567
568 468 jjdelcerro
    @Override
569 464 jjdelcerro
    public File getRootUserFolder() {
570
        return new File(this.getHomeFolder(), "scripts");
571
    }
572
573 468 jjdelcerro
    @Override
574 464 jjdelcerro
    public void registerSystemFolder(String name, File folder) {
575
        this.systemFolders.add(new RegisterSystemFolder(name, folder));
576
        LOG.info("Register system folder name '" + name + "' folder " + folder.getAbsolutePath() + "'");
577
578
    }
579
580
    public List<RegisterSystemFolder> getSystemFolders() {
581
        return this.systemFolders;
582
    }
583
584 468 jjdelcerro
    @Override
585 465 jjdelcerro
    public List<ScriptingFolder> getAlternativeUserFolders() {
586
        return this.alternativeUserFolders;
587
    }
588
589 468 jjdelcerro
    @Override
590 465 jjdelcerro
    public void addAlternativeUserFolder(File f, String name, String description) {
591
        UserFolder x = new UserFolder(this, f);
592 468 jjdelcerro
        x.setName(name);
593 465 jjdelcerro
        x.setDescription(description);
594 468 jjdelcerro
        x.setId("UserFolder_" + this.alternativeUserFolders.size() + 1);
595 465 jjdelcerro
        this.alternativeUserFolders.add(x);
596
    }
597 478 jjdelcerro
598
    private void initLanguages() {
599 468 jjdelcerro
        if (this.extensionOfLanguage == null) {
600 1020 jjdelcerro
            Map<String, String> theExtensionOfLanguage = new HashMap<>();
601 468 jjdelcerro
            List<ScriptEngineFactory> factories = getEngineManager().getEngineFactories();
602
            for (ScriptEngineFactory factory : factories) {
603 597 jjdelcerro
                if( "ognl".equals(factory.getLanguageName()) ) {
604
                    continue;
605
                }
606 468 jjdelcerro
                List<String> extensions = factory.getExtensions();
607
                if (extensions != null && !extensions.isEmpty()) {
608 1020 jjdelcerro
                    theExtensionOfLanguage.put(
609 468 jjdelcerro
                            factory.getLanguageName().toLowerCase(),
610
                            extensions.get(0).toLowerCase()
611
                    );
612
                }
613
            }
614 1020 jjdelcerro
            this.extensionOfLanguage = theExtensionOfLanguage;
615 464 jjdelcerro
        }
616 478 jjdelcerro
        if (this.languageOfExtension == null) {
617 1020 jjdelcerro
            Map<String, String> theLanguageOfExtension = new HashMap<>();
618 478 jjdelcerro
            List<ScriptEngineFactory> factories = getEngineManager().getEngineFactories();
619
            for (ScriptEngineFactory factory : factories) {
620 597 jjdelcerro
                if( "ognl".equals(factory.getLanguageName()) ) {
621
                    continue;
622
                }
623 478 jjdelcerro
                List<String> extensions = factory.getExtensions();
624
                if (extensions != null) {
625
                    for (String extension1 : extensions) {
626 1020 jjdelcerro
                        theLanguageOfExtension.put(
627 478 jjdelcerro
                                extension1.toLowerCase(),
628
                                factory.getLanguageName().toLowerCase()
629
                        );
630
                    }
631
                }
632
            }
633 1020 jjdelcerro
            this.languageOfExtension = theLanguageOfExtension;
634 478 jjdelcerro
        }
635
    }
636
637
    @Override
638
    public String getExtensionOfLanguage(String langName) {
639 468 jjdelcerro
        if (langName == null) {
640
            return null;
641
        }
642
        langName = langName.toLowerCase();
643 478 jjdelcerro
        initLanguages();
644 468 jjdelcerro
        return this.extensionOfLanguage.get(langName);
645 464 jjdelcerro
    }
646
647 468 jjdelcerro
    @Override
648
    public List<String> getSupportedLanguages() {
649
        List<String> languages = new ArrayList<>();
650 464 jjdelcerro
651 478 jjdelcerro
        initLanguages();
652 468 jjdelcerro
        languages.addAll(this.extensionOfLanguage.keySet());
653
        Collections.sort(languages);
654
        return languages;
655
    }
656 164 jobacas
657 468 jjdelcerro
    public String getLanguageOfExtension(String extension) {
658
        if (extension == null) {
659
            return null;
660 464 jjdelcerro
        }
661 468 jjdelcerro
        extension = extension.toLowerCase();
662
        if (extension.startsWith(".")) {
663
            extension = extension.substring(1);
664
        }
665 478 jjdelcerro
        initLanguages();
666 468 jjdelcerro
        return this.languageOfExtension.get(extension);
667 464 jjdelcerro
    }
668 175 jobacas
669 799 jjdelcerro
    @Override
670 464 jjdelcerro
    public Object get(String key) {
671
        return this.bindings.get(key);
672
    }
673 441 jjdelcerro
674 799 jjdelcerro
    @Override
675 464 jjdelcerro
    public void put(String key, Object value) {
676
        this.bindings.put(key, value);
677 175 jobacas
678 464 jjdelcerro
    }
679 301 jjdelcerro
680 468 jjdelcerro
    @Override
681 464 jjdelcerro
    public ScriptingUnit createUnit(String unitType, ScriptingFolder folder, String id) {
682
        return createUnit(unitType, folder, id, null);
683
    }
684
685 468 jjdelcerro
    @Override
686 464 jjdelcerro
    public ScriptingUnit createUnit(String unitType, ScriptingFolder folder, String id, String language) {
687
        if (unitType.equals(UNIT_SCRIPT)) {
688
            return this.createScript(folder, id, language);
689
        }
690
        if (unitType.equals(UNIT_DIALOG)) {
691
            return this.createDialog(folder, id, language);
692
        }
693
        if (unitType.equals(UNIT_FOLDER)) {
694
            return this.createFolder(folder, id);
695
        }
696 702 jjdelcerro
        if (unitType.equals(UNIT_EXTERNALFILE)) {
697
            return this.createExternalFile(folder, id);
698
        }
699 464 jjdelcerro
        return null;
700
    }
701
702 468 jjdelcerro
    @Override
703 464 jjdelcerro
    public List<String> getUnitTypes() {
704
        if (this.unitTypes == null) {
705 468 jjdelcerro
            this.unitTypes = new ArrayList<>();
706 464 jjdelcerro
            this.unitTypes.add(UNIT_SCRIPT);
707
            this.unitTypes.add(UNIT_DIALOG);
708
            this.unitTypes.add(UNIT_FOLDER);
709 702 jjdelcerro
            this.unitTypes.add(UNIT_EXTERNALFILE);
710 464 jjdelcerro
        }
711
        return this.unitTypes;
712
    }
713
714 468 jjdelcerro
    @Override
715 464 jjdelcerro
    public void addLibFolder(File lib) {
716
        if (lib.exists()) {
717
            LOG.info("Add scripting lib folder '" + lib.getAbsolutePath() + "'");
718
            this.libFolders.add(lib);
719
        } else {
720
            LOG.info("Skip add scripting lib folder '" + lib.getAbsolutePath() + "', folder don't exist");
721
        }
722
    }
723
724 669 jjdelcerro
    @Override
725 464 jjdelcerro
    public List<File> getLibFolders() {
726 669 jjdelcerro
        return new ArrayList(this.libFolders);
727 464 jjdelcerro
    }
728 468 jjdelcerro
729 669 jjdelcerro
    @Override
730
    public Map<String, String> getLibFoldersVersions() {
731
        Map<String, String>versions = new HashMap<>();
732
        List<File> folders = this.getLibFolders();
733
        for (File folder : folders) {
734
            File parent = folder.getParentFile();
735
            File libVersions = new File(parent,folder.getName()+".versions");
736
            if( libVersions.exists() ) {
737
                this.loadLibVersions(versions, libVersions);
738
            }
739
        }
740
        if( versions.isEmpty() ) {
741
            return null;
742
        }
743
        return versions;
744
    }
745
746
    private void loadLibVersions(Map<String,String>versions, File file) {
747
        List<String> lines;
748
        try {
749
            lines = FileUtils.readLines(file);
750
        } catch (IOException ex) {
751
            LOG.warn("Can't load lib versions from '"+file+".",ex);
752
            return;
753
        }
754
        for (String line : lines) {
755
            String[] x = line.split("=");
756
            if( x.length==2 ) {
757
                versions.put(x[0], x[1]);
758
            }
759
        }
760
    }
761
762
    @Override
763 468 jjdelcerro
    public ProviderFactory getInstallerFactory() {
764
        return new ScriptingInstallerProviderFactory();
765
    }
766
767 799 jjdelcerro
    @Override
768 468 jjdelcerro
    public File getPackagesFolder() {
769
        return this.packagesFolder;
770
    }
771
772
    @Override
773
    public void setPackagesFolder(File folder) {
774
        this.packagesFolder = folder;
775
    }
776
777 989 jjdelcerro
    @Override
778
    public ScriptingFolder createLink(String name, File link, String targetPathName) {
779
        StringBuilder contents = new StringBuilder();
780
        contents.append("[Unit]\n")
781
            .append("type = Folder\n")
782
            .append("name = ").append(name).append("\n")
783
            .append("description =\n")
784
            .append("createdBy =\n")
785
            .append("version =\n")
786
            .append("\n")
787
            .append("[Folder]\n")
788
            .append("path =").append(targetPathName).append("\n")
789
            .append("\n\n");
790
791
        if( link.isDirectory() ) {
792
            link = new File(link,name+".inf");
793
        } else if( !link.getName().endsWith(".inf") ) {
794
            link = new File( link.getPath() + ".inf");
795
        }
796
        if( !link.exists() ) {
797
            try {
798
                FileUtils.writeStringToFile(link, contents.toString());
799
            } catch (IOException ex) {
800
                LOG.warn("Can't create ScriptingFolder file in '" + link.getAbsolutePath() + "'.", ex);
801
            }
802
        }
803
        ScriptingFolder folder = this.getFolder(link);
804
        return folder;
805
    }
806
807
    @Override
808
    public ScriptingFolder createLink(String name, ScriptingFolder link, String targetPathName) {
809
        return this.createLink(name, link.getFile(), targetPathName);
810
    }
811
812 1020 jjdelcerro
    private final Map<File,File> links = new HashMap<>();
813 989 jjdelcerro
814
    public void addLink(File source, File target) {
815
        this.links.put(FileUtils.getRealFile(target), source);
816
    }
817
818
    public File getLinkSource(File target) {
819
        File source = this.links.get(FileUtils.getRealFile(target));
820
        if( source == null ) {
821
            return target;
822
        }
823
        if( source.exists() ) {
824
            return source;
825
        }
826
        return target;
827
    }
828
829
    public boolean isInUserFolder(File f) {
830
        if( FileUtils.isSubfolder(this.getRootUserFolder(), f) ) {
831
            return true;
832
        }
833
        for( File file : this.links.keySet()) {
834
            if( FileUtils.isSubfolder(file, f) ) {
835
                return true;
836
            }
837
        }
838
        return false;
839
    }
840 164 jobacas
}