Statistics
| Revision:

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

History | View | Annotate | Download (30.6 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

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

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

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

    
90
    private static String[] arguments;
91

    
92
    private static ExclusiveUIExtension exclusiveUIExtension = null;
93

    
94
    private PluginClassLoader loader;
95

    
96
    private XMLEntity persistentXML;
97

    
98
    private DynObject pluginPersistence = null;
99

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

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

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

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

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

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

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

    
216
    /**
217
     * Gets the window manager (MDIManager).
218
     * 
219
     * @return A reference to the window manager (MDIManager).
220
     */
221
    @Deprecated
222
    public static MDIManager getMDIManager() {
223
        return Launcher.getFrame().getMDIManager();
224
    }
225

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

    
236
    public static void registerKeyStroke(KeyStroke key, KeyEventDispatcher a) {
237
        GlobalKeyEventDispatcher.getInstance().registerKeyStroke(key, a);
238
    }
239

    
240
    public static void unRegisterKeyStroke(KeyStroke key) {
241
        GlobalKeyEventDispatcher.getInstance().removeKeyStrokeBinding(key);
242
    }
243

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

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

    
281
    /**
282
     * Returns an array containing references to all the loaded extensions.
283
     * 
284
     * @return ExtensionDecorator[] An array of ExtensionDecorators (each
285
     *         Decorator contains one extension).
286
     */
287
    @Deprecated
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
    @Deprecated
304
    public static Iterator getExtensions() {
305
        return Launcher.getClassesExtensions().values().iterator();
306
    }
307

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

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

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

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

    
387
        if (frame == null) {
388
            throw new RuntimeException("MDIFrame not loaded yet");
389
        }
390

    
391
        frame.addPopupMenuListener(name, c, listener, loader);
392
    }
393

    
394
    /**
395
     * Gets the plugin's root directory.
396
     * 
397
     * @return A File pointing to the plugin's root directory.
398
     */
399
    public File getPluginDirectory() {
400
        return Launcher.getPluginFolder(this.getPluginName());
401
    }
402

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

    
416
        return t;
417
    }
418

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

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

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

    
450
        Component mainFrame = (Component) PluginServices.getMainFrame();
451

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

    
470
        worker.start();
471

    
472
    }
473

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

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

    
490
        private Runnable r;
491

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

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

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

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

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

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

    
582
    /**
583
     * Gets the logger. The logger is used to register important
584
     * events (errors, etc), which are stored on a file which
585
     * can be checked later.
586
     * 
587
     * @return A Logger object.
588
     * @see Logger object from the Log4j library.
589
     * 
590
     */
591
    @Deprecated
592
    public static Logger getLogger() {
593
        return logger;
594
    }
595

    
596
    @Deprecated
597
    public static DlgPreferences getDlgPreferences() {
598
        return DlgPreferences.getInstance();
599
    }
600

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

    
611
        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, ss);
612
    }
613

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

    
623
        try {
624
            return (String) Toolkit.getDefaultToolkit()
625
            .getSystemClipboard()
626
            .getContents(null)
627
            .getTransferData(DataFlavor.stringFlavor);
628
        } catch (Exception e) {
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
    @Deprecated
647
    public static ExclusiveUIExtension getExclusiveUIExtension() {
648
        return PluginServices.exclusiveUIExtension;
649
    }
650

    
651
    /**
652
     * Sets the ExclusiveUIExtension, an special extension which
653
     * will take
654
     * control over the UI and will decide which extensions may be
655
     * enable/disabled or visible/hidden. <br>
656
     * <br>
657
     * The ExclusiveUIExtension is normally set by the following
658
     * Andami startup argument: <br>
659
     * <br>
660
     * <code>ExclusiveUIExtension=ExtensionName</code>
661
     * 
662
     * @see org.gvsig.andami.Launcher#initializeExclusiveUIExtension()
663
     * @see org.gvsig.andami.plugins.IExtension#isEnabled(IExtension extension)
664
     * @see org.gvsig.andami.plugins.IExtension#isVisible(IExtension extension)
665
     */
666
    @Deprecated
667
    public static void setExclusiveUIExtension(ExclusiveUIExtension extension) {
668
        PluginServices.exclusiveUIExtension = extension;
669
    }
670

    
671
    public static void addLoaders(ArrayList classLoaders) {
672
        PluginClassLoader.addLoaders(classLoaders);
673
    }
674

    
675
    /**
676
     * @deprecated use ToolsSwingLocator.getIconThemeManager()
677
     */
678
    public static IconThemeManager getIconThemeManager() {
679
            return ToolsSwingLocator.getIconThemeManager();
680
    }
681

    
682
    /**
683
     * @deprecated use  ToolsSwingLocator.getIconThemeManager().getCurrent()
684
     */
685
    public static IconTheme getIconTheme() {
686
            return getIconThemeManager().getCurrent(); 
687
    }
688

    
689
    /**
690
     * Try to detect if the application is running in a development
691
     * environment. <br>
692
     * This look for <b>.project</b> and <b>.classpath</b> files in the starts
693
     * path of the application.
694
     * 
695
     * @return true if <b>.project</b> and <b>.classpath</b> are in the
696
     *         development path
697
     */
698
    public static boolean runningInDevelopment() {
699
        String andamiPath;
700
        Properties props = System.getProperties();
701

    
702
        try {
703
            try {
704
                andamiPath =
705
                    (new File(Launcher.class.getResource(".").getFile()
706
                        + File.separator + ".." + File.separator + ".."
707
                        + File.separator + ".." + File.separator + "..")).getCanonicalPath();
708
            } catch (IOException e) {
709
                andamiPath =
710
                    (new File(Launcher.class.getResource(".").getFile()
711
                        + File.separator + ".." + File.separator + ".."
712
                        + File.separator + ".." + File.separator + "..")).getAbsolutePath();
713
            }
714
        } catch (Exception e1) {
715
            andamiPath = (String) props.get("user.dir");
716
        }
717

    
718
        File andamiJar = new File(andamiPath + File.separator + "andami.jar");
719
        if (!andamiJar.exists())
720
            return false;
721
        File projectFile = new File(andamiPath + File.separator + ".project");
722
        File classpathFile =
723
            new File(andamiPath + File.separator + ".classpath");
724
        return projectFile.exists() && classpathFile.exists();
725

    
726
    }
727

    
728
    @Deprecated    
729
    public PluginsManager getManager() {
730
        return PluginsLocator.getManager();
731
    }
732

    
733
    private String[] getAllPluginNames() {
734
            String[] names = new String[this.alternativeNames.length+1];
735
            names[0] = this.getPluginName();
736
            for( int n=0; n<this.alternativeNames.length; n++ ) {
737
                names[n+1] = this.alternativeNames[n];
738
            }
739
            return names;
740
    }
741
    
742
    public DynObject getPluginProperties() {
743
        if (this.pluginPersistence == null) {
744
            PersistenceManager manager = ToolsLocator.getPersistenceManager();
745
            DynStruct dynStruct = manager.getDynObjectDefinition(getPluginName());
746
            if ( dynStruct == null) {
747
                File persistenceDefinitionFile =
748
                    new File(this.getPluginDirectory(), "plugin-persistence.def");
749
                String[] names = getAllPluginNames(); 
750
                for( int i=0; i<names.length ; i++ ) {
751
                        try {
752
                            dynStruct = manager.addDefinition(DynObject.class,
753
                                names[i],
754
                                new FileInputStream(persistenceDefinitionFile),
755
                                this.getClassLoader(),
756
                                null,
757
                                null);
758
                            break;
759
                        } catch (FileNotFoundException e) {
760
                            throw new PluginPersistenceNeedDefinitionException(this.getPluginName(), e);
761
                        } catch (AddDefinitionException e) {
762
                                if( i+1 >= names.length ) { // Si ya no hay mas nombres peta
763
                                        throw new PluginPersistenceAddDefinitionException(this.getPluginName(), e);
764
                                }
765
                        }
766
                }
767
            }
768

    
769
            File persistenceFile = getPluginPersistenceFile();
770
            if (persistenceFile.exists()) {
771
                PersistentState state;
772

    
773
                try {
774
                    state = manager.loadState(new FileInputStream(persistenceFile));
775
                    pluginPersistence = (DynObject) manager.create(state);
776
                } catch (Throwable e) {
777
                        
778
                    logger.info("Can't retrieve persistent values from plugin "+
779
                    getPluginName(), e);
780
                    showMessageDialogDelayed(Messages.getText("_Unable_to_read_persistence_for_plugin")
781
                                    + ": " + getPluginName() + "\n" +
782
                                    Messages.getText("_Perhaps_saved_data_refers_to_missing_plugin"),
783
                                    Messages.getText("_Persistence"),
784
                                    JOptionPane.WARNING_MESSAGE);
785
                }
786
            }
787
            if (this.pluginPersistence == null) {
788
                logger.info("Creating default values for plugin persistence ("+this.getPluginName()+").");
789
                this.pluginPersistence =
790
                    ToolsLocator.getDynObjectManager()
791
                    .createDynObject(dynStruct); 
792
            }
793
        }
794
        return pluginPersistence;
795
    }
796

    
797
    private void showMessageDialogDelayed(final String msg, final String title, final int type) {
798
        PluginsManager pluginManger = PluginsLocator.getManager();
799
        pluginManger.addStartupTask("Persistence_"+getPluginName(), new Runnable() {
800
           public void run() {
801
                JOptionPane.showMessageDialog(
802
                                (Component) PluginServices.getMainFrame(),
803
                                msg,
804
                                title,
805
                                type);
806
                    }
807
        }, true, 100);
808
    }
809
    
810
    public void savePluginProperties() {
811
        if (this.pluginPersistence == null) {
812
            return;
813
        }
814
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
815
                File persistenceFile = getPluginPersistenceFile();
816
        PersistentState state;
817
        FileOutputStream fos;
818
        try {
819
            state = manager.getState(pluginPersistence);
820
            manager.saveState(state, new FileOutputStream(persistenceFile));
821
        } catch (Exception e) {
822
            throw new PluginSaveDataException(this.getPluginName(), e);
823
        }
824

    
825

    
826
    }
827

    
828
        /**
829
         * Returns the plugin persistence file.
830
         * 
831
         * @return the plugin persistence file
832
         */
833
        private File getPluginPersistenceFile() {
834
                return new File(getPluginHomeFolder(), "plugin-persistence.dat");
835
        }
836

    
837
        /**
838
         * Returns the folder where the plugin stores its resources. That folder
839
         * will be usually a subfolder into the application folder in the user home
840
         * folder.
841
         * 
842
         * @return the folder where the plugin stores its resources
843
         */
844
        public File getPluginHomeFolder() {
845
        return PluginsLocator.getManager().getPluginHomeFolder(this.getPluginName());
846
        }
847

    
848
    public class PluginPersistenceNeedDefinitionException extends
849
    BaseRuntimeException {
850

    
851
        /**
852
         * 
853
         */
854
        private static final long serialVersionUID = -2036279527440882712L;
855

    
856
        PluginPersistenceNeedDefinitionException(String name, Throwable cause) {
857
            super("Can't load persistence definition of plugin %(name).",
858
                "_cant_load_persistence_definition_of_plugin_XnameX",
859
                serialVersionUID);
860
            initCause(cause);
861
            setValue("name", name);
862
        }
863
    }
864

    
865
    public class PluginPersistenceAddDefinitionException extends
866
    BaseRuntimeException {
867

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

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

    
882
    public class PluginLoadDataException extends
883
    BaseRuntimeException {
884

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

    
890
        PluginLoadDataException(String name) {
891
            super("Can't load data of plugin %(name).",
892
                "_cant_load_data_of_plugin_XnameX",
893
                serialVersionUID);
894
            setValue("name", name);
895
        }
896
    }
897

    
898
    public class PluginSaveDataException extends
899
    BaseRuntimeException {
900

    
901
        /**
902
         * 
903
         */
904
        private static final long serialVersionUID = 4893241183911774542L;
905
        private final static String MESSAGE_FORMAT = "Can't save data of plugin %(name).";
906
        private final static String MESSAGE_KEY = "_cant_save_data_of_plugin_XnameX";
907

    
908
        PluginSaveDataException(String name) {
909
            super(MESSAGE_FORMAT,
910
                MESSAGE_KEY,
911
                serialVersionUID);
912
            setValue("name", name);
913
        }
914

    
915
        public PluginSaveDataException(String name, Throwable cause) {
916
            super(MESSAGE_FORMAT, cause, MESSAGE_KEY, serialVersionUID);
917
            setValue("name", name);
918

    
919
        }
920
    }
921
    
922
    @Override
923
    public String toString() {
924
        return super.toString()+" "+this.getPluginName();
925
    }
926
    
927
    public void addDependencyWithPlugin(PluginServices otherPlugin) {
928
        if( otherPlugin==null ) {
929
            return;
930
        }
931
        this.getClassLoader().addPluginClassLoader(otherPlugin.getClassLoader());
932
    }
933
}