Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.framework / org.gvsig.andami / src / main / java / org / gvsig / andami / PluginServices.java @ 45739

History | View | Annotate | Download (31.3 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.andami;
25

    
26
import java.awt.Component;
27
import java.awt.Frame;
28
import java.awt.KeyEventDispatcher;
29
import java.awt.Toolkit;
30
import java.awt.datatransfer.DataFlavor;
31
import java.awt.datatransfer.StringSelection;
32
import java.awt.event.ActionListener;
33
import java.io.File;
34
import java.io.FileInputStream;
35
import java.io.FileNotFoundException;
36
import java.io.FileOutputStream;
37
import java.io.IOException;
38
import java.lang.reflect.InvocationTargetException;
39
import java.util.ArrayList;
40
import java.util.HashMap;
41
import java.util.Iterator;
42
import java.util.Properties;
43

    
44
import javax.swing.JOptionPane;
45
import javax.swing.KeyStroke;
46
import javax.swing.SwingUtilities;
47
import javax.swing.Timer;
48
import org.apache.commons.lang3.StringUtils;
49

    
50
import org.gvsig.andami.messages.NotificationManager;
51
import org.gvsig.andami.plugins.ExclusiveUIExtension;
52
import org.gvsig.andami.plugins.ExtensionDecorator;
53
import org.gvsig.andami.plugins.IExtension;
54
import org.gvsig.andami.plugins.PluginClassLoader;
55
import org.gvsig.andami.preferences.DlgPreferences;
56
import org.gvsig.andami.ui.mdiFrame.MDIFrame;
57
import org.gvsig.andami.ui.mdiFrame.MainFrame;
58
import org.gvsig.andami.ui.mdiManager.MDIManager;
59
import org.gvsig.i18n.Messages;
60
import org.gvsig.tools.ToolsLocator;
61
import org.gvsig.tools.dynobject.DynObject;
62
import org.gvsig.tools.dynobject.DynStruct;
63
import org.gvsig.tools.exception.BaseRuntimeException;
64
import org.gvsig.tools.persistence.PersistenceManager;
65
import org.gvsig.tools.persistence.PersistentState;
66
import org.gvsig.tools.persistence.exception.AddDefinitionException;
67
import org.gvsig.tools.swing.api.ToolsSwingLocator;
68
import org.gvsig.tools.swing.icontheme.IconTheme;
69
import org.gvsig.tools.swing.icontheme.IconThemeManager;
70
import org.gvsig.utils.XMLEntity;
71
import org.gvsig.utils.swing.threads.IMonitorableTask;
72
import org.gvsig.utils.swing.threads.IProgressMonitorIF;
73
import org.gvsig.utils.swing.threads.TaskMonitorTimerListener;
74
import org.gvsig.utils.swing.threads.UndefinedProgressMonitor;
75
import org.slf4j.Logger;
76
import org.slf4j.LoggerFactory;
77

    
78
/**
79
 * Provides services to Plugins. Each plugin has an associated PluginServices
80
 * object, which provides specific services. Main of them: translations,
81
 * logging, access to plugin's resources, background tasks, clipboard access
82
 * and data persistence.
83
 * 
84
 */
85
@SuppressWarnings("UseSpecificCatch")
86
public class PluginServices {
87

    
88
    private static Logger logger =
89
        LoggerFactory.getLogger(PluginServices.class);
90

    
91
    private static String[] arguments;
92

    
93
    private static ExclusiveUIExtension exclusiveUIExtension = null;
94

    
95
    private PluginClassLoader loader;
96

    
97
    private XMLEntity persistentXML;
98

    
99
    private DynObject pluginPersistence = null;
100

    
101
    private String[] alternativeNames = null;
102
    /**
103
     * Creates a new PluginServices objetct.
104
     * 
105
     * @param loader
106
     *            The Plugin's ClassLoader.
107
     */
108
    public PluginServices(PluginClassLoader loader) {
109
        this.loader = loader;
110
    }
111

    
112
    public PluginServices(PluginClassLoader loader, String[] alternativeNames) {
113
            this(loader);
114
        this.alternativeNames = alternativeNames;
115
    }
116

    
117
    public String[] getAlternativeNames() {
118
            return this.alternativeNames;
119
    }
120
    
121
    /**
122
     * Returns the message in the current's locale language
123
     * corresponding to the provided translation key.
124
     * The key-message pairs are obtained from the plugin's
125
     * translation files (text_xx.properties files).
126
     * 
127
     * @param key
128
     *            Translation key whose associated message is to be obtained
129
     * 
130
     * @return The message associated with the provided key, in one of the
131
     *         current locale languages, or the key if the translation is not
132
     *         found.
133
     * @deprecated use I18NManager
134
     */
135
    public String getText(String key) {
136
        if (key == null)
137
            return null;
138
        String translation = org.gvsig.i18n.Messages.getText(key, false);
139
        if (translation != null)
140
            return translation;
141
        else {
142
            logger.debug("Can't find translation for ''{}'' in plugin ''{}''.",
143
                key,
144
                getPluginName());
145
            return key;
146
        }
147
    }
148

    
149
    /**
150
     * Gets the plugin's classloader.
151
     * 
152
     * @return Returns the loader.
153
     */
154
    public PluginClassLoader getClassLoader() {
155
        return loader;
156
    }
157

    
158
    /**
159
     * Gets the plugin's name
160
     * 
161
     * @return The plugin's name
162
     */
163
    public String getPluginName() {
164
        return loader.getPluginName();
165
    }
166

    
167
    /**
168
     * Gets a reference to the PluginServices object associated with the
169
     * plugin containing the provided class.
170
     * 
171
     * Obtienen una referencia al PluginServices del plugin cuyo nombre se pasa
172
     * como par�metro
173
     * 
174
     * @param pluginClassInstance
175
     *            An instance of a class. This class is contained in a plugin,
176
     *            whose
177
     *            services are to be obtained
178
     * 
179
     * @return The PluginServices object associated to the containing plugin
180
     * 
181
     * @throws RuntimeException
182
     *             If the parameter was not loaded from a plugin
183
     */
184
    @Deprecated
185
    public static PluginServices getPluginServices(Object pluginClassInstance) {
186
        try {
187
                PluginClassLoader loader;
188
                    if( pluginClassInstance instanceof Class ) {
189
                            loader = (PluginClassLoader) ((Class) pluginClassInstance).getClassLoader();
190
                    } else {
191
                            loader = (PluginClassLoader) pluginClassInstance.getClass().getClassLoader();
192
                    }
193
            return Launcher.getPluginServices(loader.getPluginName());
194
        } catch (ClassCastException e) {
195
            /*
196
             * throw new RuntimeException( "Parameter is not a plugin class
197
             * instance");
198
             */
199
            return null;
200
        }
201
    }
202

    
203
    /**
204
     * Gets a reference to the PluginServices object associated with the
205
     * provided plugin.
206
     * 
207
     * @param pluginName
208
     *            Plugin's name whose services are going to be used
209
     * 
210
     * @return The PluginServices object associated with the provided plugin.
211
     */
212
    @Deprecated
213
    public static PluginServices getPluginServices(String pluginName) {
214
        return Launcher.getPluginServices(pluginName);
215
    }
216

    
217
    /**
218
     * Gets the window manager (MDIManager).
219
     * 
220
     * @return A reference to the window manager (MDIManager).
221
     */
222
    @Deprecated
223
    public static MDIManager getMDIManager() {
224
        MDIFrame frame = Launcher.getFrame();
225
        if( frame == null ) {
226
            return null;
227
        }
228
        return frame.getMDIManager();
229
    }
230

    
231
    /**
232
     * Gets the application's main frame.
233
     * 
234
     * @return A reference to the application's main window
235
     */
236
    @Deprecated
237
    public static MainFrame getMainFrame() {
238
        return Launcher.getFrame();
239
    }
240

    
241
    public static void registerKeyStroke(KeyStroke key, KeyEventDispatcher a) {
242
        GlobalKeyEventDispatcher.getInstance().registerKeyStroke(key, a);
243
    }
244

    
245
    public static void unRegisterKeyStroke(KeyStroke key) {
246
        GlobalKeyEventDispatcher.getInstance().removeKeyStrokeBinding(key);
247
    }
248

    
249
    /**
250
     * Gets the instance of the extension whose class is provided.
251
     * 
252
     * @param extensionClass
253
     *            Class of the extension whose instance is to be returned
254
     * 
255
     * @return The instance of the extension, or null if the instance does
256
     *         not exist.Instancia de la extensi�n o null en caso de que no haya
257
     *         una
258
     */
259
    @Deprecated
260
    public static IExtension getExtension(Class extensionClass) {
261
        ExtensionDecorator extAux =
262
            (ExtensionDecorator) Launcher.getClassesExtensions()
263
            .get(extensionClass);
264
        try {
265
            return extAux.getExtension();
266
        } catch (NullPointerException ex) {
267
            return null;
268
        }
269
    }
270

    
271
    /**
272
     * Gets a reference to the Extension Decorator which adds some extra options
273
     * to the basic extension interface.
274
     * 
275
     * @param extensionClass
276
     *            The class of the extension whose decorator is to be returned
277
     * @return The ExtensionDecorator associated with the provided extension,
278
     *         or null if the extension does not exist.
279
     */
280
    @Deprecated
281
    public static ExtensionDecorator getDecoratedExtension(Class extensionClass) {
282
        return (ExtensionDecorator) Launcher.getClassesExtensions()
283
        .get(extensionClass);
284
    }
285

    
286
    /**
287
     * Returns an array containing references to all the loaded extensions.
288
     * 
289
     * @return ExtensionDecorator[] An array of ExtensionDecorators (each
290
     *         Decorator contains one extension).
291
     */
292
    @Deprecated
293
    public static ExtensionDecorator[] getDecoratedExtensions() {
294
        HashMap map = Launcher.getClassesExtensions();
295
        ExtensionDecorator[] extensions =
296
            (ExtensionDecorator[]) map.values()
297
            .toArray(new ExtensionDecorator[0]);
298
        return extensions;
299
    }
300

    
301
    /**
302
     * Gets an iterator with all the loaded Extensions.
303
     * 
304
     * @return Iterator over the decorated extensions (each member of
305
     *         the iterator is an ExtensionDecorator, which in turn contains
306
     *         one IExtension object).
307
     */
308
    @Deprecated
309
    public static Iterator getExtensions() {
310
        return Launcher.getClassesExtensions().values().iterator();
311
    }
312

    
313
    /**
314
     * Returns the message in the current's locale language
315
     * corresponding to the provided translation key.
316
     * The key-message pairs are obtained from the plugin's
317
     * translation files (text_xx.properties files).
318
     * 
319
     * @param pluginObject
320
     *            Any object which was loaded from a plugin
321
     * 
322
     * @param key
323
     *            Translation key whose associated message is to be obtained
324
     * 
325
     * @return The message associated with the provided key, in one of the
326
     *         current locale languages, or the key if the translation is not
327
     *         found.
328
     * @deprecated use I18NManager
329
     */
330
    public static String getText(Object pluginObject, String key) {
331
        if (key == null)
332
            return null;
333
        String translation = org.gvsig.i18n.Messages.getText(key, false);
334
        if (translation != null)
335
            return translation;
336
        else {
337
            logger.debug("Can't find translation for ''{}''.", key);
338
            return key;
339
        }
340
    }
341

    
342
    /**
343
     * Sets the XML data which should be saved on disk for this plugin. This
344
     * data can be retrieved on following sessions.
345
     * 
346
     * @param The
347
     *            XMLEntity object containing the data to be persisted.
348
     * 
349
     * @see PluginServices.getPersistentXML()
350
     * @see XMLEntity
351
     */
352
    public void setPersistentXML(XMLEntity entity) {
353
        persistentXML = entity;
354
    }
355

    
356
    /**
357
     * Gets the XML data which was saved on previous sessions for this
358
     * plugins.
359
     * 
360
     * @return An XMLEntity object containing the persisted data
361
     */
362
    @Deprecated
363
    public XMLEntity getPersistentXML() {
364
        if (persistentXML == null) {
365
            persistentXML = new XMLEntity();
366
        }
367
        return persistentXML;
368
    }
369

    
370
    /**
371
     * A�ade un listener a un popup menu registrado en el config.xml de alg�n
372
     * plugin
373
     * 
374
     * @param name
375
     *            Nombre del men� contextual
376
     * @param c
377
     *            Componente que desplegar� el men� cuando se haga click con el
378
     *            bot�n derecho
379
     * @param listener
380
     *            Listener que se ejecutar� cuando se seleccione cualquier
381
     *            entrada del men�
382
     * 
383
     * @throws RuntimeException
384
     *             Si la interfaz no est� preparada todav�a. S�lo puede darse
385
     *             durante el arranque
386
     */
387
    public void addPopupMenuListener(String name,
388
        Component c,
389
        ActionListener listener) {
390
        MDIFrame frame = Launcher.getFrame();
391

    
392
        if (frame == null) {
393
            throw new RuntimeException("MDIFrame not loaded yet");
394
        }
395

    
396
        frame.addPopupMenuListener(name, c, listener, loader);
397
    }
398

    
399
    /**
400
     * Gets the plugin's root directory.
401
     * 
402
     * @return A File pointing to the plugin's root directory.
403
     */
404
    public File getPluginDirectory() {
405
        return Launcher.getPluginFolder(this.getPluginName());
406
    }
407

    
408
    /**
409
     * Runs a background task. The events produced on the main frame will
410
     * be inhibited.
411
     * 
412
     * @param r
413
     *            The task to run.
414
     * 
415
     * @return The Thread on which the task is executed.
416
     */
417
    public static Thread backgroundExecution(Runnable r) {
418
        Thread t = new Thread(new RunnableDecorator(r));
419
        t.start();
420

    
421
        return t;
422
    }
423

    
424
    /**
425
     * Runs a backbround task. This task may be monitored and canceled, and
426
     * does not inhibit any event.
427
     * 
428
     * @param task
429
     *            The task to run.
430
     */
431
    public static void cancelableBackgroundExecution(final IMonitorableTask task) {
432
        final org.gvsig.utils.swing.threads.SwingWorker worker =
433
            new org.gvsig.utils.swing.threads.SwingWorker() {
434

    
435
            public Object construct() {
436
                try {
437
                    task.run();
438
                    return task;
439
                } catch (Exception e) {
440
                    NotificationManager.addError(null, e);
441
                }
442
                return null;
443
            }
444

    
445
            /**
446
             * Called on the event dispatching thread (not on the worker
447
             * thread)
448
             * after the <code>construct</code> method has returned.
449
             */
450
            public void finished() {
451
                task.finished();
452
            }
453
        };
454

    
455
        Component mainFrame = (Component) PluginServices.getMainFrame();
456

    
457
        IProgressMonitorIF progressMonitor = null;
458
        String title = getText(null, "PluginServices.Procesando");
459
        progressMonitor =
460
            new UndefinedProgressMonitor((Frame) mainFrame, title);
461
        progressMonitor.setIndeterminated(!task.isDefined());
462
        progressMonitor.setInitialStep(task.getInitialStep());
463
        progressMonitor.setLastStep(task.getFinishStep());
464
        progressMonitor.setCurrentStep(task.getCurrentStep());
465
        progressMonitor.setMainTitleLabel(task.getStatusMessage());
466
        progressMonitor.setNote(task.getNote());
467
        progressMonitor.open();
468
        int delay = 500;
469
        TaskMonitorTimerListener timerListener =
470
            new TaskMonitorTimerListener(progressMonitor, task);
471
        Timer timer = new Timer(delay, timerListener);
472
        timerListener.setTimer(timer);
473
        timer.start();
474

    
475
        worker.start();
476

    
477
    }
478

    
479
    /**
480
     * Closes the application. Cleanly exits from the application:
481
     * terminates all the extensions, then exits.
482
     * 
483
     */
484
    public static void closeApplication() {
485
        Launcher.closeApplication();
486
    }
487

    
488
    /**
489
     * DOCUMENT ME!
490
     * 
491
     * @author Fernando Gonz�lez Cort�s
492
     */
493
    private static class RunnableDecorator implements Runnable {
494

    
495
        private Runnable r;
496

    
497
        /**
498
         * Crea un nuevo RunnableDecorator.
499
         * 
500
         * @param r
501
         *            DOCUMENT ME!
502
         */
503
        public RunnableDecorator(Runnable r) {
504
            this.r = r;
505
        }
506

    
507
        /**
508
         * @see java.lang.Runnable#run()
509
         */
510
        public void run() {
511
            try {
512
                SwingUtilities.invokeAndWait(new Runnable() {
513

    
514
                    public void run() {
515
                        try {
516
                            r.run();
517
                        } catch (RuntimeException e) {
518
                            NotificationManager.addError(Messages.getText("PluginServices.Bug_en_el_codigo"),
519
                                e);
520
                        } catch (Error e) {
521
                            NotificationManager.addError(Messages.getText("PluginServices.Error_grave_de_la_aplicaci�n"),
522
                                e);
523
                        }
524
                    }
525
                });
526
            } catch (InterruptedException e) {
527
                NotificationManager.addWarning(Messages.getText("PluginServices.No_se_pudo_poner_el_reloj_de_arena"),
528
                    e);
529
            } catch (InvocationTargetException e) {
530
                NotificationManager.addWarning(Messages.getText("PluginServices.No_se_pudo_poner_el_reloj_de_arena"),
531
                    e);
532
            }
533
        }
534
    }
535

    
536
    /**
537
     * Gets an array containing the application's startup arguments. <br>
538
     * <br>
539
     * Usually: <code>appName plugins-directory [locale] [other args]</code>
540
     * 
541
     * @return the original arguments that Andami received. (app-name
542
     *         plugins-directory, locale, etc)
543
     */
544
    @Deprecated
545
    public static String[] getArguments() {
546
        return arguments;
547
    }
548

    
549
    /**
550
     * Replaces the original Andami arguments with the provided arguments.
551
     * 
552
     * @param arguments
553
     *            An array of String, each element of the array
554
     *            represents one
555
     *            argument.
556
     */
557
    @Deprecated
558
    public static void setArguments(String[] arguments) {
559
        PluginServices.arguments = arguments;
560
    }
561

    
562
    /**
563
     * Returns the value of a command line named argument. <br>
564
     * <br>
565
     * The argument format is: <br>
566
     * -{argumentName}={argumentValue} <br>
567
     * <br>
568
     * example: <br>
569
     * ' -language=en '
570
     * 
571
     * @return String The value of the argument
572
     * @deprecated use PluginManager.getArguments
573
     */
574
    public static String getArgumentByName(String name) {
575
        name = StringUtils.removeStart(name, "-");
576
        name = StringUtils.removeStart(name, "-");
577
        for (int i = 2; i < PluginServices.arguments.length; i++) {
578
            String arg = PluginServices.arguments[i];
579
            arg = StringUtils.removeStart(arg, "-");
580
            arg = StringUtils.removeStart(arg, "-");
581
            int n = arg.indexOf('=');
582
            if (n > 0) {
583
                String argname = arg.substring(0, n);
584
                if (StringUtils.equalsIgnoreCase(argname, name)) {
585
                    if (n == arg.length()) {
586
                        return "";
587
                    }
588
                    return arg.substring(n + 1);
589
                }
590
            } else {
591
                if (StringUtils.equalsIgnoreCase(arg, name)) {
592
                    return "true";
593
                }
594
            }
595
        }
596
        return null;
597
    }
598

    
599
    /**
600
     * Gets the logger. The logger is used to register important
601
     * events (errors, etc), which are stored on a file which
602
     * can be checked later.
603
     * 
604
     * @return A Logger object.
605
     * @see Logger object from the Log4j library.
606
     * 
607
     */
608
    @Deprecated
609
    public static Logger getLogger() {
610
        return logger;
611
    }
612

    
613
    @Deprecated
614
    public static DlgPreferences getDlgPreferences() {
615
        return DlgPreferences.getInstance();
616
    }
617

    
618
    /**
619
     * Stores the provided text data on the clipboard.
620
     * 
621
     * @param data
622
     *            An String containing the data to be stored
623
     *            on the clipboard.
624
     */
625
    public static void putInClipboard(String data) {
626
        StringSelection ss = new StringSelection(data);
627

    
628
        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, ss);
629
    }
630

    
631
    /**
632
     * Gets text data from the Clipboard, if available.
633
     * 
634
     * @return An String containing the clipboard's data, or <code>null</code>
635
     *         if the data was not available.
636
     */
637
    @Deprecated
638
    public static String getFromClipboard() {
639

    
640
        try {
641
            return (String) Toolkit.getDefaultToolkit()
642
            .getSystemClipboard()
643
            .getContents(null)
644
            .getTransferData(DataFlavor.stringFlavor);
645
        } catch (Exception e) {
646
            return null;
647
        }
648
    }
649

    
650
    /**
651
     * Gets the ExclusiveUIExtension, an special extension which
652
     * will take
653
     * control over the UI and will decide which extensions may be
654
     * enable/disabled or visible/hidden.
655
     * 
656
     * @return If an ExclusiveUIExtension was set, return this extension.
657
     *         Otherwise, return <code>null</code>.
658
     * 
659
     * @see org.gvsig.andami.Launcher#initializeExclusiveUIExtension()
660
     * @see org.gvsig.andami.plugins.IExtension#isEnabled(IExtension extension)
661
     * @see org.gvsig.andami.plugins.IExtension#isVisible(IExtension extension)
662
     */
663
    @Deprecated
664
    public static ExclusiveUIExtension getExclusiveUIExtension() {
665
        return PluginServices.exclusiveUIExtension;
666
    }
667

    
668
    /**
669
     * Sets the ExclusiveUIExtension, an special extension which
670
     * will take
671
     * control over the UI and will decide which extensions may be
672
     * enable/disabled or visible/hidden. <br>
673
     * <br>
674
     * The ExclusiveUIExtension is normally set by the following
675
     * Andami startup argument: <br>
676
     * <br>
677
     * <code>ExclusiveUIExtension=ExtensionName</code>
678
     * 
679
     * @see org.gvsig.andami.Launcher#initializeExclusiveUIExtension()
680
     * @see org.gvsig.andami.plugins.IExtension#isEnabled(IExtension extension)
681
     * @see org.gvsig.andami.plugins.IExtension#isVisible(IExtension extension)
682
     */
683
    @Deprecated
684
    public static void setExclusiveUIExtension(ExclusiveUIExtension extension) {
685
        PluginServices.exclusiveUIExtension = extension;
686
    }
687

    
688
    public static void addLoaders(ArrayList classLoaders) {
689
        PluginClassLoader.addLoaders(classLoaders);
690
    }
691

    
692
    /**
693
     * @deprecated use ToolsSwingLocator.getIconThemeManager()
694
     */
695
    public static IconThemeManager getIconThemeManager() {
696
            return ToolsSwingLocator.getIconThemeManager();
697
    }
698

    
699
    /**
700
     * @deprecated use  ToolsSwingLocator.getIconThemeManager().getCurrent()
701
     */
702
    public static IconTheme getIconTheme() {
703
            return getIconThemeManager().getCurrent(); 
704
    }
705

    
706
    /**
707
     * Try to detect if the application is running in a development
708
     * environment. <br>
709
     * This look for <b>.project</b> and <b>.classpath</b> files in the starts
710
     * path of the application.
711
     * 
712
     * @return true if <b>.project</b> and <b>.classpath</b> are in the
713
     *         development path
714
     */
715
    public static boolean runningInDevelopment() {
716
        String andamiPath;
717
        Properties props = System.getProperties();
718

    
719
        try {
720
            try {
721
                andamiPath =
722
                    (new File(Launcher.class.getResource(".").getFile()
723
                        + File.separator + ".." + File.separator + ".."
724
                        + File.separator + ".." + File.separator + "..")).getCanonicalPath();
725
            } catch (IOException e) {
726
                andamiPath =
727
                    (new File(Launcher.class.getResource(".").getFile()
728
                        + File.separator + ".." + File.separator + ".."
729
                        + File.separator + ".." + File.separator + "..")).getAbsolutePath();
730
            }
731
        } catch (Exception e1) {
732
            andamiPath = (String) props.get("user.dir");
733
        }
734

    
735
        File andamiJar = new File(andamiPath + File.separator + "andami.jar");
736
        if (!andamiJar.exists())
737
            return false;
738
        File projectFile = new File(andamiPath + File.separator + ".project");
739
        File classpathFile =
740
            new File(andamiPath + File.separator + ".classpath");
741
        return projectFile.exists() && classpathFile.exists();
742

    
743
    }
744

    
745
    @Deprecated    
746
    public PluginsManager getManager() {
747
        return PluginsLocator.getManager();
748
    }
749

    
750
    private String[] getAllPluginNames() {
751
            String[] names = new String[this.alternativeNames.length+1];
752
            names[0] = this.getPluginName();
753
            for( int n=0; n<this.alternativeNames.length; n++ ) {
754
                names[n+1] = this.alternativeNames[n];
755
            }
756
            return names;
757
    }
758
    
759
    public DynObject getPluginProperties() {
760
        if (this.pluginPersistence == null) {
761
            PersistenceManager manager = ToolsLocator.getPersistenceManager();
762
            DynStruct dynStruct = manager.getDynObjectDefinition(getPluginName());
763
            if ( dynStruct == null) {
764
                File persistenceDefinitionFile =
765
                    new File(this.getPluginDirectory(), "plugin-persistence.def");
766
                String[] names = getAllPluginNames(); 
767
                for( int i=0; i<names.length ; i++ ) {
768
                        try {
769
                            dynStruct = manager.addDefinition(DynObject.class,
770
                                names[i],
771
                                new FileInputStream(persistenceDefinitionFile),
772
                                this.getClassLoader(),
773
                                null,
774
                                null);
775
                            break;
776
                        } catch (FileNotFoundException e) {
777
                            throw new PluginPersistenceNeedDefinitionException(this.getPluginName(), e);
778
                        } catch (AddDefinitionException e) {
779
                                if( i+1 >= names.length ) { // Si ya no hay mas nombres peta
780
                                        throw new PluginPersistenceAddDefinitionException(this.getPluginName(), e);
781
                                }
782
                        }
783
                }
784
            }
785

    
786
            File persistenceFile = getPluginPersistenceFile();
787
            if (persistenceFile.exists()) {
788
                PersistentState state;
789

    
790
                try {
791
                    state = manager.loadState(new FileInputStream(persistenceFile));
792
                    pluginPersistence = (DynObject) manager.create(state);
793
                } catch (Throwable e) {
794
                        
795
                    logger.info("Can't retrieve persistent values from plugin "+
796
                    getPluginName(), e);
797
                    showMessageDialogDelayed(Messages.getText("_Unable_to_read_persistence_for_plugin")
798
                                    + ": " + getPluginName() + "\n" +
799
                                    Messages.getText("_Perhaps_saved_data_refers_to_missing_plugin"),
800
                                    Messages.getText("_Persistence"),
801
                                    JOptionPane.WARNING_MESSAGE);
802
                }
803
            }
804
            if (this.pluginPersistence == null) {
805
                logger.info("Creating default values for plugin persistence ("+this.getPluginName()+").");
806
                this.pluginPersistence =
807
                    ToolsLocator.getDynObjectManager()
808
                    .createDynObject(dynStruct); 
809
            }
810
        }
811
        return pluginPersistence;
812
    }
813

    
814
    private void showMessageDialogDelayed(final String msg, final String title, final int type) {
815
        PluginsManager pluginManger = PluginsLocator.getManager();
816
        pluginManger.addStartupTask("Persistence_"+getPluginName(), new Runnable() {
817
           public void run() {
818
                JOptionPane.showMessageDialog(
819
                                (Component) PluginServices.getMainFrame(),
820
                                msg,
821
                                title,
822
                                type);
823
                    }
824
        }, true, 100);
825
    }
826
    
827
    public void savePluginProperties() {
828
        if (this.pluginPersistence == null) {
829
            return;
830
        }
831
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
832
                File persistenceFile = getPluginPersistenceFile();
833
        PersistentState state;
834
        FileOutputStream fos;
835
        try {
836
            state = manager.getState(pluginPersistence);
837
            manager.saveState(state, new FileOutputStream(persistenceFile));
838
        } catch (Exception e) {
839
            throw new PluginSaveDataException(this.getPluginName(), e);
840
        }
841

    
842

    
843
    }
844

    
845
        /**
846
         * Returns the plugin persistence file.
847
         * 
848
         * @return the plugin persistence file
849
         */
850
        private File getPluginPersistenceFile() {
851
                return new File(getPluginHomeFolder(), "plugin-persistence.dat");
852
        }
853

    
854
        /**
855
         * Returns the folder where the plugin stores its resources. That folder
856
         * will be usually a subfolder into the application folder in the user home
857
         * folder.
858
         * 
859
         * @return the folder where the plugin stores its resources
860
         */
861
        public File getPluginHomeFolder() {
862
        return PluginsLocator.getManager().getPluginHomeFolder(this.getPluginName());
863
        }
864

    
865
    public class PluginPersistenceNeedDefinitionException extends
866
    BaseRuntimeException {
867

    
868
        /**
869
         * 
870
         */
871
        private static final long serialVersionUID = -2036279527440882712L;
872

    
873
        PluginPersistenceNeedDefinitionException(String name, Throwable cause) {
874
            super("Can't load persistence definition of plugin %(name).",
875
                "_cant_load_persistence_definition_of_plugin_XnameX",
876
                serialVersionUID);
877
            initCause(cause);
878
            setValue("name", name);
879
        }
880
    }
881

    
882
    public class PluginPersistenceAddDefinitionException extends
883
    BaseRuntimeException {
884

    
885
        /**
886
         * 
887
         */
888
        private static final long serialVersionUID = 2227722796640780361L;
889

    
890
        PluginPersistenceAddDefinitionException(String name, Throwable cause) {
891
            super("Can't add persistence definition of plugin %(name).",
892
                "_cant_add_persistence_definition_of_plugin_XnameX",
893
                serialVersionUID);
894
            this.initCause(cause);
895
            setValue("name", name);
896
        }
897
    }
898

    
899
    public class PluginLoadDataException extends
900
    BaseRuntimeException {
901

    
902
        /**
903
         * 
904
         */
905
        private static final long serialVersionUID = 1168749231143949111L;
906

    
907
        PluginLoadDataException(String name) {
908
            super("Can't load data of plugin %(name).",
909
                "_cant_load_data_of_plugin_XnameX",
910
                serialVersionUID);
911
            setValue("name", name);
912
        }
913
    }
914

    
915
    public class PluginSaveDataException extends
916
    BaseRuntimeException {
917

    
918
        /**
919
         * 
920
         */
921
        private static final long serialVersionUID = 4893241183911774542L;
922
        private final static String MESSAGE_FORMAT = "Can't save data of plugin %(name).";
923
        private final static String MESSAGE_KEY = "_cant_save_data_of_plugin_XnameX";
924

    
925
        PluginSaveDataException(String name) {
926
            super(MESSAGE_FORMAT,
927
                MESSAGE_KEY,
928
                serialVersionUID);
929
            setValue("name", name);
930
        }
931

    
932
        public PluginSaveDataException(String name, Throwable cause) {
933
            super(MESSAGE_FORMAT, cause, MESSAGE_KEY, serialVersionUID);
934
            setValue("name", name);
935

    
936
        }
937
    }
938
    
939
    @Override
940
    public String toString() {
941
        return super.toString()+" "+this.getPluginName();
942
    }
943
    
944
    public void addDependencyWithPlugin(PluginServices otherPlugin) {
945
        if( otherPlugin==null ) {
946
            return;
947
        }
948
        this.getClassLoader().addPluginClassLoader(otherPlugin.getClassLoader());
949
    }
950
}