Statistics
| Revision:

svn-gvsig-desktop / tags / v2_0_0_Build_2023 / frameworks / _fwAndami / src / org / gvsig / andami / PluginServices.java @ 34328

History | View | Annotate | Download (28.6 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004-2007 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package org.gvsig.andami;
42

    
43
import java.awt.Component;
44
import java.awt.Frame;
45
import java.awt.KeyEventDispatcher;
46
import java.awt.Toolkit;
47
import java.awt.datatransfer.DataFlavor;
48
import java.awt.datatransfer.StringSelection;
49
import java.awt.datatransfer.UnsupportedFlavorException;
50
import java.awt.event.ActionListener;
51
import java.io.File;
52
import java.io.FileInputStream;
53
import java.io.FileNotFoundException;
54
import java.io.FileOutputStream;
55
import java.io.IOException;
56
import java.lang.reflect.InvocationTargetException;
57
import java.util.ArrayList;
58
import java.util.HashMap;
59
import java.util.Iterator;
60
import java.util.Properties;
61

    
62
import javax.swing.KeyStroke;
63
import javax.swing.SwingUtilities;
64
import javax.swing.Timer;
65

    
66
import org.slf4j.Logger;
67
import org.slf4j.LoggerFactory;
68

    
69
import org.gvsig.andami.authentication.IAuthentication;
70
import org.gvsig.andami.iconthemes.IIconTheme;
71
import org.gvsig.andami.iconthemes.IconThemeManager;
72
import org.gvsig.andami.messages.Messages;
73
import org.gvsig.andami.messages.NotificationManager;
74
import org.gvsig.andami.plugins.ExclusiveUIExtension;
75
import org.gvsig.andami.plugins.ExtensionDecorator;
76
import org.gvsig.andami.plugins.IExtension;
77
import org.gvsig.andami.plugins.PluginClassLoader;
78
import org.gvsig.andami.preferences.DlgPreferences;
79
import org.gvsig.andami.ui.mdiFrame.MDIFrame;
80
import org.gvsig.andami.ui.mdiFrame.MainFrame;
81
import org.gvsig.andami.ui.mdiManager.MDIManager;
82
import org.gvsig.tools.ToolsLocator;
83
import org.gvsig.tools.dynobject.DynObject;
84
import org.gvsig.tools.dynobject.DynStruct;
85
import org.gvsig.tools.exception.BaseRuntimeException;
86
import org.gvsig.tools.persistence.PersistenceManager;
87
import org.gvsig.tools.persistence.PersistentState;
88
import org.gvsig.tools.persistence.exception.AddDefinitionException;
89
import org.gvsig.utils.XMLEntity;
90
import org.gvsig.utils.swing.threads.IMonitorableTask;
91
import org.gvsig.utils.swing.threads.IProgressMonitorIF;
92
import org.gvsig.utils.swing.threads.TaskMonitorTimerListener;
93
import org.gvsig.utils.swing.threads.UndefinedProgressMonitor;
94

    
95
/**
96
 * Provides services to Plugins. Each plugin has an associated PluginServices
97
 * object, which provides specific services. Main of them: translations,
98
 * logging, access to plugin's resources, background tasks, clipboard access
99
 * and data persistence.
100
 * 
101
 * @author Fernando Gonz?lez Cort?s
102
 */
103
public class PluginServices {
104

    
105
    private static Logger logger =
106
        LoggerFactory.getLogger(PluginServices.class);
107

    
108
    private static String[] arguments;
109

    
110
    private static IAuthentication authentication;
111

    
112
    private static ExclusiveUIExtension exclusiveUIExtension = null;
113

    
114
    private PluginClassLoader loader;
115

    
116
    private XMLEntity persistentXML;
117

    
118
    private DynObject pluginPersistence = null;
119

    
120
    /**
121
     * Creates a new PluginServices objetct.
122
     * 
123
     * @param loader
124
     *            The Plugin's ClassLoader.
125
     */
126
    public PluginServices(PluginClassLoader loader) {
127
        this.loader = loader;
128
    }
129

    
130
    /**
131
     * Returns the message in the current's locale language
132
     * corresponding to the provided translation key.
133
     * The key-message pairs are obtained from the plugin's
134
     * translation files (text_xx.properties files).
135
     * 
136
     * @param key
137
     *            Translation key whose associated message is to be obtained
138
     * 
139
     * @return The message associated with the provided key, in one of the
140
     *         current locale languages, or the key if the translation is not
141
     *         found.
142
     */
143
    public String getText(String key) {
144
        if (key == null)
145
            return null;
146
        String translation = org.gvsig.i18n.Messages.getText(key, false);
147
        if (translation != null)
148
            return translation;
149
        else {
150
            logger.debug("Can't find translation for ''{1}'' in plugin ''{2}''.",
151
                key,
152
                getPluginName());
153
            return key;
154
        }
155
    }
156

    
157
    /**
158
     * Gets the plugin's classloader.
159
     * 
160
     * @return Returns the loader.
161
     */
162
    public PluginClassLoader getClassLoader() {
163
        return loader;
164
    }
165

    
166
    /**
167
     * Gets the plugin's name
168
     * 
169
     * @return The plugin's name
170
     */
171
    String getPluginName() {
172
        return loader.getPluginName();
173
    }
174

    
175
    /**
176
     * Gets a reference to the PluginServices object associated with the
177
     * plugin containing the provided class.
178
     * 
179
     * Obtienen una referencia al PluginServices del plugin cuyo nombre se pasa
180
     * como par?metro
181
     * 
182
     * @param pluginClassInstance
183
     *            An instance of a class. This class is contained in a plugin,
184
     *            whose
185
     *            services are to be obtained
186
     * 
187
     * @return The PluginServices object associated to the containing plugin
188
     * 
189
     * @throws RuntimeException
190
     *             If the parameter was not loaded from a plugin
191
     */
192
    public static PluginServices getPluginServices(Object pluginClassInstance) {
193
        try {
194
            PluginClassLoader loader =
195
                (PluginClassLoader) pluginClassInstance.getClass()
196
                .getClassLoader();
197

    
198
            return Launcher.getPluginServices(loader.getPluginName());
199
        } catch (ClassCastException e) {
200
            /*
201
             * throw new RuntimeException( "Parameter is not a plugin class
202
             * instance");
203
             */
204
            return null;
205
        }
206
    }
207

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

    
221
    /**
222
     * Gets the window manager (MDIManager).
223
     * 
224
     * @return A reference to the window manager (MDIManager).
225
     */
226
    public static MDIManager getMDIManager() {
227
        return Launcher.getFrame().getMDIManager();
228
    }
229

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

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

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

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

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

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

    
296
    /**
297
     * Gets an iterator with all the loaded Extensions.
298
     * 
299
     * @return Iterator over the decorated extensions (each member of
300
     *         the iterator is an ExtensionDecorator, which in turn contains
301
     *         one IExtension object).
302
     */
303
    public static Iterator getExtensions() {
304
        return Launcher.getClassesExtensions().values().iterator();
305
    }
306

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

    
335
    /**
336
     * Sets the XML data which should be saved on disk for this plugin. This
337
     * data can be retrieved on following sessions.
338
     * 
339
     * @param The
340
     *            XMLEntity object containing the data to be persisted.
341
     * 
342
     * @see PluginServices.getPersistentXML()
343
     * @see XMLEntity
344
     */
345
    public void setPersistentXML(XMLEntity entity) {
346
        persistentXML = entity;
347
    }
348

    
349
    /**
350
     * Gets the XML data which was saved on previous sessions for this
351
     * plugins.
352
     * 
353
     * @return An XMLEntity object containing the persisted data
354
     */
355
    public XMLEntity getPersistentXML() {
356
        if (persistentXML == null) {
357
            persistentXML = new XMLEntity();
358
        }
359
        return persistentXML;
360
    }
361

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

    
384
        if (frame == null) {
385
            throw new RuntimeException("MDIFrame not loaded yet");
386
        }
387

    
388
        frame.addPopupMenuListener(name, c, listener, loader);
389
    }
390

    
391
    /**
392
     * Gets the plugin's root directory.
393
     * 
394
     * @return A File pointing to the plugin's root directory.
395
     */
396
    public File getPluginDirectory() {
397
        return new File(Launcher.getPluginsDir() + File.separator
398
            + getPluginName());
399
    }
400

    
401
    /**
402
     * Runs a background task. The events produced on the main frame will
403
     * be inhibited.
404
     * 
405
     * @param r
406
     *            The task to run.
407
     * 
408
     * @return The Thread on which the task is executed.
409
     */
410
    public static Thread backgroundExecution(Runnable r) {
411
        Thread t = new Thread(new RunnableDecorator(r));
412
        t.start();
413

    
414
        return t;
415
    }
416

    
417
    /**
418
     * Runs a backbround task. This task may be monitored and canceled, and
419
     * does not inhibit any event.
420
     * 
421
     * @param task
422
     *            The task to run.
423
     */
424
    public static void cancelableBackgroundExecution(final IMonitorableTask task) {
425
        final org.gvsig.utils.swing.threads.SwingWorker worker =
426
            new org.gvsig.utils.swing.threads.SwingWorker() {
427

    
428
            public Object construct() {
429
                try {
430
                    task.run();
431
                    return task;
432
                } catch (Exception e) {
433
                    NotificationManager.addError(null, e);
434
                }
435
                return null;
436
            }
437

    
438
            /**
439
             * Called on the event dispatching thread (not on the worker
440
             * thread)
441
             * after the <code>construct</code> method has returned.
442
             */
443
            public void finished() {
444
                task.finished();
445
            }
446
        };
447

    
448
        Component mainFrame = (Component) PluginServices.getMainFrame();
449

    
450
        IProgressMonitorIF progressMonitor = null;
451
        String title = getText(null, "PluginServices.Procesando");
452
        progressMonitor =
453
            new UndefinedProgressMonitor((Frame) mainFrame, title);
454
        progressMonitor.setIndeterminated(!task.isDefined());
455
        progressMonitor.setInitialStep(task.getInitialStep());
456
        progressMonitor.setLastStep(task.getFinishStep());
457
        progressMonitor.setCurrentStep(task.getCurrentStep());
458
        progressMonitor.setMainTitleLabel(task.getStatusMessage());
459
        progressMonitor.setNote(task.getNote());
460
        progressMonitor.open();
461
        int delay = 500;
462
        TaskMonitorTimerListener timerListener =
463
            new TaskMonitorTimerListener(progressMonitor, task);
464
        Timer timer = new Timer(delay, timerListener);
465
        timerListener.setTimer(timer);
466
        timer.start();
467

    
468
        worker.start();
469

    
470
    }
471

    
472
    /**
473
     * Closes the application. Cleanly exits from the application:
474
     * terminates all the extensions, then exits.
475
     * 
476
     */
477
    public static void closeApplication() {
478
        Launcher.closeApplication();
479
    }
480

    
481
    /**
482
     * DOCUMENT ME!
483
     * 
484
     * @author Fernando Gonz?lez Cort?s
485
     */
486
    private static class RunnableDecorator implements Runnable {
487

    
488
        private Runnable r;
489

    
490
        /**
491
         * Crea un nuevo RunnableDecorator.
492
         * 
493
         * @param r
494
         *            DOCUMENT ME!
495
         */
496
        public RunnableDecorator(Runnable r) {
497
            this.r = r;
498
        }
499

    
500
        /**
501
         * @see java.lang.Runnable#run()
502
         */
503
        public void run() {
504
            try {
505
                SwingUtilities.invokeAndWait(new Runnable() {
506

    
507
                    public void run() {
508
                        try {
509
                            r.run();
510
                        } catch (RuntimeException e) {
511
                            NotificationManager.addError(Messages.getString("PluginServices.Bug_en_el_codigo"),
512
                                e);
513
                        } catch (Error e) {
514
                            NotificationManager.addError(Messages.getString("PluginServices.Error_grave_de_la_aplicaci?n"),
515
                                e);
516
                        }
517
                    }
518
                });
519
            } catch (InterruptedException e) {
520
                NotificationManager.addWarning(Messages.getString("PluginServices.No_se_pudo_poner_el_reloj_de_arena"),
521
                    e);
522
            } catch (InvocationTargetException e) {
523
                NotificationManager.addWarning(Messages.getString("PluginServices.No_se_pudo_poner_el_reloj_de_arena"),
524
                    e);
525
            }
526
        }
527
    }
528

    
529
    /**
530
     * Gets an array containing the application's startup arguments. <br>
531
     * <br>
532
     * Usually: <code>appName plugins-directory [locale] [other args]</code>
533
     * 
534
     * @return the original arguments that Andami received. (app-name
535
     *         plugins-directory, locale, etc)
536
     */
537
    public static String[] getArguments() {
538
        return arguments;
539
    }
540

    
541
    /**
542
     * Replaces the original Andami arguments with the provided arguments.
543
     * 
544
     * @param arguments
545
     *            An array of String, each element of the array
546
     *            represents one
547
     *            argument.
548
     */
549
    public static void setArguments(String[] arguments) {
550
        PluginServices.arguments = arguments;
551
    }
552

    
553
    /**
554
     * Returns the value of a command line named argument. <br>
555
     * <br>
556
     * The argument format is: <br>
557
     * -{argumentName}={argumentValue} <br>
558
     * <br>
559
     * example: <br>
560
     * ' -language=en '
561
     * 
562
     * @return String The value of the argument
563
     */
564
    public static String getArgumentByName(String name) {
565
        for (int i = 2; i < PluginServices.arguments.length; i++) {
566
            int index = PluginServices.arguments[i].indexOf(name + "=");
567
            if (index != -1)
568
                return PluginServices.arguments[i].substring(index
569
                    + name.length() + 1);
570
        }
571
        return null;
572
    }
573

    
574
    /**
575
     * Gets the logger. The logger is used to register important
576
     * events (errors, etc), which are stored on a file which
577
     * can be checked later.
578
     * 
579
     * @return A Logger object.
580
     * @see Logger object from the Log4j library.
581
     * 
582
     */
583
    public static Logger getLogger() {
584
        return logger;
585
    }
586

    
587
    public static IAuthentication getAuthentication() {
588
        return authentication;
589
    }
590

    
591
    public static void setAuthentication(IAuthentication authen) {
592
        authentication = authen;
593
    }
594

    
595
    public static DlgPreferences getDlgPreferences() {
596
        return DlgPreferences.getInstance();
597
    }
598

    
599
    /**
600
     * Stores the provided text data on the clipboard.
601
     * 
602
     * @param data
603
     *            An String containing the data to be stored
604
     *            on the clipboard.
605
     */
606
    public static void putInClipboard(String data) {
607
        StringSelection ss = new StringSelection(data);
608

    
609
        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, ss);
610
    }
611

    
612
    /**
613
     * Gets text data from the Clipboard, if available.
614
     * 
615
     * @return An String containing the clipboard's data, or <code>null</code>
616
     *         if the data was not available.
617
     */
618
    public static String getFromClipboard() {
619

    
620
        try {
621
            return (String) Toolkit.getDefaultToolkit()
622
            .getSystemClipboard()
623
            .getContents(null)
624
            .getTransferData(DataFlavor.stringFlavor);
625
        } catch (UnsupportedFlavorException e) {
626
            return null;
627
        } catch (IOException e) {
628
            // TODO Auto-generated catch block
629
            return null;
630
        }
631
    }
632

    
633
    /**
634
     * Gets the ExclusiveUIExtension, an special extension which
635
     * will take
636
     * control over the UI and will decide which extensions may be
637
     * enable/disabled or visible/hidden.
638
     * 
639
     * @return If an ExclusiveUIExtension was set, return this extension.
640
     *         Otherwise, return <code>null</code>.
641
     * 
642
     * @see org.gvsig.andami.Launcher#initializeExclusiveUIExtension()
643
     * @see org.gvsig.andami.plugins.IExtension#isEnabled(IExtension extension)
644
     * @see org.gvsig.andami.plugins.IExtension#isVisible(IExtension extension)
645
     */
646
    public static ExclusiveUIExtension getExclusiveUIExtension() {
647
        return PluginServices.exclusiveUIExtension;
648
    }
649

    
650
    /**
651
     * Sets 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. <br>
655
     * <br>
656
     * The ExclusiveUIExtension is normally set by the following
657
     * Andami startup argument: <br>
658
     * <br>
659
     * <code>ExclusiveUIExtension=ExtensionName</code>
660
     * 
661
     * @see org.gvsig.andami.Launcher#initializeExclusiveUIExtension()
662
     * @see org.gvsig.andami.plugins.IExtension#isEnabled(IExtension extension)
663
     * @see org.gvsig.andami.plugins.IExtension#isVisible(IExtension extension)
664
     */
665
    public static void setExclusiveUIExtension(ExclusiveUIExtension extension) {
666
        PluginServices.exclusiveUIExtension = extension;
667
    }
668

    
669
    public static void addLoaders(ArrayList classLoaders) {
670
        PluginClassLoader.addLoaders(classLoaders);
671
    }
672

    
673
    public static IconThemeManager getIconThemeManager() {
674
        return IconThemeManager.getIconThemeManager();
675
    }
676

    
677
    public static IIconTheme getIconTheme() {
678
        return IconThemeManager.getIconThemeManager().getCurrent();
679
    }
680

    
681
    /**
682
     * Try to detect if the application is running in a development
683
     * environment. <br>
684
     * This look for <b>.project</b> and <b>.classpath</b> files in the starts
685
     * path of the application.
686
     * 
687
     * @return true if <b>.project</b> and <b>.classpath</b> are in the
688
     *         development path
689
     */
690
    public static boolean runningInDevelopment() {
691
        String andamiPath;
692
        Properties props = System.getProperties();
693

    
694
        try {
695
            try {
696
                andamiPath =
697
                    (new File(Launcher.class.getResource(".").getFile()
698
                        + File.separator + ".." + File.separator + ".."
699
                        + File.separator + ".." + File.separator + "..")).getCanonicalPath();
700
            } catch (IOException e) {
701
                andamiPath =
702
                    (new File(Launcher.class.getResource(".").getFile()
703
                        + File.separator + ".." + File.separator + ".."
704
                        + File.separator + ".." + File.separator + "..")).getAbsolutePath();
705
            }
706
        } catch (Exception e1) {
707
            andamiPath = (String) props.get("user.dir");
708
        }
709

    
710
        File andamiJar = new File(andamiPath + File.separator + "andami.jar");
711
        if (!andamiJar.exists())
712
            return false;
713
        File projectFile = new File(andamiPath + File.separator + ".project");
714
        File classpathFile =
715
            new File(andamiPath + File.separator + ".classpath");
716
        return projectFile.exists() && classpathFile.exists();
717

    
718
    }
719

    
720
    public PluginsManager getManager() {
721
        return PluginsLocator.getManager();
722
    }
723

    
724
    public DynObject getPluginProperties() {
725
        if (this.pluginPersistence == null) {
726
            PersistenceManager manager = ToolsLocator.getPersistenceManager();
727
            DynStruct dynStruct = manager.getDynObjectDefinition(getPluginName());
728
            if ( dynStruct == null) {
729
                File persistenceDefinitionFile =
730
                    new File(getManager().getPluginsDirectory().getAbsolutePath()
731
                        + File.separator + this.getPluginName()
732
                        + File.separator + "plugin-persistence.def");
733
                try {
734
                    manager.addDefinition(DynObject.class,
735
                        this.getPluginName(),
736
                        new FileInputStream(persistenceDefinitionFile),
737
                        this.getClassLoader(),
738
                        null,
739
                        null);
740
                } catch (AddDefinitionException e) {
741
                    throw new PluginPersistenceAddDefinitionException(this.getPluginName());
742
                } catch (FileNotFoundException e) {
743
                    throw new PluginPersistenceNeedDefinitionException(this.getPluginName());
744
                }
745
            }
746

    
747

    
748
                        File persistenceFile = getPluginPersistenceFile();
749
            if (persistenceFile.exists()) {
750
                PersistentState state;
751

    
752
                try {
753
                    state = manager.loadState(new FileInputStream(persistenceFile));
754
                    pluginPersistence = (DynObject) manager.create(state);
755
                } catch (Exception e) {
756
                    logger.error("Can't retrieve persistent values from plugin "+this.getPluginName(), e);
757
                }
758
            }
759
            if (this.pluginPersistence == null) {
760
                this.pluginPersistence =
761
                    ToolsLocator.getDynObjectManager()
762
                    .createDynObject(dynStruct); 
763
            }
764
        }
765
        return pluginPersistence;
766
    }
767

    
768
    public void savePluginProperties() {
769
        if (this.pluginPersistence == null) {
770
            return;
771
        }
772
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
773
                File persistenceFile = getPluginPersistenceFile();
774
        PersistentState state;
775
        FileOutputStream fos;
776
        try {
777
            state = manager.getState(pluginPersistence);
778
            manager.saveState(state, new FileOutputStream(persistenceFile));
779
        } catch (Exception e) {
780
            throw new PluginSaveDataException(this.getPluginName(), e);
781
        }
782

    
783

    
784
    }
785

    
786
        /**
787
         * Returns the plugin persistence file.
788
         * 
789
         * @return the plugin persistence file
790
         */
791
        private File getPluginPersistenceFile() {
792
                return new File(getPluginPersistenceFolder(), "plugin-persistence.dat");
793
        }
794

    
795
        /**
796
         * Returns the folder where the plugin stores its resources. That folder
797
         * will be usually a subfolder into the application folder in the user home
798
         * folder.
799
         * 
800
         * @return the folder where the plugin stores its resources
801
         */
802
        public File getPluginPersistenceFolder() {
803
                File persistenceFolder = new File(Launcher.getAppHomeDir()
804
                                + File.separator + "plugins" + File.separator
805
                                + this.getPluginName());
806

    
807
                if (!persistenceFolder.exists()) {
808
                        persistenceFolder.mkdirs();
809
                }
810

    
811
                return persistenceFolder;
812
        }
813

    
814
    public class PluginPersistenceNeedDefinitionException extends
815
    BaseRuntimeException {
816

    
817
        /**
818
         * 
819
         */
820
        private static final long serialVersionUID = -2036279527440882712L;
821

    
822
        PluginPersistenceNeedDefinitionException(String name) {
823
            super("Can't load persistence definition of plugin %(name).",
824
                "_cant_load_persistence_definition_of_plugin_XnameX",
825
                serialVersionUID);
826
            setValue("name", name);
827
        }
828
    }
829

    
830
    public class PluginPersistenceAddDefinitionException extends
831
    BaseRuntimeException {
832

    
833
        /**
834
         * 
835
         */
836
        private static final long serialVersionUID = 2227722796640780361L;
837

    
838
        PluginPersistenceAddDefinitionException(String name) {
839
            super("Can't add persistence definition of plugin %(name).",
840
                "_cant_add_persistence_definition_of_plugin_XnameX",
841
                serialVersionUID);
842
            setValue("name", name);
843
        }
844
    }
845

    
846
    public class PluginLoadDataException extends
847
    BaseRuntimeException {
848

    
849
        /**
850
         * 
851
         */
852
        private static final long serialVersionUID = 1168749231143949111L;
853

    
854
        PluginLoadDataException(String name) {
855
            super("Can't load data of plugin %(name).",
856
                "_cant_load_data_of_plugin_XnameX",
857
                serialVersionUID);
858
            setValue("name", name);
859
        }
860
    }
861

    
862
    public class PluginSaveDataException extends
863
    BaseRuntimeException {
864

    
865
        /**
866
         * 
867
         */
868
        private static final long serialVersionUID = 4893241183911774542L;
869
        private final static String MESSAGE_FORMAT = "Can't save data of plugin %(name).";
870
        private final static String MESSAGE_KEY = "_cant_save_data_of_plugin_XnameX";
871

    
872
        PluginSaveDataException(String name) {
873
            super(MESSAGE_FORMAT,
874
                MESSAGE_KEY,
875
                serialVersionUID);
876
            setValue("name", name);
877
        }
878

    
879
        public PluginSaveDataException(String name, Throwable cause) {
880
            super(MESSAGE_FORMAT, cause, MESSAGE_KEY, serialVersionUID);
881
            setValue("name", name);
882

    
883
        }
884
    }
885
    
886
    @Override
887
    public String toString() {
888
        return super.toString()+" "+this.getPluginName();
889
    }
890
}