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

History | View | Annotate | Download (25.8 KB)

1
package org.gvsig.scripting.impl;
2

    
3
import java.io.File;
4
import java.io.IOException;
5
import java.net.URI;
6
import java.util.ArrayList;
7
import java.util.Collections;
8
import java.util.HashMap;
9
import java.util.Iterator;
10
import java.util.List;
11
import java.util.Map;
12
import java.util.Set;
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.lang3.StringUtils;
22
import org.gvsig.scripting.DataFolderFound;
23
import org.gvsig.scripting.ScriptingBaseScript;
24
import org.gvsig.scripting.ScriptingDialog;
25
import org.gvsig.scripting.ScriptingExternalFile;
26
import org.gvsig.scripting.ScriptingFolder;
27
import org.gvsig.scripting.ScriptingManager;
28
import org.gvsig.scripting.ScriptingScript;
29
import org.gvsig.scripting.ScriptingUnit;
30
import org.gvsig.tools.packageutils.Version;
31
import org.gvsig.tools.script.Script;
32
import org.gvsig.tools.service.spi.ProviderFactory;
33
import org.gvsig.tools.util.FolderSet;
34
import org.python.jsr223.MyPyScriptEngine;
35
import org.slf4j.Logger;
36
import org.slf4j.LoggerFactory;
37

    
38

    
39
@SuppressWarnings("UseSpecificCatch")
40
public class DefaultScriptingManager implements ScriptingManager {
41

    
42
    public static class RegisterSystemFolder {
43

    
44
        public String name;
45
        public File folder;
46

    
47
        public RegisterSystemFolder(String name, File folder) {
48
            this.name = name;
49
            this.folder = folder;
50
        }
51
    }
52

    
53
    static final Logger LOG = LoggerFactory
54
            .getLogger(DefaultScriptingManager.class);
55
    
56
    protected Map<String, ImageIcon> icons;
57
    protected List<RegisterSystemFolder> systemFolders = new ArrayList<>();
58
    protected ScriptEngineManager engineManager = null;
59
    private final SimpleBindings bindings = new SimpleBindings();
60
    private List<String> unitTypes = null;
61
    private ClassLoader classLoader = null;
62
    private final List<File> libFolders = new ArrayList<>();
63
    private File home = null;
64
    private final List<ScriptingFolder> alternativeUserFolders = new ArrayList<>();
65
    private Map<String, String> extensionOfLanguage = null;
66
    private Map<String, String> languageOfExtension = null;
67
    private File packagesFolder;
68
    private final Map properties = new HashMap();
69
    private final Map<String,ScriptEngine> engineGroups = new HashMap<>();
70
    private DataFolderManager dataFolderManager = null;
71
    private ScriptingFolder userFolder = null;
72
    private ScriptingFolder systemFolder = null;
73
    
74
    @SuppressWarnings({"OverridableMethodCallInConstructor", "LeakingThisInConstructor"})
75
    public DefaultScriptingManager() {
76
        this.classLoader = getClass().getClassLoader();
77
        this.setHomeFolder(null);
78
        this.bindings.put("ScriptingManager", this);
79
    }
80

    
81
    public DefaultScriptingManager(ClassLoader classLoader) {
82
        this();
83
        this.classLoader = classLoader;
84
    }
85

    
86
    @Override
87
    public Object getProperty(Object key) {
88
        return properties.get(key);
89
    }
90

    
91
    @Override
92
    public void setProperty(Object key, Object val) {
93
        properties.put(key, val);
94
    }
95

    
96
    @Override
97
    public Map getExtendedProperties() {
98
        return properties;
99
    }
100

    
101
    private void createFolder(File f) {
102
        if (!f.exists()) {
103
            try {
104
                FileUtils.forceMkdir(f);
105
                LOG.info("Created scripting folder '" + f.getAbsolutePath() + "'");
106
            } catch (Throwable e) {
107
                LOG.warn("Can't Create scripting folder '" + f.getAbsolutePath() + "'");
108
            }
109
        }
110
    }
111

    
112
    private void createDefaultFolders(File home) {
113
        createFolder(new File(home, "scripts"));
114
        createFolder(new File(home, "lib"));
115
        createFolder(new File(home, "data"));
116
    }
117

    
118
    @Override
119
    public File getHomeFolder() {
120
        if (!this.home.exists()) {
121
            createFolder(home);
122
            createDefaultFolders(home);
123
        }
124
        return this.home;
125
    }
126

    
127
    @Override
128
    public void setHomeFolder(File home) {
129
        if (home == null) {
130
            this.home = new File(System.getProperty("user.home"), ".gvsig-scripting");
131
        } else {
132
            this.home = home;
133
        }
134
        createDefaultFolders(this.home);
135
        LOG.info("Set scripting home to '" + this.home.getAbsolutePath() + "'");
136
        this.addLibFolder(new File(this.home, "lib"));
137
    }
138
    
139
    private DataFolderManager getDataFolderManager() {
140
        if( this.dataFolderManager==null ) {
141
            this.dataFolderManager = new DataFolderManager(this);
142
        }
143
        return this.dataFolderManager;
144
    }
145
    
146
    @Override
147
    public File getDataFolder(String id) {
148
        return this.getDataFolderManager().getDataFolder(id);
149
    }
150

    
151
    public void registerDataFolder(ScriptingFolder folderScript, String id ) {
152
        this.getDataFolderManager().registerDataFolder(folderScript, id);
153
    }
154

    
155
    @Override
156
    public List<DataFolderFound> searchOldVersions(Version currentVersion, FolderSet folder) {
157
        return this.getDataFolderManager().searchOldVersions(currentVersion, folder);
158
    }
159
    
160
    protected synchronized ScriptEngineManager getEngineManager() {
161
        if (this.engineManager == null) {
162
            this.engineManager
163
                    = classLoader == null ? new ScriptEngineManager()
164
                            : new ScriptEngineManager(classLoader);
165
            showEnginesInfo(engineManager);
166
        }
167
        return this.engineManager;
168
    }
169

    
170
    private void showEnginesInfo(ScriptEngineManager mgr) {
171
        if (LOG.isInfoEnabled()) {
172
            List<ScriptEngineFactory> factories = mgr.getEngineFactories();
173
            StringBuilder buffer = new StringBuilder();
174
            List<Object> values = new ArrayList<>();
175
            buffer.append("Scripting engines available:");
176
            for (ScriptEngineFactory factory : factories) {
177

    
178
                // Main engine info
179
                buffer
180
                        .append("\n- {}: version = {}, language = {}, langVersion = {}");
181
                values.add(factory.getEngineName());
182
                values.add(factory.getEngineVersion());
183
                values.add(factory.getLanguageName());
184
                values.add(factory.getLanguageVersion());
185

    
186
                // Aliases
187
                buffer.append("\n\t- Aliases: ");
188
                List<String> engNames = factory.getNames();
189
                int size = engNames.size();
190
                for (String name : engNames) {
191
                    size--;
192
                    buffer.append("{}");
193
                    if (size > 0) {
194
                        buffer.append(", ");
195
                    }
196
                    values.add(name);
197
                }
198
                buffer.append("\n\t- File extensions: ");
199
                List<String> extNames = factory.getExtensions();
200
                size = extNames.size();
201
                for (String name : extNames) {
202
                    size--;
203
                    buffer.append("{}");
204
                    if (size > 0) {
205
                        buffer.append(", ");
206
                    }
207
                    values.add(name);
208
                }
209
                buffer.append("\n\t- Mime types: ");
210
                List<String> mimeNames = factory.getMimeTypes();
211
                size = mimeNames.size();
212
                for (String name : mimeNames) {
213
                    size--;
214
                    buffer.append("{}");
215
                    if (size > 0) {
216
                        buffer.append(", ");
217
                    }
218
                    values.add(name);
219
                }
220

    
221
            }
222
            LOG.info(buffer.toString(), values.toArray());
223
        }
224
    }
225

    
226
    @Override
227
    public synchronized void loadEngines() {
228
        this.getEngineManager();
229
    }
230
    
231
    private ScriptEngine createJythonEngine() {
232
        ScriptEngineFactory factory = this.getEngineFactoryByLanguage(PYTHON_LANGUAGE_NAME);
233
        ScriptEngine engine = new MyPyScriptEngine(factory);
234
        return engine;
235
    }
236
    
237
    public ImageIcon getIcon(String name) {
238
        return this.icons.get(name);
239
    }
240

    
241
    @Override
242
    public String getEngineNameByLanguage(String langName) {
243
        ScriptEngineFactory factory = this.getEngineFactoryByLanguage(langName);
244
        if( factory == null ) {
245
            return null;
246
        }
247
        return factory.getEngineName();
248
    }
249
    
250
    public ScriptEngine getEngineByLanguage(String langName) {
251
        return this.getEngineByLanguage(langName, null);
252
    }
253
    
254
    public synchronized ScriptEngine getEngineByLanguage(String langName, String isolationGroup) {
255
        ScriptEngine engine = null;
256
        if( !StringUtils.isEmpty(isolationGroup) ) {
257
            isolationGroup += "-" + langName;
258
            engine = this.engineGroups.get(isolationGroup.toLowerCase());
259
        } 
260
        if( engine == null ) {
261
            if( PYTHON_LANGUAGE_NAME.equalsIgnoreCase(langName) ) {
262
                engine = createJythonEngine();
263
            } else {
264
                ScriptEngineFactory factory = this.getEngineFactoryByLanguage(langName);
265
                if( factory == null ) {
266
                    return null;
267
                }
268
                engine = factory.getScriptEngine();
269
            }
270
//            if( SCALA_LANGUAGE_NAME.equalsIgnoreCase(langName) ) {
271
//                try {
272
//                    // https://gist.github.com/takawitter/5479445
273
//                    Object settings = engine.getClass().getMethod("settings", new Class[0]).invoke(engine, new Object[0]);
274
//                    settings.getClass().getMethod("processArgumentString", new Class[] { String.class }).invoke(settings, new String[] { "-usejavacp"});
275
//                } catch(Throwable th) {
276
//                    LOG.warn("Can't initialice scala setting -usejavacp",th);
277
//                }
278
//            }            
279
            if( !StringUtils.isEmpty(isolationGroup) ) {
280
                this.engineGroups.put(isolationGroup.toLowerCase(), engine);
281
            }
282
        }
283
        engine.getBindings(ScriptContext.ENGINE_SCOPE).putAll(bindings);
284
        return engine;
285
    }
286

    
287
    @Override
288
    public synchronized Set<String> getEnginesIsolationGroups() {
289
        return this.engineGroups.keySet();
290
    }
291
    
292
    public ScriptEngineFactory getEngineFactoryByLanguage(String langName) {
293
        List<ScriptEngineFactory> factories
294
                = getEngineManager().getEngineFactories();
295

    
296
        for (ScriptEngineFactory factory : factories) {
297
            if (factory.getLanguageName().equalsIgnoreCase(langName)) {
298
                return factory;
299
            }
300
        }
301
        return null;
302
    }
303

    
304
    @Override
305
    public boolean validateUnitId(ScriptingFolder folder, String id) {
306
        File f = new File(folder.getFile(),id+".inf");
307
        return !f.exists();
308
    }
309

    
310
    public ScriptingScript createScript(ScriptingFolder folder, String id) {
311
        return this.createScript(folder, id, null);
312
    }
313
    
314
    @Override
315
    public Script createScript(String name, String code, String languaje) {
316
        ScriptingScript script = new DefaultScriptingScript(this.getUserFolder(), this, name);
317
        script.setCode(code);
318
        script.setSaved(true);
319
        return script;        
320
    }
321

    
322
    private ScriptingScript createScript(ScriptingFolder folder, String id, String language) {
323
        DefaultScriptingScript script = new DefaultScriptingScript(folder, this, id);
324
        if (!script.getFile().exists()) {
325
            script.create(folder, id, language);
326
        } else {
327
            script.load(folder, id);
328
        }
329
        return script;
330
    }
331

    
332
    public ScriptingDialog createDialog(ScriptingFolder folder, String id) {
333
        return this.createDialog(folder, id, null);
334
    }
335

    
336
    private ScriptingDialog createDialog(ScriptingFolder folder, String id, String language) {
337
        DefaultScriptingDialog dialog = new DefaultScriptingDialog(folder, this, id);
338
        if (!dialog.getFile().exists()) {
339
            dialog.create(folder, id, language);
340
        } else {
341
            dialog.load(folder, id);
342
        }
343
        return dialog;
344
    }
345

    
346
    public ScriptingFolder createFolder(ScriptingFolder folder, String id) {
347
        DefaultScriptingFolder unit = new DefaultScriptingFolder(folder, this, new File(folder.getFile(), id));
348
        unit.load(folder, id);
349
        if (!unit.getFile().exists()) {
350
            unit.create(folder, id);
351
        }
352
        return unit;
353
    }
354

    
355
    public ScriptingExternalFile createExternalFile(ScriptingFolder folder, String id) {
356
        DefaultScriptingExternalFile unit = new DefaultScriptingExternalFile(folder, this, id);
357
        if( unit.getExternalFile()!=null && !unit.getExternalFile().exists() ) {
358
            unit.create(folder, id);
359
        }
360
        return unit;
361
    }
362
    
363
    @Override
364
    public ScriptingBaseScript getScript(File file) {
365
        ScriptingBaseScript script = (ScriptingBaseScript) this.getUnit(file);
366
        if (script == null) {
367
            throw new ScriptNotFoundException(file);
368
        }
369
        return script;
370
    }
371
    
372
    @Override
373
    public Script loadScript(URI uri) {
374
        File f = new File(uri);
375
        try {
376
            return (Script) this.getScript(f);
377
        } catch(ScriptNotFoundException ex) {
378
            throw ex;
379
        } catch(Throwable th) {
380
            throw new ScriptNotFoundException(f);
381
        }
382
    }
383

    
384

    
385
    
386
    @Override
387
    public ScriptingFolder getFolder(File file) {
388
        if( file == null ) {
389
            throw new IllegalArgumentException("file argument can't be null");
390
        }
391
        file = this.getLinkSource(file);
392
        if( FileUtils.isSameFile(this.getRootUserFolder(),file) ) {
393
            return this.getUserFolder();
394
        }
395
        
396
        ScriptingFolder folder = (ScriptingFolder) this.getUnit(file);
397
        if (folder == null) {
398
            throw new IllegalArgumentException("Can't get ScriptFolder from '"+file.getAbsolutePath()+"'.");
399
        }
400
        return folder;
401
    }
402

    
403
    public ScriptingUnit getUnit(String pathName) {
404
        ScriptingUnit unit = null;
405
        String[] parts = StringUtils.split(pathName, '/');
406
        if( pathName.equals(this.getUserFolder().getName()) ) {
407
            unit = this.getUserFolder().getUnit( 
408
                    StringUtils.join(parts, "/", 1, parts.length) 
409
            );
410
        } else if( pathName.equals(this.getSystemFolder().getName()) ) {
411
            unit = this.getSystemFolder().getUnit( 
412
                    StringUtils.join(parts, "/", 1, parts.length) 
413
            );
414
        } 
415
        return unit;
416
    }
417
    
418
    public ScriptingUnit getUnit(File file) {
419
        ScriptingFolder folder;
420
        ScriptingUnit unit;
421

    
422
        if (file.isAbsolute()) {
423
            if( FileUtils.isSameFile(this.getRootUserFolder(), file.getParentFile()) ) {
424
                folder = this.getUserFolder();
425
                // FIXME: que pasa si esta en SystemFolder ???
426
            } else {
427
                folder = new DefaultScriptingFolder(null, this, file.getParentFile());
428
            }
429
            unit = folder.getUnit(file);
430
            return unit;
431
        } else {
432
            folder = this.getUserFolder();
433
            unit = folder.getUnit(file);
434
            if (unit != null) {
435
                return unit;
436
            }
437

    
438
            folder = this.getSystemFolder();
439
            unit = folder.getUnit(file);
440
            if (unit != null) {
441
                return unit;
442
            }
443
        }
444
        return null;
445
    }
446

    
447
    @Override
448
    public ScriptingFolder getSystemFolder() {
449
        if( this.systemFolder == null ) {
450
            this.systemFolder = new SystemFolder(this);
451
        }
452
        return  this.systemFolder;
453
    }
454

    
455
    @Override
456
    public ScriptingFolder getUserFolder() {
457
        if( this.userFolder == null ) {
458
            this.userFolder = new UserFolder(this, this.getRootUserFolder());
459
        }
460
        return  this.userFolder;
461
    }
462

    
463
    @Override
464
    public ScriptingBaseScript getScript(String name) {
465
        return (ScriptingBaseScript) findScript(null, name);
466
    }
467

    
468
    @Override
469
    public Script locateScript(String name) {
470
        ScriptingUnit script = findScript(null, name);
471
        if( script instanceof Script ) {
472
            return (Script) script;
473
        }
474
        return null;
475
    }
476
    
477
    private ScriptingUnit findScript(ScriptingFolder folder, String name) {
478
        if (name == null) {
479
            return null;
480
        }
481
        if (name.trim().length() == 0) {
482
            return null;
483
        }
484
        ScriptingUnit unit;
485
        if (folder == null) {
486
            unit = findScript(this.getUserFolder(), name);
487
            if (unit != null) {
488
                return unit;
489
            }
490
            unit = findScript(this.getSystemFolder(), name);
491
            return unit;
492
        }
493
        List<ScriptingUnit> units = folder.getUnits();
494
        Iterator<ScriptingUnit> it = units.iterator();
495
        while (it.hasNext()) {
496
            unit = it.next();
497
            if (unit instanceof ScriptingFolder) {
498
                unit = findScript((ScriptingFolder) unit, name);
499
                if (unit != null) {
500
                    return unit;
501
                }
502
            } else if (unit instanceof ScriptingBaseScript) {
503
                if (name.equalsIgnoreCase(unit.getId())) {
504
                    return unit;
505
                }
506
            }
507
        }
508
        return null;
509
    }
510

    
511
    @Override
512
    public File getRootUserFolder() {
513
        return new File(this.getHomeFolder(), "scripts");
514
    }
515

    
516
    @Override
517
    public void registerSystemFolder(String name, File folder) {
518
        this.systemFolders.add(new RegisterSystemFolder(name, folder));
519
        LOG.info("Register system folder name '" + name + "' folder " + folder.getAbsolutePath() + "'");
520

    
521
    }
522

    
523
    public List<RegisterSystemFolder> getSystemFolders() {
524
        return this.systemFolders;
525
    }
526

    
527
    @Override
528
    public List<ScriptingFolder> getAlternativeUserFolders() {
529
        return this.alternativeUserFolders;
530
    }
531

    
532
    @Override
533
    public void addAlternativeUserFolder(File f, String name, String description) {
534
        UserFolder x = new UserFolder(this, f);
535
        x.setName(name);
536
        x.setDescription(description);
537
        x.setId("UserFolder_" + this.alternativeUserFolders.size() + 1);
538
        this.alternativeUserFolders.add(x);
539
    }
540
    
541
    private void initLanguages() {
542
        if (this.extensionOfLanguage == null) {
543
            Map<String, String> theExtensionOfLanguage = new HashMap<>();
544
            List<ScriptEngineFactory> factories = getEngineManager().getEngineFactories();
545
            for (ScriptEngineFactory factory : factories) {
546
                if( "ognl".equals(factory.getLanguageName()) ) {
547
                    continue;
548
                }
549
                List<String> extensions = factory.getExtensions();
550
                if (extensions != null && !extensions.isEmpty()) {
551
                    theExtensionOfLanguage.put(
552
                            factory.getLanguageName().toLowerCase(),
553
                            extensions.get(0).toLowerCase()
554
                    );
555
                }
556
            }
557
            this.extensionOfLanguage = theExtensionOfLanguage;
558
        }
559
        if (this.languageOfExtension == null) {
560
            Map<String, String> theLanguageOfExtension = new HashMap<>();
561
            List<ScriptEngineFactory> factories = getEngineManager().getEngineFactories();
562
            for (ScriptEngineFactory factory : factories) {
563
                if( "ognl".equals(factory.getLanguageName()) ) {
564
                    continue;
565
                }
566
                List<String> extensions = factory.getExtensions();
567
                if (extensions != null) {
568
                    for (String extension1 : extensions) {
569
                        theLanguageOfExtension.put(
570
                                extension1.toLowerCase(),
571
                                factory.getLanguageName().toLowerCase()
572
                        );
573
                    }
574
                }
575
            }
576
            this.languageOfExtension = theLanguageOfExtension;
577
        }
578
    }
579

    
580
    @Override
581
    public String getExtensionOfLanguage(String langName) {
582
        if (langName == null) {
583
            return null;
584
        }
585
        langName = langName.toLowerCase();
586
        initLanguages();
587
        return this.extensionOfLanguage.get(langName);
588
    }
589

    
590
    @Override
591
    public List<String> getSupportedLanguages() {
592
        List<String> languages = new ArrayList<>();
593

    
594
        initLanguages();
595
        languages.addAll(this.extensionOfLanguage.keySet());
596
        Collections.sort(languages);
597
        return languages;
598
    }
599

    
600
    public String getLanguageOfExtension(String extension) {
601
        if (extension == null) {
602
            return null;
603
        }
604
        extension = extension.toLowerCase();
605
        if (extension.startsWith(".")) {
606
            extension = extension.substring(1);
607
        }
608
        initLanguages();
609
        return this.languageOfExtension.get(extension);
610
    }
611

    
612
    @Override
613
    public Object get(String key) {
614
        return this.bindings.get(key);
615
    }
616

    
617
    @Override
618
    public void put(String key, Object value) {
619
        this.bindings.put(key, value);
620

    
621
    }
622

    
623
    @Override
624
    public ScriptingUnit createUnit(String unitType, ScriptingFolder folder, String id) {
625
        return createUnit(unitType, folder, id, null);
626
    }
627

    
628
    @Override
629
    public ScriptingUnit createUnit(String unitType, ScriptingFolder folder, String id, String language) {
630
        if (unitType.equals(UNIT_SCRIPT)) {
631
            return this.createScript(folder, id, language);
632
        }
633
        if (unitType.equals(UNIT_DIALOG)) {
634
            return this.createDialog(folder, id, language);
635
        }
636
        if (unitType.equals(UNIT_FOLDER)) {
637
            return this.createFolder(folder, id);
638
        }
639
        if (unitType.equals(UNIT_EXTERNALFILE)) {
640
            return this.createExternalFile(folder, id);
641
        }
642
        return null;
643
    }
644

    
645
    @Override
646
    public List<String> getUnitTypes() {
647
        if (this.unitTypes == null) {
648
            this.unitTypes = new ArrayList<>();
649
            this.unitTypes.add(UNIT_SCRIPT);
650
            this.unitTypes.add(UNIT_DIALOG);
651
            this.unitTypes.add(UNIT_FOLDER);
652
            this.unitTypes.add(UNIT_EXTERNALFILE);
653
        }
654
        return this.unitTypes;
655
    }
656

    
657
    @Override
658
    public void addLibFolder(File lib) {
659
        if (lib.exists()) {
660
            LOG.info("Add scripting lib folder '" + lib.getAbsolutePath() + "'");
661
            this.libFolders.add(lib);
662
        } else {
663
            LOG.info("Skip add scripting lib folder '" + lib.getAbsolutePath() + "', folder don't exist");
664
        }
665
    }
666

    
667
    @Override
668
    public List<File> getLibFolders() {
669
        return new ArrayList(this.libFolders);
670
    }
671

    
672
    @Override
673
    public Map<String, String> getLibFoldersVersions() {
674
        Map<String, String>versions = new HashMap<>();
675
        List<File> folders = this.getLibFolders();
676
        for (File folder : folders) {
677
            File parent = folder.getParentFile();
678
            File libVersions = new File(parent,folder.getName()+".versions");
679
            if( libVersions.exists() ) {
680
                this.loadLibVersions(versions, libVersions);
681
            }
682
        }
683
        if( versions.isEmpty() ) {
684
            return null;
685
        }
686
        return versions;
687
    }
688

    
689
    private void loadLibVersions(Map<String,String>versions, File file) {
690
        List<String> lines;
691
        try {
692
            lines = FileUtils.readLines(file);
693
        } catch (IOException ex) {
694
            LOG.warn("Can't load lib versions from '"+file+".",ex);
695
            return;
696
        }
697
        for (String line : lines) {
698
            String[] x = line.split("=");
699
            if( x.length==2 ) {
700
                versions.put(x[0], x[1]);
701
            } 
702
        }
703
    }
704
    
705
    @Override
706
    public ProviderFactory getInstallerFactory() {
707
        return new ScriptingInstallerProviderFactory();
708
    }
709

    
710
    @Override
711
    public File getPackagesFolder() {
712
        return this.packagesFolder;
713
    }
714

    
715
    @Override
716
    public void setPackagesFolder(File folder) {
717
        this.packagesFolder = folder;
718
    }
719

    
720
    @Override
721
    public ScriptingFolder createLink(String name, File link, String targetPathName) {
722
        StringBuilder contents = new StringBuilder();        
723
        contents.append("[Unit]\n")
724
            .append("type = Folder\n")
725
            .append("name = ").append(name).append("\n")
726
            .append("description =\n")
727
            .append("createdBy =\n")
728
            .append("version =\n")
729
            .append("\n")
730
            .append("[Folder]\n")
731
            .append("path =").append(targetPathName).append("\n")
732
            .append("\n\n");
733

    
734
        if( link.isDirectory() ) {
735
            link = new File(link,name+".inf");
736
        } else if( !link.getName().endsWith(".inf") ) {
737
            link = new File( link.getPath() + ".inf");
738
        }
739
        if( !link.exists() ) {
740
            try {
741
                FileUtils.writeStringToFile(link, contents.toString());
742
            } catch (IOException ex) {
743
                LOG.warn("Can't create ScriptingFolder file in '" + link.getAbsolutePath() + "'.", ex);
744
            }
745
        }
746
        ScriptingFolder folder = this.getFolder(link);
747
        return folder;
748
    }
749

    
750
    @Override
751
    public ScriptingFolder createLink(String name, ScriptingFolder link, String targetPathName) {
752
        return this.createLink(name, link.getFile(), targetPathName);
753
    }
754

    
755
    private final Map<File,File> links = new HashMap<>();
756
    
757
    public void addLink(File source, File target) {    
758
        this.links.put(FileUtils.getRealFile(target), source);
759
    }
760
    
761
    public File getLinkSource(File target) {
762
        File source = this.links.get(FileUtils.getRealFile(target));
763
        if( source == null ) {
764
            return target;
765
        }
766
        if( source.exists() ) {
767
            return source;
768
        }
769
        return target;
770
    }
771
    
772
    public boolean isInUserFolder(File f) {
773
        if( FileUtils.isSubfolder(this.getRootUserFolder(), f) ) {
774
            return true;
775
        }
776
        for( File file : this.links.keySet()) {
777
            if( FileUtils.isSubfolder(file, f) ) {
778
                return true;
779
            }
780
        }
781
        return false;
782
    }
783
}