Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / frameworks / _fwAndami / src / com / iver / andami / Launcher.java @ 28943

History | View | Annotate | Download (76.2 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 com.iver.andami;
42

    
43
import java.awt.Component;
44
import java.awt.Dimension;
45
import java.awt.EventQueue;
46
import java.awt.Frame;
47
import java.awt.KeyboardFocusManager;
48
import java.awt.Point;
49
import java.awt.Toolkit;
50
import java.io.BufferedOutputStream;
51
import java.io.BufferedReader;
52
import java.io.File;
53
import java.io.FileFilter;
54
import java.io.FileInputStream;
55
import java.io.FileNotFoundException;
56
import java.io.FileOutputStream;
57
import java.io.FileReader;
58
import java.io.IOException;
59
import java.io.InputStream;
60
import java.io.InputStreamReader;
61
import java.io.OutputStreamWriter;
62
import java.io.Reader;
63
import java.net.Authenticator;
64
import java.net.MalformedURLException;
65
import java.net.PasswordAuthentication;
66
import java.net.URL;
67
import java.net.URLConnection;
68
import java.nio.channels.FileChannel;
69
import java.security.AllPermission;
70
import java.security.CodeSource;
71
import java.security.PermissionCollection;
72
import java.security.Permissions;
73
import java.security.Policy;
74
import java.util.ArrayList;
75
import java.util.Comparator;
76
import java.util.Date;
77
import java.util.HashMap;
78
import java.util.HashSet;
79
import java.util.Iterator;
80
import java.util.Locale;
81
import java.util.Properties;
82
import java.util.TreeMap;
83
import java.util.prefs.Preferences;
84

    
85
import javax.jnlp.BasicService;
86
import javax.jnlp.ServiceManager;
87
import javax.jnlp.UnavailableServiceException;
88
import javax.swing.ImageIcon;
89
import javax.swing.JButton;
90
import javax.swing.JComponent;
91
import javax.swing.JOptionPane;
92
import javax.swing.JPopupMenu;
93
import javax.swing.SwingUtilities;
94
import javax.swing.UIManager;
95

    
96
import org.apache.log4j.PatternLayout;
97
import org.apache.log4j.PropertyConfigurator;
98
import org.apache.log4j.RollingFileAppender;
99
import org.exolab.castor.xml.MarshalException;
100
import org.exolab.castor.xml.ValidationException;
101
import org.slf4j.Logger;
102
import org.slf4j.LoggerFactory;
103

    
104
import com.iver.andami.authentication.IAuthentication;
105
import com.iver.andami.authentication.LoginUI;
106
import com.iver.andami.config.generate.Andami;
107
import com.iver.andami.config.generate.AndamiConfig;
108
import com.iver.andami.config.generate.Plugin;
109
import com.iver.andami.iconthemes.IIconTheme;
110
import com.iver.andami.iconthemes.IconThemeManager;
111
import com.iver.andami.messages.Messages;
112
import com.iver.andami.messages.NotificationManager;
113
import com.iver.andami.plugins.ExclusiveUIExtension;
114
import com.iver.andami.plugins.ExtensionDecorator;
115
import com.iver.andami.plugins.IExtension;
116
import com.iver.andami.plugins.PluginClassLoader;
117
import com.iver.andami.plugins.config.generate.ActionTool;
118
import com.iver.andami.plugins.config.generate.ComboButton;
119
import com.iver.andami.plugins.config.generate.ComboButtonElement;
120
import com.iver.andami.plugins.config.generate.ComboScale;
121
import com.iver.andami.plugins.config.generate.Depends;
122
import com.iver.andami.plugins.config.generate.Extension;
123
import com.iver.andami.plugins.config.generate.Extensions;
124
import com.iver.andami.plugins.config.generate.LabelSet;
125
import com.iver.andami.plugins.config.generate.Menu;
126
import com.iver.andami.plugins.config.generate.PluginConfig;
127
import com.iver.andami.plugins.config.generate.PopupMenu;
128
import com.iver.andami.plugins.config.generate.PopupMenus;
129
import com.iver.andami.plugins.config.generate.SelectableTool;
130
import com.iver.andami.plugins.config.generate.SkinExtension;
131
import com.iver.andami.plugins.config.generate.SkinExtensionType;
132
import com.iver.andami.plugins.config.generate.ToolBar;
133
import com.iver.andami.plugins.status.IExtensionStatus;
134
import com.iver.andami.plugins.status.IUnsavedData;
135
import com.iver.andami.ui.AndamiEventQueue;
136
import com.iver.andami.ui.MDIManagerLoadException;
137
import com.iver.andami.ui.fonts.FontUtils;
138
import com.iver.andami.ui.mdiFrame.MDIFrame;
139
import com.iver.andami.ui.mdiFrame.NewStatusBar;
140
import com.iver.andami.ui.mdiManager.MDIManager;
141
import com.iver.andami.ui.mdiManager.MDIManagerFactory;
142
import com.iver.andami.ui.splash.MultiSplashWindow;
143
import com.iver.andami.ui.theme.Theme;
144
import com.iver.andami.ui.wizard.UnsavedDataPanel;
145
import com.iver.utiles.DateTime;
146
import com.iver.utiles.XMLEntity;
147
import com.iver.utiles.xml.XMLEncodingUtils;
148
import com.iver.utiles.xmlEntity.generate.XmlTag;
149

    
150

    
151
/**
152
 * <p>
153
 * Andami's launching class. This is the class used to create the Andami's plugin environment.<br>
154
 * </p>
155
 *
156
 * <p>
157
 * <b>Syntax:</b>
158
 * <br>
159
 * java [-Xmx512M (for 512MB of RAM)] [-classpath={a colon-separated(unix) or semicolon-separated(windows) list of files containg base library of classes}]
160
 * [-Djava.library.path=PATH_TO_NATIVE_LIBRARIES]
161
 * PATH_TO_APPLICATION_HOME_DIRECTORY PATH_TO_APPLICATION_PLUGINS_DIRECTORY
162
 * [{list of additional custom application arguments separated by spaces}]
163
 * </p>
164
 *
165
 *
166
 * @author $author$
167
 * @version $Revision: 28943 $
168
 */
169
public class Launcher {
170
        private static Logger logger = LoggerFactory.getLogger(Launcher.class.getName());
171
        private static Preferences prefs = Preferences.userRoot().node( "gvsig.connection" );
172
        private static AndamiConfig andamiConfig;
173
        private static MultiSplashWindow splashWindow;
174
        private static String appName;
175
        private static Locale locale;
176
        private static HashMap pluginsConfig = new HashMap();
177
        private static HashMap pluginsServices = new HashMap();
178
        private static MDIFrame frame;
179
        private static HashMap classesExtensions = new HashMap();
180
        private static String andamiConfigPath;
181
        private static String pluginsPersistencePath;
182
        private static final String nonWinDefaultLookAndFeel =  "com.jgoodies.looks.plastic.PlasticXPLookAndFeel";
183

    
184
    private static ArrayList pluginsOrdered = new ArrayList();
185
    private static ArrayList extensions=new ArrayList();
186
    private static String appHomeDir = null;
187
    // it seems castor uses this encoding
188
    private static final String CASTORENCODING = "UTF8";
189

    
190
        private static final class ProxyAuth extends Authenticator {
191
                private PasswordAuthentication auth;
192

    
193
                private ProxyAuth(String user, String pass) {
194
                        auth = new PasswordAuthentication(user, pass.toCharArray());
195
                }
196

    
197
                protected PasswordAuthentication getPasswordAuthentication() {
198
                        return auth;
199
                }
200
        }
201

    
202
    public static void main(String[] args) throws Exception {
203
            try{
204

    
205
                    if (!validJVM()){
206
                            System.exit(-1);
207
                    }
208

    
209
                    if (args.length < 1) {
210
                            System.err.println("Uso: Launcher appName plugins-directory [language=locale]");
211
                    }
212

    
213
                    //  Clean temporal files
214
                    Utilities.cleanUpTempFiles();
215

    
216
                    appName = args[0];
217

    
218
                    //Se crea el directorio de configuraci?n de la aplicaci?n
219
                    appHomeDir = System.getProperty(args[0]+".home");
220
                    if (appHomeDir == null)
221
                            appHomeDir = System.getProperty("user.home");
222

    
223
                    appHomeDir += File.separator + args[0] + File.separator;
224
                    File parent = new File( appHomeDir );
225
                    parent.mkdirs();
226

    
227
                    andamiConfigPath = appHomeDir + "andami-config.xml";
228
                    pluginsPersistencePath = appHomeDir +
229
                    "plugins-persistence.xml";
230

    
231
                    // Configurar el log4j
232
                    Launcher.class.getClassLoader()
233
                        .getResource(".");
234
                    PropertyConfigurator.configure("log4j.properties");
235

    
236
                    PatternLayout l = new PatternLayout("%p %t %C - %m%n");
237
                    RollingFileAppender fa = new RollingFileAppender(l,
238
                                    appHomeDir + args[0] + ".log", false);
239
                    fa.setMaxFileSize("512KB");
240
                    fa.setMaxBackupIndex(3);
241
                    org.apache.log4j.Logger.getRootLogger().addAppender(fa);
242

    
243
                    // Leer el fichero de configuraci?n de andami (andami-config.xsd)
244
                    // locale
245
                    // Buscar actualizaci?nes al comenzar
246
                    //  Andami
247
                    //  Plugins
248
                    // Directorio de las extensiones
249
                    andamiConfigFromXML(andamiConfigPath);
250
                    andamiConfig.setPluginsDirectory(args[1]);
251

    
252
                    // Hacemos visibles los argumentos como una propiedad est?tica
253
                    // de plugin services para quien lo quiera usar (por ejemplo, para
254
                    // cargar un proyecto por l?nea de comandos)
255
                    PluginServices.setArguments(args);
256

    
257
                    configureLocales(args);
258

    
259
                    //Se pone el lookAndFeel
260
                    try {
261
                            String lookAndFeel = getAndamiConfig().getLookAndFeel();
262
                            if (lookAndFeel == null)
263
                                    lookAndFeel = getDefaultLookAndFeel();
264
                            UIManager.setLookAndFeel(lookAndFeel);
265
                    } catch (Exception e) {
266
                            logger.warn(Messages.getString("Launcher.look_and_feel"), e);
267
                    }
268
                    FontUtils.initFonts();
269

    
270
                    // Solucionamos el problema de permisos que se produc?a con Java Web Start con este c?digo.
271
                    // System.setSecurityManager(null);
272
                    Policy.setPolicy(new Policy() {
273
                            public PermissionCollection getPermissions(CodeSource codesource) {
274
                                    Permissions perms = new Permissions();
275
                                    perms.add(new AllPermission());
276
                                    return (perms);
277
                            }
278
                            public void
279
                            refresh() {}
280
                    });
281

    
282
                    initIconThemes();
283
//                    Registramos los iconos base
284
                    registerIcons();
285
                    validate();
286

    
287
                    // Obtener la personalizaci?n de la aplicaci?n.
288
                    Theme theme=getTheme();
289

    
290
                    // Mostrar la ventana de inicio
291
                    Frame f=new Frame();
292
                    splashWindow=new MultiSplashWindow(f,theme, 190);
293

    
294
                    // 1. Ponemos los datos del proxy
295
                    splashWindow.process(10,
296
                                    PluginServices.getText(Launcher.class, "SplashWindow.configuring_proxy"));
297
                    configureProxy();
298

    
299
                    // 2. TODO Buscar actualizaciones de los plugins
300
                    splashWindow.process(20,
301
                                    PluginServices.getText(Launcher.class, "SplashWindow.looking_for_updates"));
302
                    downloadExtensions(andamiConfig.getPluginsDirectory());
303

    
304
                    // 3. Se leen los config.xml de los plugins -----++++
305
                    splashWindow.process(30,
306
                                    PluginServices.getText(Launcher.class, "SplashWindow.reading_plugins_config.xml"));
307
                    loadPlugins(andamiConfig.getPluginsDirectory());
308

    
309
                    // 4. Se configura el classloader del plugin
310
                    splashWindow.process(40,
311
                                    PluginServices.getText(Launcher.class, "SplashWindow.setting_up_class_loaders"));
312
                    pluginsClassLoaders();
313

    
314
                    // 5. Se carga un Skin si alguno de los plugins trae informaci?n para ello
315
                    splashWindow.process(50,
316
                                    PluginServices.getText(Launcher.class, "SplashWindow.looking_for_a_skin"));
317
//                    skinPlugin(        "com.iver.core.mdiManager.NewSkin");
318
                    skinPlugin(null);
319

    
320
                    // 6. Se configura la cola de eventos
321
                    splashWindow.process(60,
322
                                    PluginServices.getText(Launcher.class, "setting_up_event_queue"));
323
                    EventQueue waitQueue = new AndamiEventQueue();
324
                    Toolkit.getDefaultToolkit().getSystemEventQueue().push(waitQueue);
325

    
326
                    // 7. Se configura la mensajer?a del plugin
327
                    splashWindow.process(70,
328
                                    PluginServices.getText(Launcher.class, "SplashWindow.starting_plugin_internationalization_system"));
329
                    pluginsMessages();
330

    
331
                    // 8. Se modifica el andami-config con los plugins nuevos
332
                    splashWindow.process(80,
333
                                    PluginServices.getText(Launcher.class, "SplashWindow.looking_for_a_skin"));
334
                    updateAndamiConfig();
335

    
336

    
337
                    frame = new MDIFrame();
338
                    // 9. Se configura el nombre e icono de la aplicaci?n
339
                    splashWindow.process(90,
340
                                    PluginServices.getText(Launcher.class, "SplashWindow.setting_up_applications_name_and_icons"));
341
                    frameIcon(theme);
342

    
343
                    // 10. Se prepara el MainFrame para albergar las extensiones
344
                    splashWindow.process(100,
345
                                    PluginServices.getText(Launcher.class, "SplashWindow.preparing_workbench"));
346
                    JPopupMenu.setDefaultLightWeightPopupEnabled(false);
347

    
348
                    SwingUtilities.invokeAndWait(new Runnable() {
349
                            public void run() {
350
                                    frame.init();
351
                            }
352
                    });
353

    
354

    
355

    
356
                    // 11. Leer el fichero de persistencia
357
                    //  info de los plugins
358
                    //  bookmarks de los plugins
359
                    splashWindow.process(110,
360
                                    PluginServices.getText(Launcher.class, "SplashWindow.loading_plugin_settings"));
361
                    loadPluginsPersistence();
362

    
363

    
364

    
365
                    // Se instalan los controles del skin
366
                    // 12. Se inicializan todas las extensiones de todos los plugins
367
                    splashWindow.process(120,
368
                                        PluginServices.getText(Launcher.class, "SplashWindow.initializing_extensions"));
369
                    SwingUtilities.invokeAndWait(new Runnable() {
370
                            public void run() {
371
                                    initializeExtensions();
372
                            }
373
                    });
374

    
375
                    // 13. Se inicializan la extensi?n exclusiva
376
                        splashWindow.process(130,
377
                                        PluginServices.getText(Launcher.class, "SplashWindow.setting_up_master_extension"));
378
                        SwingUtilities.invokeAndWait(new Runnable() {
379
                            public void run() {
380
                                    initializeExclusiveUIExtension();
381
                            }
382
                    });
383
                    frame.setClassesExtensions(classesExtensions);
384

    
385

    
386

    
387

    
388

    
389
                    // 14. Se instalan los controles de las extensiones de los plugins
390
                    splashWindow.process(140,
391
                                    PluginServices.getText(Launcher.class, "SplashWindow.installing_extensions_controls"));
392
                    SwingUtilities.invokeAndWait(new Runnable() {
393
                            public void run() {
394
                                    installPluginsControls();
395

    
396
                            }
397
                    });
398

    
399
                    // 15. Se instalan los menus de las extensiones de los plugins
400
                    splashWindow.process(150,
401
                                    PluginServices.getText(Launcher.class, "SplashWindow.installing_extensions_menus"));
402
                    SwingUtilities.invokeAndWait(new Runnable() {
403
                            public void run() {
404
                                    installPluginsMenus();
405

    
406
                            }
407
                    });
408

    
409
                    // 16. Se instalan las etiquetas de las extensiones de los plugins
410
                    splashWindow.process(160,
411
                                    PluginServices.getText(Launcher.class, "SplashWindow.installing_extensions_labels"));
412
                    SwingUtilities.invokeAndWait(new Runnable() {
413
                            public void run() {
414
                                    installPluginsLabels();
415

    
416
                            }
417
                    });
418

    
419

    
420
                    // 17. Se instalan los bookmarks de los plugins
421

    
422
                    // 18. Se muestra el frame principal
423
                    splashWindow.process(180,
424
                                    PluginServices.getText(Launcher.class, "creating_main_window"));
425
                    frame.setVisible(true);
426

    
427
                    // 19. Se ejecuta el postInitialize
428
                        splashWindow.process(190,
429
                                        PluginServices.getText(Launcher.class, "SplashWindow.post_initializing_extensions"));
430
                    SwingUtilities.invokeAndWait(new Runnable() {
431
                            public void run() {
432
                                    postInitializeExtensions();
433

    
434
                            }
435
                    });
436

    
437

    
438
                    // Definimos un KeyEventDispatcher global para que las extensiones
439
                    // puedan registrar sus "teclas r?pidas".
440
                    GlobalKeyEventDispatcher keyDispatcher = GlobalKeyEventDispatcher.getInstance();
441
                    KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(keyDispatcher);
442

    
443
                    SwingUtilities.invokeAndWait(new Runnable() {
444
                            public void run() {
445
                                    frame.enableControls();
446
                            }
447
                    });
448
                    splashWindow.close();
449
            }catch(Exception e){
450
                    logger.error("excepci?n al arrancar", e);
451
                    System.exit(-1);
452
            }
453

    
454
    }
455

    
456
    private static void registerIcons(){
457
            PluginServices.getIconTheme().registerDefault(
458
                            "login-gvsig",
459
                            LoginUI.class.getClassLoader().getResource("images/login_gvsig.png")
460
                    );
461
            PluginServices.getIconTheme().registerDefault(
462
                            "splash-gvsig",
463
                            MultiSplashWindow.class.getClassLoader().getResource("images/splash.png")
464
                    );
465
            PluginServices.getIconTheme().registerDefault(
466
                            "info-icon",
467
                            NewStatusBar.class.getClassLoader().getResource("images/info.gif")
468
                    );
469
            PluginServices.getIconTheme().registerDefault(
470
                            "error-icon",
471
                            NewStatusBar.class.getClassLoader().getResource("images/error.gif")
472
                    );
473
            PluginServices.getIconTheme().registerDefault(
474
                            "warning-icon",
475
                            NewStatusBar.class.getClassLoader().getResource("images/warning.gif")
476
                    );
477
            PluginServices.getIconTheme().registerDefault(
478
                            "no-icon",
479
                            NewStatusBar.class.getClassLoader().getResource("images/no_icon.png")
480
                    );
481
    }
482

    
483
    /**
484
     * Obtiene la personalizaci?n de los iconos, splash, fondo y el nombre de
485
     * la aplicaci?n.
486
     *
487
     * @return Theme
488
     */
489
    private static Theme getTheme() {
490
            Theme theme=new Theme();
491
            String name=PluginServices.getArgumentByName("andamiTheme");
492
                //File file=new File("theme/andami-theme.xml");
493
            File file;
494
            if (name==null){
495
                    file=new File("theme/andami-theme.xml");
496
            }else{
497
                    file=new File(name);
498
            }
499

    
500
            if (file.exists()) {
501
                        theme.readTheme(file);
502
                }
503
                return theme;
504
        }
505
        /**
506
     *Establece los datos que ten?amos guardados respecto de la configuraci?n
507
     *del proxy.
508
     */
509
        private static void configureProxy() {
510
                String host = prefs.get("firewall.http.host", "");
511
                String port = prefs.get("firewall.http.port", "");
512

    
513
                System.getProperties().put("http.proxyHost", host);
514
                System.getProperties().put("http.proxyPort", port);
515

    
516
                // Ponemos el usuario y clave del proxy, si existe
517
                String proxyUser = prefs.get("firewall.http.user",null);
518
                String proxyPassword = prefs.get("firewall.http.password", null);
519
                if (proxyUser != null )
520
                {
521
                        System.getProperties().put("http.proxyUserName", proxyUser);
522
                        System.getProperties().put("http.proxyPassword", proxyPassword);
523

    
524
                        Authenticator.setDefault(new ProxyAuth(proxyUser,
525
                                                        proxyPassword));
526
                } else {
527
                        Authenticator.setDefault(new ProxyAuth("", ""));
528
                }
529
        }
530

    
531
        /**
532
         * Recupera la geometr?a (tama?o, posic?n y estado) de la ventana principal de Andami.
533
         * TODO Pendiente de ver como se asigna un pluginServices para el launcher.
534
         * @author LWS
535
         */
536
        private static void restoreMDIStatus(XMLEntity xml) {
537
                if (xml == null) xml = new XMLEntity();
538
                //  restore frame size
539
                Dimension sz = new Dimension(700,580);
540
                if (xml.contains("MDIFrameSize")) {
541
                        int [] wh = xml.getIntArrayProperty("MDIFrameSize");
542
                        sz = new Dimension(wh[0], wh[1]);
543
                }
544
                frame.setSize(sz);
545
                //  restore frame location
546
                Point pos = new Point(10,10);
547
                if (xml.contains("MDIFramePos")) {
548
                        int [] xy = xml.getIntArrayProperty("MDIFramePos");
549
                        pos = new Point(xy[0], xy[1]);
550
                }
551
                frame.setLocation(pos);
552

    
553
                //  restore frame status (Maximized, minimized, etc);
554
                int state = java.awt.Frame.MAXIMIZED_BOTH;
555
                if (xml.contains("MDIFrameState")) {
556
                        state = xml.getIntProperty("MDIFrameState");
557
                }
558
                frame.setExtendedState(state);
559
        }
560

    
561
        private static XMLEntity saveMDIStatus() {
562
                XMLEntity xml = new XMLEntity();
563
                // save frame size
564
                int [] wh = new int[2];
565
                wh[0] = frame.getWidth();
566
                wh[1] = frame.getHeight();
567
                xml.putProperty("MDIFrameSize", wh);
568
                // save frame location
569
                int [] xy = new int[2];
570
                xy[0] = frame.getX();
571
                xy[1] = frame.getY();
572
                xml.putProperty("MDIFramePos", xy);
573
                // save frame status
574
                xml.putProperty("MDIFrameState", frame.getExtendedState());
575
                return xml;
576
        }
577

    
578
    private static boolean validJVM() {
579
        char thirdCharacter = System.getProperty("java.version").charAt(2);
580
        if (thirdCharacter < '4'){
581
            return false;
582
            }else{
583
                return true;
584
            }
585
    }
586

    
587
        private static void loadPluginsPersistence() throws ConfigurationException {
588
                XMLEntity entity = persistenceFromXML();
589

    
590
                for (int i = 0; i < entity.getChildrenCount(); i++) {
591
                        XMLEntity plugin = entity.getChild(i);
592
                        String pName = plugin.getStringProperty(
593
                                        "com.iver.andami.pluginName");
594
                        if (pluginsServices.get(pName)!= null){
595
                                ((PluginServices) pluginsServices.get(pName)).setPersistentXML(plugin);
596
                        } else {
597
                                if (pName.startsWith("Andami.Launcher"))
598
                                        restoreMDIStatus(plugin);
599
                        }
600
                }
601
        }
602

    
603
        /**
604
         * Salva la persistencia de los plugins.
605
         * @author LWS
606
         */
607
        private static void savePluginPersistence() {
608
                Iterator i = pluginsConfig.keySet().iterator();
609

    
610
                XMLEntity entity = new XMLEntity();
611

    
612
                while (i.hasNext()) {
613
                        String pName = (String) i.next();
614
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
615
                        XMLEntity ent = ps.getPersistentXML();
616

    
617
                        if (ent != null) {
618
                                ent.putProperty("com.iver.andami.pluginName", pName);
619
                                entity.addChild(ent);
620
                        }
621
                }
622
                XMLEntity ent = saveMDIStatus();
623
                if (ent != null) {
624
                        ent.putProperty("com.iver.andami.pluginName", "Andami.Launcher");
625
                        entity.addChild(ent);
626
                }
627
                try {
628
                        persistenceToXML(entity);
629
                } catch (ConfigurationException e1) {
630
                        logger.error(Messages.getString(
631
                                        "Launcher.Se_produjo_un_error_guardando_la_configuracion_de_los_plugins"),
632
                                e1);
633
                }
634
        }
635

    
636
        private static void installPluginsLabels() {
637
                Iterator i = pluginsConfig.keySet().iterator();
638

    
639
                while (i.hasNext()) {
640
                        String name = (String) i.next();
641
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(name);
642
                        PluginServices ps = (PluginServices) pluginsServices.get(name);
643

    
644
                        LabelSet[] ls = pc.getLabelSet();
645

    
646
                        for (int j = 0; j < ls.length; j++) {
647
                                PluginClassLoader loader = ps.getClassLoader();
648

    
649
                                try {
650
                                        Class clase = loader.loadClass(ls[j].getClassName());
651
                                        frame.setStatusBarLabels(clase, ls[j].getLabel());
652
                                } catch (ClassNotFoundException e) {
653
                                        logger.error(Messages.getString("Launcher.labelset_class"),
654
                                                e);
655
                                }
656
                        }
657
                }
658
        }
659

    
660
        private static String configureSkin(XMLEntity xml,String defaultSkin) {
661
                if (defaultSkin == null){
662
                        for (int i = 0; i < xml.getChildrenCount(); i++) {
663
                                if (xml.getChild(i).contains("Skin-Selected")) {
664
                                        String className = xml.getChild(i).getStringProperty(
665
                                        "Skin-Selected");
666
                                        return className;
667
                                }
668
                        }
669
                }
670
//                return "com.iver.core.mdiManager.NewSkin";
671
                return  defaultSkin;
672
        }
673

    
674
        private static void fixSkin(SkinExtension skinExtension,PluginClassLoader pluginClassLoader) throws MDIManagerLoadException{
675
                // now insert the skin selected.
676
                MDIManagerFactory.setSkinExtension(skinExtension, pluginClassLoader);
677
                // MDIManagerFactory.setSkinExtension(se,
678
                // ps.getClassLoader());
679

    
680
                Class skinClass;
681

    
682
                try {
683
                        skinClass = pluginClassLoader.loadClass(
684
                                        skinExtension.getClassName());
685

    
686
                        com.iver.andami.plugins.IExtension skinInstance = (com.iver.andami.plugins.IExtension) skinClass
687
                        .newInstance();
688
                        // classesExtensions.put(skinClass, skinInstance);
689
                        // jaume
690
                        ExtensionDecorator newExtensionDecorator = new ExtensionDecorator(
691
                                        skinInstance, ExtensionDecorator.INACTIVE);
692
                        classesExtensions.put(skinClass, newExtensionDecorator);
693
                } catch (ClassNotFoundException e) {
694
                        logger
695
                        .error(
696
                                        Messages
697
                                        .getString("Launcher.No_se_encontro_la_clase_mdi_manager"),
698
                                        e);
699
                        throw new MDIManagerLoadException(e);
700
                } catch (InstantiationException e) {
701
                        logger
702
                        .error(
703
                                        Messages
704
                                        .getString("Launcher.No_se_pudo_instanciar_la_clase_mdi_manager"),
705
                                        e);
706
                        throw new MDIManagerLoadException(e);
707
                } catch (IllegalAccessException e) {
708
                        logger
709
                        .error(
710
                                        Messages
711
                                        .getString("Launcher.No_se_pudo_acceder_a_la_clase_mdi_manager"),
712
                                        e);
713
                        throw new MDIManagerLoadException(e);
714
                }
715

    
716
        }
717
        /**
718
         * DOCUMENT ME!
719
         *
720
         * @throws MDIManagerLoadException
721
         */
722
        private static void skinPlugin(String defaultSkin) throws MDIManagerLoadException {
723
                XMLEntity entity =null;
724
                try {
725
                        entity = persistenceFromXML();
726
                } catch (ConfigurationException e1) {
727
                        // TODO Auto-generated catch block
728
                        e1.printStackTrace();
729
                }
730
                Iterator i = pluginsConfig.keySet().iterator();
731

    
732
                SkinExtension skinExtension = null;
733
                PluginClassLoader pluginClassLoader = null;
734
                ArrayList skinExtensions = new ArrayList();
735
                while (i.hasNext()) {
736
                        String name = (String) i.next();
737
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(name);
738
                        PluginServices ps = (PluginServices) pluginsServices.get(name);
739

    
740
                        if (pc.getExtensions().getSkinExtension() != null) {
741
//                                if (MDIManagerFactory.getSkinExtension() != null) {
742
//                                        logger.warn(Messages.getString(
743
//                                                        "Launcher.Dos_skin_extension"));
744
//                                }
745

    
746
                                SkinExtension[] se = pc.getExtensions().getSkinExtension();
747
                                for (int numExten=0; numExten<se.length; numExten++) {
748
                                        skinExtensions.add(se[numExten]);
749
                                }
750
                                for (int j=0;j<se.length;j++){
751
                                        String configuredSkin = Launcher.configureSkin(entity,defaultSkin);
752
                                        if (configuredSkin!=null && configuredSkin.equals(se[j].getClassName())) {
753
                                                skinExtension = se[j];
754
                                                pluginClassLoader = ps.getClassLoader();
755
                                        }
756
                                }
757
                        }
758
                }
759

    
760
                if ((skinExtension != null) && (pluginClassLoader != null)) {
761
                        // configured skin was found
762
                        fixSkin(skinExtension, pluginClassLoader);
763
                } else {
764
                        if (skinExtensions.contains("com.iver.core.mdiManager.NewSkin")) {
765
                                // try first NewSkin (from CorePlugin)
766
                                skinPlugin("com.iver.core.mdiManager.NewSkin");
767
                        }
768
                        else if (skinExtensions.size()>0){
769
                                // try to load the first skin found
770
                                SkinExtension se =  (SkinExtension)skinExtensions.get(0);
771
                                skinPlugin((String)se.getClassName());
772
                        }
773
                        else {
774
                                throw new MDIManagerLoadException("No Skin-Extension installed");
775
                        }
776
                }
777

    
778
        }
779

    
780
        private static void frameIcon(Theme theme) {
781
                Iterator i = pluginsConfig.keySet().iterator();
782

    
783
                while (i.hasNext()) {
784
                        String pName = (String) i.next();
785
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
786
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
787
                        if (pc.getIcon() != null) {
788
                                if (theme.getIcon() != null) {
789
                                        frame.setIconImage(theme.getIcon().getImage());
790
                                } else {
791

    
792
                                        ImageIcon icon = PluginServices.getIconTheme().get(pc.getIcon().getSrc());
793
                                        frame.setIconImage(icon.getImage());
794

    
795
                                }
796
                                if (theme.getName() != null) {
797
                                        frame.setTitlePrefix(theme.getName());
798
                                } else {
799
                                        frame.setTitlePrefix(pc.getIcon().getText());
800
                                }
801
                                if (theme.getBackgroundImage() != null) {
802

    
803
                                        PluginServices.getMDIManager().setBackgroundImage(theme.getBackgroundImage(),theme.getTypeDesktop());
804
                                }
805
                        }
806
                }
807
        }
808

    
809
        private static void initializeExtensions() {
810
                Iterator i = pluginsOrdered.iterator();
811

    
812
                while (i.hasNext()) {
813
                        String pName = (String) i.next();
814
            logger.debug("Initializing extensions from " + pName);
815
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
816
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
817

    
818
                        Extension[] exts = pc.getExtensions().getExtension();
819

    
820
                        TreeMap orderedExtensions = new TreeMap(new ExtensionComparator());
821

    
822
                        for (int j = 0; j < exts.length; j++) {
823
                                if (!exts[j].getActive()) {
824
                                        continue;
825
                                }
826

    
827
                                if (orderedExtensions.containsKey(exts[j])) {
828
                                        logger.warn(Messages.getString(
829
                                                        "Launcher.Two_extensions_with_the_same_priority") +
830
                                                exts[j].getClassName());
831
                                }
832

    
833
                                orderedExtensions.put(exts[j], null);
834
                        }
835

    
836
                        Iterator e = orderedExtensions.keySet().iterator();
837

    
838
                        while (e.hasNext()) {
839
                                Extension extension = (Extension) e.next();
840
                                com.iver.andami.plugins.IExtension extensionInstance;
841

    
842
                                try {
843
                                        Class extensionClass = ps.getClassLoader().loadClass(extension.getClassName());
844
                                        extensionInstance = (com.iver.andami.plugins.IExtension) extensionClass.newInstance();
845

    
846
                                        // CON DECORATOR
847
                                        // ANTES: classesExtensions.put(extensionClass, extensionInstance);
848
                                        // AHORA: CREAMOS UNA ExtensionDecorator y asignamos esta instancia para
849
                                        // poder ampliar con nuevas propiedades (AlwaysVisible, por ejemplo)
850
                                        // Para crear la nueva clase ExtensionDecorator, le pasamos como par?metro
851
                                        // la extensi?n original que acabamos de crear
852
                                        // 0-> Inactivo, controla la extension
853
                                        // 1-> Siempre visible
854
                                        // 2-> Invisible
855
                                        ExtensionDecorator newExtensionDecorator = new ExtensionDecorator(extensionInstance, ExtensionDecorator.INACTIVE);
856
                                        classesExtensions.put(extensionClass, newExtensionDecorator);
857
                                        logger.info("Initializing " + extension.getClassName()+"...");
858
                    // logger.debug("Initializing " + extension.getClassName());
859
                    extensionInstance.initialize();
860
                    extensions.add(extensionInstance);
861
                    // logger.debug(extension.getClassName() + " initialized.");
862

    
863
                                } catch (InstantiationException e1) {
864
                                        logger.error(Messages.getString(
865
                                                        "Launcher.Error_instanciando_la_extension") +
866
                                                extension.getClassName(), e1);
867
                                } catch (IllegalAccessException e1) {
868
                                        logger.error(Messages.getString(
869
                                                        "Launcher.Error_instanciando_la_extension") +
870
                                                extension.getClassName(), e1);
871
                                } catch (ClassNotFoundException e1) {
872
                                        logger.error(Messages.getString(
873
                                                        "Launcher.No_se_encontro_la_clase_de_la_extension") +
874
                                                extension.getClassName(), e1);
875
                                } catch (NoClassDefFoundError e1) {
876
                                        logger.error(Messages.getString(
877
                                                        "Launcher.Error_localizando_la_clase_de_la_extension") +
878
                                                extension.getClassName(), e1);
879
                                }
880
                        }
881
                }
882
        }
883

    
884
        private static void postInitializeExtensions() {
885
                for (int i=0;i<extensions.size();i++) {
886
                        com.iver.andami.plugins.IExtension extensionInstance=(com.iver.andami.plugins.IExtension)extensions.get(i);
887
                        extensionInstance.postInitialize();
888
                }
889
        }
890

    
891
        private static void installPluginsMenus() {
892
                TreeMap orderedMenus = new TreeMap(new MenuComparator());
893

    
894
                Iterator i = pluginsConfig.keySet().iterator();
895

    
896
                while (i.hasNext()) {
897
                        String pName = (String) i.next();
898
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
899
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
900

    
901
                        Extension[] exts = pc.getExtensions().getExtension();
902

    
903
                        for (int j = 0; j < exts.length; j++) {
904
                                if (!exts[j].getActive()) {
905
                                        continue;
906
                                }
907

    
908
                                Menu[] menus = exts[j].getMenu();
909

    
910
                                for (int k = 0; k < menus.length; k++) {
911
                                        SortableMenu sm = new SortableMenu(ps.getClassLoader(),
912
                                                        exts[j], menus[k]);
913

    
914
                                        if (orderedMenus.containsKey(sm)) {
915
                                                logger.error(Messages.getString(
916
                                                                "Launcher.Two_menus_with_the_same_position") + " - " +
917
                                                        menus[k].getText()+ " - " + exts[j].getClassName());
918
                                        }
919

    
920
                                        orderedMenus.put(sm, null);
921
                                }
922
                        }
923

    
924
                        // Se instalan las extensiones de MDI
925
                        SkinExtension[] skinExts = pc.getExtensions().getSkinExtension();
926
                        for (int j = 0; j < skinExts.length; j++) {
927

    
928

    
929
                        if (skinExts[j] != null) {
930
                                Menu[] menu = skinExts[j].getMenu();
931

    
932
                                for (int k = 0; k < menu.length; k++) {
933
                                        SortableMenu sm = new SortableMenu(ps.getClassLoader(),
934
                                                        skinExts[j], menu[k]);
935

    
936
                                        if (orderedMenus.containsKey(sm)) {
937
                                                logger.error(Messages.getString(
938
                                                                "Launcher.Two_menus_with_the_same_position") +
939
                                                        skinExts[j].getClassName());
940
                                        }
941

    
942
                                        orderedMenus.put(sm, null);
943
                                }
944
                        }
945
                        }
946
                }
947

    
948
                //Se itera por los menus ordenados
949
                Iterator e = orderedMenus.keySet().iterator();
950

    
951
                // Se ordenan los menues
952
                while (e.hasNext()) {
953
                        try {
954
                                SortableMenu sm = (SortableMenu) e.next();
955

    
956
                                frame.addMenu(sm.loader, sm.extension, sm.menu);
957
                        } catch (ClassNotFoundException ex) {
958
                                logger.error(Messages.getString(
959
                                                "Launcher.No_se_encontro_la_clase_de_la_extension"), ex);
960
                        }
961
                }
962
        }
963

    
964
        /**
965
         * Installs the menus, toolbars, actiontools, selectable toolbars and combos.
966
         * The order in which they are shown is determined here.
967
         */
968
        private static void installPluginsControls() {
969
                Iterator i = pluginsConfig.keySet().iterator();
970

    
971
                HashMap extensionPluginServices = new HashMap();
972
                HashMap extensionPluginConfig = new HashMap();
973
                TreeMap orderedExtensions = new TreeMap(new ExtensionComparator());
974

    
975
                // First of all, sort the extensions.
976
                // We need to iterate on the plugins, and iterate on each plugin's extensions
977
                // (each plugin may contain one or more extensions)
978
                while (i.hasNext()) { // iterate on the plugins
979
                        String pName = (String) i.next();
980
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
981
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
982

    
983
                        Extension[] exts = pc.getExtensions().getExtension();
984

    
985
                        for (int j = 0; j < exts.length; j++) { // iterate on the extensions
986
                                if (exts[j].getActive()) {
987
                                        if (orderedExtensions.containsKey(exts[j])) {
988
                                                logger.error(Messages.getString(
989
                                                "Launcher.Two_extensions_with_the_same_priority") +
990
                                                exts[j].getClassName());
991
                                        }
992

    
993
                                        orderedExtensions.put(exts[j], null);
994
                                        extensionPluginServices.put(exts[j], ps);
995
                                        extensionPluginConfig.put(exts[j], pc);
996
                                }
997
                        }
998
                }
999

    
1000
                TreeMap orderedTools = new TreeMap(new ToolComparator());
1001
                Iterator e = orderedExtensions.keySet().iterator();
1002

    
1003
                // sort the toolbars and tools from 'normal' extensions (actiontools, selectabletools)
1004
                // and load the  combo-scales and combo-buttons for the status bar
1005
                while (e.hasNext()) {
1006
                        Extension ext = (Extension) e.next();
1007

    
1008
                        ToolBar[] toolbars = ext.getToolBar();
1009

    
1010
                        // get tools from toolbars
1011
                        for (int k = 0; k < toolbars.length; k++) {
1012
                                ActionTool[] tools = toolbars[k].getActionTool();
1013

    
1014
                                for (int t = 0; t < tools.length; t++) {
1015
                                        SortableTool sm = new SortableTool(((PluginServices)extensionPluginServices.get(ext)).getClassLoader(), ext,
1016
                                                        toolbars[k], tools[t]);
1017
                                        orderedTools.put(sm, null);
1018
                                }
1019

    
1020
                                SelectableTool[] sTools = toolbars[k].getSelectableTool();
1021

    
1022
                                for (int t = 0; t < sTools.length; t++) {
1023
                                        SortableTool sm=new SortableTool(((PluginServices)extensionPluginServices.get(ext)).getClassLoader(), ext,
1024
                                                        toolbars[k], sTools[t]);
1025
                                        orderedTools.put(sm, null);
1026
                                }
1027
                        }
1028

    
1029
                        // get controls for statusBar
1030
                        PluginServices ps = (PluginServices) extensionPluginServices.get(ext);
1031
                        PluginClassLoader loader = ps.getClassLoader();
1032

    
1033
                        //ArrayList componentList = new ArrayList();
1034
                        ComboScale[] comboScaleArray = ext.getComboScale();
1035
                        for (int k=0; k < comboScaleArray.length; k++) {
1036
                                org.gvsig.gui.beans.controls.comboscale.ComboScale combo = new org.gvsig.gui.beans.controls.comboscale.ComboScale();
1037
                                String label = comboScaleArray[k].getLabel();
1038
                                if (label!=null)
1039
                                        combo.setLabel(label);
1040
                                String name = comboScaleArray[k].getName();
1041
                                if (name!=null)
1042
                                        combo.setName(name);
1043
                                String[] elementsString = ((String)comboScaleArray[k].getElements()).split(";");
1044
                                long[] elements = new long[elementsString.length];
1045
                                for (int currentElem=0; currentElem<elementsString.length; currentElem++) {
1046
                                        try {
1047
                                                elements[currentElem] = Long.parseLong(elementsString[currentElem]);
1048
                                        }
1049
                                        catch (NumberFormatException nfex1) {
1050
                                                logger.error(ext.getClassName()+" -- "+Messages.getString( "error_parsing_comboscale_elements"));
1051
                                                elements[currentElem] = 0;
1052
                                        }
1053
                                }
1054
                                combo.setItems(elements);
1055
                                try {
1056
                                        long value = Long.parseLong((String)comboScaleArray[k].getValue());
1057
                                        combo.setScale(value);
1058
                                }
1059
                                catch (NumberFormatException nfex2) {
1060
                                        logger.error(ext.getClassName()+" -- "+Messages.getString( "error_parsing_comboscale_value"));
1061
                                }
1062
                                try {
1063
                                        frame.addStatusBarControl(loader.loadClass(ext.getClassName()),combo);
1064
                                } catch (ClassNotFoundException e1) {
1065
                                        logger.error(Messages.getString("Launcher.error_getting_class_loader_for_status_bar_control"), e1);
1066
                                }
1067
                        }
1068

    
1069
                        ComboButton[] comboButtonArray = ext.getComboButton();
1070
                        for (int k=0; k < comboButtonArray.length; k++) {
1071
                                ComboButtonElement[] elementList = comboButtonArray[k].getComboButtonElement();
1072
                                org.gvsig.gui.beans.controls.combobutton.ComboButton combo = new org.gvsig.gui.beans.controls.combobutton.ComboButton();
1073
                                String name = comboButtonArray[k].getName();
1074
                                if (name!=null)
1075
                                        combo.setName(name);
1076
                                for (int currentElement=0; currentElement<elementList.length; currentElement++) {
1077
                                        ComboButtonElement element = elementList[currentElement];
1078
                                        ImageIcon icon;
1079
                                        URL iconLocation = loader.getResource(element.getIcon());
1080
                                        if (iconLocation==null)
1081
                                                logger.error(Messages.getString("Icon_not_found_")+element.getIcon());
1082
                                        else {
1083
                                                icon = new ImageIcon(iconLocation);
1084
                                                JButton button = new JButton(icon);
1085
                                                combo.addButton(button);
1086
                                                button.setActionCommand(element.getActionCommand());
1087
                                        }
1088
                                }
1089
                                try {
1090
                                        frame.addStatusBarControl(loader.loadClass(ext.getClassName()), combo);
1091
                                } catch (ClassNotFoundException e1) {
1092
                                        logger.error(Messages.getString("Launcher.error_getting_class_loader_for_status_bar_control"), e1);
1093
                                }
1094
                        }
1095
                }
1096

    
1097
                // Add the tools from MDI extensions to the ordered tool-list, so that we get a sorted list containing all the tools
1098
                i = pluginsConfig.keySet().iterator();
1099
                while (i.hasNext()) {
1100
                        String pName = (String) i.next();
1101
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
1102
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
1103

    
1104
                        SkinExtension[] skinExts = pc.getExtensions().getSkinExtension();
1105
                        for (int j = 0; j < skinExts.length; j++) {
1106

    
1107

    
1108
                        if (skinExts[j] != null) {
1109
                                ToolBar[] toolbars = skinExts[j].getToolBar();
1110

    
1111
                                for (int k = 0; k < toolbars.length; k++) {
1112
                                        ActionTool[] tools = toolbars[k].getActionTool();
1113

    
1114
                                        for (int t = 0; t < tools.length; t++) {
1115
                                                SortableTool stb=new SortableTool(ps.getClassLoader(), skinExts[j],
1116
                                                                toolbars[k], tools[t]);
1117
                                                orderedTools.put(stb,null);
1118
                                        }
1119

    
1120
                                        SelectableTool[] sTools = toolbars[k].getSelectableTool();
1121

    
1122
                                        for (int t = 0; t < sTools.length; t++) {
1123
                                                SortableTool stb=new SortableTool(ps.getClassLoader(), skinExts[j],
1124
                                                                toolbars[k], sTools[t]);
1125
                                                orderedTools.put(stb,null);
1126
                                        }
1127
                                }
1128
                        }
1129
                        }
1130
                        // Install popup menus
1131
                        PopupMenus pus = pc.getPopupMenus();
1132

    
1133
                        if (pus != null) {
1134
                                PopupMenu[] menus = pus.getPopupMenu();
1135

    
1136
                                for (int j = 0; j < menus.length; j++) {
1137
                                        frame.addPopupMenu(ps.getClassLoader(), menus[j]);
1138
                                }
1139
                        }
1140
                }
1141

    
1142
                // loop on the ordered extension list, to add them to the interface in an ordered way
1143
                Iterator t = orderedTools.keySet().iterator();
1144
                while (t.hasNext()) {
1145
                        try {
1146
                                SortableTool stb = (SortableTool) t.next();
1147
                                if (stb.actiontool!=null)
1148
                                        frame.addTool(stb.loader, stb.extension,stb.toolbar, stb.actiontool);
1149
                                else
1150
                                        frame.addTool(stb.loader, stb.extension,stb.toolbar, stb.selectabletool);
1151
                        } catch (ClassNotFoundException ex) {
1152
                                logger.error(Messages.getString(
1153
                                "Launcher.No_se_encontro_la_clase_de_la_extension"), ex);
1154
                        }
1155
                }
1156
        }
1157

    
1158
        /**
1159
         * Adds new plugins to the the andami-config file.
1160
         */
1161
        private static void updateAndamiConfig() {
1162
                HashSet olds = new HashSet();
1163

    
1164
                Plugin[] plugins = andamiConfig.getPlugin();
1165

    
1166
                for (int i = 0; i < plugins.length; i++) {
1167
                        olds.add(plugins[i].getName());
1168
                }
1169

    
1170
                Iterator i = pluginsServices.values().iterator();
1171

    
1172
                while (i.hasNext()) {
1173
                        PluginServices ps = (PluginServices) i.next();
1174

    
1175
                        if (!olds.contains(ps.getPluginName())) {
1176
                                Plugin p = new Plugin();
1177
                                p.setName(ps.getPluginName());
1178
                                p.setUpdate(false);
1179

    
1180
                                andamiConfig.addPlugin(p);
1181
                        }
1182
                }
1183
        }
1184

    
1185
        private static void pluginsClassLoaders() {
1186
                HashSet instalados = new HashSet();
1187

    
1188
                // Se itera hasta que est?n todos instalados
1189
                while (instalados.size() != pluginsConfig.size()) {
1190
                        boolean circle = true;
1191

    
1192
                        //Hacemos una pasada por todos los plugins
1193
                        Iterator i = pluginsConfig.keySet().iterator();
1194

    
1195
                        while (i.hasNext()) {
1196
                                String pluginName = (String) i.next();
1197
                                PluginConfig config = (PluginConfig) pluginsConfig.get(pluginName);
1198

    
1199
                                if (instalados.contains(pluginName)) {
1200
                                        continue;
1201
                                }
1202

    
1203
                                //Se obtienen las dependencias y sus class loaders
1204
                                boolean ready = true;
1205
                                Depends[] dependencies = config.getDepends();
1206
                                PluginClassLoader[] loaders = new PluginClassLoader[dependencies.length];
1207

    
1208
                                for (int j = 0; j < dependencies.length; j++) {
1209
                                        if (pluginsConfig.get(dependencies[j].getPluginName()) == null) {
1210
                                                logger.error(Messages.getString(
1211
                                                                "Launcher.Dependencia_no_resuelta_en_plugin") +
1212
                                                        pluginName + ": " +
1213
                                                        dependencies[j].getPluginName());
1214

    
1215
                                                continue;
1216
                                        }
1217

    
1218
                                        if (!instalados.contains(dependencies[j].getPluginName())) {
1219
                                                ready = false;
1220
                                        } else {
1221
                                                loaders[j] = ((PluginServices) pluginsServices.get(dependencies[j].getPluginName())).getClassLoader();
1222
                                        }
1223
                                }
1224

    
1225
                                //Si no est?n sus dependencias satisfechas se aborta la instalaci?n
1226
                                if (!ready) {
1227
                                        continue;
1228
                                }
1229

    
1230
                                //Se genera el class loader
1231
                                String jardir = config.getLibraries().getLibraryDir();
1232
                                File jarDir = new File(andamiConfig.getPluginsDirectory() +
1233
                                                File.separator + pluginName + File.separator + jardir);
1234
                                File[] jarFiles = jarDir.listFiles(new FileFilter() {
1235
                                                        public boolean accept(File pathname) {
1236
                                                                return (pathname.getName().toUpperCase()
1237
                                                                                                .endsWith(".JAR")) ||
1238
                                                                (pathname.getName().toUpperCase().endsWith(".ZIP"));
1239
                                                        }
1240
                                                });
1241

    
1242
                                URL[] urls = new URL[jarFiles.length];
1243

    
1244
                                for (int j = 0; j < jarFiles.length; j++) {
1245
                                        try {
1246
                                                urls[j] = new URL("file:" + jarFiles[j]);
1247
                                        } catch (MalformedURLException e) {
1248
                                                logger.error(Messages.getString(
1249
                                                                "Launcher.No_se_puede_acceder_a") +
1250
                                                        jarFiles[j]);
1251
                                        }
1252
                                }
1253

    
1254
                                PluginClassLoader loader;
1255

    
1256
                                try {
1257
                                        loader = new PluginClassLoader(urls,
1258
                                                        andamiConfig.getPluginsDirectory() +
1259
                                                        File.separator + pluginName,
1260
                                                        Launcher.class.getClassLoader(), loaders);
1261

    
1262
                                        PluginServices ps = new PluginServices(loader);
1263

    
1264
                                        pluginsServices.put(ps.getPluginName(), ps);
1265

    
1266
                                        instalados.add(pluginName);
1267
                    // FJP: Los metemos ordenados para luego no cargar uno que necesita de otro antes de tiempo. Esto lo usaremos al
1268
                    // inicializar los plugins
1269
                    pluginsOrdered.add(pluginName);
1270

    
1271
                                        circle = false;
1272
                                } catch (IOException e) {
1273
                                        logger.error(Messages.getString(
1274
                                                        "Launcher.Error_con_las_librerias_del_plugin"), e);
1275
                                        pluginsConfig.remove(pluginName);
1276
                                        i = pluginsConfig.keySet().iterator();
1277
                                }
1278
                        }
1279

    
1280
                        if (circle) {
1281
                                logger.error(Messages.getString(
1282
                                                "Launcher.Hay_dependencias_circulares"));
1283

    
1284
                                break;
1285
                        }
1286
                }
1287

    
1288
                //Se eliminan los plugins que no fueron instalados
1289
                Iterator i = pluginsConfig.keySet().iterator();
1290

    
1291
                while (i.hasNext()) {
1292
                        String pluginName = (String) i.next();
1293
                        PluginConfig config = (PluginConfig) pluginsConfig.get(pluginName);
1294
                        PluginServices ps = (PluginServices) pluginsServices.get(pluginName);
1295

    
1296
                        if (ps == null) {
1297
                                pluginsConfig.remove(pluginName);
1298
                                i = pluginsConfig.keySet().iterator();
1299
                        }
1300
                }
1301
        }
1302

    
1303
        private static void pluginsMessages() {
1304
                Iterator iterator = pluginsOrdered.iterator();
1305
                PluginConfig config;
1306
                PluginServices ps;
1307

    
1308
                while (iterator.hasNext()) {
1309
                        String pluginName = (String) iterator.next();
1310
                        config = (PluginConfig) pluginsConfig.get(pluginName);
1311
                        ps = (PluginServices) pluginsServices.get(pluginName);
1312

    
1313
                        if (config.getResourceBundle() != null && !config.getResourceBundle().getName().equals("")) {
1314
                                // add the locale files associated with the plugin
1315
                                org.gvsig.i18n.Messages.addResourceFamily(config.getResourceBundle().getName(), ps.getClassLoader(), pluginName);
1316
                        }
1317
                }
1318
        }
1319

    
1320
        static PluginServices getPluginServices(String name) {
1321
                return (PluginServices) pluginsServices.get(name);
1322
        }
1323

    
1324
        static String getPluginsDir() {
1325
                return andamiConfig.getPluginsDirectory();
1326
        }
1327

    
1328
        static void setPluginsDir(String s) {
1329
                andamiConfig.setPluginsDirectory(s);
1330
        }
1331

    
1332
        static MDIFrame getMDIFrame() {
1333
                return frame;
1334
        }
1335

    
1336
        private static void loadPlugins(String pluginsDirectory) {
1337
                File pDir = new File(pluginsDirectory);
1338

    
1339
                if (!pDir.exists()) {
1340
                        logger.error("\n\tPlugins directory not found: "+pDir.getAbsolutePath()+"\n\tDid you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
1341
                        System.exit(-1);
1342
                        return;
1343
                }
1344

    
1345
                File[] pluginDirs = pDir.listFiles();
1346
                if (pluginDirs.length==0) {
1347
                        logger.error("\n\tPlugins directory is empty: "+pDir.getAbsolutePath()+"Did you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
1348
                        System.exit(-1);
1349
                        return;
1350
                }
1351

    
1352
                for (int i = 0; i < pluginDirs.length; i++) {
1353
                        if (pluginDirs[i].isDirectory()) {
1354
                                File configXml = new File(pluginDirs[i].getAbsolutePath() +
1355
                                                File.separator + "config.xml");
1356

    
1357
                                try {
1358
                                        FileInputStream is = new FileInputStream(configXml);
1359
                                        Reader xml = com.iver.utiles.xml.XMLEncodingUtils.getReader(is);
1360
                                        if (xml==null) {
1361
                                                // the encoding was not correctly detected, use system default
1362
                                                xml = new FileReader(configXml);
1363
                                        }
1364
                                        else {
1365
                                                // use a buffered reader to improve performance
1366
                                                xml = new BufferedReader(xml);
1367
                                        }
1368
                                        PluginConfig pConfig = (PluginConfig) PluginConfig.unmarshal(xml);
1369
                                        pluginsConfig.put(pluginDirs[i].getName(), pConfig);
1370
                                } catch (FileNotFoundException e) {
1371
                                        logger.info(Messages.getString(
1372
                                                        "Launcher.Ignorando_el_directorio") +
1373
                                                pluginDirs[i].getAbsolutePath() +
1374
                                                Messages.getString("Launcher.config_no_encontrado"));
1375
                                } catch (MarshalException e) {
1376
                                        logger.info(Messages.getString(
1377
                                                        "Launcher.Ignorando_el_directorio") +
1378
                                                pluginDirs[i].getAbsolutePath() +
1379
                                                Messages.getString("Launcher.config_mal_formado"), e);
1380
                                } catch (ValidationException e) {
1381
                                        logger.info(Messages.getString(
1382
                                                        "Launcher.Ignorando_el_directorio") +
1383
                                                pluginDirs[i].getAbsolutePath() +
1384
                                                Messages.getString("Launcher.config_mal_formado"), e);
1385
                                }
1386
                        }
1387
                }
1388

    
1389
                if (pluginsConfig.size()==0) {
1390
                        logger.error("\n\tNo valid plugin was found. The plugins directory currently is: "+pDir.getAbsolutePath()+"\n\tDid you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
1391
                        System.exit(-1);
1392
                        return;
1393
                }
1394
        }
1395

    
1396
        private static Locale getLocale(String language, String country,
1397
                String variant) {
1398
                if (variant != null) {
1399
                        return new Locale(language, country, variant);
1400
                } else if (country != null) {
1401
                        return new Locale(language, country);
1402
                } else if (language != null) {
1403
                        return new Locale(language);
1404
                } else {
1405
                        return new Locale("es");
1406
                }
1407
        }
1408

    
1409
        private static void andamiConfigToXML(String file)
1410
                throws IOException, MarshalException, ValidationException {
1411
                // write on a temporary file in order to not destroy current file if there is some problem while marshaling
1412
                File tmpFile = new File(file+"-"+DateTime.getCurrentDate().getTime());
1413
                File xml = new File(file);
1414
                File parent = xml.getParentFile();
1415
                parent.mkdirs();
1416

    
1417
                BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(tmpFile));
1418
                OutputStreamWriter writer = new OutputStreamWriter(os, CASTORENCODING);
1419
                andamiConfig.marshal(writer);
1420
                writer.close();
1421

    
1422
                // if marshaling process finished correctly, move the file to the correct one
1423
                xml.delete();
1424
                if (!tmpFile.renameTo(xml)) {
1425
                        // if rename was not succesful, try copying it
1426
                        FileChannel sourceChannel = new  FileInputStream(tmpFile).getChannel();
1427
                        FileChannel destinationChannel = new FileOutputStream(xml).getChannel();
1428
                        sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel);
1429
                        sourceChannel.close();
1430
                        destinationChannel.close();
1431
                }
1432
        }
1433

    
1434
        private static void andamiConfigFromXML(String file)
1435
                throws ConfigurationException {
1436
                File xml = new File(file);
1437

    
1438
                InputStreamReader reader = null;
1439
                try {
1440
                        //Se lee la configuraci?n
1441
                        reader = XMLEncodingUtils.getReader(xml);
1442
                        andamiConfig = (AndamiConfig) AndamiConfig.unmarshal(reader);
1443
                } catch (FileNotFoundException e) {
1444
                        //Si no existe se ponen los valores por defecto
1445
                        andamiConfig = getDefaultAndamiConfig();
1446
                } catch (MarshalException e) {
1447
                        // try to close the stream, maybe it remains open
1448
                        if (reader!=null) {
1449
                                try { reader.close(); } catch (IOException e1) {}
1450
                        }
1451
                        // if there was a problem reading the file, backup it and create a new one with default values
1452
                        String backupFile = file+"-"+DateTime.getCurrentDate().getTime();
1453
                        NotificationManager.addError(Messages.getString("Error_reading_andami_config_New_file_created_A_backup_was_made_on_")+backupFile, new ConfigurationException(e));
1454
                        xml.renameTo(new File(backupFile));
1455
                        andamiConfig = getDefaultAndamiConfig();
1456
                } catch (ValidationException e) {
1457
                        throw new ConfigurationException(e);
1458
                }
1459
        }
1460

    
1461
        private static AndamiConfig getDefaultAndamiConfig() {
1462
                AndamiConfig andamiConfig = new AndamiConfig();
1463

    
1464
                Andami andami = new Andami();
1465
                andami.setUpdate(true);
1466
                andamiConfig.setAndami(andami);
1467
                andamiConfig.setLocaleCountry(Locale.getDefault().getCountry());
1468
                andamiConfig.setLocaleLanguage(Locale.getDefault().getLanguage());
1469
                andamiConfig.setLocaleVariant(Locale.getDefault().getVariant());
1470

    
1471
                if (System.getProperty("javawebstart.version") != null) // Es java web start)
1472
                 {
1473
                        andamiConfig.setPluginsDirectory(new File(appHomeDir
1474
                                        + "extensiones").getAbsolutePath());
1475
                } else {
1476
                        andamiConfig.setPluginsDirectory(new File(appName +
1477
                                        File.separator + "extensiones").getAbsolutePath());
1478
                }
1479

    
1480
                andamiConfig.setPlugin(new Plugin[0]);
1481
                return andamiConfig;
1482
        }
1483

    
1484
        private static XMLEntity persistenceFromXML() throws ConfigurationException {
1485
                File xml = new File(pluginsPersistencePath);
1486

    
1487
                if (xml.exists()) {
1488
                        InputStreamReader reader = null;
1489

    
1490
                        try {
1491
                                reader = XMLEncodingUtils.getReader(xml);
1492
                                XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
1493
                                return new XMLEntity(tag);
1494
                        } catch (FileNotFoundException e) {
1495
                                throw new ConfigurationException(e);
1496
                        } catch (MarshalException e) {
1497

    
1498
                                // try to reopen with default encoding (for backward compatibility)
1499
                                try {
1500
                                        reader = new FileReader(xml);
1501
                                        XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
1502
                                        return new XMLEntity(tag);
1503

    
1504
                                } catch (MarshalException ex) {
1505
                                        // try to close the stream, maybe it remains open
1506
                                        if (reader!=null) {
1507
                                                try { reader.close(); } catch (IOException e1) {}
1508
                                        }
1509
                                        // backup the old file
1510
                                        String backupFile = pluginsPersistencePath+"-"+DateTime.getCurrentDate().getTime();
1511
                                        NotificationManager.addError(Messages.getString("Error_reading_plugin_persinstence_New_file_created_A_backup_was_made_on_")+backupFile, new ConfigurationException(e));
1512
                                        xml.renameTo(new File(backupFile));
1513
                                        // create a new, empty configuration
1514
                                        return new XMLEntity();
1515
                                }
1516
                                catch (FileNotFoundException ex) {
1517
                                        return new XMLEntity();
1518
                                } catch (ValidationException ex) {
1519
                                        throw new ConfigurationException(e);
1520
                                }
1521
                        } catch (ValidationException e) {
1522
                                throw new ConfigurationException(e);
1523
                        }
1524
                } else {
1525
                        return new XMLEntity();
1526
                }
1527
        }
1528

    
1529
        private static void persistenceToXML(XMLEntity entity)
1530
                throws ConfigurationException {
1531
                // write on a temporary file in order to not destroy current file if there is some problem while marshaling
1532
                File tmpFile = new File(pluginsPersistencePath+"-"+DateTime.getCurrentDate().getTime());
1533

    
1534
                File xml = new File(pluginsPersistencePath);
1535
                OutputStreamWriter writer = null;
1536

    
1537
                try {
1538
                        writer = new OutputStreamWriter(new FileOutputStream(tmpFile), CASTORENCODING);
1539
                        entity.getXmlTag().marshal(writer);
1540
                        writer.close();
1541

    
1542
                        // if marshaling process finished correctly, move the file to the correct one
1543
                        xml.delete();
1544
                        if (!tmpFile.renameTo(xml)) {
1545
                                // if rename was not succesful, try copying it
1546
                                FileChannel sourceChannel = new  FileInputStream(tmpFile).getChannel();
1547
                                FileChannel destinationChannel = new FileOutputStream(xml).getChannel();
1548
                                sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel);
1549
                                sourceChannel.close();
1550
                                destinationChannel.close();
1551

    
1552
                        }
1553
                } catch (FileNotFoundException e) {
1554
                        throw new ConfigurationException(e);
1555
                } catch (MarshalException e) {
1556
                        // try to close the stream, maybe it remains open
1557
                        if (writer!=null) {
1558
                                try { writer.close(); } catch (IOException e1) {}
1559
                        }
1560
                } catch (ValidationException e) {
1561
                        throw new ConfigurationException(e);
1562
                } catch (IOException e) {
1563
                        throw new ConfigurationException(e);
1564
                }
1565
        }
1566

    
1567
        static MDIFrame getFrame() {
1568
                return frame;
1569
        }
1570

    
1571
        /**
1572
         * Gracefully closes the application. It shows dialogs to save data,
1573
         * finish processes, etc, then it terminates the extensions, removes
1574
         * temporal files and finally exits.
1575
         */
1576
        public synchronized static void closeApplication() {
1577
                TerminationProcess terminationProcess = (new Launcher()).new TerminationProcess();
1578
                terminationProcess.run();
1579
        }
1580

    
1581
        static HashMap getClassesExtensions() {
1582
                return classesExtensions;
1583
        }
1584

    
1585
        private static void downloadExtensions(String extDir) {
1586
                java.util.Date fechaActual = null;
1587

    
1588
                try {
1589
                        if (System.getProperty("javawebstart.version") != null) {
1590
                                //Obtenemos la URL del servidor
1591
                                BasicService bs = (BasicService) ServiceManager.lookup(
1592
                                                "javax.jnlp.BasicService");
1593
                                URL baseURL = bs.getCodeBase();
1594

    
1595
                                //Se descargan las extensiones
1596
                                splashWindow.process(5,
1597
                                        "Descargando las extensiones desde " + baseURL + " a " +
1598
                                        extDir);
1599

    
1600
                                URL url = new URL(baseURL + "extensiones.zip");
1601
                                URLConnection connection = url.openConnection();
1602

    
1603
                                System.out.println(url.toExternalForm() + ":");
1604
                                System.out.println("  Content Type: " +
1605
                                        connection.getContentType());
1606
                                System.out.println("  Content Length: " +
1607
                                        connection.getContentLength());
1608
                                System.out.println("  Last Modified: " +
1609
                                        new Date(connection.getLastModified()));
1610
                                System.out.println("  Expiration: " +
1611
                                        connection.getExpiration());
1612
                                System.out.println("  Content Encoding: " +
1613
                                        connection.getContentEncoding());
1614

    
1615
                                // Guardamos la fecha del fichero de extensiones que nos hemos bajado, y
1616
                                // comprobamos el ?ltimo que se ha bajado. Si no son
1617
                                // iguales, nos bajamos el nuevo. Si son iguales, no
1618
                                // nos bajamos nada.
1619
                                Long miliSecondsInWeb = new Long(connection.getLastModified());
1620

    
1621
                                File destDir = new File(extDir);
1622

    
1623
                                if (!destDir.exists()) {
1624
                                        // Creamos gvSIG
1625
                                        destDir.getParentFile().mkdir();
1626

    
1627
                                        if (!destDir.mkdir()) {
1628
                                                System.err.println("Imposible crear el directorio " +
1629
                                                        destDir.getAbsolutePath());
1630
                                        }
1631
                                }
1632

    
1633
                                File timeFile = new File(destDir.getParent() + File.separator +
1634
                                                "timeStamp.properties");
1635

    
1636
                                if (!timeFile.exists()) {
1637
                                        timeFile.createNewFile();
1638
                                }
1639

    
1640
                                FileInputStream inAux = new FileInputStream(timeFile);
1641
                                Properties prop = new Properties();
1642
                                prop.load(inAux);
1643
                                inAux.close();
1644

    
1645
                                if (prop.getProperty("timestamp") != null) {
1646
                                        Long lastMiliSeconds = (Long) new Long(prop.getProperty(
1647
                                                                "timestamp"));
1648

    
1649
                                        if (lastMiliSeconds.longValue() == miliSecondsInWeb.longValue()) {
1650
                                                System.out.println("No hay nueva actualizaci?n");
1651
                        logger.debug("No hay nueva actualizaci?n -> Return");
1652
                        logger.debug("timeStampWeb= " + miliSecondsInWeb);
1653
                        logger.debug("timeStampLocal= " + lastMiliSeconds);
1654

    
1655
                                                return;
1656
                                        }
1657

    
1658
                                        System.out.println("timeStampWeb= " + miliSecondsInWeb);
1659
                                        System.out.println("timeStampLocal= " + lastMiliSeconds);
1660
                                } else {
1661
                                        System.out.println("El timeStamp no est? escrito en " +
1662
                                                timeFile.getAbsolutePath());
1663
                                }
1664

    
1665
                                InputStream stream = url.openStream();
1666
                File temp = File.createTempFile("gvsig", ".zip");
1667

    
1668
                logger.debug(temp.getAbsolutePath());
1669

    
1670
                temp.deleteOnExit();
1671
                FileOutputStream file = new FileOutputStream(temp);
1672

    
1673
                byte[] lt_read = new byte[1];
1674

    
1675
                while (stream.read(lt_read) > 0)
1676
                  file.write(lt_read);
1677

    
1678
                                stream.close();
1679
                stream = null;
1680
                file.close();
1681
                file = null;
1682

    
1683
                System.gc();
1684

    
1685
                logger.debug("Ha creado el fichero ZIP");
1686
                                //Se extrae el zip
1687
                splashWindow.process(5, "Extensiones descargadas.");
1688

    
1689
                                System.out.println("Extrayendo a " + destDir.getAbsolutePath());
1690

    
1691
                                Date fechaDir = new Date(destDir.lastModified());
1692
                                System.out.println("Fecha del directorio " + extDir + " = " +
1693
                                        fechaDir.toString());
1694
                                Utilities.extractTo(temp, new File(extDir), splashWindow);
1695

    
1696
                                // Si todo ha ido bien, guardamos el timestamp.
1697
                                ///  App.instance.getPc().addProperties("timestamp", miliSecondsInWeb);
1698
                                // XMLEntity xml=ps.getPersistentXML();
1699
                                fechaActual = new java.util.Date();
1700

    
1701
                                FileOutputStream outAux = new FileOutputStream(timeFile);
1702
                                prop.setProperty("timestamp", miliSecondsInWeb.toString());
1703
                                prop.store(outAux, "last download");
1704
                                outAux.close();
1705
                                System.out.println("Fecha actual guardada: " +
1706
                                        fechaActual.toGMTString());
1707

    
1708
                                /* xml.putProperty("timestamp",fechaActual.toGMTString());
1709
                                   ps.setPresistentXML(xml); */
1710
                        }
1711
                } catch (IOException e) {
1712
                        NotificationManager.addError("", e);
1713
                } catch (UnavailableServiceException e) {
1714
                        NotificationManager.addError("", e);
1715
                } catch (SecurityException e) {
1716
                        System.err.println("No se puede escribir el timeStamp " +
1717
                                fechaActual.toGMTString());
1718
                        NotificationManager.addError("", e);
1719
                }
1720
        }
1721

    
1722
        private static Extensions[] getExtensions() {
1723
                ArrayList array = new ArrayList();
1724
                Iterator iter = pluginsConfig.values().iterator();
1725

    
1726
                while (iter.hasNext()) {
1727
                        array.add(((PluginConfig) iter.next()).getExtensions());
1728
                }
1729

    
1730
                return (Extensions[]) array.toArray(new Extensions[0]);
1731
        }
1732

    
1733
        public static HashMap getPluginConfig() {
1734
                return pluginsConfig;
1735
        }
1736

    
1737
        public static Extension getExtension(String s) {
1738
                Extensions[] exts = getExtensions();
1739

    
1740
                for (int i = 0; i < exts.length; i++) {
1741
                        for (int j = 0; j < exts[i].getExtensionCount(); j++) {
1742
                                if (exts[i].getExtension(j).getClassName().equals(s)) {
1743
                                        return exts[i].getExtension(j);
1744
                                }
1745
                        }
1746
                }
1747

    
1748
                return null;
1749
        }
1750

    
1751
        public static AndamiConfig getAndamiConfig() {
1752
                return andamiConfig;
1753
        }
1754

    
1755
        private static class ExtensionComparator implements Comparator {
1756
                public int compare(Object o1, Object o2) {
1757
                        Extension e1 = (Extension) o1;
1758
                        Extension e2 = (Extension) o2;
1759

    
1760
                        if (!e1.hasPriority() && !e2.hasPriority()) {
1761
                                return -1;
1762
                        }
1763

    
1764
                        if (e1.hasPriority() && !e2.hasPriority()) {
1765
                                return Integer.MIN_VALUE;
1766
                        }
1767

    
1768
                        if (e2.hasPriority() && !e1.hasPriority()) {
1769
                                return Integer.MAX_VALUE;
1770
                        }
1771

    
1772
                        if (e1.getPriority() != e2.getPriority()){
1773
                                return e2.getPriority() - e1.getPriority();
1774
                        }else{
1775
                                return (e2.toString().compareTo(e1.toString()));
1776
                        }
1777
                }
1778
        }
1779

    
1780
        private static class MenuComparator implements Comparator {
1781
                private static ExtensionComparator extComp = new ExtensionComparator();
1782

    
1783
                public int compare(Object o1, Object o2) {
1784
                        SortableMenu e1 = (SortableMenu) o1;
1785
                        SortableMenu e2 = (SortableMenu) o2;
1786

    
1787
                        if (!e1.menu.hasPosition() && !e2.menu.hasPosition()) {
1788
                                if (e1.extension instanceof SkinExtensionType) {
1789
                                        return 1;
1790
                                } else if (e2.extension instanceof SkinExtensionType) {
1791
                                        return -1;
1792
                                } else {
1793
                                        return extComp.compare(e1.extension, e2.extension);
1794
                                }
1795
                        }
1796

    
1797
                        if (e1.menu.hasPosition() && !e2.menu.hasPosition()) {
1798
                                return Integer.MIN_VALUE;
1799
                        }
1800

    
1801
                        if (e2.menu.hasPosition() && !e1.menu.hasPosition()) {
1802
                                return Integer.MAX_VALUE;
1803
                        }
1804
                        if (e1.menu.getPosition() != e2.menu.getPosition()){
1805
                                //we don't return 0 unless both objects are the same, otherwise the objects get overwritten in the treemap
1806
                                return e1.menu.getPosition() - e2.menu.getPosition();
1807
                        }else{
1808
                                return (e1.toString().compareTo(e2.toString()));
1809
                        }
1810
                }
1811
        }
1812

    
1813
        private static class SortableMenu {
1814
                public PluginClassLoader loader;
1815
                public Menu menu;
1816
                public SkinExtensionType extension;
1817

    
1818
                public SortableMenu(PluginClassLoader loader,
1819
                        SkinExtensionType skinExt, Menu menu2) {
1820
                        extension = skinExt;
1821
                        menu = menu2;
1822
                        this.loader = loader;
1823
                }
1824
        }
1825

    
1826
        private static class SortableTool {
1827
                public PluginClassLoader loader;
1828
                public ToolBar toolbar;
1829
                public ActionTool actiontool;
1830
                public SelectableTool selectabletool;
1831
                public SkinExtensionType extension;
1832

    
1833
                public SortableTool(PluginClassLoader loader,
1834
                        SkinExtensionType skinExt, ToolBar toolbar2,ActionTool actiontool2) {
1835
                        extension = skinExt;
1836
                        toolbar = toolbar2;
1837
                        actiontool=actiontool2;
1838
                        this.loader = loader;
1839
                }
1840
                public SortableTool(PluginClassLoader loader,
1841
                                SkinExtensionType skinExt, ToolBar toolbar2,SelectableTool selectabletool2) {
1842
                        extension = skinExt;
1843
                        toolbar = toolbar2;
1844
                        selectabletool=selectabletool2;
1845
                        this.loader = loader;
1846
                }
1847
        }
1848

    
1849
        private static class ToolBarComparator implements Comparator {
1850
                private static ExtensionComparator extComp = new ExtensionComparator();
1851

    
1852
                public int compare(Object o1, Object o2) {
1853
                        SortableTool e1 = (SortableTool) o1;
1854
                        SortableTool e2 = (SortableTool) o2;
1855

    
1856
                        // if the toolbars have the same name, they are considered to be
1857
                        // the same toolbar, so we don't need to do further comparing
1858
                        if (e1.toolbar.getName().equals(e2.toolbar.getName()))
1859
                                return 0;
1860

    
1861
                        if (!e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
1862
                                if (e1.extension instanceof SkinExtensionType) {
1863
                                        return 1;
1864
                                } else if (e2.extension instanceof SkinExtensionType) {
1865
                                        return -1;
1866
                                } else {
1867
                                        return extComp.compare(e1.extension, e2.extension);
1868
                                }
1869
                        }
1870

    
1871
                        if (e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
1872
                                return Integer.MIN_VALUE;
1873
                        }
1874

    
1875
                        if (e2.toolbar.hasPosition() && !e1.toolbar.hasPosition()) {
1876
                                return Integer.MAX_VALUE;
1877
                        }
1878
                        if (e1.toolbar.getPosition() != e2.toolbar.getPosition())
1879
                                return e1.toolbar.getPosition() - e2.toolbar.getPosition();
1880

    
1881
                        if (e1.toolbar.getActionTool().equals(e2.toolbar.getActionTool()) && e1.toolbar.getSelectableTool().equals(e2.toolbar.getSelectableTool())){
1882
                                return 0;
1883
                        }
1884
                        return (e1.toolbar.toString().compareTo(e2.toolbar.toString()));
1885
                }
1886
        }
1887

    
1888
        /**
1889
         * <p>This class is used to compare tools (selectabletool and actiontool),
1890
         * using the "position"
1891
         * attribute.</p>
1892
         * <p>The ordering criteria are:</p>
1893
         * <ul><li>If the tools are placed in different toolbars, they use the toolbars'
1894
         * order.
1895
         * (using the ToolBarComparator).</li>
1896
         * <li></li>
1897
         * <li>If any of the tools has not 'position' attribute, the tool which
1898
         * <strong>has</strong> the attribute will be placed first.</li>
1899
         * <li>If both tools have the same position (or they don't have a
1900
         * 'position' attribute), the priority of the extensions where the tool is defined.</li></ul>
1901
         *
1902
         * @author cesar
1903
         * @version $Revision: 28943 $
1904
         */
1905
        private static class ToolComparator implements Comparator {
1906
                private static ToolBarComparator toolBarComp = new ToolBarComparator();
1907

    
1908
                public int compare(Object o1, Object o2) {
1909
                        // compare the toolbars which contain the tools
1910
                        int result = toolBarComp.compare(o1, o2);
1911
                        if (result != 0) { // if the toolbars are different, use their order
1912
                                return result;
1913
                        }
1914
                        // otherwise, compare the tools
1915
                        SortableTool e1 = (SortableTool) o1;
1916
                        SortableTool e2 = (SortableTool) o2;
1917
                        int e1Position=-1, e2Position=-1;
1918

    
1919
                        if (e1.actiontool!=null) {
1920
                                if (e1.actiontool.hasPosition())
1921
                                        e1Position = e1.actiontool.getPosition();
1922
                        }
1923
                        else if (e1.selectabletool!=null) {
1924
                                if (e1.selectabletool.hasPosition())
1925
                                        e1Position = e1.selectabletool.getPosition();
1926
                        }
1927

    
1928
                        if (e2.actiontool!=null) {
1929
                                if (e2.actiontool.hasPosition())
1930
                                        e2Position = e2.actiontool.getPosition();
1931
                        }
1932
                        else if (e2.selectabletool!=null){
1933
                                if (e2.selectabletool.hasPosition())
1934
                                        e2Position = e2.selectabletool.getPosition();
1935
                        }
1936

    
1937
                        if (e1Position==-1 && e2Position!=-1) {
1938
                                return 1;
1939
                        }
1940
                        if (e1Position!=-1 && e2Position==-1) {
1941
                                return -1;
1942
                        }
1943
                        if (e1Position!=-1 && e2Position!=-1) {
1944
                                result = e1Position - e2Position;
1945
                                // we don't return 0 unless both objects are the same, otherwise the objects get overwritten in the treemap
1946
                                if (result!=0) return result;
1947
                        }
1948
                        return e1.toString().compareTo(e2.toString());
1949
                }
1950
        }
1951

    
1952

    
1953
        /**
1954
         * validates the user before starting gvsig
1955
         *
1956
         */
1957
        private static void validate(){
1958

    
1959
                IAuthentication session =  null;
1960
                try {
1961
                        session = (IAuthentication)Class.forName("com.iver.andami.authentication.Session").newInstance();
1962

    
1963
                } catch (ClassNotFoundException e) {
1964
                        return;
1965
                } catch (InstantiationException e) {
1966
                        return;
1967
                } catch (IllegalAccessException e) {
1968
                        return;
1969
                }
1970

    
1971
                session.setPluginDirectory( andamiConfig.getPluginsDirectory() );
1972
                if (session.validationRequired()){
1973
                        if(session.Login()){
1974
                                System.out.println("You are logged in");
1975
                        }
1976
                        else{
1977
                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),
1978
                                                 "You are not logged in");
1979
                                //System.exit(0);
1980
                        }
1981
                        PluginServices.setAuthentication(session);
1982
                }
1983
        }
1984

    
1985
        public static String getDefaultLookAndFeel() {
1986
                String osName = (String) System.getProperty("os.name");
1987

    
1988
                if (osName.length() > 4 && osName.substring(0,5).toLowerCase().equals("linux"))
1989
                        return nonWinDefaultLookAndFeel;
1990
                if (osName.toLowerCase().startsWith("mac os x"))
1991
                        return "ch.randelshofer.quaqua.QuaquaLookAndFeel";
1992

    
1993

    
1994
                return UIManager.getSystemLookAndFeelClassName();
1995
        }
1996

    
1997
        /**
1998
         * Gets the ISO 839 two-characters-long language code matching the
1999
         * provided language code (which may be an ISO 839-2/T
2000
         * three-characters-long code or an ISO 839-1 two-characters-long
2001
         * code).
2002
         *
2003
         * If the provided parameter is already two characters long, it
2004
         * returns the parameter without any modification.
2005
         *
2006
         * @param langCode A language code representing either
2007
         *  an ISO 839-2/T language code or an ISO 839-1 code.
2008
         * @return A two-characters-long code specifying
2009
         *  an ISO 839 language code.
2010
         */
2011
        private static String normalizeLanguageCode(String langCode) {
2012
                final String fileName = "iso_639.tab";
2013
                if (langCode.length()==2)
2014
                        return langCode;
2015
                else if (langCode.length()==3) {
2016
                        if (langCode.equals("va") || langCode.equals("val")) { // special case for Valencian
2017
                                return "ca";
2018
                        }
2019
                        URL isoCodes = Launcher.class.getClassLoader().getResource(fileName);
2020
                        if (isoCodes!=null) {
2021
                                try {
2022
                                        BufferedReader reader =
2023
                                                new BufferedReader(new InputStreamReader(isoCodes.openStream(), "ISO-8859-1"));
2024
                                                String line;
2025

    
2026
                                                while ((line = reader.readLine()) != null) {
2027
                                                        String[] language = line.split("\t");
2028
                                                        if (language[0].equals(langCode)) // first column is the three characters code
2029
                                                                return language[2]; // third column i the two characters code
2030
                                                }
2031
                                }
2032
                                catch (IOException ex) {
2033
                                        logger.error(Messages.getString("Error_reading_isocodes_file"), ex);
2034
                                        return "es";
2035
                                }
2036
                        }
2037
                        else {
2038
                                logger.error(Messages.getString("Error_reading_isocodes_file"));
2039
                                return "es";
2040
                        }
2041
                }
2042
                return "es";
2043
        }
2044

    
2045
        /**
2046
         * Configures the locales (languages and local resources) to be used
2047
         * by the application.
2048
         *
2049
         * First it tries to get the locale from the command line parameters,
2050
         * then the andami-config file is checked.
2051
         *
2052
         * The locale name is normalized to get a two characters language code
2053
         * as defined by ISO-639-1 (although ISO-639-2/T three characters codes
2054
         * are also accepted from the command line or the configuration file).
2055
         *
2056
         * Finally, the gvsig-i18n library and the default locales for Java and
2057
         * Swing are configured.
2058
         *
2059
         */
2060
        private static void configureLocales(String[] args) {
2061
                //                 Configurar el locale
2062
        String localeStr = null;
2063
        /*
2064
        for (int i=2; i < args.length; i++)
2065
        {
2066
                int index = args[i].indexOf("language=");
2067
                if (index != -1)
2068
                        localeStr = args[i].substring(index+9);
2069
        }
2070
         */
2071
        localeStr = PluginServices.getArgumentByName("language");
2072
                if (localeStr == null)
2073
                {
2074
            localeStr = andamiConfig.getLocaleLanguage();
2075
                }
2076
                localeStr = normalizeLanguageCode(localeStr);
2077
                locale = getLocale(localeStr,
2078
                andamiConfig.getLocaleCountry(),
2079
                andamiConfig.getLocaleVariant());
2080
                Locale.setDefault(locale);
2081
                JComponent.setDefaultLocale(locale);
2082
        org.gvsig.i18n.Messages.addLocale(locale);
2083
                // add english and spanish as fallback languages
2084
        if (localeStr.equals("es")||localeStr.equals("ca")||localeStr.equals("gl")||localeStr.equals("eu")||localeStr.equals("va")) {
2085
                // prefer Spanish for languages spoken in Spain
2086
                org.gvsig.i18n.Messages.addLocale(new Locale("es"));
2087
                org.gvsig.i18n.Messages.addLocale(new Locale("en"));
2088
        }
2089
        else {
2090
                // prefer English for the rest
2091
                org.gvsig.i18n.Messages.addLocale(new Locale("en"));
2092
                    org.gvsig.i18n.Messages.addLocale(new Locale("es"));
2093
        }
2094
        org.gvsig.i18n.Messages.addResourceFamily("com.iver.andami.text", "com.iver.andami.text");
2095

    
2096
        }
2097

    
2098
        /**
2099
         * Gets Home Directory location of the application.
2100
         * May be set from outside the aplication by means of
2101
         * -DgvSIG.home=C:/data/gvSIG, where gvSIG its the name
2102
         * of the application
2103
         * @return
2104
         */
2105
        public static String getAppHomeDir() {
2106
                return appHomeDir;
2107
        }
2108

    
2109
        /**
2110
         * Sets Home Directory location of the application.
2111
         * May be set from outside the aplication by means of
2112
         * -DgvSIG.home=C:/data/gvSIG, where gvSIG its the name
2113
         * of the application
2114
         * @param appHomeDir
2115
         */
2116
        public static void setAppHomeDir(String appHomeDir) {
2117
                Launcher.appHomeDir = appHomeDir;
2118
        }
2119

    
2120
        /**
2121
         * Initialize the extesion that have to take the control
2122
         *  of the state of action controls of the UI of all extensions.
2123
         * <br>
2124
         * <br>
2125
         * For use this option you have to add an argument
2126
         * to the command line like this:
2127
         * <br>
2128
         * <br>
2129
         * -exclusiveUI={pathToExtensionClass}
2130
         * <br>
2131
         *  @see com.iver.andami.plugins.IExtension#isEnabled(IExtension extension)
2132
         *  @see com.iver.andami.plugins.IExtension#isVisible(IExtension extension)
2133
         */
2134
        private static void initializeExclusiveUIExtension(){
2135
                String name = PluginServices.getArgumentByName("exclusiveUI");
2136
                if (name == null)
2137
                        return;
2138

    
2139

    
2140
                Iterator iter  = classesExtensions.keySet().iterator();
2141
                int charIndex;
2142
                Class key;
2143
                while (iter.hasNext()) {
2144
                        key = (Class)iter.next();
2145
                        charIndex = key.getName().indexOf(name);
2146
                        //System.out.println("key='"+key.getName()+"' name='"+name+"' charIndex="+charIndex);
2147
                        if (charIndex == 0) {
2148
                                IExtension ext =(IExtension)classesExtensions.get(key);
2149
                                if (ext instanceof ExtensionDecorator)
2150
                                        ext = ((ExtensionDecorator)ext).getExtension();
2151
                                if (ext instanceof ExclusiveUIExtension)
2152
                                        PluginServices.setExclusiveUIExtension((ExclusiveUIExtension)ext);
2153
                                break;
2154
                        }
2155
                }
2156

    
2157
                logger.error(Messages.getString("No_se_encontro_la_extension_especificada_en_el_parametro_exclusiveUI") + " '" + name +"'");
2158
        }
2159

    
2160

    
2161
//        public static void initIconThemes() {
2162
//                // load the iconTheme
2163
//                IconThemeManager iconManager = new IconThemeManager();
2164
//                PluginServices.setIconThemeManager(iconManager);
2165
//                IconThemeInfo selectedTheme = iconManager.readConfig();
2166
//                if (selectedTheme!=null) {
2167
//                        iconManager.setDefault(selectedTheme);
2168
//                        logger.info("Setting the icon theme: "+selectedTheme.toVerboseString());
2169
//                }
2170
//                else {
2171
//                        // set the default dir and try to load the default theme
2172
//                        try {
2173
//                                iconManager.setThemesDir(new File("iconThemes"));
2174
//                                IconThemeInfo[] list = iconManager.list();
2175
//
2176
//                                for (int i=0; i<list.length; i++) {
2177
//                                        if (list[i].getResourceName().equals("iconThemes/icons")) {
2178
//                                                iconManager.setDefault(list[i]);
2179
//                                                logger.info("Setting the default icon theme: "+list[i].toVerboseString());
2180
//                                                return;
2181
//                                        }
2182
//                                }
2183
//                        } catch (FileNotFoundException e) {
2184
//                                logger.info("IconTheme basedir does not exist");
2185
//                        }
2186
//                        // create an empty theme
2187
//                        IconThemeInfo info = new IconThemeInfo();
2188
//                        info.setName("No theme loaded");
2189
//                        info.setResource(null); // null resource means that no real theme is loaded
2190
//                        info.setDescription("No theme loaded");
2191
//                        info.setVersion("0");
2192
//                        iconManager.setDefault(new IconTheme(info));
2193
//                        logger.info("Setting an empty icon theme");
2194
//
2195
//                }
2196
//        }
2197

    
2198
        public static void initIconThemes(){
2199
                IconThemeManager iconManager = IconThemeManager.getIconThemeManager();
2200
                IIconTheme icontheme= iconManager.getIconThemeFromConfig();
2201
                if (icontheme!=null){
2202
                        iconManager.setCurrent(icontheme);
2203
                }
2204
        }
2205

    
2206
        /**
2207
         * Manages Andami termination process
2208
         *
2209
         * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
2210
         */
2211
        public class TerminationProcess {
2212
                private boolean proceed = false;
2213
                private UnsavedDataPanel panel = null;
2214

    
2215
                public void run() {
2216
                        int exit = manageUnsavedData();
2217
                        if (exit==JOptionPane.NO_OPTION || exit == JOptionPane.CLOSED_OPTION) {
2218
                                // the user doesn't want to exit
2219
                                return;
2220
                        }
2221

    
2222
                        closeAndami();
2223
                }
2224

    
2225
                /**
2226
                 * Finishes the application without asking user if want or not to save unsaved data.
2227
                 */
2228
                public void closeAndami() {
2229
                        //Configuraci?n de Andami
2230
                        try {
2231
                                andamiConfigToXML(andamiConfigPath);
2232
                        } catch (MarshalException e) {
2233
                                logger.error(Messages.getString(
2234
                                "Launcher.No_se_pudo_guardar_la_configuracion_de_andami"), e);
2235
                        } catch (ValidationException e) {
2236
                                logger.error(Messages.getString(
2237
                                "Launcher.No_se_pudo_guardar_la_configuracion_de_andami"), e);
2238
                        } catch (IOException e) {
2239
                                logger.error(Messages.getString(
2240
                                "Launcher.No_se_pudo_guardar_la_configuracion_de_andami"), e);
2241
                        }
2242

    
2243
                        //Persistencia de los plugins
2244
                        savePluginPersistence();
2245

    
2246
                        //Finalize all the extensions
2247
                        finalizeExtensions();
2248

    
2249
                        // Clean any temp data created
2250
                        Utilities.cleanUpTempFiles();
2251

    
2252
                        //Para la depuraci?n de memory leaks
2253
                        System.gc();
2254

    
2255
                        System.exit(0);
2256
                }
2257

    
2258
                /**
2259
                 * Exectutes the terminate method for all the extensions, in the reverse
2260
                 * order they were initialized
2261
                 *
2262
                 */
2263
                private void finalizeExtensions() {
2264
                        for (int i=extensions.size()-1; i>=0; i--) {
2265
                                com.iver.andami.plugins.IExtension extensionInstance=(com.iver.andami.plugins.IExtension)extensions.get(i);
2266
                                extensionInstance.terminate();
2267
                        }
2268
                }
2269

    
2270

    
2271
                private ArrayList getUnsavedData() {
2272
                        ArrayList unsavedDataList = new ArrayList();
2273
                        IExtension exclusiveExtension=PluginServices.getExclusiveUIExtension();
2274

    
2275
                        for (int i=extensions.size()-1; i>=0; i--) {
2276
                                com.iver.andami.plugins.IExtension extensionInstance=(com.iver.andami.plugins.IExtension)extensions.get(i);
2277
                                IExtensionStatus status = null;
2278
                                if (exclusiveExtension!=null) {
2279
                                        status = exclusiveExtension.getStatus(extensionInstance);
2280
                                }else {
2281
                                        status = extensionInstance.getStatus();
2282
                                }
2283
                                if (status!=null) {
2284
                                        if (status.hasUnsavedData()) {
2285
                                                IUnsavedData[] array = status.getUnsavedData();
2286
                                                for (int element = 0; element<array.length; element++) {
2287
                                                        unsavedDataList.add(array[element]);
2288
                                                }
2289
                                        }
2290
                                }
2291
                        }
2292
                        return unsavedDataList;
2293
                }
2294

    
2295
                public UnsavedDataPanel getUnsavedDataPanel() {
2296
                        if (panel==null) {
2297
                                panel = new UnsavedDataPanel(new IUnsavedData[0]);
2298
                        }
2299
                        return panel;
2300
                }
2301
                /**
2302
                 * Checks if the extensions have some unsaved data, and shows a dialog
2303
                 * to allow saving it. This dialog also allows to don't exit Andami.
2304
                 *
2305
                 * @return true if the user confirmed he wishes to exit, false otherwise
2306
                 */
2307
                public int manageUnsavedData(){
2308
                        ArrayList unsavedDataList = getUnsavedData();
2309

    
2310
                        // there was no unsaved data
2311
                        if (unsavedDataList.size()==0) {
2312
                                int option = JOptionPane.showConfirmDialog(frame,
2313
                                                Messages.getString("MDIFrame.quiere_salir"),
2314
                                                Messages.getString("MDIFrame.salir"),
2315
                                                JOptionPane.YES_NO_OPTION);
2316
                                return option;
2317
                        }
2318

    
2319
                        // it does not work if we directly cast the array
2320
                        IUnsavedData[] unsavedDataArray;
2321
                        unsavedDataArray = new IUnsavedData[unsavedDataList.size()];
2322
                        System.arraycopy(unsavedDataList.toArray(), 0, unsavedDataArray, 0, unsavedDataList.size());
2323

    
2324
                        UnsavedDataPanel panel = getUnsavedDataPanel();
2325
                        panel.setUnsavedDataArray(unsavedDataArray);
2326

    
2327

    
2328
                        panel.addActionListener(panel.new UnsavedDataPanelListener() {
2329
                                public void cancel(UnsavedDataPanel panel){
2330
                                        proceed(false);
2331
                                        PluginServices.getMDIManager().closeWindow(panel);
2332

    
2333
                                }
2334

    
2335
                                public void discard(UnsavedDataPanel panel){
2336
                                        proceed(true);
2337
                                        PluginServices.getMDIManager().closeWindow(panel);
2338

    
2339
                                }
2340

    
2341
                                public void accept(UnsavedDataPanel panel){
2342
                                        IUnsavedData[] unsavedDataArray = panel.getSelectedsUnsavedData();
2343
                                        boolean saved;
2344
                                        for (int i=0; i<unsavedDataArray.length; i++) {
2345
                                                try {
2346
                                                        saved = unsavedDataArray[i].saveData();
2347
                                                }
2348
                                                catch (Exception ex) {
2349
                                                        PluginServices.getLogger().error("Error saving"+unsavedDataArray[i].getResourceName() ,ex);
2350
                                                        saved = false;
2351
                                                }
2352
                                                if (!saved) {
2353
                                                        JOptionPane.showMessageDialog(
2354
                                                                        panel,
2355
                                                                        PluginServices.getText(this, "The_following_resource_could_not_be_saved_")+
2356
                                                                        "\n"+unsavedDataArray[i].getResourceName() + " -- "
2357
                                                                        + unsavedDataArray[i].getDescription(),
2358
                                                                        PluginServices.getText(this, "Resource_was_not_saved"),
2359
                                                                        JOptionPane.ERROR_MESSAGE);
2360

    
2361
                                                        ArrayList unsavedDataList = getUnsavedData();
2362
                                                        // it does not work if we directly cast the array
2363
                                                        unsavedDataArray = new IUnsavedData[unsavedDataList.size()];
2364
                                                        System.arraycopy(unsavedDataList.toArray(), 0, unsavedDataArray, 0, unsavedDataList.size());
2365
                                                        panel.setUnsavedDataArray(unsavedDataArray);
2366
                                                        return;
2367
                                                }
2368
                                        }
2369
                                        proceed(true);
2370
                                        PluginServices.getMDIManager().closeWindow(panel);
2371
                                }
2372
                        });
2373

    
2374
                        PluginServices.getMDIManager().addWindow(panel);
2375
                        if (proceed) {
2376
                                return JOptionPane.YES_OPTION;
2377
                        }
2378
                        else {
2379
                                return JOptionPane.NO_OPTION;
2380
                        }
2381
                }
2382

    
2383
                private void proceed(boolean proceed) {
2384
                        this.proceed = proceed;
2385
                }
2386

    
2387

    
2388
        }
2389

    
2390
        public static TerminationProcess getTerminationProcess() {
2391
                return (new Launcher()).new TerminationProcess();
2392
        }
2393
}