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

History | View | Annotate | Download (17.1 KB)

1
package org.gvsig.scripting.impl;
2

    
3
import java.io.File;
4
import java.util.ArrayList;
5
import java.util.Collections;
6
import java.util.HashMap;
7
import java.util.Iterator;
8
import java.util.List;
9
import java.util.Map;
10

    
11
import javax.script.ScriptContext;
12
import javax.script.ScriptEngine;
13
import javax.script.ScriptEngineFactory;
14
import javax.script.ScriptEngineManager;
15
import javax.script.SimpleBindings;
16
import javax.swing.ImageIcon;
17

    
18
import org.apache.commons.io.FileUtils;
19
import org.apache.commons.io.FilenameUtils;
20
import org.gvsig.scripting.ScriptingBaseScript;
21
import org.gvsig.scripting.ScriptingDialog;
22
import org.gvsig.scripting.ScriptingFolder;
23
import org.gvsig.scripting.ScriptingHelpManager;
24
import org.gvsig.scripting.ScriptingManager;
25
import org.gvsig.scripting.ScriptingScript;
26
import org.gvsig.scripting.ScriptingUnit;
27
import org.gvsig.tools.service.spi.ProviderFactory;
28
import org.slf4j.Logger;
29
import org.slf4j.LoggerFactory;
30

    
31
public class DefaultScriptingManager implements ScriptingManager {
32

    
33
    public static class RegisterSystemFolder {
34

    
35
        public String name;
36
        public File folder;
37

    
38
        public RegisterSystemFolder(String name, File folder) {
39
            this.name = name;
40
            this.folder = folder;
41
        }
42
    }
43

    
44
    private static final Logger LOG = LoggerFactory
45
            .getLogger(DefaultScriptingManager.class);
46

    
47
    protected Map<String, ImageIcon> icons;
48
    protected List<RegisterSystemFolder> systemFolders = new ArrayList<>();
49
    protected ScriptEngineManager engineManager = null;
50
    private final SimpleBindings bindings = new SimpleBindings();
51
    private ScriptingHelpManager helpManager = null;
52
    private List<String> unitTypes = null;
53
    private ClassLoader classLoader = null;
54
    private List<File> libFolders = new ArrayList<>();
55
    private File home = null;
56
    private List<ScriptingFolder> alternativeUserFolders = new ArrayList<>();
57
    private Map<String, String> extensionOfLanguage = null;
58
    private Map<String, String> languageOfExtension = null;
59
    private File packagesFolder;
60

    
61
    public DefaultScriptingManager() {
62
        this.classLoader = getClass().getClassLoader();
63
        this.setHomeFolder(null);
64
        this.bindings.put("ScriptingManager", this);
65
    }
66

    
67
    public DefaultScriptingManager(ClassLoader classLoader) {
68
        this();
69
        this.classLoader = classLoader;
70
    }
71

    
72
    private void createFolder(File f) {
73
        if (!f.exists()) {
74
            try {
75
                FileUtils.forceMkdir(f);
76
                LOG.info("Created scripting folder '" + f.getAbsolutePath() + "'");
77
            } catch (Throwable e) {
78
                LOG.warn("Can't Create scripting folder '" + f.getAbsolutePath() + "'");
79
            }
80
        }
81
    }
82

    
83
    private void createDefaultFolders(File home) {
84
        createFolder(new File(home, "scripts"));
85
        createFolder(new File(home, "help"));
86
        createFolder(new File(home, "lib"));
87
    }
88

    
89
    @Override
90
    public File getHomeFolder() {
91
        if (!this.home.exists()) {
92
            createFolder(home);
93
            createDefaultFolders(home);
94
        }
95
        return this.home;
96
    }
97

    
98
    @Override
99
    public void setHomeFolder(File home) {
100
        if (home == null) {
101
            this.home = new File(System.getProperty("user.home"), ".gvsig-scripting");
102
        } else {
103
            this.home = home;
104
        }
105
        createDefaultFolders(this.home);
106
        LOG.info("Set scripting home to '" + this.home.getAbsolutePath() + "'");
107
        this.addLibFolder(new File(this.home, "lib"));
108
    }
109

    
110
    protected ScriptEngineManager getEngineManager() {
111
        if (this.engineManager == null) {
112
            this.engineManager
113
                    = classLoader == null ? new ScriptEngineManager()
114
                            : new ScriptEngineManager(classLoader);
115
            showEnginesInfo(engineManager);
116
        }
117
        return this.engineManager;
118
    }
119

    
120
    private void showEnginesInfo(ScriptEngineManager mgr) {
121
        if (LOG.isInfoEnabled()) {
122
            List<ScriptEngineFactory> factories = mgr.getEngineFactories();
123
            StringBuilder buffer = new StringBuilder();
124
            List<Object> values = new ArrayList<>();
125
            buffer.append("Scripting engines available:");
126
            for (ScriptEngineFactory factory : factories) {
127

    
128
                // Main engine info
129
                buffer
130
                        .append("\n- {}: version = {}, language = {}, langVersion = {}");
131
                values.add(factory.getEngineName());
132
                values.add(factory.getEngineVersion());
133
                values.add(factory.getLanguageName());
134
                values.add(factory.getLanguageVersion());
135

    
136
                // Aliases
137
                buffer.append("\n\t- Aliases: ");
138
                List<String> engNames = factory.getNames();
139
                int size = engNames.size();
140
                for (String name : engNames) {
141
                    size--;
142
                    buffer.append("{}");
143
                    if (size > 0) {
144
                        buffer.append(", ");
145
                    }
146
                    values.add(name);
147
                }
148
                buffer.append("\n\t- File extensions: ");
149
                List<String> extNames = factory.getExtensions();
150
                size = extNames.size();
151
                for (String name : extNames) {
152
                    size--;
153
                    buffer.append("{}");
154
                    if (size > 0) {
155
                        buffer.append(", ");
156
                    }
157
                    values.add(name);
158
                }
159
                buffer.append("\n\t- Mime types: ");
160
                List<String> mimeNames = factory.getMimeTypes();
161
                size = mimeNames.size();
162
                for (String name : mimeNames) {
163
                    size--;
164
                    buffer.append("{}");
165
                    if (size > 0) {
166
                        buffer.append(", ");
167
                    }
168
                    values.add(name);
169
                }
170

    
171
            }
172
            LOG.info(buffer.toString(), values.toArray());
173
        }
174
    }
175

    
176
    public void loadEngines() {
177
        this.getEngineManager();
178
    }
179
    
180
    protected ScriptEngine getEngine(String langName) {
181
        ScriptEngineManager manager = this.getEngineManager();
182
        ScriptEngine engine = manager.getEngineByName(langName);
183
        engine.getBindings(ScriptContext.ENGINE_SCOPE).putAll(bindings);
184
        return engine;
185
    }
186

    
187
    public ImageIcon getIcon(String name) {
188
        return this.icons.get(name);
189
    }
190

    
191
    @Override
192
    public String getEngineNameByLanguage(String langName) {
193
        List<ScriptEngineFactory> factories
194
                = getEngineManager().getEngineFactories();
195

    
196
        for (ScriptEngineFactory factory : factories) {
197
            if (factory.getLanguageName().equalsIgnoreCase(langName)) {
198
                return factory.getEngineName();
199
            }
200
        }
201
        return null;
202
    }
203

    
204
    public ScriptEngine getEngineByLanguage(String langName) {
205
        List<ScriptEngineFactory> factories
206
                = getEngineManager().getEngineFactories();
207

    
208
        for (ScriptEngineFactory factory : factories) {
209
            if (factory.getLanguageName().equalsIgnoreCase(langName)) {
210
                return factory.getScriptEngine();
211
            }
212
        }
213
        return null;
214
    }
215

    
216
    @Override
217
    public boolean validateUnitId(ScriptingFolder folder, String id) {
218
        List<ScriptingUnit> units = folder.getUnits();
219
        String fileName;
220
        String s[];
221
        String extension;
222
        for (ScriptingUnit unit : units) {
223
            fileName = unit.getId();
224
            fileName = FilenameUtils.getBaseName(fileName);
225
            if (fileName.equals(id)) {
226
                return false;
227
            }
228
        }
229
        return true;
230
    }
231

    
232
    public ScriptingScript createScript(ScriptingFolder folder, String id) {
233
        return this.createScript(folder, id, null);
234
    }
235

    
236
    private ScriptingScript createScript(ScriptingFolder folder, String id, String language) {
237
        DefaultScriptingScript script = new DefaultScriptingScript(folder, this, id);
238
        if (!script.getFile().exists()) {
239
            script.create(folder, id, language);
240
        } else {
241
            script.load(folder, id);
242
        }
243
        return script;
244
    }
245

    
246
    public ScriptingDialog createDialog(ScriptingFolder folder, String id) {
247
        return this.createDialog(folder, id, null);
248
    }
249

    
250
    private ScriptingDialog createDialog(ScriptingFolder folder, String id, String language) {
251
        DefaultScriptingDialog dialog = new DefaultScriptingDialog(folder, this, id);
252
        if (!dialog.getFile().exists()) {
253
            dialog.create(folder, id, language);
254
        } else {
255
            dialog.load(folder, id);
256
        }
257
        return dialog;
258
    }
259

    
260
    public ScriptingFolder createFolder(ScriptingFolder folder, String id) {
261
        DefaultScriptingFolder unit = new DefaultScriptingFolder(folder, this, new File(folder.getFile(), id));
262
        unit.load(folder, id);
263
//        if (!unit.getFile().exists()) {
264
//            unit.create(folder, id);
265
//        } else {
266
//            unit.load(folder, id);
267
//        }
268
        return unit;
269
    }
270

    
271
    @Override
272
    public ScriptingBaseScript getScript(File file) {
273
        ScriptingBaseScript script = (ScriptingBaseScript) this.getUnit(file);
274
        if (script == null) {
275
            throw new ScriptNotFoundException(file);
276
        }
277
        return script;
278
    }
279

    
280
    @Override
281
    public ScriptingFolder getFolder(File file) {
282
        ScriptingFolder folder = (ScriptingFolder) this.getUnit(file);
283
        if (folder == null) {
284
            throw new RuntimeException(file.getAbsolutePath());
285
        }
286
        return folder;
287
    }
288

    
289
    public ScriptingUnit getUnit(File file) {
290
        ScriptingFolder folder;
291
        ScriptingUnit unit;
292

    
293
        if (file.isAbsolute()) {
294
            folder = new DefaultScriptingFolder(null, this, file.getParentFile());
295
            unit = folder.getUnit(file);
296
            return unit;
297
        } else {
298
            folder = this.getUserFolder();
299
            unit = folder.getUnit(file);
300
            if (unit != null) {
301
                return unit;
302
            }
303

    
304
            folder = this.getSystemFolder();
305
            unit = folder.getUnit(file);
306
            if (unit != null) {
307
                return unit;
308
            }
309
        }
310
        return null;
311
    }
312

    
313
    @Override
314
    public ScriptingFolder getSystemFolder() {
315
        return new SystemFolder(this);
316
    }
317

    
318
    @Override
319
    public ScriptingFolder getUserFolder() {
320
        return new UserFolder(this, this.getRootUserFolder());
321
    }
322

    
323
    @Override
324
    public ScriptingBaseScript getScript(String name) {
325
        return (ScriptingBaseScript) findScript(null, name);
326
    }
327

    
328
    private ScriptingUnit findScript(ScriptingFolder folder, String name) {
329
        if (name == null) {
330
            return null;
331
        }
332
        if (name.trim().length() == 0) {
333
            return null;
334
        }
335
        ScriptingUnit unit;
336
        if (folder == null) {
337
            unit = findScript(this.getUserFolder(), name);
338
            if (unit != null) {
339
                return unit;
340
            }
341
            unit = findScript(this.getSystemFolder(), name);
342
            return unit;
343
        }
344
        List<ScriptingUnit> units = folder.getUnits();
345
        Iterator<ScriptingUnit> it = units.iterator();
346
        while (it.hasNext()) {
347
            unit = it.next();
348
            if (unit instanceof ScriptingFolder) {
349
                unit = findScript((ScriptingFolder) unit, name);
350
                if (unit != null) {
351
                    return unit;
352
                }
353
            } else if (unit instanceof ScriptingBaseScript) {
354
                if (name.equalsIgnoreCase(unit.getId())) {
355
                    return unit;
356
                }
357
            }
358
        }
359
        return null;
360
    }
361

    
362
    @Override
363
    public File getRootUserFolder() {
364
        return new File(this.getHomeFolder(), "scripts");
365
    }
366

    
367
    @Override
368
    public void registerSystemFolder(String name, File folder) {
369
        this.systemFolders.add(new RegisterSystemFolder(name, folder));
370
        LOG.info("Register system folder name '" + name + "' folder " + folder.getAbsolutePath() + "'");
371

    
372
    }
373

    
374
    public List<RegisterSystemFolder> getSystemFolders() {
375
        return this.systemFolders;
376
    }
377

    
378
    @Override
379
    public List<ScriptingFolder> getAlternativeUserFolders() {
380
        return this.alternativeUserFolders;
381
    }
382

    
383
    @Override
384
    public void addAlternativeUserFolder(File f, String name, String description) {
385
        UserFolder x = new UserFolder(this, f);
386
        x.setName(name);
387
        x.setDescription(description);
388
        x.setId("UserFolder_" + this.alternativeUserFolders.size() + 1);
389
        this.alternativeUserFolders.add(x);
390
    }
391
    
392
    private void initLanguages() {
393
        if (this.extensionOfLanguage == null) {
394
            Map<String, String> extensionOfLanguage = new HashMap<>();
395
            List<ScriptEngineFactory> factories = getEngineManager().getEngineFactories();
396
            for (ScriptEngineFactory factory : factories) {
397
                List<String> extensions = factory.getExtensions();
398
                if (extensions != null && !extensions.isEmpty()) {
399
                    extensionOfLanguage.put(
400
                            factory.getLanguageName().toLowerCase(),
401
                            extensions.get(0).toLowerCase()
402
                    );
403
                }
404
            }
405
            this.extensionOfLanguage = extensionOfLanguage;
406
        }
407
        if (this.languageOfExtension == null) {
408
            Map<String, String> languageOfExtension = new HashMap<>();
409
            List<ScriptEngineFactory> factories = getEngineManager().getEngineFactories();
410
            for (ScriptEngineFactory factory : factories) {
411
                List<String> extensions = factory.getExtensions();
412
                if (extensions != null) {
413
                    for (String extension1 : extensions) {
414
                        languageOfExtension.put(
415
                                extension1.toLowerCase(),
416
                                factory.getLanguageName().toLowerCase()
417
                        );
418
                    }
419
                }
420
            }
421
            this.languageOfExtension = languageOfExtension;
422
        }
423
    }
424

    
425
    @Override
426
    public String getExtensionOfLanguage(String langName) {
427
        if (langName == null) {
428
            return null;
429
        }
430
        langName = langName.toLowerCase();
431
        initLanguages();
432
        return this.extensionOfLanguage.get(langName);
433
    }
434

    
435
    @Override
436
    public List<String> getSupportedLanguages() {
437
        List<String> languages = new ArrayList<>();
438

    
439
        initLanguages();
440
        languages.addAll(this.extensionOfLanguage.keySet());
441
        Collections.sort(languages);
442
        return languages;
443
    }
444

    
445
    public String getLanguageOfExtension(String extension) {
446
        if (extension == null) {
447
            return null;
448
        }
449
        extension = extension.toLowerCase();
450
        if (extension.startsWith(".")) {
451
            extension = extension.substring(1);
452
        }
453
        initLanguages();
454
        return this.languageOfExtension.get(extension);
455
    }
456

    
457
    public Object get(String key) {
458
        return this.bindings.get(key);
459
    }
460

    
461
    public void put(String key, Object value) {
462
        this.bindings.put(key, value);
463

    
464
    }
465

    
466
    @Override
467
    public ScriptingHelpManager getHelpManager() {
468
        if (this.helpManager == null) {
469
            this.helpManager = new DefaultScriptingHelpManager(this);
470
        }
471
        return this.helpManager;
472
    }
473

    
474
    @Override
475
    public ScriptingUnit createUnit(String unitType, ScriptingFolder folder, String id) {
476
        return createUnit(unitType, folder, id, null);
477
    }
478

    
479
    @Override
480
    public ScriptingUnit createUnit(String unitType, ScriptingFolder folder, String id, String language) {
481
        if (unitType.equals(UNIT_SCRIPT)) {
482
            return this.createScript(folder, id, language);
483
        }
484
        if (unitType.equals(UNIT_DIALOG)) {
485
            return this.createDialog(folder, id, language);
486
        }
487
        if (unitType.equals(UNIT_FOLDER)) {
488
            return this.createFolder(folder, id);
489
        }
490
        return null;
491
    }
492

    
493
    @Override
494
    public List<String> getUnitTypes() {
495
        if (this.unitTypes == null) {
496
            this.unitTypes = new ArrayList<>();
497
            this.unitTypes.add(UNIT_SCRIPT);
498
            this.unitTypes.add(UNIT_DIALOG);
499
            this.unitTypes.add(UNIT_FOLDER);
500
        }
501
        return this.unitTypes;
502
    }
503

    
504
    @Override
505
    public void addLibFolder(File lib) {
506
        if (lib.exists()) {
507
            LOG.info("Add scripting lib folder '" + lib.getAbsolutePath() + "'");
508
            this.libFolders.add(lib);
509
        } else {
510
            LOG.info("Skip add scripting lib folder '" + lib.getAbsolutePath() + "', folder don't exist");
511
        }
512
    }
513

    
514
    public List<File> getLibFolders() {
515
        return this.libFolders;
516
    }
517

    
518
    public ProviderFactory getInstallerFactory() {
519
        return new ScriptingInstallerProviderFactory();
520
    }
521

    
522
    public ProviderFactory getHelpInstallerFactory() {
523
        return new ScriptingHelpInstallerProviderFactory();
524
    }
525

    
526
    @Override
527
    public File getPackagesFolder() {
528
        return this.packagesFolder;
529
    }
530

    
531
    @Override
532
    public void setPackagesFolder(File folder) {
533
        this.packagesFolder = folder;
534
    }
535

    
536
}