Statistics
| Revision:

svn-gvsig-desktop / tags / v2_0_0_Build_2020 / frameworks / _fwAndami / src / org / gvsig / andami / Launcher.java @ 33917

History | View | Annotate | Download (75.6 KB)

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

    
43
import java.awt.Component;
44
import java.awt.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.InputStreamReader;
60
import java.io.OutputStreamWriter;
61
import java.io.Reader;
62
import java.net.Authenticator;
63
import java.net.MalformedURLException;
64
import java.net.PasswordAuthentication;
65
import java.net.URL;
66
import java.nio.channels.FileChannel;
67
import java.security.AllPermission;
68
import java.security.CodeSource;
69
import java.security.PermissionCollection;
70
import java.security.Permissions;
71
import java.security.Policy;
72
import java.util.ArrayList;
73
import java.util.Comparator;
74
import java.util.HashMap;
75
import java.util.HashSet;
76
import java.util.Iterator;
77
import java.util.List;
78
import java.util.Locale;
79
import java.util.TreeMap;
80
import java.util.prefs.Preferences;
81

    
82
import javax.swing.ImageIcon;
83
import javax.swing.JButton;
84
import javax.swing.JComponent;
85
import javax.swing.JOptionPane;
86
import javax.swing.JPopupMenu;
87
import javax.swing.SwingUtilities;
88
import javax.swing.UIManager;
89

    
90
import org.apache.log4j.PatternLayout;
91
import org.apache.log4j.PropertyConfigurator;
92
import org.apache.log4j.RollingFileAppender;
93
import org.exolab.castor.xml.MarshalException;
94
import org.exolab.castor.xml.ValidationException;
95
import org.gvsig.andami.authentication.IAuthentication;
96
import org.gvsig.andami.authentication.LoginUI;
97
import org.gvsig.andami.config.generate.Andami;
98
import org.gvsig.andami.config.generate.AndamiConfig;
99
import org.gvsig.andami.config.generate.Plugin;
100
import org.gvsig.andami.iconthemes.IIconTheme;
101
import org.gvsig.andami.iconthemes.IconThemeManager;
102
import org.gvsig.andami.messages.Messages;
103
import org.gvsig.andami.messages.NotificationManager;
104
import org.gvsig.andami.plugins.ExclusiveUIExtension;
105
import org.gvsig.andami.plugins.ExtensionDecorator;
106
import org.gvsig.andami.plugins.IExtension;
107
import org.gvsig.andami.plugins.PluginClassLoader;
108
import org.gvsig.andami.plugins.config.generate.ActionTool;
109
import org.gvsig.andami.plugins.config.generate.ComboButton;
110
import org.gvsig.andami.plugins.config.generate.ComboButtonElement;
111
import org.gvsig.andami.plugins.config.generate.ComboScale;
112
import org.gvsig.andami.plugins.config.generate.Depends;
113
import org.gvsig.andami.plugins.config.generate.Extension;
114
import org.gvsig.andami.plugins.config.generate.Extensions;
115
import org.gvsig.andami.plugins.config.generate.LabelSet;
116
import org.gvsig.andami.plugins.config.generate.Menu;
117
import org.gvsig.andami.plugins.config.generate.PluginConfig;
118
import org.gvsig.andami.plugins.config.generate.PopupMenu;
119
import org.gvsig.andami.plugins.config.generate.PopupMenus;
120
import org.gvsig.andami.plugins.config.generate.SelectableTool;
121
import org.gvsig.andami.plugins.config.generate.SkinExtension;
122
import org.gvsig.andami.plugins.config.generate.SkinExtensionType;
123
import org.gvsig.andami.plugins.config.generate.ToolBar;
124
import org.gvsig.andami.plugins.status.IExtensionStatus;
125
import org.gvsig.andami.plugins.status.IUnsavedData;
126
import org.gvsig.andami.ui.AndamiEventQueue;
127
import org.gvsig.andami.ui.MDIManagerLoadException;
128
import org.gvsig.andami.ui.fonts.FontUtils;
129
import org.gvsig.andami.ui.mdiFrame.MDIFrame;
130
import org.gvsig.andami.ui.mdiFrame.NewStatusBar;
131
import org.gvsig.andami.ui.mdiManager.MDIManagerFactory;
132
import org.gvsig.andami.ui.splash.MultiSplashWindow;
133
import org.gvsig.andami.ui.theme.Theme;
134
import org.gvsig.andami.ui.wizard.UnsavedDataPanel;
135
import org.gvsig.tools.exception.ListBaseException;
136
import org.gvsig.tools.library.LibrariesInitializer;
137
import org.gvsig.tools.library.impl.DefaultLibrariesInitializer;
138
import org.gvsig.utils.DateTime;
139
import org.gvsig.utils.XMLEntity;
140
import org.gvsig.utils.xml.XMLEncodingUtils;
141
import org.gvsig.utils.xmlEntity.generate.XmlTag;
142
import org.slf4j.Logger;
143
import org.slf4j.LoggerFactory;
144

    
145

    
146

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

    
181
        protected static ArrayList pluginsOrdered = new ArrayList();
182
        protected static ArrayList extensions=new ArrayList();
183
        protected static String appHomeDir = null;
184
    // it seems castor uses this encoding
185
        protected static final String CASTORENCODING = "UTF8";
186
    
187
        protected static ListBaseException launcherrors = null;
188
        
189
        private static final class ProxyAuth extends Authenticator {
190
                private PasswordAuthentication auth;
191

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

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

    
201
    public static void main(String[] args) throws Exception {
202
            Launcher launcher = new Launcher();
203
            launcher.doMain(args);
204
    }
205
  
206
        protected void downloadExtensions(String extDir) {
207
                // do nothing
208
        }
209

    
210
        public static class LaunchException extends ListBaseException{
211

    
212
                /**
213
                 * 
214
                 */
215
                private static final long serialVersionUID = 4541192746962684705L;
216

    
217
                public LaunchException() {
218
                        super(
219
                                "Errors in initialization of application.", 
220
                                "_errors_in_initialization_of_application", 
221
                                serialVersionUID
222
                        );
223
                }
224
                
225
        }
226
        
227
        protected void addError(Throwable ex) {
228
                if( launcherrors == null ) {
229
                        launcherrors = new LaunchException();
230
                }
231
                launcherrors.add(ex);
232
        }
233
        
234
        protected void addError(String msg, Throwable cause) {
235
                logger.error(msg,cause);
236
                this.addError(new RuntimeException(msg,cause));
237
        }
238
        
239
        protected void addError(String msg) {
240
                this.addError(msg, null);
241
        }
242
        
243
    public void doMain(String[] args) throws Exception {
244
            try{
245

    
246
                    if (!validJVM()){
247
                            System.exit(-1);
248
                    }
249

    
250
                    if (args.length < 1) {
251
                            System.err.println("Uso: Launcher appName plugins-directory [language=locale]");
252
                    }
253

    
254
                    //  Clean temporal files
255
                    Utilities.cleanUpTempFiles();
256

    
257
                    appName = args[0];
258

    
259
                    //Se crea el directorio de configuraci?n de la aplicaci?n
260
                    appHomeDir = System.getProperty(args[0]+".home");
261
                    if (appHomeDir == null)
262
                            appHomeDir = System.getProperty("user.home");
263

    
264
                    appHomeDir += File.separator + args[0] + File.separator;
265
                    File parent = new File( appHomeDir );
266
                    parent.mkdirs();
267

    
268
                    andamiConfigPath = appHomeDir + "andami-config.xml";
269
                    pluginsPersistencePath = appHomeDir + "plugins-persistence.xml";
270

    
271
                    // Configurar el log4j
272
                    Launcher.class.getClassLoader().getResource(".");
273
                    PropertyConfigurator.configure("log4j.properties");
274

    
275
                    PatternLayout l = new PatternLayout("%p %t %C - %m%n");
276
                    RollingFileAppender fa = new RollingFileAppender(l,
277
                                    appHomeDir + args[0] + ".log", false);
278
                    fa.setMaxFileSize("512KB");
279
                    fa.setMaxBackupIndex(3);
280
                    org.apache.log4j.Logger.getRootLogger().addAppender(fa);
281

    
282
                    //org.apache.log4j.Logger.getRootLogger().setLevel(Level.TRACE);
283
                    
284
                    // Leer el fichero de configuraci?n de andami (andami-config.xsd)
285
                    // locale
286
                    // Buscar actualizaci?nes al comenzar
287
                    //  Andami
288
                    //  Plugins
289
                    // Directorio de las extensiones
290
                    andamiConfigFromXML(andamiConfigPath);
291
                    andamiConfig.setPluginsDirectory(args[1]);
292

    
293
                    // Hacemos visibles los argumentos como una propiedad est?tica
294
                    // de plugin services para quien lo quiera usar (por ejemplo, para
295
                    // cargar un proyecto por l?nea de comandos)
296
                    PluginServices.setArguments(args);
297

    
298
                    configureLocales(args);
299

    
300
                    //Se pone el lookAndFeel
301
                    try {
302
                            String lookAndFeel = getAndamiConfig().getLookAndFeel();
303
                            if (lookAndFeel == null)
304
                                    lookAndFeel = getDefaultLookAndFeel();
305
                            UIManager.setLookAndFeel(lookAndFeel);
306
                    } catch (Exception e) {
307
                            logger.warn(Messages.getString("Launcher.look_and_feel"), e);
308
                    }
309
                    FontUtils.initFonts();
310

    
311
                    // Solucionamos el problema de permisos que se produc?a con Java Web Start con este c?digo.
312
                    // System.setSecurityManager(null);
313
                    Policy.setPolicy(new Policy() {
314
                            public PermissionCollection getPermissions(CodeSource codesource) {
315
                                    Permissions perms = new Permissions();
316
                                    perms.add(new AllPermission());
317
                                    return (perms);
318
                            }
319
                            public void
320
                            refresh() {}
321
                    });
322

    
323
                    try {
324
                            initIconThemes();
325
                    } catch(Exception ex) {
326
                            this.addError("Can't initialize icon theme",ex);
327
                    }
328
//                    Registramos los iconos base
329
                    try {
330
                            registerIcons();
331
                    } catch(Exception ex) {
332
                            this.addError("Can't register icons",ex);
333
                    }
334
                    validate();
335

    
336
                    // Obtener la personalizaci?n de la aplicaci?n.
337
                    Theme theme = null;
338
                    try {
339
                            theme=getTheme(andamiConfig.getPluginsDirectory());
340
                    } catch(Exception ex) {
341
                            this.addError("Can't get personalized theme for the application",ex);
342
                    }
343

    
344
                    // Mostrar la ventana de inicio
345
                    Frame f=new Frame();
346
                    splashWindow=new MultiSplashWindow(f,theme, 190);
347

    
348
                    // 1. Ponemos los datos del proxy
349
                    splashWindow.process(10,
350
                                    PluginServices.getText(Launcher.class, "SplashWindow.configuring_proxy"));
351
                    configureProxy();
352

    
353
                    // 2. TODO Buscar actualizaciones de los plugins
354
                    splashWindow.process(20,
355
                                    PluginServices.getText(Launcher.class, "SplashWindow.looking_for_updates"));
356
                    try {
357
                            this.downloadExtensions(andamiConfig.getPluginsDirectory());
358
                    } catch(Exception ex) {
359
                            this.addError("Can't downloads plugins",ex);
360
                    }
361

    
362
                    // 3. Se leen los config.xml de los plugins -----++++
363
                    splashWindow.process(30,
364
                                    PluginServices.getText(Launcher.class, "SplashWindow.reading_plugins_config.xml"));
365
                    try {
366
                            this.loadPlugins(andamiConfig.getPluginsDirectory());
367
                    } catch(Exception ex) {
368
                            this.addError("Can't load plugins",ex);
369
                    }
370

    
371
                    // 4. Se configura el classloader del plugin
372
                    splashWindow.process(40,
373
                                    PluginServices.getText(Launcher.class, "SplashWindow.setting_up_class_loaders"));
374
                    try {
375
                            this.pluginsClassLoaders();
376
                    } catch(Exception ex) {
377
                            this.addError("Can't initialize plugin's classloaders  ",ex);
378
                    }
379

    
380
                    // 5. Se carga un Skin si alguno de los plugins trae informaci?n para ello
381
                    splashWindow.process(50,
382
                                    PluginServices.getText(Launcher.class, "SplashWindow.looking_for_a_skin"));
383
//                    skinPlugin(        "com.iver.core.mdiManager.NewSkin");
384
                    skinPlugin(null);
385

    
386
                    // 6. Se configura la cola de eventos
387
                    splashWindow.process(60,
388
                                    PluginServices.getText(Launcher.class, "setting_up_event_queue"));
389
                    EventQueue waitQueue = new AndamiEventQueue();
390
                    Toolkit.getDefaultToolkit().getSystemEventQueue().push(waitQueue);
391

    
392
                    // 7. Se configura la mensajer?a del plugin
393
                    splashWindow.process(70,
394
                                    PluginServices.getText(Launcher.class, "SplashWindow.starting_plugin_internationalization_system"));
395
                    pluginsMessages();
396

    
397
                    // 8. Se modifica el andami-config con los plugins nuevos
398
                    splashWindow.process(80,
399
                                    PluginServices.getText(Launcher.class, "SplashWindow.looking_for_a_skin"));
400
                    updateAndamiConfig();
401

    
402

    
403
                    frame = new MDIFrame();
404
                    // 9. Se configura el nombre e icono de la aplicaci?n
405
                    splashWindow.process(90,
406
                                    PluginServices.getText(Launcher.class, "SplashWindow.setting_up_applications_name_and_icons"));
407
                    frameIcon(theme);
408

    
409
                    // 10. Se prepara el MainFrame para albergar las extensiones
410
                    splashWindow.process(100,
411
                                    PluginServices.getText(Launcher.class, "SplashWindow.preparing_workbench"));
412
                    JPopupMenu.setDefaultLightWeightPopupEnabled(false);
413

    
414
                    SwingUtilities.invokeAndWait(new Runnable() {
415
                            public void run() {
416
                                    frame.init();
417
                            }
418
                    });
419

    
420

    
421

    
422
                    // 11. Leer el fichero de persistencia
423
                    //  info de los plugins
424
                    //  bookmarks de los plugins
425
                    splashWindow.process(110,
426
                                    PluginServices.getText(Launcher.class, "SplashWindow.loading_plugin_settings"));
427
                    loadPluginsPersistence();
428

    
429

    
430

    
431
                    // Se instalan los controles del skin
432
                    // 12. Se inicializan todas las extensiones de todos los plugins
433
                    splashWindow.process(120,
434
                                        PluginServices.getText(Launcher.class, "SplashWindow.initializing_extensions"));
435
                    SwingUtilities.invokeAndWait(new Runnable() {
436
                            public void run() {
437
                                    initializeExtensions();
438
                            }
439
                    });
440

    
441
                    // 13. Se inicializan la extensi?n exclusiva
442
                        splashWindow.process(130,
443
                                        PluginServices.getText(Launcher.class, "SplashWindow.setting_up_master_extension"));
444
                        SwingUtilities.invokeAndWait(new Runnable() {
445
                            public void run() {
446
                                    initializeExclusiveUIExtension();
447
                            }
448
                    });
449
                    frame.setClassesExtensions(classesExtensions);
450

    
451

    
452

    
453

    
454

    
455
                    // 14. Se instalan los controles de las extensiones de los plugins
456
                    splashWindow.process(140,
457
                                    PluginServices.getText(Launcher.class, "SplashWindow.installing_extensions_controls"));
458
                    SwingUtilities.invokeAndWait(new Runnable() {
459
                            public void run() {
460
                                    installPluginsControls();
461

    
462
                            }
463
                    });
464

    
465
                    // 15. Se instalan los menus de las extensiones de los plugins
466
                    splashWindow.process(150,
467
                                    PluginServices.getText(Launcher.class, "SplashWindow.installing_extensions_menus"));
468
                    SwingUtilities.invokeAndWait(new Runnable() {
469
                            public void run() {
470
                                    installPluginsMenus();
471

    
472
                            }
473
                    });
474

    
475
                    // 16. Se instalan las etiquetas de las extensiones de los plugins
476
                    splashWindow.process(160,
477
                                    PluginServices.getText(Launcher.class, "SplashWindow.installing_extensions_labels"));
478
                    SwingUtilities.invokeAndWait(new Runnable() {
479
                            public void run() {
480
                                    installPluginsLabels();
481

    
482
                            }
483
                    });
484

    
485

    
486
                    // 17. Se instalan los bookmarks de los plugins
487

    
488
                    // 18. Se muestra el frame principal
489
                    splashWindow.process(180,
490
                                    PluginServices.getText(Launcher.class, "creating_main_window"));
491
                    frame.setVisible(true);
492

    
493
                    // 19. Se ejecuta el postInitialize
494
                        splashWindow.process(190,
495
                                        PluginServices.getText(Launcher.class, "SplashWindow.post_initializing_extensions"));
496
                    SwingUtilities.invokeAndWait(new Runnable() {
497
                            public void run() {
498
                                    postInitializeExtensions();
499

    
500
                            }
501
                    });
502

    
503

    
504
                    // Definimos un KeyEventDispatcher global para que las extensiones
505
                    // puedan registrar sus "teclas r?pidas".
506
                    GlobalKeyEventDispatcher keyDispatcher = GlobalKeyEventDispatcher.getInstance();
507
                    KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(keyDispatcher);
508

    
509
                    SwingUtilities.invokeAndWait(new Runnable() {
510
                            public void run() {
511
                                    frame.enableControls();
512
                            }
513
                    });
514
                    splashWindow.close();
515
                    if( launcherrors!=null ) {
516
                            NotificationManager.addError(launcherrors);
517
                    }
518
            }catch(Exception e){
519
                    logger.error("excepci?n al arrancar", e);
520
                    System.exit(-1);
521
            }
522

    
523
    }
524
    
525
    /**
526
     * Return the directory applicaction is installed.
527
     */
528
    public static String getApplicationDirectory() {
529
            return new File("").getAbsolutePath();
530
    }
531

    
532
    private void registerIcons(){
533
            PluginServices.getIconTheme().registerDefault(
534
                            "login-gvsig",
535
                            LoginUI.class.getClassLoader().getResource("images/login_gvsig.png")
536
                    );
537
            PluginServices.getIconTheme().registerDefault(
538
                            "splash-gvsig",
539
                            MultiSplashWindow.class.getClassLoader().getResource("images/splash.png")
540
                    );
541
            PluginServices.getIconTheme().registerDefault(
542
                            "info-icon",
543
                            NewStatusBar.class.getClassLoader().getResource("images/info.gif")
544
                    );
545
            PluginServices.getIconTheme().registerDefault(
546
                            "error-icon",
547
                            NewStatusBar.class.getClassLoader().getResource("images/error.gif")
548
                    );
549
            PluginServices.getIconTheme().registerDefault(
550
                            "warning-icon",
551
                            NewStatusBar.class.getClassLoader().getResource("images/warning.gif")
552
                    );
553
            PluginServices.getIconTheme().registerDefault(
554
                            "no-icon",
555
                            NewStatusBar.class.getClassLoader().getResource("images/no_icon.png")
556
                    );
557
    }
558

    
559
    /**
560
     * Obtiene la personalizaci?n de los iconos, splash, fondo y el nombre de
561
     * la aplicaci?n.
562
     *
563
     * @return Theme
564
     */
565
    private Theme getTheme(String pluginsDirectory) {
566
            File themeFile;
567
            Theme theme = new Theme();
568

    
569
            // Try to get theme from args
570
            String name = PluginServices.getArgumentByName("andamiTheme");
571
                if( name != null ) {
572
                        themeFile = new File(name);
573
                        logger.info("search andami-theme in {}", themeFile.getAbsolutePath());
574
                        if( themeFile.exists() ) {
575
                                theme.readTheme(themeFile);
576
                                logger.info("andami-theme found in {}", themeFile.getAbsolutePath());
577
                                return theme;
578
                        }
579
                }
580
                
581
                // Try to get theme from a plugin
582
                File pluginsDir = new File(pluginsDirectory);
583
                if (pluginsDir.exists()) {
584
                        logger.info("search andami-theme in plugins folder.");
585
                        File[] pluginDirs = pluginsDir.listFiles();
586
                        if (pluginDirs.length>0) {        
587
                                for (int i = 0; i < pluginDirs.length; i++) {
588
                                        themeFile = new File(pluginDirs[i],"theme"+File.separator+"andami-theme.xml");
589
                                        if( themeFile.exists() ) {
590
                                                theme.readTheme(themeFile);
591
                                                logger.info("andami-theme found in plugin {}", themeFile.getAbsolutePath());
592
                                                return theme;
593
                                        }
594
                                }
595
                        }
596
                }
597
                
598
                // Try to get theme from dir gvSIG in user home
599
            themeFile = new File(getAppHomeDir(),"theme"+File.separator+"andami-theme.xml");
600
                logger.info("search andami-theme in user's home {}", themeFile.getAbsolutePath());
601
                if( themeFile.exists() ) {
602
                        theme.readTheme(themeFile);
603
                        logger.info("andami-theme found in user's home {}", themeFile.getAbsolutePath());
604
                        return theme;
605
                }
606

    
607
                // Try to get theme from the instalation dir of gvSIG.
608
                themeFile = new File(getApplicationDirectory(),"theme"+File.separator+"andami-theme.xml");
609
                logger.info("search andami-theme in installation folder {}", themeFile.getAbsolutePath());
610
                if( themeFile.exists() ) {
611
                        theme.readTheme(themeFile);
612
                        logger.info("andami-theme found in instalation folder {}", themeFile.getAbsolutePath());
613
                        return theme;
614
                }
615
                logger.info("Apply default andami-theme.");
616
                return theme;
617
        }
618
    
619
        /**
620
     *Establece los datos que ten?amos guardados respecto de la configuraci?n
621
     *del proxy.
622
     */
623
        private void configureProxy() {
624
                String host = prefs.get("firewall.http.host", "");
625
                String port = prefs.get("firewall.http.port", "");
626

    
627
                System.getProperties().put("http.proxyHost", host);
628
                System.getProperties().put("http.proxyPort", port);
629

    
630
                // Ponemos el usuario y clave del proxy, si existe
631
                String proxyUser = prefs.get("firewall.http.user",null);
632
                String proxyPassword = prefs.get("firewall.http.password", null);
633
                if (proxyUser != null )
634
                {
635
                        System.getProperties().put("http.proxyUserName", proxyUser);
636
                        System.getProperties().put("http.proxyPassword", proxyPassword);
637

    
638
                        Authenticator.setDefault(new ProxyAuth(proxyUser,
639
                                                        proxyPassword));
640
                } else {
641
                        Authenticator.setDefault(new ProxyAuth("", ""));
642
                }
643
        }
644

    
645
        /**
646
         * Recupera la geometr?a (tama?o, posic?n y estado) de la ventana principal de Andami.
647
         * TODO Pendiente de ver como se asigna un pluginServices para el launcher.
648
         * @author LWS
649
         */
650
        private void restoreMDIStatus(XMLEntity xml) {
651
                if (xml == null) xml = new XMLEntity();
652
                //  restore frame size
653
                Dimension sz = new Dimension(700,580);
654
                if (xml.contains("MDIFrameSize")) {
655
                        int [] wh = xml.getIntArrayProperty("MDIFrameSize");
656
                        sz = new Dimension(wh[0], wh[1]);
657
                }
658
                frame.setSize(sz);
659
                //  restore frame location
660
                Point pos = new Point(10,10);
661
                if (xml.contains("MDIFramePos")) {
662
                        int [] xy = xml.getIntArrayProperty("MDIFramePos");
663
                        pos = new Point(xy[0], xy[1]);
664
                }
665
                frame.setLocation(pos);
666

    
667
                //  restore frame status (Maximized, minimized, etc);
668
                int state = java.awt.Frame.MAXIMIZED_BOTH;
669
                if (xml.contains("MDIFrameState")) {
670
                        state = xml.getIntProperty("MDIFrameState");
671
                }
672
                frame.setExtendedState(state);
673
        }
674

    
675
        private XMLEntity saveMDIStatus() {
676
                XMLEntity xml = new XMLEntity();
677
                // save frame size
678
                int [] wh = new int[2];
679
                wh[0] = frame.getWidth();
680
                wh[1] = frame.getHeight();
681
                xml.putProperty("MDIFrameSize", wh);
682
                // save frame location
683
                int [] xy = new int[2];
684
                xy[0] = frame.getX();
685
                xy[1] = frame.getY();
686
                xml.putProperty("MDIFramePos", xy);
687
                // save frame status
688
                xml.putProperty("MDIFrameState", frame.getExtendedState());
689
                return xml;
690
        }
691

    
692
    private boolean validJVM() {
693
        char thirdCharacter = System.getProperty("java.version").charAt(2);
694
        if (thirdCharacter < '4'){
695
            return false;
696
            }else{
697
                return true;
698
            }
699
    }
700

    
701
        private void loadPluginsPersistence() throws ConfigurationException {
702
                XMLEntity entity = persistenceFromXML();
703

    
704
                for (int i = 0; i < entity.getChildrenCount(); i++) {
705
                        XMLEntity plugin = entity.getChild(i);
706
                        String pName = plugin.getStringProperty(
707
                                        "com.iver.andami.pluginName");
708
                        if (pluginsServices.get(pName)!= null){
709
                                ((PluginServices) pluginsServices.get(pName)).setPersistentXML(plugin);
710
                        } else {
711
                                if (pName.startsWith("Andami.Launcher"))
712
                                        restoreMDIStatus(plugin);
713
                        }
714
                }
715
        }
716

    
717
        /**
718
         * Salva la persistencia de los plugins.
719
         * @author LWS
720
         */
721
        private void savePluginPersistence() {
722
                Iterator i = pluginsConfig.keySet().iterator();
723

    
724
                XMLEntity entity = new XMLEntity();
725

    
726
                while (i.hasNext()) {
727
                        String pName = (String) i.next();
728
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
729
                        XMLEntity ent = ps.getPersistentXML();
730

    
731
                        if (ent != null) {
732
                                ent.putProperty("com.iver.andami.pluginName", pName);
733
                                entity.addChild(ent);
734
                        }
735
                }
736
                XMLEntity ent = saveMDIStatus();
737
                if (ent != null) {
738
                        ent.putProperty("com.iver.andami.pluginName", "Andami.Launcher");
739
                        entity.addChild(ent);
740
                }
741
                try {
742
                        persistenceToXML(entity);
743
                } catch (ConfigurationException e1) {
744
                        this.addError(Messages.getString(
745
                                        "Launcher.Se_produjo_un_error_guardando_la_configuracion_de_los_plugins"),
746
                                e1);
747
                }
748
        }
749

    
750
        private void installPluginsLabels() {
751
                Iterator i = pluginsConfig.keySet().iterator();
752

    
753
                while (i.hasNext()) {
754
                        String name = (String) i.next();
755
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(name);
756
                        PluginServices ps = (PluginServices) pluginsServices.get(name);
757

    
758
                        LabelSet[] ls = pc.getLabelSet();
759

    
760
                        for (int j = 0; j < ls.length; j++) {
761
                                PluginClassLoader loader = ps.getClassLoader();
762

    
763
                                try {
764
                                        Class clase = loader.loadClass(ls[j].getClassName());
765
                                        frame.setStatusBarLabels(clase, ls[j].getLabel());
766
                                } catch (ClassNotFoundException e) {
767
                                        this.addError(Messages.getString("Launcher.labelset_class"),
768
                                                e);
769
                                }
770
                        }
771
                }
772
        }
773

    
774
        private String configureSkin(XMLEntity xml,String defaultSkin) {
775
                if (defaultSkin == null){
776
                        for (int i = 0; i < xml.getChildrenCount(); i++) {
777
                                if (xml.getChild(i).contains("Skin-Selected")) {
778
                                        String className = xml.getChild(i).getStringProperty(
779
                                        "Skin-Selected");
780
                                        return className;
781
                                }
782
                        }
783
                }
784
//                return "com.iver.core.mdiManager.NewSkin";
785
                return  defaultSkin;
786
        }
787

    
788
        private void fixSkin(SkinExtension skinExtension,PluginClassLoader pluginClassLoader) throws MDIManagerLoadException{
789
                // now insert the skin selected.
790
                MDIManagerFactory.setSkinExtension(skinExtension, pluginClassLoader);
791
                // MDIManagerFactory.setSkinExtension(se,
792
                // ps.getClassLoader());
793

    
794
                Class skinClass;
795

    
796
                try {
797
                        skinClass = pluginClassLoader.loadClass(
798
                                        skinExtension.getClassName());
799

    
800
                        org.gvsig.andami.plugins.IExtension skinInstance = (org.gvsig.andami.plugins.IExtension) skinClass
801
                        .newInstance();
802
                        // classesExtensions.put(skinClass, skinInstance);
803
                        // jaume
804
                        ExtensionDecorator newExtensionDecorator = new ExtensionDecorator(
805
                                        skinInstance, ExtensionDecorator.INACTIVE);
806
                        classesExtensions.put(skinClass, newExtensionDecorator);
807
                } catch (ClassNotFoundException e) {
808
                        logger
809
                        .error(
810
                                        Messages
811
                                        .getString("Launcher.No_se_encontro_la_clase_mdi_manager"),
812
                                        e);
813
                        throw new MDIManagerLoadException(e);
814
                } catch (InstantiationException e) {
815
                        logger
816
                        .error(
817
                                        Messages
818
                                        .getString("Launcher.No_se_pudo_instanciar_la_clase_mdi_manager"),
819
                                        e);
820
                        throw new MDIManagerLoadException(e);
821
                } catch (IllegalAccessException e) {
822
                        logger
823
                        .error(
824
                                        Messages
825
                                        .getString("Launcher.No_se_pudo_acceder_a_la_clase_mdi_manager"),
826
                                        e);
827
                        throw new MDIManagerLoadException(e);
828
                }
829

    
830
        }
831
        /**
832
         * DOCUMENT ME!
833
         *
834
         * @throws MDIManagerLoadException
835
         */
836
        private void skinPlugin(String defaultSkin) throws MDIManagerLoadException {
837
                XMLEntity entity =null;
838
                try {
839
                        entity = persistenceFromXML();
840
                } catch (ConfigurationException e1) {
841
                        // TODO Auto-generated catch block
842
                        e1.printStackTrace();
843
                }
844
                Iterator i = pluginsConfig.keySet().iterator();
845

    
846
                SkinExtension skinExtension = null;
847
                PluginClassLoader pluginClassLoader = null;
848
                ArrayList skinExtensions = new ArrayList();
849
                while (i.hasNext()) {
850
                        String name = (String) i.next();
851
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(name);
852
                        PluginServices ps = (PluginServices) pluginsServices.get(name);
853

    
854
                        if (pc.getExtensions().getSkinExtension() != null) {
855
//                                if (MDIManagerFactory.getSkinExtension() != null) {
856
//                                        logger.warn(Messages.getString(
857
//                                                        "Launcher.Dos_skin_extension"));
858
//                                }
859

    
860
                                SkinExtension[] se = pc.getExtensions().getSkinExtension();
861
                                for (int numExten=0; numExten<se.length; numExten++) {
862
                                        skinExtensions.add(se[numExten]);
863
                                }
864
                                for (int j=0;j<se.length;j++){
865
                                        String configuredSkin = this.configureSkin(entity,defaultSkin);
866
                                        if (configuredSkin!=null && configuredSkin.equals(se[j].getClassName())) {
867
                                                skinExtension = se[j];
868
                                                pluginClassLoader = ps.getClassLoader();
869
                                        }
870
                                }
871
                        }
872
                }
873

    
874
                if ((skinExtension != null) && (pluginClassLoader != null)) {
875
                        // configured skin was found
876
                        fixSkin(skinExtension, pluginClassLoader);
877
                } else {
878
                        if (skinExtensions.contains("com.iver.core.mdiManager.NewSkin")) {
879
                                // try first NewSkin (from CorePlugin)
880
                                skinPlugin("com.iver.core.mdiManager.NewSkin");
881
                        }
882
                        else if (skinExtensions.size()>0){
883
                                // try to load the first skin found
884
                                SkinExtension se =  (SkinExtension)skinExtensions.get(0);
885
                                skinPlugin((String)se.getClassName());
886
                        }
887
                        else {
888
                                throw new MDIManagerLoadException("No Skin-Extension installed");
889
                        }
890
                }
891

    
892
        }
893

    
894
        private static void frameIcon(Theme theme) {
895
                Iterator i = pluginsConfig.keySet().iterator();
896

    
897
                while (i.hasNext()) {
898
                        String pName = (String) i.next();
899
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
900
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
901
                        if (pc.getIcon() != null) {
902
                                if (theme.getIcon() != null) {
903
                                        frame.setIconImage(theme.getIcon().getImage());
904
                                } else {
905

    
906
                                        ImageIcon icon = PluginServices.getIconTheme().get(pc.getIcon().getSrc());
907
                                        frame.setIconImage(icon.getImage());
908

    
909
                                }
910
                                if (theme.getName() != null) {
911
                                        frame.setTitlePrefix(theme.getName());
912
                                } else {
913
                                        frame.setTitlePrefix(pc.getIcon().getText());
914
                                }
915
                                if (theme.getBackgroundImage() != null) {
916

    
917
                                        PluginServices.getMDIManager().setBackgroundImage(theme.getBackgroundImage(),theme.getTypeDesktop());
918
                                }
919
                        }
920
                }
921
        }
922

    
923
        private void initializeExtensions() {
924
                
925
                libInitializers = new ArrayList<LibrariesInitializer>(pluginsOrdered
926
                                .size());
927
                
928
                Iterator i = pluginsOrdered.iterator();
929

    
930
        logger.debug("Initializing plugins: ");
931
                while (i.hasNext()) {
932
                        String pName = (String) i.next();
933
            logger.debug("Initializing plugin " + pName);
934
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
935
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
936
                        
937
                        // Create the libraries initializer and 
938
                        // initialize the plugin libraries
939
                        LibrariesInitializer libsInitializer = new DefaultLibrariesInitializer(
940
                                        ps.getClassLoader());
941
                        libsInitializer.initialize(true);
942
                        libInitializers.add(libsInitializer);
943

    
944
                        Extension[] exts = pc.getExtensions().getExtension();
945

    
946
                        TreeMap orderedExtensions = new TreeMap(new ExtensionComparator());
947

    
948
                        for (int j = 0; j < exts.length; j++) {
949
                                if (!exts[j].getActive()) {
950
                                        continue;
951
                                }
952

    
953
                                if (orderedExtensions.containsKey(exts[j])) {
954
                                        logger.warn("Two extensions with the same priority (" + exts[j].getClassName()+")");
955
                                }
956

    
957
                                orderedExtensions.put(exts[j], null);
958
                        }
959
                        
960
                        Iterator e = orderedExtensions.keySet().iterator();
961

    
962
                        logger.info("Initializing extensions: ");
963
                        while (e.hasNext()) {
964
                                Extension extension = (Extension) e.next();
965
                                org.gvsig.andami.plugins.IExtension extensionInstance;
966

    
967
                                try {
968
                                        Class extensionClass = ps.getClassLoader().loadClass(extension.getClassName());
969
                                        extensionInstance = (org.gvsig.andami.plugins.IExtension) extensionClass.newInstance();
970

    
971
                                        // CON DECORATOR
972
                                        // ANTES: classesExtensions.put(extensionClass, extensionInstance);
973
                                        // AHORA: CREAMOS UNA ExtensionDecorator y asignamos esta instancia para
974
                                        // poder ampliar con nuevas propiedades (AlwaysVisible, por ejemplo)
975
                                        // Para crear la nueva clase ExtensionDecorator, le pasamos como par?metro
976
                                        // la extensi?n original que acabamos de crear
977
                                        // 0-> Inactivo, controla la extension
978
                                        // 1-> Siempre visible
979
                                        // 2-> Invisible
980
                                        ExtensionDecorator newExtensionDecorator = new ExtensionDecorator(extensionInstance, ExtensionDecorator.INACTIVE);
981
                                        classesExtensions.put(extensionClass, newExtensionDecorator);
982
                                        logger.info("Initializing " + extension.getClassName()+"...");
983
                    // logger.debug("Initializing " + extension.getClassName());
984
                                        
985
                                        
986
                                        // AQUI
987
                                        
988
                    extensionInstance.initialize();
989
                    extensions.add(extensionInstance);
990
                    // logger.debug(extension.getClassName() + " initialized.");
991

    
992
                } catch (Exception e1) {
993
                        this.addError("Can't initialize extension '"+extension.getClassName()+"'.",e1);
994
                                } catch (NoClassDefFoundError e1) {
995
                                        this.addError("Can't found class extension ("+extension.getClassName()+")",e1);
996
                                }
997
                        }
998
                }
999
        }
1000

    
1001
        private void postInitializeExtensions() {
1002
                // Post initialize all plugin libraries
1003
                for (int i = 0; i < libInitializers.size(); i++) {
1004
                        libInitializers.get(i).postInitialize(true);
1005
                }
1006
                // Remove them all, we don't need them anymore
1007
                libInitializers.clear();
1008
                libInitializers = null;
1009
                
1010
                logger.info("PostInitializing extensions: ");
1011

    
1012
                for (int i=0;i<extensions.size();i++) {
1013
                        org.gvsig.andami.plugins.IExtension extensionInstance=(org.gvsig.andami.plugins.IExtension)extensions.get(i);
1014
                        logger.info("PostInitializing "
1015
                                        + extensionInstance.getClass().getName()
1016
                                        + "...");
1017
                        try {
1018
                                extensionInstance.postInitialize();
1019
                        } catch(Exception ex) {
1020
                                this.addError("postInitialize of extension '"+extensionInstance.getClass().getName()+"' failed",ex);
1021
                        }
1022
                }
1023
        }
1024

    
1025
        private void installPluginsMenus() {
1026
                TreeMap orderedMenus = new TreeMap(new MenuComparator());
1027

    
1028
                Iterator i = pluginsConfig.keySet().iterator();
1029

    
1030
                while (i.hasNext()) {
1031
                        String pName = (String) i.next();
1032
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
1033
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
1034

    
1035
                        Extension[] exts = pc.getExtensions().getExtension();
1036

    
1037
                        for (int j = 0; j < exts.length; j++) {
1038
                                if (!exts[j].getActive()) {
1039
                                        continue;
1040
                                }
1041

    
1042
                                Menu[] menus = exts[j].getMenu();
1043

    
1044
                                for (int k = 0; k < menus.length; k++) {
1045
                                        SortableMenu sm = new SortableMenu(ps.getClassLoader(),
1046
                                                        exts[j], menus[k]);
1047

    
1048
                                        if (orderedMenus.containsKey(sm)) {
1049
                                                this.addError(Messages.getString(
1050
                                                                "Launcher.Two_menus_with_the_same_position") + " - " +
1051
                                                        menus[k].getText()+ " - " + exts[j].getClassName());
1052
                                        }
1053

    
1054
                                        orderedMenus.put(sm, null);
1055
                                }
1056
                        }
1057

    
1058
                        // Se instalan las extensiones de MDI
1059
                        SkinExtension[] skinExts = pc.getExtensions().getSkinExtension();
1060
                        for (int j = 0; j < skinExts.length; j++) {
1061

    
1062

    
1063
                        if (skinExts[j] != null) {
1064
                                Menu[] menu = skinExts[j].getMenu();
1065

    
1066
                                for (int k = 0; k < menu.length; k++) {
1067
                                        SortableMenu sm = new SortableMenu(ps.getClassLoader(),
1068
                                                        skinExts[j], menu[k]);
1069

    
1070
                                        if (orderedMenus.containsKey(sm)) {
1071
                                                this.addError(Messages.getString(
1072
                                                                "Launcher.Two_menus_with_the_same_position") +
1073
                                                        skinExts[j].getClassName());
1074
                                        }
1075

    
1076
                                        orderedMenus.put(sm, null);
1077
                                }
1078
                        }
1079
                        }
1080
                }
1081

    
1082
                //Se itera por los menus ordenados
1083
                Iterator e = orderedMenus.keySet().iterator();
1084

    
1085
                // Se ordenan los menues
1086
                while (e.hasNext()) {
1087
                        try {
1088
                                SortableMenu sm = (SortableMenu) e.next();
1089

    
1090
                                frame.addMenu(sm.loader, sm.extension, sm.menu);
1091
                        } catch (ClassNotFoundException ex) {
1092
                                this.addError(Messages.getString(
1093
                                                "Launcher.No_se_encontro_la_clase_de_la_extension"), ex);
1094
                        }
1095
                }
1096
        }
1097

    
1098
        /**
1099
         * Installs the menus, toolbars, actiontools, selectable toolbars and combos.
1100
         * The order in which they are shown is determined here.
1101
         */
1102
        private void installPluginsControls() {
1103
                Iterator i = pluginsConfig.keySet().iterator();
1104

    
1105
                HashMap extensionPluginServices = new HashMap();
1106
                HashMap extensionPluginConfig = new HashMap();
1107
                TreeMap orderedExtensions = new TreeMap(new ExtensionComparator());
1108

    
1109
                // First of all, sort the extensions.
1110
                // We need to iterate on the plugins, and iterate on each plugin's extensions
1111
                // (each plugin may contain one or more extensions)
1112
                while (i.hasNext()) { // iterate on the plugins
1113
                        String pName = (String) i.next();
1114
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
1115
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
1116

    
1117
                        Extension[] exts = pc.getExtensions().getExtension();
1118

    
1119
                        for (int j = 0; j < exts.length; j++) { // iterate on the extensions
1120
                                if (exts[j].getActive()) {
1121
                                        if (orderedExtensions.containsKey(exts[j])) {
1122
                                                this.addError(Messages.getString(
1123
                                                "Launcher.Two_extensions_with_the_same_priority") +
1124
                                                exts[j].getClassName());
1125
                                        }
1126

    
1127
                                        orderedExtensions.put(exts[j], null);
1128
                                        extensionPluginServices.put(exts[j], ps);
1129
                                        extensionPluginConfig.put(exts[j], pc);
1130
                                }
1131
                        }
1132
                }
1133

    
1134
                TreeMap orderedTools = new TreeMap(new ToolComparator());
1135
                Iterator e = orderedExtensions.keySet().iterator();
1136

    
1137
                // sort the toolbars and tools from 'normal' extensions (actiontools, selectabletools)
1138
                // and load the  combo-scales and combo-buttons for the status bar
1139
                while (e.hasNext()) {
1140
                        Extension ext = (Extension) e.next();
1141

    
1142
                        ToolBar[] toolbars = ext.getToolBar();
1143

    
1144
                        // get tools from toolbars
1145
                        for (int k = 0; k < toolbars.length; k++) {
1146
                                ActionTool[] tools = toolbars[k].getActionTool();
1147

    
1148
                                for (int t = 0; t < tools.length; t++) {
1149
                                        SortableTool sm = new SortableTool(((PluginServices)extensionPluginServices.get(ext)).getClassLoader(), ext,
1150
                                                        toolbars[k], tools[t]);
1151
                                        orderedTools.put(sm, null);
1152
                                }
1153

    
1154
                                SelectableTool[] sTools = toolbars[k].getSelectableTool();
1155

    
1156
                                for (int t = 0; t < sTools.length; t++) {
1157
                                        SortableTool sm=new SortableTool(((PluginServices)extensionPluginServices.get(ext)).getClassLoader(), ext,
1158
                                                        toolbars[k], sTools[t]);
1159
                                        orderedTools.put(sm, null);
1160
                                }
1161
                        }
1162

    
1163
                        // get controls for statusBar
1164
                        PluginServices ps = (PluginServices) extensionPluginServices.get(ext);
1165
                        PluginClassLoader loader = ps.getClassLoader();
1166

    
1167
                        //ArrayList componentList = new ArrayList();
1168
                        ComboScale[] comboScaleArray = ext.getComboScale();
1169
                        for (int k=0; k < comboScaleArray.length; k++) {
1170
                                org.gvsig.gui.beans.controls.comboscale.ComboScale combo = new org.gvsig.gui.beans.controls.comboscale.ComboScale();
1171
                                String label = comboScaleArray[k].getLabel();
1172
                                if (label!=null)
1173
                                        combo.setLabel(label);
1174
                                String name = comboScaleArray[k].getName();
1175
                                if (name!=null)
1176
                                        combo.setName(name);
1177
                                String[] elementsString = ((String)comboScaleArray[k].getElements()).split(";");
1178
                                long[] elements = new long[elementsString.length];
1179
                                for (int currentElem=0; currentElem<elementsString.length; currentElem++) {
1180
                                        try {
1181
                                                elements[currentElem] = Long.parseLong(elementsString[currentElem]);
1182
                                        }
1183
                                        catch (NumberFormatException nfex1) {
1184
                                                this.addError(ext.getClassName()+" -- "+Messages.getString( "error_parsing_comboscale_elements"));
1185
                                                elements[currentElem] = 0;
1186
                                        }
1187
                                }
1188
                                combo.setItems(elements);
1189
                                try {
1190
                                        long value = Long.parseLong((String)comboScaleArray[k].getValue());
1191
                                        combo.setScale(value);
1192
                                }
1193
                                catch (NumberFormatException nfex2) {
1194
                                        this.addError(ext.getClassName()+" -- "+Messages.getString( "error_parsing_comboscale_value"));
1195
                                }
1196
                                try {
1197
                                        frame.addStatusBarControl(loader.loadClass(ext.getClassName()),combo);
1198
                                } catch (ClassNotFoundException e1) {
1199
                                        this.addError(Messages.getString("Launcher.error_getting_class_loader_for_status_bar_control"), e1);
1200
                                }
1201
                        }
1202

    
1203
                        ComboButton[] comboButtonArray = ext.getComboButton();
1204
                        for (int k=0; k < comboButtonArray.length; k++) {
1205
                                ComboButtonElement[] elementList = comboButtonArray[k].getComboButtonElement();
1206
                                org.gvsig.gui.beans.controls.combobutton.ComboButton combo = new org.gvsig.gui.beans.controls.combobutton.ComboButton();
1207
                                String name = comboButtonArray[k].getName();
1208
                                if (name!=null)
1209
                                        combo.setName(name);
1210
                                for (int currentElement=0; currentElement<elementList.length; currentElement++) {
1211
                                        ComboButtonElement element = elementList[currentElement];
1212
                                        ImageIcon icon;
1213
                                        URL iconLocation = loader.getResource(element.getIcon());
1214
                                        if (iconLocation==null)
1215
                                                this.addError(Messages.getString("Icon_not_found_")+element.getIcon());
1216
                                        else {
1217
                                                icon = new ImageIcon(iconLocation);
1218
                                                JButton button = new JButton(icon);
1219
                                                combo.addButton(button);
1220
                                                button.setActionCommand(element.getActionCommand());
1221
                                        }
1222
                                }
1223
                                try {
1224
                                        frame.addStatusBarControl(loader.loadClass(ext.getClassName()), combo);
1225
                                } catch (ClassNotFoundException e1) {
1226
                                        this.addError(Messages.getString("Launcher.error_getting_class_loader_for_status_bar_control"), e1);
1227
                                }
1228
                        }
1229
                }
1230

    
1231
                // Add the tools from MDI extensions to the ordered tool-list, so that we get a sorted list containing all the tools
1232
                i = pluginsConfig.keySet().iterator();
1233
                while (i.hasNext()) {
1234
                        String pName = (String) i.next();
1235
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
1236
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
1237

    
1238
                        SkinExtension[] skinExts = pc.getExtensions().getSkinExtension();
1239
                        for (int j = 0; j < skinExts.length; j++) {
1240

    
1241

    
1242
                        if (skinExts[j] != null) {
1243
                                ToolBar[] toolbars = skinExts[j].getToolBar();
1244

    
1245
                                for (int k = 0; k < toolbars.length; k++) {
1246
                                        ActionTool[] tools = toolbars[k].getActionTool();
1247

    
1248
                                        for (int t = 0; t < tools.length; t++) {
1249
                                                SortableTool stb=new SortableTool(ps.getClassLoader(), skinExts[j],
1250
                                                                toolbars[k], tools[t]);
1251
                                                orderedTools.put(stb,null);
1252
                                        }
1253

    
1254
                                        SelectableTool[] sTools = toolbars[k].getSelectableTool();
1255

    
1256
                                        for (int t = 0; t < sTools.length; t++) {
1257
                                                SortableTool stb=new SortableTool(ps.getClassLoader(), skinExts[j],
1258
                                                                toolbars[k], sTools[t]);
1259
                                                orderedTools.put(stb,null);
1260
                                        }
1261
                                }
1262
                        }
1263
                        }
1264
                        // Install popup menus
1265
                        PopupMenus pus = pc.getPopupMenus();
1266

    
1267
                        if (pus != null) {
1268
                                PopupMenu[] menus = pus.getPopupMenu();
1269

    
1270
                                for (int j = 0; j < menus.length; j++) {
1271
                                        frame.addPopupMenu(ps.getClassLoader(), menus[j]);
1272
                                }
1273
                        }
1274
                }
1275

    
1276
                // loop on the ordered extension list, to add them to the interface in an ordered way
1277
                Iterator t = orderedTools.keySet().iterator();
1278
                while (t.hasNext()) {
1279
                        try {
1280
                                SortableTool stb = (SortableTool) t.next();
1281
                                if (stb.actiontool!=null)
1282
                                        frame.addTool(stb.loader, stb.extension,stb.toolbar, stb.actiontool);
1283
                                else
1284
                                        frame.addTool(stb.loader, stb.extension,stb.toolbar, stb.selectabletool);
1285
                        } catch (ClassNotFoundException ex) {
1286
                                this.addError(Messages.getString(
1287
                                "Launcher.No_se_encontro_la_clase_de_la_extension"), ex);
1288
                        }
1289
                }
1290
        }
1291

    
1292
        /**
1293
         * Adds new plugins to the the andami-config file.
1294
         */
1295
        private void updateAndamiConfig() {
1296
                HashSet olds = new HashSet();
1297

    
1298
                Plugin[] plugins = andamiConfig.getPlugin();
1299

    
1300
                for (int i = 0; i < plugins.length; i++) {
1301
                        olds.add(plugins[i].getName());
1302
                }
1303

    
1304
                Iterator i = pluginsServices.values().iterator();
1305

    
1306
                while (i.hasNext()) {
1307
                        PluginServices ps = (PluginServices) i.next();
1308

    
1309
                        if (!olds.contains(ps.getPluginName())) {
1310
                                Plugin p = new Plugin();
1311
                                p.setName(ps.getPluginName());
1312
                                p.setUpdate(false);
1313

    
1314
                                andamiConfig.addPlugin(p);
1315
                        }
1316
                }
1317
        }
1318

    
1319
        private void pluginsClassLoaders() {
1320
                HashSet instalados = new HashSet();
1321

    
1322
                // Se itera hasta que est?n todos instalados
1323
                while (instalados.size() != pluginsConfig.size()) {
1324
                        boolean circle = true;
1325

    
1326
                        //Hacemos una pasada por todos los plugins
1327
                        Iterator i = pluginsConfig.keySet().iterator();
1328

    
1329
                        while (i.hasNext()) {
1330
                                String pluginName = (String) i.next();
1331
                                PluginConfig config = (PluginConfig) pluginsConfig.get(pluginName);
1332

    
1333
                                if (instalados.contains(pluginName)) {
1334
                                        continue;
1335
                                }
1336

    
1337
                                //Se obtienen las dependencias y sus class loaders
1338
                                boolean ready = true;
1339
                                Depends[] dependencies = config.getDepends();
1340
                                PluginClassLoader[] loaders = new PluginClassLoader[dependencies.length];
1341

    
1342
                                for (int j = 0; j < dependencies.length; j++) {
1343
                                        if (pluginsConfig.get(dependencies[j].getPluginName()) == null) {
1344
                                                this.addError(Messages.getString(
1345
                                                                "Launcher.Dependencia_no_resuelta_en_plugin") +
1346
                                                        " " +pluginName + ": " +
1347
                                                        dependencies[j].getPluginName());
1348

    
1349
                                                continue;
1350
                                        }
1351

    
1352
                                        if (!instalados.contains(dependencies[j].getPluginName())) {
1353
                                                ready = false;
1354
                                        } else {
1355
                                                loaders[j] = ((PluginServices) pluginsServices.get(dependencies[j].getPluginName())).getClassLoader();
1356
                                        }
1357
                                }
1358

    
1359
                                //Si no est?n sus dependencias satisfechas se aborta la instalaci?n
1360
                                if (!ready) {
1361
                                        continue;
1362
                                }
1363

    
1364
                                //Se genera el class loader
1365
                                String jardir = config.getLibraries().getLibraryDir();
1366
                                File jarDir = new File(andamiConfig.getPluginsDirectory() +
1367
                                                File.separator + pluginName + File.separator + jardir);
1368
                                File[] jarFiles = jarDir.listFiles(new FileFilter() {
1369
                                                        public boolean accept(File pathname) {
1370
                                                                return (pathname.getName().toUpperCase()
1371
                                                                                                .endsWith(".JAR")) ||
1372
                                                                (pathname.getName().toUpperCase().endsWith(".ZIP"));
1373
                                                        }
1374
                                                });
1375

    
1376
                                URL[] urls = new URL[jarFiles.length];
1377

    
1378
                                for (int j = 0; j < jarFiles.length; j++) {
1379
                                        try {
1380
                                                urls[j] = new URL("file:" + jarFiles[j]);
1381
                                        } catch (MalformedURLException e) {
1382
                                                this.addError(Messages.getString(
1383
                                                                "Launcher.No_se_puede_acceder_a") +" " +
1384
                                                        jarFiles[j]);
1385
                                        }
1386
                                }
1387

    
1388
                                PluginClassLoader loader;
1389

    
1390
                                try {
1391
                                        loader = new PluginClassLoader(urls,
1392
                                                        andamiConfig.getPluginsDirectory() +
1393
                                                        File.separator + pluginName,
1394
                                                        Launcher.class.getClassLoader(), loaders);
1395

    
1396
                                        PluginServices ps = new PluginServices(loader);
1397

    
1398
                                        pluginsServices.put(ps.getPluginName(), ps);
1399

    
1400
                                        instalados.add(pluginName);
1401
                    // FJP: Los metemos ordenados para luego no cargar uno que necesita de otro antes de tiempo. Esto lo usaremos al
1402
                    // inicializar los plugins
1403
                    pluginsOrdered.add(pluginName);
1404

    
1405
                                        circle = false;
1406
                                } catch (IOException e) {
1407
                                        this.addError(Messages.getString(
1408
                                                        "Launcher.Error_con_las_librerias_del_plugin"), e);
1409
                                        pluginsConfig.remove(pluginName);
1410
                                        i = pluginsConfig.keySet().iterator();
1411
                                }
1412
                        }
1413

    
1414
                        if (circle) {
1415
                                this.addError(Messages.getString(
1416
                                                "Launcher.Hay_dependencias_circulares"));
1417

    
1418
                                break;
1419
                        }
1420
                }
1421

    
1422
                //Se eliminan los plugins que no fueron instalados
1423
                Iterator i = pluginsConfig.keySet().iterator();
1424

    
1425
                while (i.hasNext()) {
1426
                        String pluginName = (String) i.next();
1427
                        PluginConfig config = (PluginConfig) pluginsConfig.get(pluginName);
1428
                        PluginServices ps = (PluginServices) pluginsServices.get(pluginName);
1429

    
1430
                        if (ps == null) {
1431
                                pluginsConfig.remove(pluginName);
1432
                                i = pluginsConfig.keySet().iterator();
1433
                        }
1434
                }
1435
        }
1436

    
1437
        private void pluginsMessages() {
1438
                Iterator iterator = pluginsOrdered.iterator();
1439
                PluginConfig config;
1440
                PluginServices ps;
1441

    
1442
                while (iterator.hasNext()) {
1443
                        String pluginName = (String) iterator.next();
1444
                        config = (PluginConfig) pluginsConfig.get(pluginName);
1445
                        ps = (PluginServices) pluginsServices.get(pluginName);
1446

    
1447
                        if (config.getResourceBundle() != null && !config.getResourceBundle().getName().equals("")) {
1448
                                // add the locale files associated with the plugin
1449
                                org.gvsig.i18n.Messages.addResourceFamily(config.getResourceBundle().getName(), ps.getClassLoader(), pluginName);
1450
                        }
1451
                }
1452
        }
1453

    
1454
        static PluginServices getPluginServices(String name) {
1455
                return (PluginServices) pluginsServices.get(name);
1456
        }
1457

    
1458
        static String getPluginsDir() {
1459
                return andamiConfig.getPluginsDirectory();
1460
        }
1461

    
1462
        static void setPluginsDir(String s) {
1463
                andamiConfig.setPluginsDirectory(s);
1464
        }
1465

    
1466
        static MDIFrame getMDIFrame() {
1467
                return frame;
1468
        }
1469

    
1470
        private void loadPlugins(String pluginsDirectory) {
1471
                File pDir = new File(pluginsDirectory);
1472

    
1473
                if (!pDir.exists()) {
1474
                        logger.error("\n\tPlugins directory not found: "+pDir.getAbsolutePath()+"\n\tDid you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
1475
                        System.exit(-1);
1476
                        return;
1477
                }
1478

    
1479
                File[] pluginDirs = pDir.listFiles();
1480
                if (pluginDirs.length==0) {
1481
                        logger.error("\n\tPlugins directory is empty: "+pDir.getAbsolutePath()+"Did you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
1482
                        System.exit(-1);
1483
                        return;
1484
                }
1485

    
1486
                for (int i = 0; i < pluginDirs.length; i++) {
1487
                        if (pluginDirs[i].isDirectory()) {
1488
                                File configXml = new File(pluginDirs[i].getAbsolutePath() +
1489
                                                File.separator + "config.xml");
1490

    
1491
                                try {
1492
                                        FileInputStream is = new FileInputStream(configXml);
1493
                                        Reader xml = org.gvsig.utils.xml.XMLEncodingUtils.getReader(is);
1494
                                        if (xml==null) {
1495
                                                // the encoding was not correctly detected, use system default
1496
                                                xml = new FileReader(configXml);
1497
                                        }
1498
                                        else {
1499
                                                // use a buffered reader to improve performance
1500
                                                xml = new BufferedReader(xml);
1501
                                        }
1502
                                        PluginConfig pConfig = (PluginConfig) PluginConfig.unmarshal(xml);
1503
                                        pluginsConfig.put(pluginDirs[i].getName(), pConfig);
1504
                                } catch (FileNotFoundException e) {
1505
                                        logger.info("Plugin folder without config.xml. Skip plugin '"+pluginDirs[i].getAbsolutePath() +"'.");
1506
                                } catch (MarshalException e) {
1507
                                        this.addError("Can't load plugin '"+pluginDirs[i].getAbsolutePath() +"'." ,
1508
                                                        e
1509
                                        );
1510
                                } catch (ValidationException e) {
1511
                                        this.addError("Can't load plugin '"+pluginDirs[i].getAbsolutePath() +"'." ,
1512
                                                        e
1513
                                        );
1514
                                }
1515
                        }
1516
                }
1517

    
1518
                if (pluginsConfig.size()==0) {
1519
                        logger.error("No 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...");
1520
                        System.exit(-1);
1521
                        return;
1522
                }
1523
        }
1524

    
1525
        private static Locale getLocale(String language, String country,
1526
                String variant) {
1527
                if (variant != null) {
1528
                        return new Locale(language, country, variant);
1529
                } else if (country != null) {
1530
                        return new Locale(language, country);
1531
                } else if (language != null) {
1532
                        return new Locale(language);
1533
                } else {
1534
                        return new Locale("es");
1535
                }
1536
        }
1537

    
1538
        private static void andamiConfigToXML(String file)
1539
                throws IOException, MarshalException, ValidationException {
1540
                // write on a temporary file in order to not destroy current file if there is some problem while marshaling
1541
                File tmpFile = new File(file+"-"+DateTime.getCurrentDate().getTime());
1542
                File xml = new File(file);
1543
                File parent = xml.getParentFile();
1544
                parent.mkdirs();
1545

    
1546
                BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(tmpFile));
1547
                OutputStreamWriter writer = new OutputStreamWriter(os, CASTORENCODING);
1548
                andamiConfig.marshal(writer);
1549
                writer.close();
1550

    
1551
                // if marshaling process finished correctly, move the file to the correct one
1552
                xml.delete();
1553
                if (!tmpFile.renameTo(xml)) {
1554
                        // if rename was not succesful, try copying it
1555
                        FileChannel sourceChannel = new  FileInputStream(tmpFile).getChannel();
1556
                        FileChannel destinationChannel = new FileOutputStream(xml).getChannel();
1557
                        sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel);
1558
                        sourceChannel.close();
1559
                        destinationChannel.close();
1560
                }
1561
        }
1562

    
1563
        private static void andamiConfigFromXML(String file)
1564
                throws ConfigurationException {
1565
                File xml = new File(file);
1566

    
1567
                InputStreamReader reader = null;
1568
                try {
1569
                        //Se lee la configuraci?n
1570
                        reader = XMLEncodingUtils.getReader(xml);
1571
                        andamiConfig = (AndamiConfig) AndamiConfig.unmarshal(reader);
1572
                } catch (FileNotFoundException e) {
1573
                        //Si no existe se ponen los valores por defecto
1574
                        andamiConfig = getDefaultAndamiConfig();
1575
                } catch (MarshalException e) {
1576
                        // try to close the stream, maybe it remains open
1577
                        if (reader!=null) {
1578
                                try { reader.close(); } catch (IOException e1) {}
1579
                        }
1580
                        // if there was a problem reading the file, backup it and create a new one with default values
1581
                        String backupFile = file+"-"+DateTime.getCurrentDate().getTime();
1582
                        NotificationManager.addError(Messages.getString("Error_reading_andami_config_New_file_created_A_backup_was_made_on_")+backupFile, new ConfigurationException(e));
1583
                        xml.renameTo(new File(backupFile));
1584
                        andamiConfig = getDefaultAndamiConfig();
1585
                } catch (ValidationException e) {
1586
                        throw new ConfigurationException(e);
1587
                }
1588
        }
1589

    
1590
        private static AndamiConfig getDefaultAndamiConfig() {
1591
                AndamiConfig andamiConfig = new AndamiConfig();
1592

    
1593
                Andami andami = new Andami();
1594
                andami.setUpdate(true);
1595
                andamiConfig.setAndami(andami);
1596
                andamiConfig.setLocaleCountry(Locale.getDefault().getCountry());
1597
                andamiConfig.setLocaleLanguage(Locale.getDefault().getLanguage());
1598
                andamiConfig.setLocaleVariant(Locale.getDefault().getVariant());
1599

    
1600
                if (System.getProperty("javawebstart.version") != null) // Es java web start)
1601
                 {
1602
                        andamiConfig.setPluginsDirectory(new File(appHomeDir
1603
                                        + "extensiones").getAbsolutePath());
1604
                } else {
1605
                        andamiConfig.setPluginsDirectory(new File(appName +
1606
                                        File.separator + "extensiones").getAbsolutePath());
1607
                }
1608

    
1609
                andamiConfig.setPlugin(new Plugin[0]);
1610
                return andamiConfig;
1611
        }
1612

    
1613
        private static XMLEntity persistenceFromXML() throws ConfigurationException {
1614
                File xml = new File(pluginsPersistencePath);
1615

    
1616
                if (xml.exists()) {
1617
                        InputStreamReader reader = null;
1618

    
1619
                        try {
1620
                                reader = XMLEncodingUtils.getReader(xml);
1621
                                XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
1622
                                return new XMLEntity(tag);
1623
                        } catch (FileNotFoundException e) {
1624
                                throw new ConfigurationException(e);
1625
                        } catch (MarshalException e) {
1626

    
1627
                                // try to reopen with default encoding (for backward compatibility)
1628
                                try {
1629
                                        reader = new FileReader(xml);
1630
                                        XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
1631
                                        return new XMLEntity(tag);
1632

    
1633
                                } catch (MarshalException ex) {
1634
                                        // try to close the stream, maybe it remains open
1635
                                        if (reader!=null) {
1636
                                                try { reader.close(); } catch (IOException e1) {}
1637
                                        }
1638
                                        // backup the old file
1639
                                        String backupFile = pluginsPersistencePath+"-"+DateTime.getCurrentDate().getTime();
1640
                                        NotificationManager.addError(Messages.getString("Error_reading_plugin_persinstence_New_file_created_A_backup_was_made_on_")+backupFile, new ConfigurationException(e));
1641
                                        xml.renameTo(new File(backupFile));
1642
                                        // create a new, empty configuration
1643
                                        return new XMLEntity();
1644
                                }
1645
                                catch (FileNotFoundException ex) {
1646
                                        return new XMLEntity();
1647
                                } catch (ValidationException ex) {
1648
                                        throw new ConfigurationException(e);
1649
                                }
1650
                        } catch (ValidationException e) {
1651
                                throw new ConfigurationException(e);
1652
                        }
1653
                } else {
1654
                        return new XMLEntity();
1655
                }
1656
        }
1657

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

    
1663
                File xml = new File(pluginsPersistencePath);
1664
                OutputStreamWriter writer = null;
1665

    
1666
                try {
1667
                        writer = new OutputStreamWriter(new FileOutputStream(tmpFile), CASTORENCODING);
1668
                        entity.getXmlTag().marshal(writer);
1669
                        writer.close();
1670

    
1671
                        // if marshaling process finished correctly, move the file to the correct one
1672
                        xml.delete();
1673
                        if (!tmpFile.renameTo(xml)) {
1674
                                // if rename was not succesful, try copying it
1675
                                FileChannel sourceChannel = new  FileInputStream(tmpFile).getChannel();
1676
                                FileChannel destinationChannel = new FileOutputStream(xml).getChannel();
1677
                                sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel);
1678
                                sourceChannel.close();
1679
                                destinationChannel.close();
1680

    
1681
                        }
1682
                } catch (FileNotFoundException e) {
1683
                        throw new ConfigurationException(e);
1684
                } catch (MarshalException e) {
1685
                        // try to close the stream, maybe it remains open
1686
                        if (writer!=null) {
1687
                                try { writer.close(); } catch (IOException e1) {}
1688
                        }
1689
                } catch (ValidationException e) {
1690
                        throw new ConfigurationException(e);
1691
                } catch (IOException e) {
1692
                        throw new ConfigurationException(e);
1693
                }
1694
        }
1695

    
1696
        static MDIFrame getFrame() {
1697
                return frame;
1698
        }
1699

    
1700
        /**
1701
         * Gracefully closes the application. It shows dialogs to save data,
1702
         * finish processes, etc, then it terminates the extensions, removes
1703
         * temporal files and finally exits.
1704
         */
1705
        public synchronized static void closeApplication() {
1706
                TerminationProcess terminationProcess = (new Launcher()).new TerminationProcess();
1707
                terminationProcess.run();
1708
        }
1709

    
1710
        static HashMap getClassesExtensions() {
1711
                return classesExtensions;
1712
        }
1713

    
1714

    
1715
        private static Extensions[] getExtensions() {
1716
                ArrayList array = new ArrayList();
1717
                Iterator iter = pluginsConfig.values().iterator();
1718

    
1719
                while (iter.hasNext()) {
1720
                        array.add(((PluginConfig) iter.next()).getExtensions());
1721
                }
1722

    
1723
                return (Extensions[]) array.toArray(new Extensions[0]);
1724
        }
1725

    
1726
        public static Iterator getExtensionIterator() {
1727
                return extensions.iterator();
1728
        }
1729

    
1730
        public static HashMap getPluginConfig() {
1731
                return pluginsConfig;
1732
        }
1733

    
1734
        public static Extension getExtension(String s) {
1735
                Extensions[] exts = getExtensions();
1736

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

    
1745
                return null;
1746
        }
1747

    
1748
        public static AndamiConfig getAndamiConfig() {
1749
                return andamiConfig;
1750
        }
1751

    
1752
        private static class ExtensionComparator implements Comparator {
1753
                public int compare(Object o1, Object o2) {
1754
                        Extension e1 = (Extension) o1;
1755
                        Extension e2 = (Extension) o2;
1756

    
1757
                        if (!e1.hasPriority() && !e2.hasPriority()) {
1758
                                return -1;
1759
                        }
1760

    
1761
                        if (e1.hasPriority() && !e2.hasPriority()) {
1762
                                return Integer.MIN_VALUE;
1763
                        }
1764

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

    
1769
                        if (e1.getPriority() != e2.getPriority()){
1770
                                return e2.getPriority() - e1.getPriority();
1771
                        }else{
1772
                                return (e2.toString().compareTo(e1.toString()));
1773
                        }
1774
                }
1775
        }
1776

    
1777
        private static class MenuComparator implements Comparator {
1778
                private static ExtensionComparator extComp = new ExtensionComparator();
1779

    
1780
                public int compare(Object o1, Object o2) {
1781
                        SortableMenu e1 = (SortableMenu) o1;
1782
                        SortableMenu e2 = (SortableMenu) o2;
1783

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

    
1794
                        if (e1.menu.hasPosition() && !e2.menu.hasPosition()) {
1795
                                return Integer.MIN_VALUE;
1796
                        }
1797

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

    
1810
        private static class SortableMenu {
1811
                public PluginClassLoader loader;
1812
                public Menu menu;
1813
                public SkinExtensionType extension;
1814

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

    
1823
        private static class SortableTool {
1824
                public PluginClassLoader loader;
1825
                public ToolBar toolbar;
1826
                public ActionTool actiontool;
1827
                public SelectableTool selectabletool;
1828
                public SkinExtensionType extension;
1829

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

    
1846
        private static class ToolBarComparator implements Comparator {
1847
                private static ExtensionComparator extComp = new ExtensionComparator();
1848

    
1849
                public int compare(Object o1, Object o2) {
1850
                        SortableTool e1 = (SortableTool) o1;
1851
                        SortableTool e2 = (SortableTool) o2;
1852

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

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

    
1868
                        if (e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
1869
                                return Integer.MIN_VALUE;
1870
                        }
1871

    
1872
                        if (e2.toolbar.hasPosition() && !e1.toolbar.hasPosition()) {
1873
                                return Integer.MAX_VALUE;
1874
                        }
1875
                        if (e1.toolbar.getPosition() != e2.toolbar.getPosition())
1876
                                return e1.toolbar.getPosition() - e2.toolbar.getPosition();
1877

    
1878
                        if (e1.toolbar.getActionTool().equals(e2.toolbar.getActionTool()) && e1.toolbar.getSelectableTool().equals(e2.toolbar.getSelectableTool())){
1879
                                return 0;
1880
                        }
1881
                        return (e1.toolbar.toString().compareTo(e2.toolbar.toString()));
1882
                }
1883
        }
1884

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

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

    
1916
                        if (e1.actiontool!=null) {
1917
                                if (e1.actiontool.hasPosition())
1918
                                        e1Position = e1.actiontool.getPosition();
1919
                        }
1920
                        else if (e1.selectabletool!=null) {
1921
                                if (e1.selectabletool.hasPosition())
1922
                                        e1Position = e1.selectabletool.getPosition();
1923
                        }
1924

    
1925
                        if (e2.actiontool!=null) {
1926
                                if (e2.actiontool.hasPosition())
1927
                                        e2Position = e2.actiontool.getPosition();
1928
                        }
1929
                        else if (e2.selectabletool!=null){
1930
                                if (e2.selectabletool.hasPosition())
1931
                                        e2Position = e2.selectabletool.getPosition();
1932
                        }
1933

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

    
1949

    
1950
        /**
1951
         * validates the user before starting gvsig
1952
         *
1953
         */
1954
        private static void validate(){
1955

    
1956
                IAuthentication session =  null;
1957
                try {
1958
                        session = (IAuthentication)Class.forName("com.iver.andami.authentication.Session").newInstance();
1959

    
1960
                } catch (ClassNotFoundException e) {
1961
                        return;
1962
                } catch (InstantiationException e) {
1963
                        return;
1964
                } catch (IllegalAccessException e) {
1965
                        return;
1966
                }
1967

    
1968
                session.setPluginDirectory( andamiConfig.getPluginsDirectory() );
1969
                if (session.validationRequired()){
1970
                        if(session.Login()){
1971
                                logger.info("You are logged in");
1972
                        } else {
1973
                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),
1974
                                                 "You are not logged in");
1975
                        }
1976
                        PluginServices.setAuthentication(session);
1977
                }
1978
        }
1979

    
1980
        public static String getDefaultLookAndFeel() {
1981
                String osName = (String) System.getProperty("os.name");
1982

    
1983
                if (osName.length() > 4 && osName.substring(0,5).toLowerCase().equals("linux"))
1984
                        return nonWinDefaultLookAndFeel;
1985
                if (osName.toLowerCase().startsWith("mac os x"))
1986
                        return "ch.randelshofer.quaqua.QuaquaLookAndFeel";
1987

    
1988

    
1989
                return UIManager.getSystemLookAndFeelClassName();
1990
        }
1991

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

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

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

    
2091
        }
2092

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

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

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

    
2135

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

    
2153
                logger.error(Messages.getString("No_se_encontro_la_extension_especificada_en_el_parametro_exclusiveUI") + " '" + name +"'");
2154
        }
2155

    
2156

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

    
2194
        public static void initIconThemes(){
2195
                IconThemeManager iconManager = IconThemeManager.getIconThemeManager();
2196
                IIconTheme icontheme= iconManager.getIconThemeFromConfig();
2197
                if (icontheme!=null){
2198
                        iconManager.setCurrent(icontheme);
2199
                }
2200
        }
2201

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

    
2211
                public void run() {
2212
                        int exit = manageUnsavedData();
2213
                        if (exit==JOptionPane.NO_OPTION || exit == JOptionPane.CLOSED_OPTION) {
2214
                                // the user doesn't want to exit
2215
                                return;
2216
                        }
2217

    
2218
                        closeAndami();
2219
                }
2220

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

    
2239
                        //Persistencia de los plugins
2240
                        savePluginPersistence();
2241

    
2242
                        //Finalize all the extensions
2243
                        finalizeExtensions();
2244

    
2245
                        // Clean any temp data created
2246
                        Utilities.cleanUpTempFiles();
2247

    
2248
                        //Para la depuraci?n de memory leaks
2249
                        System.gc();
2250

    
2251
                        System.exit(0);
2252
                }
2253

    
2254
                /**
2255
                 * Exectutes the terminate method for all the extensions, in the reverse
2256
                 * order they were initialized
2257
                 *
2258
                 */
2259
                private void finalizeExtensions() {
2260
                        for (int i=extensions.size()-1; i>=0; i--) {
2261
                                org.gvsig.andami.plugins.IExtension extensionInstance=(org.gvsig.andami.plugins.IExtension)extensions.get(i);
2262
                                extensionInstance.terminate();
2263
                        }
2264
                }
2265

    
2266

    
2267
                private ArrayList getUnsavedData() {
2268
                        ArrayList unsavedDataList = new ArrayList();
2269
                        IExtension exclusiveExtension=PluginServices.getExclusiveUIExtension();
2270

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

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

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

    
2315
                        // it does not work if we directly cast the array
2316
                        IUnsavedData[] unsavedDataArray;
2317
                        unsavedDataArray = new IUnsavedData[unsavedDataList.size()];
2318
                        System.arraycopy(unsavedDataList.toArray(), 0, unsavedDataArray, 0, unsavedDataList.size());
2319

    
2320
                        UnsavedDataPanel panel = getUnsavedDataPanel();
2321
                        panel.setUnsavedDataArray(unsavedDataArray);
2322

    
2323

    
2324
                        panel.addActionListener(panel.new UnsavedDataPanelListener() {
2325
                                public void cancel(UnsavedDataPanel panel){
2326
                                        proceed(false);
2327
                                        PluginServices.getMDIManager().closeWindow(panel);
2328

    
2329
                                }
2330

    
2331
                                public void discard(UnsavedDataPanel panel){
2332
                                        proceed(true);
2333
                                        PluginServices.getMDIManager().closeWindow(panel);
2334

    
2335
                                }
2336

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

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

    
2370
                        PluginServices.getMDIManager().addWindow(panel);
2371
                        if (proceed) {
2372
                                return JOptionPane.YES_OPTION;
2373
                        }
2374
                        else {
2375
                                return JOptionPane.NO_OPTION;
2376
                        }
2377
                }
2378

    
2379
                private void proceed(boolean proceed) {
2380
                        this.proceed = proceed;
2381
                }
2382

    
2383

    
2384
        }
2385

    
2386
        public static TerminationProcess getTerminationProcess() {
2387
                return (new Launcher()).new TerminationProcess();
2388
        }
2389
}