Statistics
| Revision:

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

History | View | Annotate | Download (30.8 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.datatransfer.UnsupportedFlavorException;
33
import java.awt.event.ActionListener;
34
import java.io.File;
35
import java.io.FileInputStream;
36
import java.io.FileNotFoundException;
37
import java.io.FileOutputStream;
38
import java.io.IOException;
39
import java.lang.reflect.InvocationTargetException;
40
import java.util.ArrayList;
41
import java.util.Arrays;
42
import java.util.HashMap;
43
import java.util.Iterator;
44
import java.util.Properties;
45

    
46
import javax.swing.JOptionPane;
47
import javax.swing.KeyStroke;
48
import javax.swing.SwingUtilities;
49
import javax.swing.Timer;
50

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

    
79
/**
80
 * Provides services to Plugins. Each plugin has an associated PluginServices
81
 * object, which provides specific services. Main of them: translations,
82
 * logging, access to plugin's resources, background tasks, clipboard access
83
 * and data persistence.
84
 * 
85
 * @author Fernando Gonz�lez Cort�s
86
 */
87
public class PluginServices {
88

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

    
92
    private static String[] arguments;
93

    
94
    private static ExclusiveUIExtension exclusiveUIExtension = null;
95

    
96
    private PluginClassLoader loader;
97

    
98
    private XMLEntity persistentXML;
99

    
100
    private DynObject pluginPersistence = null;
101

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

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

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

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

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

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

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

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

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

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

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

    
246
    /**
247
     * Gets the instance of the extension whose class is provided.
248
     * 
249
     * @param extensionClass
250
     *            Class of the extension whose instance is to be returned
251
     * 
252
     * @return The instance of the extension, or null if the instance does
253
     *         not exist.Instancia de la extensi�n o null en caso de que no haya
254
     *         una
255
     */
256
    @Deprecated
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
    @Deprecated
278
    public static ExtensionDecorator getDecoratedExtension(Class extensionClass) {
279
        return (ExtensionDecorator) Launcher.getClassesExtensions()
280
        .get(extensionClass);
281
    }
282

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

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

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

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

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

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

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

    
393
        frame.addPopupMenuListener(name, c, listener, loader);
394
    }
395

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

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

    
418
        return t;
419
    }
420

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

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

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

    
452
        Component mainFrame = (Component) PluginServices.getMainFrame();
453

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

    
472
        worker.start();
473

    
474
    }
475

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

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

    
492
        private Runnable r;
493

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

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

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

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

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

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

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

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

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

    
613
        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, ss);
614
    }
615

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

    
625
        try {
626
            return (String) Toolkit.getDefaultToolkit()
627
            .getSystemClipboard()
628
            .getContents(null)
629
            .getTransferData(DataFlavor.stringFlavor);
630
        } catch (UnsupportedFlavorException e) {
631
            return null;
632
        } catch (IOException e) {
633
            // TODO Auto-generated catch block
634
            return null;
635
        }
636
    }
637

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

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

    
676
    public static void addLoaders(ArrayList classLoaders) {
677
        PluginClassLoader.addLoaders(classLoaders);
678
    }
679

    
680
    /**
681
     * @deprecated use ToolsSwingLocator.getIconThemeManager()
682
     */
683
    public static IconThemeManager getIconThemeManager() {
684
            return ToolsSwingLocator.getIconThemeManager();
685
    }
686

    
687
    /**
688
     * @deprecated use  ToolsSwingLocator.getIconThemeManager().getCurrent()
689
     */
690
    public static IconTheme getIconTheme() {
691
            return getIconThemeManager().getCurrent(); 
692
    }
693

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

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

    
723
        File andamiJar = new File(andamiPath + File.separator + "andami.jar");
724
        if (!andamiJar.exists())
725
            return false;
726
        File projectFile = new File(andamiPath + File.separator + ".project");
727
        File classpathFile =
728
            new File(andamiPath + File.separator + ".classpath");
729
        return projectFile.exists() && classpathFile.exists();
730

    
731
    }
732

    
733
    @Deprecated    
734
    public PluginsManager getManager() {
735
        return PluginsLocator.getManager();
736
    }
737

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

    
774
            File persistenceFile = getPluginPersistenceFile();
775
            if (persistenceFile.exists()) {
776
                PersistentState state;
777

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

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

    
830

    
831
    }
832

    
833
        /**
834
         * Returns the plugin persistence file.
835
         * 
836
         * @return the plugin persistence file
837
         */
838
        private File getPluginPersistenceFile() {
839
                return new File(getPluginHomeFolder(), "plugin-persistence.dat");
840
        }
841

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

    
853
    public class PluginPersistenceNeedDefinitionException extends
854
    BaseRuntimeException {
855

    
856
        /**
857
         * 
858
         */
859
        private static final long serialVersionUID = -2036279527440882712L;
860

    
861
        PluginPersistenceNeedDefinitionException(String name, Throwable cause) {
862
            super("Can't load persistence definition of plugin %(name).",
863
                "_cant_load_persistence_definition_of_plugin_XnameX",
864
                serialVersionUID);
865
            initCause(cause);
866
            setValue("name", name);
867
        }
868
    }
869

    
870
    public class PluginPersistenceAddDefinitionException extends
871
    BaseRuntimeException {
872

    
873
        /**
874
         * 
875
         */
876
        private static final long serialVersionUID = 2227722796640780361L;
877

    
878
        PluginPersistenceAddDefinitionException(String name, Throwable cause) {
879
            super("Can't add persistence definition of plugin %(name).",
880
                "_cant_add_persistence_definition_of_plugin_XnameX",
881
                serialVersionUID);
882
            this.initCause(cause);
883
            setValue("name", name);
884
        }
885
    }
886

    
887
    public class PluginLoadDataException extends
888
    BaseRuntimeException {
889

    
890
        /**
891
         * 
892
         */
893
        private static final long serialVersionUID = 1168749231143949111L;
894

    
895
        PluginLoadDataException(String name) {
896
            super("Can't load data of plugin %(name).",
897
                "_cant_load_data_of_plugin_XnameX",
898
                serialVersionUID);
899
            setValue("name", name);
900
        }
901
    }
902

    
903
    public class PluginSaveDataException extends
904
    BaseRuntimeException {
905

    
906
        /**
907
         * 
908
         */
909
        private static final long serialVersionUID = 4893241183911774542L;
910
        private final static String MESSAGE_FORMAT = "Can't save data of plugin %(name).";
911
        private final static String MESSAGE_KEY = "_cant_save_data_of_plugin_XnameX";
912

    
913
        PluginSaveDataException(String name) {
914
            super(MESSAGE_FORMAT,
915
                MESSAGE_KEY,
916
                serialVersionUID);
917
            setValue("name", name);
918
        }
919

    
920
        public PluginSaveDataException(String name, Throwable cause) {
921
            super(MESSAGE_FORMAT, cause, MESSAGE_KEY, serialVersionUID);
922
            setValue("name", name);
923

    
924
        }
925
    }
926
    
927
    @Override
928
    public String toString() {
929
        return super.toString()+" "+this.getPluginName();
930
    }
931
    
932
    public void addDependencyWithPlugin(PluginServices otherPlugin) {
933
        if( otherPlugin==null ) {
934
            return;
935
        }
936
        this.getClassLoader().addPluginClassLoader(otherPlugin.getClassLoader());
937
    }
938
}