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

History | View | Annotate | Download (23.9 KB)

1
package org.gvsig.scripting.impl;
2

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

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

    
20
import org.apache.commons.lang3.StringUtils;
21
import org.gvsig.scripting.ScriptingBaseScript;
22
import org.gvsig.scripting.ScriptingDialog;
23
import org.gvsig.scripting.ScriptingExternalFile;
24
import org.gvsig.scripting.ScriptingFolder;
25
import org.gvsig.scripting.ScriptingManager;
26
import org.gvsig.scripting.ScriptingScript;
27
import org.gvsig.scripting.ScriptingUnit;
28
import org.gvsig.tools.script.Script;
29
import org.gvsig.tools.service.spi.ProviderFactory;
30
import org.python.jsr223.MyPyScriptEngine;
31
import org.slf4j.Logger;
32
import org.slf4j.LoggerFactory;
33

    
34

    
35
public class DefaultScriptingManager implements ScriptingManager {
36

    
37
    public static class RegisterSystemFolder {
38

    
39
        public String name;
40
        public File folder;
41

    
42
        public RegisterSystemFolder(String name, File folder) {
43
            this.name = name;
44
            this.folder = folder;
45
        }
46
    }
47

    
48
    static final Logger LOG = LoggerFactory
49
            .getLogger(DefaultScriptingManager.class);
50
    
51
    protected Map<String, ImageIcon> icons;
52
    protected List<RegisterSystemFolder> systemFolders = new ArrayList<>();
53
    protected ScriptEngineManager engineManager = null;
54
    private final SimpleBindings bindings = new SimpleBindings();
55
    private List<String> unitTypes = null;
56
    private ClassLoader classLoader = null;
57
    private final List<File> libFolders = new ArrayList<>();
58
    private File home = null;
59
    private final List<ScriptingFolder> alternativeUserFolders = new ArrayList<>();
60
    private Map<String, String> extensionOfLanguage = null;
61
    private Map<String, String> languageOfExtension = null;
62
    private File packagesFolder;
63
    private final Map properties = new HashMap();
64
    private final Map<String,ScriptEngine> engineGroups = new HashMap<>();
65
    
66
    public DefaultScriptingManager() {
67
        this.classLoader = getClass().getClassLoader();
68
        this.setHomeFolder(null);
69
        this.bindings.put("ScriptingManager", this);
70
    }
71

    
72
    public DefaultScriptingManager(ClassLoader classLoader) {
73
        this();
74
        this.classLoader = classLoader;
75
    }
76

    
77
    @Override
78
    public Object getProperty(Object key) {
79
        return properties.get(key);
80
    }
81

    
82
    @Override
83
    public void setProperty(Object key, Object val) {
84
        properties.put(key, val);
85
    }
86

    
87
    @Override
88
    public Map getExtendedProperties() {
89
        return properties;
90
    }
91

    
92
    private void createFolder(File f) {
93
        if (!f.exists()) {
94
            try {
95
                FileUtils.forceMkdir(f);
96
                LOG.info("Created scripting folder '" + f.getAbsolutePath() + "'");
97
            } catch (Throwable e) {
98
                LOG.warn("Can't Create scripting folder '" + f.getAbsolutePath() + "'");
99
            }
100
        }
101
    }
102

    
103
    private void createDefaultFolders(File home) {
104
        createFolder(new File(home, "scripts"));
105
        createFolder(new File(home, "lib"));
106
        createFolder(new File(home, "data"));
107
    }
108

    
109
    @Override
110
    public File getHomeFolder() {
111
        if (!this.home.exists()) {
112
            createFolder(home);
113
            createDefaultFolders(home);
114
        }
115
        return this.home;
116
    }
117

    
118
    @Override
119
    public void setHomeFolder(File home) {
120
        if (home == null) {
121
            this.home = new File(System.getProperty("user.home"), ".gvsig-scripting");
122
        } else {
123
            this.home = home;
124
        }
125
        createDefaultFolders(this.home);
126
        LOG.info("Set scripting home to '" + this.home.getAbsolutePath() + "'");
127
        this.addLibFolder(new File(this.home, "lib"));
128
    }
129
    
130
    @Override
131
    public File getDataFolder(String id) {
132
        File f = FileUtils.getFile(getHomeFolder(), "data",id);
133
        createFolder(f);
134
        return f;
135
    }
136

    
137
    protected synchronized ScriptEngineManager getEngineManager() {
138
        if (this.engineManager == null) {
139
            this.engineManager
140
                    = classLoader == null ? new ScriptEngineManager()
141
                            : new ScriptEngineManager(classLoader);
142
            showEnginesInfo(engineManager);
143
        }
144
        return this.engineManager;
145
    }
146

    
147
    private void showEnginesInfo(ScriptEngineManager mgr) {
148
        if (LOG.isInfoEnabled()) {
149
            List<ScriptEngineFactory> factories = mgr.getEngineFactories();
150
            StringBuilder buffer = new StringBuilder();
151
            List<Object> values = new ArrayList<>();
152
            buffer.append("Scripting engines available:");
153
            for (ScriptEngineFactory factory : factories) {
154

    
155
                // Main engine info
156
                buffer
157
                        .append("\n- {}: version = {}, language = {}, langVersion = {}");
158
                values.add(factory.getEngineName());
159
                values.add(factory.getEngineVersion());
160
                values.add(factory.getLanguageName());
161
                values.add(factory.getLanguageVersion());
162

    
163
                // Aliases
164
                buffer.append("\n\t- Aliases: ");
165
                List<String> engNames = factory.getNames();
166
                int size = engNames.size();
167
                for (String name : engNames) {
168
                    size--;
169
                    buffer.append("{}");
170
                    if (size > 0) {
171
                        buffer.append(", ");
172
                    }
173
                    values.add(name);
174
                }
175
                buffer.append("\n\t- File extensions: ");
176
                List<String> extNames = factory.getExtensions();
177
                size = extNames.size();
178
                for (String name : extNames) {
179
                    size--;
180
                    buffer.append("{}");
181
                    if (size > 0) {
182
                        buffer.append(", ");
183
                    }
184
                    values.add(name);
185
                }
186
                buffer.append("\n\t- Mime types: ");
187
                List<String> mimeNames = factory.getMimeTypes();
188
                size = mimeNames.size();
189
                for (String name : mimeNames) {
190
                    size--;
191
                    buffer.append("{}");
192
                    if (size > 0) {
193
                        buffer.append(", ");
194
                    }
195
                    values.add(name);
196
                }
197

    
198
            }
199
            LOG.info(buffer.toString(), values.toArray());
200
        }
201
    }
202

    
203
    @Override
204
    public synchronized void loadEngines() {
205
        this.getEngineManager();
206
    }
207
    
208
    private ScriptEngine createJythonEngine() {
209
        ScriptEngineFactory factory = this.getEngineFactoryByLanguage(PYTHON_LANGUAGE_NAME);
210
        ScriptEngine engine = new MyPyScriptEngine(factory);
211
        return engine;
212
    }
213
    
214
    public ImageIcon getIcon(String name) {
215
        return this.icons.get(name);
216
    }
217

    
218
    @Override
219
    public String getEngineNameByLanguage(String langName) {
220
        ScriptEngineFactory factory = this.getEngineFactoryByLanguage(langName);
221
        if( factory == null ) {
222
            return null;
223
        }
224
        return factory.getEngineName();
225
    }
226
    
227
    public ScriptEngine getEngineByLanguage(String langName) {
228
        return this.getEngineByLanguage(langName, null);
229
    }
230
    
231
    public synchronized ScriptEngine getEngineByLanguage(String langName, String isolationGroup) {
232
        ScriptEngine engine = null;
233
        if( !StringUtils.isEmpty(isolationGroup) ) {
234
            isolationGroup += "-" + langName;
235
            engine = this.engineGroups.get(isolationGroup.toLowerCase());
236
        } 
237
        if( engine == null ) {
238
            if( PYTHON_LANGUAGE_NAME.equalsIgnoreCase(langName) ) {
239
                engine = createJythonEngine();
240
            } else {
241
                ScriptEngineFactory factory = this.getEngineFactoryByLanguage(langName);
242
                if( factory == null ) {
243
                    return null;
244
                }
245
                engine = factory.getScriptEngine();
246
            }
247
            if( SCALA_LANGUAGE_NAME.equalsIgnoreCase(langName) ) {
248
                try {
249
                    // https://gist.github.com/takawitter/5479445
250
                    Object settings = engine.getClass().getMethod("settings", new Class[0]).invoke(engine, new Object[0]);
251
                    settings.getClass().getMethod("processArgumentString", new Class[] { String.class }).invoke(settings, new String[] { "-usejavacp"});
252
                } catch(Throwable th) {
253
                    LOG.warn("Can't initialice scala setting -usejavacp",th);
254
                }
255
            }            
256
            if( !StringUtils.isEmpty(isolationGroup) ) {
257
                this.engineGroups.put(isolationGroup.toLowerCase(), engine);
258
            }
259
        }
260
        engine.getBindings(ScriptContext.ENGINE_SCOPE).putAll(bindings);
261
        return engine;
262
    }
263

    
264
    @Override
265
    public synchronized Set<String> getEnginesIsolationGroups() {
266
        return this.engineGroups.keySet();
267
    }
268
    
269
    public ScriptEngineFactory getEngineFactoryByLanguage(String langName) {
270
        List<ScriptEngineFactory> factories
271
                = getEngineManager().getEngineFactories();
272

    
273
        for (ScriptEngineFactory factory : factories) {
274
            if (factory.getLanguageName().equalsIgnoreCase(langName)) {
275
                return factory;
276
            }
277
        }
278
        return null;
279
    }
280

    
281
    @Override
282
    public boolean validateUnitId(ScriptingFolder folder, String id) {
283
        File f = new File(folder.getFile(),id+".inf");
284
        if( f.exists() ) {
285
            return false;
286
        }
287
        return true;
288
//        List<ScriptingUnit> units = folder.getUnits();
289
//        String fileName;
290
//        for (ScriptingUnit unit : units) {
291
//            fileName = unit.getId();
292
//            fileName = FilenameUtils.getBaseName(fileName);
293
//            if (fileName.equals(id)) {
294
//                return false;
295
//            }
296
//        }
297
//        return true;
298
    }
299

    
300
    public ScriptingScript createScript(ScriptingFolder folder, String id) {
301
        return this.createScript(folder, id, null);
302
    }
303
    
304
    @Override
305
    public Script createScript(String name, String code, String languaje) {
306
        ScriptingScript script = new DefaultScriptingScript(this.getUserFolder(), this, name);
307
        script.setCode(code);
308
        script.setSaved(true);
309
        return script;        
310
    }
311

    
312
    private ScriptingScript createScript(ScriptingFolder folder, String id, String language) {
313
        DefaultScriptingScript script = new DefaultScriptingScript(folder, this, id);
314
        if (!script.getFile().exists()) {
315
            script.create(folder, id, language);
316
        } else {
317
            script.load(folder, id);
318
        }
319
        return script;
320
    }
321

    
322
    public ScriptingDialog createDialog(ScriptingFolder folder, String id) {
323
        return this.createDialog(folder, id, null);
324
    }
325

    
326
    private ScriptingDialog createDialog(ScriptingFolder folder, String id, String language) {
327
        DefaultScriptingDialog dialog = new DefaultScriptingDialog(folder, this, id);
328
        if (!dialog.getFile().exists()) {
329
            dialog.create(folder, id, language);
330
        } else {
331
            dialog.load(folder, id);
332
        }
333
        return dialog;
334
    }
335

    
336
    public ScriptingFolder createFolder(ScriptingFolder folder, String id) {
337
        DefaultScriptingFolder unit = new DefaultScriptingFolder(folder, this, new File(folder.getFile(), id));
338
        unit.load(folder, id);
339
        if (!unit.getFile().exists()) {
340
            unit.create(folder, id);
341
        }
342
        return unit;
343
    }
344

    
345
    public ScriptingExternalFile createExternalFile(ScriptingFolder folder, String id) {
346
        DefaultScriptingExternalFile unit = new DefaultScriptingExternalFile(folder, this, id);
347
        if( unit.getExternalFile()!=null && !unit.getExternalFile().exists() ) {
348
            unit.create(folder, id);
349
        }
350
        return unit;
351
    }
352
    
353
    @Override
354
    public ScriptingBaseScript getScript(File file) {
355
        ScriptingBaseScript script = (ScriptingBaseScript) this.getUnit(file);
356
        if (script == null) {
357
            throw new ScriptNotFoundException(file);
358
        }
359
        return script;
360
    }
361

    
362
    
363
    @Override
364
    public ScriptingFolder getFolder(File file) {
365
        if( file == null ) {
366
            throw new IllegalArgumentException("file argument can't be null");
367
        }
368
        file = this.getLinkSource(file);
369
        if( FileUtils.isSameFile(this.getRootUserFolder(),file) ) {
370
            return this.getUserFolder();
371
        }
372
        
373
        ScriptingFolder folder = (ScriptingFolder) this.getUnit(file);
374
        if (folder == null) {
375
            throw new IllegalArgumentException("Can't get ScriptFolder from '"+file.getAbsolutePath()+"'.");
376
        }
377
        return folder;
378
    }
379

    
380
    public ScriptingUnit getUnit(File file) {
381
        ScriptingFolder folder;
382
        ScriptingUnit unit;
383

    
384
        if (file.isAbsolute()) {
385
            folder = new DefaultScriptingFolder(null, this, file.getParentFile());
386
            unit = folder.getUnit(file);
387
            return unit;
388
        } else {
389
            folder = this.getUserFolder();
390
            unit = folder.getUnit(file);
391
            if (unit != null) {
392
                return unit;
393
            }
394

    
395
            folder = this.getSystemFolder();
396
            unit = folder.getUnit(file);
397
            if (unit != null) {
398
                return unit;
399
            }
400
        }
401
        return null;
402
    }
403

    
404
    @Override
405
    public ScriptingFolder getSystemFolder() {
406
        return new SystemFolder(this);
407
    }
408

    
409
    @Override
410
    public ScriptingFolder getUserFolder() {
411
        return new UserFolder(this, this.getRootUserFolder());
412
    }
413

    
414
    @Override
415
    public ScriptingBaseScript getScript(String name) {
416
        return (ScriptingBaseScript) findScript(null, name);
417
    }
418

    
419
    @Override
420
    public Script locateScript(String name) {
421
        ScriptingUnit script = findScript(null, name);
422
        if( script instanceof Script ) {
423
            return (Script) script;
424
        }
425
        return null;
426
    }
427
    
428
    private ScriptingUnit findScript(ScriptingFolder folder, String name) {
429
        if (name == null) {
430
            return null;
431
        }
432
        if (name.trim().length() == 0) {
433
            return null;
434
        }
435
        ScriptingUnit unit;
436
        if (folder == null) {
437
            unit = findScript(this.getUserFolder(), name);
438
            if (unit != null) {
439
                return unit;
440
            }
441
            unit = findScript(this.getSystemFolder(), name);
442
            return unit;
443
        }
444
        List<ScriptingUnit> units = folder.getUnits();
445
        Iterator<ScriptingUnit> it = units.iterator();
446
        while (it.hasNext()) {
447
            unit = it.next();
448
            if (unit instanceof ScriptingFolder) {
449
                unit = findScript((ScriptingFolder) unit, name);
450
                if (unit != null) {
451
                    return unit;
452
                }
453
            } else if (unit instanceof ScriptingBaseScript) {
454
                if (name.equalsIgnoreCase(unit.getId())) {
455
                    return unit;
456
                }
457
            }
458
        }
459
        return null;
460
    }
461

    
462
    @Override
463
    public File getRootUserFolder() {
464
        return new File(this.getHomeFolder(), "scripts");
465
    }
466

    
467
    @Override
468
    public void registerSystemFolder(String name, File folder) {
469
        this.systemFolders.add(new RegisterSystemFolder(name, folder));
470
        LOG.info("Register system folder name '" + name + "' folder " + folder.getAbsolutePath() + "'");
471

    
472
    }
473

    
474
    public List<RegisterSystemFolder> getSystemFolders() {
475
        return this.systemFolders;
476
    }
477

    
478
    @Override
479
    public List<ScriptingFolder> getAlternativeUserFolders() {
480
        return this.alternativeUserFolders;
481
    }
482

    
483
    @Override
484
    public void addAlternativeUserFolder(File f, String name, String description) {
485
        UserFolder x = new UserFolder(this, f);
486
        x.setName(name);
487
        x.setDescription(description);
488
        x.setId("UserFolder_" + this.alternativeUserFolders.size() + 1);
489
        this.alternativeUserFolders.add(x);
490
    }
491
    
492
    private void initLanguages() {
493
        if (this.extensionOfLanguage == null) {
494
            Map<String, String> extensionOfLanguage = new HashMap<>();
495
            List<ScriptEngineFactory> factories = getEngineManager().getEngineFactories();
496
            for (ScriptEngineFactory factory : factories) {
497
                if( "ognl".equals(factory.getLanguageName()) ) {
498
                    continue;
499
                }
500
                List<String> extensions = factory.getExtensions();
501
                if (extensions != null && !extensions.isEmpty()) {
502
                    extensionOfLanguage.put(
503
                            factory.getLanguageName().toLowerCase(),
504
                            extensions.get(0).toLowerCase()
505
                    );
506
                }
507
            }
508
            this.extensionOfLanguage = extensionOfLanguage;
509
        }
510
        if (this.languageOfExtension == null) {
511
            Map<String, String> languageOfExtension = new HashMap<>();
512
            List<ScriptEngineFactory> factories = getEngineManager().getEngineFactories();
513
            for (ScriptEngineFactory factory : factories) {
514
                if( "ognl".equals(factory.getLanguageName()) ) {
515
                    continue;
516
                }
517
                List<String> extensions = factory.getExtensions();
518
                if (extensions != null) {
519
                    for (String extension1 : extensions) {
520
                        languageOfExtension.put(
521
                                extension1.toLowerCase(),
522
                                factory.getLanguageName().toLowerCase()
523
                        );
524
                    }
525
                }
526
            }
527
            this.languageOfExtension = languageOfExtension;
528
        }
529
    }
530

    
531
    @Override
532
    public String getExtensionOfLanguage(String langName) {
533
        if (langName == null) {
534
            return null;
535
        }
536
        langName = langName.toLowerCase();
537
        initLanguages();
538
        return this.extensionOfLanguage.get(langName);
539
    }
540

    
541
    @Override
542
    public List<String> getSupportedLanguages() {
543
        List<String> languages = new ArrayList<>();
544

    
545
        initLanguages();
546
        languages.addAll(this.extensionOfLanguage.keySet());
547
        Collections.sort(languages);
548
        return languages;
549
    }
550

    
551
    public String getLanguageOfExtension(String extension) {
552
        if (extension == null) {
553
            return null;
554
        }
555
        extension = extension.toLowerCase();
556
        if (extension.startsWith(".")) {
557
            extension = extension.substring(1);
558
        }
559
        initLanguages();
560
        return this.languageOfExtension.get(extension);
561
    }
562

    
563
    @Override
564
    public Object get(String key) {
565
        return this.bindings.get(key);
566
    }
567

    
568
    @Override
569
    public void put(String key, Object value) {
570
        this.bindings.put(key, value);
571

    
572
    }
573

    
574
    @Override
575
    public ScriptingUnit createUnit(String unitType, ScriptingFolder folder, String id) {
576
        return createUnit(unitType, folder, id, null);
577
    }
578

    
579
    @Override
580
    public ScriptingUnit createUnit(String unitType, ScriptingFolder folder, String id, String language) {
581
        if (unitType.equals(UNIT_SCRIPT)) {
582
            return this.createScript(folder, id, language);
583
        }
584
        if (unitType.equals(UNIT_DIALOG)) {
585
            return this.createDialog(folder, id, language);
586
        }
587
        if (unitType.equals(UNIT_FOLDER)) {
588
            return this.createFolder(folder, id);
589
        }
590
        if (unitType.equals(UNIT_EXTERNALFILE)) {
591
            return this.createExternalFile(folder, id);
592
        }
593
        return null;
594
    }
595

    
596
    @Override
597
    public List<String> getUnitTypes() {
598
        if (this.unitTypes == null) {
599
            this.unitTypes = new ArrayList<>();
600
            this.unitTypes.add(UNIT_SCRIPT);
601
            this.unitTypes.add(UNIT_DIALOG);
602
            this.unitTypes.add(UNIT_FOLDER);
603
            this.unitTypes.add(UNIT_EXTERNALFILE);
604
        }
605
        return this.unitTypes;
606
    }
607

    
608
    @Override
609
    public void addLibFolder(File lib) {
610
        if (lib.exists()) {
611
            LOG.info("Add scripting lib folder '" + lib.getAbsolutePath() + "'");
612
            this.libFolders.add(lib);
613
        } else {
614
            LOG.info("Skip add scripting lib folder '" + lib.getAbsolutePath() + "', folder don't exist");
615
        }
616
    }
617

    
618
    @Override
619
    public List<File> getLibFolders() {
620
        return new ArrayList(this.libFolders);
621
    }
622

    
623
    @Override
624
    public Map<String, String> getLibFoldersVersions() {
625
        Map<String, String>versions = new HashMap<>();
626
        List<File> folders = this.getLibFolders();
627
        for (File folder : folders) {
628
            File parent = folder.getParentFile();
629
            File libVersions = new File(parent,folder.getName()+".versions");
630
            if( libVersions.exists() ) {
631
                this.loadLibVersions(versions, libVersions);
632
            }
633
        }
634
        if( versions.isEmpty() ) {
635
            return null;
636
        }
637
        return versions;
638
    }
639

    
640
    private void loadLibVersions(Map<String,String>versions, File file) {
641
        List<String> lines;
642
        try {
643
            lines = FileUtils.readLines(file);
644
        } catch (IOException ex) {
645
            LOG.warn("Can't load lib versions from '"+file+".",ex);
646
            return;
647
        }
648
        for (String line : lines) {
649
            String[] x = line.split("=");
650
            if( x.length==2 ) {
651
                versions.put(x[0], x[1]);
652
            } 
653
        }
654
    }
655
    
656
    @Override
657
    public ProviderFactory getInstallerFactory() {
658
        return new ScriptingInstallerProviderFactory();
659
    }
660

    
661
    @Override
662
    public File getPackagesFolder() {
663
        return this.packagesFolder;
664
    }
665

    
666
    @Override
667
    public void setPackagesFolder(File folder) {
668
        this.packagesFolder = folder;
669
    }
670

    
671
    @Override
672
    public ScriptingFolder createLink(String name, File link, String targetPathName) {
673
        StringBuilder contents = new StringBuilder();        
674
        contents.append("[Unit]\n")
675
            .append("type = Folder\n")
676
            .append("name = ").append(name).append("\n")
677
            .append("description =\n")
678
            .append("createdBy =\n")
679
            .append("version =\n")
680
            .append("\n")
681
            .append("[Folder]\n")
682
            .append("path =").append(targetPathName).append("\n")
683
            .append("\n\n");
684

    
685
        if( link.isDirectory() ) {
686
            link = new File(link,name+".inf");
687
        } else if( !link.getName().endsWith(".inf") ) {
688
            link = new File( link.getPath() + ".inf");
689
        }
690
        if( !link.exists() ) {
691
            try {
692
                FileUtils.writeStringToFile(link, contents.toString());
693
            } catch (IOException ex) {
694
                LOG.warn("Can't create ScriptingFolder file in '" + link.getAbsolutePath() + "'.", ex);
695
            }
696
        }
697
        ScriptingFolder folder = this.getFolder(link);
698
        return folder;
699
    }
700

    
701
    @Override
702
    public ScriptingFolder createLink(String name, ScriptingFolder link, String targetPathName) {
703
        return this.createLink(name, link.getFile(), targetPathName);
704
    }
705

    
706
    private Map<File,File> links = new HashMap<>();
707
    
708
    public void addLink(File source, File target) {    
709
        this.links.put(FileUtils.getRealFile(target), source);
710
    }
711
    
712
    public File getLinkSource(File target) {
713
        File source = this.links.get(FileUtils.getRealFile(target));
714
        if( source == null ) {
715
            return target;
716
        }
717
        if( source.exists() ) {
718
            return source;
719
        }
720
        return target;
721
    }
722
    
723
    public boolean isInUserFolder(File f) {
724
        if( FileUtils.isSubfolder(this.getRootUserFolder(), f) ) {
725
            return true;
726
        }
727
        for( File file : this.links.keySet()) {
728
            if( FileUtils.isSubfolder(file, f) ) {
729
                return true;
730
            }
731
        }
732
        return false;
733
    }
734
}