Statistics
| Revision:

gvsig-scripting / org.gvsig.scripting / trunk / org.gvsig.scripting / org.gvsig.scripting.app / org.gvsig.scripting.app.mainplugin / src / main / java / org / gvsig / scripting / app / extension / ScriptingUtils.java @ 1862

History | View | Annotate | Download (27.5 KB)

1
package org.gvsig.scripting.app.extension;
2

    
3
import java.awt.event.ActionEvent;
4
import java.awt.event.ActionListener;
5
import java.io.File;
6
import java.io.IOException;
7
import java.nio.file.FileVisitOption;
8
import static java.nio.file.FileVisitOption.FOLLOW_LINKS;
9
import java.nio.file.FileVisitResult;
10
import java.nio.file.Files;
11
import java.nio.file.Path;
12
import java.nio.file.Paths;
13
import java.nio.file.SimpleFileVisitor;
14
import java.nio.file.attribute.BasicFileAttributes;
15
import java.text.MessageFormat;
16
import java.util.ArrayList;
17
import java.util.Arrays;
18
import java.util.Collections;
19
import java.util.Comparator;
20
import java.util.EnumSet;
21
import java.util.List;
22
import java.util.function.Predicate;
23
import java.util.logging.Level;
24
import javax.swing.JOptionPane;
25
import javax.swing.SwingUtilities;
26
import org.apache.commons.collections4.CollectionUtils;
27
import org.apache.commons.io.FileUtils;
28
import org.apache.commons.io.FilenameUtils;
29
import org.apache.commons.io.IOCase;
30
import org.apache.commons.lang3.BooleanUtils;
31
import org.apache.commons.lang3.StringUtils;
32
import org.gvsig.andami.PluginServices;
33
import org.gvsig.andami.PluginsLocator;
34
import org.gvsig.andami.PluginsManager;
35
import org.gvsig.expressionevaluator.Code;
36
import org.gvsig.expressionevaluator.ExpressionUtils;
37
import org.gvsig.scripting.DataFolderFound;
38
import org.gvsig.scripting.ScriptingBaseScript;
39
import org.gvsig.scripting.ScriptingFolder;
40
import org.gvsig.scripting.ScriptingLocator;
41
import org.gvsig.scripting.ScriptingManager;
42
import org.gvsig.scripting.ScriptingScript;
43
import org.gvsig.scripting.ScriptingUnit;
44
import org.gvsig.scripting.app.extension.messagewait.MessageWait;
45
import org.gvsig.scripting.swing.api.JScriptingComposer;
46
import org.gvsig.scripting.swing.api.ScriptingSwingLocator;
47
import org.gvsig.scripting.swing.api.ScriptingUIManager;
48
import static org.gvsig.scripting.swing.api.ScriptingUIManager.SCRIPT_COMPOSER_AUTORUN;
49
import org.gvsig.tools.ToolsLocator;
50
import org.gvsig.tools.dynobject.DynObject;
51
import org.gvsig.tools.exception.BaseException;
52
import org.gvsig.tools.i18n.I18nManager;
53
import org.gvsig.tools.packageutils.PackageManager;
54
import org.gvsig.tools.packageutils.Version;
55
import org.gvsig.tools.swing.api.ToolsSwingLocator;
56
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
57
import org.gvsig.tools.swing.api.windowmanager.Dialog;
58
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
59
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
60
import org.gvsig.tools.swing.impl.windowmanager.DefaultWindowManager;
61
import org.gvsig.tools.task.SimpleTaskStatus;
62
import org.gvsig.tools.visitor.VisitCanceledException;
63
import org.gvsig.tools.visitor.Visitor;
64
import org.slf4j.Logger;
65
import org.slf4j.LoggerFactory;
66
import org.gvsig.tools.util.FolderSet;
67
import org.gvsig.tools.util.impl.DefaultFolderSet;
68
/**
69
 *
70
 * @author jjdelcerro
71
 */
72
@SuppressWarnings("UseSpecificCatch")
73
public class ScriptingUtils {
74
    
75
    public static final String SKIP_AUTORUNS = "skipAutoruns";
76
    
77
    private static final Logger LOGGER = LoggerFactory.getLogger(ScriptingExtension.class);
78

    
79
    private boolean executingAutorunScripts = false;
80
    private static boolean composer_initialized = false;
81
    private final MessageWait message;
82

    
83
    /*
84
     * la funcion log y las constantes estan pensadas para usarlas desde los scripts.
85
     */
86
    public static final int INFO = 0;
87
    public static final int TRACE = 1;
88
    public static final int WARN = 2;
89
    public static final int ERROR = 3;
90

    
91
    public static void log(String message) {
92
        log(INFO, message, null);
93
    }
94

    
95
    public static void log(int level, String message) {
96
        log(level, message, null);
97
    }
98

    
99
    public static void log(int level, String message, Throwable th) {
100
        switch( level ) {
101
        case TRACE:
102
            LOGGER.trace(message, th);
103
            break;
104
        case ERROR:
105
            LOGGER.error(message, th);
106
            break;
107
        case WARN:
108
            LOGGER.warn(message, th);
109
            break;
110
        default:
111
        case INFO:
112
            LOGGER.info(message, th);
113
            break;
114
        }
115
    }
116
    private String appversion;
117
    private File pluginHomeFolder;
118

    
119
    public ScriptingUtils() {
120
        message = new MessageWait();
121
    }
122
    
123
    public static File getScriptsHomeFolder(File pluginHomeFolder, String appversion) {
124
        File scriptsHomeFolder;
125
        File f = FileUtils.getFile(pluginHomeFolder, "scripts-folder.txt");
126
        if( f.exists() ) {
127
            try {
128
                List<String> lines = FileUtils.readLines(f);
129
                for( String line : lines ) {
130
                    line = line.trim();
131
                    if( !line.startsWith("#") ) {
132
                        scriptsHomeFolder = new File(line);
133
                        if( !scriptsHomeFolder.isAbsolute() ) {
134
                            scriptsHomeFolder = new File(pluginHomeFolder, line);
135
                        }
136
                        scriptsHomeFolder = new File(
137
                            FilenameUtils.normalizeNoEndSeparator(
138
                                scriptsHomeFolder.getAbsolutePath(),
139
                                true
140
                            )
141
                        );
142
                        if( scriptsHomeFolder.exists() ) {
143
                            return scriptsHomeFolder;
144
                        }
145
                    }
146
                }
147
            } catch (IOException ex) {
148
            }
149
        } else {
150
            try {
151
                FileUtils.touch(f);
152
            } catch (IOException ex) {
153
            }
154
        }
155
        scriptsHomeFolder = FileUtils.getFile(pluginHomeFolder, appversion) ;
156
        return scriptsHomeFolder;
157
    }
158
    
159
    public void initializaPaths(List<File> pluginsFolder, File installFolder, File pluginHoneFolder, String appversion) {
160

    
161
        this.appversion = appversion;
162
        this.pluginHomeFolder = pluginHoneFolder;
163
        ScriptingManager manager = ScriptingLocator.getManager();
164
        manager.setHomeFolder(getScriptsHomeFolder(pluginHoneFolder, appversion));
165

    
166
        ScriptingFolder folder = manager.createLink(
167
            "Common",
168
            manager.getUserFolder(), 
169
            "../../scripts"
170
        );
171
        folder.setProperty(ScriptingUtils.SKIP_AUTORUNS, BooleanUtils.toStringTrueFalse(true));
172
        folder.save();
173
//        manager.createLink(
174
//            "Previous version",
175
//            manager.getUserFolder(), 
176
//            "../../../org.gvsig.scripting.app.extension/scripts"
177
//        );
178

    
179
        List<File> pluginsFolders = new ArrayList<>();
180
        for( File f : pluginsFolder ) {
181
            pluginsFolders.addAll(Arrays.asList(f.listFiles()));
182
        }
183

    
184
        for( File pluginFolder : pluginsFolders ) {
185
            File scriptsFolder = new File(pluginFolder, "scripting/scripts");
186
            if( scriptsFolder.exists() ) {
187
                manager.registerSystemFolder(pluginFolder.getName(), scriptsFolder);
188
            }
189
            File libFolder = new File(pluginFolder, "scripting/lib");
190
            if( libFolder.exists() ) {
191
                manager.addLibFolder(libFolder);
192
            }
193
        }
194
        manager.setPackagesFolder(installFolder);
195

    
196
        File localAddonRepositoryFolder = new File(manager.getRootUserFolder(), "addons");
197
        if( !localAddonRepositoryFolder.exists() ) {
198
            try {
199
                FileUtils.forceMkdir(localAddonRepositoryFolder);
200
            } catch (IOException ex) {
201
                LOGGER.info("Can't create addons folder in '" + localAddonRepositoryFolder.getAbsolutePath() + "'.", ex);
202
            }
203
        }
204
        File initAddonFile = new File(localAddonRepositoryFolder, "__init__.py");
205
        if( !initAddonFile.exists() ) {
206
            try {
207
                FileUtils.touch(initAddonFile);
208
            } catch (IOException ex) {
209
                LOGGER.info("Can't create addons __init__ file in '" + localAddonRepositoryFolder.getAbsolutePath() + "'.", ex);
210
            }
211
        }
212
    }
213
    
214
    
215
    public void runScript(String name, Object[] args) {
216
        if( StringUtils.isBlank(name) ) {
217
            return;
218
        }
219
        String method = null;
220
        if( name.contains(".") ) {
221
            String[] ss = StringUtils.split(name, '.');
222
            name = ss[0];
223
            if( StringUtils.isAlphanumeric(ss[1]) ) {
224
                method = ss[1];
225
            } else {
226
                try {
227
                    Code.Callable code = (Code.Callable) ExpressionUtils.compile(ss[1]);
228
                    method = code.name();
229
                    try {
230
                        code.link();
231
                        List<Object> args2 = new ArrayList<>();
232
                        for (Code param : code.parameters()) {
233
                            args2.add(((Code.Constant)param).value());
234
                        }
235
                        if( !CollectionUtils.isEmpty(args2) ) {
236
                            args = args2.toArray(new Object[args2.size()]);
237
                        }
238
                    } catch(Throwable t) {
239
                        LOGGER.warn("Can't process command args ("+name+").",t);
240
                    }
241
                } catch(Throwable t) {
242
                    LOGGER.warn("Can't process command ("+name+").",t);
243
                    method = StringUtils.left(ss[1], indexOfNonAlphanumeric(ss[1])+1);
244
                }
245
            }
246
        }
247
        ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
248
        ScriptingUIManager uimanager = ScriptingSwingLocator.getUIManager();
249
        ScriptingBaseScript script = uimanager.getManager().getScript(name);
250
        if( script != null ) {
251
            if( StringUtils.isNotBlank(method) && script instanceof ScriptingScript ) {
252
                try {
253
                    ((ScriptingScript)script).invokeFunction(method, args);
254
                } catch (NoSuchMethodException ex) {
255
                    LOGGER.warn("Can't call method '"+method+"' of script '"+name+"'.", ex);
256
                    dialogs.messageDialog(
257
                            "Can't call method '"+method+"' of script '"+name+"'.", 
258
                            "ScriptLaunch", 
259
                            JOptionPane.OK_OPTION
260
                    );
261
                }
262
            } else {
263
                script.run(args);
264
            }
265
        } else {
266
            dialogs.messageDialog(
267
                    "Can't locate script '" + name + "'.", 
268
                    "ScriptLaunch", 
269
                    JOptionPane.OK_OPTION
270
            );
271
        }
272
    }
273
    
274
    public void runLauncher() {
275
        ScriptingUIManager uimanager = ScriptingSwingLocator.getUIManager();
276
        WindowManager winmanager = ToolsSwingLocator.getWindowManager();        
277
        winmanager.showWindow(uimanager.createLauncher().asJComponent(), uimanager.getTranslation("Scripting_Launcher"), WindowManager.MODE.TOOL);        
278
    }
279
    
280
    public void runComposer() {
281
        PluginsManager pluginsManager = PluginsLocator.getPluginsManager();
282
        PluginServices plugin = pluginsManager.getPlugin(ScriptingExtension.class);
283
        if( plugin!=null ) {
284
            DynObject preferences = plugin.getPluginProperties();
285
            if( preferences!=null ) {
286
                Boolean composerUseHisWindowManager = (Boolean) preferences.getDynValue("ComposerUseHisWindowManager");
287
                if( composerUseHisWindowManager!=null && composerUseHisWindowManager ) {
288
                    DefaultWindowManager winmanager = new DefaultWindowManager();
289
                    ScriptingUIManager uimanager = ScriptingSwingLocator.getUIManager();
290
                    uimanager.setWindowManager(winmanager);
291
                }
292
            }
293
        }
294

    
295
        I18nManager i18n = ToolsLocator.getI18nManager();
296
        message.showMessage(
297
                i18n.getTranslation("_notice"),
298
                i18n.getTranslation("_Initializing_the_scripting_plugin_Xhorizontal_ellipsisX") + "\n"
299
                + i18n.getTranslation("_Waiting_to_terminate"),
300
                new MessageWait.WaitingCondition() {
301
            private Thread th = null;
302

    
303
            @Override
304
            public boolean stopWaiting() {
305
                if (executingAutorunScripts) {
306
                    return false;
307
                }
308
                if (composer_initialized) {
309
                    return true;
310
                }
311
                if (th == null) {
312
                    th = new Thread(new ExecuteScriptsFromScriptingFolders(null, "scautorun", SCRIPT_COMPOSER_AUTORUN), "StartupScriptingComposer");
313
                    th.start();
314
                }
315
                return false;
316
            }
317
        },
318
                new Runnable() {
319
            @Override
320
            public void run() {
321
                showScriptingComposer();
322
            }
323
        }
324
        );
325

    
326
    }
327
    
328
    public Runnable getAutorunScriptsOnStartup(List<File> pluginsFolders) {
329
        return new ExecuteAutorunScriptsOnStartup(pluginsFolders);
330
    }
331
    
332
    private void showScriptingComposer() {
333
        ScriptingUIManager uimanager = ScriptingSwingLocator.getUIManager();
334
        JScriptingComposer composer = uimanager.createComposer();
335
        uimanager.showWindow(
336
            composer.asJComponent(),
337
            uimanager.getTranslation("Scripting_Composer")
338
        );
339
    }
340

    
341
    private class ExecuteScriptsFromScriptingFolders extends AbstractExecuteScripts {
342
        
343
        public ExecuteScriptsFromScriptingFolders(List<File> pluginsFolders, String title, String patternName) {
344
            super(pluginsFolders, title, patternName);
345
        }
346
        
347
        @Override
348
        public void run() {            
349
            ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
350
            SimpleTaskStatus status = ToolsLocator.getTaskStatusManager().createDefaultSimpleTaskStatus("Scripts startup");
351
            status.setIndeterminate();
352
            status.setAutoremove(true);
353
            status.add();
354
            final I18nManager i18nManager = ToolsLocator.getI18nManager();            
355
            try {
356
                LOGGER.info("Searching "+title+" scripts...");
357
                dialogs.message(
358
                    i18nManager.getTranslation("_Searching_autorun_scripts_Xhorizontal_ellipsisX"),
359
                    JOptionPane.INFORMATION_MESSAGE
360
                );
361
                ScriptingManager manager = ScriptingLocator.getManager();
362
                final List<ScriptingScript> scripts = new ArrayList<>();
363
                
364
                Visitor visitor = new Visitor() {
365
                    @Override
366
                    public void visit(Object o) throws VisitCanceledException, BaseException {
367
                        ScriptingUnit unit = (ScriptingUnit) o;
368
                        if( unit instanceof ScriptingScript && 
369
                            FilenameUtils.wildcardMatch(unit.getName(), patternName, IOCase.INSENSITIVE) ) {
370
                            ScriptingScript script = (ScriptingScript) unit;
371
                            if( script.isEnabled() ) {
372
                                scripts.add(script);
373
                            } else {
374
                                LOGGER.info("Skip "+title+" script '" + script.getFile().getAbsolutePath() + "'.");
375
                            }
376
                        }
377
                    }
378
                };
379
                Predicate<ScriptingUnit> includeFilter = new Predicate<ScriptingUnit>() {
380
                    @Override
381
                    public boolean test(ScriptingUnit unit) {
382
                        if( unit instanceof ScriptingFolder ) {
383
                            return !BooleanUtils.toBoolean(unit.getProperty(SKIP_AUTORUNS));
384
                        }
385
                        return false;
386
                    }
387
                };
388
                manager.getSystemFolder().accept(visitor, includeFilter);
389
                manager.getUserFolder().accept(visitor, includeFilter);
390
                sortScripts(scripts);
391
                executeScripts(scripts, status);
392
            } catch(Throwable th) {
393
                
394
            } finally {
395
                composer_initialized = true;
396
                LOGGER.info("Running "+title+" scripts terminated.");
397
                dialogs.message("", JOptionPane.INFORMATION_MESSAGE);
398
                status.terminate();
399
            }
400
        }
401
    }
402

    
403
    public class ExecuteAutorunScriptsOnStartup implements Runnable {
404

    
405
        private final List<File> pluginsFolders;
406

    
407
        public ExecuteAutorunScriptsOnStartup(List<File> pluginsFolders) {
408
            this.pluginsFolders = pluginsFolders;
409
        }
410
        
411
        @Override
412
        public void run() {
413
            Runnable process = new ExecuteScriptsFromFilesystem(
414
                    this.pluginsFolders,
415
                    "autorun", 
416
                    "autorun.inf"
417
            );
418
            process.run();
419
        }
420
    }
421

    
422
    private abstract class AbstractExecuteScripts implements Runnable {
423

    
424
        protected String patternName;
425
        protected String title;
426
        private final List<File> pluginsFolders;
427

    
428
        public AbstractExecuteScripts(List<File> pluginsFolders, String title, String patternName) {
429
            if( pluginsFolders==null ) {
430
                this.pluginsFolders = Collections.EMPTY_LIST;
431
            } else {
432
                this.pluginsFolders = pluginsFolders;
433
            }
434
            this.patternName = patternName;
435
            this.title = title;
436
        }
437
        
438
        protected List<File> getPluginsFolders() {
439
            return this.pluginsFolders;
440
        }
441
        
442
        private String getScriptOrderKey(ScriptingBaseScript o) {
443
            int groupOrder = 500;
444
            String groupName = "default";
445
            int scriptOrder = 500;
446
            String s = o.getProperty("autorun.group.order");
447
            if (s != null) {
448
                try {
449
                    groupOrder = Integer.parseInt(s);
450
                } catch (Exception ex) {
451
                    // Do nothing.
452
                }
453
            }
454
            s = o.getProperty("autorun.group.name");
455
            if (s != null) {
456
                groupName = s;
457
            }
458
            s = o.getProperty("autorun.order");
459
            if (s != null) {
460
                try {
461
                    scriptOrder = Integer.parseInt(s);
462
                } catch (Exception ex) {
463
                    // Do nothing.
464
                }
465
            }
466
            String key = MessageFormat.format(
467
                    "{0,number,000000}.{1}.{2,number,000000}",
468
                    groupOrder,
469
                    groupName,
470
                    scriptOrder
471
            );
472
            return key;
473
        }
474

    
475
        protected void sortScripts(List<ScriptingScript> scripts) {
476
            Collections.sort(scripts, new Comparator<ScriptingBaseScript>() {
477

    
478
                @Override
479
                public int compare(ScriptingBaseScript o1, ScriptingBaseScript o2) {
480
                    return getScriptOrderKey(o1).compareToIgnoreCase(getScriptOrderKey(o2));
481
                }
482
            });
483
        }
484

    
485
        protected void executeScripts(List<ScriptingScript> scripts, SimpleTaskStatus status) {
486
            ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
487
            final I18nManager i18nManager = ToolsLocator.getI18nManager();
488
            if (scripts != null && !scripts.isEmpty()) {
489
                LOGGER.info("Scripts to run:");
490
                for (ScriptingBaseScript script : scripts) {
491
                    try {
492
                        LOGGER.info(StringUtils.abbreviateMiddle(script.getFile().getParent(),"...",50) + " (" + getScriptOrderKey(script) + ", " + script.getIsolationGroup() + ")");
493
                    } catch(Throwable t) {
494
                        LOGGER.info("...Error...");
495
                    }
496
                }                
497
                if (status != null) {
498
                    status.setRangeOfValues(0, scripts.size());
499
                }
500
                int n = 0;
501
                for (ScriptingBaseScript script : scripts) {
502
                    if (status != null) {
503
                        status.setCurValue(n++);
504
                    }
505
                    try {
506
                        if( StringUtils.equals("autorun", title) ) {
507
                            LOGGER.info("running '" + script.getFile().getParent() + "'.");
508
                        } else {
509
                            LOGGER.info("running " + title + " '" + script.getFile().getAbsolutePath() + "'.");
510
                        }
511
                        dialogs.message(
512
                                i18nManager.getTranslation(
513
                                        "_Starting_XnameX",
514
                                        new String[]{
515
                                            script.getFile().getParentFile().getName()}
516
                                ),
517
                                JOptionPane.INFORMATION_MESSAGE
518
                        );
519
                    } catch (Exception ex) {
520
                        // Ignore it
521
                    }
522
                    try {
523
                        // Hacemos un reload por si un sript deshabilito a otro.
524
                        script.reload();
525
                        if( script.isEnabled() ) {
526
                            script.run();
527
                        } else {
528
                            LOGGER.info("Skip " + title + " script '" + script.getFile().getAbsolutePath() + "' (" + getScriptOrderKey(script) + ", " + script.getIsolationGroup() + ").");
529
                        }
530
                    } catch (Exception ex) {
531
                        LOGGER.warn("Can't execute " + title + " from '" + script.getFile().getAbsolutePath() + "'.", ex);
532
                    }
533
                }
534
            }
535

    
536
        }
537
    }
538

    
539
    private class ExecuteScriptsFromFilesystem extends AbstractExecuteScripts {
540

    
541
        public ExecuteScriptsFromFilesystem(List<File> pluginsFolder, String title, String patternName) {
542
            super(pluginsFolder, title, patternName);
543
        }
544

    
545
        @Override
546
        public void run() {
547
            ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
548
            executingAutorunScripts = true;
549
            try {
550
                final ScriptingManager manager = ScriptingLocator.getManager();
551
                manager.loadEngines();
552

    
553
//                final PluginsManager pluginManager = PluginsLocator.getManager();
554
                final I18nManager i18nManager = ToolsLocator.getI18nManager();
555

    
556
                final List<ScriptingScript> scripts = new ArrayList<>();
557

    
558
                List<File> pluginsFolders = new ArrayList<>();
559
                for (File pluginsFolders2 : this.getPluginsFolders()) {
560
                    for (File pluginFolder : pluginsFolders2.listFiles()) {
561
                        File f = FileUtils.getFile(pluginFolder, "scripting", "scripts");
562
                        if (f.exists()) {
563
                            pluginsFolders.add(f);
564
                        }
565
                    }
566
                }
567

    
568
                dialogs.message(
569
                        i18nManager.getTranslation("_Searching_autorun_scripts_Xhorizontal_ellipsisX"),
570
                        JOptionPane.INFORMATION_MESSAGE
571
                );
572

    
573
                SimpleFileVisitor<Path> visitor = new SimpleFileVisitor<Path>() {
574
                    @Override
575
                    public FileVisitResult visitFile(Path path, BasicFileAttributes bfa) throws IOException {
576
                        File file = path.toFile();
577
                        if (FilenameUtils.wildcardMatch(file.getName(), patternName, IOCase.INSENSITIVE)) {
578
                            if (file.exists()) {
579
                                ScriptingScript script = (ScriptingScript) manager.getScript(file);
580
                                if (script.isEnabled()) {
581
                                    scripts.add(script);
582
                                } else {
583
                                    LOGGER.info("Skip " + title + " script '" + file.getAbsolutePath() + "'.");
584
                                }
585
                            }
586
                        }
587
                        return FileVisitResult.CONTINUE;
588
                    }
589
                };
590
                try {
591
                    EnumSet<FileVisitOption> opts = EnumSet.of(FOLLOW_LINKS);
592
                    for (File pluginFolder : pluginsFolders) {
593
                        Files.walkFileTree(Paths.get(pluginFolder.toURI()), opts, Integer.MAX_VALUE, visitor);
594
                    }
595
                    Files.walkFileTree(Paths.get(manager.getRootUserFolder().toURI()), opts, Integer.MAX_VALUE, visitor);
596
                    List<ScriptingFolder> folders = manager.getAlternativeUserFolders();
597
                    for (ScriptingFolder folder : folders) {
598
                        Files.walkFileTree(Paths.get(folder.getFile().toURI()), opts, Integer.MAX_VALUE, visitor);
599
                    }
600
                } catch (Exception ex) {
601
                    LOGGER.warn("Can't execute " + title + " in home.", ex);
602
                }
603
                sortScripts(scripts);
604
                executeScripts(scripts, null);
605

    
606
            } finally {
607
                LOGGER.info("Running " + title + " scripts terminated.");
608
                dialogs.message("", JOptionPane.INFORMATION_MESSAGE);
609
                executingAutorunScripts = false;
610
            }
611
            checkDataFoldersVersions();
612
        }
613

    
614
    }
615
    
616
    private void checkDataFoldersVersions() {
617
        final ScriptingManager manager = ScriptingLocator.getManager();
618
        PackageManager versionFactory = ToolsLocator.getPackageManager();
619
        Version currentVersion = versionFactory.createVersion(this.appversion);
620
        FolderSet folders = new DefaultFolderSet();
621
        folders.add(this.pluginHomeFolder);
622
        final List<DataFolderFound> dataFoldersFound = manager.searchOldVersions(currentVersion, folders);
623
        if( dataFoldersFound == null || dataFoldersFound.isEmpty() ) {
624
            return;
625
        }
626
        Runnable askUser = new Runnable() {
627
            @Override
628
            public void run() {
629
                WindowManager_v2 winManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
630
                final DataFoldersRecoverPanel panel = new DataFoldersRecoverPanel(dataFoldersFound);
631
                final Dialog dialog = winManager.createDialog(
632
                        panel,
633
                        "Recuperacion de preferencias",
634
                        null,
635
                        WindowManager_v2.BUTTONS_OK_CANCEL
636
                );
637
                dialog.addActionListener(new ActionListener() {
638
                    @Override
639
                    public void actionPerformed(ActionEvent e) {
640
                        if (dialog.getAction() == WindowManager_v2.BUTTON_OK) {
641
                            List<DataFolderFound> toRestore = panel.getSelectedDataFolders();
642
                            for (DataFolderFound dataFolderFound : dataFoldersFound) {
643
                                if (toRestore.contains(dataFolderFound)) {
644
                                    dataFolderFound.restore();
645
                                } else {
646
                                    dataFolderFound.leave();
647
                                }
648
                            }
649
                        }
650
                    }
651
                });
652
                dialog.show(WindowManager.MODE.WINDOW);
653
            }
654
        };
655
        if( SwingUtilities.isEventDispatchThread() ) {
656
            askUser.run();
657
        } else {
658
            SwingUtilities.invokeLater(askUser);
659
        }
660
    }
661
    
662
    private int indexOfNonAlphanumeric(String s) {
663
        if( StringUtils.isBlank(s) ) {
664
            return -1;
665
        }
666
        char ch = s.charAt(0);
667
        if( !Character.isJavaIdentifierStart(ch) ) {
668
            return -1;
669
        }
670
        int i = 0;
671
        for (; i < s.length(); i++) {
672
            ch = s.charAt(i);
673
            if( !Character.isJavaIdentifierPart(ch) ) {
674
                return i-1;
675
            }
676
        }
677
        return i-1;
678
    }
679
}