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

History | View | Annotate | Download (16 KB)

1
package org.gvsig.scripting.impl;
2

    
3
import java.io.BufferedReader;
4
import java.io.File;
5
import java.io.FileNotFoundException;
6
import java.io.FileReader;
7
import java.io.IOException;
8
import java.util.ArrayList;
9
import java.util.HashMap;
10
import java.util.Iterator;
11
import java.util.List;
12
import java.util.Map;
13

    
14
import javax.script.ScriptContext;
15
import javax.script.ScriptEngine;
16
import javax.script.ScriptEngineFactory;
17
import javax.script.ScriptEngineManager;
18
import javax.script.SimpleBindings;
19
import javax.swing.ImageIcon;
20

    
21
import org.apache.commons.io.FileUtils;
22
import org.gvsig.scripting.ScriptingBaseScript;
23
import org.gvsig.scripting.ScriptingDialog;
24
import org.gvsig.scripting.ScriptingFolder;
25
import org.gvsig.scripting.ScriptingHelpManager;
26
import org.gvsig.scripting.ScriptingManager;
27
import org.gvsig.scripting.ScriptingProject;
28
import org.gvsig.scripting.ScriptingScript;
29
import org.gvsig.scripting.ScriptingUnit;
30
import org.slf4j.Logger;
31
import org.slf4j.LoggerFactory;
32

    
33
public class DefaultScriptingManager implements ScriptingManager {
34

    
35
    private static final Logger LOG = LoggerFactory
36
            .getLogger(DefaultScriptingManager.class);
37

    
38
    protected Map<String, ImageIcon> icons;
39
    protected List<RegisterSystemFolder> systemFolders = new ArrayList<RegisterSystemFolder>();
40
    protected ScriptEngineManager engineManager = null;
41
    private final SimpleBindings bindings = new SimpleBindings();
42
    private ScriptingHelpManager helpManager = null;
43
    private List<String> unitTypes = null;
44
    private ClassLoader classLoader = null;
45
    private List<File> libFolders = new ArrayList<File>();
46
    private File home = null;
47
    private List<ScriptingFolder> alternativeUserFolders = new ArrayList<ScriptingFolder>();
48

    
49
    public DefaultScriptingManager() {
50
        this.classLoader = getClass().getClassLoader();
51
        this.setHomeFolder(null);
52
        this.bindings.put("ScriptingManager", this);
53
    }
54

    
55
    public DefaultScriptingManager(ClassLoader classLoader) {
56
        this();
57
        this.classLoader = classLoader;
58
    }
59

    
60
    private void createFolder(File f) {
61
        if (!f.exists()) {
62
            try {
63
                FileUtils.forceMkdir(f);
64
                LOG.info("Created scripting folder '" + f.getAbsolutePath() + "'");
65
            } catch (Throwable e) {
66
                LOG.warn("Can't Create scripting folder '" + f.getAbsolutePath() + "'");
67
            }
68
        }
69
    }
70

    
71
    private void createDefaultFolders(File home) {
72
        createFolder(new File(home, "scripts"));
73
        createFolder(new File(home, "help"));
74
        createFolder(new File(home, "lib"));
75
    }
76

    
77
    public File getHomeFolder() {
78
        if (!this.home.exists()) {
79
            createFolder(home);
80
            createDefaultFolders(home);
81
        }
82
        return this.home;
83
    }
84

    
85
    public void setHomeFolder(File home) {
86
        if (home == null) {
87
            this.home = new File(System.getProperty("user.home"), ".gvsig-scripting");
88
        } else {
89
            this.home = home;
90
        }
91
        createDefaultFolders(this.home);
92
        LOG.info("Set scripting home to '" + this.home.getAbsolutePath() + "'");
93
        this.addLibFolder(new File(this.home, "lib"));
94
    }
95

    
96
    protected ScriptEngineManager getEngineManager() {
97
        if (this.engineManager == null) {
98
            this.engineManager
99
                    = classLoader == null ? new ScriptEngineManager()
100
                            : new ScriptEngineManager(classLoader);
101
            showEnginesInfo(engineManager);
102
        }
103
        return this.engineManager;
104
    }
105

    
106
    private void showEnginesInfo(ScriptEngineManager mgr) {
107
        if (LOG.isInfoEnabled()) {
108
            List<ScriptEngineFactory> factories = mgr.getEngineFactories();
109
            StringBuffer buffer = new StringBuffer();
110
            List<Object> values = new ArrayList<Object>();
111
            buffer.append("Scripting engines available:");
112
            for (ScriptEngineFactory factory : factories) {
113

    
114
                // Main engine info
115
                buffer
116
                        .append("\n- {}: version = {}, language = {}, langVersion = {}");
117
                values.add(factory.getEngineName());
118
                values.add(factory.getEngineVersion());
119
                values.add(factory.getLanguageName());
120
                values.add(factory.getLanguageVersion());
121

    
122
                // Aliases
123
                buffer.append("\n\t- Aliases: ");
124
                List<String> engNames = factory.getNames();
125
                int size = engNames.size();
126
                for (String name : engNames) {
127
                    size--;
128
                    buffer.append("{}");
129
                    if (size > 0) {
130
                        buffer.append(", ");
131
                    }
132
                    values.add(name);
133
                }
134
                buffer.append("\n\t- File extensions: ");
135
                List<String> extNames = factory.getExtensions();
136
                size = extNames.size();
137
                for (String name : extNames) {
138
                    size--;
139
                    buffer.append("{}");
140
                    if (size > 0) {
141
                        buffer.append(", ");
142
                    }
143
                    values.add(name);
144
                }
145
                buffer.append("\n\t- Mime types: ");
146
                List<String> mimeNames = factory.getMimeTypes();
147
                size = mimeNames.size();
148
                for (String name : mimeNames) {
149
                    size--;
150
                    buffer.append("{}");
151
                    if (size > 0) {
152
                        buffer.append(", ");
153
                    }
154
                    values.add(name);
155
                }
156

    
157
            }
158
            LOG.info(buffer.toString(), values.toArray());
159
        }
160
    }
161

    
162
    protected ScriptEngine getEngine(String langName) {
163
        ScriptEngine engine = this.getEngineManager().getEngineByName(langName);
164
        engine.getBindings(ScriptContext.ENGINE_SCOPE).putAll(bindings);
165
        return engine;
166
    }
167

    
168
    public ImageIcon getIcon(String name) {
169
        return this.icons.get(name);
170
    }
171

    
172
    public Map<String, String> getSupportedLanguagesByExtension() {
173
        List<ScriptEngineFactory> factories
174
                = getEngineManager().getEngineFactories();
175
        Map<String, String> extToLang = new HashMap<String, String>();
176

    
177
        for (ScriptEngineFactory factory : factories) {
178
            List<String> extNames = factory.getExtensions();
179
            for (String name : extNames) {
180
                extToLang.put(".".concat(name), factory.getLanguageName());
181
            }
182
        }
183

    
184
        return extToLang;
185
    }
186

    
187
    public Map<String, String> getExtensionsByLanguages() {
188
        Map<String, String> l = getSupportedLanguagesByExtension();
189
        Map<String, String> result = new HashMap<String, String>();
190
        Iterator<Map.Entry<String, String>> it = l.entrySet().iterator();
191
        while (it.hasNext()) {
192
            Map.Entry<String, String> pairs = it.next();
193
            result.put(pairs.getValue(), pairs.getKey());
194
        }
195
        return result;
196
    }
197

    
198
    public boolean validateUnitId(ScriptingFolder folder, String id) {
199
        List<ScriptingUnit> units = folder.getUnits();
200
        String fileName;
201
        String s[];
202
        String extension;
203
        for (int i = 0; i < units.size(); i++) {
204
            fileName = (units.get(i)).getId();
205
            s = fileName.split("\\.");
206
            extension = null;
207
            if (s.length > 1) {
208
                extension = "." + s[s.length - 1];
209
                fileName = fileName.substring(0, fileName.length() - extension.length());
210
            }
211
            if (fileName.equals(id)) {
212
                return false;
213
            }
214
        }
215
        return true;
216
    }
217

    
218
    public static String getStringFromFile(String filename) {
219

    
220
        BufferedReader b = null;
221
        try {
222
            try {
223
                b = new BufferedReader(new FileReader(filename));
224
            } catch (FileNotFoundException e) {
225
                LOG.warn("Can't open file '" + filename + "'.", e);
226
            }
227
            StringBuffer sb = new StringBuffer();
228
            String str;
229
            try {
230
                while ((str = b.readLine()) != null) {
231
                    sb.append(str);
232
                    sb.append('\n');
233
                }
234
            } catch (IOException e) {
235
                LOG.warn("Can't read file '" + filename + "'.", e);
236
            }
237
            return sb.toString();
238
        } finally {
239
            if (b != null) {
240
                try {
241
                    b.close();
242
                } catch (IOException e) {
243
                    LOG.warn("Can't close file '" + filename + "'", e);
244
                }
245
                b = null;
246
            }
247
        }
248
    }
249

    
250
    public ScriptingScript createScript(ScriptingFolder folder, String id) {
251
        return this.createScript(folder, id, null);
252
    }
253

    
254
    private ScriptingScript createScript(ScriptingFolder folder, String id, String language) {
255
        DefaultScriptingScript script = new DefaultScriptingScript(folder, this, id);
256
        if (!script.getFile().exists()) {
257
            script.create(folder, id, language);
258
        } else {
259
            script.load(folder, id);
260
        }
261
        return script;
262
    }
263

    
264
    public ScriptingDialog createDialog(ScriptingFolder folder, String id) {
265
        return this.createDialog(folder, id, null);
266
    }
267

    
268
    private ScriptingDialog createDialog(ScriptingFolder folder, String id, String language) {
269
        DefaultScriptingDialog dialog = new DefaultScriptingDialog(folder, this, id);
270
        if (!dialog.getFile().exists()) {
271
            dialog.create(folder, id, language);
272
        } else {
273
            dialog.load(folder, id);
274
        }
275
        return dialog;
276
    }
277

    
278
    public ScriptingFolder createFolder(ScriptingFolder folder, String id) {
279
        DefaultScriptingFolder unit = new DefaultScriptingFolder(folder, this, new File(folder.getFile(), id));
280
        if (!unit.getFile().exists()) {
281
            unit.create(folder, id);
282
        } else {
283
            unit.load(folder, id);
284
        }
285
        return unit;
286
    }
287

    
288
    public ScriptingProject createProject(ScriptingFolder folder, String id) {
289
        LOG.warn("Projects can't be implementeds");
290
        return null;
291
    }
292

    
293
    public ScriptingBaseScript getScript(File file) {
294
        ScriptingBaseScript script = (ScriptingBaseScript) this.getUnit(file);
295
        if (script == null) {
296
            throw new ScriptNotFoundException(file);
297
        }
298
        return script;
299
    }
300

    
301
    public ScriptingFolder getFolder(File file) {
302
        ScriptingFolder folder = (ScriptingFolder) this.getUnit(file);
303
        if (folder == null) {
304
            throw new RuntimeException(file.getAbsolutePath());
305
        }
306
        return folder;
307
    }
308

    
309
    public ScriptingUnit getUnit(File file) {
310
        ScriptingFolder folder = null;
311
        ScriptingUnit unit = null;
312

    
313
        if (file.isAbsolute()) {
314
            folder = new DefaultScriptingFolder(null, this, file.getParentFile());
315
            unit = folder.getUnit(file);
316
            return unit;
317
        } else {
318
            folder = this.getUserFolder();
319
            unit = folder.getUnit(file);
320
            if (unit != null) {
321
                return unit;
322
            }
323

    
324
            folder = this.getSystemFolder();
325
            unit = folder.getUnit(file);
326
            if (unit != null) {
327
                return unit;
328
            }
329
        }
330
        return null;
331
    }
332

    
333
    public ScriptingFolder getSystemFolder() {
334
        return new SystemFolder(this);
335
    }
336

    
337
    public ScriptingFolder getUserFolder() {
338
        return new UserFolder(this, this.getRootUserFolder());
339
    }
340

    
341
    public ScriptingBaseScript getScript(String name) {
342
        return (ScriptingBaseScript) findScript(null, name);
343
    }
344

    
345
    private ScriptingUnit findScript(ScriptingFolder folder, String name) {
346
        if (name == null) {
347
            return null;
348
        }
349
        if (name.trim().length() == 0) {
350
            return null;
351
        }
352
        ScriptingUnit unit = null;
353
        if (folder == null) {
354
            unit = findScript(this.getUserFolder(), name);
355
            if (unit != null) {
356
                return unit;
357
            }
358
            unit = findScript(this.getSystemFolder(), name);
359
            return unit;
360
        }
361
        List<ScriptingUnit> units = folder.getUnits();
362
        Iterator<ScriptingUnit> it = units.iterator();
363
        while (it.hasNext()) {
364
            unit = it.next();
365
            if (unit instanceof ScriptingFolder) {
366
                unit = findScript((ScriptingFolder) unit, name);
367
                if (unit != null) {
368
                    return unit;
369
                }
370
            } else if (unit instanceof ScriptingBaseScript) {
371
                if (name.equalsIgnoreCase(unit.getId())) {
372
                    return unit;
373
                }
374
            }
375
        }
376
        return null;
377
    }
378

    
379
    public File getRootUserFolder() {
380
        return new File(this.getHomeFolder(), "scripts");
381
    }
382

    
383
    public void registerSystemFolder(String name, File folder) {
384
        this.systemFolders.add(new RegisterSystemFolder(name, folder));
385
        LOG.info("Register system folder name '" + name + "' folder " + folder.getAbsolutePath() + "'");
386

    
387
    }
388

    
389
    public List<RegisterSystemFolder> getSystemFolders() {
390
        return this.systemFolders;
391
    }
392

    
393
    public List<ScriptingFolder> getAlternativeUserFolders() {
394
        return this.alternativeUserFolders;
395
    }
396

    
397
    public void addAlternativeUserFolder(File f, String name, String description) {
398
        UserFolder x = new UserFolder(this, f);
399
        x.setName(name); 
400
        x.setDescription(description);
401
        x.setId("UserFolder_"+this.alternativeUserFolders.size()+1);
402
        this.alternativeUserFolders.add(x);
403
    }
404

    
405
    public static class RegisterSystemFolder {
406

    
407
        public String name;
408
        public File folder;
409

    
410
        public RegisterSystemFolder(String name, File folder) {
411
            this.name = name;
412
            this.folder = folder;
413
        }
414
    }
415

    
416
    public String getExtensionByLanguage(String langName) {
417
        Map<String, String> extensions = getSupportedLanguagesByExtension();
418
        Iterator<String> iterator = extensions.keySet().iterator();
419
        String extension = null;
420
        String s = null;
421

    
422
        while (iterator.hasNext()) {
423
            extension = iterator.next();
424
            s = extensions.get(extension);
425
            if (s.equalsIgnoreCase(langName)) {
426
                return extension;
427
            }
428

    
429
        }
430

    
431
        return null;
432
    }
433

    
434
    public Object get(String key) {
435
        return this.bindings.get(key);
436
    }
437

    
438
    public void put(String key, Object value) {
439
        this.bindings.put(key, value);
440

    
441
    }
442

    
443
    public ScriptingHelpManager getHelpManager() {
444
        if (this.helpManager == null) {
445
            this.helpManager = new DefaultScriptingHelpManager(this);
446
        }
447
        return this.helpManager;
448
    }
449

    
450
    public ScriptingUnit createUnit(String unitType, ScriptingFolder folder, String id) {
451
        return createUnit(unitType, folder, id, null);
452
    }
453

    
454
    public ScriptingUnit createUnit(String unitType, ScriptingFolder folder, String id, String language) {
455
        if (unitType.equals(UNIT_SCRIPT)) {
456
            return this.createScript(folder, id, language);
457
        }
458
        if (unitType.equals(UNIT_DIALOG)) {
459
            return this.createDialog(folder, id, language);
460
        }
461
        if (unitType.equals(UNIT_FOLDER)) {
462
            return this.createFolder(folder, id);
463
        }
464
        if (unitType.equals(UNIT_PROJECT)) {
465
            return null;
466
        }
467
        return null;
468
    }
469

    
470
    public List<String> getUnitTypes() {
471
        if (this.unitTypes == null) {
472
            this.unitTypes = new ArrayList<String>();
473
            this.unitTypes.add(UNIT_SCRIPT);
474
            this.unitTypes.add(UNIT_DIALOG);
475
            this.unitTypes.add(UNIT_PROJECT);
476
            this.unitTypes.add(UNIT_FOLDER);
477
        }
478
        return this.unitTypes;
479
    }
480

    
481
    public void addLibFolder(File lib) {
482
        if (lib.exists()) {
483
            LOG.info("Add scripting lib folder '" + lib.getAbsolutePath() + "'");
484
            this.libFolders.add(lib);
485
        } else {
486
            LOG.info("Skip add scripting lib folder '" + lib.getAbsolutePath() + "', folder don't exist");
487
        }
488
    }
489

    
490
    public List<File> getLibFolders() {
491
        return this.libFolders;
492
    }
493
}